1 // 2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // Specify priority of register selection within phases of register 135 // allocation. Highest priority is first. A useful heuristic is to 136 // give registers a low priority when they are required by machine 137 // instructions, like EAX and EDX on I486, and choose no-save registers 138 // before save-on-call, & save-on-call before save-on-entry. Registers 139 // which participate in fixed calling sequences should come last. 140 // Registers which are used as pairs must fall on an even boundary. 141 142 alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160 //----------Architecture Description Register Classes-------------------------- 161 // Several register classes are automatically defined based upon information in 162 // this architecture description. 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167 // 168 169 // Empty register class. 170 reg_class no_reg(); 171 172 // Class for all pointer registers (including RSP and RBP) 173 reg_class any_reg_with_rbp(RAX, RAX_H, 174 RDX, RDX_H, 175 RBP, RBP_H, 176 RDI, RDI_H, 177 RSI, RSI_H, 178 RCX, RCX_H, 179 RBX, RBX_H, 180 RSP, RSP_H, 181 R8, R8_H, 182 R9, R9_H, 183 R10, R10_H, 184 R11, R11_H, 185 R12, R12_H, 186 R13, R13_H, 187 R14, R14_H, 188 R15, R15_H); 189 190 // Class for all pointer registers (including RSP, but excluding RBP) 191 reg_class any_reg_no_rbp(RAX, RAX_H, 192 RDX, RDX_H, 193 RDI, RDI_H, 194 RSI, RSI_H, 195 RCX, RCX_H, 196 RBX, RBX_H, 197 RSP, RSP_H, 198 R8, R8_H, 199 R9, R9_H, 200 R10, R10_H, 201 R11, R11_H, 202 R12, R12_H, 203 R13, R13_H, 204 R14, R14_H, 205 R15, R15_H); 206 207 // Dynamic register class that selects at runtime between register classes 208 // any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer). 209 // Equivalent to: return PreserveFramePointer ? any_reg_no_rbp : any_reg_with_rbp; 210 reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %}); 211 212 // Class for all pointer registers (excluding RSP) 213 reg_class ptr_reg_with_rbp(RAX, RAX_H, 214 RDX, RDX_H, 215 RBP, RBP_H, 216 RDI, RDI_H, 217 RSI, RSI_H, 218 RCX, RCX_H, 219 RBX, RBX_H, 220 R8, R8_H, 221 R9, R9_H, 222 R10, R10_H, 223 R11, R11_H, 224 R13, R13_H, 225 R14, R14_H); 226 227 // Class for all pointer registers (excluding RSP and RBP) 228 reg_class ptr_reg_no_rbp(RAX, RAX_H, 229 RDX, RDX_H, 230 RDI, RDI_H, 231 RSI, RSI_H, 232 RCX, RCX_H, 233 RBX, RBX_H, 234 R8, R8_H, 235 R9, R9_H, 236 R10, R10_H, 237 R11, R11_H, 238 R13, R13_H, 239 R14, R14_H); 240 241 // Dynamic register class that selects between ptr_reg_no_rbp and ptr_reg_with_rbp. 242 reg_class_dynamic ptr_reg(ptr_reg_no_rbp, ptr_reg_with_rbp, %{ PreserveFramePointer %}); 243 244 // Class for all pointer registers (excluding RAX and RSP) 245 reg_class ptr_no_rax_reg_with_rbp(RDX, RDX_H, 246 RBP, RBP_H, 247 RDI, RDI_H, 248 RSI, RSI_H, 249 RCX, RCX_H, 250 RBX, RBX_H, 251 R8, R8_H, 252 R9, R9_H, 253 R10, R10_H, 254 R11, R11_H, 255 R13, R13_H, 256 R14, R14_H); 257 258 // Class for all pointer registers (excluding RAX, RSP, and RBP) 259 reg_class ptr_no_rax_reg_no_rbp(RDX, RDX_H, 260 RDI, RDI_H, 261 RSI, RSI_H, 262 RCX, RCX_H, 263 RBX, RBX_H, 264 R8, R8_H, 265 R9, R9_H, 266 R10, R10_H, 267 R11, R11_H, 268 R13, R13_H, 269 R14, R14_H); 270 271 // Dynamic register class that selects between ptr_no_rax_reg_no_rbp and ptr_no_rax_reg_with_rbp. 272 reg_class_dynamic ptr_no_rax_reg(ptr_no_rax_reg_no_rbp, ptr_no_rax_reg_with_rbp, %{ PreserveFramePointer %}); 273 274 // Class for all pointer registers (excluding RAX, RBX, and RSP) 275 reg_class ptr_no_rax_rbx_reg_with_rbp(RDX, RDX_H, 276 RBP, RBP_H, 277 RDI, RDI_H, 278 RSI, RSI_H, 279 RCX, RCX_H, 280 R8, R8_H, 281 R9, R9_H, 282 R10, R10_H, 283 R11, R11_H, 284 R13, R13_H, 285 R14, R14_H); 286 287 // Class for all pointer registers (excluding RAX, RBX, RSP, and RBP) 288 reg_class ptr_no_rax_rbx_reg_no_rbp(RDX, RDX_H, 289 RDI, RDI_H, 290 RSI, RSI_H, 291 RCX, RCX_H, 292 R8, R8_H, 293 R9, R9_H, 294 R10, R10_H, 295 R11, R11_H, 296 R13, R13_H, 297 R14, R14_H); 298 299 // Dynamic register class that selects between ptr_no_rax_rbx_reg_no_rbp and ptr_no_rax_rbx_reg_with_rbp. 300 reg_class_dynamic ptr_no_rax_rbx_reg(ptr_no_rax_rbx_reg_no_rbp, ptr_no_rax_rbx_reg_with_rbp, %{ PreserveFramePointer %}); 301 302 // Singleton class for RAX pointer register 303 reg_class ptr_rax_reg(RAX, RAX_H); 304 305 // Singleton class for RBX pointer register 306 reg_class ptr_rbx_reg(RBX, RBX_H); 307 308 // Singleton class for RSI pointer register 309 reg_class ptr_rsi_reg(RSI, RSI_H); 310 311 // Singleton class for RDI pointer register 312 reg_class ptr_rdi_reg(RDI, RDI_H); 313 314 // Singleton class for stack pointer 315 reg_class ptr_rsp_reg(RSP, RSP_H); 316 317 // Singleton class for TLS pointer 318 reg_class ptr_r15_reg(R15, R15_H); 319 320 // Class for all long registers (excluding RSP) 321 reg_class long_reg_with_rbp(RAX, RAX_H, 322 RDX, RDX_H, 323 RBP, RBP_H, 324 RDI, RDI_H, 325 RSI, RSI_H, 326 RCX, RCX_H, 327 RBX, RBX_H, 328 R8, R8_H, 329 R9, R9_H, 330 R10, R10_H, 331 R11, R11_H, 332 R13, R13_H, 333 R14, R14_H); 334 335 // Class for all long registers (excluding RSP and RBP) 336 reg_class long_reg_no_rbp(RAX, RAX_H, 337 RDX, RDX_H, 338 RDI, RDI_H, 339 RSI, RSI_H, 340 RCX, RCX_H, 341 RBX, RBX_H, 342 R8, R8_H, 343 R9, R9_H, 344 R10, R10_H, 345 R11, R11_H, 346 R13, R13_H, 347 R14, R14_H); 348 349 // Dynamic register class that selects between long_reg_no_rbp and long_reg_with_rbp. 350 reg_class_dynamic long_reg(long_reg_no_rbp, long_reg_with_rbp, %{ PreserveFramePointer %}); 351 352 // Class for all long registers (excluding RAX, RDX and RSP) 353 reg_class long_no_rax_rdx_reg_with_rbp(RBP, RBP_H, 354 RDI, RDI_H, 355 RSI, RSI_H, 356 RCX, RCX_H, 357 RBX, RBX_H, 358 R8, R8_H, 359 R9, R9_H, 360 R10, R10_H, 361 R11, R11_H, 362 R13, R13_H, 363 R14, R14_H); 364 365 // Class for all long registers (excluding RAX, RDX, RSP, and RBP) 366 reg_class long_no_rax_rdx_reg_no_rbp(RDI, RDI_H, 367 RSI, RSI_H, 368 RCX, RCX_H, 369 RBX, RBX_H, 370 R8, R8_H, 371 R9, R9_H, 372 R10, R10_H, 373 R11, R11_H, 374 R13, R13_H, 375 R14, R14_H); 376 377 // Dynamic register class that selects between long_no_rax_rdx_reg_no_rbp and long_no_rax_rdx_reg_with_rbp. 378 reg_class_dynamic long_no_rax_rdx_reg(long_no_rax_rdx_reg_no_rbp, long_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 379 380 // Class for all long registers (excluding RCX and RSP) 381 reg_class long_no_rcx_reg_with_rbp(RBP, RBP_H, 382 RDI, RDI_H, 383 RSI, RSI_H, 384 RAX, RAX_H, 385 RDX, RDX_H, 386 RBX, RBX_H, 387 R8, R8_H, 388 R9, R9_H, 389 R10, R10_H, 390 R11, R11_H, 391 R13, R13_H, 392 R14, R14_H); 393 394 // Class for all long registers (excluding RCX, RSP, and RBP) 395 reg_class long_no_rcx_reg_no_rbp(RDI, RDI_H, 396 RSI, RSI_H, 397 RAX, RAX_H, 398 RDX, RDX_H, 399 RBX, RBX_H, 400 R8, R8_H, 401 R9, R9_H, 402 R10, R10_H, 403 R11, R11_H, 404 R13, R13_H, 405 R14, R14_H); 406 407 // Dynamic register class that selects between long_no_rcx_reg_no_rbp and long_no_rcx_reg_with_rbp. 408 reg_class_dynamic long_no_rcx_reg(long_no_rcx_reg_no_rbp, long_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 409 410 // Singleton class for RAX long register 411 reg_class long_rax_reg(RAX, RAX_H); 412 413 // Singleton class for RCX long register 414 reg_class long_rcx_reg(RCX, RCX_H); 415 416 // Singleton class for RDX long register 417 reg_class long_rdx_reg(RDX, RDX_H); 418 419 // Class for all int registers (excluding RSP) 420 reg_class int_reg_with_rbp(RAX, 421 RDX, 422 RBP, 423 RDI, 424 RSI, 425 RCX, 426 RBX, 427 R8, 428 R9, 429 R10, 430 R11, 431 R13, 432 R14); 433 434 // Class for all int registers (excluding RSP and RBP) 435 reg_class int_reg_no_rbp(RAX, 436 RDX, 437 RDI, 438 RSI, 439 RCX, 440 RBX, 441 R8, 442 R9, 443 R10, 444 R11, 445 R13, 446 R14); 447 448 // Dynamic register class that selects between int_reg_no_rbp and int_reg_with_rbp. 449 reg_class_dynamic int_reg(int_reg_no_rbp, int_reg_with_rbp, %{ PreserveFramePointer %}); 450 451 // Class for all int registers (excluding RCX and RSP) 452 reg_class int_no_rcx_reg_with_rbp(RAX, 453 RDX, 454 RBP, 455 RDI, 456 RSI, 457 RBX, 458 R8, 459 R9, 460 R10, 461 R11, 462 R13, 463 R14); 464 465 // Class for all int registers (excluding RCX, RSP, and RBP) 466 reg_class int_no_rcx_reg_no_rbp(RAX, 467 RDX, 468 RDI, 469 RSI, 470 RBX, 471 R8, 472 R9, 473 R10, 474 R11, 475 R13, 476 R14); 477 478 // Dynamic register class that selects between int_no_rcx_reg_no_rbp and int_no_rcx_reg_with_rbp. 479 reg_class_dynamic int_no_rcx_reg(int_no_rcx_reg_no_rbp, int_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 480 481 // Class for all int registers (excluding RAX, RDX, and RSP) 482 reg_class int_no_rax_rdx_reg_with_rbp(RBP, 483 RDI, 484 RSI, 485 RCX, 486 RBX, 487 R8, 488 R9, 489 R10, 490 R11, 491 R13, 492 R14); 493 494 // Class for all int registers (excluding RAX, RDX, RSP, and RBP) 495 reg_class int_no_rax_rdx_reg_no_rbp(RDI, 496 RSI, 497 RCX, 498 RBX, 499 R8, 500 R9, 501 R10, 502 R11, 503 R13, 504 R14); 505 506 // Dynamic register class that selects between int_no_rax_rdx_reg_no_rbp and int_no_rax_rdx_reg_with_rbp. 507 reg_class_dynamic int_no_rax_rdx_reg(int_no_rax_rdx_reg_no_rbp, int_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 508 509 // Singleton class for RAX int register 510 reg_class int_rax_reg(RAX); 511 512 // Singleton class for RBX int register 513 reg_class int_rbx_reg(RBX); 514 515 // Singleton class for RCX int register 516 reg_class int_rcx_reg(RCX); 517 518 // Singleton class for RCX int register 519 reg_class int_rdx_reg(RDX); 520 521 // Singleton class for RCX int register 522 reg_class int_rdi_reg(RDI); 523 524 // Singleton class for instruction pointer 525 // reg_class ip_reg(RIP); 526 527 %} 528 529 source_hpp %{ 530 531 #include "gc_implementation/shenandoah/brooksPointer.hpp" 532 533 %} 534 535 //----------SOURCE BLOCK------------------------------------------------------- 536 // This is a block of C++ code which provides values, functions, and 537 // definitions necessary in the rest of the architecture description 538 source %{ 539 #define RELOC_IMM64 Assembler::imm_operand 540 #define RELOC_DISP32 Assembler::disp32_operand 541 542 #define __ _masm. 543 544 static int clear_avx_size() { 545 return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper 546 } 547 548 // !!!!! Special hack to get all types of calls to specify the byte offset 549 // from the start of the call to the point where the return address 550 // will point. 551 int MachCallStaticJavaNode::ret_addr_offset() 552 { 553 int offset = 5; // 5 bytes from start of call to where return address points 554 offset += clear_avx_size(); 555 return offset; 556 } 557 558 int MachCallDynamicJavaNode::ret_addr_offset() 559 { 560 int offset = 15; // 15 bytes from start of call to where return address points 561 offset += clear_avx_size(); 562 return offset; 563 } 564 565 int MachCallRuntimeNode::ret_addr_offset() { 566 int offset = 13; // movq r10,#addr; callq (r10) 567 offset += clear_avx_size(); 568 return offset; 569 } 570 571 // Indicate if the safepoint node needs the polling page as an input, 572 // it does if the polling page is more than disp32 away. 573 bool SafePointNode::needs_polling_address_input() 574 { 575 return Assembler::is_polling_page_far(); 576 } 577 578 // 579 // Compute padding required for nodes which need alignment 580 // 581 582 // The address of the call instruction needs to be 4-byte aligned to 583 // ensure that it does not span a cache line so that it can be patched. 584 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 585 { 586 current_offset += clear_avx_size(); // skip vzeroupper 587 current_offset += 1; // skip call opcode byte 588 return round_to(current_offset, alignment_required()) - current_offset; 589 } 590 591 // The address of the call instruction needs to be 4-byte aligned to 592 // ensure that it does not span a cache line so that it can be patched. 593 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 594 { 595 current_offset += clear_avx_size(); // skip vzeroupper 596 current_offset += 11; // skip movq instruction + call opcode byte 597 return round_to(current_offset, alignment_required()) - current_offset; 598 } 599 600 // EMIT_RM() 601 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 602 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 603 cbuf.insts()->emit_int8(c); 604 } 605 606 // EMIT_CC() 607 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 608 unsigned char c = (unsigned char) (f1 | f2); 609 cbuf.insts()->emit_int8(c); 610 } 611 612 // EMIT_OPCODE() 613 void emit_opcode(CodeBuffer &cbuf, int code) { 614 cbuf.insts()->emit_int8((unsigned char) code); 615 } 616 617 // EMIT_OPCODE() w/ relocation information 618 void emit_opcode(CodeBuffer &cbuf, 619 int code, relocInfo::relocType reloc, int offset, int format) 620 { 621 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 622 emit_opcode(cbuf, code); 623 } 624 625 // EMIT_D8() 626 void emit_d8(CodeBuffer &cbuf, int d8) { 627 cbuf.insts()->emit_int8((unsigned char) d8); 628 } 629 630 // EMIT_D16() 631 void emit_d16(CodeBuffer &cbuf, int d16) { 632 cbuf.insts()->emit_int16(d16); 633 } 634 635 // EMIT_D32() 636 void emit_d32(CodeBuffer &cbuf, int d32) { 637 cbuf.insts()->emit_int32(d32); 638 } 639 640 // EMIT_D64() 641 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 642 cbuf.insts()->emit_int64(d64); 643 } 644 645 // emit 32 bit value and construct relocation entry from relocInfo::relocType 646 void emit_d32_reloc(CodeBuffer& cbuf, 647 int d32, 648 relocInfo::relocType reloc, 649 int format) 650 { 651 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 652 cbuf.relocate(cbuf.insts_mark(), reloc, format); 653 cbuf.insts()->emit_int32(d32); 654 } 655 656 // emit 32 bit value and construct relocation entry from RelocationHolder 657 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 658 #ifdef ASSERT 659 if (rspec.reloc()->type() == relocInfo::oop_type && 660 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 661 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 662 assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 663 } 664 #endif 665 cbuf.relocate(cbuf.insts_mark(), rspec, format); 666 cbuf.insts()->emit_int32(d32); 667 } 668 669 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 670 address next_ip = cbuf.insts_end() + 4; 671 emit_d32_reloc(cbuf, (int) (addr - next_ip), 672 external_word_Relocation::spec(addr), 673 RELOC_DISP32); 674 } 675 676 677 // emit 64 bit value and construct relocation entry from relocInfo::relocType 678 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 679 cbuf.relocate(cbuf.insts_mark(), reloc, format); 680 cbuf.insts()->emit_int64(d64); 681 } 682 683 // emit 64 bit value and construct relocation entry from RelocationHolder 684 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 685 #ifdef ASSERT 686 if (rspec.reloc()->type() == relocInfo::oop_type && 687 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 688 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 689 assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()), 690 "cannot embed scavengable oops in code"); 691 } 692 #endif 693 cbuf.relocate(cbuf.insts_mark(), rspec, format); 694 cbuf.insts()->emit_int64(d64); 695 } 696 697 // Access stack slot for load or store 698 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 699 { 700 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 701 if (-0x80 <= disp && disp < 0x80) { 702 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 703 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 704 emit_d8(cbuf, disp); // Displacement // R/M byte 705 } else { 706 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 707 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 708 emit_d32(cbuf, disp); // Displacement // R/M byte 709 } 710 } 711 712 // rRegI ereg, memory mem) %{ // emit_reg_mem 713 void encode_RegMem(CodeBuffer &cbuf, 714 int reg, 715 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 716 { 717 assert(disp_reloc == relocInfo::none, "cannot have disp"); 718 int regenc = reg & 7; 719 int baseenc = base & 7; 720 int indexenc = index & 7; 721 722 // There is no index & no scale, use form without SIB byte 723 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 724 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 725 if (disp == 0 && base != RBP_enc && base != R13_enc) { 726 emit_rm(cbuf, 0x0, regenc, baseenc); // * 727 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 728 // If 8-bit displacement, mode 0x1 729 emit_rm(cbuf, 0x1, regenc, baseenc); // * 730 emit_d8(cbuf, disp); 731 } else { 732 // If 32-bit displacement 733 if (base == -1) { // Special flag for absolute address 734 emit_rm(cbuf, 0x0, regenc, 0x5); // * 735 if (disp_reloc != relocInfo::none) { 736 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 737 } else { 738 emit_d32(cbuf, disp); 739 } 740 } else { 741 // Normal base + offset 742 emit_rm(cbuf, 0x2, regenc, baseenc); // * 743 if (disp_reloc != relocInfo::none) { 744 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 745 } else { 746 emit_d32(cbuf, disp); 747 } 748 } 749 } 750 } else { 751 // Else, encode with the SIB byte 752 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 753 if (disp == 0 && base != RBP_enc && base != R13_enc) { 754 // If no displacement 755 emit_rm(cbuf, 0x0, regenc, 0x4); // * 756 emit_rm(cbuf, scale, indexenc, baseenc); 757 } else { 758 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 759 // If 8-bit displacement, mode 0x1 760 emit_rm(cbuf, 0x1, regenc, 0x4); // * 761 emit_rm(cbuf, scale, indexenc, baseenc); 762 emit_d8(cbuf, disp); 763 } else { 764 // If 32-bit displacement 765 if (base == 0x04 ) { 766 emit_rm(cbuf, 0x2, regenc, 0x4); 767 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 768 } else { 769 emit_rm(cbuf, 0x2, regenc, 0x4); 770 emit_rm(cbuf, scale, indexenc, baseenc); // * 771 } 772 if (disp_reloc != relocInfo::none) { 773 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 774 } else { 775 emit_d32(cbuf, disp); 776 } 777 } 778 } 779 } 780 } 781 782 // This could be in MacroAssembler but it's fairly C2 specific 783 void emit_cmpfp_fixup(MacroAssembler& _masm) { 784 Label exit; 785 __ jccb(Assembler::noParity, exit); 786 __ pushf(); 787 // 788 // comiss/ucomiss instructions set ZF,PF,CF flags and 789 // zero OF,AF,SF for NaN values. 790 // Fixup flags by zeroing ZF,PF so that compare of NaN 791 // values returns 'less than' result (CF is set). 792 // Leave the rest of flags unchanged. 793 // 794 // 7 6 5 4 3 2 1 0 795 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 796 // 0 0 1 0 1 0 1 1 (0x2B) 797 // 798 __ andq(Address(rsp, 0), 0xffffff2b); 799 __ popf(); 800 __ bind(exit); 801 } 802 803 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 804 Label done; 805 __ movl(dst, -1); 806 __ jcc(Assembler::parity, done); 807 __ jcc(Assembler::below, done); 808 __ setb(Assembler::notEqual, dst); 809 __ movzbl(dst, dst); 810 __ bind(done); 811 } 812 813 814 //============================================================================= 815 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 816 817 int Compile::ConstantTable::calculate_table_base_offset() const { 818 return 0; // absolute addressing, no offset 819 } 820 821 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 822 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 823 ShouldNotReachHere(); 824 } 825 826 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 827 // Empty encoding 828 } 829 830 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 831 return 0; 832 } 833 834 #ifndef PRODUCT 835 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 836 st->print("# MachConstantBaseNode (empty encoding)"); 837 } 838 #endif 839 840 841 //============================================================================= 842 #ifndef PRODUCT 843 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 844 Compile* C = ra_->C; 845 846 int framesize = C->frame_size_in_bytes(); 847 int bangsize = C->bang_size_in_bytes(); 848 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 849 // Remove wordSize for return addr which is already pushed. 850 framesize -= wordSize; 851 852 if (C->need_stack_bang(bangsize)) { 853 framesize -= wordSize; 854 st->print("# stack bang (%d bytes)", bangsize); 855 st->print("\n\t"); 856 st->print("pushq rbp\t# Save rbp"); 857 if (PreserveFramePointer) { 858 st->print("\n\t"); 859 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 860 } 861 if (framesize) { 862 st->print("\n\t"); 863 st->print("subq rsp, #%d\t# Create frame",framesize); 864 } 865 } else { 866 st->print("subq rsp, #%d\t# Create frame",framesize); 867 st->print("\n\t"); 868 framesize -= wordSize; 869 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 870 if (PreserveFramePointer) { 871 st->print("\n\t"); 872 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 873 if (framesize > 0) { 874 st->print("\n\t"); 875 st->print("addq rbp, #%d", framesize); 876 } 877 } 878 } 879 880 if (VerifyStackAtCalls) { 881 st->print("\n\t"); 882 framesize -= wordSize; 883 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 884 #ifdef ASSERT 885 st->print("\n\t"); 886 st->print("# stack alignment check"); 887 #endif 888 } 889 st->cr(); 890 } 891 #endif 892 893 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 894 Compile* C = ra_->C; 895 MacroAssembler _masm(&cbuf); 896 897 int framesize = C->frame_size_in_bytes(); 898 int bangsize = C->bang_size_in_bytes(); 899 900 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); 901 902 C->set_frame_complete(cbuf.insts_size()); 903 904 if (C->has_mach_constant_base_node()) { 905 // NOTE: We set the table base offset here because users might be 906 // emitted before MachConstantBaseNode. 907 Compile::ConstantTable& constant_table = C->constant_table(); 908 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 909 } 910 } 911 912 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 913 { 914 return MachNode::size(ra_); // too many variables; just compute it 915 // the hard way 916 } 917 918 int MachPrologNode::reloc() const 919 { 920 return 0; // a large enough number 921 } 922 923 //============================================================================= 924 #ifndef PRODUCT 925 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 926 { 927 Compile* C = ra_->C; 928 if (C->max_vector_size() > 16) { 929 st->print("vzeroupper"); 930 st->cr(); st->print("\t"); 931 } 932 933 int framesize = C->frame_size_in_bytes(); 934 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 935 // Remove word for return adr already pushed 936 // and RBP 937 framesize -= 2*wordSize; 938 939 if (framesize) { 940 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 941 st->print("\t"); 942 } 943 944 st->print_cr("popq rbp"); 945 if (do_polling() && C->is_method_compilation()) { 946 st->print("\t"); 947 if (Assembler::is_polling_page_far()) { 948 st->print_cr("movq rscratch1, #polling_page_address\n\t" 949 "testl rax, [rscratch1]\t" 950 "# Safepoint: poll for GC"); 951 } else { 952 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 953 "# Safepoint: poll for GC"); 954 } 955 } 956 } 957 #endif 958 959 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 960 { 961 Compile* C = ra_->C; 962 if (C->max_vector_size() > 16) { 963 // Clear upper bits of YMM registers when current compiled code uses 964 // wide vectors to avoid AVX <-> SSE transition penalty during call. 965 MacroAssembler _masm(&cbuf); 966 __ vzeroupper(); 967 } 968 969 int framesize = C->frame_size_in_bytes(); 970 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 971 // Remove word for return adr already pushed 972 // and RBP 973 framesize -= 2*wordSize; 974 975 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 976 977 if (framesize) { 978 emit_opcode(cbuf, Assembler::REX_W); 979 if (framesize < 0x80) { 980 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 981 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 982 emit_d8(cbuf, framesize); 983 } else { 984 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 985 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 986 emit_d32(cbuf, framesize); 987 } 988 } 989 990 // popq rbp 991 emit_opcode(cbuf, 0x58 | RBP_enc); 992 993 if (do_polling() && C->is_method_compilation()) { 994 MacroAssembler _masm(&cbuf); 995 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 996 if (Assembler::is_polling_page_far()) { 997 __ lea(rscratch1, polling_page); 998 __ relocate(relocInfo::poll_return_type); 999 __ testl(rax, Address(rscratch1, 0)); 1000 } else { 1001 __ testl(rax, polling_page); 1002 } 1003 } 1004 } 1005 1006 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1007 { 1008 return MachNode::size(ra_); // too many variables; just compute it 1009 // the hard way 1010 } 1011 1012 int MachEpilogNode::reloc() const 1013 { 1014 return 2; // a large enough number 1015 } 1016 1017 const Pipeline* MachEpilogNode::pipeline() const 1018 { 1019 return MachNode::pipeline_class(); 1020 } 1021 1022 int MachEpilogNode::safepoint_offset() const 1023 { 1024 return 0; 1025 } 1026 1027 //============================================================================= 1028 1029 enum RC { 1030 rc_bad, 1031 rc_int, 1032 rc_float, 1033 rc_stack 1034 }; 1035 1036 static enum RC rc_class(OptoReg::Name reg) 1037 { 1038 if( !OptoReg::is_valid(reg) ) return rc_bad; 1039 1040 if (OptoReg::is_stack(reg)) return rc_stack; 1041 1042 VMReg r = OptoReg::as_VMReg(reg); 1043 1044 if (r->is_Register()) return rc_int; 1045 1046 assert(r->is_XMMRegister(), "must be"); 1047 return rc_float; 1048 } 1049 1050 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1051 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1052 int src_hi, int dst_hi, uint ireg, outputStream* st); 1053 1054 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1055 int stack_offset, int reg, uint ireg, outputStream* st); 1056 1057 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1058 int dst_offset, uint ireg, outputStream* st) { 1059 if (cbuf) { 1060 MacroAssembler _masm(cbuf); 1061 switch (ireg) { 1062 case Op_VecS: 1063 __ movq(Address(rsp, -8), rax); 1064 __ movl(rax, Address(rsp, src_offset)); 1065 __ movl(Address(rsp, dst_offset), rax); 1066 __ movq(rax, Address(rsp, -8)); 1067 break; 1068 case Op_VecD: 1069 __ pushq(Address(rsp, src_offset)); 1070 __ popq (Address(rsp, dst_offset)); 1071 break; 1072 case Op_VecX: 1073 __ pushq(Address(rsp, src_offset)); 1074 __ popq (Address(rsp, dst_offset)); 1075 __ pushq(Address(rsp, src_offset+8)); 1076 __ popq (Address(rsp, dst_offset+8)); 1077 break; 1078 case Op_VecY: 1079 __ vmovdqu(Address(rsp, -32), xmm0); 1080 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1081 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1082 __ vmovdqu(xmm0, Address(rsp, -32)); 1083 break; 1084 default: 1085 ShouldNotReachHere(); 1086 } 1087 #ifndef PRODUCT 1088 } else { 1089 switch (ireg) { 1090 case Op_VecS: 1091 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1092 "movl rax, [rsp + #%d]\n\t" 1093 "movl [rsp + #%d], rax\n\t" 1094 "movq rax, [rsp - #8]", 1095 src_offset, dst_offset); 1096 break; 1097 case Op_VecD: 1098 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1099 "popq [rsp + #%d]", 1100 src_offset, dst_offset); 1101 break; 1102 case Op_VecX: 1103 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1104 "popq [rsp + #%d]\n\t" 1105 "pushq [rsp + #%d]\n\t" 1106 "popq [rsp + #%d]", 1107 src_offset, dst_offset, src_offset+8, dst_offset+8); 1108 break; 1109 case Op_VecY: 1110 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1111 "vmovdqu xmm0, [rsp + #%d]\n\t" 1112 "vmovdqu [rsp + #%d], xmm0\n\t" 1113 "vmovdqu xmm0, [rsp - #32]", 1114 src_offset, dst_offset); 1115 break; 1116 default: 1117 ShouldNotReachHere(); 1118 } 1119 #endif 1120 } 1121 } 1122 1123 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1124 PhaseRegAlloc* ra_, 1125 bool do_size, 1126 outputStream* st) const { 1127 assert(cbuf != NULL || st != NULL, "sanity"); 1128 // Get registers to move 1129 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1130 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1131 OptoReg::Name dst_second = ra_->get_reg_second(this); 1132 OptoReg::Name dst_first = ra_->get_reg_first(this); 1133 1134 enum RC src_second_rc = rc_class(src_second); 1135 enum RC src_first_rc = rc_class(src_first); 1136 enum RC dst_second_rc = rc_class(dst_second); 1137 enum RC dst_first_rc = rc_class(dst_first); 1138 1139 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1140 "must move at least 1 register" ); 1141 1142 if (src_first == dst_first && src_second == dst_second) { 1143 // Self copy, no move 1144 return 0; 1145 } 1146 if (bottom_type()->isa_vect() != NULL) { 1147 uint ireg = ideal_reg(); 1148 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1149 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity"); 1150 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1151 // mem -> mem 1152 int src_offset = ra_->reg2offset(src_first); 1153 int dst_offset = ra_->reg2offset(dst_first); 1154 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1155 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1156 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1157 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1158 int stack_offset = ra_->reg2offset(dst_first); 1159 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1160 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1161 int stack_offset = ra_->reg2offset(src_first); 1162 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1163 } else { 1164 ShouldNotReachHere(); 1165 } 1166 return 0; 1167 } 1168 if (src_first_rc == rc_stack) { 1169 // mem -> 1170 if (dst_first_rc == rc_stack) { 1171 // mem -> mem 1172 assert(src_second != dst_first, "overlap"); 1173 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1174 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1175 // 64-bit 1176 int src_offset = ra_->reg2offset(src_first); 1177 int dst_offset = ra_->reg2offset(dst_first); 1178 if (cbuf) { 1179 MacroAssembler _masm(cbuf); 1180 __ pushq(Address(rsp, src_offset)); 1181 __ popq (Address(rsp, dst_offset)); 1182 #ifndef PRODUCT 1183 } else { 1184 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1185 "popq [rsp + #%d]", 1186 src_offset, dst_offset); 1187 #endif 1188 } 1189 } else { 1190 // 32-bit 1191 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1192 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1193 // No pushl/popl, so: 1194 int src_offset = ra_->reg2offset(src_first); 1195 int dst_offset = ra_->reg2offset(dst_first); 1196 if (cbuf) { 1197 MacroAssembler _masm(cbuf); 1198 __ movq(Address(rsp, -8), rax); 1199 __ movl(rax, Address(rsp, src_offset)); 1200 __ movl(Address(rsp, dst_offset), rax); 1201 __ movq(rax, Address(rsp, -8)); 1202 #ifndef PRODUCT 1203 } else { 1204 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1205 "movl rax, [rsp + #%d]\n\t" 1206 "movl [rsp + #%d], rax\n\t" 1207 "movq rax, [rsp - #8]", 1208 src_offset, dst_offset); 1209 #endif 1210 } 1211 } 1212 return 0; 1213 } else if (dst_first_rc == rc_int) { 1214 // mem -> gpr 1215 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1216 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1217 // 64-bit 1218 int offset = ra_->reg2offset(src_first); 1219 if (cbuf) { 1220 MacroAssembler _masm(cbuf); 1221 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1222 #ifndef PRODUCT 1223 } else { 1224 st->print("movq %s, [rsp + #%d]\t# spill", 1225 Matcher::regName[dst_first], 1226 offset); 1227 #endif 1228 } 1229 } else { 1230 // 32-bit 1231 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1232 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1233 int offset = ra_->reg2offset(src_first); 1234 if (cbuf) { 1235 MacroAssembler _masm(cbuf); 1236 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1237 #ifndef PRODUCT 1238 } else { 1239 st->print("movl %s, [rsp + #%d]\t# spill", 1240 Matcher::regName[dst_first], 1241 offset); 1242 #endif 1243 } 1244 } 1245 return 0; 1246 } else if (dst_first_rc == rc_float) { 1247 // mem-> xmm 1248 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1249 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1250 // 64-bit 1251 int offset = ra_->reg2offset(src_first); 1252 if (cbuf) { 1253 MacroAssembler _masm(cbuf); 1254 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1255 #ifndef PRODUCT 1256 } else { 1257 st->print("%s %s, [rsp + #%d]\t# spill", 1258 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1259 Matcher::regName[dst_first], 1260 offset); 1261 #endif 1262 } 1263 } else { 1264 // 32-bit 1265 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1266 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1267 int offset = ra_->reg2offset(src_first); 1268 if (cbuf) { 1269 MacroAssembler _masm(cbuf); 1270 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1271 #ifndef PRODUCT 1272 } else { 1273 st->print("movss %s, [rsp + #%d]\t# spill", 1274 Matcher::regName[dst_first], 1275 offset); 1276 #endif 1277 } 1278 } 1279 return 0; 1280 } 1281 } else if (src_first_rc == rc_int) { 1282 // gpr -> 1283 if (dst_first_rc == rc_stack) { 1284 // gpr -> mem 1285 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1286 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1287 // 64-bit 1288 int offset = ra_->reg2offset(dst_first); 1289 if (cbuf) { 1290 MacroAssembler _masm(cbuf); 1291 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1292 #ifndef PRODUCT 1293 } else { 1294 st->print("movq [rsp + #%d], %s\t# spill", 1295 offset, 1296 Matcher::regName[src_first]); 1297 #endif 1298 } 1299 } else { 1300 // 32-bit 1301 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1302 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1303 int offset = ra_->reg2offset(dst_first); 1304 if (cbuf) { 1305 MacroAssembler _masm(cbuf); 1306 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1307 #ifndef PRODUCT 1308 } else { 1309 st->print("movl [rsp + #%d], %s\t# spill", 1310 offset, 1311 Matcher::regName[src_first]); 1312 #endif 1313 } 1314 } 1315 return 0; 1316 } else if (dst_first_rc == rc_int) { 1317 // gpr -> gpr 1318 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1319 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1320 // 64-bit 1321 if (cbuf) { 1322 MacroAssembler _masm(cbuf); 1323 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1324 as_Register(Matcher::_regEncode[src_first])); 1325 #ifndef PRODUCT 1326 } else { 1327 st->print("movq %s, %s\t# spill", 1328 Matcher::regName[dst_first], 1329 Matcher::regName[src_first]); 1330 #endif 1331 } 1332 return 0; 1333 } else { 1334 // 32-bit 1335 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1336 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1337 if (cbuf) { 1338 MacroAssembler _masm(cbuf); 1339 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1340 as_Register(Matcher::_regEncode[src_first])); 1341 #ifndef PRODUCT 1342 } else { 1343 st->print("movl %s, %s\t# spill", 1344 Matcher::regName[dst_first], 1345 Matcher::regName[src_first]); 1346 #endif 1347 } 1348 return 0; 1349 } 1350 } else if (dst_first_rc == rc_float) { 1351 // gpr -> xmm 1352 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1353 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1354 // 64-bit 1355 if (cbuf) { 1356 MacroAssembler _masm(cbuf); 1357 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1358 #ifndef PRODUCT 1359 } else { 1360 st->print("movdq %s, %s\t# spill", 1361 Matcher::regName[dst_first], 1362 Matcher::regName[src_first]); 1363 #endif 1364 } 1365 } else { 1366 // 32-bit 1367 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1368 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1369 if (cbuf) { 1370 MacroAssembler _masm(cbuf); 1371 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1372 #ifndef PRODUCT 1373 } else { 1374 st->print("movdl %s, %s\t# spill", 1375 Matcher::regName[dst_first], 1376 Matcher::regName[src_first]); 1377 #endif 1378 } 1379 } 1380 return 0; 1381 } 1382 } else if (src_first_rc == rc_float) { 1383 // xmm -> 1384 if (dst_first_rc == rc_stack) { 1385 // xmm -> mem 1386 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1387 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1388 // 64-bit 1389 int offset = ra_->reg2offset(dst_first); 1390 if (cbuf) { 1391 MacroAssembler _masm(cbuf); 1392 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1393 #ifndef PRODUCT 1394 } else { 1395 st->print("movsd [rsp + #%d], %s\t# spill", 1396 offset, 1397 Matcher::regName[src_first]); 1398 #endif 1399 } 1400 } else { 1401 // 32-bit 1402 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1403 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1404 int offset = ra_->reg2offset(dst_first); 1405 if (cbuf) { 1406 MacroAssembler _masm(cbuf); 1407 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1408 #ifndef PRODUCT 1409 } else { 1410 st->print("movss [rsp + #%d], %s\t# spill", 1411 offset, 1412 Matcher::regName[src_first]); 1413 #endif 1414 } 1415 } 1416 return 0; 1417 } else if (dst_first_rc == rc_int) { 1418 // xmm -> gpr 1419 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1420 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1421 // 64-bit 1422 if (cbuf) { 1423 MacroAssembler _masm(cbuf); 1424 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1425 #ifndef PRODUCT 1426 } else { 1427 st->print("movdq %s, %s\t# spill", 1428 Matcher::regName[dst_first], 1429 Matcher::regName[src_first]); 1430 #endif 1431 } 1432 } else { 1433 // 32-bit 1434 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1435 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1436 if (cbuf) { 1437 MacroAssembler _masm(cbuf); 1438 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1439 #ifndef PRODUCT 1440 } else { 1441 st->print("movdl %s, %s\t# spill", 1442 Matcher::regName[dst_first], 1443 Matcher::regName[src_first]); 1444 #endif 1445 } 1446 } 1447 return 0; 1448 } else if (dst_first_rc == rc_float) { 1449 // xmm -> xmm 1450 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1451 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1452 // 64-bit 1453 if (cbuf) { 1454 MacroAssembler _masm(cbuf); 1455 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1456 #ifndef PRODUCT 1457 } else { 1458 st->print("%s %s, %s\t# spill", 1459 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1460 Matcher::regName[dst_first], 1461 Matcher::regName[src_first]); 1462 #endif 1463 } 1464 } else { 1465 // 32-bit 1466 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1467 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1468 if (cbuf) { 1469 MacroAssembler _masm(cbuf); 1470 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1471 #ifndef PRODUCT 1472 } else { 1473 st->print("%s %s, %s\t# spill", 1474 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1475 Matcher::regName[dst_first], 1476 Matcher::regName[src_first]); 1477 #endif 1478 } 1479 } 1480 return 0; 1481 } 1482 } 1483 1484 assert(0," foo "); 1485 Unimplemented(); 1486 return 0; 1487 } 1488 1489 #ifndef PRODUCT 1490 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1491 implementation(NULL, ra_, false, st); 1492 } 1493 #endif 1494 1495 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1496 implementation(&cbuf, ra_, false, NULL); 1497 } 1498 1499 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1500 return MachNode::size(ra_); 1501 } 1502 1503 //============================================================================= 1504 #ifndef PRODUCT 1505 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1506 { 1507 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1508 int reg = ra_->get_reg_first(this); 1509 st->print("leaq %s, [rsp + #%d]\t# box lock", 1510 Matcher::regName[reg], offset); 1511 } 1512 #endif 1513 1514 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1515 { 1516 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1517 int reg = ra_->get_encode(this); 1518 if (offset >= 0x80) { 1519 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1520 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1521 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1522 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1523 emit_d32(cbuf, offset); 1524 } else { 1525 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1526 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1527 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1528 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1529 emit_d8(cbuf, offset); 1530 } 1531 } 1532 1533 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1534 { 1535 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1536 return (offset < 0x80) ? 5 : 8; // REX 1537 } 1538 1539 //============================================================================= 1540 #ifndef PRODUCT 1541 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1542 { 1543 if (UseCompressedClassPointers) { 1544 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1545 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1546 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1547 } else { 1548 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1549 "# Inline cache check"); 1550 } 1551 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1552 st->print_cr("\tnop\t# nops to align entry point"); 1553 } 1554 #endif 1555 1556 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1557 { 1558 MacroAssembler masm(&cbuf); 1559 uint insts_size = cbuf.insts_size(); 1560 if (UseCompressedClassPointers) { 1561 masm.load_klass(rscratch1, j_rarg0); 1562 masm.cmpptr(rax, rscratch1); 1563 } else { 1564 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1565 } 1566 1567 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1568 1569 /* WARNING these NOPs are critical so that verified entry point is properly 1570 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1571 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1572 if (OptoBreakpoint) { 1573 // Leave space for int3 1574 nops_cnt -= 1; 1575 } 1576 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1577 if (nops_cnt > 0) 1578 masm.nop(nops_cnt); 1579 } 1580 1581 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1582 { 1583 return MachNode::size(ra_); // too many variables; just compute it 1584 // the hard way 1585 } 1586 1587 1588 //============================================================================= 1589 1590 int Matcher::regnum_to_fpu_offset(int regnum) 1591 { 1592 return regnum - 32; // The FP registers are in the second chunk 1593 } 1594 1595 // This is UltraSparc specific, true just means we have fast l2f conversion 1596 const bool Matcher::convL2FSupported(void) { 1597 return true; 1598 } 1599 1600 // Is this branch offset short enough that a short branch can be used? 1601 // 1602 // NOTE: If the platform does not provide any short branch variants, then 1603 // this method should return false for offset 0. 1604 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1605 // The passed offset is relative to address of the branch. 1606 // On 86 a branch displacement is calculated relative to address 1607 // of a next instruction. 1608 offset -= br_size; 1609 1610 // the short version of jmpConUCF2 contains multiple branches, 1611 // making the reach slightly less 1612 if (rule == jmpConUCF2_rule) 1613 return (-126 <= offset && offset <= 125); 1614 return (-128 <= offset && offset <= 127); 1615 } 1616 1617 const bool Matcher::isSimpleConstant64(jlong value) { 1618 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1619 //return value == (int) value; // Cf. storeImmL and immL32. 1620 1621 // Probably always true, even if a temp register is required. 1622 return true; 1623 } 1624 1625 // The ecx parameter to rep stosq for the ClearArray node is in words. 1626 const bool Matcher::init_array_count_is_in_bytes = false; 1627 1628 // Threshold size for cleararray. 1629 const int Matcher::init_array_short_size = 8 * BytesPerLong; 1630 1631 // No additional cost for CMOVL. 1632 const int Matcher::long_cmove_cost() { return 0; } 1633 1634 // No CMOVF/CMOVD with SSE2 1635 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1636 1637 // Does the CPU require late expand (see block.cpp for description of late expand)? 1638 const bool Matcher::require_postalloc_expand = false; 1639 1640 // Should the Matcher clone shifts on addressing modes, expecting them 1641 // to be subsumed into complex addressing expressions or compute them 1642 // into registers? True for Intel but false for most RISCs 1643 const bool Matcher::clone_shift_expressions = true; 1644 1645 // Do we need to mask the count passed to shift instructions or does 1646 // the cpu only look at the lower 5/6 bits anyway? 1647 const bool Matcher::need_masked_shift_count = false; 1648 1649 bool Matcher::narrow_oop_use_complex_address() { 1650 assert(UseCompressedOops, "only for compressed oops code"); 1651 return (LogMinObjAlignmentInBytes <= 3); 1652 } 1653 1654 bool Matcher::narrow_klass_use_complex_address() { 1655 assert(UseCompressedClassPointers, "only for compressed klass code"); 1656 return (LogKlassAlignmentInBytes <= 3); 1657 } 1658 1659 // Is it better to copy float constants, or load them directly from 1660 // memory? Intel can load a float constant from a direct address, 1661 // requiring no extra registers. Most RISCs will have to materialize 1662 // an address into a register first, so they would do better to copy 1663 // the constant from stack. 1664 const bool Matcher::rematerialize_float_constants = true; // XXX 1665 1666 // If CPU can load and store mis-aligned doubles directly then no 1667 // fixup is needed. Else we split the double into 2 integer pieces 1668 // and move it piece-by-piece. Only happens when passing doubles into 1669 // C code as the Java calling convention forces doubles to be aligned. 1670 const bool Matcher::misaligned_doubles_ok = true; 1671 1672 // No-op on amd64 1673 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1674 1675 // Advertise here if the CPU requires explicit rounding operations to 1676 // implement the UseStrictFP mode. 1677 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1678 1679 // Are floats conerted to double when stored to stack during deoptimization? 1680 // On x64 it is stored without convertion so we can use normal access. 1681 bool Matcher::float_in_double() { return false; } 1682 1683 // Do ints take an entire long register or just half? 1684 const bool Matcher::int_in_long = true; 1685 1686 // Return whether or not this register is ever used as an argument. 1687 // This function is used on startup to build the trampoline stubs in 1688 // generateOptoStub. Registers not mentioned will be killed by the VM 1689 // call in the trampoline, and arguments in those registers not be 1690 // available to the callee. 1691 bool Matcher::can_be_java_arg(int reg) 1692 { 1693 return 1694 reg == RDI_num || reg == RDI_H_num || 1695 reg == RSI_num || reg == RSI_H_num || 1696 reg == RDX_num || reg == RDX_H_num || 1697 reg == RCX_num || reg == RCX_H_num || 1698 reg == R8_num || reg == R8_H_num || 1699 reg == R9_num || reg == R9_H_num || 1700 reg == R12_num || reg == R12_H_num || 1701 reg == XMM0_num || reg == XMM0b_num || 1702 reg == XMM1_num || reg == XMM1b_num || 1703 reg == XMM2_num || reg == XMM2b_num || 1704 reg == XMM3_num || reg == XMM3b_num || 1705 reg == XMM4_num || reg == XMM4b_num || 1706 reg == XMM5_num || reg == XMM5b_num || 1707 reg == XMM6_num || reg == XMM6b_num || 1708 reg == XMM7_num || reg == XMM7b_num; 1709 } 1710 1711 bool Matcher::is_spillable_arg(int reg) 1712 { 1713 return can_be_java_arg(reg); 1714 } 1715 1716 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1717 // In 64 bit mode a code which use multiply when 1718 // devisor is constant is faster than hardware 1719 // DIV instruction (it uses MulHiL). 1720 return false; 1721 } 1722 1723 // Register for DIVI projection of divmodI 1724 RegMask Matcher::divI_proj_mask() { 1725 return INT_RAX_REG_mask(); 1726 } 1727 1728 // Register for MODI projection of divmodI 1729 RegMask Matcher::modI_proj_mask() { 1730 return INT_RDX_REG_mask(); 1731 } 1732 1733 // Register for DIVL projection of divmodL 1734 RegMask Matcher::divL_proj_mask() { 1735 return LONG_RAX_REG_mask(); 1736 } 1737 1738 // Register for MODL projection of divmodL 1739 RegMask Matcher::modL_proj_mask() { 1740 return LONG_RDX_REG_mask(); 1741 } 1742 1743 // Register for saving SP into on method handle invokes. Not used on x86_64. 1744 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1745 return NO_REG_mask(); 1746 } 1747 1748 %} 1749 1750 //----------ENCODING BLOCK----------------------------------------------------- 1751 // This block specifies the encoding classes used by the compiler to 1752 // output byte streams. Encoding classes are parameterized macros 1753 // used by Machine Instruction Nodes in order to generate the bit 1754 // encoding of the instruction. Operands specify their base encoding 1755 // interface with the interface keyword. There are currently 1756 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1757 // COND_INTER. REG_INTER causes an operand to generate a function 1758 // which returns its register number when queried. CONST_INTER causes 1759 // an operand to generate a function which returns the value of the 1760 // constant when queried. MEMORY_INTER causes an operand to generate 1761 // four functions which return the Base Register, the Index Register, 1762 // the Scale Value, and the Offset Value of the operand when queried. 1763 // COND_INTER causes an operand to generate six functions which return 1764 // the encoding code (ie - encoding bits for the instruction) 1765 // associated with each basic boolean condition for a conditional 1766 // instruction. 1767 // 1768 // Instructions specify two basic values for encoding. Again, a 1769 // function is available to check if the constant displacement is an 1770 // oop. They use the ins_encode keyword to specify their encoding 1771 // classes (which must be a sequence of enc_class names, and their 1772 // parameters, specified in the encoding block), and they use the 1773 // opcode keyword to specify, in order, their primary, secondary, and 1774 // tertiary opcode. Only the opcode sections which a particular 1775 // instruction needs for encoding need to be specified. 1776 encode %{ 1777 // Build emit functions for each basic byte or larger field in the 1778 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1779 // from C++ code in the enc_class source block. Emit functions will 1780 // live in the main source block for now. In future, we can 1781 // generalize this by adding a syntax that specifies the sizes of 1782 // fields in an order, so that the adlc can build the emit functions 1783 // automagically 1784 1785 // Emit primary opcode 1786 enc_class OpcP 1787 %{ 1788 emit_opcode(cbuf, $primary); 1789 %} 1790 1791 // Emit secondary opcode 1792 enc_class OpcS 1793 %{ 1794 emit_opcode(cbuf, $secondary); 1795 %} 1796 1797 // Emit tertiary opcode 1798 enc_class OpcT 1799 %{ 1800 emit_opcode(cbuf, $tertiary); 1801 %} 1802 1803 // Emit opcode directly 1804 enc_class Opcode(immI d8) 1805 %{ 1806 emit_opcode(cbuf, $d8$$constant); 1807 %} 1808 1809 // Emit size prefix 1810 enc_class SizePrefix 1811 %{ 1812 emit_opcode(cbuf, 0x66); 1813 %} 1814 1815 enc_class reg(rRegI reg) 1816 %{ 1817 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1818 %} 1819 1820 enc_class reg_reg(rRegI dst, rRegI src) 1821 %{ 1822 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1823 %} 1824 1825 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1826 %{ 1827 emit_opcode(cbuf, $opcode$$constant); 1828 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1829 %} 1830 1831 enc_class cdql_enc(no_rax_rdx_RegI div) 1832 %{ 1833 // Full implementation of Java idiv and irem; checks for 1834 // special case as described in JVM spec., p.243 & p.271. 1835 // 1836 // normal case special case 1837 // 1838 // input : rax: dividend min_int 1839 // reg: divisor -1 1840 // 1841 // output: rax: quotient (= rax idiv reg) min_int 1842 // rdx: remainder (= rax irem reg) 0 1843 // 1844 // Code sequnce: 1845 // 1846 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1847 // 5: 75 07/08 jne e <normal> 1848 // 7: 33 d2 xor %edx,%edx 1849 // [div >= 8 -> offset + 1] 1850 // [REX_B] 1851 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1852 // c: 74 03/04 je 11 <done> 1853 // 000000000000000e <normal>: 1854 // e: 99 cltd 1855 // [div >= 8 -> offset + 1] 1856 // [REX_B] 1857 // f: f7 f9 idiv $div 1858 // 0000000000000011 <done>: 1859 1860 // cmp $0x80000000,%eax 1861 emit_opcode(cbuf, 0x3d); 1862 emit_d8(cbuf, 0x00); 1863 emit_d8(cbuf, 0x00); 1864 emit_d8(cbuf, 0x00); 1865 emit_d8(cbuf, 0x80); 1866 1867 // jne e <normal> 1868 emit_opcode(cbuf, 0x75); 1869 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1870 1871 // xor %edx,%edx 1872 emit_opcode(cbuf, 0x33); 1873 emit_d8(cbuf, 0xD2); 1874 1875 // cmp $0xffffffffffffffff,%ecx 1876 if ($div$$reg >= 8) { 1877 emit_opcode(cbuf, Assembler::REX_B); 1878 } 1879 emit_opcode(cbuf, 0x83); 1880 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1881 emit_d8(cbuf, 0xFF); 1882 1883 // je 11 <done> 1884 emit_opcode(cbuf, 0x74); 1885 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1886 1887 // <normal> 1888 // cltd 1889 emit_opcode(cbuf, 0x99); 1890 1891 // idivl (note: must be emitted by the user of this rule) 1892 // <done> 1893 %} 1894 1895 enc_class cdqq_enc(no_rax_rdx_RegL div) 1896 %{ 1897 // Full implementation of Java ldiv and lrem; checks for 1898 // special case as described in JVM spec., p.243 & p.271. 1899 // 1900 // normal case special case 1901 // 1902 // input : rax: dividend min_long 1903 // reg: divisor -1 1904 // 1905 // output: rax: quotient (= rax idiv reg) min_long 1906 // rdx: remainder (= rax irem reg) 0 1907 // 1908 // Code sequnce: 1909 // 1910 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1911 // 7: 00 00 80 1912 // a: 48 39 d0 cmp %rdx,%rax 1913 // d: 75 08 jne 17 <normal> 1914 // f: 33 d2 xor %edx,%edx 1915 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1916 // 15: 74 05 je 1c <done> 1917 // 0000000000000017 <normal>: 1918 // 17: 48 99 cqto 1919 // 19: 48 f7 f9 idiv $div 1920 // 000000000000001c <done>: 1921 1922 // mov $0x8000000000000000,%rdx 1923 emit_opcode(cbuf, Assembler::REX_W); 1924 emit_opcode(cbuf, 0xBA); 1925 emit_d8(cbuf, 0x00); 1926 emit_d8(cbuf, 0x00); 1927 emit_d8(cbuf, 0x00); 1928 emit_d8(cbuf, 0x00); 1929 emit_d8(cbuf, 0x00); 1930 emit_d8(cbuf, 0x00); 1931 emit_d8(cbuf, 0x00); 1932 emit_d8(cbuf, 0x80); 1933 1934 // cmp %rdx,%rax 1935 emit_opcode(cbuf, Assembler::REX_W); 1936 emit_opcode(cbuf, 0x39); 1937 emit_d8(cbuf, 0xD0); 1938 1939 // jne 17 <normal> 1940 emit_opcode(cbuf, 0x75); 1941 emit_d8(cbuf, 0x08); 1942 1943 // xor %edx,%edx 1944 emit_opcode(cbuf, 0x33); 1945 emit_d8(cbuf, 0xD2); 1946 1947 // cmp $0xffffffffffffffff,$div 1948 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1949 emit_opcode(cbuf, 0x83); 1950 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1951 emit_d8(cbuf, 0xFF); 1952 1953 // je 1e <done> 1954 emit_opcode(cbuf, 0x74); 1955 emit_d8(cbuf, 0x05); 1956 1957 // <normal> 1958 // cqto 1959 emit_opcode(cbuf, Assembler::REX_W); 1960 emit_opcode(cbuf, 0x99); 1961 1962 // idivq (note: must be emitted by the user of this rule) 1963 // <done> 1964 %} 1965 1966 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1967 enc_class OpcSE(immI imm) 1968 %{ 1969 // Emit primary opcode and set sign-extend bit 1970 // Check for 8-bit immediate, and set sign extend bit in opcode 1971 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1972 emit_opcode(cbuf, $primary | 0x02); 1973 } else { 1974 // 32-bit immediate 1975 emit_opcode(cbuf, $primary); 1976 } 1977 %} 1978 1979 enc_class OpcSErm(rRegI dst, immI imm) 1980 %{ 1981 // OpcSEr/m 1982 int dstenc = $dst$$reg; 1983 if (dstenc >= 8) { 1984 emit_opcode(cbuf, Assembler::REX_B); 1985 dstenc -= 8; 1986 } 1987 // Emit primary opcode and set sign-extend bit 1988 // Check for 8-bit immediate, and set sign extend bit in opcode 1989 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1990 emit_opcode(cbuf, $primary | 0x02); 1991 } else { 1992 // 32-bit immediate 1993 emit_opcode(cbuf, $primary); 1994 } 1995 // Emit r/m byte with secondary opcode, after primary opcode. 1996 emit_rm(cbuf, 0x3, $secondary, dstenc); 1997 %} 1998 1999 enc_class OpcSErm_wide(rRegL dst, immI imm) 2000 %{ 2001 // OpcSEr/m 2002 int dstenc = $dst$$reg; 2003 if (dstenc < 8) { 2004 emit_opcode(cbuf, Assembler::REX_W); 2005 } else { 2006 emit_opcode(cbuf, Assembler::REX_WB); 2007 dstenc -= 8; 2008 } 2009 // Emit primary opcode and set sign-extend bit 2010 // Check for 8-bit immediate, and set sign extend bit in opcode 2011 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2012 emit_opcode(cbuf, $primary | 0x02); 2013 } else { 2014 // 32-bit immediate 2015 emit_opcode(cbuf, $primary); 2016 } 2017 // Emit r/m byte with secondary opcode, after primary opcode. 2018 emit_rm(cbuf, 0x3, $secondary, dstenc); 2019 %} 2020 2021 enc_class Con8or32(immI imm) 2022 %{ 2023 // Check for 8-bit immediate, and set sign extend bit in opcode 2024 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2025 $$$emit8$imm$$constant; 2026 } else { 2027 // 32-bit immediate 2028 $$$emit32$imm$$constant; 2029 } 2030 %} 2031 2032 enc_class opc2_reg(rRegI dst) 2033 %{ 2034 // BSWAP 2035 emit_cc(cbuf, $secondary, $dst$$reg); 2036 %} 2037 2038 enc_class opc3_reg(rRegI dst) 2039 %{ 2040 // BSWAP 2041 emit_cc(cbuf, $tertiary, $dst$$reg); 2042 %} 2043 2044 enc_class reg_opc(rRegI div) 2045 %{ 2046 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2047 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2048 %} 2049 2050 enc_class enc_cmov(cmpOp cop) 2051 %{ 2052 // CMOV 2053 $$$emit8$primary; 2054 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2055 %} 2056 2057 enc_class enc_PartialSubtypeCheck() 2058 %{ 2059 Register Rrdi = as_Register(RDI_enc); // result register 2060 Register Rrax = as_Register(RAX_enc); // super class 2061 Register Rrcx = as_Register(RCX_enc); // killed 2062 Register Rrsi = as_Register(RSI_enc); // sub class 2063 Label miss; 2064 const bool set_cond_codes = true; 2065 2066 MacroAssembler _masm(&cbuf); 2067 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2068 NULL, &miss, 2069 /*set_cond_codes:*/ true); 2070 if ($primary) { 2071 __ xorptr(Rrdi, Rrdi); 2072 } 2073 __ bind(miss); 2074 %} 2075 2076 enc_class clear_avx %{ 2077 debug_only(int off0 = cbuf.insts_size()); 2078 if (ra_->C->max_vector_size() > 16) { 2079 // Clear upper bits of YMM registers when current compiled code uses 2080 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2081 MacroAssembler _masm(&cbuf); 2082 __ vzeroupper(); 2083 } 2084 debug_only(int off1 = cbuf.insts_size()); 2085 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2086 %} 2087 2088 enc_class Java_To_Runtime(method meth) %{ 2089 // No relocation needed 2090 MacroAssembler _masm(&cbuf); 2091 __ mov64(r10, (int64_t) $meth$$method); 2092 __ call(r10); 2093 %} 2094 2095 enc_class Java_To_Interpreter(method meth) 2096 %{ 2097 // CALL Java_To_Interpreter 2098 // This is the instruction starting address for relocation info. 2099 cbuf.set_insts_mark(); 2100 $$$emit8$primary; 2101 // CALL directly to the runtime 2102 emit_d32_reloc(cbuf, 2103 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2104 runtime_call_Relocation::spec(), 2105 RELOC_DISP32); 2106 %} 2107 2108 enc_class Java_Static_Call(method meth) 2109 %{ 2110 // JAVA STATIC CALL 2111 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2112 // determine who we intended to call. 2113 cbuf.set_insts_mark(); 2114 $$$emit8$primary; 2115 2116 if (!_method) { 2117 emit_d32_reloc(cbuf, 2118 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2119 runtime_call_Relocation::spec(), 2120 RELOC_DISP32); 2121 } else if (_optimized_virtual) { 2122 emit_d32_reloc(cbuf, 2123 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2124 opt_virtual_call_Relocation::spec(), 2125 RELOC_DISP32); 2126 } else { 2127 emit_d32_reloc(cbuf, 2128 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2129 static_call_Relocation::spec(), 2130 RELOC_DISP32); 2131 } 2132 if (_method) { 2133 // Emit stub for static call. 2134 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 2135 if (stub == NULL) { 2136 ciEnv::current()->record_failure("CodeCache is full"); 2137 return; 2138 } 2139 } 2140 %} 2141 2142 enc_class Java_Dynamic_Call(method meth) %{ 2143 MacroAssembler _masm(&cbuf); 2144 __ ic_call((address)$meth$$method); 2145 %} 2146 2147 enc_class Java_Compiled_Call(method meth) 2148 %{ 2149 // JAVA COMPILED CALL 2150 int disp = in_bytes(Method:: from_compiled_offset()); 2151 2152 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2153 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2154 2155 // callq *disp(%rax) 2156 cbuf.set_insts_mark(); 2157 $$$emit8$primary; 2158 if (disp < 0x80) { 2159 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2160 emit_d8(cbuf, disp); // Displacement 2161 } else { 2162 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2163 emit_d32(cbuf, disp); // Displacement 2164 } 2165 %} 2166 2167 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2168 %{ 2169 // SAL, SAR, SHR 2170 int dstenc = $dst$$reg; 2171 if (dstenc >= 8) { 2172 emit_opcode(cbuf, Assembler::REX_B); 2173 dstenc -= 8; 2174 } 2175 $$$emit8$primary; 2176 emit_rm(cbuf, 0x3, $secondary, dstenc); 2177 $$$emit8$shift$$constant; 2178 %} 2179 2180 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2181 %{ 2182 // SAL, SAR, SHR 2183 int dstenc = $dst$$reg; 2184 if (dstenc < 8) { 2185 emit_opcode(cbuf, Assembler::REX_W); 2186 } else { 2187 emit_opcode(cbuf, Assembler::REX_WB); 2188 dstenc -= 8; 2189 } 2190 $$$emit8$primary; 2191 emit_rm(cbuf, 0x3, $secondary, dstenc); 2192 $$$emit8$shift$$constant; 2193 %} 2194 2195 enc_class load_immI(rRegI dst, immI src) 2196 %{ 2197 int dstenc = $dst$$reg; 2198 if (dstenc >= 8) { 2199 emit_opcode(cbuf, Assembler::REX_B); 2200 dstenc -= 8; 2201 } 2202 emit_opcode(cbuf, 0xB8 | dstenc); 2203 $$$emit32$src$$constant; 2204 %} 2205 2206 enc_class load_immL(rRegL dst, immL src) 2207 %{ 2208 int dstenc = $dst$$reg; 2209 if (dstenc < 8) { 2210 emit_opcode(cbuf, Assembler::REX_W); 2211 } else { 2212 emit_opcode(cbuf, Assembler::REX_WB); 2213 dstenc -= 8; 2214 } 2215 emit_opcode(cbuf, 0xB8 | dstenc); 2216 emit_d64(cbuf, $src$$constant); 2217 %} 2218 2219 enc_class load_immUL32(rRegL dst, immUL32 src) 2220 %{ 2221 // same as load_immI, but this time we care about zeroes in the high word 2222 int dstenc = $dst$$reg; 2223 if (dstenc >= 8) { 2224 emit_opcode(cbuf, Assembler::REX_B); 2225 dstenc -= 8; 2226 } 2227 emit_opcode(cbuf, 0xB8 | dstenc); 2228 $$$emit32$src$$constant; 2229 %} 2230 2231 enc_class load_immL32(rRegL dst, immL32 src) 2232 %{ 2233 int dstenc = $dst$$reg; 2234 if (dstenc < 8) { 2235 emit_opcode(cbuf, Assembler::REX_W); 2236 } else { 2237 emit_opcode(cbuf, Assembler::REX_WB); 2238 dstenc -= 8; 2239 } 2240 emit_opcode(cbuf, 0xC7); 2241 emit_rm(cbuf, 0x03, 0x00, dstenc); 2242 $$$emit32$src$$constant; 2243 %} 2244 2245 enc_class load_immP31(rRegP dst, immP32 src) 2246 %{ 2247 // same as load_immI, but this time we care about zeroes in the high word 2248 int dstenc = $dst$$reg; 2249 if (dstenc >= 8) { 2250 emit_opcode(cbuf, Assembler::REX_B); 2251 dstenc -= 8; 2252 } 2253 emit_opcode(cbuf, 0xB8 | dstenc); 2254 $$$emit32$src$$constant; 2255 %} 2256 2257 enc_class load_immP(rRegP dst, immP src) 2258 %{ 2259 int dstenc = $dst$$reg; 2260 if (dstenc < 8) { 2261 emit_opcode(cbuf, Assembler::REX_W); 2262 } else { 2263 emit_opcode(cbuf, Assembler::REX_WB); 2264 dstenc -= 8; 2265 } 2266 emit_opcode(cbuf, 0xB8 | dstenc); 2267 // This next line should be generated from ADLC 2268 if ($src->constant_reloc() != relocInfo::none) { 2269 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2270 } else { 2271 emit_d64(cbuf, $src$$constant); 2272 } 2273 %} 2274 2275 enc_class Con32(immI src) 2276 %{ 2277 // Output immediate 2278 $$$emit32$src$$constant; 2279 %} 2280 2281 enc_class Con32F_as_bits(immF src) 2282 %{ 2283 // Output Float immediate bits 2284 jfloat jf = $src$$constant; 2285 jint jf_as_bits = jint_cast(jf); 2286 emit_d32(cbuf, jf_as_bits); 2287 %} 2288 2289 enc_class Con16(immI src) 2290 %{ 2291 // Output immediate 2292 $$$emit16$src$$constant; 2293 %} 2294 2295 // How is this different from Con32??? XXX 2296 enc_class Con_d32(immI src) 2297 %{ 2298 emit_d32(cbuf,$src$$constant); 2299 %} 2300 2301 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2302 // Output immediate memory reference 2303 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2304 emit_d32(cbuf, 0x00); 2305 %} 2306 2307 enc_class lock_prefix() 2308 %{ 2309 if (os::is_MP()) { 2310 emit_opcode(cbuf, 0xF0); // lock 2311 } 2312 %} 2313 2314 enc_class REX_mem(memory mem) 2315 %{ 2316 if ($mem$$base >= 8) { 2317 if ($mem$$index < 8) { 2318 emit_opcode(cbuf, Assembler::REX_B); 2319 } else { 2320 emit_opcode(cbuf, Assembler::REX_XB); 2321 } 2322 } else { 2323 if ($mem$$index >= 8) { 2324 emit_opcode(cbuf, Assembler::REX_X); 2325 } 2326 } 2327 %} 2328 2329 enc_class REX_mem_wide(memory mem) 2330 %{ 2331 if ($mem$$base >= 8) { 2332 if ($mem$$index < 8) { 2333 emit_opcode(cbuf, Assembler::REX_WB); 2334 } else { 2335 emit_opcode(cbuf, Assembler::REX_WXB); 2336 } 2337 } else { 2338 if ($mem$$index < 8) { 2339 emit_opcode(cbuf, Assembler::REX_W); 2340 } else { 2341 emit_opcode(cbuf, Assembler::REX_WX); 2342 } 2343 } 2344 %} 2345 2346 // for byte regs 2347 enc_class REX_breg(rRegI reg) 2348 %{ 2349 if ($reg$$reg >= 4) { 2350 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2351 } 2352 %} 2353 2354 // for byte regs 2355 enc_class REX_reg_breg(rRegI dst, rRegI src) 2356 %{ 2357 if ($dst$$reg < 8) { 2358 if ($src$$reg >= 4) { 2359 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2360 } 2361 } else { 2362 if ($src$$reg < 8) { 2363 emit_opcode(cbuf, Assembler::REX_R); 2364 } else { 2365 emit_opcode(cbuf, Assembler::REX_RB); 2366 } 2367 } 2368 %} 2369 2370 // for byte regs 2371 enc_class REX_breg_mem(rRegI reg, memory mem) 2372 %{ 2373 if ($reg$$reg < 8) { 2374 if ($mem$$base < 8) { 2375 if ($mem$$index >= 8) { 2376 emit_opcode(cbuf, Assembler::REX_X); 2377 } else if ($reg$$reg >= 4) { 2378 emit_opcode(cbuf, Assembler::REX); 2379 } 2380 } else { 2381 if ($mem$$index < 8) { 2382 emit_opcode(cbuf, Assembler::REX_B); 2383 } else { 2384 emit_opcode(cbuf, Assembler::REX_XB); 2385 } 2386 } 2387 } else { 2388 if ($mem$$base < 8) { 2389 if ($mem$$index < 8) { 2390 emit_opcode(cbuf, Assembler::REX_R); 2391 } else { 2392 emit_opcode(cbuf, Assembler::REX_RX); 2393 } 2394 } else { 2395 if ($mem$$index < 8) { 2396 emit_opcode(cbuf, Assembler::REX_RB); 2397 } else { 2398 emit_opcode(cbuf, Assembler::REX_RXB); 2399 } 2400 } 2401 } 2402 %} 2403 2404 enc_class REX_reg(rRegI reg) 2405 %{ 2406 if ($reg$$reg >= 8) { 2407 emit_opcode(cbuf, Assembler::REX_B); 2408 } 2409 %} 2410 2411 enc_class REX_reg_wide(rRegI reg) 2412 %{ 2413 if ($reg$$reg < 8) { 2414 emit_opcode(cbuf, Assembler::REX_W); 2415 } else { 2416 emit_opcode(cbuf, Assembler::REX_WB); 2417 } 2418 %} 2419 2420 enc_class REX_reg_reg(rRegI dst, rRegI src) 2421 %{ 2422 if ($dst$$reg < 8) { 2423 if ($src$$reg >= 8) { 2424 emit_opcode(cbuf, Assembler::REX_B); 2425 } 2426 } else { 2427 if ($src$$reg < 8) { 2428 emit_opcode(cbuf, Assembler::REX_R); 2429 } else { 2430 emit_opcode(cbuf, Assembler::REX_RB); 2431 } 2432 } 2433 %} 2434 2435 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2436 %{ 2437 if ($dst$$reg < 8) { 2438 if ($src$$reg < 8) { 2439 emit_opcode(cbuf, Assembler::REX_W); 2440 } else { 2441 emit_opcode(cbuf, Assembler::REX_WB); 2442 } 2443 } else { 2444 if ($src$$reg < 8) { 2445 emit_opcode(cbuf, Assembler::REX_WR); 2446 } else { 2447 emit_opcode(cbuf, Assembler::REX_WRB); 2448 } 2449 } 2450 %} 2451 2452 enc_class REX_reg_mem(rRegI reg, memory mem) 2453 %{ 2454 if ($reg$$reg < 8) { 2455 if ($mem$$base < 8) { 2456 if ($mem$$index >= 8) { 2457 emit_opcode(cbuf, Assembler::REX_X); 2458 } 2459 } else { 2460 if ($mem$$index < 8) { 2461 emit_opcode(cbuf, Assembler::REX_B); 2462 } else { 2463 emit_opcode(cbuf, Assembler::REX_XB); 2464 } 2465 } 2466 } else { 2467 if ($mem$$base < 8) { 2468 if ($mem$$index < 8) { 2469 emit_opcode(cbuf, Assembler::REX_R); 2470 } else { 2471 emit_opcode(cbuf, Assembler::REX_RX); 2472 } 2473 } else { 2474 if ($mem$$index < 8) { 2475 emit_opcode(cbuf, Assembler::REX_RB); 2476 } else { 2477 emit_opcode(cbuf, Assembler::REX_RXB); 2478 } 2479 } 2480 } 2481 %} 2482 2483 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2484 %{ 2485 if ($reg$$reg < 8) { 2486 if ($mem$$base < 8) { 2487 if ($mem$$index < 8) { 2488 emit_opcode(cbuf, Assembler::REX_W); 2489 } else { 2490 emit_opcode(cbuf, Assembler::REX_WX); 2491 } 2492 } else { 2493 if ($mem$$index < 8) { 2494 emit_opcode(cbuf, Assembler::REX_WB); 2495 } else { 2496 emit_opcode(cbuf, Assembler::REX_WXB); 2497 } 2498 } 2499 } else { 2500 if ($mem$$base < 8) { 2501 if ($mem$$index < 8) { 2502 emit_opcode(cbuf, Assembler::REX_WR); 2503 } else { 2504 emit_opcode(cbuf, Assembler::REX_WRX); 2505 } 2506 } else { 2507 if ($mem$$index < 8) { 2508 emit_opcode(cbuf, Assembler::REX_WRB); 2509 } else { 2510 emit_opcode(cbuf, Assembler::REX_WRXB); 2511 } 2512 } 2513 } 2514 %} 2515 2516 enc_class reg_mem(rRegI ereg, memory mem) 2517 %{ 2518 // High registers handle in encode_RegMem 2519 int reg = $ereg$$reg; 2520 int base = $mem$$base; 2521 int index = $mem$$index; 2522 int scale = $mem$$scale; 2523 int disp = $mem$$disp; 2524 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2525 2526 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2527 %} 2528 2529 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2530 %{ 2531 int rm_byte_opcode = $rm_opcode$$constant; 2532 2533 // High registers handle in encode_RegMem 2534 int base = $mem$$base; 2535 int index = $mem$$index; 2536 int scale = $mem$$scale; 2537 int displace = $mem$$disp; 2538 2539 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2540 // working with static 2541 // globals 2542 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2543 disp_reloc); 2544 %} 2545 2546 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2547 %{ 2548 int reg_encoding = $dst$$reg; 2549 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2550 int index = 0x04; // 0x04 indicates no index 2551 int scale = 0x00; // 0x00 indicates no scale 2552 int displace = $src1$$constant; // 0x00 indicates no displacement 2553 relocInfo::relocType disp_reloc = relocInfo::none; 2554 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2555 disp_reloc); 2556 %} 2557 2558 enc_class neg_reg(rRegI dst) 2559 %{ 2560 int dstenc = $dst$$reg; 2561 if (dstenc >= 8) { 2562 emit_opcode(cbuf, Assembler::REX_B); 2563 dstenc -= 8; 2564 } 2565 // NEG $dst 2566 emit_opcode(cbuf, 0xF7); 2567 emit_rm(cbuf, 0x3, 0x03, dstenc); 2568 %} 2569 2570 enc_class neg_reg_wide(rRegI dst) 2571 %{ 2572 int dstenc = $dst$$reg; 2573 if (dstenc < 8) { 2574 emit_opcode(cbuf, Assembler::REX_W); 2575 } else { 2576 emit_opcode(cbuf, Assembler::REX_WB); 2577 dstenc -= 8; 2578 } 2579 // NEG $dst 2580 emit_opcode(cbuf, 0xF7); 2581 emit_rm(cbuf, 0x3, 0x03, dstenc); 2582 %} 2583 2584 enc_class setLT_reg(rRegI dst) 2585 %{ 2586 int dstenc = $dst$$reg; 2587 if (dstenc >= 8) { 2588 emit_opcode(cbuf, Assembler::REX_B); 2589 dstenc -= 8; 2590 } else if (dstenc >= 4) { 2591 emit_opcode(cbuf, Assembler::REX); 2592 } 2593 // SETLT $dst 2594 emit_opcode(cbuf, 0x0F); 2595 emit_opcode(cbuf, 0x9C); 2596 emit_rm(cbuf, 0x3, 0x0, dstenc); 2597 %} 2598 2599 enc_class setNZ_reg(rRegI dst) 2600 %{ 2601 int dstenc = $dst$$reg; 2602 if (dstenc >= 8) { 2603 emit_opcode(cbuf, Assembler::REX_B); 2604 dstenc -= 8; 2605 } else if (dstenc >= 4) { 2606 emit_opcode(cbuf, Assembler::REX); 2607 } 2608 // SETNZ $dst 2609 emit_opcode(cbuf, 0x0F); 2610 emit_opcode(cbuf, 0x95); 2611 emit_rm(cbuf, 0x3, 0x0, dstenc); 2612 %} 2613 2614 2615 // Compare the lonogs and set -1, 0, or 1 into dst 2616 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2617 %{ 2618 int src1enc = $src1$$reg; 2619 int src2enc = $src2$$reg; 2620 int dstenc = $dst$$reg; 2621 2622 // cmpq $src1, $src2 2623 if (src1enc < 8) { 2624 if (src2enc < 8) { 2625 emit_opcode(cbuf, Assembler::REX_W); 2626 } else { 2627 emit_opcode(cbuf, Assembler::REX_WB); 2628 } 2629 } else { 2630 if (src2enc < 8) { 2631 emit_opcode(cbuf, Assembler::REX_WR); 2632 } else { 2633 emit_opcode(cbuf, Assembler::REX_WRB); 2634 } 2635 } 2636 emit_opcode(cbuf, 0x3B); 2637 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2638 2639 // movl $dst, -1 2640 if (dstenc >= 8) { 2641 emit_opcode(cbuf, Assembler::REX_B); 2642 } 2643 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2644 emit_d32(cbuf, -1); 2645 2646 // jl,s done 2647 emit_opcode(cbuf, 0x7C); 2648 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2649 2650 // setne $dst 2651 if (dstenc >= 4) { 2652 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2653 } 2654 emit_opcode(cbuf, 0x0F); 2655 emit_opcode(cbuf, 0x95); 2656 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2657 2658 // movzbl $dst, $dst 2659 if (dstenc >= 4) { 2660 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2661 } 2662 emit_opcode(cbuf, 0x0F); 2663 emit_opcode(cbuf, 0xB6); 2664 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2665 %} 2666 2667 enc_class Push_ResultXD(regD dst) %{ 2668 MacroAssembler _masm(&cbuf); 2669 __ fstp_d(Address(rsp, 0)); 2670 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2671 __ addptr(rsp, 8); 2672 %} 2673 2674 enc_class Push_SrcXD(regD src) %{ 2675 MacroAssembler _masm(&cbuf); 2676 __ subptr(rsp, 8); 2677 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2678 __ fld_d(Address(rsp, 0)); 2679 %} 2680 2681 2682 enc_class enc_rethrow() 2683 %{ 2684 cbuf.set_insts_mark(); 2685 emit_opcode(cbuf, 0xE9); // jmp entry 2686 emit_d32_reloc(cbuf, 2687 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2688 runtime_call_Relocation::spec(), 2689 RELOC_DISP32); 2690 %} 2691 2692 %} 2693 2694 2695 2696 //----------FRAME-------------------------------------------------------------- 2697 // Definition of frame structure and management information. 2698 // 2699 // S T A C K L A Y O U T Allocators stack-slot number 2700 // | (to get allocators register number 2701 // G Owned by | | v add OptoReg::stack0()) 2702 // r CALLER | | 2703 // o | +--------+ pad to even-align allocators stack-slot 2704 // w V | pad0 | numbers; owned by CALLER 2705 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2706 // h ^ | in | 5 2707 // | | args | 4 Holes in incoming args owned by SELF 2708 // | | | | 3 2709 // | | +--------+ 2710 // V | | old out| Empty on Intel, window on Sparc 2711 // | old |preserve| Must be even aligned. 2712 // | SP-+--------+----> Matcher::_old_SP, even aligned 2713 // | | in | 3 area for Intel ret address 2714 // Owned by |preserve| Empty on Sparc. 2715 // SELF +--------+ 2716 // | | pad2 | 2 pad to align old SP 2717 // | +--------+ 1 2718 // | | locks | 0 2719 // | +--------+----> OptoReg::stack0(), even aligned 2720 // | | pad1 | 11 pad to align new SP 2721 // | +--------+ 2722 // | | | 10 2723 // | | spills | 9 spills 2724 // V | | 8 (pad0 slot for callee) 2725 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2726 // ^ | out | 7 2727 // | | args | 6 Holes in outgoing args owned by CALLEE 2728 // Owned by +--------+ 2729 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2730 // | new |preserve| Must be even-aligned. 2731 // | SP-+--------+----> Matcher::_new_SP, even aligned 2732 // | | | 2733 // 2734 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2735 // known from SELF's arguments and the Java calling convention. 2736 // Region 6-7 is determined per call site. 2737 // Note 2: If the calling convention leaves holes in the incoming argument 2738 // area, those holes are owned by SELF. Holes in the outgoing area 2739 // are owned by the CALLEE. Holes should not be nessecary in the 2740 // incoming area, as the Java calling convention is completely under 2741 // the control of the AD file. Doubles can be sorted and packed to 2742 // avoid holes. Holes in the outgoing arguments may be nessecary for 2743 // varargs C calling conventions. 2744 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2745 // even aligned with pad0 as needed. 2746 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2747 // region 6-11 is even aligned; it may be padded out more so that 2748 // the region from SP to FP meets the minimum stack alignment. 2749 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2750 // alignment. Region 11, pad1, may be dynamically extended so that 2751 // SP meets the minimum alignment. 2752 2753 frame 2754 %{ 2755 // What direction does stack grow in (assumed to be same for C & Java) 2756 stack_direction(TOWARDS_LOW); 2757 2758 // These three registers define part of the calling convention 2759 // between compiled code and the interpreter. 2760 inline_cache_reg(RAX); // Inline Cache Register 2761 interpreter_method_oop_reg(RBX); // Method Oop Register when 2762 // calling interpreter 2763 2764 // Optional: name the operand used by cisc-spilling to access 2765 // [stack_pointer + offset] 2766 cisc_spilling_operand_name(indOffset32); 2767 2768 // Number of stack slots consumed by locking an object 2769 sync_stack_slots(2); 2770 2771 // Compiled code's Frame Pointer 2772 frame_pointer(RSP); 2773 2774 // Interpreter stores its frame pointer in a register which is 2775 // stored to the stack by I2CAdaptors. 2776 // I2CAdaptors convert from interpreted java to compiled java. 2777 interpreter_frame_pointer(RBP); 2778 2779 // Stack alignment requirement 2780 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2781 2782 // Number of stack slots between incoming argument block and the start of 2783 // a new frame. The PROLOG must add this many slots to the stack. The 2784 // EPILOG must remove this many slots. amd64 needs two slots for 2785 // return address. 2786 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2787 2788 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2789 // for calls to C. Supports the var-args backing area for register parms. 2790 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2791 2792 // The after-PROLOG location of the return address. Location of 2793 // return address specifies a type (REG or STACK) and a number 2794 // representing the register number (i.e. - use a register name) or 2795 // stack slot. 2796 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2797 // Otherwise, it is above the locks and verification slot and alignment word 2798 return_addr(STACK - 2 + 2799 round_to((Compile::current()->in_preserve_stack_slots() + 2800 Compile::current()->fixed_slots()), 2801 stack_alignment_in_slots())); 2802 2803 // Body of function which returns an integer array locating 2804 // arguments either in registers or in stack slots. Passed an array 2805 // of ideal registers called "sig" and a "length" count. Stack-slot 2806 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2807 // arguments for a CALLEE. Incoming stack arguments are 2808 // automatically biased by the preserve_stack_slots field above. 2809 2810 calling_convention 2811 %{ 2812 // No difference between ingoing/outgoing just pass false 2813 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2814 %} 2815 2816 c_calling_convention 2817 %{ 2818 // This is obviously always outgoing 2819 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2820 %} 2821 2822 // Location of compiled Java return values. Same as C for now. 2823 return_value 2824 %{ 2825 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2826 "only return normal values"); 2827 2828 static const int lo[Op_RegL + 1] = { 2829 0, 2830 0, 2831 RAX_num, // Op_RegN 2832 RAX_num, // Op_RegI 2833 RAX_num, // Op_RegP 2834 XMM0_num, // Op_RegF 2835 XMM0_num, // Op_RegD 2836 RAX_num // Op_RegL 2837 }; 2838 static const int hi[Op_RegL + 1] = { 2839 0, 2840 0, 2841 OptoReg::Bad, // Op_RegN 2842 OptoReg::Bad, // Op_RegI 2843 RAX_H_num, // Op_RegP 2844 OptoReg::Bad, // Op_RegF 2845 XMM0b_num, // Op_RegD 2846 RAX_H_num // Op_RegL 2847 }; 2848 // Excluded flags and vector registers. 2849 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type"); 2850 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2851 %} 2852 %} 2853 2854 //----------ATTRIBUTES--------------------------------------------------------- 2855 //----------Operand Attributes------------------------------------------------- 2856 op_attrib op_cost(0); // Required cost attribute 2857 2858 //----------Instruction Attributes--------------------------------------------- 2859 ins_attrib ins_cost(100); // Required cost attribute 2860 ins_attrib ins_size(8); // Required size attribute (in bits) 2861 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2862 // a non-matching short branch variant 2863 // of some long branch? 2864 ins_attrib ins_alignment(1); // Required alignment attribute (must 2865 // be a power of 2) specifies the 2866 // alignment that some part of the 2867 // instruction (not necessarily the 2868 // start) requires. If > 1, a 2869 // compute_padding() function must be 2870 // provided for the instruction 2871 2872 //----------OPERANDS----------------------------------------------------------- 2873 // Operand definitions must precede instruction definitions for correct parsing 2874 // in the ADLC because operands constitute user defined types which are used in 2875 // instruction definitions. 2876 2877 //----------Simple Operands---------------------------------------------------- 2878 // Immediate Operands 2879 // Integer Immediate 2880 operand immI() 2881 %{ 2882 match(ConI); 2883 2884 op_cost(10); 2885 format %{ %} 2886 interface(CONST_INTER); 2887 %} 2888 2889 // Constant for test vs zero 2890 operand immI0() 2891 %{ 2892 predicate(n->get_int() == 0); 2893 match(ConI); 2894 2895 op_cost(0); 2896 format %{ %} 2897 interface(CONST_INTER); 2898 %} 2899 2900 // Constant for increment 2901 operand immI1() 2902 %{ 2903 predicate(n->get_int() == 1); 2904 match(ConI); 2905 2906 op_cost(0); 2907 format %{ %} 2908 interface(CONST_INTER); 2909 %} 2910 2911 // Constant for decrement 2912 operand immI_M1() 2913 %{ 2914 predicate(n->get_int() == -1); 2915 match(ConI); 2916 2917 op_cost(0); 2918 format %{ %} 2919 interface(CONST_INTER); 2920 %} 2921 2922 // Valid scale values for addressing modes 2923 operand immI2() 2924 %{ 2925 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2926 match(ConI); 2927 2928 format %{ %} 2929 interface(CONST_INTER); 2930 %} 2931 2932 operand immI8() 2933 %{ 2934 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2935 match(ConI); 2936 2937 op_cost(5); 2938 format %{ %} 2939 interface(CONST_INTER); 2940 %} 2941 2942 operand immU8() 2943 %{ 2944 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2945 match(ConI); 2946 2947 op_cost(5); 2948 format %{ %} 2949 interface(CONST_INTER); 2950 %} 2951 2952 operand immI16() 2953 %{ 2954 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2955 match(ConI); 2956 2957 op_cost(10); 2958 format %{ %} 2959 interface(CONST_INTER); 2960 %} 2961 2962 // Int Immediate non-negative 2963 operand immU31() 2964 %{ 2965 predicate(n->get_int() >= 0); 2966 match(ConI); 2967 2968 op_cost(0); 2969 format %{ %} 2970 interface(CONST_INTER); 2971 %} 2972 2973 // Constant for long shifts 2974 operand immI_32() 2975 %{ 2976 predicate( n->get_int() == 32 ); 2977 match(ConI); 2978 2979 op_cost(0); 2980 format %{ %} 2981 interface(CONST_INTER); 2982 %} 2983 2984 // Constant for long shifts 2985 operand immI_64() 2986 %{ 2987 predicate( n->get_int() == 64 ); 2988 match(ConI); 2989 2990 op_cost(0); 2991 format %{ %} 2992 interface(CONST_INTER); 2993 %} 2994 2995 // Pointer Immediate 2996 operand immP() 2997 %{ 2998 match(ConP); 2999 3000 op_cost(10); 3001 format %{ %} 3002 interface(CONST_INTER); 3003 %} 3004 3005 // NULL Pointer Immediate 3006 operand immP0() 3007 %{ 3008 predicate(n->get_ptr() == 0); 3009 match(ConP); 3010 3011 op_cost(5); 3012 format %{ %} 3013 interface(CONST_INTER); 3014 %} 3015 3016 // Pointer Immediate 3017 operand immN() %{ 3018 match(ConN); 3019 3020 op_cost(10); 3021 format %{ %} 3022 interface(CONST_INTER); 3023 %} 3024 3025 operand immNKlass() %{ 3026 match(ConNKlass); 3027 3028 op_cost(10); 3029 format %{ %} 3030 interface(CONST_INTER); 3031 %} 3032 3033 // NULL Pointer Immediate 3034 operand immN0() %{ 3035 predicate(n->get_narrowcon() == 0); 3036 match(ConN); 3037 3038 op_cost(5); 3039 format %{ %} 3040 interface(CONST_INTER); 3041 %} 3042 3043 operand immP31() 3044 %{ 3045 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3046 && (n->get_ptr() >> 31) == 0); 3047 match(ConP); 3048 3049 op_cost(5); 3050 format %{ %} 3051 interface(CONST_INTER); 3052 %} 3053 3054 3055 // Long Immediate 3056 operand immL() 3057 %{ 3058 match(ConL); 3059 3060 op_cost(20); 3061 format %{ %} 3062 interface(CONST_INTER); 3063 %} 3064 3065 // Long Immediate 8-bit 3066 operand immL8() 3067 %{ 3068 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3069 match(ConL); 3070 3071 op_cost(5); 3072 format %{ %} 3073 interface(CONST_INTER); 3074 %} 3075 3076 // Long Immediate 32-bit unsigned 3077 operand immUL32() 3078 %{ 3079 predicate(n->get_long() == (unsigned int) (n->get_long())); 3080 match(ConL); 3081 3082 op_cost(10); 3083 format %{ %} 3084 interface(CONST_INTER); 3085 %} 3086 3087 // Long Immediate 32-bit signed 3088 operand immL32() 3089 %{ 3090 predicate(n->get_long() == (int) (n->get_long())); 3091 match(ConL); 3092 3093 op_cost(15); 3094 format %{ %} 3095 interface(CONST_INTER); 3096 %} 3097 3098 // Long Immediate zero 3099 operand immL0() 3100 %{ 3101 predicate(n->get_long() == 0L); 3102 match(ConL); 3103 3104 op_cost(10); 3105 format %{ %} 3106 interface(CONST_INTER); 3107 %} 3108 3109 // Constant for increment 3110 operand immL1() 3111 %{ 3112 predicate(n->get_long() == 1); 3113 match(ConL); 3114 3115 format %{ %} 3116 interface(CONST_INTER); 3117 %} 3118 3119 // Constant for decrement 3120 operand immL_M1() 3121 %{ 3122 predicate(n->get_long() == -1); 3123 match(ConL); 3124 3125 format %{ %} 3126 interface(CONST_INTER); 3127 %} 3128 3129 // Long Immediate: the value 10 3130 operand immL10() 3131 %{ 3132 predicate(n->get_long() == 10); 3133 match(ConL); 3134 3135 format %{ %} 3136 interface(CONST_INTER); 3137 %} 3138 3139 // Long immediate from 0 to 127. 3140 // Used for a shorter form of long mul by 10. 3141 operand immL_127() 3142 %{ 3143 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3144 match(ConL); 3145 3146 op_cost(10); 3147 format %{ %} 3148 interface(CONST_INTER); 3149 %} 3150 3151 // Long Immediate: low 32-bit mask 3152 operand immL_32bits() 3153 %{ 3154 predicate(n->get_long() == 0xFFFFFFFFL); 3155 match(ConL); 3156 op_cost(20); 3157 3158 format %{ %} 3159 interface(CONST_INTER); 3160 %} 3161 3162 // Float Immediate zero 3163 operand immF0() 3164 %{ 3165 predicate(jint_cast(n->getf()) == 0); 3166 match(ConF); 3167 3168 op_cost(5); 3169 format %{ %} 3170 interface(CONST_INTER); 3171 %} 3172 3173 // Float Immediate 3174 operand immF() 3175 %{ 3176 match(ConF); 3177 3178 op_cost(15); 3179 format %{ %} 3180 interface(CONST_INTER); 3181 %} 3182 3183 // Double Immediate zero 3184 operand immD0() 3185 %{ 3186 predicate(jlong_cast(n->getd()) == 0); 3187 match(ConD); 3188 3189 op_cost(5); 3190 format %{ %} 3191 interface(CONST_INTER); 3192 %} 3193 3194 // Double Immediate 3195 operand immD() 3196 %{ 3197 match(ConD); 3198 3199 op_cost(15); 3200 format %{ %} 3201 interface(CONST_INTER); 3202 %} 3203 3204 // Immediates for special shifts (sign extend) 3205 3206 // Constants for increment 3207 operand immI_16() 3208 %{ 3209 predicate(n->get_int() == 16); 3210 match(ConI); 3211 3212 format %{ %} 3213 interface(CONST_INTER); 3214 %} 3215 3216 operand immI_24() 3217 %{ 3218 predicate(n->get_int() == 24); 3219 match(ConI); 3220 3221 format %{ %} 3222 interface(CONST_INTER); 3223 %} 3224 3225 // Constant for byte-wide masking 3226 operand immI_255() 3227 %{ 3228 predicate(n->get_int() == 255); 3229 match(ConI); 3230 3231 format %{ %} 3232 interface(CONST_INTER); 3233 %} 3234 3235 // Constant for short-wide masking 3236 operand immI_65535() 3237 %{ 3238 predicate(n->get_int() == 65535); 3239 match(ConI); 3240 3241 format %{ %} 3242 interface(CONST_INTER); 3243 %} 3244 3245 // Constant for byte-wide masking 3246 operand immL_255() 3247 %{ 3248 predicate(n->get_long() == 255); 3249 match(ConL); 3250 3251 format %{ %} 3252 interface(CONST_INTER); 3253 %} 3254 3255 // Constant for short-wide masking 3256 operand immL_65535() 3257 %{ 3258 predicate(n->get_long() == 65535); 3259 match(ConL); 3260 3261 format %{ %} 3262 interface(CONST_INTER); 3263 %} 3264 3265 // Register Operands 3266 // Integer Register 3267 operand rRegI() 3268 %{ 3269 constraint(ALLOC_IN_RC(int_reg)); 3270 match(RegI); 3271 3272 match(rax_RegI); 3273 match(rbx_RegI); 3274 match(rcx_RegI); 3275 match(rdx_RegI); 3276 match(rdi_RegI); 3277 3278 format %{ %} 3279 interface(REG_INTER); 3280 %} 3281 3282 // Special Registers 3283 operand rax_RegI() 3284 %{ 3285 constraint(ALLOC_IN_RC(int_rax_reg)); 3286 match(RegI); 3287 match(rRegI); 3288 3289 format %{ "RAX" %} 3290 interface(REG_INTER); 3291 %} 3292 3293 // Special Registers 3294 operand rbx_RegI() 3295 %{ 3296 constraint(ALLOC_IN_RC(int_rbx_reg)); 3297 match(RegI); 3298 match(rRegI); 3299 3300 format %{ "RBX" %} 3301 interface(REG_INTER); 3302 %} 3303 3304 operand rcx_RegI() 3305 %{ 3306 constraint(ALLOC_IN_RC(int_rcx_reg)); 3307 match(RegI); 3308 match(rRegI); 3309 3310 format %{ "RCX" %} 3311 interface(REG_INTER); 3312 %} 3313 3314 operand rdx_RegI() 3315 %{ 3316 constraint(ALLOC_IN_RC(int_rdx_reg)); 3317 match(RegI); 3318 match(rRegI); 3319 3320 format %{ "RDX" %} 3321 interface(REG_INTER); 3322 %} 3323 3324 operand rdi_RegI() 3325 %{ 3326 constraint(ALLOC_IN_RC(int_rdi_reg)); 3327 match(RegI); 3328 match(rRegI); 3329 3330 format %{ "RDI" %} 3331 interface(REG_INTER); 3332 %} 3333 3334 operand no_rcx_RegI() 3335 %{ 3336 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3337 match(RegI); 3338 match(rax_RegI); 3339 match(rbx_RegI); 3340 match(rdx_RegI); 3341 match(rdi_RegI); 3342 3343 format %{ %} 3344 interface(REG_INTER); 3345 %} 3346 3347 operand no_rax_rdx_RegI() 3348 %{ 3349 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3350 match(RegI); 3351 match(rbx_RegI); 3352 match(rcx_RegI); 3353 match(rdi_RegI); 3354 3355 format %{ %} 3356 interface(REG_INTER); 3357 %} 3358 3359 // Pointer Register 3360 operand any_RegP() 3361 %{ 3362 constraint(ALLOC_IN_RC(any_reg)); 3363 match(RegP); 3364 match(rax_RegP); 3365 match(rbx_RegP); 3366 match(rdi_RegP); 3367 match(rsi_RegP); 3368 match(rbp_RegP); 3369 match(r15_RegP); 3370 match(rRegP); 3371 3372 format %{ %} 3373 interface(REG_INTER); 3374 %} 3375 3376 operand rRegP() 3377 %{ 3378 constraint(ALLOC_IN_RC(ptr_reg)); 3379 match(RegP); 3380 match(rax_RegP); 3381 match(rbx_RegP); 3382 match(rdi_RegP); 3383 match(rsi_RegP); 3384 match(rbp_RegP); // See Q&A below about 3385 match(r15_RegP); // r15_RegP and rbp_RegP. 3386 3387 format %{ %} 3388 interface(REG_INTER); 3389 %} 3390 3391 operand rRegN() %{ 3392 constraint(ALLOC_IN_RC(int_reg)); 3393 match(RegN); 3394 3395 format %{ %} 3396 interface(REG_INTER); 3397 %} 3398 3399 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3400 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3401 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3402 // The output of an instruction is controlled by the allocator, which respects 3403 // register class masks, not match rules. Unless an instruction mentions 3404 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3405 // by the allocator as an input. 3406 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3407 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3408 // result, RBP is not included in the output of the instruction either. 3409 3410 operand no_rax_RegP() 3411 %{ 3412 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3413 match(RegP); 3414 match(rbx_RegP); 3415 match(rsi_RegP); 3416 match(rdi_RegP); 3417 3418 format %{ %} 3419 interface(REG_INTER); 3420 %} 3421 3422 // This operand is not allowed to use RBP even if 3423 // RBP is not used to hold the frame pointer. 3424 operand no_rbp_RegP() 3425 %{ 3426 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3427 match(RegP); 3428 match(rbx_RegP); 3429 match(rsi_RegP); 3430 match(rdi_RegP); 3431 3432 format %{ %} 3433 interface(REG_INTER); 3434 %} 3435 3436 operand no_rax_rbx_RegP() 3437 %{ 3438 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3439 match(RegP); 3440 match(rsi_RegP); 3441 match(rdi_RegP); 3442 3443 format %{ %} 3444 interface(REG_INTER); 3445 %} 3446 3447 // Special Registers 3448 // Return a pointer value 3449 operand rax_RegP() 3450 %{ 3451 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3452 match(RegP); 3453 match(rRegP); 3454 3455 format %{ %} 3456 interface(REG_INTER); 3457 %} 3458 3459 // Special Registers 3460 // Return a compressed pointer value 3461 operand rax_RegN() 3462 %{ 3463 constraint(ALLOC_IN_RC(int_rax_reg)); 3464 match(RegN); 3465 match(rRegN); 3466 3467 format %{ %} 3468 interface(REG_INTER); 3469 %} 3470 3471 // Used in AtomicAdd 3472 operand rbx_RegP() 3473 %{ 3474 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3475 match(RegP); 3476 match(rRegP); 3477 3478 format %{ %} 3479 interface(REG_INTER); 3480 %} 3481 3482 operand rsi_RegP() 3483 %{ 3484 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3485 match(RegP); 3486 match(rRegP); 3487 3488 format %{ %} 3489 interface(REG_INTER); 3490 %} 3491 3492 // Used in rep stosq 3493 operand rdi_RegP() 3494 %{ 3495 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3496 match(RegP); 3497 match(rRegP); 3498 3499 format %{ %} 3500 interface(REG_INTER); 3501 %} 3502 3503 operand r15_RegP() 3504 %{ 3505 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3506 match(RegP); 3507 match(rRegP); 3508 3509 format %{ %} 3510 interface(REG_INTER); 3511 %} 3512 3513 operand rRegL() 3514 %{ 3515 constraint(ALLOC_IN_RC(long_reg)); 3516 match(RegL); 3517 match(rax_RegL); 3518 match(rdx_RegL); 3519 3520 format %{ %} 3521 interface(REG_INTER); 3522 %} 3523 3524 // Special Registers 3525 operand no_rax_rdx_RegL() 3526 %{ 3527 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3528 match(RegL); 3529 match(rRegL); 3530 3531 format %{ %} 3532 interface(REG_INTER); 3533 %} 3534 3535 operand no_rax_RegL() 3536 %{ 3537 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3538 match(RegL); 3539 match(rRegL); 3540 match(rdx_RegL); 3541 3542 format %{ %} 3543 interface(REG_INTER); 3544 %} 3545 3546 operand no_rcx_RegL() 3547 %{ 3548 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3549 match(RegL); 3550 match(rRegL); 3551 3552 format %{ %} 3553 interface(REG_INTER); 3554 %} 3555 3556 operand rax_RegL() 3557 %{ 3558 constraint(ALLOC_IN_RC(long_rax_reg)); 3559 match(RegL); 3560 match(rRegL); 3561 3562 format %{ "RAX" %} 3563 interface(REG_INTER); 3564 %} 3565 3566 operand rcx_RegL() 3567 %{ 3568 constraint(ALLOC_IN_RC(long_rcx_reg)); 3569 match(RegL); 3570 match(rRegL); 3571 3572 format %{ %} 3573 interface(REG_INTER); 3574 %} 3575 3576 operand rdx_RegL() 3577 %{ 3578 constraint(ALLOC_IN_RC(long_rdx_reg)); 3579 match(RegL); 3580 match(rRegL); 3581 3582 format %{ %} 3583 interface(REG_INTER); 3584 %} 3585 3586 // Flags register, used as output of compare instructions 3587 operand rFlagsReg() 3588 %{ 3589 constraint(ALLOC_IN_RC(int_flags)); 3590 match(RegFlags); 3591 3592 format %{ "RFLAGS" %} 3593 interface(REG_INTER); 3594 %} 3595 3596 // Flags register, used as output of FLOATING POINT compare instructions 3597 operand rFlagsRegU() 3598 %{ 3599 constraint(ALLOC_IN_RC(int_flags)); 3600 match(RegFlags); 3601 3602 format %{ "RFLAGS_U" %} 3603 interface(REG_INTER); 3604 %} 3605 3606 operand rFlagsRegUCF() %{ 3607 constraint(ALLOC_IN_RC(int_flags)); 3608 match(RegFlags); 3609 predicate(false); 3610 3611 format %{ "RFLAGS_U_CF" %} 3612 interface(REG_INTER); 3613 %} 3614 3615 // Float register operands 3616 operand regF() 3617 %{ 3618 constraint(ALLOC_IN_RC(float_reg)); 3619 match(RegF); 3620 3621 format %{ %} 3622 interface(REG_INTER); 3623 %} 3624 3625 // Double register operands 3626 operand regD() 3627 %{ 3628 constraint(ALLOC_IN_RC(double_reg)); 3629 match(RegD); 3630 3631 format %{ %} 3632 interface(REG_INTER); 3633 %} 3634 3635 //----------Memory Operands---------------------------------------------------- 3636 // Direct Memory Operand 3637 // operand direct(immP addr) 3638 // %{ 3639 // match(addr); 3640 3641 // format %{ "[$addr]" %} 3642 // interface(MEMORY_INTER) %{ 3643 // base(0xFFFFFFFF); 3644 // index(0x4); 3645 // scale(0x0); 3646 // disp($addr); 3647 // %} 3648 // %} 3649 3650 // Indirect Memory Operand 3651 operand indirect(any_RegP reg) 3652 %{ 3653 constraint(ALLOC_IN_RC(ptr_reg)); 3654 match(reg); 3655 3656 format %{ "[$reg]" %} 3657 interface(MEMORY_INTER) %{ 3658 base($reg); 3659 index(0x4); 3660 scale(0x0); 3661 disp(0x0); 3662 %} 3663 %} 3664 3665 // Indirect Memory Plus Short Offset Operand 3666 operand indOffset8(any_RegP reg, immL8 off) 3667 %{ 3668 constraint(ALLOC_IN_RC(ptr_reg)); 3669 match(AddP reg off); 3670 3671 format %{ "[$reg + $off (8-bit)]" %} 3672 interface(MEMORY_INTER) %{ 3673 base($reg); 3674 index(0x4); 3675 scale(0x0); 3676 disp($off); 3677 %} 3678 %} 3679 3680 // Indirect Memory Plus Long Offset Operand 3681 operand indOffset32(any_RegP reg, immL32 off) 3682 %{ 3683 constraint(ALLOC_IN_RC(ptr_reg)); 3684 match(AddP reg off); 3685 3686 format %{ "[$reg + $off (32-bit)]" %} 3687 interface(MEMORY_INTER) %{ 3688 base($reg); 3689 index(0x4); 3690 scale(0x0); 3691 disp($off); 3692 %} 3693 %} 3694 3695 // Indirect Memory Plus Index Register Plus Offset Operand 3696 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3697 %{ 3698 constraint(ALLOC_IN_RC(ptr_reg)); 3699 match(AddP (AddP reg lreg) off); 3700 3701 op_cost(10); 3702 format %{"[$reg + $off + $lreg]" %} 3703 interface(MEMORY_INTER) %{ 3704 base($reg); 3705 index($lreg); 3706 scale(0x0); 3707 disp($off); 3708 %} 3709 %} 3710 3711 // Indirect Memory Plus Index Register Plus Offset Operand 3712 operand indIndex(any_RegP reg, rRegL lreg) 3713 %{ 3714 constraint(ALLOC_IN_RC(ptr_reg)); 3715 match(AddP reg lreg); 3716 3717 op_cost(10); 3718 format %{"[$reg + $lreg]" %} 3719 interface(MEMORY_INTER) %{ 3720 base($reg); 3721 index($lreg); 3722 scale(0x0); 3723 disp(0x0); 3724 %} 3725 %} 3726 3727 // Indirect Memory Times Scale Plus Index Register 3728 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3729 %{ 3730 constraint(ALLOC_IN_RC(ptr_reg)); 3731 match(AddP reg (LShiftL lreg scale)); 3732 3733 op_cost(10); 3734 format %{"[$reg + $lreg << $scale]" %} 3735 interface(MEMORY_INTER) %{ 3736 base($reg); 3737 index($lreg); 3738 scale($scale); 3739 disp(0x0); 3740 %} 3741 %} 3742 3743 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3744 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3745 %{ 3746 constraint(ALLOC_IN_RC(ptr_reg)); 3747 match(AddP (AddP reg (LShiftL lreg scale)) off); 3748 3749 op_cost(10); 3750 format %{"[$reg + $off + $lreg << $scale]" %} 3751 interface(MEMORY_INTER) %{ 3752 base($reg); 3753 index($lreg); 3754 scale($scale); 3755 disp($off); 3756 %} 3757 %} 3758 3759 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3760 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3761 %{ 3762 constraint(ALLOC_IN_RC(ptr_reg)); 3763 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3764 match(AddP (AddP reg (ConvI2L idx)) off); 3765 3766 op_cost(10); 3767 format %{"[$reg + $off + $idx]" %} 3768 interface(MEMORY_INTER) %{ 3769 base($reg); 3770 index($idx); 3771 scale(0x0); 3772 disp($off); 3773 %} 3774 %} 3775 3776 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3777 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3778 %{ 3779 constraint(ALLOC_IN_RC(ptr_reg)); 3780 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3781 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3782 3783 op_cost(10); 3784 format %{"[$reg + $off + $idx << $scale]" %} 3785 interface(MEMORY_INTER) %{ 3786 base($reg); 3787 index($idx); 3788 scale($scale); 3789 disp($off); 3790 %} 3791 %} 3792 3793 // Indirect Narrow Oop Plus Offset Operand 3794 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3795 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3796 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3797 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3798 constraint(ALLOC_IN_RC(ptr_reg)); 3799 match(AddP (DecodeN reg) off); 3800 3801 op_cost(10); 3802 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3803 interface(MEMORY_INTER) %{ 3804 base(0xc); // R12 3805 index($reg); 3806 scale(0x3); 3807 disp($off); 3808 %} 3809 %} 3810 3811 // Indirect Memory Operand 3812 operand indirectNarrow(rRegN reg) 3813 %{ 3814 predicate(Universe::narrow_oop_shift() == 0); 3815 constraint(ALLOC_IN_RC(ptr_reg)); 3816 match(DecodeN reg); 3817 3818 format %{ "[$reg]" %} 3819 interface(MEMORY_INTER) %{ 3820 base($reg); 3821 index(0x4); 3822 scale(0x0); 3823 disp(0x0); 3824 %} 3825 %} 3826 3827 // Indirect Memory Plus Short Offset Operand 3828 operand indOffset8Narrow(rRegN reg, immL8 off) 3829 %{ 3830 predicate(Universe::narrow_oop_shift() == 0); 3831 constraint(ALLOC_IN_RC(ptr_reg)); 3832 match(AddP (DecodeN reg) off); 3833 3834 format %{ "[$reg + $off (8-bit)]" %} 3835 interface(MEMORY_INTER) %{ 3836 base($reg); 3837 index(0x4); 3838 scale(0x0); 3839 disp($off); 3840 %} 3841 %} 3842 3843 // Indirect Memory Plus Long Offset Operand 3844 operand indOffset32Narrow(rRegN reg, immL32 off) 3845 %{ 3846 predicate(Universe::narrow_oop_shift() == 0); 3847 constraint(ALLOC_IN_RC(ptr_reg)); 3848 match(AddP (DecodeN reg) off); 3849 3850 format %{ "[$reg + $off (32-bit)]" %} 3851 interface(MEMORY_INTER) %{ 3852 base($reg); 3853 index(0x4); 3854 scale(0x0); 3855 disp($off); 3856 %} 3857 %} 3858 3859 // Indirect Memory Plus Index Register Plus Offset Operand 3860 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3861 %{ 3862 predicate(Universe::narrow_oop_shift() == 0); 3863 constraint(ALLOC_IN_RC(ptr_reg)); 3864 match(AddP (AddP (DecodeN reg) lreg) off); 3865 3866 op_cost(10); 3867 format %{"[$reg + $off + $lreg]" %} 3868 interface(MEMORY_INTER) %{ 3869 base($reg); 3870 index($lreg); 3871 scale(0x0); 3872 disp($off); 3873 %} 3874 %} 3875 3876 // Indirect Memory Plus Index Register Plus Offset Operand 3877 operand indIndexNarrow(rRegN reg, rRegL lreg) 3878 %{ 3879 predicate(Universe::narrow_oop_shift() == 0); 3880 constraint(ALLOC_IN_RC(ptr_reg)); 3881 match(AddP (DecodeN reg) lreg); 3882 3883 op_cost(10); 3884 format %{"[$reg + $lreg]" %} 3885 interface(MEMORY_INTER) %{ 3886 base($reg); 3887 index($lreg); 3888 scale(0x0); 3889 disp(0x0); 3890 %} 3891 %} 3892 3893 // Indirect Memory Times Scale Plus Index Register 3894 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3895 %{ 3896 predicate(Universe::narrow_oop_shift() == 0); 3897 constraint(ALLOC_IN_RC(ptr_reg)); 3898 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3899 3900 op_cost(10); 3901 format %{"[$reg + $lreg << $scale]" %} 3902 interface(MEMORY_INTER) %{ 3903 base($reg); 3904 index($lreg); 3905 scale($scale); 3906 disp(0x0); 3907 %} 3908 %} 3909 3910 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3911 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3912 %{ 3913 predicate(Universe::narrow_oop_shift() == 0); 3914 constraint(ALLOC_IN_RC(ptr_reg)); 3915 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3916 3917 op_cost(10); 3918 format %{"[$reg + $off + $lreg << $scale]" %} 3919 interface(MEMORY_INTER) %{ 3920 base($reg); 3921 index($lreg); 3922 scale($scale); 3923 disp($off); 3924 %} 3925 %} 3926 3927 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3928 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3929 %{ 3930 constraint(ALLOC_IN_RC(ptr_reg)); 3931 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3932 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3933 3934 op_cost(10); 3935 format %{"[$reg + $off + $idx]" %} 3936 interface(MEMORY_INTER) %{ 3937 base($reg); 3938 index($idx); 3939 scale(0x0); 3940 disp($off); 3941 %} 3942 %} 3943 3944 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3945 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3946 %{ 3947 constraint(ALLOC_IN_RC(ptr_reg)); 3948 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3949 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3950 3951 op_cost(10); 3952 format %{"[$reg + $off + $idx << $scale]" %} 3953 interface(MEMORY_INTER) %{ 3954 base($reg); 3955 index($idx); 3956 scale($scale); 3957 disp($off); 3958 %} 3959 %} 3960 3961 //----------Special Memory Operands-------------------------------------------- 3962 // Stack Slot Operand - This operand is used for loading and storing temporary 3963 // values on the stack where a match requires a value to 3964 // flow through memory. 3965 operand stackSlotP(sRegP reg) 3966 %{ 3967 constraint(ALLOC_IN_RC(stack_slots)); 3968 // No match rule because this operand is only generated in matching 3969 3970 format %{ "[$reg]" %} 3971 interface(MEMORY_INTER) %{ 3972 base(0x4); // RSP 3973 index(0x4); // No Index 3974 scale(0x0); // No Scale 3975 disp($reg); // Stack Offset 3976 %} 3977 %} 3978 3979 operand stackSlotI(sRegI reg) 3980 %{ 3981 constraint(ALLOC_IN_RC(stack_slots)); 3982 // No match rule because this operand is only generated in matching 3983 3984 format %{ "[$reg]" %} 3985 interface(MEMORY_INTER) %{ 3986 base(0x4); // RSP 3987 index(0x4); // No Index 3988 scale(0x0); // No Scale 3989 disp($reg); // Stack Offset 3990 %} 3991 %} 3992 3993 operand stackSlotF(sRegF reg) 3994 %{ 3995 constraint(ALLOC_IN_RC(stack_slots)); 3996 // No match rule because this operand is only generated in matching 3997 3998 format %{ "[$reg]" %} 3999 interface(MEMORY_INTER) %{ 4000 base(0x4); // RSP 4001 index(0x4); // No Index 4002 scale(0x0); // No Scale 4003 disp($reg); // Stack Offset 4004 %} 4005 %} 4006 4007 operand stackSlotD(sRegD reg) 4008 %{ 4009 constraint(ALLOC_IN_RC(stack_slots)); 4010 // No match rule because this operand is only generated in matching 4011 4012 format %{ "[$reg]" %} 4013 interface(MEMORY_INTER) %{ 4014 base(0x4); // RSP 4015 index(0x4); // No Index 4016 scale(0x0); // No Scale 4017 disp($reg); // Stack Offset 4018 %} 4019 %} 4020 operand stackSlotL(sRegL reg) 4021 %{ 4022 constraint(ALLOC_IN_RC(stack_slots)); 4023 // No match rule because this operand is only generated in matching 4024 4025 format %{ "[$reg]" %} 4026 interface(MEMORY_INTER) %{ 4027 base(0x4); // RSP 4028 index(0x4); // No Index 4029 scale(0x0); // No Scale 4030 disp($reg); // Stack Offset 4031 %} 4032 %} 4033 4034 //----------Conditional Branch Operands---------------------------------------- 4035 // Comparison Op - This is the operation of the comparison, and is limited to 4036 // the following set of codes: 4037 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4038 // 4039 // Other attributes of the comparison, such as unsignedness, are specified 4040 // by the comparison instruction that sets a condition code flags register. 4041 // That result is represented by a flags operand whose subtype is appropriate 4042 // to the unsignedness (etc.) of the comparison. 4043 // 4044 // Later, the instruction which matches both the Comparison Op (a Bool) and 4045 // the flags (produced by the Cmp) specifies the coding of the comparison op 4046 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4047 4048 // Comparision Code 4049 operand cmpOp() 4050 %{ 4051 match(Bool); 4052 4053 format %{ "" %} 4054 interface(COND_INTER) %{ 4055 equal(0x4, "e"); 4056 not_equal(0x5, "ne"); 4057 less(0xC, "l"); 4058 greater_equal(0xD, "ge"); 4059 less_equal(0xE, "le"); 4060 greater(0xF, "g"); 4061 overflow(0x0, "o"); 4062 no_overflow(0x1, "no"); 4063 %} 4064 %} 4065 4066 // Comparison Code, unsigned compare. Used by FP also, with 4067 // C2 (unordered) turned into GT or LT already. The other bits 4068 // C0 and C3 are turned into Carry & Zero flags. 4069 operand cmpOpU() 4070 %{ 4071 match(Bool); 4072 4073 format %{ "" %} 4074 interface(COND_INTER) %{ 4075 equal(0x4, "e"); 4076 not_equal(0x5, "ne"); 4077 less(0x2, "b"); 4078 greater_equal(0x3, "nb"); 4079 less_equal(0x6, "be"); 4080 greater(0x7, "nbe"); 4081 overflow(0x0, "o"); 4082 no_overflow(0x1, "no"); 4083 %} 4084 %} 4085 4086 4087 // Floating comparisons that don't require any fixup for the unordered case 4088 operand cmpOpUCF() %{ 4089 match(Bool); 4090 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4091 n->as_Bool()->_test._test == BoolTest::ge || 4092 n->as_Bool()->_test._test == BoolTest::le || 4093 n->as_Bool()->_test._test == BoolTest::gt); 4094 format %{ "" %} 4095 interface(COND_INTER) %{ 4096 equal(0x4, "e"); 4097 not_equal(0x5, "ne"); 4098 less(0x2, "b"); 4099 greater_equal(0x3, "nb"); 4100 less_equal(0x6, "be"); 4101 greater(0x7, "nbe"); 4102 overflow(0x0, "o"); 4103 no_overflow(0x1, "no"); 4104 %} 4105 %} 4106 4107 4108 // Floating comparisons that can be fixed up with extra conditional jumps 4109 operand cmpOpUCF2() %{ 4110 match(Bool); 4111 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4112 n->as_Bool()->_test._test == BoolTest::eq); 4113 format %{ "" %} 4114 interface(COND_INTER) %{ 4115 equal(0x4, "e"); 4116 not_equal(0x5, "ne"); 4117 less(0x2, "b"); 4118 greater_equal(0x3, "nb"); 4119 less_equal(0x6, "be"); 4120 greater(0x7, "nbe"); 4121 overflow(0x0, "o"); 4122 no_overflow(0x1, "no"); 4123 %} 4124 %} 4125 4126 4127 //----------OPERAND CLASSES---------------------------------------------------- 4128 // Operand Classes are groups of operands that are used as to simplify 4129 // instruction definitions by not requiring the AD writer to specify separate 4130 // instructions for every form of operand when the instruction accepts 4131 // multiple operand types with the same basic encoding and format. The classic 4132 // case of this is memory operands. 4133 4134 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4135 indIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4136 indCompressedOopOffset, 4137 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4138 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4139 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4140 4141 //----------PIPELINE----------------------------------------------------------- 4142 // Rules which define the behavior of the target architectures pipeline. 4143 pipeline %{ 4144 4145 //----------ATTRIBUTES--------------------------------------------------------- 4146 attributes %{ 4147 variable_size_instructions; // Fixed size instructions 4148 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4149 instruction_unit_size = 1; // An instruction is 1 bytes long 4150 instruction_fetch_unit_size = 16; // The processor fetches one line 4151 instruction_fetch_units = 1; // of 16 bytes 4152 4153 // List of nop instructions 4154 nops( MachNop ); 4155 %} 4156 4157 //----------RESOURCES---------------------------------------------------------- 4158 // Resources are the functional units available to the machine 4159 4160 // Generic P2/P3 pipeline 4161 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4162 // 3 instructions decoded per cycle. 4163 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4164 // 3 ALU op, only ALU0 handles mul instructions. 4165 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4166 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4167 BR, FPU, 4168 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4169 4170 //----------PIPELINE DESCRIPTION----------------------------------------------- 4171 // Pipeline Description specifies the stages in the machine's pipeline 4172 4173 // Generic P2/P3 pipeline 4174 pipe_desc(S0, S1, S2, S3, S4, S5); 4175 4176 //----------PIPELINE CLASSES--------------------------------------------------- 4177 // Pipeline Classes describe the stages in which input and output are 4178 // referenced by the hardware pipeline. 4179 4180 // Naming convention: ialu or fpu 4181 // Then: _reg 4182 // Then: _reg if there is a 2nd register 4183 // Then: _long if it's a pair of instructions implementing a long 4184 // Then: _fat if it requires the big decoder 4185 // Or: _mem if it requires the big decoder and a memory unit. 4186 4187 // Integer ALU reg operation 4188 pipe_class ialu_reg(rRegI dst) 4189 %{ 4190 single_instruction; 4191 dst : S4(write); 4192 dst : S3(read); 4193 DECODE : S0; // any decoder 4194 ALU : S3; // any alu 4195 %} 4196 4197 // Long ALU reg operation 4198 pipe_class ialu_reg_long(rRegL dst) 4199 %{ 4200 instruction_count(2); 4201 dst : S4(write); 4202 dst : S3(read); 4203 DECODE : S0(2); // any 2 decoders 4204 ALU : S3(2); // both alus 4205 %} 4206 4207 // Integer ALU reg operation using big decoder 4208 pipe_class ialu_reg_fat(rRegI dst) 4209 %{ 4210 single_instruction; 4211 dst : S4(write); 4212 dst : S3(read); 4213 D0 : S0; // big decoder only 4214 ALU : S3; // any alu 4215 %} 4216 4217 // Long ALU reg operation using big decoder 4218 pipe_class ialu_reg_long_fat(rRegL dst) 4219 %{ 4220 instruction_count(2); 4221 dst : S4(write); 4222 dst : S3(read); 4223 D0 : S0(2); // big decoder only; twice 4224 ALU : S3(2); // any 2 alus 4225 %} 4226 4227 // Integer ALU reg-reg operation 4228 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4229 %{ 4230 single_instruction; 4231 dst : S4(write); 4232 src : S3(read); 4233 DECODE : S0; // any decoder 4234 ALU : S3; // any alu 4235 %} 4236 4237 // Long ALU reg-reg operation 4238 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4239 %{ 4240 instruction_count(2); 4241 dst : S4(write); 4242 src : S3(read); 4243 DECODE : S0(2); // any 2 decoders 4244 ALU : S3(2); // both alus 4245 %} 4246 4247 // Integer ALU reg-reg operation 4248 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4249 %{ 4250 single_instruction; 4251 dst : S4(write); 4252 src : S3(read); 4253 D0 : S0; // big decoder only 4254 ALU : S3; // any alu 4255 %} 4256 4257 // Long ALU reg-reg operation 4258 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4259 %{ 4260 instruction_count(2); 4261 dst : S4(write); 4262 src : S3(read); 4263 D0 : S0(2); // big decoder only; twice 4264 ALU : S3(2); // both alus 4265 %} 4266 4267 // Integer ALU reg-mem operation 4268 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4269 %{ 4270 single_instruction; 4271 dst : S5(write); 4272 mem : S3(read); 4273 D0 : S0; // big decoder only 4274 ALU : S4; // any alu 4275 MEM : S3; // any mem 4276 %} 4277 4278 // Integer mem operation (prefetch) 4279 pipe_class ialu_mem(memory mem) 4280 %{ 4281 single_instruction; 4282 mem : S3(read); 4283 D0 : S0; // big decoder only 4284 MEM : S3; // any mem 4285 %} 4286 4287 // Integer Store to Memory 4288 pipe_class ialu_mem_reg(memory mem, rRegI src) 4289 %{ 4290 single_instruction; 4291 mem : S3(read); 4292 src : S5(read); 4293 D0 : S0; // big decoder only 4294 ALU : S4; // any alu 4295 MEM : S3; 4296 %} 4297 4298 // // Long Store to Memory 4299 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4300 // %{ 4301 // instruction_count(2); 4302 // mem : S3(read); 4303 // src : S5(read); 4304 // D0 : S0(2); // big decoder only; twice 4305 // ALU : S4(2); // any 2 alus 4306 // MEM : S3(2); // Both mems 4307 // %} 4308 4309 // Integer Store to Memory 4310 pipe_class ialu_mem_imm(memory mem) 4311 %{ 4312 single_instruction; 4313 mem : S3(read); 4314 D0 : S0; // big decoder only 4315 ALU : S4; // any alu 4316 MEM : S3; 4317 %} 4318 4319 // Integer ALU0 reg-reg operation 4320 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4321 %{ 4322 single_instruction; 4323 dst : S4(write); 4324 src : S3(read); 4325 D0 : S0; // Big decoder only 4326 ALU0 : S3; // only alu0 4327 %} 4328 4329 // Integer ALU0 reg-mem operation 4330 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4331 %{ 4332 single_instruction; 4333 dst : S5(write); 4334 mem : S3(read); 4335 D0 : S0; // big decoder only 4336 ALU0 : S4; // ALU0 only 4337 MEM : S3; // any mem 4338 %} 4339 4340 // Integer ALU reg-reg operation 4341 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4342 %{ 4343 single_instruction; 4344 cr : S4(write); 4345 src1 : S3(read); 4346 src2 : S3(read); 4347 DECODE : S0; // any decoder 4348 ALU : S3; // any alu 4349 %} 4350 4351 // Integer ALU reg-imm operation 4352 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4353 %{ 4354 single_instruction; 4355 cr : S4(write); 4356 src1 : S3(read); 4357 DECODE : S0; // any decoder 4358 ALU : S3; // any alu 4359 %} 4360 4361 // Integer ALU reg-mem operation 4362 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4363 %{ 4364 single_instruction; 4365 cr : S4(write); 4366 src1 : S3(read); 4367 src2 : S3(read); 4368 D0 : S0; // big decoder only 4369 ALU : S4; // any alu 4370 MEM : S3; 4371 %} 4372 4373 // Conditional move reg-reg 4374 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4375 %{ 4376 instruction_count(4); 4377 y : S4(read); 4378 q : S3(read); 4379 p : S3(read); 4380 DECODE : S0(4); // any decoder 4381 %} 4382 4383 // Conditional move reg-reg 4384 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4385 %{ 4386 single_instruction; 4387 dst : S4(write); 4388 src : S3(read); 4389 cr : S3(read); 4390 DECODE : S0; // any decoder 4391 %} 4392 4393 // Conditional move reg-mem 4394 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4395 %{ 4396 single_instruction; 4397 dst : S4(write); 4398 src : S3(read); 4399 cr : S3(read); 4400 DECODE : S0; // any decoder 4401 MEM : S3; 4402 %} 4403 4404 // Conditional move reg-reg long 4405 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4406 %{ 4407 single_instruction; 4408 dst : S4(write); 4409 src : S3(read); 4410 cr : S3(read); 4411 DECODE : S0(2); // any 2 decoders 4412 %} 4413 4414 // XXX 4415 // // Conditional move double reg-reg 4416 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4417 // %{ 4418 // single_instruction; 4419 // dst : S4(write); 4420 // src : S3(read); 4421 // cr : S3(read); 4422 // DECODE : S0; // any decoder 4423 // %} 4424 4425 // Float reg-reg operation 4426 pipe_class fpu_reg(regD dst) 4427 %{ 4428 instruction_count(2); 4429 dst : S3(read); 4430 DECODE : S0(2); // any 2 decoders 4431 FPU : S3; 4432 %} 4433 4434 // Float reg-reg operation 4435 pipe_class fpu_reg_reg(regD dst, regD src) 4436 %{ 4437 instruction_count(2); 4438 dst : S4(write); 4439 src : S3(read); 4440 DECODE : S0(2); // any 2 decoders 4441 FPU : S3; 4442 %} 4443 4444 // Float reg-reg operation 4445 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4446 %{ 4447 instruction_count(3); 4448 dst : S4(write); 4449 src1 : S3(read); 4450 src2 : S3(read); 4451 DECODE : S0(3); // any 3 decoders 4452 FPU : S3(2); 4453 %} 4454 4455 // Float reg-reg operation 4456 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4457 %{ 4458 instruction_count(4); 4459 dst : S4(write); 4460 src1 : S3(read); 4461 src2 : S3(read); 4462 src3 : S3(read); 4463 DECODE : S0(4); // any 3 decoders 4464 FPU : S3(2); 4465 %} 4466 4467 // Float reg-reg operation 4468 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4469 %{ 4470 instruction_count(4); 4471 dst : S4(write); 4472 src1 : S3(read); 4473 src2 : S3(read); 4474 src3 : S3(read); 4475 DECODE : S1(3); // any 3 decoders 4476 D0 : S0; // Big decoder only 4477 FPU : S3(2); 4478 MEM : S3; 4479 %} 4480 4481 // Float reg-mem operation 4482 pipe_class fpu_reg_mem(regD dst, memory mem) 4483 %{ 4484 instruction_count(2); 4485 dst : S5(write); 4486 mem : S3(read); 4487 D0 : S0; // big decoder only 4488 DECODE : S1; // any decoder for FPU POP 4489 FPU : S4; 4490 MEM : S3; // any mem 4491 %} 4492 4493 // Float reg-mem operation 4494 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4495 %{ 4496 instruction_count(3); 4497 dst : S5(write); 4498 src1 : S3(read); 4499 mem : S3(read); 4500 D0 : S0; // big decoder only 4501 DECODE : S1(2); // any decoder for FPU POP 4502 FPU : S4; 4503 MEM : S3; // any mem 4504 %} 4505 4506 // Float mem-reg operation 4507 pipe_class fpu_mem_reg(memory mem, regD src) 4508 %{ 4509 instruction_count(2); 4510 src : S5(read); 4511 mem : S3(read); 4512 DECODE : S0; // any decoder for FPU PUSH 4513 D0 : S1; // big decoder only 4514 FPU : S4; 4515 MEM : S3; // any mem 4516 %} 4517 4518 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4519 %{ 4520 instruction_count(3); 4521 src1 : S3(read); 4522 src2 : S3(read); 4523 mem : S3(read); 4524 DECODE : S0(2); // any decoder for FPU PUSH 4525 D0 : S1; // big decoder only 4526 FPU : S4; 4527 MEM : S3; // any mem 4528 %} 4529 4530 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4531 %{ 4532 instruction_count(3); 4533 src1 : S3(read); 4534 src2 : S3(read); 4535 mem : S4(read); 4536 DECODE : S0; // any decoder for FPU PUSH 4537 D0 : S0(2); // big decoder only 4538 FPU : S4; 4539 MEM : S3(2); // any mem 4540 %} 4541 4542 pipe_class fpu_mem_mem(memory dst, memory src1) 4543 %{ 4544 instruction_count(2); 4545 src1 : S3(read); 4546 dst : S4(read); 4547 D0 : S0(2); // big decoder only 4548 MEM : S3(2); // any mem 4549 %} 4550 4551 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4552 %{ 4553 instruction_count(3); 4554 src1 : S3(read); 4555 src2 : S3(read); 4556 dst : S4(read); 4557 D0 : S0(3); // big decoder only 4558 FPU : S4; 4559 MEM : S3(3); // any mem 4560 %} 4561 4562 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4563 %{ 4564 instruction_count(3); 4565 src1 : S4(read); 4566 mem : S4(read); 4567 DECODE : S0; // any decoder for FPU PUSH 4568 D0 : S0(2); // big decoder only 4569 FPU : S4; 4570 MEM : S3(2); // any mem 4571 %} 4572 4573 // Float load constant 4574 pipe_class fpu_reg_con(regD dst) 4575 %{ 4576 instruction_count(2); 4577 dst : S5(write); 4578 D0 : S0; // big decoder only for the load 4579 DECODE : S1; // any decoder for FPU POP 4580 FPU : S4; 4581 MEM : S3; // any mem 4582 %} 4583 4584 // Float load constant 4585 pipe_class fpu_reg_reg_con(regD dst, regD src) 4586 %{ 4587 instruction_count(3); 4588 dst : S5(write); 4589 src : S3(read); 4590 D0 : S0; // big decoder only for the load 4591 DECODE : S1(2); // any decoder for FPU POP 4592 FPU : S4; 4593 MEM : S3; // any mem 4594 %} 4595 4596 // UnConditional branch 4597 pipe_class pipe_jmp(label labl) 4598 %{ 4599 single_instruction; 4600 BR : S3; 4601 %} 4602 4603 // Conditional branch 4604 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4605 %{ 4606 single_instruction; 4607 cr : S1(read); 4608 BR : S3; 4609 %} 4610 4611 // Allocation idiom 4612 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4613 %{ 4614 instruction_count(1); force_serialization; 4615 fixed_latency(6); 4616 heap_ptr : S3(read); 4617 DECODE : S0(3); 4618 D0 : S2; 4619 MEM : S3; 4620 ALU : S3(2); 4621 dst : S5(write); 4622 BR : S5; 4623 %} 4624 4625 // Generic big/slow expanded idiom 4626 pipe_class pipe_slow() 4627 %{ 4628 instruction_count(10); multiple_bundles; force_serialization; 4629 fixed_latency(100); 4630 D0 : S0(2); 4631 MEM : S3(2); 4632 %} 4633 4634 // The real do-nothing guy 4635 pipe_class empty() 4636 %{ 4637 instruction_count(0); 4638 %} 4639 4640 // Define the class for the Nop node 4641 define 4642 %{ 4643 MachNop = empty; 4644 %} 4645 4646 %} 4647 4648 //----------INSTRUCTIONS------------------------------------------------------- 4649 // 4650 // match -- States which machine-independent subtree may be replaced 4651 // by this instruction. 4652 // ins_cost -- The estimated cost of this instruction is used by instruction 4653 // selection to identify a minimum cost tree of machine 4654 // instructions that matches a tree of machine-independent 4655 // instructions. 4656 // format -- A string providing the disassembly for this instruction. 4657 // The value of an instruction's operand may be inserted 4658 // by referring to it with a '$' prefix. 4659 // opcode -- Three instruction opcodes may be provided. These are referred 4660 // to within an encode class as $primary, $secondary, and $tertiary 4661 // rrspectively. The primary opcode is commonly used to 4662 // indicate the type of machine instruction, while secondary 4663 // and tertiary are often used for prefix options or addressing 4664 // modes. 4665 // ins_encode -- A list of encode classes with parameters. The encode class 4666 // name must have been defined in an 'enc_class' specification 4667 // in the encode section of the architecture description. 4668 4669 4670 //----------Load/Store/Move Instructions--------------------------------------- 4671 //----------Load Instructions-------------------------------------------------- 4672 4673 // Load Byte (8 bit signed) 4674 instruct loadB(rRegI dst, memory mem) 4675 %{ 4676 match(Set dst (LoadB mem)); 4677 4678 ins_cost(125); 4679 format %{ "movsbl $dst, $mem\t# byte" %} 4680 4681 ins_encode %{ 4682 __ movsbl($dst$$Register, $mem$$Address); 4683 %} 4684 4685 ins_pipe(ialu_reg_mem); 4686 %} 4687 4688 // Load Byte (8 bit signed) into Long Register 4689 instruct loadB2L(rRegL dst, memory mem) 4690 %{ 4691 match(Set dst (ConvI2L (LoadB mem))); 4692 4693 ins_cost(125); 4694 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4695 4696 ins_encode %{ 4697 __ movsbq($dst$$Register, $mem$$Address); 4698 %} 4699 4700 ins_pipe(ialu_reg_mem); 4701 %} 4702 4703 // Load Unsigned Byte (8 bit UNsigned) 4704 instruct loadUB(rRegI dst, memory mem) 4705 %{ 4706 match(Set dst (LoadUB mem)); 4707 4708 ins_cost(125); 4709 format %{ "movzbl $dst, $mem\t# ubyte" %} 4710 4711 ins_encode %{ 4712 __ movzbl($dst$$Register, $mem$$Address); 4713 %} 4714 4715 ins_pipe(ialu_reg_mem); 4716 %} 4717 4718 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4719 instruct loadUB2L(rRegL dst, memory mem) 4720 %{ 4721 match(Set dst (ConvI2L (LoadUB mem))); 4722 4723 ins_cost(125); 4724 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4725 4726 ins_encode %{ 4727 __ movzbq($dst$$Register, $mem$$Address); 4728 %} 4729 4730 ins_pipe(ialu_reg_mem); 4731 %} 4732 4733 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register 4734 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ 4735 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4736 effect(KILL cr); 4737 4738 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" 4739 "andl $dst, $mask" %} 4740 ins_encode %{ 4741 Register Rdst = $dst$$Register; 4742 __ movzbq(Rdst, $mem$$Address); 4743 __ andl(Rdst, $mask$$constant); 4744 %} 4745 ins_pipe(ialu_reg_mem); 4746 %} 4747 4748 // Load Short (16 bit signed) 4749 instruct loadS(rRegI dst, memory mem) 4750 %{ 4751 match(Set dst (LoadS mem)); 4752 4753 ins_cost(125); 4754 format %{ "movswl $dst, $mem\t# short" %} 4755 4756 ins_encode %{ 4757 __ movswl($dst$$Register, $mem$$Address); 4758 %} 4759 4760 ins_pipe(ialu_reg_mem); 4761 %} 4762 4763 // Load Short (16 bit signed) to Byte (8 bit signed) 4764 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4765 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4766 4767 ins_cost(125); 4768 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4769 ins_encode %{ 4770 __ movsbl($dst$$Register, $mem$$Address); 4771 %} 4772 ins_pipe(ialu_reg_mem); 4773 %} 4774 4775 // Load Short (16 bit signed) into Long Register 4776 instruct loadS2L(rRegL dst, memory mem) 4777 %{ 4778 match(Set dst (ConvI2L (LoadS mem))); 4779 4780 ins_cost(125); 4781 format %{ "movswq $dst, $mem\t# short -> long" %} 4782 4783 ins_encode %{ 4784 __ movswq($dst$$Register, $mem$$Address); 4785 %} 4786 4787 ins_pipe(ialu_reg_mem); 4788 %} 4789 4790 // Load Unsigned Short/Char (16 bit UNsigned) 4791 instruct loadUS(rRegI dst, memory mem) 4792 %{ 4793 match(Set dst (LoadUS mem)); 4794 4795 ins_cost(125); 4796 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4797 4798 ins_encode %{ 4799 __ movzwl($dst$$Register, $mem$$Address); 4800 %} 4801 4802 ins_pipe(ialu_reg_mem); 4803 %} 4804 4805 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4806 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4807 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4808 4809 ins_cost(125); 4810 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4811 ins_encode %{ 4812 __ movsbl($dst$$Register, $mem$$Address); 4813 %} 4814 ins_pipe(ialu_reg_mem); 4815 %} 4816 4817 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4818 instruct loadUS2L(rRegL dst, memory mem) 4819 %{ 4820 match(Set dst (ConvI2L (LoadUS mem))); 4821 4822 ins_cost(125); 4823 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4824 4825 ins_encode %{ 4826 __ movzwq($dst$$Register, $mem$$Address); 4827 %} 4828 4829 ins_pipe(ialu_reg_mem); 4830 %} 4831 4832 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4833 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4834 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4835 4836 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4837 ins_encode %{ 4838 __ movzbq($dst$$Register, $mem$$Address); 4839 %} 4840 ins_pipe(ialu_reg_mem); 4841 %} 4842 4843 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register 4844 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ 4845 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4846 effect(KILL cr); 4847 4848 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" 4849 "andl $dst, $mask" %} 4850 ins_encode %{ 4851 Register Rdst = $dst$$Register; 4852 __ movzwq(Rdst, $mem$$Address); 4853 __ andl(Rdst, $mask$$constant); 4854 %} 4855 ins_pipe(ialu_reg_mem); 4856 %} 4857 4858 // Load Integer 4859 instruct loadI(rRegI dst, memory mem) 4860 %{ 4861 match(Set dst (LoadI mem)); 4862 4863 ins_cost(125); 4864 format %{ "movl $dst, $mem\t# int" %} 4865 4866 ins_encode %{ 4867 __ movl($dst$$Register, $mem$$Address); 4868 %} 4869 4870 ins_pipe(ialu_reg_mem); 4871 %} 4872 4873 // Load Integer (32 bit signed) to Byte (8 bit signed) 4874 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4875 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4876 4877 ins_cost(125); 4878 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4879 ins_encode %{ 4880 __ movsbl($dst$$Register, $mem$$Address); 4881 %} 4882 ins_pipe(ialu_reg_mem); 4883 %} 4884 4885 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4886 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4887 match(Set dst (AndI (LoadI mem) mask)); 4888 4889 ins_cost(125); 4890 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4891 ins_encode %{ 4892 __ movzbl($dst$$Register, $mem$$Address); 4893 %} 4894 ins_pipe(ialu_reg_mem); 4895 %} 4896 4897 // Load Integer (32 bit signed) to Short (16 bit signed) 4898 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4899 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4900 4901 ins_cost(125); 4902 format %{ "movswl $dst, $mem\t# int -> short" %} 4903 ins_encode %{ 4904 __ movswl($dst$$Register, $mem$$Address); 4905 %} 4906 ins_pipe(ialu_reg_mem); 4907 %} 4908 4909 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4910 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4911 match(Set dst (AndI (LoadI mem) mask)); 4912 4913 ins_cost(125); 4914 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4915 ins_encode %{ 4916 __ movzwl($dst$$Register, $mem$$Address); 4917 %} 4918 ins_pipe(ialu_reg_mem); 4919 %} 4920 4921 // Load Integer into Long Register 4922 instruct loadI2L(rRegL dst, memory mem) 4923 %{ 4924 match(Set dst (ConvI2L (LoadI mem))); 4925 4926 ins_cost(125); 4927 format %{ "movslq $dst, $mem\t# int -> long" %} 4928 4929 ins_encode %{ 4930 __ movslq($dst$$Register, $mem$$Address); 4931 %} 4932 4933 ins_pipe(ialu_reg_mem); 4934 %} 4935 4936 // Load Integer with mask 0xFF into Long Register 4937 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4938 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4939 4940 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4941 ins_encode %{ 4942 __ movzbq($dst$$Register, $mem$$Address); 4943 %} 4944 ins_pipe(ialu_reg_mem); 4945 %} 4946 4947 // Load Integer with mask 0xFFFF into Long Register 4948 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4949 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4950 4951 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4952 ins_encode %{ 4953 __ movzwq($dst$$Register, $mem$$Address); 4954 %} 4955 ins_pipe(ialu_reg_mem); 4956 %} 4957 4958 // Load Integer with a 31-bit mask into Long Register 4959 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4960 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4961 effect(KILL cr); 4962 4963 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4964 "andl $dst, $mask" %} 4965 ins_encode %{ 4966 Register Rdst = $dst$$Register; 4967 __ movl(Rdst, $mem$$Address); 4968 __ andl(Rdst, $mask$$constant); 4969 %} 4970 ins_pipe(ialu_reg_mem); 4971 %} 4972 4973 // Load Unsigned Integer into Long Register 4974 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4975 %{ 4976 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4977 4978 ins_cost(125); 4979 format %{ "movl $dst, $mem\t# uint -> long" %} 4980 4981 ins_encode %{ 4982 __ movl($dst$$Register, $mem$$Address); 4983 %} 4984 4985 ins_pipe(ialu_reg_mem); 4986 %} 4987 4988 // Load Long 4989 instruct loadL(rRegL dst, memory mem) 4990 %{ 4991 match(Set dst (LoadL mem)); 4992 4993 ins_cost(125); 4994 format %{ "movq $dst, $mem\t# long" %} 4995 4996 ins_encode %{ 4997 __ movq($dst$$Register, $mem$$Address); 4998 %} 4999 5000 ins_pipe(ialu_reg_mem); // XXX 5001 %} 5002 5003 // Load Range 5004 instruct loadRange(rRegI dst, memory mem) 5005 %{ 5006 match(Set dst (LoadRange mem)); 5007 5008 ins_cost(125); // XXX 5009 format %{ "movl $dst, $mem\t# range" %} 5010 opcode(0x8B); 5011 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5012 ins_pipe(ialu_reg_mem); 5013 %} 5014 5015 // Load Pointer 5016 instruct loadP(rRegP dst, memory mem) 5017 %{ 5018 match(Set dst (LoadP mem)); 5019 5020 ins_cost(125); // XXX 5021 format %{ "movq $dst, $mem\t# ptr" %} 5022 opcode(0x8B); 5023 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5024 ins_pipe(ialu_reg_mem); // XXX 5025 %} 5026 5027 // Load Compressed Pointer 5028 instruct loadN(rRegN dst, memory mem) 5029 %{ 5030 match(Set dst (LoadN mem)); 5031 5032 ins_cost(125); // XXX 5033 format %{ "movl $dst, $mem\t# compressed ptr" %} 5034 ins_encode %{ 5035 __ movl($dst$$Register, $mem$$Address); 5036 %} 5037 ins_pipe(ialu_reg_mem); // XXX 5038 %} 5039 5040 5041 // Load Klass Pointer 5042 instruct loadKlass(rRegP dst, memory mem) 5043 %{ 5044 match(Set dst (LoadKlass mem)); 5045 5046 ins_cost(125); // XXX 5047 format %{ "movq $dst, $mem\t# class" %} 5048 opcode(0x8B); 5049 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5050 ins_pipe(ialu_reg_mem); // XXX 5051 %} 5052 5053 // Load narrow Klass Pointer 5054 instruct loadNKlass(rRegN dst, memory mem) 5055 %{ 5056 match(Set dst (LoadNKlass mem)); 5057 5058 ins_cost(125); // XXX 5059 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5060 ins_encode %{ 5061 __ movl($dst$$Register, $mem$$Address); 5062 %} 5063 ins_pipe(ialu_reg_mem); // XXX 5064 %} 5065 5066 // Load Float 5067 instruct loadF(regF dst, memory mem) 5068 %{ 5069 match(Set dst (LoadF mem)); 5070 5071 ins_cost(145); // XXX 5072 format %{ "movss $dst, $mem\t# float" %} 5073 ins_encode %{ 5074 __ movflt($dst$$XMMRegister, $mem$$Address); 5075 %} 5076 ins_pipe(pipe_slow); // XXX 5077 %} 5078 5079 // Load Double 5080 instruct loadD_partial(regD dst, memory mem) 5081 %{ 5082 predicate(!UseXmmLoadAndClearUpper); 5083 match(Set dst (LoadD mem)); 5084 5085 ins_cost(145); // XXX 5086 format %{ "movlpd $dst, $mem\t# double" %} 5087 ins_encode %{ 5088 __ movdbl($dst$$XMMRegister, $mem$$Address); 5089 %} 5090 ins_pipe(pipe_slow); // XXX 5091 %} 5092 5093 instruct loadD(regD dst, memory mem) 5094 %{ 5095 predicate(UseXmmLoadAndClearUpper); 5096 match(Set dst (LoadD mem)); 5097 5098 ins_cost(145); // XXX 5099 format %{ "movsd $dst, $mem\t# double" %} 5100 ins_encode %{ 5101 __ movdbl($dst$$XMMRegister, $mem$$Address); 5102 %} 5103 ins_pipe(pipe_slow); // XXX 5104 %} 5105 5106 // Load Effective Address 5107 instruct leaP8(rRegP dst, indOffset8 mem) 5108 %{ 5109 match(Set dst mem); 5110 5111 ins_cost(110); // XXX 5112 format %{ "leaq $dst, $mem\t# ptr 8" %} 5113 opcode(0x8D); 5114 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5115 ins_pipe(ialu_reg_reg_fat); 5116 %} 5117 5118 instruct leaP32(rRegP dst, indOffset32 mem) 5119 %{ 5120 match(Set dst mem); 5121 5122 ins_cost(110); 5123 format %{ "leaq $dst, $mem\t# ptr 32" %} 5124 opcode(0x8D); 5125 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5126 ins_pipe(ialu_reg_reg_fat); 5127 %} 5128 5129 // instruct leaPIdx(rRegP dst, indIndex mem) 5130 // %{ 5131 // match(Set dst mem); 5132 5133 // ins_cost(110); 5134 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5135 // opcode(0x8D); 5136 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5137 // ins_pipe(ialu_reg_reg_fat); 5138 // %} 5139 5140 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5141 %{ 5142 match(Set dst mem); 5143 5144 ins_cost(110); 5145 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5146 opcode(0x8D); 5147 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5148 ins_pipe(ialu_reg_reg_fat); 5149 %} 5150 5151 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5152 %{ 5153 match(Set dst mem); 5154 5155 ins_cost(110); 5156 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5157 opcode(0x8D); 5158 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5159 ins_pipe(ialu_reg_reg_fat); 5160 %} 5161 5162 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5163 %{ 5164 match(Set dst mem); 5165 5166 ins_cost(110); 5167 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5168 opcode(0x8D); 5169 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5170 ins_pipe(ialu_reg_reg_fat); 5171 %} 5172 5173 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5174 %{ 5175 match(Set dst mem); 5176 5177 ins_cost(110); 5178 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5179 opcode(0x8D); 5180 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5181 ins_pipe(ialu_reg_reg_fat); 5182 %} 5183 5184 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5185 %{ 5186 match(Set dst mem); 5187 5188 ins_cost(110); 5189 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5190 opcode(0x8D); 5191 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5192 ins_pipe(ialu_reg_reg_fat); 5193 %} 5194 5195 // Load Effective Address which uses Narrow (32-bits) oop 5196 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5197 %{ 5198 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5199 match(Set dst mem); 5200 5201 ins_cost(110); 5202 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5203 opcode(0x8D); 5204 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5205 ins_pipe(ialu_reg_reg_fat); 5206 %} 5207 5208 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5209 %{ 5210 predicate(Universe::narrow_oop_shift() == 0); 5211 match(Set dst mem); 5212 5213 ins_cost(110); // XXX 5214 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5215 opcode(0x8D); 5216 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5217 ins_pipe(ialu_reg_reg_fat); 5218 %} 5219 5220 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5221 %{ 5222 predicate(Universe::narrow_oop_shift() == 0); 5223 match(Set dst mem); 5224 5225 ins_cost(110); 5226 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5227 opcode(0x8D); 5228 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5229 ins_pipe(ialu_reg_reg_fat); 5230 %} 5231 5232 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5233 %{ 5234 predicate(Universe::narrow_oop_shift() == 0); 5235 match(Set dst mem); 5236 5237 ins_cost(110); 5238 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5239 opcode(0x8D); 5240 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5241 ins_pipe(ialu_reg_reg_fat); 5242 %} 5243 5244 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5245 %{ 5246 predicate(Universe::narrow_oop_shift() == 0); 5247 match(Set dst mem); 5248 5249 ins_cost(110); 5250 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5251 opcode(0x8D); 5252 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5253 ins_pipe(ialu_reg_reg_fat); 5254 %} 5255 5256 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5257 %{ 5258 predicate(Universe::narrow_oop_shift() == 0); 5259 match(Set dst mem); 5260 5261 ins_cost(110); 5262 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5263 opcode(0x8D); 5264 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5265 ins_pipe(ialu_reg_reg_fat); 5266 %} 5267 5268 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5269 %{ 5270 predicate(Universe::narrow_oop_shift() == 0); 5271 match(Set dst mem); 5272 5273 ins_cost(110); 5274 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5275 opcode(0x8D); 5276 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5277 ins_pipe(ialu_reg_reg_fat); 5278 %} 5279 5280 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5281 %{ 5282 predicate(Universe::narrow_oop_shift() == 0); 5283 match(Set dst mem); 5284 5285 ins_cost(110); 5286 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5287 opcode(0x8D); 5288 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5289 ins_pipe(ialu_reg_reg_fat); 5290 %} 5291 5292 instruct loadConI(rRegI dst, immI src) 5293 %{ 5294 match(Set dst src); 5295 5296 format %{ "movl $dst, $src\t# int" %} 5297 ins_encode(load_immI(dst, src)); 5298 ins_pipe(ialu_reg_fat); // XXX 5299 %} 5300 5301 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5302 %{ 5303 match(Set dst src); 5304 effect(KILL cr); 5305 5306 ins_cost(50); 5307 format %{ "xorl $dst, $dst\t# int" %} 5308 opcode(0x33); /* + rd */ 5309 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5310 ins_pipe(ialu_reg); 5311 %} 5312 5313 instruct loadConL(rRegL dst, immL src) 5314 %{ 5315 match(Set dst src); 5316 5317 ins_cost(150); 5318 format %{ "movq $dst, $src\t# long" %} 5319 ins_encode(load_immL(dst, src)); 5320 ins_pipe(ialu_reg); 5321 %} 5322 5323 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5324 %{ 5325 match(Set dst src); 5326 effect(KILL cr); 5327 5328 ins_cost(50); 5329 format %{ "xorl $dst, $dst\t# long" %} 5330 opcode(0x33); /* + rd */ 5331 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5332 ins_pipe(ialu_reg); // XXX 5333 %} 5334 5335 instruct loadConUL32(rRegL dst, immUL32 src) 5336 %{ 5337 match(Set dst src); 5338 5339 ins_cost(60); 5340 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5341 ins_encode(load_immUL32(dst, src)); 5342 ins_pipe(ialu_reg); 5343 %} 5344 5345 instruct loadConL32(rRegL dst, immL32 src) 5346 %{ 5347 match(Set dst src); 5348 5349 ins_cost(70); 5350 format %{ "movq $dst, $src\t# long (32-bit)" %} 5351 ins_encode(load_immL32(dst, src)); 5352 ins_pipe(ialu_reg); 5353 %} 5354 5355 instruct loadConP(rRegP dst, immP con) %{ 5356 match(Set dst con); 5357 5358 format %{ "movq $dst, $con\t# ptr" %} 5359 ins_encode(load_immP(dst, con)); 5360 ins_pipe(ialu_reg_fat); // XXX 5361 %} 5362 5363 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5364 %{ 5365 match(Set dst src); 5366 effect(KILL cr); 5367 5368 ins_cost(50); 5369 format %{ "xorl $dst, $dst\t# ptr" %} 5370 opcode(0x33); /* + rd */ 5371 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5372 ins_pipe(ialu_reg); 5373 %} 5374 5375 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5376 %{ 5377 match(Set dst src); 5378 effect(KILL cr); 5379 5380 ins_cost(60); 5381 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5382 ins_encode(load_immP31(dst, src)); 5383 ins_pipe(ialu_reg); 5384 %} 5385 5386 instruct loadConF(regF dst, immF con) %{ 5387 match(Set dst con); 5388 ins_cost(125); 5389 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5390 ins_encode %{ 5391 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5392 %} 5393 ins_pipe(pipe_slow); 5394 %} 5395 5396 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5397 match(Set dst src); 5398 effect(KILL cr); 5399 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5400 ins_encode %{ 5401 __ xorq($dst$$Register, $dst$$Register); 5402 %} 5403 ins_pipe(ialu_reg); 5404 %} 5405 5406 instruct loadConN(rRegN dst, immN src) %{ 5407 match(Set dst src); 5408 5409 ins_cost(125); 5410 format %{ "movl $dst, $src\t# compressed ptr" %} 5411 ins_encode %{ 5412 address con = (address)$src$$constant; 5413 if (con == NULL) { 5414 ShouldNotReachHere(); 5415 } else { 5416 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5417 } 5418 %} 5419 ins_pipe(ialu_reg_fat); // XXX 5420 %} 5421 5422 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5423 match(Set dst src); 5424 5425 ins_cost(125); 5426 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5427 ins_encode %{ 5428 address con = (address)$src$$constant; 5429 if (con == NULL) { 5430 ShouldNotReachHere(); 5431 } else { 5432 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5433 } 5434 %} 5435 ins_pipe(ialu_reg_fat); // XXX 5436 %} 5437 5438 instruct loadConF0(regF dst, immF0 src) 5439 %{ 5440 match(Set dst src); 5441 ins_cost(100); 5442 5443 format %{ "xorps $dst, $dst\t# float 0.0" %} 5444 ins_encode %{ 5445 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5446 %} 5447 ins_pipe(pipe_slow); 5448 %} 5449 5450 // Use the same format since predicate() can not be used here. 5451 instruct loadConD(regD dst, immD con) %{ 5452 match(Set dst con); 5453 ins_cost(125); 5454 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5455 ins_encode %{ 5456 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5457 %} 5458 ins_pipe(pipe_slow); 5459 %} 5460 5461 instruct loadConD0(regD dst, immD0 src) 5462 %{ 5463 match(Set dst src); 5464 ins_cost(100); 5465 5466 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5467 ins_encode %{ 5468 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5469 %} 5470 ins_pipe(pipe_slow); 5471 %} 5472 5473 instruct loadSSI(rRegI dst, stackSlotI src) 5474 %{ 5475 match(Set dst src); 5476 5477 ins_cost(125); 5478 format %{ "movl $dst, $src\t# int stk" %} 5479 opcode(0x8B); 5480 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5481 ins_pipe(ialu_reg_mem); 5482 %} 5483 5484 instruct loadSSL(rRegL dst, stackSlotL src) 5485 %{ 5486 match(Set dst src); 5487 5488 ins_cost(125); 5489 format %{ "movq $dst, $src\t# long stk" %} 5490 opcode(0x8B); 5491 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5492 ins_pipe(ialu_reg_mem); 5493 %} 5494 5495 instruct loadSSP(rRegP dst, stackSlotP src) 5496 %{ 5497 match(Set dst src); 5498 5499 ins_cost(125); 5500 format %{ "movq $dst, $src\t# ptr stk" %} 5501 opcode(0x8B); 5502 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5503 ins_pipe(ialu_reg_mem); 5504 %} 5505 5506 instruct loadSSF(regF dst, stackSlotF src) 5507 %{ 5508 match(Set dst src); 5509 5510 ins_cost(125); 5511 format %{ "movss $dst, $src\t# float stk" %} 5512 ins_encode %{ 5513 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5514 %} 5515 ins_pipe(pipe_slow); // XXX 5516 %} 5517 5518 // Use the same format since predicate() can not be used here. 5519 instruct loadSSD(regD dst, stackSlotD src) 5520 %{ 5521 match(Set dst src); 5522 5523 ins_cost(125); 5524 format %{ "movsd $dst, $src\t# double stk" %} 5525 ins_encode %{ 5526 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5527 %} 5528 ins_pipe(pipe_slow); // XXX 5529 %} 5530 5531 // Prefetch instructions. 5532 // Must be safe to execute with invalid address (cannot fault). 5533 5534 instruct prefetchr( memory mem ) %{ 5535 predicate(ReadPrefetchInstr==3); 5536 match(PrefetchRead mem); 5537 ins_cost(125); 5538 5539 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} 5540 ins_encode %{ 5541 __ prefetchr($mem$$Address); 5542 %} 5543 ins_pipe(ialu_mem); 5544 %} 5545 5546 instruct prefetchrNTA( memory mem ) %{ 5547 predicate(ReadPrefetchInstr==0); 5548 match(PrefetchRead mem); 5549 ins_cost(125); 5550 5551 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} 5552 ins_encode %{ 5553 __ prefetchnta($mem$$Address); 5554 %} 5555 ins_pipe(ialu_mem); 5556 %} 5557 5558 instruct prefetchrT0( memory mem ) %{ 5559 predicate(ReadPrefetchInstr==1); 5560 match(PrefetchRead mem); 5561 ins_cost(125); 5562 5563 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} 5564 ins_encode %{ 5565 __ prefetcht0($mem$$Address); 5566 %} 5567 ins_pipe(ialu_mem); 5568 %} 5569 5570 instruct prefetchrT2( memory mem ) %{ 5571 predicate(ReadPrefetchInstr==2); 5572 match(PrefetchRead mem); 5573 ins_cost(125); 5574 5575 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} 5576 ins_encode %{ 5577 __ prefetcht2($mem$$Address); 5578 %} 5579 ins_pipe(ialu_mem); 5580 %} 5581 5582 instruct prefetchwNTA( memory mem ) %{ 5583 match(PrefetchWrite mem); 5584 ins_cost(125); 5585 5586 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} 5587 ins_encode %{ 5588 __ prefetchnta($mem$$Address); 5589 %} 5590 ins_pipe(ialu_mem); 5591 %} 5592 5593 // Prefetch instructions for allocation. 5594 5595 instruct prefetchAlloc( memory mem ) %{ 5596 predicate(AllocatePrefetchInstr==3); 5597 match(PrefetchAllocation mem); 5598 ins_cost(125); 5599 5600 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5601 ins_encode %{ 5602 __ prefetchw($mem$$Address); 5603 %} 5604 ins_pipe(ialu_mem); 5605 %} 5606 5607 instruct prefetchAllocNTA( memory mem ) %{ 5608 predicate(AllocatePrefetchInstr==0); 5609 match(PrefetchAllocation mem); 5610 ins_cost(125); 5611 5612 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5613 ins_encode %{ 5614 __ prefetchnta($mem$$Address); 5615 %} 5616 ins_pipe(ialu_mem); 5617 %} 5618 5619 instruct prefetchAllocT0( memory mem ) %{ 5620 predicate(AllocatePrefetchInstr==1); 5621 match(PrefetchAllocation mem); 5622 ins_cost(125); 5623 5624 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5625 ins_encode %{ 5626 __ prefetcht0($mem$$Address); 5627 %} 5628 ins_pipe(ialu_mem); 5629 %} 5630 5631 instruct prefetchAllocT2( memory mem ) %{ 5632 predicate(AllocatePrefetchInstr==2); 5633 match(PrefetchAllocation mem); 5634 ins_cost(125); 5635 5636 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5637 ins_encode %{ 5638 __ prefetcht2($mem$$Address); 5639 %} 5640 ins_pipe(ialu_mem); 5641 %} 5642 5643 //----------Store Instructions------------------------------------------------- 5644 5645 // Store Byte 5646 instruct storeB(memory mem, rRegI src) 5647 %{ 5648 match(Set mem (StoreB mem src)); 5649 5650 ins_cost(125); // XXX 5651 format %{ "movb $mem, $src\t# byte" %} 5652 opcode(0x88); 5653 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5654 ins_pipe(ialu_mem_reg); 5655 %} 5656 5657 // Store Char/Short 5658 instruct storeC(memory mem, rRegI src) 5659 %{ 5660 match(Set mem (StoreC mem src)); 5661 5662 ins_cost(125); // XXX 5663 format %{ "movw $mem, $src\t# char/short" %} 5664 opcode(0x89); 5665 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5666 ins_pipe(ialu_mem_reg); 5667 %} 5668 5669 // Store Integer 5670 instruct storeI(memory mem, rRegI src) 5671 %{ 5672 match(Set mem (StoreI mem src)); 5673 5674 ins_cost(125); // XXX 5675 format %{ "movl $mem, $src\t# int" %} 5676 opcode(0x89); 5677 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5678 ins_pipe(ialu_mem_reg); 5679 %} 5680 5681 // Store Long 5682 instruct storeL(memory mem, rRegL src) 5683 %{ 5684 match(Set mem (StoreL mem src)); 5685 5686 ins_cost(125); // XXX 5687 format %{ "movq $mem, $src\t# long" %} 5688 opcode(0x89); 5689 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5690 ins_pipe(ialu_mem_reg); // XXX 5691 %} 5692 5693 // Store Pointer 5694 instruct storeP(memory mem, any_RegP src) 5695 %{ 5696 match(Set mem (StoreP mem src)); 5697 5698 ins_cost(125); // XXX 5699 format %{ "movq $mem, $src\t# ptr" %} 5700 opcode(0x89); 5701 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5702 ins_pipe(ialu_mem_reg); 5703 %} 5704 5705 instruct storeImmP0(memory mem, immP0 zero) 5706 %{ 5707 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5708 match(Set mem (StoreP mem zero)); 5709 5710 ins_cost(125); // XXX 5711 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5712 ins_encode %{ 5713 __ movq($mem$$Address, r12); 5714 %} 5715 ins_pipe(ialu_mem_reg); 5716 %} 5717 5718 // Store NULL Pointer, mark word, or other simple pointer constant. 5719 instruct storeImmP(memory mem, immP31 src) 5720 %{ 5721 match(Set mem (StoreP mem src)); 5722 5723 ins_cost(150); // XXX 5724 format %{ "movq $mem, $src\t# ptr" %} 5725 opcode(0xC7); /* C7 /0 */ 5726 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5727 ins_pipe(ialu_mem_imm); 5728 %} 5729 5730 // Store Compressed Pointer 5731 instruct storeN(memory mem, rRegN src) 5732 %{ 5733 match(Set mem (StoreN mem src)); 5734 5735 ins_cost(125); // XXX 5736 format %{ "movl $mem, $src\t# compressed ptr" %} 5737 ins_encode %{ 5738 __ movl($mem$$Address, $src$$Register); 5739 %} 5740 ins_pipe(ialu_mem_reg); 5741 %} 5742 5743 instruct storeNKlass(memory mem, rRegN src) 5744 %{ 5745 match(Set mem (StoreNKlass mem src)); 5746 5747 ins_cost(125); // XXX 5748 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5749 ins_encode %{ 5750 __ movl($mem$$Address, $src$$Register); 5751 %} 5752 ins_pipe(ialu_mem_reg); 5753 %} 5754 5755 instruct storeImmN0(memory mem, immN0 zero) 5756 %{ 5757 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5758 match(Set mem (StoreN mem zero)); 5759 5760 ins_cost(125); // XXX 5761 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5762 ins_encode %{ 5763 __ movl($mem$$Address, r12); 5764 %} 5765 ins_pipe(ialu_mem_reg); 5766 %} 5767 5768 instruct storeImmN(memory mem, immN src) 5769 %{ 5770 match(Set mem (StoreN mem src)); 5771 5772 ins_cost(150); // XXX 5773 format %{ "movl $mem, $src\t# compressed ptr" %} 5774 ins_encode %{ 5775 address con = (address)$src$$constant; 5776 if (con == NULL) { 5777 __ movl($mem$$Address, (int32_t)0); 5778 } else { 5779 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5780 } 5781 %} 5782 ins_pipe(ialu_mem_imm); 5783 %} 5784 5785 instruct storeImmNKlass(memory mem, immNKlass src) 5786 %{ 5787 match(Set mem (StoreNKlass mem src)); 5788 5789 ins_cost(150); // XXX 5790 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5791 ins_encode %{ 5792 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5793 %} 5794 ins_pipe(ialu_mem_imm); 5795 %} 5796 5797 // Store Integer Immediate 5798 instruct storeImmI0(memory mem, immI0 zero) 5799 %{ 5800 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5801 match(Set mem (StoreI mem zero)); 5802 5803 ins_cost(125); // XXX 5804 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5805 ins_encode %{ 5806 __ movl($mem$$Address, r12); 5807 %} 5808 ins_pipe(ialu_mem_reg); 5809 %} 5810 5811 instruct storeImmI(memory mem, immI src) 5812 %{ 5813 match(Set mem (StoreI mem src)); 5814 5815 ins_cost(150); 5816 format %{ "movl $mem, $src\t# int" %} 5817 opcode(0xC7); /* C7 /0 */ 5818 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5819 ins_pipe(ialu_mem_imm); 5820 %} 5821 5822 // Store Long Immediate 5823 instruct storeImmL0(memory mem, immL0 zero) 5824 %{ 5825 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5826 match(Set mem (StoreL mem zero)); 5827 5828 ins_cost(125); // XXX 5829 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5830 ins_encode %{ 5831 __ movq($mem$$Address, r12); 5832 %} 5833 ins_pipe(ialu_mem_reg); 5834 %} 5835 5836 instruct storeImmL(memory mem, immL32 src) 5837 %{ 5838 match(Set mem (StoreL mem src)); 5839 5840 ins_cost(150); 5841 format %{ "movq $mem, $src\t# long" %} 5842 opcode(0xC7); /* C7 /0 */ 5843 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5844 ins_pipe(ialu_mem_imm); 5845 %} 5846 5847 // Store Short/Char Immediate 5848 instruct storeImmC0(memory mem, immI0 zero) 5849 %{ 5850 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5851 match(Set mem (StoreC mem zero)); 5852 5853 ins_cost(125); // XXX 5854 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5855 ins_encode %{ 5856 __ movw($mem$$Address, r12); 5857 %} 5858 ins_pipe(ialu_mem_reg); 5859 %} 5860 5861 instruct storeImmI16(memory mem, immI16 src) 5862 %{ 5863 predicate(UseStoreImmI16); 5864 match(Set mem (StoreC mem src)); 5865 5866 ins_cost(150); 5867 format %{ "movw $mem, $src\t# short/char" %} 5868 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 5869 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 5870 ins_pipe(ialu_mem_imm); 5871 %} 5872 5873 // Store Byte Immediate 5874 instruct storeImmB0(memory mem, immI0 zero) 5875 %{ 5876 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5877 match(Set mem (StoreB mem zero)); 5878 5879 ins_cost(125); // XXX 5880 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5881 ins_encode %{ 5882 __ movb($mem$$Address, r12); 5883 %} 5884 ins_pipe(ialu_mem_reg); 5885 %} 5886 5887 instruct storeImmB(memory mem, immI8 src) 5888 %{ 5889 match(Set mem (StoreB mem src)); 5890 5891 ins_cost(150); // XXX 5892 format %{ "movb $mem, $src\t# byte" %} 5893 opcode(0xC6); /* C6 /0 */ 5894 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5895 ins_pipe(ialu_mem_imm); 5896 %} 5897 5898 // Store CMS card-mark Immediate 5899 instruct storeImmCM0_reg(memory mem, immI0 zero) 5900 %{ 5901 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5902 match(Set mem (StoreCM mem zero)); 5903 5904 ins_cost(125); // XXX 5905 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5906 ins_encode %{ 5907 __ movb($mem$$Address, r12); 5908 %} 5909 ins_pipe(ialu_mem_reg); 5910 %} 5911 5912 instruct storeImmCM0(memory mem, immI0 src) 5913 %{ 5914 match(Set mem (StoreCM mem src)); 5915 5916 ins_cost(150); // XXX 5917 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5918 opcode(0xC6); /* C6 /0 */ 5919 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5920 ins_pipe(ialu_mem_imm); 5921 %} 5922 5923 // Store Float 5924 instruct storeF(memory mem, regF src) 5925 %{ 5926 match(Set mem (StoreF mem src)); 5927 5928 ins_cost(95); // XXX 5929 format %{ "movss $mem, $src\t# float" %} 5930 ins_encode %{ 5931 __ movflt($mem$$Address, $src$$XMMRegister); 5932 %} 5933 ins_pipe(pipe_slow); // XXX 5934 %} 5935 5936 // Store immediate Float value (it is faster than store from XMM register) 5937 instruct storeF0(memory mem, immF0 zero) 5938 %{ 5939 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5940 match(Set mem (StoreF mem zero)); 5941 5942 ins_cost(25); // XXX 5943 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5944 ins_encode %{ 5945 __ movl($mem$$Address, r12); 5946 %} 5947 ins_pipe(ialu_mem_reg); 5948 %} 5949 5950 instruct storeF_imm(memory mem, immF src) 5951 %{ 5952 match(Set mem (StoreF mem src)); 5953 5954 ins_cost(50); 5955 format %{ "movl $mem, $src\t# float" %} 5956 opcode(0xC7); /* C7 /0 */ 5957 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5958 ins_pipe(ialu_mem_imm); 5959 %} 5960 5961 // Store Double 5962 instruct storeD(memory mem, regD src) 5963 %{ 5964 match(Set mem (StoreD mem src)); 5965 5966 ins_cost(95); // XXX 5967 format %{ "movsd $mem, $src\t# double" %} 5968 ins_encode %{ 5969 __ movdbl($mem$$Address, $src$$XMMRegister); 5970 %} 5971 ins_pipe(pipe_slow); // XXX 5972 %} 5973 5974 // Store immediate double 0.0 (it is faster than store from XMM register) 5975 instruct storeD0_imm(memory mem, immD0 src) 5976 %{ 5977 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 5978 match(Set mem (StoreD mem src)); 5979 5980 ins_cost(50); 5981 format %{ "movq $mem, $src\t# double 0." %} 5982 opcode(0xC7); /* C7 /0 */ 5983 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5984 ins_pipe(ialu_mem_imm); 5985 %} 5986 5987 instruct storeD0(memory mem, immD0 zero) 5988 %{ 5989 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5990 match(Set mem (StoreD mem zero)); 5991 5992 ins_cost(25); // XXX 5993 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5994 ins_encode %{ 5995 __ movq($mem$$Address, r12); 5996 %} 5997 ins_pipe(ialu_mem_reg); 5998 %} 5999 6000 instruct storeSSI(stackSlotI dst, rRegI src) 6001 %{ 6002 match(Set dst src); 6003 6004 ins_cost(100); 6005 format %{ "movl $dst, $src\t# int stk" %} 6006 opcode(0x89); 6007 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6008 ins_pipe( ialu_mem_reg ); 6009 %} 6010 6011 instruct storeSSL(stackSlotL dst, rRegL src) 6012 %{ 6013 match(Set dst src); 6014 6015 ins_cost(100); 6016 format %{ "movq $dst, $src\t# long stk" %} 6017 opcode(0x89); 6018 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6019 ins_pipe(ialu_mem_reg); 6020 %} 6021 6022 instruct storeSSP(stackSlotP dst, rRegP src) 6023 %{ 6024 match(Set dst src); 6025 6026 ins_cost(100); 6027 format %{ "movq $dst, $src\t# ptr stk" %} 6028 opcode(0x89); 6029 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6030 ins_pipe(ialu_mem_reg); 6031 %} 6032 6033 instruct storeSSF(stackSlotF dst, regF src) 6034 %{ 6035 match(Set dst src); 6036 6037 ins_cost(95); // XXX 6038 format %{ "movss $dst, $src\t# float stk" %} 6039 ins_encode %{ 6040 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6041 %} 6042 ins_pipe(pipe_slow); // XXX 6043 %} 6044 6045 instruct storeSSD(stackSlotD dst, regD src) 6046 %{ 6047 match(Set dst src); 6048 6049 ins_cost(95); // XXX 6050 format %{ "movsd $dst, $src\t# double stk" %} 6051 ins_encode %{ 6052 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6053 %} 6054 ins_pipe(pipe_slow); // XXX 6055 %} 6056 6057 //----------BSWAP Instructions------------------------------------------------- 6058 instruct bytes_reverse_int(rRegI dst) %{ 6059 match(Set dst (ReverseBytesI dst)); 6060 6061 format %{ "bswapl $dst" %} 6062 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6063 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6064 ins_pipe( ialu_reg ); 6065 %} 6066 6067 instruct bytes_reverse_long(rRegL dst) %{ 6068 match(Set dst (ReverseBytesL dst)); 6069 6070 format %{ "bswapq $dst" %} 6071 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6072 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6073 ins_pipe( ialu_reg); 6074 %} 6075 6076 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6077 match(Set dst (ReverseBytesUS dst)); 6078 effect(KILL cr); 6079 6080 format %{ "bswapl $dst\n\t" 6081 "shrl $dst,16\n\t" %} 6082 ins_encode %{ 6083 __ bswapl($dst$$Register); 6084 __ shrl($dst$$Register, 16); 6085 %} 6086 ins_pipe( ialu_reg ); 6087 %} 6088 6089 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6090 match(Set dst (ReverseBytesS dst)); 6091 effect(KILL cr); 6092 6093 format %{ "bswapl $dst\n\t" 6094 "sar $dst,16\n\t" %} 6095 ins_encode %{ 6096 __ bswapl($dst$$Register); 6097 __ sarl($dst$$Register, 16); 6098 %} 6099 ins_pipe( ialu_reg ); 6100 %} 6101 6102 //---------- Zeros Count Instructions ------------------------------------------ 6103 6104 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6105 predicate(UseCountLeadingZerosInstruction); 6106 match(Set dst (CountLeadingZerosI src)); 6107 effect(KILL cr); 6108 6109 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6110 ins_encode %{ 6111 __ lzcntl($dst$$Register, $src$$Register); 6112 %} 6113 ins_pipe(ialu_reg); 6114 %} 6115 6116 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6117 predicate(!UseCountLeadingZerosInstruction); 6118 match(Set dst (CountLeadingZerosI src)); 6119 effect(KILL cr); 6120 6121 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6122 "jnz skip\n\t" 6123 "movl $dst, -1\n" 6124 "skip:\n\t" 6125 "negl $dst\n\t" 6126 "addl $dst, 31" %} 6127 ins_encode %{ 6128 Register Rdst = $dst$$Register; 6129 Register Rsrc = $src$$Register; 6130 Label skip; 6131 __ bsrl(Rdst, Rsrc); 6132 __ jccb(Assembler::notZero, skip); 6133 __ movl(Rdst, -1); 6134 __ bind(skip); 6135 __ negl(Rdst); 6136 __ addl(Rdst, BitsPerInt - 1); 6137 %} 6138 ins_pipe(ialu_reg); 6139 %} 6140 6141 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6142 predicate(UseCountLeadingZerosInstruction); 6143 match(Set dst (CountLeadingZerosL src)); 6144 effect(KILL cr); 6145 6146 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6147 ins_encode %{ 6148 __ lzcntq($dst$$Register, $src$$Register); 6149 %} 6150 ins_pipe(ialu_reg); 6151 %} 6152 6153 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6154 predicate(!UseCountLeadingZerosInstruction); 6155 match(Set dst (CountLeadingZerosL src)); 6156 effect(KILL cr); 6157 6158 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6159 "jnz skip\n\t" 6160 "movl $dst, -1\n" 6161 "skip:\n\t" 6162 "negl $dst\n\t" 6163 "addl $dst, 63" %} 6164 ins_encode %{ 6165 Register Rdst = $dst$$Register; 6166 Register Rsrc = $src$$Register; 6167 Label skip; 6168 __ bsrq(Rdst, Rsrc); 6169 __ jccb(Assembler::notZero, skip); 6170 __ movl(Rdst, -1); 6171 __ bind(skip); 6172 __ negl(Rdst); 6173 __ addl(Rdst, BitsPerLong - 1); 6174 %} 6175 ins_pipe(ialu_reg); 6176 %} 6177 6178 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6179 predicate(UseCountTrailingZerosInstruction); 6180 match(Set dst (CountTrailingZerosI src)); 6181 effect(KILL cr); 6182 6183 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6184 ins_encode %{ 6185 __ tzcntl($dst$$Register, $src$$Register); 6186 %} 6187 ins_pipe(ialu_reg); 6188 %} 6189 6190 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6191 predicate(!UseCountTrailingZerosInstruction); 6192 match(Set dst (CountTrailingZerosI src)); 6193 effect(KILL cr); 6194 6195 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6196 "jnz done\n\t" 6197 "movl $dst, 32\n" 6198 "done:" %} 6199 ins_encode %{ 6200 Register Rdst = $dst$$Register; 6201 Label done; 6202 __ bsfl(Rdst, $src$$Register); 6203 __ jccb(Assembler::notZero, done); 6204 __ movl(Rdst, BitsPerInt); 6205 __ bind(done); 6206 %} 6207 ins_pipe(ialu_reg); 6208 %} 6209 6210 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6211 predicate(UseCountTrailingZerosInstruction); 6212 match(Set dst (CountTrailingZerosL src)); 6213 effect(KILL cr); 6214 6215 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6216 ins_encode %{ 6217 __ tzcntq($dst$$Register, $src$$Register); 6218 %} 6219 ins_pipe(ialu_reg); 6220 %} 6221 6222 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6223 predicate(!UseCountTrailingZerosInstruction); 6224 match(Set dst (CountTrailingZerosL src)); 6225 effect(KILL cr); 6226 6227 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6228 "jnz done\n\t" 6229 "movl $dst, 64\n" 6230 "done:" %} 6231 ins_encode %{ 6232 Register Rdst = $dst$$Register; 6233 Label done; 6234 __ bsfq(Rdst, $src$$Register); 6235 __ jccb(Assembler::notZero, done); 6236 __ movl(Rdst, BitsPerLong); 6237 __ bind(done); 6238 %} 6239 ins_pipe(ialu_reg); 6240 %} 6241 6242 6243 //---------- Population Count Instructions ------------------------------------- 6244 6245 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6246 predicate(UsePopCountInstruction); 6247 match(Set dst (PopCountI src)); 6248 effect(KILL cr); 6249 6250 format %{ "popcnt $dst, $src" %} 6251 ins_encode %{ 6252 __ popcntl($dst$$Register, $src$$Register); 6253 %} 6254 ins_pipe(ialu_reg); 6255 %} 6256 6257 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6258 predicate(UsePopCountInstruction); 6259 match(Set dst (PopCountI (LoadI mem))); 6260 effect(KILL cr); 6261 6262 format %{ "popcnt $dst, $mem" %} 6263 ins_encode %{ 6264 __ popcntl($dst$$Register, $mem$$Address); 6265 %} 6266 ins_pipe(ialu_reg); 6267 %} 6268 6269 // Note: Long.bitCount(long) returns an int. 6270 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6271 predicate(UsePopCountInstruction); 6272 match(Set dst (PopCountL src)); 6273 effect(KILL cr); 6274 6275 format %{ "popcnt $dst, $src" %} 6276 ins_encode %{ 6277 __ popcntq($dst$$Register, $src$$Register); 6278 %} 6279 ins_pipe(ialu_reg); 6280 %} 6281 6282 // Note: Long.bitCount(long) returns an int. 6283 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6284 predicate(UsePopCountInstruction); 6285 match(Set dst (PopCountL (LoadL mem))); 6286 effect(KILL cr); 6287 6288 format %{ "popcnt $dst, $mem" %} 6289 ins_encode %{ 6290 __ popcntq($dst$$Register, $mem$$Address); 6291 %} 6292 ins_pipe(ialu_reg); 6293 %} 6294 6295 6296 //----------MemBar Instructions----------------------------------------------- 6297 // Memory barrier flavors 6298 6299 instruct membar_acquire() 6300 %{ 6301 match(MemBarAcquire); 6302 match(LoadFence); 6303 ins_cost(0); 6304 6305 size(0); 6306 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6307 ins_encode(); 6308 ins_pipe(empty); 6309 %} 6310 6311 instruct membar_acquire_lock() 6312 %{ 6313 match(MemBarAcquireLock); 6314 ins_cost(0); 6315 6316 size(0); 6317 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6318 ins_encode(); 6319 ins_pipe(empty); 6320 %} 6321 6322 instruct membar_release() 6323 %{ 6324 match(MemBarRelease); 6325 match(StoreFence); 6326 ins_cost(0); 6327 6328 size(0); 6329 format %{ "MEMBAR-release ! (empty encoding)" %} 6330 ins_encode(); 6331 ins_pipe(empty); 6332 %} 6333 6334 instruct membar_release_lock() 6335 %{ 6336 match(MemBarReleaseLock); 6337 ins_cost(0); 6338 6339 size(0); 6340 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6341 ins_encode(); 6342 ins_pipe(empty); 6343 %} 6344 6345 instruct membar_volatile(rFlagsReg cr) %{ 6346 match(MemBarVolatile); 6347 effect(KILL cr); 6348 ins_cost(400); 6349 6350 format %{ 6351 $$template 6352 if (os::is_MP()) { 6353 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6354 } else { 6355 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6356 } 6357 %} 6358 ins_encode %{ 6359 __ membar(Assembler::StoreLoad); 6360 %} 6361 ins_pipe(pipe_slow); 6362 %} 6363 6364 instruct unnecessary_membar_volatile() 6365 %{ 6366 match(MemBarVolatile); 6367 predicate(Matcher::post_store_load_barrier(n)); 6368 ins_cost(0); 6369 6370 size(0); 6371 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6372 ins_encode(); 6373 ins_pipe(empty); 6374 %} 6375 6376 instruct membar_storestore() %{ 6377 match(MemBarStoreStore); 6378 ins_cost(0); 6379 6380 size(0); 6381 format %{ "MEMBAR-storestore (empty encoding)" %} 6382 ins_encode( ); 6383 ins_pipe(empty); 6384 %} 6385 6386 //----------Move Instructions-------------------------------------------------- 6387 6388 instruct castX2P(rRegP dst, rRegL src) 6389 %{ 6390 match(Set dst (CastX2P src)); 6391 6392 format %{ "movq $dst, $src\t# long->ptr" %} 6393 ins_encode %{ 6394 if ($dst$$reg != $src$$reg) { 6395 __ movptr($dst$$Register, $src$$Register); 6396 } 6397 %} 6398 ins_pipe(ialu_reg_reg); // XXX 6399 %} 6400 6401 instruct castP2X(rRegL dst, rRegP src) 6402 %{ 6403 match(Set dst (CastP2X src)); 6404 6405 format %{ "movq $dst, $src\t# ptr -> long" %} 6406 ins_encode %{ 6407 if ($dst$$reg != $src$$reg) { 6408 __ movptr($dst$$Register, $src$$Register); 6409 } 6410 %} 6411 ins_pipe(ialu_reg_reg); // XXX 6412 %} 6413 6414 // Convert oop into int for vectors alignment masking 6415 instruct convP2I(rRegI dst, rRegP src) 6416 %{ 6417 match(Set dst (ConvL2I (CastP2X src))); 6418 6419 format %{ "movl $dst, $src\t# ptr -> int" %} 6420 ins_encode %{ 6421 __ movl($dst$$Register, $src$$Register); 6422 %} 6423 ins_pipe(ialu_reg_reg); // XXX 6424 %} 6425 6426 // Convert compressed oop into int for vectors alignment masking 6427 // in case of 32bit oops (heap < 4Gb). 6428 instruct convN2I(rRegI dst, rRegN src) 6429 %{ 6430 predicate(Universe::narrow_oop_shift() == 0); 6431 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6432 6433 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6434 ins_encode %{ 6435 __ movl($dst$$Register, $src$$Register); 6436 %} 6437 ins_pipe(ialu_reg_reg); // XXX 6438 %} 6439 6440 instruct shenandoahRB(rRegP dst, rRegP src, rFlagsReg cr) %{ 6441 match(Set dst (ShenandoahReadBarrier src)); 6442 effect(DEF dst, USE src); 6443 ins_cost(125); // XXX 6444 format %{ "shenandoah_rb $dst, $src" %} 6445 ins_encode %{ 6446 Register d = $dst$$Register; 6447 Register s = $src$$Register; 6448 __ movptr(d, Address(s, BrooksPointer::byte_offset())); 6449 %} 6450 ins_pipe(ialu_reg_mem); 6451 %} 6452 6453 instruct shenandoahRBNarrow(rRegP dst, rRegN src) %{ 6454 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == 0)); 6455 match(Set dst (ShenandoahReadBarrier (DecodeN src))); 6456 effect(DEF dst, USE src); 6457 ins_cost(125); // XXX 6458 format %{ "shenandoah_rb $dst, $src" %} 6459 ins_encode %{ 6460 Register d = $dst$$Register; 6461 Register s = $src$$Register; 6462 __ movptr(d, Address(r12, s, Address::times_1, BrooksPointer::byte_offset())); 6463 %} 6464 ins_pipe(ialu_reg_mem); 6465 %} 6466 6467 instruct shenandoahRBNarrowShift(rRegP dst, rRegN src) %{ 6468 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 6469 match(Set dst (ShenandoahReadBarrier (DecodeN src))); 6470 effect(DEF dst, USE src); 6471 ins_cost(125); // XXX 6472 format %{ "shenandoah_rb $dst, $src" %} 6473 ins_encode %{ 6474 Register d = $dst$$Register; 6475 Register s = $src$$Register; 6476 __ movptr(d, Address(r12, s, Address::times_8, BrooksPointer::byte_offset())); 6477 %} 6478 ins_pipe(ialu_reg_mem); 6479 %} 6480 6481 // Convert oop pointer into compressed form 6482 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6483 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6484 match(Set dst (EncodeP src)); 6485 effect(KILL cr); 6486 format %{ "encode_heap_oop $dst,$src" %} 6487 ins_encode %{ 6488 Register s = $src$$Register; 6489 Register d = $dst$$Register; 6490 if (s != d) { 6491 __ movq(d, s); 6492 } 6493 __ encode_heap_oop(d); 6494 %} 6495 ins_pipe(ialu_reg_long); 6496 %} 6497 6498 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6499 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6500 match(Set dst (EncodeP src)); 6501 effect(KILL cr); 6502 format %{ "encode_heap_oop_not_null $dst,$src" %} 6503 ins_encode %{ 6504 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6505 %} 6506 ins_pipe(ialu_reg_long); 6507 %} 6508 6509 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6510 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6511 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6512 match(Set dst (DecodeN src)); 6513 effect(KILL cr); 6514 format %{ "decode_heap_oop $dst,$src" %} 6515 ins_encode %{ 6516 Register s = $src$$Register; 6517 Register d = $dst$$Register; 6518 if (s != d) { 6519 __ movq(d, s); 6520 } 6521 __ decode_heap_oop(d); 6522 %} 6523 ins_pipe(ialu_reg_long); 6524 %} 6525 6526 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6527 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6528 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6529 match(Set dst (DecodeN src)); 6530 effect(KILL cr); 6531 format %{ "decode_heap_oop_not_null $dst,$src" %} 6532 ins_encode %{ 6533 Register s = $src$$Register; 6534 Register d = $dst$$Register; 6535 if (s != d) { 6536 __ decode_heap_oop_not_null(d, s); 6537 } else { 6538 __ decode_heap_oop_not_null(d); 6539 } 6540 %} 6541 ins_pipe(ialu_reg_long); 6542 %} 6543 6544 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6545 match(Set dst (EncodePKlass src)); 6546 effect(KILL cr); 6547 format %{ "encode_klass_not_null $dst,$src" %} 6548 ins_encode %{ 6549 __ encode_klass_not_null($dst$$Register, $src$$Register); 6550 %} 6551 ins_pipe(ialu_reg_long); 6552 %} 6553 6554 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6555 match(Set dst (DecodeNKlass src)); 6556 effect(KILL cr); 6557 format %{ "decode_klass_not_null $dst,$src" %} 6558 ins_encode %{ 6559 Register s = $src$$Register; 6560 Register d = $dst$$Register; 6561 if (s != d) { 6562 __ decode_klass_not_null(d, s); 6563 } else { 6564 __ decode_klass_not_null(d); 6565 } 6566 %} 6567 ins_pipe(ialu_reg_long); 6568 %} 6569 6570 6571 //----------Conditional Move--------------------------------------------------- 6572 // Jump 6573 // dummy instruction for generating temp registers 6574 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6575 match(Jump (LShiftL switch_val shift)); 6576 ins_cost(350); 6577 predicate(false); 6578 effect(TEMP dest); 6579 6580 format %{ "leaq $dest, [$constantaddress]\n\t" 6581 "jmp [$dest + $switch_val << $shift]\n\t" %} 6582 ins_encode %{ 6583 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6584 // to do that and the compiler is using that register as one it can allocate. 6585 // So we build it all by hand. 6586 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6587 // ArrayAddress dispatch(table, index); 6588 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6589 __ lea($dest$$Register, $constantaddress); 6590 __ jmp(dispatch); 6591 %} 6592 ins_pipe(pipe_jmp); 6593 %} 6594 6595 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6596 match(Jump (AddL (LShiftL switch_val shift) offset)); 6597 ins_cost(350); 6598 effect(TEMP dest); 6599 6600 format %{ "leaq $dest, [$constantaddress]\n\t" 6601 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6602 ins_encode %{ 6603 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6604 // to do that and the compiler is using that register as one it can allocate. 6605 // So we build it all by hand. 6606 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6607 // ArrayAddress dispatch(table, index); 6608 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6609 __ lea($dest$$Register, $constantaddress); 6610 __ jmp(dispatch); 6611 %} 6612 ins_pipe(pipe_jmp); 6613 %} 6614 6615 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6616 match(Jump switch_val); 6617 ins_cost(350); 6618 effect(TEMP dest); 6619 6620 format %{ "leaq $dest, [$constantaddress]\n\t" 6621 "jmp [$dest + $switch_val]\n\t" %} 6622 ins_encode %{ 6623 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6624 // to do that and the compiler is using that register as one it can allocate. 6625 // So we build it all by hand. 6626 // Address index(noreg, switch_reg, Address::times_1); 6627 // ArrayAddress dispatch(table, index); 6628 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6629 __ lea($dest$$Register, $constantaddress); 6630 __ jmp(dispatch); 6631 %} 6632 ins_pipe(pipe_jmp); 6633 %} 6634 6635 // Conditional move 6636 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6637 %{ 6638 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6639 6640 ins_cost(200); // XXX 6641 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6642 opcode(0x0F, 0x40); 6643 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6644 ins_pipe(pipe_cmov_reg); 6645 %} 6646 6647 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6648 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6649 6650 ins_cost(200); // XXX 6651 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6652 opcode(0x0F, 0x40); 6653 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6654 ins_pipe(pipe_cmov_reg); 6655 %} 6656 6657 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6658 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6659 ins_cost(200); 6660 expand %{ 6661 cmovI_regU(cop, cr, dst, src); 6662 %} 6663 %} 6664 6665 // Conditional move 6666 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6667 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6668 6669 ins_cost(250); // XXX 6670 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6671 opcode(0x0F, 0x40); 6672 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6673 ins_pipe(pipe_cmov_mem); 6674 %} 6675 6676 // Conditional move 6677 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6678 %{ 6679 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6680 6681 ins_cost(250); // XXX 6682 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6683 opcode(0x0F, 0x40); 6684 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6685 ins_pipe(pipe_cmov_mem); 6686 %} 6687 6688 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6689 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6690 ins_cost(250); 6691 expand %{ 6692 cmovI_memU(cop, cr, dst, src); 6693 %} 6694 %} 6695 6696 // Conditional move 6697 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6698 %{ 6699 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6700 6701 ins_cost(200); // XXX 6702 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6703 opcode(0x0F, 0x40); 6704 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6705 ins_pipe(pipe_cmov_reg); 6706 %} 6707 6708 // Conditional move 6709 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6710 %{ 6711 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6712 6713 ins_cost(200); // XXX 6714 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6715 opcode(0x0F, 0x40); 6716 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6717 ins_pipe(pipe_cmov_reg); 6718 %} 6719 6720 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6721 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6722 ins_cost(200); 6723 expand %{ 6724 cmovN_regU(cop, cr, dst, src); 6725 %} 6726 %} 6727 6728 // Conditional move 6729 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6730 %{ 6731 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6732 6733 ins_cost(200); // XXX 6734 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6735 opcode(0x0F, 0x40); 6736 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6737 ins_pipe(pipe_cmov_reg); // XXX 6738 %} 6739 6740 // Conditional move 6741 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6742 %{ 6743 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6744 6745 ins_cost(200); // XXX 6746 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6747 opcode(0x0F, 0x40); 6748 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6749 ins_pipe(pipe_cmov_reg); // XXX 6750 %} 6751 6752 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6753 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6754 ins_cost(200); 6755 expand %{ 6756 cmovP_regU(cop, cr, dst, src); 6757 %} 6758 %} 6759 6760 // DISABLED: Requires the ADLC to emit a bottom_type call that 6761 // correctly meets the two pointer arguments; one is an incoming 6762 // register but the other is a memory operand. ALSO appears to 6763 // be buggy with implicit null checks. 6764 // 6765 //// Conditional move 6766 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6767 //%{ 6768 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6769 // ins_cost(250); 6770 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6771 // opcode(0x0F,0x40); 6772 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6773 // ins_pipe( pipe_cmov_mem ); 6774 //%} 6775 // 6776 //// Conditional move 6777 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6778 //%{ 6779 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6780 // ins_cost(250); 6781 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6782 // opcode(0x0F,0x40); 6783 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6784 // ins_pipe( pipe_cmov_mem ); 6785 //%} 6786 6787 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6788 %{ 6789 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6790 6791 ins_cost(200); // XXX 6792 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6793 opcode(0x0F, 0x40); 6794 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6795 ins_pipe(pipe_cmov_reg); // XXX 6796 %} 6797 6798 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6799 %{ 6800 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6801 6802 ins_cost(200); // XXX 6803 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6804 opcode(0x0F, 0x40); 6805 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6806 ins_pipe(pipe_cmov_mem); // XXX 6807 %} 6808 6809 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6810 %{ 6811 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6812 6813 ins_cost(200); // XXX 6814 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6815 opcode(0x0F, 0x40); 6816 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6817 ins_pipe(pipe_cmov_reg); // XXX 6818 %} 6819 6820 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6821 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6822 ins_cost(200); 6823 expand %{ 6824 cmovL_regU(cop, cr, dst, src); 6825 %} 6826 %} 6827 6828 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6829 %{ 6830 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6831 6832 ins_cost(200); // XXX 6833 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6834 opcode(0x0F, 0x40); 6835 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6836 ins_pipe(pipe_cmov_mem); // XXX 6837 %} 6838 6839 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6840 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6841 ins_cost(200); 6842 expand %{ 6843 cmovL_memU(cop, cr, dst, src); 6844 %} 6845 %} 6846 6847 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6848 %{ 6849 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6850 6851 ins_cost(200); // XXX 6852 format %{ "jn$cop skip\t# signed cmove float\n\t" 6853 "movss $dst, $src\n" 6854 "skip:" %} 6855 ins_encode %{ 6856 Label Lskip; 6857 // Invert sense of branch from sense of CMOV 6858 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6859 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6860 __ bind(Lskip); 6861 %} 6862 ins_pipe(pipe_slow); 6863 %} 6864 6865 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6866 // %{ 6867 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 6868 6869 // ins_cost(200); // XXX 6870 // format %{ "jn$cop skip\t# signed cmove float\n\t" 6871 // "movss $dst, $src\n" 6872 // "skip:" %} 6873 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 6874 // ins_pipe(pipe_slow); 6875 // %} 6876 6877 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6878 %{ 6879 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6880 6881 ins_cost(200); // XXX 6882 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6883 "movss $dst, $src\n" 6884 "skip:" %} 6885 ins_encode %{ 6886 Label Lskip; 6887 // Invert sense of branch from sense of CMOV 6888 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6889 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6890 __ bind(Lskip); 6891 %} 6892 ins_pipe(pipe_slow); 6893 %} 6894 6895 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6896 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6897 ins_cost(200); 6898 expand %{ 6899 cmovF_regU(cop, cr, dst, src); 6900 %} 6901 %} 6902 6903 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6904 %{ 6905 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6906 6907 ins_cost(200); // XXX 6908 format %{ "jn$cop skip\t# signed cmove double\n\t" 6909 "movsd $dst, $src\n" 6910 "skip:" %} 6911 ins_encode %{ 6912 Label Lskip; 6913 // Invert sense of branch from sense of CMOV 6914 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6915 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6916 __ bind(Lskip); 6917 %} 6918 ins_pipe(pipe_slow); 6919 %} 6920 6921 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6922 %{ 6923 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6924 6925 ins_cost(200); // XXX 6926 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6927 "movsd $dst, $src\n" 6928 "skip:" %} 6929 ins_encode %{ 6930 Label Lskip; 6931 // Invert sense of branch from sense of CMOV 6932 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6933 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6934 __ bind(Lskip); 6935 %} 6936 ins_pipe(pipe_slow); 6937 %} 6938 6939 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6940 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6941 ins_cost(200); 6942 expand %{ 6943 cmovD_regU(cop, cr, dst, src); 6944 %} 6945 %} 6946 6947 //----------Arithmetic Instructions-------------------------------------------- 6948 //----------Addition Instructions---------------------------------------------- 6949 6950 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6951 %{ 6952 match(Set dst (AddI dst src)); 6953 effect(KILL cr); 6954 6955 format %{ "addl $dst, $src\t# int" %} 6956 opcode(0x03); 6957 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 6958 ins_pipe(ialu_reg_reg); 6959 %} 6960 6961 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6962 %{ 6963 match(Set dst (AddI dst src)); 6964 effect(KILL cr); 6965 6966 format %{ "addl $dst, $src\t# int" %} 6967 opcode(0x81, 0x00); /* /0 id */ 6968 ins_encode(OpcSErm(dst, src), Con8or32(src)); 6969 ins_pipe( ialu_reg ); 6970 %} 6971 6972 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6973 %{ 6974 match(Set dst (AddI dst (LoadI src))); 6975 effect(KILL cr); 6976 6977 ins_cost(125); // XXX 6978 format %{ "addl $dst, $src\t# int" %} 6979 opcode(0x03); 6980 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6981 ins_pipe(ialu_reg_mem); 6982 %} 6983 6984 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6985 %{ 6986 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6987 effect(KILL cr); 6988 6989 ins_cost(150); // XXX 6990 format %{ "addl $dst, $src\t# int" %} 6991 opcode(0x01); /* Opcode 01 /r */ 6992 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6993 ins_pipe(ialu_mem_reg); 6994 %} 6995 6996 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6997 %{ 6998 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6999 effect(KILL cr); 7000 7001 ins_cost(125); // XXX 7002 format %{ "addl $dst, $src\t# int" %} 7003 opcode(0x81); /* Opcode 81 /0 id */ 7004 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7005 ins_pipe(ialu_mem_imm); 7006 %} 7007 7008 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7009 %{ 7010 predicate(UseIncDec); 7011 match(Set dst (AddI dst src)); 7012 effect(KILL cr); 7013 7014 format %{ "incl $dst\t# int" %} 7015 opcode(0xFF, 0x00); // FF /0 7016 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7017 ins_pipe(ialu_reg); 7018 %} 7019 7020 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7021 %{ 7022 predicate(UseIncDec); 7023 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7024 effect(KILL cr); 7025 7026 ins_cost(125); // XXX 7027 format %{ "incl $dst\t# int" %} 7028 opcode(0xFF); /* Opcode FF /0 */ 7029 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7030 ins_pipe(ialu_mem_imm); 7031 %} 7032 7033 // XXX why does that use AddI 7034 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7035 %{ 7036 predicate(UseIncDec); 7037 match(Set dst (AddI dst src)); 7038 effect(KILL cr); 7039 7040 format %{ "decl $dst\t# int" %} 7041 opcode(0xFF, 0x01); // FF /1 7042 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7043 ins_pipe(ialu_reg); 7044 %} 7045 7046 // XXX why does that use AddI 7047 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7048 %{ 7049 predicate(UseIncDec); 7050 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7051 effect(KILL cr); 7052 7053 ins_cost(125); // XXX 7054 format %{ "decl $dst\t# int" %} 7055 opcode(0xFF); /* Opcode FF /1 */ 7056 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7057 ins_pipe(ialu_mem_imm); 7058 %} 7059 7060 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7061 %{ 7062 match(Set dst (AddI src0 src1)); 7063 7064 ins_cost(110); 7065 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7066 opcode(0x8D); /* 0x8D /r */ 7067 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7068 ins_pipe(ialu_reg_reg); 7069 %} 7070 7071 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7072 %{ 7073 match(Set dst (AddL dst src)); 7074 effect(KILL cr); 7075 7076 format %{ "addq $dst, $src\t# long" %} 7077 opcode(0x03); 7078 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7079 ins_pipe(ialu_reg_reg); 7080 %} 7081 7082 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7083 %{ 7084 match(Set dst (AddL dst src)); 7085 effect(KILL cr); 7086 7087 format %{ "addq $dst, $src\t# long" %} 7088 opcode(0x81, 0x00); /* /0 id */ 7089 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7090 ins_pipe( ialu_reg ); 7091 %} 7092 7093 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7094 %{ 7095 match(Set dst (AddL dst (LoadL src))); 7096 effect(KILL cr); 7097 7098 ins_cost(125); // XXX 7099 format %{ "addq $dst, $src\t# long" %} 7100 opcode(0x03); 7101 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7102 ins_pipe(ialu_reg_mem); 7103 %} 7104 7105 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7106 %{ 7107 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7108 effect(KILL cr); 7109 7110 ins_cost(150); // XXX 7111 format %{ "addq $dst, $src\t# long" %} 7112 opcode(0x01); /* Opcode 01 /r */ 7113 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7114 ins_pipe(ialu_mem_reg); 7115 %} 7116 7117 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7118 %{ 7119 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7120 effect(KILL cr); 7121 7122 ins_cost(125); // XXX 7123 format %{ "addq $dst, $src\t# long" %} 7124 opcode(0x81); /* Opcode 81 /0 id */ 7125 ins_encode(REX_mem_wide(dst), 7126 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7127 ins_pipe(ialu_mem_imm); 7128 %} 7129 7130 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7131 %{ 7132 predicate(UseIncDec); 7133 match(Set dst (AddL dst src)); 7134 effect(KILL cr); 7135 7136 format %{ "incq $dst\t# long" %} 7137 opcode(0xFF, 0x00); // FF /0 7138 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7139 ins_pipe(ialu_reg); 7140 %} 7141 7142 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7143 %{ 7144 predicate(UseIncDec); 7145 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7146 effect(KILL cr); 7147 7148 ins_cost(125); // XXX 7149 format %{ "incq $dst\t# long" %} 7150 opcode(0xFF); /* Opcode FF /0 */ 7151 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7152 ins_pipe(ialu_mem_imm); 7153 %} 7154 7155 // XXX why does that use AddL 7156 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7157 %{ 7158 predicate(UseIncDec); 7159 match(Set dst (AddL dst src)); 7160 effect(KILL cr); 7161 7162 format %{ "decq $dst\t# long" %} 7163 opcode(0xFF, 0x01); // FF /1 7164 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7165 ins_pipe(ialu_reg); 7166 %} 7167 7168 // XXX why does that use AddL 7169 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7170 %{ 7171 predicate(UseIncDec); 7172 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7173 effect(KILL cr); 7174 7175 ins_cost(125); // XXX 7176 format %{ "decq $dst\t# long" %} 7177 opcode(0xFF); /* Opcode FF /1 */ 7178 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7179 ins_pipe(ialu_mem_imm); 7180 %} 7181 7182 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7183 %{ 7184 match(Set dst (AddL src0 src1)); 7185 7186 ins_cost(110); 7187 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7188 opcode(0x8D); /* 0x8D /r */ 7189 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7190 ins_pipe(ialu_reg_reg); 7191 %} 7192 7193 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7194 %{ 7195 match(Set dst (AddP dst src)); 7196 effect(KILL cr); 7197 7198 format %{ "addq $dst, $src\t# ptr" %} 7199 opcode(0x03); 7200 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7201 ins_pipe(ialu_reg_reg); 7202 %} 7203 7204 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7205 %{ 7206 match(Set dst (AddP dst src)); 7207 effect(KILL cr); 7208 7209 format %{ "addq $dst, $src\t# ptr" %} 7210 opcode(0x81, 0x00); /* /0 id */ 7211 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7212 ins_pipe( ialu_reg ); 7213 %} 7214 7215 // XXX addP mem ops ???? 7216 7217 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7218 %{ 7219 match(Set dst (AddP src0 src1)); 7220 7221 ins_cost(110); 7222 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7223 opcode(0x8D); /* 0x8D /r */ 7224 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7225 ins_pipe(ialu_reg_reg); 7226 %} 7227 7228 instruct checkCastPP(rRegP dst) 7229 %{ 7230 match(Set dst (CheckCastPP dst)); 7231 7232 size(0); 7233 format %{ "# checkcastPP of $dst" %} 7234 ins_encode(/* empty encoding */); 7235 ins_pipe(empty); 7236 %} 7237 7238 instruct castPP(rRegP dst) 7239 %{ 7240 match(Set dst (CastPP dst)); 7241 7242 size(0); 7243 format %{ "# castPP of $dst" %} 7244 ins_encode(/* empty encoding */); 7245 ins_pipe(empty); 7246 %} 7247 7248 instruct castII(rRegI dst) 7249 %{ 7250 match(Set dst (CastII dst)); 7251 7252 size(0); 7253 format %{ "# castII of $dst" %} 7254 ins_encode(/* empty encoding */); 7255 ins_cost(0); 7256 ins_pipe(empty); 7257 %} 7258 7259 // LoadP-locked same as a regular LoadP when used with compare-swap 7260 instruct loadPLocked(rRegP dst, memory mem) 7261 %{ 7262 match(Set dst (LoadPLocked mem)); 7263 7264 ins_cost(125); // XXX 7265 format %{ "movq $dst, $mem\t# ptr locked" %} 7266 opcode(0x8B); 7267 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7268 ins_pipe(ialu_reg_mem); // XXX 7269 %} 7270 7271 // Conditional-store of the updated heap-top. 7272 // Used during allocation of the shared heap. 7273 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7274 7275 instruct storePConditional(memory heap_top_ptr, 7276 rax_RegP oldval, rRegP newval, 7277 rFlagsReg cr) 7278 %{ 7279 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7280 7281 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7282 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7283 opcode(0x0F, 0xB1); 7284 ins_encode(lock_prefix, 7285 REX_reg_mem_wide(newval, heap_top_ptr), 7286 OpcP, OpcS, 7287 reg_mem(newval, heap_top_ptr)); 7288 ins_pipe(pipe_cmpxchg); 7289 %} 7290 7291 // Conditional-store of an int value. 7292 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7293 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7294 %{ 7295 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7296 effect(KILL oldval); 7297 7298 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7299 opcode(0x0F, 0xB1); 7300 ins_encode(lock_prefix, 7301 REX_reg_mem(newval, mem), 7302 OpcP, OpcS, 7303 reg_mem(newval, mem)); 7304 ins_pipe(pipe_cmpxchg); 7305 %} 7306 7307 // Conditional-store of a long value. 7308 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7309 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7310 %{ 7311 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7312 effect(KILL oldval); 7313 7314 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7315 opcode(0x0F, 0xB1); 7316 ins_encode(lock_prefix, 7317 REX_reg_mem_wide(newval, mem), 7318 OpcP, OpcS, 7319 reg_mem(newval, mem)); 7320 ins_pipe(pipe_cmpxchg); 7321 %} 7322 7323 7324 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7325 instruct compareAndSwapP(rRegI res, 7326 memory mem_ptr, 7327 rax_RegP oldval, rRegP newval, 7328 rFlagsReg cr) 7329 %{ 7330 predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); 7331 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7332 effect(KILL cr, KILL oldval); 7333 7334 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7335 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7336 "sete $res\n\t" 7337 "movzbl $res, $res" %} 7338 opcode(0x0F, 0xB1); 7339 ins_encode(lock_prefix, 7340 REX_reg_mem_wide(newval, mem_ptr), 7341 OpcP, OpcS, 7342 reg_mem(newval, mem_ptr), 7343 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7344 REX_reg_breg(res, res), // movzbl 7345 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7346 ins_pipe( pipe_cmpxchg ); 7347 %} 7348 7349 instruct compareAndSwapP_shenandoah(rRegI res, 7350 memory mem_ptr, 7351 rRegP tmp1, rRegP tmp2, 7352 rax_RegP oldval, rRegP newval, 7353 rFlagsReg cr) 7354 %{ 7355 predicate(VM_Version::supports_cx8() && UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR); 7356 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7357 effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 7358 7359 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7360 7361 ins_encode %{ 7362 __ cmpxchg_oop_shenandoah($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7363 false, // swap 7364 $tmp1$$Register, $tmp2$$Register 7365 ); 7366 %} 7367 ins_pipe( pipe_cmpxchg ); 7368 %} 7369 7370 instruct compareAndSwapL(rRegI res, 7371 memory mem_ptr, 7372 rax_RegL oldval, rRegL newval, 7373 rFlagsReg cr) 7374 %{ 7375 predicate(VM_Version::supports_cx8()); 7376 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7377 effect(KILL cr, KILL oldval); 7378 7379 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7380 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7381 "sete $res\n\t" 7382 "movzbl $res, $res" %} 7383 opcode(0x0F, 0xB1); 7384 ins_encode(lock_prefix, 7385 REX_reg_mem_wide(newval, mem_ptr), 7386 OpcP, OpcS, 7387 reg_mem(newval, mem_ptr), 7388 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7389 REX_reg_breg(res, res), // movzbl 7390 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7391 ins_pipe( pipe_cmpxchg ); 7392 %} 7393 7394 instruct compareAndSwapI(rRegI res, 7395 memory mem_ptr, 7396 rax_RegI oldval, rRegI newval, 7397 rFlagsReg cr) 7398 %{ 7399 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7400 effect(KILL cr, KILL oldval); 7401 7402 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7403 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7404 "sete $res\n\t" 7405 "movzbl $res, $res" %} 7406 opcode(0x0F, 0xB1); 7407 ins_encode(lock_prefix, 7408 REX_reg_mem(newval, mem_ptr), 7409 OpcP, OpcS, 7410 reg_mem(newval, mem_ptr), 7411 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7412 REX_reg_breg(res, res), // movzbl 7413 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7414 ins_pipe( pipe_cmpxchg ); 7415 %} 7416 7417 7418 instruct compareAndSwapN(rRegI res, 7419 memory mem_ptr, 7420 rax_RegN oldval, rRegN newval, 7421 rFlagsReg cr) %{ 7422 predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR); 7423 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7424 effect(KILL cr, KILL oldval); 7425 7426 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7427 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7428 "sete $res\n\t" 7429 "movzbl $res, $res" %} 7430 opcode(0x0F, 0xB1); 7431 ins_encode(lock_prefix, 7432 REX_reg_mem(newval, mem_ptr), 7433 OpcP, OpcS, 7434 reg_mem(newval, mem_ptr), 7435 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7436 REX_reg_breg(res, res), // movzbl 7437 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7438 ins_pipe( pipe_cmpxchg ); 7439 %} 7440 7441 instruct compareAndSwapN_shenandoah(rRegI res, 7442 memory mem_ptr, 7443 rRegP tmp1, rRegP tmp2, 7444 rax_RegN oldval, rRegN newval, 7445 rFlagsReg cr) %{ 7446 predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR); 7447 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7448 effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 7449 7450 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7451 7452 ins_encode %{ 7453 __ cmpxchg_oop_shenandoah($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7454 false, // swap 7455 $tmp1$$Register, $tmp2$$Register 7456 ); 7457 %} 7458 ins_pipe( pipe_cmpxchg ); 7459 %} 7460 7461 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7462 predicate(n->as_LoadStore()->result_not_used()); 7463 match(Set dummy (GetAndAddI mem add)); 7464 effect(KILL cr); 7465 format %{ "ADDL [$mem],$add" %} 7466 ins_encode %{ 7467 if (os::is_MP()) { __ lock(); } 7468 __ addl($mem$$Address, $add$$constant); 7469 %} 7470 ins_pipe( pipe_cmpxchg ); 7471 %} 7472 7473 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7474 match(Set newval (GetAndAddI mem newval)); 7475 effect(KILL cr); 7476 format %{ "XADDL [$mem],$newval" %} 7477 ins_encode %{ 7478 if (os::is_MP()) { __ lock(); } 7479 __ xaddl($mem$$Address, $newval$$Register); 7480 %} 7481 ins_pipe( pipe_cmpxchg ); 7482 %} 7483 7484 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7485 predicate(n->as_LoadStore()->result_not_used()); 7486 match(Set dummy (GetAndAddL mem add)); 7487 effect(KILL cr); 7488 format %{ "ADDQ [$mem],$add" %} 7489 ins_encode %{ 7490 if (os::is_MP()) { __ lock(); } 7491 __ addq($mem$$Address, $add$$constant); 7492 %} 7493 ins_pipe( pipe_cmpxchg ); 7494 %} 7495 7496 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7497 match(Set newval (GetAndAddL mem newval)); 7498 effect(KILL cr); 7499 format %{ "XADDQ [$mem],$newval" %} 7500 ins_encode %{ 7501 if (os::is_MP()) { __ lock(); } 7502 __ xaddq($mem$$Address, $newval$$Register); 7503 %} 7504 ins_pipe( pipe_cmpxchg ); 7505 %} 7506 7507 instruct xchgI( memory mem, rRegI newval) %{ 7508 match(Set newval (GetAndSetI mem newval)); 7509 format %{ "XCHGL $newval,[$mem]" %} 7510 ins_encode %{ 7511 __ xchgl($newval$$Register, $mem$$Address); 7512 %} 7513 ins_pipe( pipe_cmpxchg ); 7514 %} 7515 7516 instruct xchgL( memory mem, rRegL newval) %{ 7517 match(Set newval (GetAndSetL mem newval)); 7518 format %{ "XCHGL $newval,[$mem]" %} 7519 ins_encode %{ 7520 __ xchgq($newval$$Register, $mem$$Address); 7521 %} 7522 ins_pipe( pipe_cmpxchg ); 7523 %} 7524 7525 instruct xchgP( memory mem, rRegP newval) %{ 7526 match(Set newval (GetAndSetP mem newval)); 7527 format %{ "XCHGQ $newval,[$mem]" %} 7528 ins_encode %{ 7529 __ xchgq($newval$$Register, $mem$$Address); 7530 %} 7531 ins_pipe( pipe_cmpxchg ); 7532 %} 7533 7534 instruct xchgN( memory mem, rRegN newval) %{ 7535 match(Set newval (GetAndSetN mem newval)); 7536 format %{ "XCHGL $newval,$mem]" %} 7537 ins_encode %{ 7538 __ xchgl($newval$$Register, $mem$$Address); 7539 %} 7540 ins_pipe( pipe_cmpxchg ); 7541 %} 7542 7543 //----------Subtraction Instructions------------------------------------------- 7544 7545 // Integer Subtraction Instructions 7546 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7547 %{ 7548 match(Set dst (SubI dst src)); 7549 effect(KILL cr); 7550 7551 format %{ "subl $dst, $src\t# int" %} 7552 opcode(0x2B); 7553 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7554 ins_pipe(ialu_reg_reg); 7555 %} 7556 7557 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7558 %{ 7559 match(Set dst (SubI dst src)); 7560 effect(KILL cr); 7561 7562 format %{ "subl $dst, $src\t# int" %} 7563 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7564 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7565 ins_pipe(ialu_reg); 7566 %} 7567 7568 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7569 %{ 7570 match(Set dst (SubI dst (LoadI src))); 7571 effect(KILL cr); 7572 7573 ins_cost(125); 7574 format %{ "subl $dst, $src\t# int" %} 7575 opcode(0x2B); 7576 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7577 ins_pipe(ialu_reg_mem); 7578 %} 7579 7580 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7581 %{ 7582 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7583 effect(KILL cr); 7584 7585 ins_cost(150); 7586 format %{ "subl $dst, $src\t# int" %} 7587 opcode(0x29); /* Opcode 29 /r */ 7588 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7589 ins_pipe(ialu_mem_reg); 7590 %} 7591 7592 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7593 %{ 7594 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7595 effect(KILL cr); 7596 7597 ins_cost(125); // XXX 7598 format %{ "subl $dst, $src\t# int" %} 7599 opcode(0x81); /* Opcode 81 /5 id */ 7600 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7601 ins_pipe(ialu_mem_imm); 7602 %} 7603 7604 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7605 %{ 7606 match(Set dst (SubL dst src)); 7607 effect(KILL cr); 7608 7609 format %{ "subq $dst, $src\t# long" %} 7610 opcode(0x2B); 7611 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7612 ins_pipe(ialu_reg_reg); 7613 %} 7614 7615 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7616 %{ 7617 match(Set dst (SubL dst src)); 7618 effect(KILL cr); 7619 7620 format %{ "subq $dst, $src\t# long" %} 7621 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7622 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7623 ins_pipe(ialu_reg); 7624 %} 7625 7626 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7627 %{ 7628 match(Set dst (SubL dst (LoadL src))); 7629 effect(KILL cr); 7630 7631 ins_cost(125); 7632 format %{ "subq $dst, $src\t# long" %} 7633 opcode(0x2B); 7634 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7635 ins_pipe(ialu_reg_mem); 7636 %} 7637 7638 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7639 %{ 7640 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7641 effect(KILL cr); 7642 7643 ins_cost(150); 7644 format %{ "subq $dst, $src\t# long" %} 7645 opcode(0x29); /* Opcode 29 /r */ 7646 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7647 ins_pipe(ialu_mem_reg); 7648 %} 7649 7650 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7651 %{ 7652 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7653 effect(KILL cr); 7654 7655 ins_cost(125); // XXX 7656 format %{ "subq $dst, $src\t# long" %} 7657 opcode(0x81); /* Opcode 81 /5 id */ 7658 ins_encode(REX_mem_wide(dst), 7659 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7660 ins_pipe(ialu_mem_imm); 7661 %} 7662 7663 // Subtract from a pointer 7664 // XXX hmpf??? 7665 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7666 %{ 7667 match(Set dst (AddP dst (SubI zero src))); 7668 effect(KILL cr); 7669 7670 format %{ "subq $dst, $src\t# ptr - int" %} 7671 opcode(0x2B); 7672 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7673 ins_pipe(ialu_reg_reg); 7674 %} 7675 7676 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7677 %{ 7678 match(Set dst (SubI zero dst)); 7679 effect(KILL cr); 7680 7681 format %{ "negl $dst\t# int" %} 7682 opcode(0xF7, 0x03); // Opcode F7 /3 7683 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7684 ins_pipe(ialu_reg); 7685 %} 7686 7687 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7688 %{ 7689 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7690 effect(KILL cr); 7691 7692 format %{ "negl $dst\t# int" %} 7693 opcode(0xF7, 0x03); // Opcode F7 /3 7694 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7695 ins_pipe(ialu_reg); 7696 %} 7697 7698 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7699 %{ 7700 match(Set dst (SubL zero dst)); 7701 effect(KILL cr); 7702 7703 format %{ "negq $dst\t# long" %} 7704 opcode(0xF7, 0x03); // Opcode F7 /3 7705 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7706 ins_pipe(ialu_reg); 7707 %} 7708 7709 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7710 %{ 7711 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7712 effect(KILL cr); 7713 7714 format %{ "negq $dst\t# long" %} 7715 opcode(0xF7, 0x03); // Opcode F7 /3 7716 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7717 ins_pipe(ialu_reg); 7718 %} 7719 7720 //----------Multiplication/Division Instructions------------------------------- 7721 // Integer Multiplication Instructions 7722 // Multiply Register 7723 7724 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7725 %{ 7726 match(Set dst (MulI dst src)); 7727 effect(KILL cr); 7728 7729 ins_cost(300); 7730 format %{ "imull $dst, $src\t# int" %} 7731 opcode(0x0F, 0xAF); 7732 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7733 ins_pipe(ialu_reg_reg_alu0); 7734 %} 7735 7736 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7737 %{ 7738 match(Set dst (MulI src imm)); 7739 effect(KILL cr); 7740 7741 ins_cost(300); 7742 format %{ "imull $dst, $src, $imm\t# int" %} 7743 opcode(0x69); /* 69 /r id */ 7744 ins_encode(REX_reg_reg(dst, src), 7745 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7746 ins_pipe(ialu_reg_reg_alu0); 7747 %} 7748 7749 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7750 %{ 7751 match(Set dst (MulI dst (LoadI src))); 7752 effect(KILL cr); 7753 7754 ins_cost(350); 7755 format %{ "imull $dst, $src\t# int" %} 7756 opcode(0x0F, 0xAF); 7757 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7758 ins_pipe(ialu_reg_mem_alu0); 7759 %} 7760 7761 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7762 %{ 7763 match(Set dst (MulI (LoadI src) imm)); 7764 effect(KILL cr); 7765 7766 ins_cost(300); 7767 format %{ "imull $dst, $src, $imm\t# int" %} 7768 opcode(0x69); /* 69 /r id */ 7769 ins_encode(REX_reg_mem(dst, src), 7770 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7771 ins_pipe(ialu_reg_mem_alu0); 7772 %} 7773 7774 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7775 %{ 7776 match(Set dst (MulL dst src)); 7777 effect(KILL cr); 7778 7779 ins_cost(300); 7780 format %{ "imulq $dst, $src\t# long" %} 7781 opcode(0x0F, 0xAF); 7782 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7783 ins_pipe(ialu_reg_reg_alu0); 7784 %} 7785 7786 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7787 %{ 7788 match(Set dst (MulL src imm)); 7789 effect(KILL cr); 7790 7791 ins_cost(300); 7792 format %{ "imulq $dst, $src, $imm\t# long" %} 7793 opcode(0x69); /* 69 /r id */ 7794 ins_encode(REX_reg_reg_wide(dst, src), 7795 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7796 ins_pipe(ialu_reg_reg_alu0); 7797 %} 7798 7799 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7800 %{ 7801 match(Set dst (MulL dst (LoadL src))); 7802 effect(KILL cr); 7803 7804 ins_cost(350); 7805 format %{ "imulq $dst, $src\t# long" %} 7806 opcode(0x0F, 0xAF); 7807 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7808 ins_pipe(ialu_reg_mem_alu0); 7809 %} 7810 7811 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7812 %{ 7813 match(Set dst (MulL (LoadL src) imm)); 7814 effect(KILL cr); 7815 7816 ins_cost(300); 7817 format %{ "imulq $dst, $src, $imm\t# long" %} 7818 opcode(0x69); /* 69 /r id */ 7819 ins_encode(REX_reg_mem_wide(dst, src), 7820 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7821 ins_pipe(ialu_reg_mem_alu0); 7822 %} 7823 7824 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7825 %{ 7826 match(Set dst (MulHiL src rax)); 7827 effect(USE_KILL rax, KILL cr); 7828 7829 ins_cost(300); 7830 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7831 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7832 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7833 ins_pipe(ialu_reg_reg_alu0); 7834 %} 7835 7836 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7837 rFlagsReg cr) 7838 %{ 7839 match(Set rax (DivI rax div)); 7840 effect(KILL rdx, KILL cr); 7841 7842 ins_cost(30*100+10*100); // XXX 7843 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7844 "jne,s normal\n\t" 7845 "xorl rdx, rdx\n\t" 7846 "cmpl $div, -1\n\t" 7847 "je,s done\n" 7848 "normal: cdql\n\t" 7849 "idivl $div\n" 7850 "done:" %} 7851 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7852 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7853 ins_pipe(ialu_reg_reg_alu0); 7854 %} 7855 7856 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7857 rFlagsReg cr) 7858 %{ 7859 match(Set rax (DivL rax div)); 7860 effect(KILL rdx, KILL cr); 7861 7862 ins_cost(30*100+10*100); // XXX 7863 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7864 "cmpq rax, rdx\n\t" 7865 "jne,s normal\n\t" 7866 "xorl rdx, rdx\n\t" 7867 "cmpq $div, -1\n\t" 7868 "je,s done\n" 7869 "normal: cdqq\n\t" 7870 "idivq $div\n" 7871 "done:" %} 7872 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7873 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7874 ins_pipe(ialu_reg_reg_alu0); 7875 %} 7876 7877 // Integer DIVMOD with Register, both quotient and mod results 7878 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7879 rFlagsReg cr) 7880 %{ 7881 match(DivModI rax div); 7882 effect(KILL cr); 7883 7884 ins_cost(30*100+10*100); // XXX 7885 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7886 "jne,s normal\n\t" 7887 "xorl rdx, rdx\n\t" 7888 "cmpl $div, -1\n\t" 7889 "je,s done\n" 7890 "normal: cdql\n\t" 7891 "idivl $div\n" 7892 "done:" %} 7893 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7894 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7895 ins_pipe(pipe_slow); 7896 %} 7897 7898 // Long DIVMOD with Register, both quotient and mod results 7899 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7900 rFlagsReg cr) 7901 %{ 7902 match(DivModL rax div); 7903 effect(KILL cr); 7904 7905 ins_cost(30*100+10*100); // XXX 7906 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7907 "cmpq rax, rdx\n\t" 7908 "jne,s normal\n\t" 7909 "xorl rdx, rdx\n\t" 7910 "cmpq $div, -1\n\t" 7911 "je,s done\n" 7912 "normal: cdqq\n\t" 7913 "idivq $div\n" 7914 "done:" %} 7915 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7916 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7917 ins_pipe(pipe_slow); 7918 %} 7919 7920 //----------- DivL-By-Constant-Expansions-------------------------------------- 7921 // DivI cases are handled by the compiler 7922 7923 // Magic constant, reciprocal of 10 7924 instruct loadConL_0x6666666666666667(rRegL dst) 7925 %{ 7926 effect(DEF dst); 7927 7928 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 7929 ins_encode(load_immL(dst, 0x6666666666666667)); 7930 ins_pipe(ialu_reg); 7931 %} 7932 7933 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7934 %{ 7935 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 7936 7937 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 7938 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7939 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7940 ins_pipe(ialu_reg_reg_alu0); 7941 %} 7942 7943 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 7944 %{ 7945 effect(USE_DEF dst, KILL cr); 7946 7947 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 7948 opcode(0xC1, 0x7); /* C1 /7 ib */ 7949 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 7950 ins_pipe(ialu_reg); 7951 %} 7952 7953 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 7954 %{ 7955 effect(USE_DEF dst, KILL cr); 7956 7957 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 7958 opcode(0xC1, 0x7); /* C1 /7 ib */ 7959 ins_encode(reg_opc_imm_wide(dst, 0x2)); 7960 ins_pipe(ialu_reg); 7961 %} 7962 7963 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 7964 %{ 7965 match(Set dst (DivL src div)); 7966 7967 ins_cost((5+8)*100); 7968 expand %{ 7969 rax_RegL rax; // Killed temp 7970 rFlagsReg cr; // Killed 7971 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 7972 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 7973 sarL_rReg_63(src, cr); // sarq src, 63 7974 sarL_rReg_2(dst, cr); // sarq rdx, 2 7975 subL_rReg(dst, src, cr); // subl rdx, src 7976 %} 7977 %} 7978 7979 //----------------------------------------------------------------------------- 7980 7981 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7982 rFlagsReg cr) 7983 %{ 7984 match(Set rdx (ModI rax div)); 7985 effect(KILL rax, KILL cr); 7986 7987 ins_cost(300); // XXX 7988 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7989 "jne,s normal\n\t" 7990 "xorl rdx, rdx\n\t" 7991 "cmpl $div, -1\n\t" 7992 "je,s done\n" 7993 "normal: cdql\n\t" 7994 "idivl $div\n" 7995 "done:" %} 7996 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7997 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7998 ins_pipe(ialu_reg_reg_alu0); 7999 %} 8000 8001 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8002 rFlagsReg cr) 8003 %{ 8004 match(Set rdx (ModL rax div)); 8005 effect(KILL rax, KILL cr); 8006 8007 ins_cost(300); // XXX 8008 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8009 "cmpq rax, rdx\n\t" 8010 "jne,s normal\n\t" 8011 "xorl rdx, rdx\n\t" 8012 "cmpq $div, -1\n\t" 8013 "je,s done\n" 8014 "normal: cdqq\n\t" 8015 "idivq $div\n" 8016 "done:" %} 8017 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8018 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8019 ins_pipe(ialu_reg_reg_alu0); 8020 %} 8021 8022 // Integer Shift Instructions 8023 // Shift Left by one 8024 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8025 %{ 8026 match(Set dst (LShiftI dst shift)); 8027 effect(KILL cr); 8028 8029 format %{ "sall $dst, $shift" %} 8030 opcode(0xD1, 0x4); /* D1 /4 */ 8031 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8032 ins_pipe(ialu_reg); 8033 %} 8034 8035 // Shift Left by one 8036 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8037 %{ 8038 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8039 effect(KILL cr); 8040 8041 format %{ "sall $dst, $shift\t" %} 8042 opcode(0xD1, 0x4); /* D1 /4 */ 8043 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8044 ins_pipe(ialu_mem_imm); 8045 %} 8046 8047 // Shift Left by 8-bit immediate 8048 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8049 %{ 8050 match(Set dst (LShiftI dst shift)); 8051 effect(KILL cr); 8052 8053 format %{ "sall $dst, $shift" %} 8054 opcode(0xC1, 0x4); /* C1 /4 ib */ 8055 ins_encode(reg_opc_imm(dst, shift)); 8056 ins_pipe(ialu_reg); 8057 %} 8058 8059 // Shift Left by 8-bit immediate 8060 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8061 %{ 8062 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8063 effect(KILL cr); 8064 8065 format %{ "sall $dst, $shift" %} 8066 opcode(0xC1, 0x4); /* C1 /4 ib */ 8067 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8068 ins_pipe(ialu_mem_imm); 8069 %} 8070 8071 // Shift Left by variable 8072 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8073 %{ 8074 match(Set dst (LShiftI dst shift)); 8075 effect(KILL cr); 8076 8077 format %{ "sall $dst, $shift" %} 8078 opcode(0xD3, 0x4); /* D3 /4 */ 8079 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8080 ins_pipe(ialu_reg_reg); 8081 %} 8082 8083 // Shift Left by variable 8084 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8085 %{ 8086 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8087 effect(KILL cr); 8088 8089 format %{ "sall $dst, $shift" %} 8090 opcode(0xD3, 0x4); /* D3 /4 */ 8091 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8092 ins_pipe(ialu_mem_reg); 8093 %} 8094 8095 // Arithmetic shift right by one 8096 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8097 %{ 8098 match(Set dst (RShiftI dst shift)); 8099 effect(KILL cr); 8100 8101 format %{ "sarl $dst, $shift" %} 8102 opcode(0xD1, 0x7); /* D1 /7 */ 8103 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8104 ins_pipe(ialu_reg); 8105 %} 8106 8107 // Arithmetic shift right by one 8108 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8109 %{ 8110 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8111 effect(KILL cr); 8112 8113 format %{ "sarl $dst, $shift" %} 8114 opcode(0xD1, 0x7); /* D1 /7 */ 8115 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8116 ins_pipe(ialu_mem_imm); 8117 %} 8118 8119 // Arithmetic Shift Right by 8-bit immediate 8120 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8121 %{ 8122 match(Set dst (RShiftI dst shift)); 8123 effect(KILL cr); 8124 8125 format %{ "sarl $dst, $shift" %} 8126 opcode(0xC1, 0x7); /* C1 /7 ib */ 8127 ins_encode(reg_opc_imm(dst, shift)); 8128 ins_pipe(ialu_mem_imm); 8129 %} 8130 8131 // Arithmetic Shift Right by 8-bit immediate 8132 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8133 %{ 8134 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8135 effect(KILL cr); 8136 8137 format %{ "sarl $dst, $shift" %} 8138 opcode(0xC1, 0x7); /* C1 /7 ib */ 8139 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8140 ins_pipe(ialu_mem_imm); 8141 %} 8142 8143 // Arithmetic Shift Right by variable 8144 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8145 %{ 8146 match(Set dst (RShiftI dst shift)); 8147 effect(KILL cr); 8148 8149 format %{ "sarl $dst, $shift" %} 8150 opcode(0xD3, 0x7); /* D3 /7 */ 8151 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8152 ins_pipe(ialu_reg_reg); 8153 %} 8154 8155 // Arithmetic Shift Right by variable 8156 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8157 %{ 8158 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8159 effect(KILL cr); 8160 8161 format %{ "sarl $dst, $shift" %} 8162 opcode(0xD3, 0x7); /* D3 /7 */ 8163 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8164 ins_pipe(ialu_mem_reg); 8165 %} 8166 8167 // Logical shift right by one 8168 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8169 %{ 8170 match(Set dst (URShiftI dst shift)); 8171 effect(KILL cr); 8172 8173 format %{ "shrl $dst, $shift" %} 8174 opcode(0xD1, 0x5); /* D1 /5 */ 8175 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8176 ins_pipe(ialu_reg); 8177 %} 8178 8179 // Logical shift right by one 8180 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8181 %{ 8182 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8183 effect(KILL cr); 8184 8185 format %{ "shrl $dst, $shift" %} 8186 opcode(0xD1, 0x5); /* D1 /5 */ 8187 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8188 ins_pipe(ialu_mem_imm); 8189 %} 8190 8191 // Logical Shift Right by 8-bit immediate 8192 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8193 %{ 8194 match(Set dst (URShiftI dst shift)); 8195 effect(KILL cr); 8196 8197 format %{ "shrl $dst, $shift" %} 8198 opcode(0xC1, 0x5); /* C1 /5 ib */ 8199 ins_encode(reg_opc_imm(dst, shift)); 8200 ins_pipe(ialu_reg); 8201 %} 8202 8203 // Logical Shift Right by 8-bit immediate 8204 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8205 %{ 8206 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8207 effect(KILL cr); 8208 8209 format %{ "shrl $dst, $shift" %} 8210 opcode(0xC1, 0x5); /* C1 /5 ib */ 8211 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8212 ins_pipe(ialu_mem_imm); 8213 %} 8214 8215 // Logical Shift Right by variable 8216 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8217 %{ 8218 match(Set dst (URShiftI dst shift)); 8219 effect(KILL cr); 8220 8221 format %{ "shrl $dst, $shift" %} 8222 opcode(0xD3, 0x5); /* D3 /5 */ 8223 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8224 ins_pipe(ialu_reg_reg); 8225 %} 8226 8227 // Logical Shift Right by variable 8228 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8229 %{ 8230 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8231 effect(KILL cr); 8232 8233 format %{ "shrl $dst, $shift" %} 8234 opcode(0xD3, 0x5); /* D3 /5 */ 8235 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8236 ins_pipe(ialu_mem_reg); 8237 %} 8238 8239 // Long Shift Instructions 8240 // Shift Left by one 8241 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8242 %{ 8243 match(Set dst (LShiftL dst shift)); 8244 effect(KILL cr); 8245 8246 format %{ "salq $dst, $shift" %} 8247 opcode(0xD1, 0x4); /* D1 /4 */ 8248 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8249 ins_pipe(ialu_reg); 8250 %} 8251 8252 // Shift Left by one 8253 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8254 %{ 8255 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8256 effect(KILL cr); 8257 8258 format %{ "salq $dst, $shift" %} 8259 opcode(0xD1, 0x4); /* D1 /4 */ 8260 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8261 ins_pipe(ialu_mem_imm); 8262 %} 8263 8264 // Shift Left by 8-bit immediate 8265 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8266 %{ 8267 match(Set dst (LShiftL dst shift)); 8268 effect(KILL cr); 8269 8270 format %{ "salq $dst, $shift" %} 8271 opcode(0xC1, 0x4); /* C1 /4 ib */ 8272 ins_encode(reg_opc_imm_wide(dst, shift)); 8273 ins_pipe(ialu_reg); 8274 %} 8275 8276 // Shift Left by 8-bit immediate 8277 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8278 %{ 8279 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8280 effect(KILL cr); 8281 8282 format %{ "salq $dst, $shift" %} 8283 opcode(0xC1, 0x4); /* C1 /4 ib */ 8284 ins_encode(REX_mem_wide(dst), OpcP, 8285 RM_opc_mem(secondary, dst), Con8or32(shift)); 8286 ins_pipe(ialu_mem_imm); 8287 %} 8288 8289 // Shift Left by variable 8290 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8291 %{ 8292 match(Set dst (LShiftL dst shift)); 8293 effect(KILL cr); 8294 8295 format %{ "salq $dst, $shift" %} 8296 opcode(0xD3, 0x4); /* D3 /4 */ 8297 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8298 ins_pipe(ialu_reg_reg); 8299 %} 8300 8301 // Shift Left by variable 8302 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8303 %{ 8304 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8305 effect(KILL cr); 8306 8307 format %{ "salq $dst, $shift" %} 8308 opcode(0xD3, 0x4); /* D3 /4 */ 8309 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8310 ins_pipe(ialu_mem_reg); 8311 %} 8312 8313 // Arithmetic shift right by one 8314 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8315 %{ 8316 match(Set dst (RShiftL dst shift)); 8317 effect(KILL cr); 8318 8319 format %{ "sarq $dst, $shift" %} 8320 opcode(0xD1, 0x7); /* D1 /7 */ 8321 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8322 ins_pipe(ialu_reg); 8323 %} 8324 8325 // Arithmetic shift right by one 8326 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8327 %{ 8328 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8329 effect(KILL cr); 8330 8331 format %{ "sarq $dst, $shift" %} 8332 opcode(0xD1, 0x7); /* D1 /7 */ 8333 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8334 ins_pipe(ialu_mem_imm); 8335 %} 8336 8337 // Arithmetic Shift Right by 8-bit immediate 8338 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8339 %{ 8340 match(Set dst (RShiftL dst shift)); 8341 effect(KILL cr); 8342 8343 format %{ "sarq $dst, $shift" %} 8344 opcode(0xC1, 0x7); /* C1 /7 ib */ 8345 ins_encode(reg_opc_imm_wide(dst, shift)); 8346 ins_pipe(ialu_mem_imm); 8347 %} 8348 8349 // Arithmetic Shift Right by 8-bit immediate 8350 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8351 %{ 8352 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8353 effect(KILL cr); 8354 8355 format %{ "sarq $dst, $shift" %} 8356 opcode(0xC1, 0x7); /* C1 /7 ib */ 8357 ins_encode(REX_mem_wide(dst), OpcP, 8358 RM_opc_mem(secondary, dst), Con8or32(shift)); 8359 ins_pipe(ialu_mem_imm); 8360 %} 8361 8362 // Arithmetic Shift Right by variable 8363 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8364 %{ 8365 match(Set dst (RShiftL dst shift)); 8366 effect(KILL cr); 8367 8368 format %{ "sarq $dst, $shift" %} 8369 opcode(0xD3, 0x7); /* D3 /7 */ 8370 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8371 ins_pipe(ialu_reg_reg); 8372 %} 8373 8374 // Arithmetic Shift Right by variable 8375 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8376 %{ 8377 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8378 effect(KILL cr); 8379 8380 format %{ "sarq $dst, $shift" %} 8381 opcode(0xD3, 0x7); /* D3 /7 */ 8382 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8383 ins_pipe(ialu_mem_reg); 8384 %} 8385 8386 // Logical shift right by one 8387 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8388 %{ 8389 match(Set dst (URShiftL dst shift)); 8390 effect(KILL cr); 8391 8392 format %{ "shrq $dst, $shift" %} 8393 opcode(0xD1, 0x5); /* D1 /5 */ 8394 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8395 ins_pipe(ialu_reg); 8396 %} 8397 8398 // Logical shift right by one 8399 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8400 %{ 8401 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8402 effect(KILL cr); 8403 8404 format %{ "shrq $dst, $shift" %} 8405 opcode(0xD1, 0x5); /* D1 /5 */ 8406 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8407 ins_pipe(ialu_mem_imm); 8408 %} 8409 8410 // Logical Shift Right by 8-bit immediate 8411 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8412 %{ 8413 match(Set dst (URShiftL dst shift)); 8414 effect(KILL cr); 8415 8416 format %{ "shrq $dst, $shift" %} 8417 opcode(0xC1, 0x5); /* C1 /5 ib */ 8418 ins_encode(reg_opc_imm_wide(dst, shift)); 8419 ins_pipe(ialu_reg); 8420 %} 8421 8422 8423 // Logical Shift Right by 8-bit immediate 8424 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8425 %{ 8426 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8427 effect(KILL cr); 8428 8429 format %{ "shrq $dst, $shift" %} 8430 opcode(0xC1, 0x5); /* C1 /5 ib */ 8431 ins_encode(REX_mem_wide(dst), OpcP, 8432 RM_opc_mem(secondary, dst), Con8or32(shift)); 8433 ins_pipe(ialu_mem_imm); 8434 %} 8435 8436 // Logical Shift Right by variable 8437 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8438 %{ 8439 match(Set dst (URShiftL dst shift)); 8440 effect(KILL cr); 8441 8442 format %{ "shrq $dst, $shift" %} 8443 opcode(0xD3, 0x5); /* D3 /5 */ 8444 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8445 ins_pipe(ialu_reg_reg); 8446 %} 8447 8448 // Logical Shift Right by variable 8449 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8450 %{ 8451 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8452 effect(KILL cr); 8453 8454 format %{ "shrq $dst, $shift" %} 8455 opcode(0xD3, 0x5); /* D3 /5 */ 8456 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8457 ins_pipe(ialu_mem_reg); 8458 %} 8459 8460 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8461 // This idiom is used by the compiler for the i2b bytecode. 8462 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8463 %{ 8464 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8465 8466 format %{ "movsbl $dst, $src\t# i2b" %} 8467 opcode(0x0F, 0xBE); 8468 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8469 ins_pipe(ialu_reg_reg); 8470 %} 8471 8472 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8473 // This idiom is used by the compiler the i2s bytecode. 8474 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8475 %{ 8476 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8477 8478 format %{ "movswl $dst, $src\t# i2s" %} 8479 opcode(0x0F, 0xBF); 8480 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8481 ins_pipe(ialu_reg_reg); 8482 %} 8483 8484 // ROL/ROR instructions 8485 8486 // ROL expand 8487 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8488 effect(KILL cr, USE_DEF dst); 8489 8490 format %{ "roll $dst" %} 8491 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8492 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8493 ins_pipe(ialu_reg); 8494 %} 8495 8496 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8497 effect(USE_DEF dst, USE shift, KILL cr); 8498 8499 format %{ "roll $dst, $shift" %} 8500 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8501 ins_encode( reg_opc_imm(dst, shift) ); 8502 ins_pipe(ialu_reg); 8503 %} 8504 8505 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8506 %{ 8507 effect(USE_DEF dst, USE shift, KILL cr); 8508 8509 format %{ "roll $dst, $shift" %} 8510 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8511 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8512 ins_pipe(ialu_reg_reg); 8513 %} 8514 // end of ROL expand 8515 8516 // Rotate Left by one 8517 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8518 %{ 8519 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8520 8521 expand %{ 8522 rolI_rReg_imm1(dst, cr); 8523 %} 8524 %} 8525 8526 // Rotate Left by 8-bit immediate 8527 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8528 %{ 8529 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8530 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8531 8532 expand %{ 8533 rolI_rReg_imm8(dst, lshift, cr); 8534 %} 8535 %} 8536 8537 // Rotate Left by variable 8538 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8539 %{ 8540 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8541 8542 expand %{ 8543 rolI_rReg_CL(dst, shift, cr); 8544 %} 8545 %} 8546 8547 // Rotate Left by variable 8548 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8549 %{ 8550 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8551 8552 expand %{ 8553 rolI_rReg_CL(dst, shift, cr); 8554 %} 8555 %} 8556 8557 // ROR expand 8558 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8559 %{ 8560 effect(USE_DEF dst, KILL cr); 8561 8562 format %{ "rorl $dst" %} 8563 opcode(0xD1, 0x1); /* D1 /1 */ 8564 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8565 ins_pipe(ialu_reg); 8566 %} 8567 8568 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8569 %{ 8570 effect(USE_DEF dst, USE shift, KILL cr); 8571 8572 format %{ "rorl $dst, $shift" %} 8573 opcode(0xC1, 0x1); /* C1 /1 ib */ 8574 ins_encode(reg_opc_imm(dst, shift)); 8575 ins_pipe(ialu_reg); 8576 %} 8577 8578 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8579 %{ 8580 effect(USE_DEF dst, USE shift, KILL cr); 8581 8582 format %{ "rorl $dst, $shift" %} 8583 opcode(0xD3, 0x1); /* D3 /1 */ 8584 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8585 ins_pipe(ialu_reg_reg); 8586 %} 8587 // end of ROR expand 8588 8589 // Rotate Right by one 8590 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8591 %{ 8592 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8593 8594 expand %{ 8595 rorI_rReg_imm1(dst, cr); 8596 %} 8597 %} 8598 8599 // Rotate Right by 8-bit immediate 8600 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8601 %{ 8602 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8603 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8604 8605 expand %{ 8606 rorI_rReg_imm8(dst, rshift, cr); 8607 %} 8608 %} 8609 8610 // Rotate Right by variable 8611 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8612 %{ 8613 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8614 8615 expand %{ 8616 rorI_rReg_CL(dst, shift, cr); 8617 %} 8618 %} 8619 8620 // Rotate Right by variable 8621 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8622 %{ 8623 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8624 8625 expand %{ 8626 rorI_rReg_CL(dst, shift, cr); 8627 %} 8628 %} 8629 8630 // for long rotate 8631 // ROL expand 8632 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8633 effect(USE_DEF dst, KILL cr); 8634 8635 format %{ "rolq $dst" %} 8636 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8637 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8638 ins_pipe(ialu_reg); 8639 %} 8640 8641 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8642 effect(USE_DEF dst, USE shift, KILL cr); 8643 8644 format %{ "rolq $dst, $shift" %} 8645 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8646 ins_encode( reg_opc_imm_wide(dst, shift) ); 8647 ins_pipe(ialu_reg); 8648 %} 8649 8650 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8651 %{ 8652 effect(USE_DEF dst, USE shift, KILL cr); 8653 8654 format %{ "rolq $dst, $shift" %} 8655 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8656 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8657 ins_pipe(ialu_reg_reg); 8658 %} 8659 // end of ROL expand 8660 8661 // Rotate Left by one 8662 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8663 %{ 8664 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8665 8666 expand %{ 8667 rolL_rReg_imm1(dst, cr); 8668 %} 8669 %} 8670 8671 // Rotate Left by 8-bit immediate 8672 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8673 %{ 8674 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8675 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8676 8677 expand %{ 8678 rolL_rReg_imm8(dst, lshift, cr); 8679 %} 8680 %} 8681 8682 // Rotate Left by variable 8683 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8684 %{ 8685 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8686 8687 expand %{ 8688 rolL_rReg_CL(dst, shift, cr); 8689 %} 8690 %} 8691 8692 // Rotate Left by variable 8693 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8694 %{ 8695 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8696 8697 expand %{ 8698 rolL_rReg_CL(dst, shift, cr); 8699 %} 8700 %} 8701 8702 // ROR expand 8703 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8704 %{ 8705 effect(USE_DEF dst, KILL cr); 8706 8707 format %{ "rorq $dst" %} 8708 opcode(0xD1, 0x1); /* D1 /1 */ 8709 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8710 ins_pipe(ialu_reg); 8711 %} 8712 8713 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8714 %{ 8715 effect(USE_DEF dst, USE shift, KILL cr); 8716 8717 format %{ "rorq $dst, $shift" %} 8718 opcode(0xC1, 0x1); /* C1 /1 ib */ 8719 ins_encode(reg_opc_imm_wide(dst, shift)); 8720 ins_pipe(ialu_reg); 8721 %} 8722 8723 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8724 %{ 8725 effect(USE_DEF dst, USE shift, KILL cr); 8726 8727 format %{ "rorq $dst, $shift" %} 8728 opcode(0xD3, 0x1); /* D3 /1 */ 8729 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8730 ins_pipe(ialu_reg_reg); 8731 %} 8732 // end of ROR expand 8733 8734 // Rotate Right by one 8735 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8736 %{ 8737 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8738 8739 expand %{ 8740 rorL_rReg_imm1(dst, cr); 8741 %} 8742 %} 8743 8744 // Rotate Right by 8-bit immediate 8745 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8746 %{ 8747 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8748 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8749 8750 expand %{ 8751 rorL_rReg_imm8(dst, rshift, cr); 8752 %} 8753 %} 8754 8755 // Rotate Right by variable 8756 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8757 %{ 8758 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8759 8760 expand %{ 8761 rorL_rReg_CL(dst, shift, cr); 8762 %} 8763 %} 8764 8765 // Rotate Right by variable 8766 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8767 %{ 8768 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8769 8770 expand %{ 8771 rorL_rReg_CL(dst, shift, cr); 8772 %} 8773 %} 8774 8775 // Logical Instructions 8776 8777 // Integer Logical Instructions 8778 8779 // And Instructions 8780 // And Register with Register 8781 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8782 %{ 8783 match(Set dst (AndI dst src)); 8784 effect(KILL cr); 8785 8786 format %{ "andl $dst, $src\t# int" %} 8787 opcode(0x23); 8788 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8789 ins_pipe(ialu_reg_reg); 8790 %} 8791 8792 // And Register with Immediate 255 8793 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 8794 %{ 8795 match(Set dst (AndI dst src)); 8796 8797 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 8798 opcode(0x0F, 0xB6); 8799 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8800 ins_pipe(ialu_reg); 8801 %} 8802 8803 // And Register with Immediate 255 and promote to long 8804 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8805 %{ 8806 match(Set dst (ConvI2L (AndI src mask))); 8807 8808 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8809 opcode(0x0F, 0xB6); 8810 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8811 ins_pipe(ialu_reg); 8812 %} 8813 8814 // And Register with Immediate 65535 8815 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 8816 %{ 8817 match(Set dst (AndI dst src)); 8818 8819 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 8820 opcode(0x0F, 0xB7); 8821 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8822 ins_pipe(ialu_reg); 8823 %} 8824 8825 // And Register with Immediate 65535 and promote to long 8826 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8827 %{ 8828 match(Set dst (ConvI2L (AndI src mask))); 8829 8830 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8831 opcode(0x0F, 0xB7); 8832 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8833 ins_pipe(ialu_reg); 8834 %} 8835 8836 // And Register with Immediate 8837 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8838 %{ 8839 match(Set dst (AndI dst src)); 8840 effect(KILL cr); 8841 8842 format %{ "andl $dst, $src\t# int" %} 8843 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8844 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8845 ins_pipe(ialu_reg); 8846 %} 8847 8848 // And Register with Memory 8849 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8850 %{ 8851 match(Set dst (AndI dst (LoadI src))); 8852 effect(KILL cr); 8853 8854 ins_cost(125); 8855 format %{ "andl $dst, $src\t# int" %} 8856 opcode(0x23); 8857 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8858 ins_pipe(ialu_reg_mem); 8859 %} 8860 8861 // And Memory with Register 8862 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8863 %{ 8864 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8865 effect(KILL cr); 8866 8867 ins_cost(150); 8868 format %{ "andl $dst, $src\t# int" %} 8869 opcode(0x21); /* Opcode 21 /r */ 8870 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8871 ins_pipe(ialu_mem_reg); 8872 %} 8873 8874 // And Memory with Immediate 8875 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8876 %{ 8877 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8878 effect(KILL cr); 8879 8880 ins_cost(125); 8881 format %{ "andl $dst, $src\t# int" %} 8882 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 8883 ins_encode(REX_mem(dst), OpcSE(src), 8884 RM_opc_mem(secondary, dst), Con8or32(src)); 8885 ins_pipe(ialu_mem_imm); 8886 %} 8887 8888 // BMI1 instructions 8889 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8890 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8891 predicate(UseBMI1Instructions); 8892 effect(KILL cr); 8893 8894 ins_cost(125); 8895 format %{ "andnl $dst, $src1, $src2" %} 8896 8897 ins_encode %{ 8898 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8899 %} 8900 ins_pipe(ialu_reg_mem); 8901 %} 8902 8903 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8904 match(Set dst (AndI (XorI src1 minus_1) src2)); 8905 predicate(UseBMI1Instructions); 8906 effect(KILL cr); 8907 8908 format %{ "andnl $dst, $src1, $src2" %} 8909 8910 ins_encode %{ 8911 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8912 %} 8913 ins_pipe(ialu_reg); 8914 %} 8915 8916 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 8917 match(Set dst (AndI (SubI imm_zero src) src)); 8918 predicate(UseBMI1Instructions); 8919 effect(KILL cr); 8920 8921 format %{ "blsil $dst, $src" %} 8922 8923 ins_encode %{ 8924 __ blsil($dst$$Register, $src$$Register); 8925 %} 8926 ins_pipe(ialu_reg); 8927 %} 8928 8929 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 8930 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 8931 predicate(UseBMI1Instructions); 8932 effect(KILL cr); 8933 8934 ins_cost(125); 8935 format %{ "blsil $dst, $src" %} 8936 8937 ins_encode %{ 8938 __ blsil($dst$$Register, $src$$Address); 8939 %} 8940 ins_pipe(ialu_reg_mem); 8941 %} 8942 8943 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8944 %{ 8945 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8946 predicate(UseBMI1Instructions); 8947 effect(KILL cr); 8948 8949 ins_cost(125); 8950 format %{ "blsmskl $dst, $src" %} 8951 8952 ins_encode %{ 8953 __ blsmskl($dst$$Register, $src$$Address); 8954 %} 8955 ins_pipe(ialu_reg_mem); 8956 %} 8957 8958 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8959 %{ 8960 match(Set dst (XorI (AddI src minus_1) src)); 8961 predicate(UseBMI1Instructions); 8962 effect(KILL cr); 8963 8964 format %{ "blsmskl $dst, $src" %} 8965 8966 ins_encode %{ 8967 __ blsmskl($dst$$Register, $src$$Register); 8968 %} 8969 8970 ins_pipe(ialu_reg); 8971 %} 8972 8973 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8974 %{ 8975 match(Set dst (AndI (AddI src minus_1) src) ); 8976 predicate(UseBMI1Instructions); 8977 effect(KILL cr); 8978 8979 format %{ "blsrl $dst, $src" %} 8980 8981 ins_encode %{ 8982 __ blsrl($dst$$Register, $src$$Register); 8983 %} 8984 8985 ins_pipe(ialu_reg_mem); 8986 %} 8987 8988 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8989 %{ 8990 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8991 predicate(UseBMI1Instructions); 8992 effect(KILL cr); 8993 8994 ins_cost(125); 8995 format %{ "blsrl $dst, $src" %} 8996 8997 ins_encode %{ 8998 __ blsrl($dst$$Register, $src$$Address); 8999 %} 9000 9001 ins_pipe(ialu_reg); 9002 %} 9003 9004 // Or Instructions 9005 // Or Register with Register 9006 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9007 %{ 9008 match(Set dst (OrI dst src)); 9009 effect(KILL cr); 9010 9011 format %{ "orl $dst, $src\t# int" %} 9012 opcode(0x0B); 9013 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9014 ins_pipe(ialu_reg_reg); 9015 %} 9016 9017 // Or Register with Immediate 9018 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9019 %{ 9020 match(Set dst (OrI dst src)); 9021 effect(KILL cr); 9022 9023 format %{ "orl $dst, $src\t# int" %} 9024 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9025 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9026 ins_pipe(ialu_reg); 9027 %} 9028 9029 // Or Register with Memory 9030 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9031 %{ 9032 match(Set dst (OrI dst (LoadI src))); 9033 effect(KILL cr); 9034 9035 ins_cost(125); 9036 format %{ "orl $dst, $src\t# int" %} 9037 opcode(0x0B); 9038 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9039 ins_pipe(ialu_reg_mem); 9040 %} 9041 9042 // Or Memory with Register 9043 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9044 %{ 9045 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9046 effect(KILL cr); 9047 9048 ins_cost(150); 9049 format %{ "orl $dst, $src\t# int" %} 9050 opcode(0x09); /* Opcode 09 /r */ 9051 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9052 ins_pipe(ialu_mem_reg); 9053 %} 9054 9055 // Or Memory with Immediate 9056 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9057 %{ 9058 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9059 effect(KILL cr); 9060 9061 ins_cost(125); 9062 format %{ "orl $dst, $src\t# int" %} 9063 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9064 ins_encode(REX_mem(dst), OpcSE(src), 9065 RM_opc_mem(secondary, dst), Con8or32(src)); 9066 ins_pipe(ialu_mem_imm); 9067 %} 9068 9069 // Xor Instructions 9070 // Xor Register with Register 9071 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9072 %{ 9073 match(Set dst (XorI dst src)); 9074 effect(KILL cr); 9075 9076 format %{ "xorl $dst, $src\t# int" %} 9077 opcode(0x33); 9078 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9079 ins_pipe(ialu_reg_reg); 9080 %} 9081 9082 // Xor Register with Immediate -1 9083 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9084 match(Set dst (XorI dst imm)); 9085 9086 format %{ "not $dst" %} 9087 ins_encode %{ 9088 __ notl($dst$$Register); 9089 %} 9090 ins_pipe(ialu_reg); 9091 %} 9092 9093 // Xor Register with Immediate 9094 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9095 %{ 9096 match(Set dst (XorI dst src)); 9097 effect(KILL cr); 9098 9099 format %{ "xorl $dst, $src\t# int" %} 9100 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9101 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9102 ins_pipe(ialu_reg); 9103 %} 9104 9105 // Xor Register with Memory 9106 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9107 %{ 9108 match(Set dst (XorI dst (LoadI src))); 9109 effect(KILL cr); 9110 9111 ins_cost(125); 9112 format %{ "xorl $dst, $src\t# int" %} 9113 opcode(0x33); 9114 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9115 ins_pipe(ialu_reg_mem); 9116 %} 9117 9118 // Xor Memory with Register 9119 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9120 %{ 9121 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9122 effect(KILL cr); 9123 9124 ins_cost(150); 9125 format %{ "xorl $dst, $src\t# int" %} 9126 opcode(0x31); /* Opcode 31 /r */ 9127 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9128 ins_pipe(ialu_mem_reg); 9129 %} 9130 9131 // Xor Memory with Immediate 9132 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9133 %{ 9134 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9135 effect(KILL cr); 9136 9137 ins_cost(125); 9138 format %{ "xorl $dst, $src\t# int" %} 9139 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9140 ins_encode(REX_mem(dst), OpcSE(src), 9141 RM_opc_mem(secondary, dst), Con8or32(src)); 9142 ins_pipe(ialu_mem_imm); 9143 %} 9144 9145 9146 // Long Logical Instructions 9147 9148 // And Instructions 9149 // And Register with Register 9150 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9151 %{ 9152 match(Set dst (AndL dst src)); 9153 effect(KILL cr); 9154 9155 format %{ "andq $dst, $src\t# long" %} 9156 opcode(0x23); 9157 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9158 ins_pipe(ialu_reg_reg); 9159 %} 9160 9161 // And Register with Immediate 255 9162 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9163 %{ 9164 match(Set dst (AndL dst src)); 9165 9166 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9167 opcode(0x0F, 0xB6); 9168 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9169 ins_pipe(ialu_reg); 9170 %} 9171 9172 // And Register with Immediate 65535 9173 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9174 %{ 9175 match(Set dst (AndL dst src)); 9176 9177 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9178 opcode(0x0F, 0xB7); 9179 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9180 ins_pipe(ialu_reg); 9181 %} 9182 9183 // And Register with Immediate 9184 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9185 %{ 9186 match(Set dst (AndL dst src)); 9187 effect(KILL cr); 9188 9189 format %{ "andq $dst, $src\t# long" %} 9190 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9191 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9192 ins_pipe(ialu_reg); 9193 %} 9194 9195 // And Register with Memory 9196 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9197 %{ 9198 match(Set dst (AndL dst (LoadL src))); 9199 effect(KILL cr); 9200 9201 ins_cost(125); 9202 format %{ "andq $dst, $src\t# long" %} 9203 opcode(0x23); 9204 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9205 ins_pipe(ialu_reg_mem); 9206 %} 9207 9208 // And Memory with Register 9209 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9210 %{ 9211 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9212 effect(KILL cr); 9213 9214 ins_cost(150); 9215 format %{ "andq $dst, $src\t# long" %} 9216 opcode(0x21); /* Opcode 21 /r */ 9217 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9218 ins_pipe(ialu_mem_reg); 9219 %} 9220 9221 // And Memory with Immediate 9222 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9223 %{ 9224 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9225 effect(KILL cr); 9226 9227 ins_cost(125); 9228 format %{ "andq $dst, $src\t# long" %} 9229 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9230 ins_encode(REX_mem_wide(dst), OpcSE(src), 9231 RM_opc_mem(secondary, dst), Con8or32(src)); 9232 ins_pipe(ialu_mem_imm); 9233 %} 9234 9235 // BMI1 instructions 9236 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9237 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9238 predicate(UseBMI1Instructions); 9239 effect(KILL cr); 9240 9241 ins_cost(125); 9242 format %{ "andnq $dst, $src1, $src2" %} 9243 9244 ins_encode %{ 9245 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9246 %} 9247 ins_pipe(ialu_reg_mem); 9248 %} 9249 9250 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9251 match(Set dst (AndL (XorL src1 minus_1) src2)); 9252 predicate(UseBMI1Instructions); 9253 effect(KILL cr); 9254 9255 format %{ "andnq $dst, $src1, $src2" %} 9256 9257 ins_encode %{ 9258 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9259 %} 9260 ins_pipe(ialu_reg_mem); 9261 %} 9262 9263 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9264 match(Set dst (AndL (SubL imm_zero src) src)); 9265 predicate(UseBMI1Instructions); 9266 effect(KILL cr); 9267 9268 format %{ "blsiq $dst, $src" %} 9269 9270 ins_encode %{ 9271 __ blsiq($dst$$Register, $src$$Register); 9272 %} 9273 ins_pipe(ialu_reg); 9274 %} 9275 9276 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9277 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9278 predicate(UseBMI1Instructions); 9279 effect(KILL cr); 9280 9281 ins_cost(125); 9282 format %{ "blsiq $dst, $src" %} 9283 9284 ins_encode %{ 9285 __ blsiq($dst$$Register, $src$$Address); 9286 %} 9287 ins_pipe(ialu_reg_mem); 9288 %} 9289 9290 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9291 %{ 9292 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9293 predicate(UseBMI1Instructions); 9294 effect(KILL cr); 9295 9296 ins_cost(125); 9297 format %{ "blsmskq $dst, $src" %} 9298 9299 ins_encode %{ 9300 __ blsmskq($dst$$Register, $src$$Address); 9301 %} 9302 ins_pipe(ialu_reg_mem); 9303 %} 9304 9305 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9306 %{ 9307 match(Set dst (XorL (AddL src minus_1) src)); 9308 predicate(UseBMI1Instructions); 9309 effect(KILL cr); 9310 9311 format %{ "blsmskq $dst, $src" %} 9312 9313 ins_encode %{ 9314 __ blsmskq($dst$$Register, $src$$Register); 9315 %} 9316 9317 ins_pipe(ialu_reg); 9318 %} 9319 9320 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9321 %{ 9322 match(Set dst (AndL (AddL src minus_1) src) ); 9323 predicate(UseBMI1Instructions); 9324 effect(KILL cr); 9325 9326 format %{ "blsrq $dst, $src" %} 9327 9328 ins_encode %{ 9329 __ blsrq($dst$$Register, $src$$Register); 9330 %} 9331 9332 ins_pipe(ialu_reg); 9333 %} 9334 9335 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9336 %{ 9337 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9338 predicate(UseBMI1Instructions); 9339 effect(KILL cr); 9340 9341 ins_cost(125); 9342 format %{ "blsrq $dst, $src" %} 9343 9344 ins_encode %{ 9345 __ blsrq($dst$$Register, $src$$Address); 9346 %} 9347 9348 ins_pipe(ialu_reg); 9349 %} 9350 9351 // Or Instructions 9352 // Or Register with Register 9353 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9354 %{ 9355 match(Set dst (OrL dst src)); 9356 effect(KILL cr); 9357 9358 format %{ "orq $dst, $src\t# long" %} 9359 opcode(0x0B); 9360 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9361 ins_pipe(ialu_reg_reg); 9362 %} 9363 9364 // Use any_RegP to match R15 (TLS register) without spilling. 9365 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9366 match(Set dst (OrL dst (CastP2X src))); 9367 effect(KILL cr); 9368 9369 format %{ "orq $dst, $src\t# long" %} 9370 opcode(0x0B); 9371 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9372 ins_pipe(ialu_reg_reg); 9373 %} 9374 9375 9376 // Or Register with Immediate 9377 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9378 %{ 9379 match(Set dst (OrL dst src)); 9380 effect(KILL cr); 9381 9382 format %{ "orq $dst, $src\t# long" %} 9383 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9384 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9385 ins_pipe(ialu_reg); 9386 %} 9387 9388 // Or Register with Memory 9389 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9390 %{ 9391 match(Set dst (OrL dst (LoadL src))); 9392 effect(KILL cr); 9393 9394 ins_cost(125); 9395 format %{ "orq $dst, $src\t# long" %} 9396 opcode(0x0B); 9397 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9398 ins_pipe(ialu_reg_mem); 9399 %} 9400 9401 // Or Memory with Register 9402 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9403 %{ 9404 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9405 effect(KILL cr); 9406 9407 ins_cost(150); 9408 format %{ "orq $dst, $src\t# long" %} 9409 opcode(0x09); /* Opcode 09 /r */ 9410 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9411 ins_pipe(ialu_mem_reg); 9412 %} 9413 9414 // Or Memory with Immediate 9415 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9416 %{ 9417 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9418 effect(KILL cr); 9419 9420 ins_cost(125); 9421 format %{ "orq $dst, $src\t# long" %} 9422 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9423 ins_encode(REX_mem_wide(dst), OpcSE(src), 9424 RM_opc_mem(secondary, dst), Con8or32(src)); 9425 ins_pipe(ialu_mem_imm); 9426 %} 9427 9428 // Xor Instructions 9429 // Xor Register with Register 9430 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9431 %{ 9432 match(Set dst (XorL dst src)); 9433 effect(KILL cr); 9434 9435 format %{ "xorq $dst, $src\t# long" %} 9436 opcode(0x33); 9437 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9438 ins_pipe(ialu_reg_reg); 9439 %} 9440 9441 // Xor Register with Immediate -1 9442 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9443 match(Set dst (XorL dst imm)); 9444 9445 format %{ "notq $dst" %} 9446 ins_encode %{ 9447 __ notq($dst$$Register); 9448 %} 9449 ins_pipe(ialu_reg); 9450 %} 9451 9452 // Xor Register with Immediate 9453 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9454 %{ 9455 match(Set dst (XorL dst src)); 9456 effect(KILL cr); 9457 9458 format %{ "xorq $dst, $src\t# long" %} 9459 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9460 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9461 ins_pipe(ialu_reg); 9462 %} 9463 9464 // Xor Register with Memory 9465 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9466 %{ 9467 match(Set dst (XorL dst (LoadL src))); 9468 effect(KILL cr); 9469 9470 ins_cost(125); 9471 format %{ "xorq $dst, $src\t# long" %} 9472 opcode(0x33); 9473 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9474 ins_pipe(ialu_reg_mem); 9475 %} 9476 9477 // Xor Memory with Register 9478 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9479 %{ 9480 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9481 effect(KILL cr); 9482 9483 ins_cost(150); 9484 format %{ "xorq $dst, $src\t# long" %} 9485 opcode(0x31); /* Opcode 31 /r */ 9486 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9487 ins_pipe(ialu_mem_reg); 9488 %} 9489 9490 // Xor Memory with Immediate 9491 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9492 %{ 9493 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9494 effect(KILL cr); 9495 9496 ins_cost(125); 9497 format %{ "xorq $dst, $src\t# long" %} 9498 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9499 ins_encode(REX_mem_wide(dst), OpcSE(src), 9500 RM_opc_mem(secondary, dst), Con8or32(src)); 9501 ins_pipe(ialu_mem_imm); 9502 %} 9503 9504 // Convert Int to Boolean 9505 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9506 %{ 9507 match(Set dst (Conv2B src)); 9508 effect(KILL cr); 9509 9510 format %{ "testl $src, $src\t# ci2b\n\t" 9511 "setnz $dst\n\t" 9512 "movzbl $dst, $dst" %} 9513 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9514 setNZ_reg(dst), 9515 REX_reg_breg(dst, dst), // movzbl 9516 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9517 ins_pipe(pipe_slow); // XXX 9518 %} 9519 9520 // Convert Pointer to Boolean 9521 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9522 %{ 9523 match(Set dst (Conv2B src)); 9524 effect(KILL cr); 9525 9526 format %{ "testq $src, $src\t# cp2b\n\t" 9527 "setnz $dst\n\t" 9528 "movzbl $dst, $dst" %} 9529 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9530 setNZ_reg(dst), 9531 REX_reg_breg(dst, dst), // movzbl 9532 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9533 ins_pipe(pipe_slow); // XXX 9534 %} 9535 9536 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9537 %{ 9538 match(Set dst (CmpLTMask p q)); 9539 effect(KILL cr); 9540 9541 ins_cost(400); 9542 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9543 "setlt $dst\n\t" 9544 "movzbl $dst, $dst\n\t" 9545 "negl $dst" %} 9546 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9547 setLT_reg(dst), 9548 REX_reg_breg(dst, dst), // movzbl 9549 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9550 neg_reg(dst)); 9551 ins_pipe(pipe_slow); 9552 %} 9553 9554 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9555 %{ 9556 match(Set dst (CmpLTMask dst zero)); 9557 effect(KILL cr); 9558 9559 ins_cost(100); 9560 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9561 ins_encode %{ 9562 __ sarl($dst$$Register, 31); 9563 %} 9564 ins_pipe(ialu_reg); 9565 %} 9566 9567 /* Better to save a register than avoid a branch */ 9568 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9569 %{ 9570 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9571 effect(KILL cr); 9572 ins_cost(300); 9573 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9574 "jge done\n\t" 9575 "addl $p,$y\n" 9576 "done: " %} 9577 ins_encode %{ 9578 Register Rp = $p$$Register; 9579 Register Rq = $q$$Register; 9580 Register Ry = $y$$Register; 9581 Label done; 9582 __ subl(Rp, Rq); 9583 __ jccb(Assembler::greaterEqual, done); 9584 __ addl(Rp, Ry); 9585 __ bind(done); 9586 %} 9587 ins_pipe(pipe_cmplt); 9588 %} 9589 9590 /* Better to save a register than avoid a branch */ 9591 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9592 %{ 9593 match(Set y (AndI (CmpLTMask p q) y)); 9594 effect(KILL cr); 9595 9596 ins_cost(300); 9597 9598 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9599 "jlt done\n\t" 9600 "xorl $y, $y\n" 9601 "done: " %} 9602 ins_encode %{ 9603 Register Rp = $p$$Register; 9604 Register Rq = $q$$Register; 9605 Register Ry = $y$$Register; 9606 Label done; 9607 __ cmpl(Rp, Rq); 9608 __ jccb(Assembler::less, done); 9609 __ xorl(Ry, Ry); 9610 __ bind(done); 9611 %} 9612 ins_pipe(pipe_cmplt); 9613 %} 9614 9615 9616 //---------- FP Instructions------------------------------------------------ 9617 9618 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9619 %{ 9620 match(Set cr (CmpF src1 src2)); 9621 9622 ins_cost(145); 9623 format %{ "ucomiss $src1, $src2\n\t" 9624 "jnp,s exit\n\t" 9625 "pushfq\t# saw NaN, set CF\n\t" 9626 "andq [rsp], #0xffffff2b\n\t" 9627 "popfq\n" 9628 "exit:" %} 9629 ins_encode %{ 9630 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9631 emit_cmpfp_fixup(_masm); 9632 %} 9633 ins_pipe(pipe_slow); 9634 %} 9635 9636 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9637 match(Set cr (CmpF src1 src2)); 9638 9639 ins_cost(100); 9640 format %{ "ucomiss $src1, $src2" %} 9641 ins_encode %{ 9642 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9643 %} 9644 ins_pipe(pipe_slow); 9645 %} 9646 9647 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9648 %{ 9649 match(Set cr (CmpF src1 (LoadF src2))); 9650 9651 ins_cost(145); 9652 format %{ "ucomiss $src1, $src2\n\t" 9653 "jnp,s exit\n\t" 9654 "pushfq\t# saw NaN, set CF\n\t" 9655 "andq [rsp], #0xffffff2b\n\t" 9656 "popfq\n" 9657 "exit:" %} 9658 ins_encode %{ 9659 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9660 emit_cmpfp_fixup(_masm); 9661 %} 9662 ins_pipe(pipe_slow); 9663 %} 9664 9665 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9666 match(Set cr (CmpF src1 (LoadF src2))); 9667 9668 ins_cost(100); 9669 format %{ "ucomiss $src1, $src2" %} 9670 ins_encode %{ 9671 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9672 %} 9673 ins_pipe(pipe_slow); 9674 %} 9675 9676 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9677 match(Set cr (CmpF src con)); 9678 9679 ins_cost(145); 9680 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9681 "jnp,s exit\n\t" 9682 "pushfq\t# saw NaN, set CF\n\t" 9683 "andq [rsp], #0xffffff2b\n\t" 9684 "popfq\n" 9685 "exit:" %} 9686 ins_encode %{ 9687 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9688 emit_cmpfp_fixup(_masm); 9689 %} 9690 ins_pipe(pipe_slow); 9691 %} 9692 9693 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9694 match(Set cr (CmpF src con)); 9695 ins_cost(100); 9696 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9697 ins_encode %{ 9698 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9699 %} 9700 ins_pipe(pipe_slow); 9701 %} 9702 9703 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9704 %{ 9705 match(Set cr (CmpD src1 src2)); 9706 9707 ins_cost(145); 9708 format %{ "ucomisd $src1, $src2\n\t" 9709 "jnp,s exit\n\t" 9710 "pushfq\t# saw NaN, set CF\n\t" 9711 "andq [rsp], #0xffffff2b\n\t" 9712 "popfq\n" 9713 "exit:" %} 9714 ins_encode %{ 9715 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9716 emit_cmpfp_fixup(_masm); 9717 %} 9718 ins_pipe(pipe_slow); 9719 %} 9720 9721 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9722 match(Set cr (CmpD src1 src2)); 9723 9724 ins_cost(100); 9725 format %{ "ucomisd $src1, $src2 test" %} 9726 ins_encode %{ 9727 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9728 %} 9729 ins_pipe(pipe_slow); 9730 %} 9731 9732 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9733 %{ 9734 match(Set cr (CmpD src1 (LoadD src2))); 9735 9736 ins_cost(145); 9737 format %{ "ucomisd $src1, $src2\n\t" 9738 "jnp,s exit\n\t" 9739 "pushfq\t# saw NaN, set CF\n\t" 9740 "andq [rsp], #0xffffff2b\n\t" 9741 "popfq\n" 9742 "exit:" %} 9743 ins_encode %{ 9744 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9745 emit_cmpfp_fixup(_masm); 9746 %} 9747 ins_pipe(pipe_slow); 9748 %} 9749 9750 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9751 match(Set cr (CmpD src1 (LoadD src2))); 9752 9753 ins_cost(100); 9754 format %{ "ucomisd $src1, $src2" %} 9755 ins_encode %{ 9756 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9757 %} 9758 ins_pipe(pipe_slow); 9759 %} 9760 9761 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9762 match(Set cr (CmpD src con)); 9763 9764 ins_cost(145); 9765 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9766 "jnp,s exit\n\t" 9767 "pushfq\t# saw NaN, set CF\n\t" 9768 "andq [rsp], #0xffffff2b\n\t" 9769 "popfq\n" 9770 "exit:" %} 9771 ins_encode %{ 9772 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9773 emit_cmpfp_fixup(_masm); 9774 %} 9775 ins_pipe(pipe_slow); 9776 %} 9777 9778 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9779 match(Set cr (CmpD src con)); 9780 ins_cost(100); 9781 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9782 ins_encode %{ 9783 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9784 %} 9785 ins_pipe(pipe_slow); 9786 %} 9787 9788 // Compare into -1,0,1 9789 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9790 %{ 9791 match(Set dst (CmpF3 src1 src2)); 9792 effect(KILL cr); 9793 9794 ins_cost(275); 9795 format %{ "ucomiss $src1, $src2\n\t" 9796 "movl $dst, #-1\n\t" 9797 "jp,s done\n\t" 9798 "jb,s done\n\t" 9799 "setne $dst\n\t" 9800 "movzbl $dst, $dst\n" 9801 "done:" %} 9802 ins_encode %{ 9803 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9804 emit_cmpfp3(_masm, $dst$$Register); 9805 %} 9806 ins_pipe(pipe_slow); 9807 %} 9808 9809 // Compare into -1,0,1 9810 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9811 %{ 9812 match(Set dst (CmpF3 src1 (LoadF src2))); 9813 effect(KILL cr); 9814 9815 ins_cost(275); 9816 format %{ "ucomiss $src1, $src2\n\t" 9817 "movl $dst, #-1\n\t" 9818 "jp,s done\n\t" 9819 "jb,s done\n\t" 9820 "setne $dst\n\t" 9821 "movzbl $dst, $dst\n" 9822 "done:" %} 9823 ins_encode %{ 9824 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9825 emit_cmpfp3(_masm, $dst$$Register); 9826 %} 9827 ins_pipe(pipe_slow); 9828 %} 9829 9830 // Compare into -1,0,1 9831 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9832 match(Set dst (CmpF3 src con)); 9833 effect(KILL cr); 9834 9835 ins_cost(275); 9836 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9837 "movl $dst, #-1\n\t" 9838 "jp,s done\n\t" 9839 "jb,s done\n\t" 9840 "setne $dst\n\t" 9841 "movzbl $dst, $dst\n" 9842 "done:" %} 9843 ins_encode %{ 9844 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9845 emit_cmpfp3(_masm, $dst$$Register); 9846 %} 9847 ins_pipe(pipe_slow); 9848 %} 9849 9850 // Compare into -1,0,1 9851 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9852 %{ 9853 match(Set dst (CmpD3 src1 src2)); 9854 effect(KILL cr); 9855 9856 ins_cost(275); 9857 format %{ "ucomisd $src1, $src2\n\t" 9858 "movl $dst, #-1\n\t" 9859 "jp,s done\n\t" 9860 "jb,s done\n\t" 9861 "setne $dst\n\t" 9862 "movzbl $dst, $dst\n" 9863 "done:" %} 9864 ins_encode %{ 9865 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9866 emit_cmpfp3(_masm, $dst$$Register); 9867 %} 9868 ins_pipe(pipe_slow); 9869 %} 9870 9871 // Compare into -1,0,1 9872 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9873 %{ 9874 match(Set dst (CmpD3 src1 (LoadD src2))); 9875 effect(KILL cr); 9876 9877 ins_cost(275); 9878 format %{ "ucomisd $src1, $src2\n\t" 9879 "movl $dst, #-1\n\t" 9880 "jp,s done\n\t" 9881 "jb,s done\n\t" 9882 "setne $dst\n\t" 9883 "movzbl $dst, $dst\n" 9884 "done:" %} 9885 ins_encode %{ 9886 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9887 emit_cmpfp3(_masm, $dst$$Register); 9888 %} 9889 ins_pipe(pipe_slow); 9890 %} 9891 9892 // Compare into -1,0,1 9893 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9894 match(Set dst (CmpD3 src con)); 9895 effect(KILL cr); 9896 9897 ins_cost(275); 9898 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9899 "movl $dst, #-1\n\t" 9900 "jp,s done\n\t" 9901 "jb,s done\n\t" 9902 "setne $dst\n\t" 9903 "movzbl $dst, $dst\n" 9904 "done:" %} 9905 ins_encode %{ 9906 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9907 emit_cmpfp3(_masm, $dst$$Register); 9908 %} 9909 ins_pipe(pipe_slow); 9910 %} 9911 9912 // -----------Trig and Trancendental Instructions------------------------------ 9913 instruct cosD_reg(regD dst) %{ 9914 match(Set dst (CosD dst)); 9915 9916 format %{ "dcos $dst\n\t" %} 9917 opcode(0xD9, 0xFF); 9918 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9919 ins_pipe( pipe_slow ); 9920 %} 9921 9922 instruct sinD_reg(regD dst) %{ 9923 match(Set dst (SinD dst)); 9924 9925 format %{ "dsin $dst\n\t" %} 9926 opcode(0xD9, 0xFE); 9927 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9928 ins_pipe( pipe_slow ); 9929 %} 9930 9931 instruct tanD_reg(regD dst) %{ 9932 match(Set dst (TanD dst)); 9933 9934 format %{ "dtan $dst\n\t" %} 9935 ins_encode( Push_SrcXD(dst), 9936 Opcode(0xD9), Opcode(0xF2), //fptan 9937 Opcode(0xDD), Opcode(0xD8), //fstp st 9938 Push_ResultXD(dst) ); 9939 ins_pipe( pipe_slow ); 9940 %} 9941 9942 instruct log10D_reg(regD dst) %{ 9943 // The source and result Double operands in XMM registers 9944 match(Set dst (Log10D dst)); 9945 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 9946 // fyl2x ; compute log_10(2) * log_2(x) 9947 format %{ "fldlg2\t\t\t#Log10\n\t" 9948 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 9949 %} 9950 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 9951 Push_SrcXD(dst), 9952 Opcode(0xD9), Opcode(0xF1), // fyl2x 9953 Push_ResultXD(dst)); 9954 9955 ins_pipe( pipe_slow ); 9956 %} 9957 9958 instruct logD_reg(regD dst) %{ 9959 // The source and result Double operands in XMM registers 9960 match(Set dst (LogD dst)); 9961 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 9962 // fyl2x ; compute log_e(2) * log_2(x) 9963 format %{ "fldln2\t\t\t#Log_e\n\t" 9964 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 9965 %} 9966 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 9967 Push_SrcXD(dst), 9968 Opcode(0xD9), Opcode(0xF1), // fyl2x 9969 Push_ResultXD(dst)); 9970 ins_pipe( pipe_slow ); 9971 %} 9972 9973 instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9974 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power 9975 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); 9976 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %} 9977 ins_encode %{ 9978 __ subptr(rsp, 8); 9979 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); 9980 __ fld_d(Address(rsp, 0)); 9981 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); 9982 __ fld_d(Address(rsp, 0)); 9983 __ fast_pow(); 9984 __ fstp_d(Address(rsp, 0)); 9985 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9986 __ addptr(rsp, 8); 9987 %} 9988 ins_pipe( pipe_slow ); 9989 %} 9990 9991 instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9992 match(Set dst (ExpD src)); 9993 effect(KILL rax, KILL rcx, KILL rdx, KILL cr); 9994 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %} 9995 ins_encode %{ 9996 __ subptr(rsp, 8); 9997 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9998 __ fld_d(Address(rsp, 0)); 9999 __ fast_exp(); 10000 __ fstp_d(Address(rsp, 0)); 10001 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 10002 __ addptr(rsp, 8); 10003 %} 10004 ins_pipe( pipe_slow ); 10005 %} 10006 10007 //----------Arithmetic Conversion Instructions--------------------------------- 10008 10009 instruct roundFloat_nop(regF dst) 10010 %{ 10011 match(Set dst (RoundFloat dst)); 10012 10013 ins_cost(0); 10014 ins_encode(); 10015 ins_pipe(empty); 10016 %} 10017 10018 instruct roundDouble_nop(regD dst) 10019 %{ 10020 match(Set dst (RoundDouble dst)); 10021 10022 ins_cost(0); 10023 ins_encode(); 10024 ins_pipe(empty); 10025 %} 10026 10027 instruct convF2D_reg_reg(regD dst, regF src) 10028 %{ 10029 match(Set dst (ConvF2D src)); 10030 10031 format %{ "cvtss2sd $dst, $src" %} 10032 ins_encode %{ 10033 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10034 %} 10035 ins_pipe(pipe_slow); // XXX 10036 %} 10037 10038 instruct convF2D_reg_mem(regD dst, memory src) 10039 %{ 10040 match(Set dst (ConvF2D (LoadF src))); 10041 10042 format %{ "cvtss2sd $dst, $src" %} 10043 ins_encode %{ 10044 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10045 %} 10046 ins_pipe(pipe_slow); // XXX 10047 %} 10048 10049 instruct convD2F_reg_reg(regF dst, regD src) 10050 %{ 10051 match(Set dst (ConvD2F src)); 10052 10053 format %{ "cvtsd2ss $dst, $src" %} 10054 ins_encode %{ 10055 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10056 %} 10057 ins_pipe(pipe_slow); // XXX 10058 %} 10059 10060 instruct convD2F_reg_mem(regF dst, memory src) 10061 %{ 10062 match(Set dst (ConvD2F (LoadD src))); 10063 10064 format %{ "cvtsd2ss $dst, $src" %} 10065 ins_encode %{ 10066 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10067 %} 10068 ins_pipe(pipe_slow); // XXX 10069 %} 10070 10071 // XXX do mem variants 10072 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10073 %{ 10074 match(Set dst (ConvF2I src)); 10075 effect(KILL cr); 10076 10077 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10078 "cmpl $dst, #0x80000000\n\t" 10079 "jne,s done\n\t" 10080 "subq rsp, #8\n\t" 10081 "movss [rsp], $src\n\t" 10082 "call f2i_fixup\n\t" 10083 "popq $dst\n" 10084 "done: "%} 10085 ins_encode %{ 10086 Label done; 10087 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10088 __ cmpl($dst$$Register, 0x80000000); 10089 __ jccb(Assembler::notEqual, done); 10090 __ subptr(rsp, 8); 10091 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10092 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10093 __ pop($dst$$Register); 10094 __ bind(done); 10095 %} 10096 ins_pipe(pipe_slow); 10097 %} 10098 10099 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10100 %{ 10101 match(Set dst (ConvF2L src)); 10102 effect(KILL cr); 10103 10104 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10105 "cmpq $dst, [0x8000000000000000]\n\t" 10106 "jne,s done\n\t" 10107 "subq rsp, #8\n\t" 10108 "movss [rsp], $src\n\t" 10109 "call f2l_fixup\n\t" 10110 "popq $dst\n" 10111 "done: "%} 10112 ins_encode %{ 10113 Label done; 10114 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10115 __ cmp64($dst$$Register, 10116 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10117 __ jccb(Assembler::notEqual, done); 10118 __ subptr(rsp, 8); 10119 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10120 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10121 __ pop($dst$$Register); 10122 __ bind(done); 10123 %} 10124 ins_pipe(pipe_slow); 10125 %} 10126 10127 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10128 %{ 10129 match(Set dst (ConvD2I src)); 10130 effect(KILL cr); 10131 10132 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10133 "cmpl $dst, #0x80000000\n\t" 10134 "jne,s done\n\t" 10135 "subq rsp, #8\n\t" 10136 "movsd [rsp], $src\n\t" 10137 "call d2i_fixup\n\t" 10138 "popq $dst\n" 10139 "done: "%} 10140 ins_encode %{ 10141 Label done; 10142 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10143 __ cmpl($dst$$Register, 0x80000000); 10144 __ jccb(Assembler::notEqual, done); 10145 __ subptr(rsp, 8); 10146 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10147 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10148 __ pop($dst$$Register); 10149 __ bind(done); 10150 %} 10151 ins_pipe(pipe_slow); 10152 %} 10153 10154 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10155 %{ 10156 match(Set dst (ConvD2L src)); 10157 effect(KILL cr); 10158 10159 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10160 "cmpq $dst, [0x8000000000000000]\n\t" 10161 "jne,s done\n\t" 10162 "subq rsp, #8\n\t" 10163 "movsd [rsp], $src\n\t" 10164 "call d2l_fixup\n\t" 10165 "popq $dst\n" 10166 "done: "%} 10167 ins_encode %{ 10168 Label done; 10169 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10170 __ cmp64($dst$$Register, 10171 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10172 __ jccb(Assembler::notEqual, done); 10173 __ subptr(rsp, 8); 10174 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10175 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10176 __ pop($dst$$Register); 10177 __ bind(done); 10178 %} 10179 ins_pipe(pipe_slow); 10180 %} 10181 10182 instruct convI2F_reg_reg(regF dst, rRegI src) 10183 %{ 10184 predicate(!UseXmmI2F); 10185 match(Set dst (ConvI2F src)); 10186 10187 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10188 ins_encode %{ 10189 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10190 %} 10191 ins_pipe(pipe_slow); // XXX 10192 %} 10193 10194 instruct convI2F_reg_mem(regF dst, memory src) 10195 %{ 10196 match(Set dst (ConvI2F (LoadI src))); 10197 10198 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10199 ins_encode %{ 10200 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10201 %} 10202 ins_pipe(pipe_slow); // XXX 10203 %} 10204 10205 instruct convI2D_reg_reg(regD dst, rRegI src) 10206 %{ 10207 predicate(!UseXmmI2D); 10208 match(Set dst (ConvI2D src)); 10209 10210 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10211 ins_encode %{ 10212 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10213 %} 10214 ins_pipe(pipe_slow); // XXX 10215 %} 10216 10217 instruct convI2D_reg_mem(regD dst, memory src) 10218 %{ 10219 match(Set dst (ConvI2D (LoadI src))); 10220 10221 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10222 ins_encode %{ 10223 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10224 %} 10225 ins_pipe(pipe_slow); // XXX 10226 %} 10227 10228 instruct convXI2F_reg(regF dst, rRegI src) 10229 %{ 10230 predicate(UseXmmI2F); 10231 match(Set dst (ConvI2F src)); 10232 10233 format %{ "movdl $dst, $src\n\t" 10234 "cvtdq2psl $dst, $dst\t# i2f" %} 10235 ins_encode %{ 10236 __ movdl($dst$$XMMRegister, $src$$Register); 10237 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10238 %} 10239 ins_pipe(pipe_slow); // XXX 10240 %} 10241 10242 instruct convXI2D_reg(regD dst, rRegI src) 10243 %{ 10244 predicate(UseXmmI2D); 10245 match(Set dst (ConvI2D src)); 10246 10247 format %{ "movdl $dst, $src\n\t" 10248 "cvtdq2pdl $dst, $dst\t# i2d" %} 10249 ins_encode %{ 10250 __ movdl($dst$$XMMRegister, $src$$Register); 10251 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10252 %} 10253 ins_pipe(pipe_slow); // XXX 10254 %} 10255 10256 instruct convL2F_reg_reg(regF dst, rRegL src) 10257 %{ 10258 match(Set dst (ConvL2F src)); 10259 10260 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10261 ins_encode %{ 10262 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10263 %} 10264 ins_pipe(pipe_slow); // XXX 10265 %} 10266 10267 instruct convL2F_reg_mem(regF dst, memory src) 10268 %{ 10269 match(Set dst (ConvL2F (LoadL src))); 10270 10271 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10272 ins_encode %{ 10273 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10274 %} 10275 ins_pipe(pipe_slow); // XXX 10276 %} 10277 10278 instruct convL2D_reg_reg(regD dst, rRegL src) 10279 %{ 10280 match(Set dst (ConvL2D src)); 10281 10282 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10283 ins_encode %{ 10284 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10285 %} 10286 ins_pipe(pipe_slow); // XXX 10287 %} 10288 10289 instruct convL2D_reg_mem(regD dst, memory src) 10290 %{ 10291 match(Set dst (ConvL2D (LoadL src))); 10292 10293 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10294 ins_encode %{ 10295 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10296 %} 10297 ins_pipe(pipe_slow); // XXX 10298 %} 10299 10300 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10301 %{ 10302 match(Set dst (ConvI2L src)); 10303 10304 ins_cost(125); 10305 format %{ "movslq $dst, $src\t# i2l" %} 10306 ins_encode %{ 10307 __ movslq($dst$$Register, $src$$Register); 10308 %} 10309 ins_pipe(ialu_reg_reg); 10310 %} 10311 10312 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10313 // %{ 10314 // match(Set dst (ConvI2L src)); 10315 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10316 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10317 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10318 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10319 // ((const TypeNode*) n)->type()->is_long()->_lo == 10320 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10321 10322 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10323 // ins_encode(enc_copy(dst, src)); 10324 // // opcode(0x63); // needs REX.W 10325 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10326 // ins_pipe(ialu_reg_reg); 10327 // %} 10328 10329 // Zero-extend convert int to long 10330 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10331 %{ 10332 match(Set dst (AndL (ConvI2L src) mask)); 10333 10334 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10335 ins_encode %{ 10336 if ($dst$$reg != $src$$reg) { 10337 __ movl($dst$$Register, $src$$Register); 10338 } 10339 %} 10340 ins_pipe(ialu_reg_reg); 10341 %} 10342 10343 // Zero-extend convert int to long 10344 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10345 %{ 10346 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10347 10348 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10349 ins_encode %{ 10350 __ movl($dst$$Register, $src$$Address); 10351 %} 10352 ins_pipe(ialu_reg_mem); 10353 %} 10354 10355 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10356 %{ 10357 match(Set dst (AndL src mask)); 10358 10359 format %{ "movl $dst, $src\t# zero-extend long" %} 10360 ins_encode %{ 10361 __ movl($dst$$Register, $src$$Register); 10362 %} 10363 ins_pipe(ialu_reg_reg); 10364 %} 10365 10366 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10367 %{ 10368 match(Set dst (ConvL2I src)); 10369 10370 format %{ "movl $dst, $src\t# l2i" %} 10371 ins_encode %{ 10372 __ movl($dst$$Register, $src$$Register); 10373 %} 10374 ins_pipe(ialu_reg_reg); 10375 %} 10376 10377 10378 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10379 match(Set dst (MoveF2I src)); 10380 effect(DEF dst, USE src); 10381 10382 ins_cost(125); 10383 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10384 ins_encode %{ 10385 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10386 %} 10387 ins_pipe(ialu_reg_mem); 10388 %} 10389 10390 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10391 match(Set dst (MoveI2F src)); 10392 effect(DEF dst, USE src); 10393 10394 ins_cost(125); 10395 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10396 ins_encode %{ 10397 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10398 %} 10399 ins_pipe(pipe_slow); 10400 %} 10401 10402 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10403 match(Set dst (MoveD2L src)); 10404 effect(DEF dst, USE src); 10405 10406 ins_cost(125); 10407 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10408 ins_encode %{ 10409 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10410 %} 10411 ins_pipe(ialu_reg_mem); 10412 %} 10413 10414 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10415 predicate(!UseXmmLoadAndClearUpper); 10416 match(Set dst (MoveL2D src)); 10417 effect(DEF dst, USE src); 10418 10419 ins_cost(125); 10420 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10421 ins_encode %{ 10422 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10423 %} 10424 ins_pipe(pipe_slow); 10425 %} 10426 10427 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10428 predicate(UseXmmLoadAndClearUpper); 10429 match(Set dst (MoveL2D src)); 10430 effect(DEF dst, USE src); 10431 10432 ins_cost(125); 10433 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10434 ins_encode %{ 10435 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10436 %} 10437 ins_pipe(pipe_slow); 10438 %} 10439 10440 10441 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10442 match(Set dst (MoveF2I src)); 10443 effect(DEF dst, USE src); 10444 10445 ins_cost(95); // XXX 10446 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10447 ins_encode %{ 10448 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10449 %} 10450 ins_pipe(pipe_slow); 10451 %} 10452 10453 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10454 match(Set dst (MoveI2F src)); 10455 effect(DEF dst, USE src); 10456 10457 ins_cost(100); 10458 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10459 ins_encode %{ 10460 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10461 %} 10462 ins_pipe( ialu_mem_reg ); 10463 %} 10464 10465 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10466 match(Set dst (MoveD2L src)); 10467 effect(DEF dst, USE src); 10468 10469 ins_cost(95); // XXX 10470 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10471 ins_encode %{ 10472 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10473 %} 10474 ins_pipe(pipe_slow); 10475 %} 10476 10477 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10478 match(Set dst (MoveL2D src)); 10479 effect(DEF dst, USE src); 10480 10481 ins_cost(100); 10482 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10483 ins_encode %{ 10484 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10485 %} 10486 ins_pipe(ialu_mem_reg); 10487 %} 10488 10489 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10490 match(Set dst (MoveF2I src)); 10491 effect(DEF dst, USE src); 10492 ins_cost(85); 10493 format %{ "movd $dst,$src\t# MoveF2I" %} 10494 ins_encode %{ 10495 __ movdl($dst$$Register, $src$$XMMRegister); 10496 %} 10497 ins_pipe( pipe_slow ); 10498 %} 10499 10500 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10501 match(Set dst (MoveD2L src)); 10502 effect(DEF dst, USE src); 10503 ins_cost(85); 10504 format %{ "movd $dst,$src\t# MoveD2L" %} 10505 ins_encode %{ 10506 __ movdq($dst$$Register, $src$$XMMRegister); 10507 %} 10508 ins_pipe( pipe_slow ); 10509 %} 10510 10511 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10512 match(Set dst (MoveI2F src)); 10513 effect(DEF dst, USE src); 10514 ins_cost(100); 10515 format %{ "movd $dst,$src\t# MoveI2F" %} 10516 ins_encode %{ 10517 __ movdl($dst$$XMMRegister, $src$$Register); 10518 %} 10519 ins_pipe( pipe_slow ); 10520 %} 10521 10522 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10523 match(Set dst (MoveL2D src)); 10524 effect(DEF dst, USE src); 10525 ins_cost(100); 10526 format %{ "movd $dst,$src\t# MoveL2D" %} 10527 ins_encode %{ 10528 __ movdq($dst$$XMMRegister, $src$$Register); 10529 %} 10530 ins_pipe( pipe_slow ); 10531 %} 10532 10533 10534 // ======================================================================= 10535 // fast clearing of an array 10536 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10537 rFlagsReg cr) 10538 %{ 10539 predicate(!UseFastStosb); 10540 match(Set dummy (ClearArray cnt base)); 10541 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10542 10543 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10544 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 10545 ins_encode %{ 10546 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10547 %} 10548 ins_pipe(pipe_slow); 10549 %} 10550 10551 instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10552 rFlagsReg cr) 10553 %{ 10554 predicate(UseFastStosb); 10555 match(Set dummy (ClearArray cnt base)); 10556 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10557 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10558 "shlq rcx,3\t# Convert doublewords to bytes\n\t" 10559 "rep stosb\t# Store rax to *rdi++ while rcx--" %} 10560 ins_encode %{ 10561 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10562 %} 10563 ins_pipe( pipe_slow ); 10564 %} 10565 10566 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10567 rax_RegI result, regD tmp1, rFlagsReg cr) 10568 %{ 10569 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10570 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10571 10572 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10573 ins_encode %{ 10574 __ string_compare($str1$$Register, $str2$$Register, 10575 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10576 $tmp1$$XMMRegister); 10577 %} 10578 ins_pipe( pipe_slow ); 10579 %} 10580 10581 // fast search of substring with known size. 10582 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10583 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10584 %{ 10585 predicate(UseSSE42Intrinsics); 10586 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10587 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10588 10589 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10590 ins_encode %{ 10591 int icnt2 = (int)$int_cnt2$$constant; 10592 if (icnt2 >= 8) { 10593 // IndexOf for constant substrings with size >= 8 elements 10594 // which don't need to be loaded through stack. 10595 __ string_indexofC8($str1$$Register, $str2$$Register, 10596 $cnt1$$Register, $cnt2$$Register, 10597 icnt2, $result$$Register, 10598 $vec$$XMMRegister, $tmp$$Register); 10599 } else { 10600 // Small strings are loaded through stack if they cross page boundary. 10601 __ string_indexof($str1$$Register, $str2$$Register, 10602 $cnt1$$Register, $cnt2$$Register, 10603 icnt2, $result$$Register, 10604 $vec$$XMMRegister, $tmp$$Register); 10605 } 10606 %} 10607 ins_pipe( pipe_slow ); 10608 %} 10609 10610 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10611 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10612 %{ 10613 predicate(UseSSE42Intrinsics); 10614 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10615 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10616 10617 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10618 ins_encode %{ 10619 __ string_indexof($str1$$Register, $str2$$Register, 10620 $cnt1$$Register, $cnt2$$Register, 10621 (-1), $result$$Register, 10622 $vec$$XMMRegister, $tmp$$Register); 10623 %} 10624 ins_pipe( pipe_slow ); 10625 %} 10626 10627 // fast string equals 10628 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10629 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10630 %{ 10631 match(Set result (StrEquals (Binary str1 str2) cnt)); 10632 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10633 10634 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10635 ins_encode %{ 10636 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 10637 $cnt$$Register, $result$$Register, $tmp3$$Register, 10638 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10639 %} 10640 ins_pipe( pipe_slow ); 10641 %} 10642 10643 // fast array equals 10644 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10645 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10646 %{ 10647 match(Set result (AryEq ary1 ary2)); 10648 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10649 //ins_cost(300); 10650 10651 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10652 ins_encode %{ 10653 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 10654 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10655 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10656 %} 10657 ins_pipe( pipe_slow ); 10658 %} 10659 10660 // encode char[] to byte[] in ISO_8859_1 10661 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 10662 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 10663 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 10664 match(Set result (EncodeISOArray src (Binary dst len))); 10665 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 10666 10667 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 10668 ins_encode %{ 10669 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 10670 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 10671 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 10672 %} 10673 ins_pipe( pipe_slow ); 10674 %} 10675 10676 //----------Overflow Math Instructions----------------------------------------- 10677 10678 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10679 %{ 10680 match(Set cr (OverflowAddI op1 op2)); 10681 effect(DEF cr, USE_KILL op1, USE op2); 10682 10683 format %{ "addl $op1, $op2\t# overflow check int" %} 10684 10685 ins_encode %{ 10686 __ addl($op1$$Register, $op2$$Register); 10687 %} 10688 ins_pipe(ialu_reg_reg); 10689 %} 10690 10691 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 10692 %{ 10693 match(Set cr (OverflowAddI op1 op2)); 10694 effect(DEF cr, USE_KILL op1, USE op2); 10695 10696 format %{ "addl $op1, $op2\t# overflow check int" %} 10697 10698 ins_encode %{ 10699 __ addl($op1$$Register, $op2$$constant); 10700 %} 10701 ins_pipe(ialu_reg_reg); 10702 %} 10703 10704 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10705 %{ 10706 match(Set cr (OverflowAddL op1 op2)); 10707 effect(DEF cr, USE_KILL op1, USE op2); 10708 10709 format %{ "addq $op1, $op2\t# overflow check long" %} 10710 ins_encode %{ 10711 __ addq($op1$$Register, $op2$$Register); 10712 %} 10713 ins_pipe(ialu_reg_reg); 10714 %} 10715 10716 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 10717 %{ 10718 match(Set cr (OverflowAddL op1 op2)); 10719 effect(DEF cr, USE_KILL op1, USE op2); 10720 10721 format %{ "addq $op1, $op2\t# overflow check long" %} 10722 ins_encode %{ 10723 __ addq($op1$$Register, $op2$$constant); 10724 %} 10725 ins_pipe(ialu_reg_reg); 10726 %} 10727 10728 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10729 %{ 10730 match(Set cr (OverflowSubI op1 op2)); 10731 10732 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10733 ins_encode %{ 10734 __ cmpl($op1$$Register, $op2$$Register); 10735 %} 10736 ins_pipe(ialu_reg_reg); 10737 %} 10738 10739 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10740 %{ 10741 match(Set cr (OverflowSubI op1 op2)); 10742 10743 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10744 ins_encode %{ 10745 __ cmpl($op1$$Register, $op2$$constant); 10746 %} 10747 ins_pipe(ialu_reg_reg); 10748 %} 10749 10750 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10751 %{ 10752 match(Set cr (OverflowSubL op1 op2)); 10753 10754 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10755 ins_encode %{ 10756 __ cmpq($op1$$Register, $op2$$Register); 10757 %} 10758 ins_pipe(ialu_reg_reg); 10759 %} 10760 10761 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10762 %{ 10763 match(Set cr (OverflowSubL op1 op2)); 10764 10765 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10766 ins_encode %{ 10767 __ cmpq($op1$$Register, $op2$$constant); 10768 %} 10769 ins_pipe(ialu_reg_reg); 10770 %} 10771 10772 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 10773 %{ 10774 match(Set cr (OverflowSubI zero op2)); 10775 effect(DEF cr, USE_KILL op2); 10776 10777 format %{ "negl $op2\t# overflow check int" %} 10778 ins_encode %{ 10779 __ negl($op2$$Register); 10780 %} 10781 ins_pipe(ialu_reg_reg); 10782 %} 10783 10784 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 10785 %{ 10786 match(Set cr (OverflowSubL zero op2)); 10787 effect(DEF cr, USE_KILL op2); 10788 10789 format %{ "negq $op2\t# overflow check long" %} 10790 ins_encode %{ 10791 __ negq($op2$$Register); 10792 %} 10793 ins_pipe(ialu_reg_reg); 10794 %} 10795 10796 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10797 %{ 10798 match(Set cr (OverflowMulI op1 op2)); 10799 effect(DEF cr, USE_KILL op1, USE op2); 10800 10801 format %{ "imull $op1, $op2\t# overflow check int" %} 10802 ins_encode %{ 10803 __ imull($op1$$Register, $op2$$Register); 10804 %} 10805 ins_pipe(ialu_reg_reg_alu0); 10806 %} 10807 10808 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 10809 %{ 10810 match(Set cr (OverflowMulI op1 op2)); 10811 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10812 10813 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 10814 ins_encode %{ 10815 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 10816 %} 10817 ins_pipe(ialu_reg_reg_alu0); 10818 %} 10819 10820 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10821 %{ 10822 match(Set cr (OverflowMulL op1 op2)); 10823 effect(DEF cr, USE_KILL op1, USE op2); 10824 10825 format %{ "imulq $op1, $op2\t# overflow check long" %} 10826 ins_encode %{ 10827 __ imulq($op1$$Register, $op2$$Register); 10828 %} 10829 ins_pipe(ialu_reg_reg_alu0); 10830 %} 10831 10832 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 10833 %{ 10834 match(Set cr (OverflowMulL op1 op2)); 10835 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10836 10837 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 10838 ins_encode %{ 10839 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 10840 %} 10841 ins_pipe(ialu_reg_reg_alu0); 10842 %} 10843 10844 10845 //----------Control Flow Instructions------------------------------------------ 10846 // Signed compare Instructions 10847 10848 // XXX more variants!! 10849 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10850 %{ 10851 match(Set cr (CmpI op1 op2)); 10852 effect(DEF cr, USE op1, USE op2); 10853 10854 format %{ "cmpl $op1, $op2" %} 10855 opcode(0x3B); /* Opcode 3B /r */ 10856 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10857 ins_pipe(ialu_cr_reg_reg); 10858 %} 10859 10860 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10861 %{ 10862 match(Set cr (CmpI op1 op2)); 10863 10864 format %{ "cmpl $op1, $op2" %} 10865 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10866 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10867 ins_pipe(ialu_cr_reg_imm); 10868 %} 10869 10870 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 10871 %{ 10872 match(Set cr (CmpI op1 (LoadI op2))); 10873 10874 ins_cost(500); // XXX 10875 format %{ "cmpl $op1, $op2" %} 10876 opcode(0x3B); /* Opcode 3B /r */ 10877 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10878 ins_pipe(ialu_cr_reg_mem); 10879 %} 10880 10881 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 10882 %{ 10883 match(Set cr (CmpI src zero)); 10884 10885 format %{ "testl $src, $src" %} 10886 opcode(0x85); 10887 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10888 ins_pipe(ialu_cr_reg_imm); 10889 %} 10890 10891 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 10892 %{ 10893 match(Set cr (CmpI (AndI src con) zero)); 10894 10895 format %{ "testl $src, $con" %} 10896 opcode(0xF7, 0x00); 10897 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 10898 ins_pipe(ialu_cr_reg_imm); 10899 %} 10900 10901 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 10902 %{ 10903 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 10904 10905 format %{ "testl $src, $mem" %} 10906 opcode(0x85); 10907 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 10908 ins_pipe(ialu_cr_reg_mem); 10909 %} 10910 10911 // Unsigned compare Instructions; really, same as signed except they 10912 // produce an rFlagsRegU instead of rFlagsReg. 10913 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 10914 %{ 10915 match(Set cr (CmpU op1 op2)); 10916 10917 format %{ "cmpl $op1, $op2\t# unsigned" %} 10918 opcode(0x3B); /* Opcode 3B /r */ 10919 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10920 ins_pipe(ialu_cr_reg_reg); 10921 %} 10922 10923 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 10924 %{ 10925 match(Set cr (CmpU op1 op2)); 10926 10927 format %{ "cmpl $op1, $op2\t# unsigned" %} 10928 opcode(0x81,0x07); /* Opcode 81 /7 */ 10929 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10930 ins_pipe(ialu_cr_reg_imm); 10931 %} 10932 10933 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 10934 %{ 10935 match(Set cr (CmpU op1 (LoadI op2))); 10936 10937 ins_cost(500); // XXX 10938 format %{ "cmpl $op1, $op2\t# unsigned" %} 10939 opcode(0x3B); /* Opcode 3B /r */ 10940 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10941 ins_pipe(ialu_cr_reg_mem); 10942 %} 10943 10944 // // // Cisc-spilled version of cmpU_rReg 10945 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 10946 // //%{ 10947 // // match(Set cr (CmpU (LoadI op1) op2)); 10948 // // 10949 // // format %{ "CMPu $op1,$op2" %} 10950 // // ins_cost(500); 10951 // // opcode(0x39); /* Opcode 39 /r */ 10952 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10953 // //%} 10954 10955 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 10956 %{ 10957 match(Set cr (CmpU src zero)); 10958 10959 format %{ "testl $src, $src\t# unsigned" %} 10960 opcode(0x85); 10961 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10962 ins_pipe(ialu_cr_reg_imm); 10963 %} 10964 10965 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 10966 %{ 10967 match(Set cr (CmpP op1 op2)); 10968 10969 format %{ "cmpq $op1, $op2\t# ptr" %} 10970 opcode(0x3B); /* Opcode 3B /r */ 10971 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10972 ins_pipe(ialu_cr_reg_reg); 10973 %} 10974 10975 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 10976 %{ 10977 match(Set cr (CmpP op1 (LoadP op2))); 10978 10979 ins_cost(500); // XXX 10980 format %{ "cmpq $op1, $op2\t# ptr" %} 10981 opcode(0x3B); /* Opcode 3B /r */ 10982 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10983 ins_pipe(ialu_cr_reg_mem); 10984 %} 10985 10986 // // // Cisc-spilled version of cmpP_rReg 10987 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 10988 // //%{ 10989 // // match(Set cr (CmpP (LoadP op1) op2)); 10990 // // 10991 // // format %{ "CMPu $op1,$op2" %} 10992 // // ins_cost(500); 10993 // // opcode(0x39); /* Opcode 39 /r */ 10994 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10995 // //%} 10996 10997 // XXX this is generalized by compP_rReg_mem??? 10998 // Compare raw pointer (used in out-of-heap check). 10999 // Only works because non-oop pointers must be raw pointers 11000 // and raw pointers have no anti-dependencies. 11001 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11002 %{ 11003 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11004 match(Set cr (CmpP op1 (LoadP op2))); 11005 11006 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11007 opcode(0x3B); /* Opcode 3B /r */ 11008 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11009 ins_pipe(ialu_cr_reg_mem); 11010 %} 11011 11012 // This will generate a signed flags result. This should be OK since 11013 // any compare to a zero should be eq/neq. 11014 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11015 %{ 11016 match(Set cr (CmpP src zero)); 11017 11018 format %{ "testq $src, $src\t# ptr" %} 11019 opcode(0x85); 11020 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11021 ins_pipe(ialu_cr_reg_imm); 11022 %} 11023 11024 // This will generate a signed flags result. This should be OK since 11025 // any compare to a zero should be eq/neq. 11026 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11027 %{ 11028 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11029 match(Set cr (CmpP (LoadP op) zero)); 11030 11031 ins_cost(500); // XXX 11032 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11033 opcode(0xF7); /* Opcode F7 /0 */ 11034 ins_encode(REX_mem_wide(op), 11035 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11036 ins_pipe(ialu_cr_reg_imm); 11037 %} 11038 11039 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11040 %{ 11041 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11042 match(Set cr (CmpP (LoadP mem) zero)); 11043 11044 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11045 ins_encode %{ 11046 __ cmpq(r12, $mem$$Address); 11047 %} 11048 ins_pipe(ialu_cr_reg_mem); 11049 %} 11050 11051 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11052 %{ 11053 match(Set cr (CmpN op1 op2)); 11054 11055 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11056 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11057 ins_pipe(ialu_cr_reg_reg); 11058 %} 11059 11060 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11061 %{ 11062 match(Set cr (CmpN src (LoadN mem))); 11063 11064 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11065 ins_encode %{ 11066 __ cmpl($src$$Register, $mem$$Address); 11067 %} 11068 ins_pipe(ialu_cr_reg_mem); 11069 %} 11070 11071 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11072 match(Set cr (CmpN op1 op2)); 11073 11074 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11075 ins_encode %{ 11076 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11077 %} 11078 ins_pipe(ialu_cr_reg_imm); 11079 %} 11080 11081 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11082 %{ 11083 match(Set cr (CmpN src (LoadN mem))); 11084 11085 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11086 ins_encode %{ 11087 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11088 %} 11089 ins_pipe(ialu_cr_reg_mem); 11090 %} 11091 11092 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11093 match(Set cr (CmpN op1 op2)); 11094 11095 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11096 ins_encode %{ 11097 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11098 %} 11099 ins_pipe(ialu_cr_reg_imm); 11100 %} 11101 11102 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11103 %{ 11104 match(Set cr (CmpN src (LoadNKlass mem))); 11105 11106 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11107 ins_encode %{ 11108 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11109 %} 11110 ins_pipe(ialu_cr_reg_mem); 11111 %} 11112 11113 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11114 match(Set cr (CmpN src zero)); 11115 11116 format %{ "testl $src, $src\t# compressed ptr" %} 11117 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11118 ins_pipe(ialu_cr_reg_imm); 11119 %} 11120 11121 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11122 %{ 11123 predicate(Universe::narrow_oop_base() != NULL); 11124 match(Set cr (CmpN (LoadN mem) zero)); 11125 11126 ins_cost(500); // XXX 11127 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11128 ins_encode %{ 11129 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11130 %} 11131 ins_pipe(ialu_cr_reg_mem); 11132 %} 11133 11134 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11135 %{ 11136 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11137 match(Set cr (CmpN (LoadN mem) zero)); 11138 11139 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11140 ins_encode %{ 11141 __ cmpl(r12, $mem$$Address); 11142 %} 11143 ins_pipe(ialu_cr_reg_mem); 11144 %} 11145 11146 // Yanked all unsigned pointer compare operations. 11147 // Pointer compares are done with CmpP which is already unsigned. 11148 11149 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11150 %{ 11151 match(Set cr (CmpL op1 op2)); 11152 11153 format %{ "cmpq $op1, $op2" %} 11154 opcode(0x3B); /* Opcode 3B /r */ 11155 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11156 ins_pipe(ialu_cr_reg_reg); 11157 %} 11158 11159 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11160 %{ 11161 match(Set cr (CmpL op1 op2)); 11162 11163 format %{ "cmpq $op1, $op2" %} 11164 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11165 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11166 ins_pipe(ialu_cr_reg_imm); 11167 %} 11168 11169 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11170 %{ 11171 match(Set cr (CmpL op1 (LoadL op2))); 11172 11173 format %{ "cmpq $op1, $op2" %} 11174 opcode(0x3B); /* Opcode 3B /r */ 11175 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11176 ins_pipe(ialu_cr_reg_mem); 11177 %} 11178 11179 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11180 %{ 11181 match(Set cr (CmpL src zero)); 11182 11183 format %{ "testq $src, $src" %} 11184 opcode(0x85); 11185 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11186 ins_pipe(ialu_cr_reg_imm); 11187 %} 11188 11189 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11190 %{ 11191 match(Set cr (CmpL (AndL src con) zero)); 11192 11193 format %{ "testq $src, $con\t# long" %} 11194 opcode(0xF7, 0x00); 11195 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11196 ins_pipe(ialu_cr_reg_imm); 11197 %} 11198 11199 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11200 %{ 11201 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11202 11203 format %{ "testq $src, $mem" %} 11204 opcode(0x85); 11205 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11206 ins_pipe(ialu_cr_reg_mem); 11207 %} 11208 11209 // Manifest a CmpL result in an integer register. Very painful. 11210 // This is the test to avoid. 11211 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11212 %{ 11213 match(Set dst (CmpL3 src1 src2)); 11214 effect(KILL flags); 11215 11216 ins_cost(275); // XXX 11217 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11218 "movl $dst, -1\n\t" 11219 "jl,s done\n\t" 11220 "setne $dst\n\t" 11221 "movzbl $dst, $dst\n\t" 11222 "done:" %} 11223 ins_encode(cmpl3_flag(src1, src2, dst)); 11224 ins_pipe(pipe_slow); 11225 %} 11226 11227 // Unsigned long compare Instructions; really, same as signed long except they 11228 // produce an rFlagsRegU instead of rFlagsReg. 11229 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11230 %{ 11231 match(Set cr (CmpUL op1 op2)); 11232 11233 format %{ "cmpq $op1, $op2\t# unsigned" %} 11234 opcode(0x3B); /* Opcode 3B /r */ 11235 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11236 ins_pipe(ialu_cr_reg_reg); 11237 %} 11238 11239 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11240 %{ 11241 match(Set cr (CmpUL op1 op2)); 11242 11243 format %{ "cmpq $op1, $op2\t# unsigned" %} 11244 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11245 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11246 ins_pipe(ialu_cr_reg_imm); 11247 %} 11248 11249 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11250 %{ 11251 match(Set cr (CmpUL op1 (LoadL op2))); 11252 11253 format %{ "cmpq $op1, $op2\t# unsigned" %} 11254 opcode(0x3B); /* Opcode 3B /r */ 11255 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11256 ins_pipe(ialu_cr_reg_mem); 11257 %} 11258 11259 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11260 %{ 11261 match(Set cr (CmpUL src zero)); 11262 11263 format %{ "testq $src, $src\t# unsigned" %} 11264 opcode(0x85); 11265 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11266 ins_pipe(ialu_cr_reg_imm); 11267 %} 11268 11269 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11270 %{ 11271 // This match is actually generic, but protect with Shenandoah flag, 11272 // because it is not tested upstream. 11273 predicate(UseShenandoahGC); 11274 match(Set cr (CmpI (LoadB mem) imm)); 11275 11276 ins_cost(125); 11277 format %{ "cmpb $mem, $imm" %} 11278 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11279 ins_pipe(ialu_cr_reg_mem); 11280 %} 11281 11282 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 11283 %{ 11284 // This match is actually generic, but protect with Shenandoah flag, 11285 // because it is not tested upstream 11286 predicate(UseShenandoahGC); 11287 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11288 11289 ins_cost(125); 11290 format %{ "testb $mem, $imm" %} 11291 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11292 ins_pipe(ialu_cr_reg_mem); 11293 %} 11294 11295 //----------Max and Min-------------------------------------------------------- 11296 // Min Instructions 11297 11298 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11299 %{ 11300 effect(USE_DEF dst, USE src, USE cr); 11301 11302 format %{ "cmovlgt $dst, $src\t# min" %} 11303 opcode(0x0F, 0x4F); 11304 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11305 ins_pipe(pipe_cmov_reg); 11306 %} 11307 11308 11309 instruct minI_rReg(rRegI dst, rRegI src) 11310 %{ 11311 match(Set dst (MinI dst src)); 11312 11313 ins_cost(200); 11314 expand %{ 11315 rFlagsReg cr; 11316 compI_rReg(cr, dst, src); 11317 cmovI_reg_g(dst, src, cr); 11318 %} 11319 %} 11320 11321 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11322 %{ 11323 effect(USE_DEF dst, USE src, USE cr); 11324 11325 format %{ "cmovllt $dst, $src\t# max" %} 11326 opcode(0x0F, 0x4C); 11327 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11328 ins_pipe(pipe_cmov_reg); 11329 %} 11330 11331 11332 instruct maxI_rReg(rRegI dst, rRegI src) 11333 %{ 11334 match(Set dst (MaxI dst src)); 11335 11336 ins_cost(200); 11337 expand %{ 11338 rFlagsReg cr; 11339 compI_rReg(cr, dst, src); 11340 cmovI_reg_l(dst, src, cr); 11341 %} 11342 %} 11343 11344 // ============================================================================ 11345 // Branch Instructions 11346 11347 // Jump Direct - Label defines a relative address from JMP+1 11348 instruct jmpDir(label labl) 11349 %{ 11350 match(Goto); 11351 effect(USE labl); 11352 11353 ins_cost(300); 11354 format %{ "jmp $labl" %} 11355 size(5); 11356 ins_encode %{ 11357 Label* L = $labl$$label; 11358 __ jmp(*L, false); // Always long jump 11359 %} 11360 ins_pipe(pipe_jmp); 11361 %} 11362 11363 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11364 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11365 %{ 11366 match(If cop cr); 11367 effect(USE labl); 11368 11369 ins_cost(300); 11370 format %{ "j$cop $labl" %} 11371 size(6); 11372 ins_encode %{ 11373 Label* L = $labl$$label; 11374 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11375 %} 11376 ins_pipe(pipe_jcc); 11377 %} 11378 11379 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11380 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11381 %{ 11382 match(CountedLoopEnd cop cr); 11383 effect(USE labl); 11384 11385 ins_cost(300); 11386 format %{ "j$cop $labl\t# loop end" %} 11387 size(6); 11388 ins_encode %{ 11389 Label* L = $labl$$label; 11390 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11391 %} 11392 ins_pipe(pipe_jcc); 11393 %} 11394 11395 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11396 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11397 match(CountedLoopEnd cop cmp); 11398 effect(USE labl); 11399 11400 ins_cost(300); 11401 format %{ "j$cop,u $labl\t# loop end" %} 11402 size(6); 11403 ins_encode %{ 11404 Label* L = $labl$$label; 11405 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11406 %} 11407 ins_pipe(pipe_jcc); 11408 %} 11409 11410 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11411 match(CountedLoopEnd cop cmp); 11412 effect(USE labl); 11413 11414 ins_cost(200); 11415 format %{ "j$cop,u $labl\t# loop end" %} 11416 size(6); 11417 ins_encode %{ 11418 Label* L = $labl$$label; 11419 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11420 %} 11421 ins_pipe(pipe_jcc); 11422 %} 11423 11424 // Jump Direct Conditional - using unsigned comparison 11425 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11426 match(If cop cmp); 11427 effect(USE labl); 11428 11429 ins_cost(300); 11430 format %{ "j$cop,u $labl" %} 11431 size(6); 11432 ins_encode %{ 11433 Label* L = $labl$$label; 11434 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11435 %} 11436 ins_pipe(pipe_jcc); 11437 %} 11438 11439 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11440 match(If cop cmp); 11441 effect(USE labl); 11442 11443 ins_cost(200); 11444 format %{ "j$cop,u $labl" %} 11445 size(6); 11446 ins_encode %{ 11447 Label* L = $labl$$label; 11448 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11449 %} 11450 ins_pipe(pipe_jcc); 11451 %} 11452 11453 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11454 match(If cop cmp); 11455 effect(USE labl); 11456 11457 ins_cost(200); 11458 format %{ $$template 11459 if ($cop$$cmpcode == Assembler::notEqual) { 11460 $$emit$$"jp,u $labl\n\t" 11461 $$emit$$"j$cop,u $labl" 11462 } else { 11463 $$emit$$"jp,u done\n\t" 11464 $$emit$$"j$cop,u $labl\n\t" 11465 $$emit$$"done:" 11466 } 11467 %} 11468 ins_encode %{ 11469 Label* l = $labl$$label; 11470 if ($cop$$cmpcode == Assembler::notEqual) { 11471 __ jcc(Assembler::parity, *l, false); 11472 __ jcc(Assembler::notEqual, *l, false); 11473 } else if ($cop$$cmpcode == Assembler::equal) { 11474 Label done; 11475 __ jccb(Assembler::parity, done); 11476 __ jcc(Assembler::equal, *l, false); 11477 __ bind(done); 11478 } else { 11479 ShouldNotReachHere(); 11480 } 11481 %} 11482 ins_pipe(pipe_jcc); 11483 %} 11484 11485 // ============================================================================ 11486 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11487 // superklass array for an instance of the superklass. Set a hidden 11488 // internal cache on a hit (cache is checked with exposed code in 11489 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11490 // encoding ALSO sets flags. 11491 11492 instruct partialSubtypeCheck(rdi_RegP result, 11493 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11494 rFlagsReg cr) 11495 %{ 11496 match(Set result (PartialSubtypeCheck sub super)); 11497 effect(KILL rcx, KILL cr); 11498 11499 ins_cost(1100); // slightly larger than the next version 11500 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11501 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11502 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11503 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11504 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11505 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11506 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11507 "miss:\t" %} 11508 11509 opcode(0x1); // Force a XOR of RDI 11510 ins_encode(enc_PartialSubtypeCheck()); 11511 ins_pipe(pipe_slow); 11512 %} 11513 11514 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11515 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11516 immP0 zero, 11517 rdi_RegP result) 11518 %{ 11519 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11520 effect(KILL rcx, KILL result); 11521 11522 ins_cost(1000); 11523 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11524 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11525 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11526 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11527 "jne,s miss\t\t# Missed: flags nz\n\t" 11528 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11529 "miss:\t" %} 11530 11531 opcode(0x0); // No need to XOR RDI 11532 ins_encode(enc_PartialSubtypeCheck()); 11533 ins_pipe(pipe_slow); 11534 %} 11535 11536 // ============================================================================ 11537 // Branch Instructions -- short offset versions 11538 // 11539 // These instructions are used to replace jumps of a long offset (the default 11540 // match) with jumps of a shorter offset. These instructions are all tagged 11541 // with the ins_short_branch attribute, which causes the ADLC to suppress the 11542 // match rules in general matching. Instead, the ADLC generates a conversion 11543 // method in the MachNode which can be used to do in-place replacement of the 11544 // long variant with the shorter variant. The compiler will determine if a 11545 // branch can be taken by the is_short_branch_offset() predicate in the machine 11546 // specific code section of the file. 11547 11548 // Jump Direct - Label defines a relative address from JMP+1 11549 instruct jmpDir_short(label labl) %{ 11550 match(Goto); 11551 effect(USE labl); 11552 11553 ins_cost(300); 11554 format %{ "jmp,s $labl" %} 11555 size(2); 11556 ins_encode %{ 11557 Label* L = $labl$$label; 11558 __ jmpb(*L); 11559 %} 11560 ins_pipe(pipe_jmp); 11561 ins_short_branch(1); 11562 %} 11563 11564 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11565 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11566 match(If cop cr); 11567 effect(USE labl); 11568 11569 ins_cost(300); 11570 format %{ "j$cop,s $labl" %} 11571 size(2); 11572 ins_encode %{ 11573 Label* L = $labl$$label; 11574 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11575 %} 11576 ins_pipe(pipe_jcc); 11577 ins_short_branch(1); 11578 %} 11579 11580 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11581 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11582 match(CountedLoopEnd cop cr); 11583 effect(USE labl); 11584 11585 ins_cost(300); 11586 format %{ "j$cop,s $labl\t# loop end" %} 11587 size(2); 11588 ins_encode %{ 11589 Label* L = $labl$$label; 11590 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11591 %} 11592 ins_pipe(pipe_jcc); 11593 ins_short_branch(1); 11594 %} 11595 11596 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11597 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11598 match(CountedLoopEnd cop cmp); 11599 effect(USE labl); 11600 11601 ins_cost(300); 11602 format %{ "j$cop,us $labl\t# loop end" %} 11603 size(2); 11604 ins_encode %{ 11605 Label* L = $labl$$label; 11606 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11607 %} 11608 ins_pipe(pipe_jcc); 11609 ins_short_branch(1); 11610 %} 11611 11612 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11613 match(CountedLoopEnd cop cmp); 11614 effect(USE labl); 11615 11616 ins_cost(300); 11617 format %{ "j$cop,us $labl\t# loop end" %} 11618 size(2); 11619 ins_encode %{ 11620 Label* L = $labl$$label; 11621 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11622 %} 11623 ins_pipe(pipe_jcc); 11624 ins_short_branch(1); 11625 %} 11626 11627 // Jump Direct Conditional - using unsigned comparison 11628 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11629 match(If cop cmp); 11630 effect(USE labl); 11631 11632 ins_cost(300); 11633 format %{ "j$cop,us $labl" %} 11634 size(2); 11635 ins_encode %{ 11636 Label* L = $labl$$label; 11637 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11638 %} 11639 ins_pipe(pipe_jcc); 11640 ins_short_branch(1); 11641 %} 11642 11643 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11644 match(If cop cmp); 11645 effect(USE labl); 11646 11647 ins_cost(300); 11648 format %{ "j$cop,us $labl" %} 11649 size(2); 11650 ins_encode %{ 11651 Label* L = $labl$$label; 11652 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11653 %} 11654 ins_pipe(pipe_jcc); 11655 ins_short_branch(1); 11656 %} 11657 11658 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11659 match(If cop cmp); 11660 effect(USE labl); 11661 11662 ins_cost(300); 11663 format %{ $$template 11664 if ($cop$$cmpcode == Assembler::notEqual) { 11665 $$emit$$"jp,u,s $labl\n\t" 11666 $$emit$$"j$cop,u,s $labl" 11667 } else { 11668 $$emit$$"jp,u,s done\n\t" 11669 $$emit$$"j$cop,u,s $labl\n\t" 11670 $$emit$$"done:" 11671 } 11672 %} 11673 size(4); 11674 ins_encode %{ 11675 Label* l = $labl$$label; 11676 if ($cop$$cmpcode == Assembler::notEqual) { 11677 __ jccb(Assembler::parity, *l); 11678 __ jccb(Assembler::notEqual, *l); 11679 } else if ($cop$$cmpcode == Assembler::equal) { 11680 Label done; 11681 __ jccb(Assembler::parity, done); 11682 __ jccb(Assembler::equal, *l); 11683 __ bind(done); 11684 } else { 11685 ShouldNotReachHere(); 11686 } 11687 %} 11688 ins_pipe(pipe_jcc); 11689 ins_short_branch(1); 11690 %} 11691 11692 // ============================================================================ 11693 // inlined locking and unlocking 11694 11695 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 11696 predicate(Compile::current()->use_rtm()); 11697 match(Set cr (FastLock object box)); 11698 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 11699 ins_cost(300); 11700 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 11701 ins_encode %{ 11702 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 11703 $scr$$Register, $cx1$$Register, $cx2$$Register, 11704 _counters, _rtm_counters, _stack_rtm_counters, 11705 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11706 true, ra_->C->profile_rtm()); 11707 %} 11708 ins_pipe(pipe_slow); 11709 %} 11710 11711 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 11712 predicate(!Compile::current()->use_rtm()); 11713 match(Set cr (FastLock object box)); 11714 effect(TEMP tmp, TEMP scr, USE_KILL box); 11715 ins_cost(300); 11716 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 11717 ins_encode %{ 11718 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 11719 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 11720 %} 11721 ins_pipe(pipe_slow); 11722 %} 11723 11724 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 11725 match(Set cr (FastUnlock object box)); 11726 effect(TEMP tmp, USE_KILL box); 11727 ins_cost(300); 11728 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 11729 ins_encode %{ 11730 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 11731 %} 11732 ins_pipe(pipe_slow); 11733 %} 11734 11735 11736 // ============================================================================ 11737 // Safepoint Instructions 11738 instruct safePoint_poll(rFlagsReg cr) 11739 %{ 11740 predicate(!Assembler::is_polling_page_far()); 11741 match(SafePoint); 11742 effect(KILL cr); 11743 11744 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 11745 "# Safepoint: poll for GC" %} 11746 ins_cost(125); 11747 ins_encode %{ 11748 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 11749 __ testl(rax, addr); 11750 %} 11751 ins_pipe(ialu_reg_mem); 11752 %} 11753 11754 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 11755 %{ 11756 predicate(Assembler::is_polling_page_far()); 11757 match(SafePoint poll); 11758 effect(KILL cr, USE poll); 11759 11760 format %{ "testl rax, [$poll]\t" 11761 "# Safepoint: poll for GC" %} 11762 ins_cost(125); 11763 ins_encode %{ 11764 __ relocate(relocInfo::poll_type); 11765 __ testl(rax, Address($poll$$Register, 0)); 11766 %} 11767 ins_pipe(ialu_reg_mem); 11768 %} 11769 11770 // ============================================================================ 11771 // Procedure Call/Return Instructions 11772 // Call Java Static Instruction 11773 // Note: If this code changes, the corresponding ret_addr_offset() and 11774 // compute_padding() functions will have to be adjusted. 11775 instruct CallStaticJavaDirect(method meth) %{ 11776 match(CallStaticJava); 11777 effect(USE meth); 11778 11779 ins_cost(300); 11780 format %{ "call,static " %} 11781 opcode(0xE8); /* E8 cd */ 11782 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 11783 ins_pipe(pipe_slow); 11784 ins_alignment(4); 11785 %} 11786 11787 // Call Java Dynamic Instruction 11788 // Note: If this code changes, the corresponding ret_addr_offset() and 11789 // compute_padding() functions will have to be adjusted. 11790 instruct CallDynamicJavaDirect(method meth) 11791 %{ 11792 match(CallDynamicJava); 11793 effect(USE meth); 11794 11795 ins_cost(300); 11796 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11797 "call,dynamic " %} 11798 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 11799 ins_pipe(pipe_slow); 11800 ins_alignment(4); 11801 %} 11802 11803 // Call Runtime Instruction 11804 instruct CallRuntimeDirect(method meth) 11805 %{ 11806 match(CallRuntime); 11807 effect(USE meth); 11808 11809 ins_cost(300); 11810 format %{ "call,runtime " %} 11811 ins_encode(clear_avx, Java_To_Runtime(meth)); 11812 ins_pipe(pipe_slow); 11813 %} 11814 11815 // Call runtime without safepoint 11816 instruct CallLeafDirect(method meth) 11817 %{ 11818 match(CallLeaf); 11819 effect(USE meth); 11820 11821 ins_cost(300); 11822 format %{ "call_leaf,runtime " %} 11823 ins_encode(clear_avx, Java_To_Runtime(meth)); 11824 ins_pipe(pipe_slow); 11825 %} 11826 11827 // Call runtime without safepoint 11828 instruct CallLeafNoFPDirect(method meth) 11829 %{ 11830 match(CallLeafNoFP); 11831 effect(USE meth); 11832 11833 ins_cost(300); 11834 format %{ "call_leaf_nofp,runtime " %} 11835 ins_encode(Java_To_Runtime(meth)); 11836 ins_pipe(pipe_slow); 11837 %} 11838 11839 // Return Instruction 11840 // Remove the return address & jump to it. 11841 // Notice: We always emit a nop after a ret to make sure there is room 11842 // for safepoint patching 11843 instruct Ret() 11844 %{ 11845 match(Return); 11846 11847 format %{ "ret" %} 11848 opcode(0xC3); 11849 ins_encode(OpcP); 11850 ins_pipe(pipe_jmp); 11851 %} 11852 11853 // Tail Call; Jump from runtime stub to Java code. 11854 // Also known as an 'interprocedural jump'. 11855 // Target of jump will eventually return to caller. 11856 // TailJump below removes the return address. 11857 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 11858 %{ 11859 match(TailCall jump_target method_oop); 11860 11861 ins_cost(300); 11862 format %{ "jmp $jump_target\t# rbx holds method oop" %} 11863 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11864 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11865 ins_pipe(pipe_jmp); 11866 %} 11867 11868 // Tail Jump; remove the return address; jump to target. 11869 // TailCall above leaves the return address around. 11870 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 11871 %{ 11872 match(TailJump jump_target ex_oop); 11873 11874 ins_cost(300); 11875 format %{ "popq rdx\t# pop return address\n\t" 11876 "jmp $jump_target" %} 11877 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11878 ins_encode(Opcode(0x5a), // popq rdx 11879 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11880 ins_pipe(pipe_jmp); 11881 %} 11882 11883 // Create exception oop: created by stack-crawling runtime code. 11884 // Created exception is now available to this handler, and is setup 11885 // just prior to jumping to this handler. No code emitted. 11886 instruct CreateException(rax_RegP ex_oop) 11887 %{ 11888 match(Set ex_oop (CreateEx)); 11889 11890 size(0); 11891 // use the following format syntax 11892 format %{ "# exception oop is in rax; no code emitted" %} 11893 ins_encode(); 11894 ins_pipe(empty); 11895 %} 11896 11897 // Rethrow exception: 11898 // The exception oop will come in the first argument position. 11899 // Then JUMP (not call) to the rethrow stub code. 11900 instruct RethrowException() 11901 %{ 11902 match(Rethrow); 11903 11904 // use the following format syntax 11905 format %{ "jmp rethrow_stub" %} 11906 ins_encode(enc_rethrow); 11907 ins_pipe(pipe_jmp); 11908 %} 11909 11910 11911 // ============================================================================ 11912 // This name is KNOWN by the ADLC and cannot be changed. 11913 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 11914 // for this guy. 11915 instruct tlsLoadP(r15_RegP dst) %{ 11916 match(Set dst (ThreadLocal)); 11917 effect(DEF dst); 11918 11919 size(0); 11920 format %{ "# TLS is in R15" %} 11921 ins_encode( /*empty encoding*/ ); 11922 ins_pipe(ialu_reg_reg); 11923 %} 11924 11925 11926 //----------PEEPHOLE RULES----------------------------------------------------- 11927 // These must follow all instruction definitions as they use the names 11928 // defined in the instructions definitions. 11929 // 11930 // peepmatch ( root_instr_name [preceding_instruction]* ); 11931 // 11932 // peepconstraint %{ 11933 // (instruction_number.operand_name relational_op instruction_number.operand_name 11934 // [, ...] ); 11935 // // instruction numbers are zero-based using left to right order in peepmatch 11936 // 11937 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 11938 // // provide an instruction_number.operand_name for each operand that appears 11939 // // in the replacement instruction's match rule 11940 // 11941 // ---------VM FLAGS--------------------------------------------------------- 11942 // 11943 // All peephole optimizations can be turned off using -XX:-OptoPeephole 11944 // 11945 // Each peephole rule is given an identifying number starting with zero and 11946 // increasing by one in the order seen by the parser. An individual peephole 11947 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 11948 // on the command-line. 11949 // 11950 // ---------CURRENT LIMITATIONS---------------------------------------------- 11951 // 11952 // Only match adjacent instructions in same basic block 11953 // Only equality constraints 11954 // Only constraints between operands, not (0.dest_reg == RAX_enc) 11955 // Only one replacement instruction 11956 // 11957 // ---------EXAMPLE---------------------------------------------------------- 11958 // 11959 // // pertinent parts of existing instructions in architecture description 11960 // instruct movI(rRegI dst, rRegI src) 11961 // %{ 11962 // match(Set dst (CopyI src)); 11963 // %} 11964 // 11965 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 11966 // %{ 11967 // match(Set dst (AddI dst src)); 11968 // effect(KILL cr); 11969 // %} 11970 // 11971 // // Change (inc mov) to lea 11972 // peephole %{ 11973 // // increment preceeded by register-register move 11974 // peepmatch ( incI_rReg movI ); 11975 // // require that the destination register of the increment 11976 // // match the destination register of the move 11977 // peepconstraint ( 0.dst == 1.dst ); 11978 // // construct a replacement instruction that sets 11979 // // the destination to ( move's source register + one ) 11980 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 11981 // %} 11982 // 11983 11984 // Implementation no longer uses movX instructions since 11985 // machine-independent system no longer uses CopyX nodes. 11986 // 11987 // peephole 11988 // %{ 11989 // peepmatch (incI_rReg movI); 11990 // peepconstraint (0.dst == 1.dst); 11991 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11992 // %} 11993 11994 // peephole 11995 // %{ 11996 // peepmatch (decI_rReg movI); 11997 // peepconstraint (0.dst == 1.dst); 11998 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11999 // %} 12000 12001 // peephole 12002 // %{ 12003 // peepmatch (addI_rReg_imm movI); 12004 // peepconstraint (0.dst == 1.dst); 12005 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12006 // %} 12007 12008 // peephole 12009 // %{ 12010 // peepmatch (incL_rReg movL); 12011 // peepconstraint (0.dst == 1.dst); 12012 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12013 // %} 12014 12015 // peephole 12016 // %{ 12017 // peepmatch (decL_rReg movL); 12018 // peepconstraint (0.dst == 1.dst); 12019 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12020 // %} 12021 12022 // peephole 12023 // %{ 12024 // peepmatch (addL_rReg_imm movL); 12025 // peepconstraint (0.dst == 1.dst); 12026 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12027 // %} 12028 12029 // peephole 12030 // %{ 12031 // peepmatch (addP_rReg_imm movP); 12032 // peepconstraint (0.dst == 1.dst); 12033 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12034 // %} 12035 12036 // // Change load of spilled value to only a spill 12037 // instruct storeI(memory mem, rRegI src) 12038 // %{ 12039 // match(Set mem (StoreI mem src)); 12040 // %} 12041 // 12042 // instruct loadI(rRegI dst, memory mem) 12043 // %{ 12044 // match(Set dst (LoadI mem)); 12045 // %} 12046 // 12047 12048 peephole 12049 %{ 12050 peepmatch (loadI storeI); 12051 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12052 peepreplace (storeI(1.mem 1.mem 1.src)); 12053 %} 12054 12055 peephole 12056 %{ 12057 peepmatch (loadL storeL); 12058 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12059 peepreplace (storeL(1.mem 1.mem 1.src)); 12060 %} 12061 12062 //----------SMARTSPILL RULES--------------------------------------------------- 12063 // These must follow all instruction definitions as they use the names 12064 // defined in the instructions definitions.