1 // 2 // Copyright (c) 2003, 2017, 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 #if INCLUDE_ZGC 531 #include "gc/z/zBarrierSetAssembler.hpp" 532 #endif 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 bool generate_vzeroupper(Compile* C) { 545 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 546 } 547 548 static int clear_avx_size() { 549 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 550 } 551 552 // !!!!! Special hack to get all types of calls to specify the byte offset 553 // from the start of the call to the point where the return address 554 // will point. 555 int MachCallStaticJavaNode::ret_addr_offset() 556 { 557 int offset = 5; // 5 bytes from start of call to where return address points 558 offset += clear_avx_size(); 559 return offset; 560 } 561 562 int MachCallDynamicJavaNode::ret_addr_offset() 563 { 564 int offset = 15; // 15 bytes from start of call to where return address points 565 offset += clear_avx_size(); 566 return offset; 567 } 568 569 int MachCallRuntimeNode::ret_addr_offset() { 570 int offset = 13; // movq r10,#addr; callq (r10) 571 offset += clear_avx_size(); 572 return offset; 573 } 574 575 // Indicate if the safepoint node needs the polling page as an input, 576 // it does if the polling page is more than disp32 away. 577 bool SafePointNode::needs_polling_address_input() 578 { 579 return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far(); 580 } 581 582 // 583 // Compute padding required for nodes which need alignment 584 // 585 586 // The address of the call instruction needs to be 4-byte aligned to 587 // ensure that it does not span a cache line so that it can be patched. 588 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 589 { 590 current_offset += clear_avx_size(); // skip vzeroupper 591 current_offset += 1; // skip call opcode byte 592 return align_up(current_offset, alignment_required()) - current_offset; 593 } 594 595 // The address of the call instruction needs to be 4-byte aligned to 596 // ensure that it does not span a cache line so that it can be patched. 597 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 598 { 599 current_offset += clear_avx_size(); // skip vzeroupper 600 current_offset += 11; // skip movq instruction + call opcode byte 601 return align_up(current_offset, alignment_required()) - current_offset; 602 } 603 604 // EMIT_RM() 605 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 606 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 607 cbuf.insts()->emit_int8(c); 608 } 609 610 // EMIT_CC() 611 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 612 unsigned char c = (unsigned char) (f1 | f2); 613 cbuf.insts()->emit_int8(c); 614 } 615 616 // EMIT_OPCODE() 617 void emit_opcode(CodeBuffer &cbuf, int code) { 618 cbuf.insts()->emit_int8((unsigned char) code); 619 } 620 621 // EMIT_OPCODE() w/ relocation information 622 void emit_opcode(CodeBuffer &cbuf, 623 int code, relocInfo::relocType reloc, int offset, int format) 624 { 625 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 626 emit_opcode(cbuf, code); 627 } 628 629 // EMIT_D8() 630 void emit_d8(CodeBuffer &cbuf, int d8) { 631 cbuf.insts()->emit_int8((unsigned char) d8); 632 } 633 634 // EMIT_D16() 635 void emit_d16(CodeBuffer &cbuf, int d16) { 636 cbuf.insts()->emit_int16(d16); 637 } 638 639 // EMIT_D32() 640 void emit_d32(CodeBuffer &cbuf, int d32) { 641 cbuf.insts()->emit_int32(d32); 642 } 643 644 // EMIT_D64() 645 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 646 cbuf.insts()->emit_int64(d64); 647 } 648 649 // emit 32 bit value and construct relocation entry from relocInfo::relocType 650 void emit_d32_reloc(CodeBuffer& cbuf, 651 int d32, 652 relocInfo::relocType reloc, 653 int format) 654 { 655 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 656 cbuf.relocate(cbuf.insts_mark(), reloc, format); 657 cbuf.insts()->emit_int32(d32); 658 } 659 660 // emit 32 bit value and construct relocation entry from RelocationHolder 661 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 662 #ifdef ASSERT 663 if (rspec.reloc()->type() == relocInfo::oop_type && 664 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 665 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 666 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop((intptr_t)d32))), "cannot embed scavengable oops in code"); 667 } 668 #endif 669 cbuf.relocate(cbuf.insts_mark(), rspec, format); 670 cbuf.insts()->emit_int32(d32); 671 } 672 673 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 674 address next_ip = cbuf.insts_end() + 4; 675 emit_d32_reloc(cbuf, (int) (addr - next_ip), 676 external_word_Relocation::spec(addr), 677 RELOC_DISP32); 678 } 679 680 681 // emit 64 bit value and construct relocation entry from relocInfo::relocType 682 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 683 cbuf.relocate(cbuf.insts_mark(), reloc, format); 684 cbuf.insts()->emit_int64(d64); 685 } 686 687 // emit 64 bit value and construct relocation entry from RelocationHolder 688 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 689 #ifdef ASSERT 690 if (rspec.reloc()->type() == relocInfo::oop_type && 691 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 692 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 693 assert(oopDesc::is_oop(cast_to_oop(d64)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop(d64))), 694 "cannot embed scavengable oops in code"); 695 } 696 #endif 697 cbuf.relocate(cbuf.insts_mark(), rspec, format); 698 cbuf.insts()->emit_int64(d64); 699 } 700 701 // Access stack slot for load or store 702 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 703 { 704 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 705 if (-0x80 <= disp && disp < 0x80) { 706 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 707 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 708 emit_d8(cbuf, disp); // Displacement // R/M byte 709 } else { 710 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 711 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 712 emit_d32(cbuf, disp); // Displacement // R/M byte 713 } 714 } 715 716 // rRegI ereg, memory mem) %{ // emit_reg_mem 717 void encode_RegMem(CodeBuffer &cbuf, 718 int reg, 719 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 720 { 721 assert(disp_reloc == relocInfo::none, "cannot have disp"); 722 int regenc = reg & 7; 723 int baseenc = base & 7; 724 int indexenc = index & 7; 725 726 // There is no index & no scale, use form without SIB byte 727 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 728 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 729 if (disp == 0 && base != RBP_enc && base != R13_enc) { 730 emit_rm(cbuf, 0x0, regenc, baseenc); // * 731 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 732 // If 8-bit displacement, mode 0x1 733 emit_rm(cbuf, 0x1, regenc, baseenc); // * 734 emit_d8(cbuf, disp); 735 } else { 736 // If 32-bit displacement 737 if (base == -1) { // Special flag for absolute address 738 emit_rm(cbuf, 0x0, regenc, 0x5); // * 739 if (disp_reloc != relocInfo::none) { 740 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 741 } else { 742 emit_d32(cbuf, disp); 743 } 744 } else { 745 // Normal base + offset 746 emit_rm(cbuf, 0x2, regenc, baseenc); // * 747 if (disp_reloc != relocInfo::none) { 748 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 749 } else { 750 emit_d32(cbuf, disp); 751 } 752 } 753 } 754 } else { 755 // Else, encode with the SIB byte 756 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 757 if (disp == 0 && base != RBP_enc && base != R13_enc) { 758 // If no displacement 759 emit_rm(cbuf, 0x0, regenc, 0x4); // * 760 emit_rm(cbuf, scale, indexenc, baseenc); 761 } else { 762 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 763 // If 8-bit displacement, mode 0x1 764 emit_rm(cbuf, 0x1, regenc, 0x4); // * 765 emit_rm(cbuf, scale, indexenc, baseenc); 766 emit_d8(cbuf, disp); 767 } else { 768 // If 32-bit displacement 769 if (base == 0x04 ) { 770 emit_rm(cbuf, 0x2, regenc, 0x4); 771 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 772 } else { 773 emit_rm(cbuf, 0x2, regenc, 0x4); 774 emit_rm(cbuf, scale, indexenc, baseenc); // * 775 } 776 if (disp_reloc != relocInfo::none) { 777 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 778 } else { 779 emit_d32(cbuf, disp); 780 } 781 } 782 } 783 } 784 } 785 786 // This could be in MacroAssembler but it's fairly C2 specific 787 void emit_cmpfp_fixup(MacroAssembler& _masm) { 788 Label exit; 789 __ jccb(Assembler::noParity, exit); 790 __ pushf(); 791 // 792 // comiss/ucomiss instructions set ZF,PF,CF flags and 793 // zero OF,AF,SF for NaN values. 794 // Fixup flags by zeroing ZF,PF so that compare of NaN 795 // values returns 'less than' result (CF is set). 796 // Leave the rest of flags unchanged. 797 // 798 // 7 6 5 4 3 2 1 0 799 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 800 // 0 0 1 0 1 0 1 1 (0x2B) 801 // 802 __ andq(Address(rsp, 0), 0xffffff2b); 803 __ popf(); 804 __ bind(exit); 805 } 806 807 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 808 Label done; 809 __ movl(dst, -1); 810 __ jcc(Assembler::parity, done); 811 __ jcc(Assembler::below, done); 812 __ setb(Assembler::notEqual, dst); 813 __ movzbl(dst, dst); 814 __ bind(done); 815 } 816 817 818 //============================================================================= 819 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 820 821 int Compile::ConstantTable::calculate_table_base_offset() const { 822 return 0; // absolute addressing, no offset 823 } 824 825 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 826 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 827 ShouldNotReachHere(); 828 } 829 830 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 831 // Empty encoding 832 } 833 834 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 835 return 0; 836 } 837 838 #ifndef PRODUCT 839 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 840 st->print("# MachConstantBaseNode (empty encoding)"); 841 } 842 #endif 843 844 845 //============================================================================= 846 #ifndef PRODUCT 847 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 848 Compile* C = ra_->C; 849 850 int framesize = C->frame_size_in_bytes(); 851 int bangsize = C->bang_size_in_bytes(); 852 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 853 // Remove wordSize for return addr which is already pushed. 854 framesize -= wordSize; 855 856 if (C->need_stack_bang(bangsize)) { 857 framesize -= wordSize; 858 st->print("# stack bang (%d bytes)", bangsize); 859 st->print("\n\t"); 860 st->print("pushq rbp\t# Save rbp"); 861 if (PreserveFramePointer) { 862 st->print("\n\t"); 863 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 864 } 865 if (framesize) { 866 st->print("\n\t"); 867 st->print("subq rsp, #%d\t# Create frame",framesize); 868 } 869 } else { 870 st->print("subq rsp, #%d\t# Create frame",framesize); 871 st->print("\n\t"); 872 framesize -= wordSize; 873 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 874 if (PreserveFramePointer) { 875 st->print("\n\t"); 876 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 877 if (framesize > 0) { 878 st->print("\n\t"); 879 st->print("addq rbp, #%d", framesize); 880 } 881 } 882 } 883 884 if (VerifyStackAtCalls) { 885 st->print("\n\t"); 886 framesize -= wordSize; 887 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 888 #ifdef ASSERT 889 st->print("\n\t"); 890 st->print("# stack alignment check"); 891 #endif 892 } 893 st->cr(); 894 } 895 #endif 896 897 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 898 Compile* C = ra_->C; 899 MacroAssembler _masm(&cbuf); 900 901 int framesize = C->frame_size_in_bytes(); 902 int bangsize = C->bang_size_in_bytes(); 903 904 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); 905 906 C->set_frame_complete(cbuf.insts_size()); 907 908 if (C->has_mach_constant_base_node()) { 909 // NOTE: We set the table base offset here because users might be 910 // emitted before MachConstantBaseNode. 911 Compile::ConstantTable& constant_table = C->constant_table(); 912 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 913 } 914 } 915 916 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 917 { 918 return MachNode::size(ra_); // too many variables; just compute it 919 // the hard way 920 } 921 922 int MachPrologNode::reloc() const 923 { 924 return 0; // a large enough number 925 } 926 927 //============================================================================= 928 #ifndef PRODUCT 929 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 930 { 931 Compile* C = ra_->C; 932 if (generate_vzeroupper(C)) { 933 st->print("vzeroupper"); 934 st->cr(); st->print("\t"); 935 } 936 937 int framesize = C->frame_size_in_bytes(); 938 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 939 // Remove word for return adr already pushed 940 // and RBP 941 framesize -= 2*wordSize; 942 943 if (framesize) { 944 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 945 st->print("\t"); 946 } 947 948 st->print_cr("popq rbp"); 949 if (do_polling() && C->is_method_compilation()) { 950 st->print("\t"); 951 if (SafepointMechanism::uses_thread_local_poll()) { 952 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 953 "testl rax, [rscratch1]\t" 954 "# Safepoint: poll for GC"); 955 } else if (Assembler::is_polling_page_far()) { 956 st->print_cr("movq rscratch1, #polling_page_address\n\t" 957 "testl rax, [rscratch1]\t" 958 "# Safepoint: poll for GC"); 959 } else { 960 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 961 "# Safepoint: poll for GC"); 962 } 963 } 964 } 965 #endif 966 967 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 968 { 969 Compile* C = ra_->C; 970 MacroAssembler _masm(&cbuf); 971 972 if (generate_vzeroupper(C)) { 973 // Clear upper bits of YMM registers when current compiled code uses 974 // wide vectors to avoid AVX <-> SSE transition penalty during call. 975 __ vzeroupper(); 976 } 977 978 int framesize = C->frame_size_in_bytes(); 979 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 980 // Remove word for return adr already pushed 981 // and RBP 982 framesize -= 2*wordSize; 983 984 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 985 986 if (framesize) { 987 emit_opcode(cbuf, Assembler::REX_W); 988 if (framesize < 0x80) { 989 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 990 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 991 emit_d8(cbuf, framesize); 992 } else { 993 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 994 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 995 emit_d32(cbuf, framesize); 996 } 997 } 998 999 // popq rbp 1000 emit_opcode(cbuf, 0x58 | RBP_enc); 1001 1002 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1003 __ reserved_stack_check(); 1004 } 1005 1006 if (do_polling() && C->is_method_compilation()) { 1007 MacroAssembler _masm(&cbuf); 1008 if (SafepointMechanism::uses_thread_local_poll()) { 1009 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 1010 __ relocate(relocInfo::poll_return_type); 1011 __ testl(rax, Address(rscratch1, 0)); 1012 } else { 1013 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1014 if (Assembler::is_polling_page_far()) { 1015 __ lea(rscratch1, polling_page); 1016 __ relocate(relocInfo::poll_return_type); 1017 __ testl(rax, Address(rscratch1, 0)); 1018 } else { 1019 __ testl(rax, polling_page); 1020 } 1021 } 1022 } 1023 } 1024 1025 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1026 { 1027 return MachNode::size(ra_); // too many variables; just compute it 1028 // the hard way 1029 } 1030 1031 int MachEpilogNode::reloc() const 1032 { 1033 return 2; // a large enough number 1034 } 1035 1036 const Pipeline* MachEpilogNode::pipeline() const 1037 { 1038 return MachNode::pipeline_class(); 1039 } 1040 1041 int MachEpilogNode::safepoint_offset() const 1042 { 1043 return 0; 1044 } 1045 1046 //============================================================================= 1047 1048 enum RC { 1049 rc_bad, 1050 rc_int, 1051 rc_float, 1052 rc_stack 1053 }; 1054 1055 static enum RC rc_class(OptoReg::Name reg) 1056 { 1057 if( !OptoReg::is_valid(reg) ) return rc_bad; 1058 1059 if (OptoReg::is_stack(reg)) return rc_stack; 1060 1061 VMReg r = OptoReg::as_VMReg(reg); 1062 1063 if (r->is_Register()) return rc_int; 1064 1065 assert(r->is_XMMRegister(), "must be"); 1066 return rc_float; 1067 } 1068 1069 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1070 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1071 int src_hi, int dst_hi, uint ireg, outputStream* st); 1072 1073 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1074 int stack_offset, int reg, uint ireg, outputStream* st); 1075 1076 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1077 int dst_offset, uint ireg, outputStream* st) { 1078 if (cbuf) { 1079 MacroAssembler _masm(cbuf); 1080 switch (ireg) { 1081 case Op_VecS: 1082 __ movq(Address(rsp, -8), rax); 1083 __ movl(rax, Address(rsp, src_offset)); 1084 __ movl(Address(rsp, dst_offset), rax); 1085 __ movq(rax, Address(rsp, -8)); 1086 break; 1087 case Op_VecD: 1088 __ pushq(Address(rsp, src_offset)); 1089 __ popq (Address(rsp, dst_offset)); 1090 break; 1091 case Op_VecX: 1092 __ pushq(Address(rsp, src_offset)); 1093 __ popq (Address(rsp, dst_offset)); 1094 __ pushq(Address(rsp, src_offset+8)); 1095 __ popq (Address(rsp, dst_offset+8)); 1096 break; 1097 case Op_VecY: 1098 __ vmovdqu(Address(rsp, -32), xmm0); 1099 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1100 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1101 __ vmovdqu(xmm0, Address(rsp, -32)); 1102 break; 1103 case Op_VecZ: 1104 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1105 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1106 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1107 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1108 break; 1109 default: 1110 ShouldNotReachHere(); 1111 } 1112 #ifndef PRODUCT 1113 } else { 1114 switch (ireg) { 1115 case Op_VecS: 1116 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1117 "movl rax, [rsp + #%d]\n\t" 1118 "movl [rsp + #%d], rax\n\t" 1119 "movq rax, [rsp - #8]", 1120 src_offset, dst_offset); 1121 break; 1122 case Op_VecD: 1123 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1124 "popq [rsp + #%d]", 1125 src_offset, dst_offset); 1126 break; 1127 case Op_VecX: 1128 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1129 "popq [rsp + #%d]\n\t" 1130 "pushq [rsp + #%d]\n\t" 1131 "popq [rsp + #%d]", 1132 src_offset, dst_offset, src_offset+8, dst_offset+8); 1133 break; 1134 case Op_VecY: 1135 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1136 "vmovdqu xmm0, [rsp + #%d]\n\t" 1137 "vmovdqu [rsp + #%d], xmm0\n\t" 1138 "vmovdqu xmm0, [rsp - #32]", 1139 src_offset, dst_offset); 1140 break; 1141 case Op_VecZ: 1142 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1143 "vmovdqu xmm0, [rsp + #%d]\n\t" 1144 "vmovdqu [rsp + #%d], xmm0\n\t" 1145 "vmovdqu xmm0, [rsp - #64]", 1146 src_offset, dst_offset); 1147 break; 1148 default: 1149 ShouldNotReachHere(); 1150 } 1151 #endif 1152 } 1153 } 1154 1155 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1156 PhaseRegAlloc* ra_, 1157 bool do_size, 1158 outputStream* st) const { 1159 assert(cbuf != NULL || st != NULL, "sanity"); 1160 // Get registers to move 1161 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1162 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1163 OptoReg::Name dst_second = ra_->get_reg_second(this); 1164 OptoReg::Name dst_first = ra_->get_reg_first(this); 1165 1166 enum RC src_second_rc = rc_class(src_second); 1167 enum RC src_first_rc = rc_class(src_first); 1168 enum RC dst_second_rc = rc_class(dst_second); 1169 enum RC dst_first_rc = rc_class(dst_first); 1170 1171 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1172 "must move at least 1 register" ); 1173 1174 if (src_first == dst_first && src_second == dst_second) { 1175 // Self copy, no move 1176 return 0; 1177 } 1178 if (bottom_type()->isa_vect() != NULL) { 1179 uint ireg = ideal_reg(); 1180 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1181 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1182 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1183 // mem -> mem 1184 int src_offset = ra_->reg2offset(src_first); 1185 int dst_offset = ra_->reg2offset(dst_first); 1186 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1187 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1188 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1189 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1190 int stack_offset = ra_->reg2offset(dst_first); 1191 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1192 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1193 int stack_offset = ra_->reg2offset(src_first); 1194 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1195 } else { 1196 ShouldNotReachHere(); 1197 } 1198 return 0; 1199 } 1200 if (src_first_rc == rc_stack) { 1201 // mem -> 1202 if (dst_first_rc == rc_stack) { 1203 // mem -> mem 1204 assert(src_second != dst_first, "overlap"); 1205 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1206 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1207 // 64-bit 1208 int src_offset = ra_->reg2offset(src_first); 1209 int dst_offset = ra_->reg2offset(dst_first); 1210 if (cbuf) { 1211 MacroAssembler _masm(cbuf); 1212 __ pushq(Address(rsp, src_offset)); 1213 __ popq (Address(rsp, dst_offset)); 1214 #ifndef PRODUCT 1215 } else { 1216 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1217 "popq [rsp + #%d]", 1218 src_offset, dst_offset); 1219 #endif 1220 } 1221 } else { 1222 // 32-bit 1223 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1224 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1225 // No pushl/popl, so: 1226 int src_offset = ra_->reg2offset(src_first); 1227 int dst_offset = ra_->reg2offset(dst_first); 1228 if (cbuf) { 1229 MacroAssembler _masm(cbuf); 1230 __ movq(Address(rsp, -8), rax); 1231 __ movl(rax, Address(rsp, src_offset)); 1232 __ movl(Address(rsp, dst_offset), rax); 1233 __ movq(rax, Address(rsp, -8)); 1234 #ifndef PRODUCT 1235 } else { 1236 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1237 "movl rax, [rsp + #%d]\n\t" 1238 "movl [rsp + #%d], rax\n\t" 1239 "movq rax, [rsp - #8]", 1240 src_offset, dst_offset); 1241 #endif 1242 } 1243 } 1244 return 0; 1245 } else if (dst_first_rc == rc_int) { 1246 // mem -> gpr 1247 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1248 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1249 // 64-bit 1250 int offset = ra_->reg2offset(src_first); 1251 if (cbuf) { 1252 MacroAssembler _masm(cbuf); 1253 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1254 #ifndef PRODUCT 1255 } else { 1256 st->print("movq %s, [rsp + #%d]\t# spill", 1257 Matcher::regName[dst_first], 1258 offset); 1259 #endif 1260 } 1261 } else { 1262 // 32-bit 1263 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1264 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1265 int offset = ra_->reg2offset(src_first); 1266 if (cbuf) { 1267 MacroAssembler _masm(cbuf); 1268 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1269 #ifndef PRODUCT 1270 } else { 1271 st->print("movl %s, [rsp + #%d]\t# spill", 1272 Matcher::regName[dst_first], 1273 offset); 1274 #endif 1275 } 1276 } 1277 return 0; 1278 } else if (dst_first_rc == rc_float) { 1279 // mem-> xmm 1280 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1281 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1282 // 64-bit 1283 int offset = ra_->reg2offset(src_first); 1284 if (cbuf) { 1285 MacroAssembler _masm(cbuf); 1286 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1287 #ifndef PRODUCT 1288 } else { 1289 st->print("%s %s, [rsp + #%d]\t# spill", 1290 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1291 Matcher::regName[dst_first], 1292 offset); 1293 #endif 1294 } 1295 } else { 1296 // 32-bit 1297 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1298 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1299 int offset = ra_->reg2offset(src_first); 1300 if (cbuf) { 1301 MacroAssembler _masm(cbuf); 1302 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1303 #ifndef PRODUCT 1304 } else { 1305 st->print("movss %s, [rsp + #%d]\t# spill", 1306 Matcher::regName[dst_first], 1307 offset); 1308 #endif 1309 } 1310 } 1311 return 0; 1312 } 1313 } else if (src_first_rc == rc_int) { 1314 // gpr -> 1315 if (dst_first_rc == rc_stack) { 1316 // gpr -> mem 1317 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1318 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1319 // 64-bit 1320 int offset = ra_->reg2offset(dst_first); 1321 if (cbuf) { 1322 MacroAssembler _masm(cbuf); 1323 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1324 #ifndef PRODUCT 1325 } else { 1326 st->print("movq [rsp + #%d], %s\t# spill", 1327 offset, 1328 Matcher::regName[src_first]); 1329 #endif 1330 } 1331 } else { 1332 // 32-bit 1333 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1334 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1335 int offset = ra_->reg2offset(dst_first); 1336 if (cbuf) { 1337 MacroAssembler _masm(cbuf); 1338 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1339 #ifndef PRODUCT 1340 } else { 1341 st->print("movl [rsp + #%d], %s\t# spill", 1342 offset, 1343 Matcher::regName[src_first]); 1344 #endif 1345 } 1346 } 1347 return 0; 1348 } else if (dst_first_rc == rc_int) { 1349 // gpr -> gpr 1350 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1351 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1352 // 64-bit 1353 if (cbuf) { 1354 MacroAssembler _masm(cbuf); 1355 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1356 as_Register(Matcher::_regEncode[src_first])); 1357 #ifndef PRODUCT 1358 } else { 1359 st->print("movq %s, %s\t# spill", 1360 Matcher::regName[dst_first], 1361 Matcher::regName[src_first]); 1362 #endif 1363 } 1364 return 0; 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 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1372 as_Register(Matcher::_regEncode[src_first])); 1373 #ifndef PRODUCT 1374 } else { 1375 st->print("movl %s, %s\t# spill", 1376 Matcher::regName[dst_first], 1377 Matcher::regName[src_first]); 1378 #endif 1379 } 1380 return 0; 1381 } 1382 } else if (dst_first_rc == rc_float) { 1383 // gpr -> xmm 1384 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1385 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1386 // 64-bit 1387 if (cbuf) { 1388 MacroAssembler _masm(cbuf); 1389 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1390 #ifndef PRODUCT 1391 } else { 1392 st->print("movdq %s, %s\t# spill", 1393 Matcher::regName[dst_first], 1394 Matcher::regName[src_first]); 1395 #endif 1396 } 1397 } else { 1398 // 32-bit 1399 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1400 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1401 if (cbuf) { 1402 MacroAssembler _masm(cbuf); 1403 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1404 #ifndef PRODUCT 1405 } else { 1406 st->print("movdl %s, %s\t# spill", 1407 Matcher::regName[dst_first], 1408 Matcher::regName[src_first]); 1409 #endif 1410 } 1411 } 1412 return 0; 1413 } 1414 } else if (src_first_rc == rc_float) { 1415 // xmm -> 1416 if (dst_first_rc == rc_stack) { 1417 // xmm -> mem 1418 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1419 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1420 // 64-bit 1421 int offset = ra_->reg2offset(dst_first); 1422 if (cbuf) { 1423 MacroAssembler _masm(cbuf); 1424 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1425 #ifndef PRODUCT 1426 } else { 1427 st->print("movsd [rsp + #%d], %s\t# spill", 1428 offset, 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 int offset = ra_->reg2offset(dst_first); 1437 if (cbuf) { 1438 MacroAssembler _masm(cbuf); 1439 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1440 #ifndef PRODUCT 1441 } else { 1442 st->print("movss [rsp + #%d], %s\t# spill", 1443 offset, 1444 Matcher::regName[src_first]); 1445 #endif 1446 } 1447 } 1448 return 0; 1449 } else if (dst_first_rc == rc_int) { 1450 // xmm -> gpr 1451 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1452 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1453 // 64-bit 1454 if (cbuf) { 1455 MacroAssembler _masm(cbuf); 1456 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1457 #ifndef PRODUCT 1458 } else { 1459 st->print("movdq %s, %s\t# spill", 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 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1471 #ifndef PRODUCT 1472 } else { 1473 st->print("movdl %s, %s\t# spill", 1474 Matcher::regName[dst_first], 1475 Matcher::regName[src_first]); 1476 #endif 1477 } 1478 } 1479 return 0; 1480 } else if (dst_first_rc == rc_float) { 1481 // xmm -> xmm 1482 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1483 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1484 // 64-bit 1485 if (cbuf) { 1486 MacroAssembler _masm(cbuf); 1487 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1488 #ifndef PRODUCT 1489 } else { 1490 st->print("%s %s, %s\t# spill", 1491 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1492 Matcher::regName[dst_first], 1493 Matcher::regName[src_first]); 1494 #endif 1495 } 1496 } else { 1497 // 32-bit 1498 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1499 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1500 if (cbuf) { 1501 MacroAssembler _masm(cbuf); 1502 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1503 #ifndef PRODUCT 1504 } else { 1505 st->print("%s %s, %s\t# spill", 1506 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1507 Matcher::regName[dst_first], 1508 Matcher::regName[src_first]); 1509 #endif 1510 } 1511 } 1512 return 0; 1513 } 1514 } 1515 1516 assert(0," foo "); 1517 Unimplemented(); 1518 return 0; 1519 } 1520 1521 #ifndef PRODUCT 1522 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1523 implementation(NULL, ra_, false, st); 1524 } 1525 #endif 1526 1527 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1528 implementation(&cbuf, ra_, false, NULL); 1529 } 1530 1531 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1532 return MachNode::size(ra_); 1533 } 1534 1535 //============================================================================= 1536 #ifndef PRODUCT 1537 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1538 { 1539 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1540 int reg = ra_->get_reg_first(this); 1541 st->print("leaq %s, [rsp + #%d]\t# box lock", 1542 Matcher::regName[reg], offset); 1543 } 1544 #endif 1545 1546 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1547 { 1548 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1549 int reg = ra_->get_encode(this); 1550 if (offset >= 0x80) { 1551 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1552 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1553 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1554 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1555 emit_d32(cbuf, offset); 1556 } else { 1557 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1558 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1559 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1560 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1561 emit_d8(cbuf, offset); 1562 } 1563 } 1564 1565 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1566 { 1567 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1568 return (offset < 0x80) ? 5 : 8; // REX 1569 } 1570 1571 //============================================================================= 1572 #ifndef PRODUCT 1573 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1574 { 1575 if (UseCompressedClassPointers) { 1576 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1577 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1578 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1579 } else { 1580 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1581 "# Inline cache check"); 1582 } 1583 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1584 st->print_cr("\tnop\t# nops to align entry point"); 1585 } 1586 #endif 1587 1588 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1589 { 1590 MacroAssembler masm(&cbuf); 1591 uint insts_size = cbuf.insts_size(); 1592 if (UseCompressedClassPointers) { 1593 masm.load_klass(rscratch1, j_rarg0); 1594 masm.cmpptr(rax, rscratch1); 1595 } else { 1596 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1597 } 1598 1599 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1600 1601 /* WARNING these NOPs are critical so that verified entry point is properly 1602 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1603 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1604 if (OptoBreakpoint) { 1605 // Leave space for int3 1606 nops_cnt -= 1; 1607 } 1608 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1609 if (nops_cnt > 0) 1610 masm.nop(nops_cnt); 1611 } 1612 1613 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1614 { 1615 return MachNode::size(ra_); // too many variables; just compute it 1616 // the hard way 1617 } 1618 1619 1620 //============================================================================= 1621 1622 int Matcher::regnum_to_fpu_offset(int regnum) 1623 { 1624 return regnum - 32; // The FP registers are in the second chunk 1625 } 1626 1627 // This is UltraSparc specific, true just means we have fast l2f conversion 1628 const bool Matcher::convL2FSupported(void) { 1629 return true; 1630 } 1631 1632 // Is this branch offset short enough that a short branch can be used? 1633 // 1634 // NOTE: If the platform does not provide any short branch variants, then 1635 // this method should return false for offset 0. 1636 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1637 // The passed offset is relative to address of the branch. 1638 // On 86 a branch displacement is calculated relative to address 1639 // of a next instruction. 1640 offset -= br_size; 1641 1642 // the short version of jmpConUCF2 contains multiple branches, 1643 // making the reach slightly less 1644 if (rule == jmpConUCF2_rule) 1645 return (-126 <= offset && offset <= 125); 1646 return (-128 <= offset && offset <= 127); 1647 } 1648 1649 const bool Matcher::isSimpleConstant64(jlong value) { 1650 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1651 //return value == (int) value; // Cf. storeImmL and immL32. 1652 1653 // Probably always true, even if a temp register is required. 1654 return true; 1655 } 1656 1657 // The ecx parameter to rep stosq for the ClearArray node is in words. 1658 const bool Matcher::init_array_count_is_in_bytes = false; 1659 1660 // No additional cost for CMOVL. 1661 const int Matcher::long_cmove_cost() { return 0; } 1662 1663 // No CMOVF/CMOVD with SSE2 1664 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1665 1666 // Does the CPU require late expand (see block.cpp for description of late expand)? 1667 const bool Matcher::require_postalloc_expand = false; 1668 1669 // Do we need to mask the count passed to shift instructions or does 1670 // the cpu only look at the lower 5/6 bits anyway? 1671 const bool Matcher::need_masked_shift_count = false; 1672 1673 bool Matcher::narrow_oop_use_complex_address() { 1674 assert(UseCompressedOops, "only for compressed oops code"); 1675 return (LogMinObjAlignmentInBytes <= 3); 1676 } 1677 1678 bool Matcher::narrow_klass_use_complex_address() { 1679 assert(UseCompressedClassPointers, "only for compressed klass code"); 1680 return (LogKlassAlignmentInBytes <= 3); 1681 } 1682 1683 bool Matcher::const_oop_prefer_decode() { 1684 // Prefer ConN+DecodeN over ConP. 1685 return true; 1686 } 1687 1688 bool Matcher::const_klass_prefer_decode() { 1689 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1690 // or condisider the following: 1691 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1692 //return Universe::narrow_klass_base() == NULL; 1693 return true; 1694 } 1695 1696 // Is it better to copy float constants, or load them directly from 1697 // memory? Intel can load a float constant from a direct address, 1698 // requiring no extra registers. Most RISCs will have to materialize 1699 // an address into a register first, so they would do better to copy 1700 // the constant from stack. 1701 const bool Matcher::rematerialize_float_constants = true; // XXX 1702 1703 // If CPU can load and store mis-aligned doubles directly then no 1704 // fixup is needed. Else we split the double into 2 integer pieces 1705 // and move it piece-by-piece. Only happens when passing doubles into 1706 // C code as the Java calling convention forces doubles to be aligned. 1707 const bool Matcher::misaligned_doubles_ok = true; 1708 1709 // No-op on amd64 1710 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1711 1712 // Advertise here if the CPU requires explicit rounding operations to 1713 // implement the UseStrictFP mode. 1714 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1715 1716 // Are floats conerted to double when stored to stack during deoptimization? 1717 // On x64 it is stored without convertion so we can use normal access. 1718 bool Matcher::float_in_double() { return false; } 1719 1720 // Do ints take an entire long register or just half? 1721 const bool Matcher::int_in_long = true; 1722 1723 // Return whether or not this register is ever used as an argument. 1724 // This function is used on startup to build the trampoline stubs in 1725 // generateOptoStub. Registers not mentioned will be killed by the VM 1726 // call in the trampoline, and arguments in those registers not be 1727 // available to the callee. 1728 bool Matcher::can_be_java_arg(int reg) 1729 { 1730 return 1731 reg == RDI_num || reg == RDI_H_num || 1732 reg == RSI_num || reg == RSI_H_num || 1733 reg == RDX_num || reg == RDX_H_num || 1734 reg == RCX_num || reg == RCX_H_num || 1735 reg == R8_num || reg == R8_H_num || 1736 reg == R9_num || reg == R9_H_num || 1737 reg == R12_num || reg == R12_H_num || 1738 reg == XMM0_num || reg == XMM0b_num || 1739 reg == XMM1_num || reg == XMM1b_num || 1740 reg == XMM2_num || reg == XMM2b_num || 1741 reg == XMM3_num || reg == XMM3b_num || 1742 reg == XMM4_num || reg == XMM4b_num || 1743 reg == XMM5_num || reg == XMM5b_num || 1744 reg == XMM6_num || reg == XMM6b_num || 1745 reg == XMM7_num || reg == XMM7b_num; 1746 } 1747 1748 bool Matcher::is_spillable_arg(int reg) 1749 { 1750 return can_be_java_arg(reg); 1751 } 1752 1753 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1754 // In 64 bit mode a code which use multiply when 1755 // devisor is constant is faster than hardware 1756 // DIV instruction (it uses MulHiL). 1757 return false; 1758 } 1759 1760 // Register for DIVI projection of divmodI 1761 RegMask Matcher::divI_proj_mask() { 1762 return INT_RAX_REG_mask(); 1763 } 1764 1765 // Register for MODI projection of divmodI 1766 RegMask Matcher::modI_proj_mask() { 1767 return INT_RDX_REG_mask(); 1768 } 1769 1770 // Register for DIVL projection of divmodL 1771 RegMask Matcher::divL_proj_mask() { 1772 return LONG_RAX_REG_mask(); 1773 } 1774 1775 // Register for MODL projection of divmodL 1776 RegMask Matcher::modL_proj_mask() { 1777 return LONG_RDX_REG_mask(); 1778 } 1779 1780 // Register for saving SP into on method handle invokes. Not used on x86_64. 1781 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1782 return NO_REG_mask(); 1783 } 1784 1785 %} 1786 1787 //----------ENCODING BLOCK----------------------------------------------------- 1788 // This block specifies the encoding classes used by the compiler to 1789 // output byte streams. Encoding classes are parameterized macros 1790 // used by Machine Instruction Nodes in order to generate the bit 1791 // encoding of the instruction. Operands specify their base encoding 1792 // interface with the interface keyword. There are currently 1793 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1794 // COND_INTER. REG_INTER causes an operand to generate a function 1795 // which returns its register number when queried. CONST_INTER causes 1796 // an operand to generate a function which returns the value of the 1797 // constant when queried. MEMORY_INTER causes an operand to generate 1798 // four functions which return the Base Register, the Index Register, 1799 // the Scale Value, and the Offset Value of the operand when queried. 1800 // COND_INTER causes an operand to generate six functions which return 1801 // the encoding code (ie - encoding bits for the instruction) 1802 // associated with each basic boolean condition for a conditional 1803 // instruction. 1804 // 1805 // Instructions specify two basic values for encoding. Again, a 1806 // function is available to check if the constant displacement is an 1807 // oop. They use the ins_encode keyword to specify their encoding 1808 // classes (which must be a sequence of enc_class names, and their 1809 // parameters, specified in the encoding block), and they use the 1810 // opcode keyword to specify, in order, their primary, secondary, and 1811 // tertiary opcode. Only the opcode sections which a particular 1812 // instruction needs for encoding need to be specified. 1813 encode %{ 1814 // Build emit functions for each basic byte or larger field in the 1815 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1816 // from C++ code in the enc_class source block. Emit functions will 1817 // live in the main source block for now. In future, we can 1818 // generalize this by adding a syntax that specifies the sizes of 1819 // fields in an order, so that the adlc can build the emit functions 1820 // automagically 1821 1822 // Emit primary opcode 1823 enc_class OpcP 1824 %{ 1825 emit_opcode(cbuf, $primary); 1826 %} 1827 1828 // Emit secondary opcode 1829 enc_class OpcS 1830 %{ 1831 emit_opcode(cbuf, $secondary); 1832 %} 1833 1834 // Emit tertiary opcode 1835 enc_class OpcT 1836 %{ 1837 emit_opcode(cbuf, $tertiary); 1838 %} 1839 1840 // Emit opcode directly 1841 enc_class Opcode(immI d8) 1842 %{ 1843 emit_opcode(cbuf, $d8$$constant); 1844 %} 1845 1846 // Emit size prefix 1847 enc_class SizePrefix 1848 %{ 1849 emit_opcode(cbuf, 0x66); 1850 %} 1851 1852 enc_class reg(rRegI reg) 1853 %{ 1854 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1855 %} 1856 1857 enc_class reg_reg(rRegI dst, rRegI src) 1858 %{ 1859 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1860 %} 1861 1862 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1863 %{ 1864 emit_opcode(cbuf, $opcode$$constant); 1865 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1866 %} 1867 1868 enc_class cdql_enc(no_rax_rdx_RegI div) 1869 %{ 1870 // Full implementation of Java idiv and irem; checks for 1871 // special case as described in JVM spec., p.243 & p.271. 1872 // 1873 // normal case special case 1874 // 1875 // input : rax: dividend min_int 1876 // reg: divisor -1 1877 // 1878 // output: rax: quotient (= rax idiv reg) min_int 1879 // rdx: remainder (= rax irem reg) 0 1880 // 1881 // Code sequnce: 1882 // 1883 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1884 // 5: 75 07/08 jne e <normal> 1885 // 7: 33 d2 xor %edx,%edx 1886 // [div >= 8 -> offset + 1] 1887 // [REX_B] 1888 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1889 // c: 74 03/04 je 11 <done> 1890 // 000000000000000e <normal>: 1891 // e: 99 cltd 1892 // [div >= 8 -> offset + 1] 1893 // [REX_B] 1894 // f: f7 f9 idiv $div 1895 // 0000000000000011 <done>: 1896 1897 // cmp $0x80000000,%eax 1898 emit_opcode(cbuf, 0x3d); 1899 emit_d8(cbuf, 0x00); 1900 emit_d8(cbuf, 0x00); 1901 emit_d8(cbuf, 0x00); 1902 emit_d8(cbuf, 0x80); 1903 1904 // jne e <normal> 1905 emit_opcode(cbuf, 0x75); 1906 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1907 1908 // xor %edx,%edx 1909 emit_opcode(cbuf, 0x33); 1910 emit_d8(cbuf, 0xD2); 1911 1912 // cmp $0xffffffffffffffff,%ecx 1913 if ($div$$reg >= 8) { 1914 emit_opcode(cbuf, Assembler::REX_B); 1915 } 1916 emit_opcode(cbuf, 0x83); 1917 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1918 emit_d8(cbuf, 0xFF); 1919 1920 // je 11 <done> 1921 emit_opcode(cbuf, 0x74); 1922 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1923 1924 // <normal> 1925 // cltd 1926 emit_opcode(cbuf, 0x99); 1927 1928 // idivl (note: must be emitted by the user of this rule) 1929 // <done> 1930 %} 1931 1932 enc_class cdqq_enc(no_rax_rdx_RegL div) 1933 %{ 1934 // Full implementation of Java ldiv and lrem; checks for 1935 // special case as described in JVM spec., p.243 & p.271. 1936 // 1937 // normal case special case 1938 // 1939 // input : rax: dividend min_long 1940 // reg: divisor -1 1941 // 1942 // output: rax: quotient (= rax idiv reg) min_long 1943 // rdx: remainder (= rax irem reg) 0 1944 // 1945 // Code sequnce: 1946 // 1947 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1948 // 7: 00 00 80 1949 // a: 48 39 d0 cmp %rdx,%rax 1950 // d: 75 08 jne 17 <normal> 1951 // f: 33 d2 xor %edx,%edx 1952 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1953 // 15: 74 05 je 1c <done> 1954 // 0000000000000017 <normal>: 1955 // 17: 48 99 cqto 1956 // 19: 48 f7 f9 idiv $div 1957 // 000000000000001c <done>: 1958 1959 // mov $0x8000000000000000,%rdx 1960 emit_opcode(cbuf, Assembler::REX_W); 1961 emit_opcode(cbuf, 0xBA); 1962 emit_d8(cbuf, 0x00); 1963 emit_d8(cbuf, 0x00); 1964 emit_d8(cbuf, 0x00); 1965 emit_d8(cbuf, 0x00); 1966 emit_d8(cbuf, 0x00); 1967 emit_d8(cbuf, 0x00); 1968 emit_d8(cbuf, 0x00); 1969 emit_d8(cbuf, 0x80); 1970 1971 // cmp %rdx,%rax 1972 emit_opcode(cbuf, Assembler::REX_W); 1973 emit_opcode(cbuf, 0x39); 1974 emit_d8(cbuf, 0xD0); 1975 1976 // jne 17 <normal> 1977 emit_opcode(cbuf, 0x75); 1978 emit_d8(cbuf, 0x08); 1979 1980 // xor %edx,%edx 1981 emit_opcode(cbuf, 0x33); 1982 emit_d8(cbuf, 0xD2); 1983 1984 // cmp $0xffffffffffffffff,$div 1985 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1986 emit_opcode(cbuf, 0x83); 1987 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1988 emit_d8(cbuf, 0xFF); 1989 1990 // je 1e <done> 1991 emit_opcode(cbuf, 0x74); 1992 emit_d8(cbuf, 0x05); 1993 1994 // <normal> 1995 // cqto 1996 emit_opcode(cbuf, Assembler::REX_W); 1997 emit_opcode(cbuf, 0x99); 1998 1999 // idivq (note: must be emitted by the user of this rule) 2000 // <done> 2001 %} 2002 2003 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2004 enc_class OpcSE(immI imm) 2005 %{ 2006 // Emit primary opcode and set sign-extend bit 2007 // Check for 8-bit immediate, and set sign extend bit in opcode 2008 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2009 emit_opcode(cbuf, $primary | 0x02); 2010 } else { 2011 // 32-bit immediate 2012 emit_opcode(cbuf, $primary); 2013 } 2014 %} 2015 2016 enc_class OpcSErm(rRegI dst, immI imm) 2017 %{ 2018 // OpcSEr/m 2019 int dstenc = $dst$$reg; 2020 if (dstenc >= 8) { 2021 emit_opcode(cbuf, Assembler::REX_B); 2022 dstenc -= 8; 2023 } 2024 // Emit primary opcode and set sign-extend bit 2025 // Check for 8-bit immediate, and set sign extend bit in opcode 2026 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2027 emit_opcode(cbuf, $primary | 0x02); 2028 } else { 2029 // 32-bit immediate 2030 emit_opcode(cbuf, $primary); 2031 } 2032 // Emit r/m byte with secondary opcode, after primary opcode. 2033 emit_rm(cbuf, 0x3, $secondary, dstenc); 2034 %} 2035 2036 enc_class OpcSErm_wide(rRegL dst, immI imm) 2037 %{ 2038 // OpcSEr/m 2039 int dstenc = $dst$$reg; 2040 if (dstenc < 8) { 2041 emit_opcode(cbuf, Assembler::REX_W); 2042 } else { 2043 emit_opcode(cbuf, Assembler::REX_WB); 2044 dstenc -= 8; 2045 } 2046 // Emit primary opcode and set sign-extend bit 2047 // Check for 8-bit immediate, and set sign extend bit in opcode 2048 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2049 emit_opcode(cbuf, $primary | 0x02); 2050 } else { 2051 // 32-bit immediate 2052 emit_opcode(cbuf, $primary); 2053 } 2054 // Emit r/m byte with secondary opcode, after primary opcode. 2055 emit_rm(cbuf, 0x3, $secondary, dstenc); 2056 %} 2057 2058 enc_class Con8or32(immI imm) 2059 %{ 2060 // Check for 8-bit immediate, and set sign extend bit in opcode 2061 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2062 $$$emit8$imm$$constant; 2063 } else { 2064 // 32-bit immediate 2065 $$$emit32$imm$$constant; 2066 } 2067 %} 2068 2069 enc_class opc2_reg(rRegI dst) 2070 %{ 2071 // BSWAP 2072 emit_cc(cbuf, $secondary, $dst$$reg); 2073 %} 2074 2075 enc_class opc3_reg(rRegI dst) 2076 %{ 2077 // BSWAP 2078 emit_cc(cbuf, $tertiary, $dst$$reg); 2079 %} 2080 2081 enc_class reg_opc(rRegI div) 2082 %{ 2083 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2084 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2085 %} 2086 2087 enc_class enc_cmov(cmpOp cop) 2088 %{ 2089 // CMOV 2090 $$$emit8$primary; 2091 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2092 %} 2093 2094 enc_class enc_PartialSubtypeCheck() 2095 %{ 2096 Register Rrdi = as_Register(RDI_enc); // result register 2097 Register Rrax = as_Register(RAX_enc); // super class 2098 Register Rrcx = as_Register(RCX_enc); // killed 2099 Register Rrsi = as_Register(RSI_enc); // sub class 2100 Label miss; 2101 const bool set_cond_codes = true; 2102 2103 MacroAssembler _masm(&cbuf); 2104 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2105 NULL, &miss, 2106 /*set_cond_codes:*/ true); 2107 if ($primary) { 2108 __ xorptr(Rrdi, Rrdi); 2109 } 2110 __ bind(miss); 2111 %} 2112 2113 enc_class clear_avx %{ 2114 debug_only(int off0 = cbuf.insts_size()); 2115 if (generate_vzeroupper(Compile::current())) { 2116 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2117 // Clear upper bits of YMM registers when current compiled code uses 2118 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2119 MacroAssembler _masm(&cbuf); 2120 __ vzeroupper(); 2121 } 2122 debug_only(int off1 = cbuf.insts_size()); 2123 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2124 %} 2125 2126 enc_class Java_To_Runtime(method meth) %{ 2127 // No relocation needed 2128 MacroAssembler _masm(&cbuf); 2129 __ mov64(r10, (int64_t) $meth$$method); 2130 __ call(r10); 2131 %} 2132 2133 enc_class Java_To_Interpreter(method meth) 2134 %{ 2135 // CALL Java_To_Interpreter 2136 // This is the instruction starting address for relocation info. 2137 cbuf.set_insts_mark(); 2138 $$$emit8$primary; 2139 // CALL directly to the runtime 2140 emit_d32_reloc(cbuf, 2141 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2142 runtime_call_Relocation::spec(), 2143 RELOC_DISP32); 2144 %} 2145 2146 enc_class Java_Static_Call(method meth) 2147 %{ 2148 // JAVA STATIC CALL 2149 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2150 // determine who we intended to call. 2151 cbuf.set_insts_mark(); 2152 $$$emit8$primary; 2153 2154 if (!_method) { 2155 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2156 runtime_call_Relocation::spec(), 2157 RELOC_DISP32); 2158 } else { 2159 int method_index = resolved_method_index(cbuf); 2160 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2161 : static_call_Relocation::spec(method_index); 2162 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2163 rspec, RELOC_DISP32); 2164 // Emit stubs for static call. 2165 address mark = cbuf.insts_mark(); 2166 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2167 if (stub == NULL) { 2168 ciEnv::current()->record_failure("CodeCache is full"); 2169 return; 2170 } 2171 #if INCLUDE_AOT 2172 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2173 #endif 2174 } 2175 %} 2176 2177 enc_class Java_Dynamic_Call(method meth) %{ 2178 MacroAssembler _masm(&cbuf); 2179 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2180 %} 2181 2182 enc_class Java_Compiled_Call(method meth) 2183 %{ 2184 // JAVA COMPILED CALL 2185 int disp = in_bytes(Method:: from_compiled_offset()); 2186 2187 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2188 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2189 2190 // callq *disp(%rax) 2191 cbuf.set_insts_mark(); 2192 $$$emit8$primary; 2193 if (disp < 0x80) { 2194 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2195 emit_d8(cbuf, disp); // Displacement 2196 } else { 2197 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2198 emit_d32(cbuf, disp); // Displacement 2199 } 2200 %} 2201 2202 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2203 %{ 2204 // SAL, SAR, SHR 2205 int dstenc = $dst$$reg; 2206 if (dstenc >= 8) { 2207 emit_opcode(cbuf, Assembler::REX_B); 2208 dstenc -= 8; 2209 } 2210 $$$emit8$primary; 2211 emit_rm(cbuf, 0x3, $secondary, dstenc); 2212 $$$emit8$shift$$constant; 2213 %} 2214 2215 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2216 %{ 2217 // SAL, SAR, SHR 2218 int dstenc = $dst$$reg; 2219 if (dstenc < 8) { 2220 emit_opcode(cbuf, Assembler::REX_W); 2221 } else { 2222 emit_opcode(cbuf, Assembler::REX_WB); 2223 dstenc -= 8; 2224 } 2225 $$$emit8$primary; 2226 emit_rm(cbuf, 0x3, $secondary, dstenc); 2227 $$$emit8$shift$$constant; 2228 %} 2229 2230 enc_class load_immI(rRegI dst, immI src) 2231 %{ 2232 int dstenc = $dst$$reg; 2233 if (dstenc >= 8) { 2234 emit_opcode(cbuf, Assembler::REX_B); 2235 dstenc -= 8; 2236 } 2237 emit_opcode(cbuf, 0xB8 | dstenc); 2238 $$$emit32$src$$constant; 2239 %} 2240 2241 enc_class load_immL(rRegL dst, immL src) 2242 %{ 2243 int dstenc = $dst$$reg; 2244 if (dstenc < 8) { 2245 emit_opcode(cbuf, Assembler::REX_W); 2246 } else { 2247 emit_opcode(cbuf, Assembler::REX_WB); 2248 dstenc -= 8; 2249 } 2250 emit_opcode(cbuf, 0xB8 | dstenc); 2251 emit_d64(cbuf, $src$$constant); 2252 %} 2253 2254 enc_class load_immUL32(rRegL dst, immUL32 src) 2255 %{ 2256 // same as load_immI, but this time we care about zeroes in the high word 2257 int dstenc = $dst$$reg; 2258 if (dstenc >= 8) { 2259 emit_opcode(cbuf, Assembler::REX_B); 2260 dstenc -= 8; 2261 } 2262 emit_opcode(cbuf, 0xB8 | dstenc); 2263 $$$emit32$src$$constant; 2264 %} 2265 2266 enc_class load_immL32(rRegL dst, immL32 src) 2267 %{ 2268 int dstenc = $dst$$reg; 2269 if (dstenc < 8) { 2270 emit_opcode(cbuf, Assembler::REX_W); 2271 } else { 2272 emit_opcode(cbuf, Assembler::REX_WB); 2273 dstenc -= 8; 2274 } 2275 emit_opcode(cbuf, 0xC7); 2276 emit_rm(cbuf, 0x03, 0x00, dstenc); 2277 $$$emit32$src$$constant; 2278 %} 2279 2280 enc_class load_immP31(rRegP dst, immP32 src) 2281 %{ 2282 // same as load_immI, but this time we care about zeroes in the high word 2283 int dstenc = $dst$$reg; 2284 if (dstenc >= 8) { 2285 emit_opcode(cbuf, Assembler::REX_B); 2286 dstenc -= 8; 2287 } 2288 emit_opcode(cbuf, 0xB8 | dstenc); 2289 $$$emit32$src$$constant; 2290 %} 2291 2292 enc_class load_immP(rRegP dst, immP src) 2293 %{ 2294 int dstenc = $dst$$reg; 2295 if (dstenc < 8) { 2296 emit_opcode(cbuf, Assembler::REX_W); 2297 } else { 2298 emit_opcode(cbuf, Assembler::REX_WB); 2299 dstenc -= 8; 2300 } 2301 emit_opcode(cbuf, 0xB8 | dstenc); 2302 // This next line should be generated from ADLC 2303 if ($src->constant_reloc() != relocInfo::none) { 2304 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2305 } else { 2306 emit_d64(cbuf, $src$$constant); 2307 } 2308 %} 2309 2310 enc_class Con32(immI src) 2311 %{ 2312 // Output immediate 2313 $$$emit32$src$$constant; 2314 %} 2315 2316 enc_class Con32F_as_bits(immF src) 2317 %{ 2318 // Output Float immediate bits 2319 jfloat jf = $src$$constant; 2320 jint jf_as_bits = jint_cast(jf); 2321 emit_d32(cbuf, jf_as_bits); 2322 %} 2323 2324 enc_class Con16(immI src) 2325 %{ 2326 // Output immediate 2327 $$$emit16$src$$constant; 2328 %} 2329 2330 // How is this different from Con32??? XXX 2331 enc_class Con_d32(immI src) 2332 %{ 2333 emit_d32(cbuf,$src$$constant); 2334 %} 2335 2336 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2337 // Output immediate memory reference 2338 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2339 emit_d32(cbuf, 0x00); 2340 %} 2341 2342 enc_class lock_prefix() 2343 %{ 2344 if (os::is_MP()) { 2345 emit_opcode(cbuf, 0xF0); // lock 2346 } 2347 %} 2348 2349 enc_class REX_mem(memory mem) 2350 %{ 2351 if ($mem$$base >= 8) { 2352 if ($mem$$index < 8) { 2353 emit_opcode(cbuf, Assembler::REX_B); 2354 } else { 2355 emit_opcode(cbuf, Assembler::REX_XB); 2356 } 2357 } else { 2358 if ($mem$$index >= 8) { 2359 emit_opcode(cbuf, Assembler::REX_X); 2360 } 2361 } 2362 %} 2363 2364 enc_class REX_mem_wide(memory mem) 2365 %{ 2366 if ($mem$$base >= 8) { 2367 if ($mem$$index < 8) { 2368 emit_opcode(cbuf, Assembler::REX_WB); 2369 } else { 2370 emit_opcode(cbuf, Assembler::REX_WXB); 2371 } 2372 } else { 2373 if ($mem$$index < 8) { 2374 emit_opcode(cbuf, Assembler::REX_W); 2375 } else { 2376 emit_opcode(cbuf, Assembler::REX_WX); 2377 } 2378 } 2379 %} 2380 2381 // for byte regs 2382 enc_class REX_breg(rRegI reg) 2383 %{ 2384 if ($reg$$reg >= 4) { 2385 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2386 } 2387 %} 2388 2389 // for byte regs 2390 enc_class REX_reg_breg(rRegI dst, rRegI src) 2391 %{ 2392 if ($dst$$reg < 8) { 2393 if ($src$$reg >= 4) { 2394 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2395 } 2396 } else { 2397 if ($src$$reg < 8) { 2398 emit_opcode(cbuf, Assembler::REX_R); 2399 } else { 2400 emit_opcode(cbuf, Assembler::REX_RB); 2401 } 2402 } 2403 %} 2404 2405 // for byte regs 2406 enc_class REX_breg_mem(rRegI reg, memory mem) 2407 %{ 2408 if ($reg$$reg < 8) { 2409 if ($mem$$base < 8) { 2410 if ($mem$$index >= 8) { 2411 emit_opcode(cbuf, Assembler::REX_X); 2412 } else if ($reg$$reg >= 4) { 2413 emit_opcode(cbuf, Assembler::REX); 2414 } 2415 } else { 2416 if ($mem$$index < 8) { 2417 emit_opcode(cbuf, Assembler::REX_B); 2418 } else { 2419 emit_opcode(cbuf, Assembler::REX_XB); 2420 } 2421 } 2422 } else { 2423 if ($mem$$base < 8) { 2424 if ($mem$$index < 8) { 2425 emit_opcode(cbuf, Assembler::REX_R); 2426 } else { 2427 emit_opcode(cbuf, Assembler::REX_RX); 2428 } 2429 } else { 2430 if ($mem$$index < 8) { 2431 emit_opcode(cbuf, Assembler::REX_RB); 2432 } else { 2433 emit_opcode(cbuf, Assembler::REX_RXB); 2434 } 2435 } 2436 } 2437 %} 2438 2439 enc_class REX_reg(rRegI reg) 2440 %{ 2441 if ($reg$$reg >= 8) { 2442 emit_opcode(cbuf, Assembler::REX_B); 2443 } 2444 %} 2445 2446 enc_class REX_reg_wide(rRegI reg) 2447 %{ 2448 if ($reg$$reg < 8) { 2449 emit_opcode(cbuf, Assembler::REX_W); 2450 } else { 2451 emit_opcode(cbuf, Assembler::REX_WB); 2452 } 2453 %} 2454 2455 enc_class REX_reg_reg(rRegI dst, rRegI src) 2456 %{ 2457 if ($dst$$reg < 8) { 2458 if ($src$$reg >= 8) { 2459 emit_opcode(cbuf, Assembler::REX_B); 2460 } 2461 } else { 2462 if ($src$$reg < 8) { 2463 emit_opcode(cbuf, Assembler::REX_R); 2464 } else { 2465 emit_opcode(cbuf, Assembler::REX_RB); 2466 } 2467 } 2468 %} 2469 2470 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2471 %{ 2472 if ($dst$$reg < 8) { 2473 if ($src$$reg < 8) { 2474 emit_opcode(cbuf, Assembler::REX_W); 2475 } else { 2476 emit_opcode(cbuf, Assembler::REX_WB); 2477 } 2478 } else { 2479 if ($src$$reg < 8) { 2480 emit_opcode(cbuf, Assembler::REX_WR); 2481 } else { 2482 emit_opcode(cbuf, Assembler::REX_WRB); 2483 } 2484 } 2485 %} 2486 2487 enc_class REX_reg_mem(rRegI reg, memory mem) 2488 %{ 2489 if ($reg$$reg < 8) { 2490 if ($mem$$base < 8) { 2491 if ($mem$$index >= 8) { 2492 emit_opcode(cbuf, Assembler::REX_X); 2493 } 2494 } else { 2495 if ($mem$$index < 8) { 2496 emit_opcode(cbuf, Assembler::REX_B); 2497 } else { 2498 emit_opcode(cbuf, Assembler::REX_XB); 2499 } 2500 } 2501 } else { 2502 if ($mem$$base < 8) { 2503 if ($mem$$index < 8) { 2504 emit_opcode(cbuf, Assembler::REX_R); 2505 } else { 2506 emit_opcode(cbuf, Assembler::REX_RX); 2507 } 2508 } else { 2509 if ($mem$$index < 8) { 2510 emit_opcode(cbuf, Assembler::REX_RB); 2511 } else { 2512 emit_opcode(cbuf, Assembler::REX_RXB); 2513 } 2514 } 2515 } 2516 %} 2517 2518 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2519 %{ 2520 if ($reg$$reg < 8) { 2521 if ($mem$$base < 8) { 2522 if ($mem$$index < 8) { 2523 emit_opcode(cbuf, Assembler::REX_W); 2524 } else { 2525 emit_opcode(cbuf, Assembler::REX_WX); 2526 } 2527 } else { 2528 if ($mem$$index < 8) { 2529 emit_opcode(cbuf, Assembler::REX_WB); 2530 } else { 2531 emit_opcode(cbuf, Assembler::REX_WXB); 2532 } 2533 } 2534 } else { 2535 if ($mem$$base < 8) { 2536 if ($mem$$index < 8) { 2537 emit_opcode(cbuf, Assembler::REX_WR); 2538 } else { 2539 emit_opcode(cbuf, Assembler::REX_WRX); 2540 } 2541 } else { 2542 if ($mem$$index < 8) { 2543 emit_opcode(cbuf, Assembler::REX_WRB); 2544 } else { 2545 emit_opcode(cbuf, Assembler::REX_WRXB); 2546 } 2547 } 2548 } 2549 %} 2550 2551 enc_class reg_mem(rRegI ereg, memory mem) 2552 %{ 2553 // High registers handle in encode_RegMem 2554 int reg = $ereg$$reg; 2555 int base = $mem$$base; 2556 int index = $mem$$index; 2557 int scale = $mem$$scale; 2558 int disp = $mem$$disp; 2559 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2560 2561 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2562 %} 2563 2564 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2565 %{ 2566 int rm_byte_opcode = $rm_opcode$$constant; 2567 2568 // High registers handle in encode_RegMem 2569 int base = $mem$$base; 2570 int index = $mem$$index; 2571 int scale = $mem$$scale; 2572 int displace = $mem$$disp; 2573 2574 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2575 // working with static 2576 // globals 2577 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2578 disp_reloc); 2579 %} 2580 2581 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2582 %{ 2583 int reg_encoding = $dst$$reg; 2584 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2585 int index = 0x04; // 0x04 indicates no index 2586 int scale = 0x00; // 0x00 indicates no scale 2587 int displace = $src1$$constant; // 0x00 indicates no displacement 2588 relocInfo::relocType disp_reloc = relocInfo::none; 2589 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2590 disp_reloc); 2591 %} 2592 2593 enc_class neg_reg(rRegI dst) 2594 %{ 2595 int dstenc = $dst$$reg; 2596 if (dstenc >= 8) { 2597 emit_opcode(cbuf, Assembler::REX_B); 2598 dstenc -= 8; 2599 } 2600 // NEG $dst 2601 emit_opcode(cbuf, 0xF7); 2602 emit_rm(cbuf, 0x3, 0x03, dstenc); 2603 %} 2604 2605 enc_class neg_reg_wide(rRegI dst) 2606 %{ 2607 int dstenc = $dst$$reg; 2608 if (dstenc < 8) { 2609 emit_opcode(cbuf, Assembler::REX_W); 2610 } else { 2611 emit_opcode(cbuf, Assembler::REX_WB); 2612 dstenc -= 8; 2613 } 2614 // NEG $dst 2615 emit_opcode(cbuf, 0xF7); 2616 emit_rm(cbuf, 0x3, 0x03, dstenc); 2617 %} 2618 2619 enc_class setLT_reg(rRegI dst) 2620 %{ 2621 int dstenc = $dst$$reg; 2622 if (dstenc >= 8) { 2623 emit_opcode(cbuf, Assembler::REX_B); 2624 dstenc -= 8; 2625 } else if (dstenc >= 4) { 2626 emit_opcode(cbuf, Assembler::REX); 2627 } 2628 // SETLT $dst 2629 emit_opcode(cbuf, 0x0F); 2630 emit_opcode(cbuf, 0x9C); 2631 emit_rm(cbuf, 0x3, 0x0, dstenc); 2632 %} 2633 2634 enc_class setNZ_reg(rRegI dst) 2635 %{ 2636 int dstenc = $dst$$reg; 2637 if (dstenc >= 8) { 2638 emit_opcode(cbuf, Assembler::REX_B); 2639 dstenc -= 8; 2640 } else if (dstenc >= 4) { 2641 emit_opcode(cbuf, Assembler::REX); 2642 } 2643 // SETNZ $dst 2644 emit_opcode(cbuf, 0x0F); 2645 emit_opcode(cbuf, 0x95); 2646 emit_rm(cbuf, 0x3, 0x0, dstenc); 2647 %} 2648 2649 2650 // Compare the lonogs and set -1, 0, or 1 into dst 2651 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2652 %{ 2653 int src1enc = $src1$$reg; 2654 int src2enc = $src2$$reg; 2655 int dstenc = $dst$$reg; 2656 2657 // cmpq $src1, $src2 2658 if (src1enc < 8) { 2659 if (src2enc < 8) { 2660 emit_opcode(cbuf, Assembler::REX_W); 2661 } else { 2662 emit_opcode(cbuf, Assembler::REX_WB); 2663 } 2664 } else { 2665 if (src2enc < 8) { 2666 emit_opcode(cbuf, Assembler::REX_WR); 2667 } else { 2668 emit_opcode(cbuf, Assembler::REX_WRB); 2669 } 2670 } 2671 emit_opcode(cbuf, 0x3B); 2672 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2673 2674 // movl $dst, -1 2675 if (dstenc >= 8) { 2676 emit_opcode(cbuf, Assembler::REX_B); 2677 } 2678 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2679 emit_d32(cbuf, -1); 2680 2681 // jl,s done 2682 emit_opcode(cbuf, 0x7C); 2683 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2684 2685 // setne $dst 2686 if (dstenc >= 4) { 2687 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2688 } 2689 emit_opcode(cbuf, 0x0F); 2690 emit_opcode(cbuf, 0x95); 2691 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2692 2693 // movzbl $dst, $dst 2694 if (dstenc >= 4) { 2695 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2696 } 2697 emit_opcode(cbuf, 0x0F); 2698 emit_opcode(cbuf, 0xB6); 2699 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2700 %} 2701 2702 enc_class Push_ResultXD(regD dst) %{ 2703 MacroAssembler _masm(&cbuf); 2704 __ fstp_d(Address(rsp, 0)); 2705 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2706 __ addptr(rsp, 8); 2707 %} 2708 2709 enc_class Push_SrcXD(regD src) %{ 2710 MacroAssembler _masm(&cbuf); 2711 __ subptr(rsp, 8); 2712 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2713 __ fld_d(Address(rsp, 0)); 2714 %} 2715 2716 2717 enc_class enc_rethrow() 2718 %{ 2719 cbuf.set_insts_mark(); 2720 emit_opcode(cbuf, 0xE9); // jmp entry 2721 emit_d32_reloc(cbuf, 2722 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2723 runtime_call_Relocation::spec(), 2724 RELOC_DISP32); 2725 %} 2726 2727 %} 2728 2729 2730 2731 //----------FRAME-------------------------------------------------------------- 2732 // Definition of frame structure and management information. 2733 // 2734 // S T A C K L A Y O U T Allocators stack-slot number 2735 // | (to get allocators register number 2736 // G Owned by | | v add OptoReg::stack0()) 2737 // r CALLER | | 2738 // o | +--------+ pad to even-align allocators stack-slot 2739 // w V | pad0 | numbers; owned by CALLER 2740 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2741 // h ^ | in | 5 2742 // | | args | 4 Holes in incoming args owned by SELF 2743 // | | | | 3 2744 // | | +--------+ 2745 // V | | old out| Empty on Intel, window on Sparc 2746 // | old |preserve| Must be even aligned. 2747 // | SP-+--------+----> Matcher::_old_SP, even aligned 2748 // | | in | 3 area for Intel ret address 2749 // Owned by |preserve| Empty on Sparc. 2750 // SELF +--------+ 2751 // | | pad2 | 2 pad to align old SP 2752 // | +--------+ 1 2753 // | | locks | 0 2754 // | +--------+----> OptoReg::stack0(), even aligned 2755 // | | pad1 | 11 pad to align new SP 2756 // | +--------+ 2757 // | | | 10 2758 // | | spills | 9 spills 2759 // V | | 8 (pad0 slot for callee) 2760 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2761 // ^ | out | 7 2762 // | | args | 6 Holes in outgoing args owned by CALLEE 2763 // Owned by +--------+ 2764 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2765 // | new |preserve| Must be even-aligned. 2766 // | SP-+--------+----> Matcher::_new_SP, even aligned 2767 // | | | 2768 // 2769 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2770 // known from SELF's arguments and the Java calling convention. 2771 // Region 6-7 is determined per call site. 2772 // Note 2: If the calling convention leaves holes in the incoming argument 2773 // area, those holes are owned by SELF. Holes in the outgoing area 2774 // are owned by the CALLEE. Holes should not be nessecary in the 2775 // incoming area, as the Java calling convention is completely under 2776 // the control of the AD file. Doubles can be sorted and packed to 2777 // avoid holes. Holes in the outgoing arguments may be nessecary for 2778 // varargs C calling conventions. 2779 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2780 // even aligned with pad0 as needed. 2781 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2782 // region 6-11 is even aligned; it may be padded out more so that 2783 // the region from SP to FP meets the minimum stack alignment. 2784 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2785 // alignment. Region 11, pad1, may be dynamically extended so that 2786 // SP meets the minimum alignment. 2787 2788 frame 2789 %{ 2790 // What direction does stack grow in (assumed to be same for C & Java) 2791 stack_direction(TOWARDS_LOW); 2792 2793 // These three registers define part of the calling convention 2794 // between compiled code and the interpreter. 2795 inline_cache_reg(RAX); // Inline Cache Register 2796 interpreter_method_oop_reg(RBX); // Method Oop Register when 2797 // calling interpreter 2798 2799 // Optional: name the operand used by cisc-spilling to access 2800 // [stack_pointer + offset] 2801 cisc_spilling_operand_name(indOffset32); 2802 2803 // Number of stack slots consumed by locking an object 2804 sync_stack_slots(2); 2805 2806 // Compiled code's Frame Pointer 2807 frame_pointer(RSP); 2808 2809 // Interpreter stores its frame pointer in a register which is 2810 // stored to the stack by I2CAdaptors. 2811 // I2CAdaptors convert from interpreted java to compiled java. 2812 interpreter_frame_pointer(RBP); 2813 2814 // Stack alignment requirement 2815 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2816 2817 // Number of stack slots between incoming argument block and the start of 2818 // a new frame. The PROLOG must add this many slots to the stack. The 2819 // EPILOG must remove this many slots. amd64 needs two slots for 2820 // return address. 2821 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2822 2823 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2824 // for calls to C. Supports the var-args backing area for register parms. 2825 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2826 2827 // The after-PROLOG location of the return address. Location of 2828 // return address specifies a type (REG or STACK) and a number 2829 // representing the register number (i.e. - use a register name) or 2830 // stack slot. 2831 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2832 // Otherwise, it is above the locks and verification slot and alignment word 2833 return_addr(STACK - 2 + 2834 align_up((Compile::current()->in_preserve_stack_slots() + 2835 Compile::current()->fixed_slots()), 2836 stack_alignment_in_slots())); 2837 2838 // Body of function which returns an integer array locating 2839 // arguments either in registers or in stack slots. Passed an array 2840 // of ideal registers called "sig" and a "length" count. Stack-slot 2841 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2842 // arguments for a CALLEE. Incoming stack arguments are 2843 // automatically biased by the preserve_stack_slots field above. 2844 2845 calling_convention 2846 %{ 2847 // No difference between ingoing/outgoing just pass false 2848 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2849 %} 2850 2851 c_calling_convention 2852 %{ 2853 // This is obviously always outgoing 2854 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2855 %} 2856 2857 // Location of compiled Java return values. Same as C for now. 2858 return_value 2859 %{ 2860 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2861 "only return normal values"); 2862 2863 static const int lo[Op_RegL + 1] = { 2864 0, 2865 0, 2866 RAX_num, // Op_RegN 2867 RAX_num, // Op_RegI 2868 RAX_num, // Op_RegP 2869 XMM0_num, // Op_RegF 2870 XMM0_num, // Op_RegD 2871 RAX_num // Op_RegL 2872 }; 2873 static const int hi[Op_RegL + 1] = { 2874 0, 2875 0, 2876 OptoReg::Bad, // Op_RegN 2877 OptoReg::Bad, // Op_RegI 2878 RAX_H_num, // Op_RegP 2879 OptoReg::Bad, // Op_RegF 2880 XMM0b_num, // Op_RegD 2881 RAX_H_num // Op_RegL 2882 }; 2883 // Excluded flags and vector registers. 2884 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2885 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2886 %} 2887 %} 2888 2889 //----------ATTRIBUTES--------------------------------------------------------- 2890 //----------Operand Attributes------------------------------------------------- 2891 op_attrib op_cost(0); // Required cost attribute 2892 2893 //----------Instruction Attributes--------------------------------------------- 2894 ins_attrib ins_cost(100); // Required cost attribute 2895 ins_attrib ins_size(8); // Required size attribute (in bits) 2896 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2897 // a non-matching short branch variant 2898 // of some long branch? 2899 ins_attrib ins_alignment(1); // Required alignment attribute (must 2900 // be a power of 2) specifies the 2901 // alignment that some part of the 2902 // instruction (not necessarily the 2903 // start) requires. If > 1, a 2904 // compute_padding() function must be 2905 // provided for the instruction 2906 2907 //----------OPERANDS----------------------------------------------------------- 2908 // Operand definitions must precede instruction definitions for correct parsing 2909 // in the ADLC because operands constitute user defined types which are used in 2910 // instruction definitions. 2911 2912 //----------Simple Operands---------------------------------------------------- 2913 // Immediate Operands 2914 // Integer Immediate 2915 operand immI() 2916 %{ 2917 match(ConI); 2918 2919 op_cost(10); 2920 format %{ %} 2921 interface(CONST_INTER); 2922 %} 2923 2924 // Constant for test vs zero 2925 operand immI0() 2926 %{ 2927 predicate(n->get_int() == 0); 2928 match(ConI); 2929 2930 op_cost(0); 2931 format %{ %} 2932 interface(CONST_INTER); 2933 %} 2934 2935 // Constant for increment 2936 operand immI1() 2937 %{ 2938 predicate(n->get_int() == 1); 2939 match(ConI); 2940 2941 op_cost(0); 2942 format %{ %} 2943 interface(CONST_INTER); 2944 %} 2945 2946 // Constant for decrement 2947 operand immI_M1() 2948 %{ 2949 predicate(n->get_int() == -1); 2950 match(ConI); 2951 2952 op_cost(0); 2953 format %{ %} 2954 interface(CONST_INTER); 2955 %} 2956 2957 // Valid scale values for addressing modes 2958 operand immI2() 2959 %{ 2960 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2961 match(ConI); 2962 2963 format %{ %} 2964 interface(CONST_INTER); 2965 %} 2966 2967 operand immI8() 2968 %{ 2969 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2970 match(ConI); 2971 2972 op_cost(5); 2973 format %{ %} 2974 interface(CONST_INTER); 2975 %} 2976 2977 operand immU8() 2978 %{ 2979 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2980 match(ConI); 2981 2982 op_cost(5); 2983 format %{ %} 2984 interface(CONST_INTER); 2985 %} 2986 2987 operand immI16() 2988 %{ 2989 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2990 match(ConI); 2991 2992 op_cost(10); 2993 format %{ %} 2994 interface(CONST_INTER); 2995 %} 2996 2997 // Int Immediate non-negative 2998 operand immU31() 2999 %{ 3000 predicate(n->get_int() >= 0); 3001 match(ConI); 3002 3003 op_cost(0); 3004 format %{ %} 3005 interface(CONST_INTER); 3006 %} 3007 3008 // Constant for long shifts 3009 operand immI_32() 3010 %{ 3011 predicate( n->get_int() == 32 ); 3012 match(ConI); 3013 3014 op_cost(0); 3015 format %{ %} 3016 interface(CONST_INTER); 3017 %} 3018 3019 // Constant for long shifts 3020 operand immI_64() 3021 %{ 3022 predicate( n->get_int() == 64 ); 3023 match(ConI); 3024 3025 op_cost(0); 3026 format %{ %} 3027 interface(CONST_INTER); 3028 %} 3029 3030 // Pointer Immediate 3031 operand immP() 3032 %{ 3033 match(ConP); 3034 3035 op_cost(10); 3036 format %{ %} 3037 interface(CONST_INTER); 3038 %} 3039 3040 // NULL Pointer Immediate 3041 operand immP0() 3042 %{ 3043 predicate(n->get_ptr() == 0); 3044 match(ConP); 3045 3046 op_cost(5); 3047 format %{ %} 3048 interface(CONST_INTER); 3049 %} 3050 3051 // Pointer Immediate 3052 operand immN() %{ 3053 match(ConN); 3054 3055 op_cost(10); 3056 format %{ %} 3057 interface(CONST_INTER); 3058 %} 3059 3060 operand immNKlass() %{ 3061 match(ConNKlass); 3062 3063 op_cost(10); 3064 format %{ %} 3065 interface(CONST_INTER); 3066 %} 3067 3068 // NULL Pointer Immediate 3069 operand immN0() %{ 3070 predicate(n->get_narrowcon() == 0); 3071 match(ConN); 3072 3073 op_cost(5); 3074 format %{ %} 3075 interface(CONST_INTER); 3076 %} 3077 3078 operand immP31() 3079 %{ 3080 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3081 && (n->get_ptr() >> 31) == 0); 3082 match(ConP); 3083 3084 op_cost(5); 3085 format %{ %} 3086 interface(CONST_INTER); 3087 %} 3088 3089 3090 // Long Immediate 3091 operand immL() 3092 %{ 3093 match(ConL); 3094 3095 op_cost(20); 3096 format %{ %} 3097 interface(CONST_INTER); 3098 %} 3099 3100 // Long Immediate 8-bit 3101 operand immL8() 3102 %{ 3103 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3104 match(ConL); 3105 3106 op_cost(5); 3107 format %{ %} 3108 interface(CONST_INTER); 3109 %} 3110 3111 // Long Immediate 32-bit unsigned 3112 operand immUL32() 3113 %{ 3114 predicate(n->get_long() == (unsigned int) (n->get_long())); 3115 match(ConL); 3116 3117 op_cost(10); 3118 format %{ %} 3119 interface(CONST_INTER); 3120 %} 3121 3122 // Long Immediate 32-bit signed 3123 operand immL32() 3124 %{ 3125 predicate(n->get_long() == (int) (n->get_long())); 3126 match(ConL); 3127 3128 op_cost(15); 3129 format %{ %} 3130 interface(CONST_INTER); 3131 %} 3132 3133 // Long Immediate zero 3134 operand immL0() 3135 %{ 3136 predicate(n->get_long() == 0L); 3137 match(ConL); 3138 3139 op_cost(10); 3140 format %{ %} 3141 interface(CONST_INTER); 3142 %} 3143 3144 // Constant for increment 3145 operand immL1() 3146 %{ 3147 predicate(n->get_long() == 1); 3148 match(ConL); 3149 3150 format %{ %} 3151 interface(CONST_INTER); 3152 %} 3153 3154 // Constant for decrement 3155 operand immL_M1() 3156 %{ 3157 predicate(n->get_long() == -1); 3158 match(ConL); 3159 3160 format %{ %} 3161 interface(CONST_INTER); 3162 %} 3163 3164 // Long Immediate: the value 10 3165 operand immL10() 3166 %{ 3167 predicate(n->get_long() == 10); 3168 match(ConL); 3169 3170 format %{ %} 3171 interface(CONST_INTER); 3172 %} 3173 3174 // Long immediate from 0 to 127. 3175 // Used for a shorter form of long mul by 10. 3176 operand immL_127() 3177 %{ 3178 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3179 match(ConL); 3180 3181 op_cost(10); 3182 format %{ %} 3183 interface(CONST_INTER); 3184 %} 3185 3186 // Long Immediate: low 32-bit mask 3187 operand immL_32bits() 3188 %{ 3189 predicate(n->get_long() == 0xFFFFFFFFL); 3190 match(ConL); 3191 op_cost(20); 3192 3193 format %{ %} 3194 interface(CONST_INTER); 3195 %} 3196 3197 // Float Immediate zero 3198 operand immF0() 3199 %{ 3200 predicate(jint_cast(n->getf()) == 0); 3201 match(ConF); 3202 3203 op_cost(5); 3204 format %{ %} 3205 interface(CONST_INTER); 3206 %} 3207 3208 // Float Immediate 3209 operand immF() 3210 %{ 3211 match(ConF); 3212 3213 op_cost(15); 3214 format %{ %} 3215 interface(CONST_INTER); 3216 %} 3217 3218 // Double Immediate zero 3219 operand immD0() 3220 %{ 3221 predicate(jlong_cast(n->getd()) == 0); 3222 match(ConD); 3223 3224 op_cost(5); 3225 format %{ %} 3226 interface(CONST_INTER); 3227 %} 3228 3229 // Double Immediate 3230 operand immD() 3231 %{ 3232 match(ConD); 3233 3234 op_cost(15); 3235 format %{ %} 3236 interface(CONST_INTER); 3237 %} 3238 3239 // Immediates for special shifts (sign extend) 3240 3241 // Constants for increment 3242 operand immI_16() 3243 %{ 3244 predicate(n->get_int() == 16); 3245 match(ConI); 3246 3247 format %{ %} 3248 interface(CONST_INTER); 3249 %} 3250 3251 operand immI_24() 3252 %{ 3253 predicate(n->get_int() == 24); 3254 match(ConI); 3255 3256 format %{ %} 3257 interface(CONST_INTER); 3258 %} 3259 3260 // Constant for byte-wide masking 3261 operand immI_255() 3262 %{ 3263 predicate(n->get_int() == 255); 3264 match(ConI); 3265 3266 format %{ %} 3267 interface(CONST_INTER); 3268 %} 3269 3270 // Constant for short-wide masking 3271 operand immI_65535() 3272 %{ 3273 predicate(n->get_int() == 65535); 3274 match(ConI); 3275 3276 format %{ %} 3277 interface(CONST_INTER); 3278 %} 3279 3280 // Constant for byte-wide masking 3281 operand immL_255() 3282 %{ 3283 predicate(n->get_long() == 255); 3284 match(ConL); 3285 3286 format %{ %} 3287 interface(CONST_INTER); 3288 %} 3289 3290 // Constant for short-wide masking 3291 operand immL_65535() 3292 %{ 3293 predicate(n->get_long() == 65535); 3294 match(ConL); 3295 3296 format %{ %} 3297 interface(CONST_INTER); 3298 %} 3299 3300 // Register Operands 3301 // Integer Register 3302 operand rRegI() 3303 %{ 3304 constraint(ALLOC_IN_RC(int_reg)); 3305 match(RegI); 3306 3307 match(rax_RegI); 3308 match(rbx_RegI); 3309 match(rcx_RegI); 3310 match(rdx_RegI); 3311 match(rdi_RegI); 3312 3313 format %{ %} 3314 interface(REG_INTER); 3315 %} 3316 3317 // Special Registers 3318 operand rax_RegI() 3319 %{ 3320 constraint(ALLOC_IN_RC(int_rax_reg)); 3321 match(RegI); 3322 match(rRegI); 3323 3324 format %{ "RAX" %} 3325 interface(REG_INTER); 3326 %} 3327 3328 // Special Registers 3329 operand rbx_RegI() 3330 %{ 3331 constraint(ALLOC_IN_RC(int_rbx_reg)); 3332 match(RegI); 3333 match(rRegI); 3334 3335 format %{ "RBX" %} 3336 interface(REG_INTER); 3337 %} 3338 3339 operand rcx_RegI() 3340 %{ 3341 constraint(ALLOC_IN_RC(int_rcx_reg)); 3342 match(RegI); 3343 match(rRegI); 3344 3345 format %{ "RCX" %} 3346 interface(REG_INTER); 3347 %} 3348 3349 operand rdx_RegI() 3350 %{ 3351 constraint(ALLOC_IN_RC(int_rdx_reg)); 3352 match(RegI); 3353 match(rRegI); 3354 3355 format %{ "RDX" %} 3356 interface(REG_INTER); 3357 %} 3358 3359 operand rdi_RegI() 3360 %{ 3361 constraint(ALLOC_IN_RC(int_rdi_reg)); 3362 match(RegI); 3363 match(rRegI); 3364 3365 format %{ "RDI" %} 3366 interface(REG_INTER); 3367 %} 3368 3369 operand no_rcx_RegI() 3370 %{ 3371 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3372 match(RegI); 3373 match(rax_RegI); 3374 match(rbx_RegI); 3375 match(rdx_RegI); 3376 match(rdi_RegI); 3377 3378 format %{ %} 3379 interface(REG_INTER); 3380 %} 3381 3382 operand no_rax_rdx_RegI() 3383 %{ 3384 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3385 match(RegI); 3386 match(rbx_RegI); 3387 match(rcx_RegI); 3388 match(rdi_RegI); 3389 3390 format %{ %} 3391 interface(REG_INTER); 3392 %} 3393 3394 // Pointer Register 3395 operand any_RegP() 3396 %{ 3397 constraint(ALLOC_IN_RC(any_reg)); 3398 match(RegP); 3399 match(rax_RegP); 3400 match(rbx_RegP); 3401 match(rdi_RegP); 3402 match(rsi_RegP); 3403 match(rbp_RegP); 3404 match(r15_RegP); 3405 match(rRegP); 3406 3407 format %{ %} 3408 interface(REG_INTER); 3409 %} 3410 3411 operand rRegP() 3412 %{ 3413 constraint(ALLOC_IN_RC(ptr_reg)); 3414 match(RegP); 3415 match(rax_RegP); 3416 match(rbx_RegP); 3417 match(rdi_RegP); 3418 match(rsi_RegP); 3419 match(rbp_RegP); // See Q&A below about 3420 match(r15_RegP); // r15_RegP and rbp_RegP. 3421 3422 format %{ %} 3423 interface(REG_INTER); 3424 %} 3425 3426 operand rRegN() %{ 3427 constraint(ALLOC_IN_RC(int_reg)); 3428 match(RegN); 3429 3430 format %{ %} 3431 interface(REG_INTER); 3432 %} 3433 3434 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3435 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3436 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3437 // The output of an instruction is controlled by the allocator, which respects 3438 // register class masks, not match rules. Unless an instruction mentions 3439 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3440 // by the allocator as an input. 3441 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3442 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3443 // result, RBP is not included in the output of the instruction either. 3444 3445 operand no_rax_RegP() 3446 %{ 3447 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3448 match(RegP); 3449 match(rbx_RegP); 3450 match(rsi_RegP); 3451 match(rdi_RegP); 3452 3453 format %{ %} 3454 interface(REG_INTER); 3455 %} 3456 3457 // This operand is not allowed to use RBP even if 3458 // RBP is not used to hold the frame pointer. 3459 operand no_rbp_RegP() 3460 %{ 3461 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3462 match(RegP); 3463 match(rbx_RegP); 3464 match(rsi_RegP); 3465 match(rdi_RegP); 3466 3467 format %{ %} 3468 interface(REG_INTER); 3469 %} 3470 3471 operand no_rax_rbx_RegP() 3472 %{ 3473 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3474 match(RegP); 3475 match(rsi_RegP); 3476 match(rdi_RegP); 3477 3478 format %{ %} 3479 interface(REG_INTER); 3480 %} 3481 3482 // Special Registers 3483 // Return a pointer value 3484 operand rax_RegP() 3485 %{ 3486 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3487 match(RegP); 3488 match(rRegP); 3489 3490 format %{ %} 3491 interface(REG_INTER); 3492 %} 3493 3494 // Special Registers 3495 // Return a compressed pointer value 3496 operand rax_RegN() 3497 %{ 3498 constraint(ALLOC_IN_RC(int_rax_reg)); 3499 match(RegN); 3500 match(rRegN); 3501 3502 format %{ %} 3503 interface(REG_INTER); 3504 %} 3505 3506 // Used in AtomicAdd 3507 operand rbx_RegP() 3508 %{ 3509 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3510 match(RegP); 3511 match(rRegP); 3512 3513 format %{ %} 3514 interface(REG_INTER); 3515 %} 3516 3517 operand rsi_RegP() 3518 %{ 3519 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3520 match(RegP); 3521 match(rRegP); 3522 3523 format %{ %} 3524 interface(REG_INTER); 3525 %} 3526 3527 // Used in rep stosq 3528 operand rdi_RegP() 3529 %{ 3530 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3531 match(RegP); 3532 match(rRegP); 3533 3534 format %{ %} 3535 interface(REG_INTER); 3536 %} 3537 3538 operand r15_RegP() 3539 %{ 3540 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3541 match(RegP); 3542 match(rRegP); 3543 3544 format %{ %} 3545 interface(REG_INTER); 3546 %} 3547 3548 operand rRegL() 3549 %{ 3550 constraint(ALLOC_IN_RC(long_reg)); 3551 match(RegL); 3552 match(rax_RegL); 3553 match(rdx_RegL); 3554 3555 format %{ %} 3556 interface(REG_INTER); 3557 %} 3558 3559 // Special Registers 3560 operand no_rax_rdx_RegL() 3561 %{ 3562 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3563 match(RegL); 3564 match(rRegL); 3565 3566 format %{ %} 3567 interface(REG_INTER); 3568 %} 3569 3570 operand no_rax_RegL() 3571 %{ 3572 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3573 match(RegL); 3574 match(rRegL); 3575 match(rdx_RegL); 3576 3577 format %{ %} 3578 interface(REG_INTER); 3579 %} 3580 3581 operand no_rcx_RegL() 3582 %{ 3583 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3584 match(RegL); 3585 match(rRegL); 3586 3587 format %{ %} 3588 interface(REG_INTER); 3589 %} 3590 3591 operand rax_RegL() 3592 %{ 3593 constraint(ALLOC_IN_RC(long_rax_reg)); 3594 match(RegL); 3595 match(rRegL); 3596 3597 format %{ "RAX" %} 3598 interface(REG_INTER); 3599 %} 3600 3601 operand rcx_RegL() 3602 %{ 3603 constraint(ALLOC_IN_RC(long_rcx_reg)); 3604 match(RegL); 3605 match(rRegL); 3606 3607 format %{ %} 3608 interface(REG_INTER); 3609 %} 3610 3611 operand rdx_RegL() 3612 %{ 3613 constraint(ALLOC_IN_RC(long_rdx_reg)); 3614 match(RegL); 3615 match(rRegL); 3616 3617 format %{ %} 3618 interface(REG_INTER); 3619 %} 3620 3621 // Flags register, used as output of compare instructions 3622 operand rFlagsReg() 3623 %{ 3624 constraint(ALLOC_IN_RC(int_flags)); 3625 match(RegFlags); 3626 3627 format %{ "RFLAGS" %} 3628 interface(REG_INTER); 3629 %} 3630 3631 // Flags register, used as output of FLOATING POINT compare instructions 3632 operand rFlagsRegU() 3633 %{ 3634 constraint(ALLOC_IN_RC(int_flags)); 3635 match(RegFlags); 3636 3637 format %{ "RFLAGS_U" %} 3638 interface(REG_INTER); 3639 %} 3640 3641 operand rFlagsRegUCF() %{ 3642 constraint(ALLOC_IN_RC(int_flags)); 3643 match(RegFlags); 3644 predicate(false); 3645 3646 format %{ "RFLAGS_U_CF" %} 3647 interface(REG_INTER); 3648 %} 3649 3650 // Float register operands 3651 operand regF() %{ 3652 constraint(ALLOC_IN_RC(float_reg)); 3653 match(RegF); 3654 3655 format %{ %} 3656 interface(REG_INTER); 3657 %} 3658 3659 // Double register operands 3660 operand regD() %{ 3661 constraint(ALLOC_IN_RC(double_reg)); 3662 match(RegD); 3663 3664 format %{ %} 3665 interface(REG_INTER); 3666 %} 3667 3668 // Vectors 3669 operand vecS() %{ 3670 constraint(ALLOC_IN_RC(vectors_reg)); 3671 match(VecS); 3672 3673 format %{ %} 3674 interface(REG_INTER); 3675 %} 3676 3677 operand vecD() %{ 3678 constraint(ALLOC_IN_RC(vectord_reg)); 3679 match(VecD); 3680 3681 format %{ %} 3682 interface(REG_INTER); 3683 %} 3684 3685 operand vecX() %{ 3686 constraint(ALLOC_IN_RC(vectorx_reg)); 3687 match(VecX); 3688 3689 format %{ %} 3690 interface(REG_INTER); 3691 %} 3692 3693 operand vecY() %{ 3694 constraint(ALLOC_IN_RC(vectory_reg)); 3695 match(VecY); 3696 3697 format %{ %} 3698 interface(REG_INTER); 3699 %} 3700 3701 //----------Memory Operands---------------------------------------------------- 3702 // Direct Memory Operand 3703 // operand direct(immP addr) 3704 // %{ 3705 // match(addr); 3706 3707 // format %{ "[$addr]" %} 3708 // interface(MEMORY_INTER) %{ 3709 // base(0xFFFFFFFF); 3710 // index(0x4); 3711 // scale(0x0); 3712 // disp($addr); 3713 // %} 3714 // %} 3715 3716 // Indirect Memory Operand 3717 operand indirect(any_RegP reg) 3718 %{ 3719 constraint(ALLOC_IN_RC(ptr_reg)); 3720 match(reg); 3721 3722 format %{ "[$reg]" %} 3723 interface(MEMORY_INTER) %{ 3724 base($reg); 3725 index(0x4); 3726 scale(0x0); 3727 disp(0x0); 3728 %} 3729 %} 3730 3731 // Indirect Memory Plus Short Offset Operand 3732 operand indOffset8(any_RegP reg, immL8 off) 3733 %{ 3734 constraint(ALLOC_IN_RC(ptr_reg)); 3735 match(AddP reg off); 3736 3737 format %{ "[$reg + $off (8-bit)]" %} 3738 interface(MEMORY_INTER) %{ 3739 base($reg); 3740 index(0x4); 3741 scale(0x0); 3742 disp($off); 3743 %} 3744 %} 3745 3746 // Indirect Memory Plus Long Offset Operand 3747 operand indOffset32(any_RegP reg, immL32 off) 3748 %{ 3749 constraint(ALLOC_IN_RC(ptr_reg)); 3750 match(AddP reg off); 3751 3752 format %{ "[$reg + $off (32-bit)]" %} 3753 interface(MEMORY_INTER) %{ 3754 base($reg); 3755 index(0x4); 3756 scale(0x0); 3757 disp($off); 3758 %} 3759 %} 3760 3761 // Indirect Memory Plus Index Register Plus Offset Operand 3762 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3763 %{ 3764 constraint(ALLOC_IN_RC(ptr_reg)); 3765 match(AddP (AddP reg lreg) off); 3766 3767 op_cost(10); 3768 format %{"[$reg + $off + $lreg]" %} 3769 interface(MEMORY_INTER) %{ 3770 base($reg); 3771 index($lreg); 3772 scale(0x0); 3773 disp($off); 3774 %} 3775 %} 3776 3777 // Indirect Memory Plus Index Register Plus Offset Operand 3778 operand indIndex(any_RegP reg, rRegL lreg) 3779 %{ 3780 constraint(ALLOC_IN_RC(ptr_reg)); 3781 match(AddP reg lreg); 3782 3783 op_cost(10); 3784 format %{"[$reg + $lreg]" %} 3785 interface(MEMORY_INTER) %{ 3786 base($reg); 3787 index($lreg); 3788 scale(0x0); 3789 disp(0x0); 3790 %} 3791 %} 3792 3793 // Indirect Memory Times Scale Plus Index Register 3794 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3795 %{ 3796 constraint(ALLOC_IN_RC(ptr_reg)); 3797 match(AddP reg (LShiftL lreg scale)); 3798 3799 op_cost(10); 3800 format %{"[$reg + $lreg << $scale]" %} 3801 interface(MEMORY_INTER) %{ 3802 base($reg); 3803 index($lreg); 3804 scale($scale); 3805 disp(0x0); 3806 %} 3807 %} 3808 3809 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3810 %{ 3811 constraint(ALLOC_IN_RC(ptr_reg)); 3812 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3813 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3814 3815 op_cost(10); 3816 format %{"[$reg + pos $idx << $scale]" %} 3817 interface(MEMORY_INTER) %{ 3818 base($reg); 3819 index($idx); 3820 scale($scale); 3821 disp(0x0); 3822 %} 3823 %} 3824 3825 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3826 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3827 %{ 3828 constraint(ALLOC_IN_RC(ptr_reg)); 3829 match(AddP (AddP reg (LShiftL lreg scale)) off); 3830 3831 op_cost(10); 3832 format %{"[$reg + $off + $lreg << $scale]" %} 3833 interface(MEMORY_INTER) %{ 3834 base($reg); 3835 index($lreg); 3836 scale($scale); 3837 disp($off); 3838 %} 3839 %} 3840 3841 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3842 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3843 %{ 3844 constraint(ALLOC_IN_RC(ptr_reg)); 3845 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3846 match(AddP (AddP reg (ConvI2L idx)) off); 3847 3848 op_cost(10); 3849 format %{"[$reg + $off + $idx]" %} 3850 interface(MEMORY_INTER) %{ 3851 base($reg); 3852 index($idx); 3853 scale(0x0); 3854 disp($off); 3855 %} 3856 %} 3857 3858 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3859 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3860 %{ 3861 constraint(ALLOC_IN_RC(ptr_reg)); 3862 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3863 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3864 3865 op_cost(10); 3866 format %{"[$reg + $off + $idx << $scale]" %} 3867 interface(MEMORY_INTER) %{ 3868 base($reg); 3869 index($idx); 3870 scale($scale); 3871 disp($off); 3872 %} 3873 %} 3874 3875 // Indirect Narrow Oop Plus Offset Operand 3876 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3877 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3878 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3879 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3880 constraint(ALLOC_IN_RC(ptr_reg)); 3881 match(AddP (DecodeN reg) off); 3882 3883 op_cost(10); 3884 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3885 interface(MEMORY_INTER) %{ 3886 base(0xc); // R12 3887 index($reg); 3888 scale(0x3); 3889 disp($off); 3890 %} 3891 %} 3892 3893 // Indirect Memory Operand 3894 operand indirectNarrow(rRegN reg) 3895 %{ 3896 predicate(Universe::narrow_oop_shift() == 0); 3897 constraint(ALLOC_IN_RC(ptr_reg)); 3898 match(DecodeN reg); 3899 3900 format %{ "[$reg]" %} 3901 interface(MEMORY_INTER) %{ 3902 base($reg); 3903 index(0x4); 3904 scale(0x0); 3905 disp(0x0); 3906 %} 3907 %} 3908 3909 // Indirect Memory Plus Short Offset Operand 3910 operand indOffset8Narrow(rRegN reg, immL8 off) 3911 %{ 3912 predicate(Universe::narrow_oop_shift() == 0); 3913 constraint(ALLOC_IN_RC(ptr_reg)); 3914 match(AddP (DecodeN reg) off); 3915 3916 format %{ "[$reg + $off (8-bit)]" %} 3917 interface(MEMORY_INTER) %{ 3918 base($reg); 3919 index(0x4); 3920 scale(0x0); 3921 disp($off); 3922 %} 3923 %} 3924 3925 // Indirect Memory Plus Long Offset Operand 3926 operand indOffset32Narrow(rRegN reg, immL32 off) 3927 %{ 3928 predicate(Universe::narrow_oop_shift() == 0); 3929 constraint(ALLOC_IN_RC(ptr_reg)); 3930 match(AddP (DecodeN reg) off); 3931 3932 format %{ "[$reg + $off (32-bit)]" %} 3933 interface(MEMORY_INTER) %{ 3934 base($reg); 3935 index(0x4); 3936 scale(0x0); 3937 disp($off); 3938 %} 3939 %} 3940 3941 // Indirect Memory Plus Index Register Plus Offset Operand 3942 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3943 %{ 3944 predicate(Universe::narrow_oop_shift() == 0); 3945 constraint(ALLOC_IN_RC(ptr_reg)); 3946 match(AddP (AddP (DecodeN reg) lreg) off); 3947 3948 op_cost(10); 3949 format %{"[$reg + $off + $lreg]" %} 3950 interface(MEMORY_INTER) %{ 3951 base($reg); 3952 index($lreg); 3953 scale(0x0); 3954 disp($off); 3955 %} 3956 %} 3957 3958 // Indirect Memory Plus Index Register Plus Offset Operand 3959 operand indIndexNarrow(rRegN reg, rRegL lreg) 3960 %{ 3961 predicate(Universe::narrow_oop_shift() == 0); 3962 constraint(ALLOC_IN_RC(ptr_reg)); 3963 match(AddP (DecodeN reg) lreg); 3964 3965 op_cost(10); 3966 format %{"[$reg + $lreg]" %} 3967 interface(MEMORY_INTER) %{ 3968 base($reg); 3969 index($lreg); 3970 scale(0x0); 3971 disp(0x0); 3972 %} 3973 %} 3974 3975 // Indirect Memory Times Scale Plus Index Register 3976 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3977 %{ 3978 predicate(Universe::narrow_oop_shift() == 0); 3979 constraint(ALLOC_IN_RC(ptr_reg)); 3980 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3981 3982 op_cost(10); 3983 format %{"[$reg + $lreg << $scale]" %} 3984 interface(MEMORY_INTER) %{ 3985 base($reg); 3986 index($lreg); 3987 scale($scale); 3988 disp(0x0); 3989 %} 3990 %} 3991 3992 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3993 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3994 %{ 3995 predicate(Universe::narrow_oop_shift() == 0); 3996 constraint(ALLOC_IN_RC(ptr_reg)); 3997 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3998 3999 op_cost(10); 4000 format %{"[$reg + $off + $lreg << $scale]" %} 4001 interface(MEMORY_INTER) %{ 4002 base($reg); 4003 index($lreg); 4004 scale($scale); 4005 disp($off); 4006 %} 4007 %} 4008 4009 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4010 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4011 %{ 4012 constraint(ALLOC_IN_RC(ptr_reg)); 4013 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4014 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4015 4016 op_cost(10); 4017 format %{"[$reg + $off + $idx]" %} 4018 interface(MEMORY_INTER) %{ 4019 base($reg); 4020 index($idx); 4021 scale(0x0); 4022 disp($off); 4023 %} 4024 %} 4025 4026 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4027 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4028 %{ 4029 constraint(ALLOC_IN_RC(ptr_reg)); 4030 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4031 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4032 4033 op_cost(10); 4034 format %{"[$reg + $off + $idx << $scale]" %} 4035 interface(MEMORY_INTER) %{ 4036 base($reg); 4037 index($idx); 4038 scale($scale); 4039 disp($off); 4040 %} 4041 %} 4042 4043 //----------Special Memory Operands-------------------------------------------- 4044 // Stack Slot Operand - This operand is used for loading and storing temporary 4045 // values on the stack where a match requires a value to 4046 // flow through memory. 4047 operand stackSlotP(sRegP reg) 4048 %{ 4049 constraint(ALLOC_IN_RC(stack_slots)); 4050 // No match rule because this operand is only generated in matching 4051 4052 format %{ "[$reg]" %} 4053 interface(MEMORY_INTER) %{ 4054 base(0x4); // RSP 4055 index(0x4); // No Index 4056 scale(0x0); // No Scale 4057 disp($reg); // Stack Offset 4058 %} 4059 %} 4060 4061 operand stackSlotI(sRegI reg) 4062 %{ 4063 constraint(ALLOC_IN_RC(stack_slots)); 4064 // No match rule because this operand is only generated in matching 4065 4066 format %{ "[$reg]" %} 4067 interface(MEMORY_INTER) %{ 4068 base(0x4); // RSP 4069 index(0x4); // No Index 4070 scale(0x0); // No Scale 4071 disp($reg); // Stack Offset 4072 %} 4073 %} 4074 4075 operand stackSlotF(sRegF reg) 4076 %{ 4077 constraint(ALLOC_IN_RC(stack_slots)); 4078 // No match rule because this operand is only generated in matching 4079 4080 format %{ "[$reg]" %} 4081 interface(MEMORY_INTER) %{ 4082 base(0x4); // RSP 4083 index(0x4); // No Index 4084 scale(0x0); // No Scale 4085 disp($reg); // Stack Offset 4086 %} 4087 %} 4088 4089 operand stackSlotD(sRegD reg) 4090 %{ 4091 constraint(ALLOC_IN_RC(stack_slots)); 4092 // No match rule because this operand is only generated in matching 4093 4094 format %{ "[$reg]" %} 4095 interface(MEMORY_INTER) %{ 4096 base(0x4); // RSP 4097 index(0x4); // No Index 4098 scale(0x0); // No Scale 4099 disp($reg); // Stack Offset 4100 %} 4101 %} 4102 operand stackSlotL(sRegL reg) 4103 %{ 4104 constraint(ALLOC_IN_RC(stack_slots)); 4105 // No match rule because this operand is only generated in matching 4106 4107 format %{ "[$reg]" %} 4108 interface(MEMORY_INTER) %{ 4109 base(0x4); // RSP 4110 index(0x4); // No Index 4111 scale(0x0); // No Scale 4112 disp($reg); // Stack Offset 4113 %} 4114 %} 4115 4116 //----------Conditional Branch Operands---------------------------------------- 4117 // Comparison Op - This is the operation of the comparison, and is limited to 4118 // the following set of codes: 4119 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4120 // 4121 // Other attributes of the comparison, such as unsignedness, are specified 4122 // by the comparison instruction that sets a condition code flags register. 4123 // That result is represented by a flags operand whose subtype is appropriate 4124 // to the unsignedness (etc.) of the comparison. 4125 // 4126 // Later, the instruction which matches both the Comparison Op (a Bool) and 4127 // the flags (produced by the Cmp) specifies the coding of the comparison op 4128 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4129 4130 // Comparision Code 4131 operand cmpOp() 4132 %{ 4133 match(Bool); 4134 4135 format %{ "" %} 4136 interface(COND_INTER) %{ 4137 equal(0x4, "e"); 4138 not_equal(0x5, "ne"); 4139 less(0xC, "l"); 4140 greater_equal(0xD, "ge"); 4141 less_equal(0xE, "le"); 4142 greater(0xF, "g"); 4143 overflow(0x0, "o"); 4144 no_overflow(0x1, "no"); 4145 %} 4146 %} 4147 4148 // Comparison Code, unsigned compare. Used by FP also, with 4149 // C2 (unordered) turned into GT or LT already. The other bits 4150 // C0 and C3 are turned into Carry & Zero flags. 4151 operand cmpOpU() 4152 %{ 4153 match(Bool); 4154 4155 format %{ "" %} 4156 interface(COND_INTER) %{ 4157 equal(0x4, "e"); 4158 not_equal(0x5, "ne"); 4159 less(0x2, "b"); 4160 greater_equal(0x3, "nb"); 4161 less_equal(0x6, "be"); 4162 greater(0x7, "nbe"); 4163 overflow(0x0, "o"); 4164 no_overflow(0x1, "no"); 4165 %} 4166 %} 4167 4168 4169 // Floating comparisons that don't require any fixup for the unordered case 4170 operand cmpOpUCF() %{ 4171 match(Bool); 4172 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4173 n->as_Bool()->_test._test == BoolTest::ge || 4174 n->as_Bool()->_test._test == BoolTest::le || 4175 n->as_Bool()->_test._test == BoolTest::gt); 4176 format %{ "" %} 4177 interface(COND_INTER) %{ 4178 equal(0x4, "e"); 4179 not_equal(0x5, "ne"); 4180 less(0x2, "b"); 4181 greater_equal(0x3, "nb"); 4182 less_equal(0x6, "be"); 4183 greater(0x7, "nbe"); 4184 overflow(0x0, "o"); 4185 no_overflow(0x1, "no"); 4186 %} 4187 %} 4188 4189 4190 // Floating comparisons that can be fixed up with extra conditional jumps 4191 operand cmpOpUCF2() %{ 4192 match(Bool); 4193 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4194 n->as_Bool()->_test._test == BoolTest::eq); 4195 format %{ "" %} 4196 interface(COND_INTER) %{ 4197 equal(0x4, "e"); 4198 not_equal(0x5, "ne"); 4199 less(0x2, "b"); 4200 greater_equal(0x3, "nb"); 4201 less_equal(0x6, "be"); 4202 greater(0x7, "nbe"); 4203 overflow(0x0, "o"); 4204 no_overflow(0x1, "no"); 4205 %} 4206 %} 4207 4208 // Operands for bound floating pointer register arguments 4209 operand rxmm0() %{ 4210 constraint(ALLOC_IN_RC(xmm0_reg)); match(VecX); 4211 predicate((UseSSE > 0) && (UseAVX<= 2)); format%{%} interface(REG_INTER); 4212 %} 4213 operand rxmm1() %{ 4214 constraint(ALLOC_IN_RC(xmm1_reg)); match(VecX); 4215 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4216 %} 4217 operand rxmm2() %{ 4218 constraint(ALLOC_IN_RC(xmm2_reg)); match(VecX); 4219 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4220 %} 4221 operand rxmm3() %{ 4222 constraint(ALLOC_IN_RC(xmm3_reg)); match(VecX); 4223 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4224 %} 4225 operand rxmm4() %{ 4226 constraint(ALLOC_IN_RC(xmm4_reg)); match(VecX); 4227 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4228 %} 4229 operand rxmm5() %{ 4230 constraint(ALLOC_IN_RC(xmm5_reg)); match(VecX); 4231 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4232 %} 4233 operand rxmm6() %{ 4234 constraint(ALLOC_IN_RC(xmm6_reg)); match(VecX); 4235 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4236 %} 4237 operand rxmm7() %{ 4238 constraint(ALLOC_IN_RC(xmm7_reg)); match(VecX); 4239 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4240 %} 4241 operand rxmm8() %{ 4242 constraint(ALLOC_IN_RC(xmm8_reg)); match(VecX); 4243 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4244 %} 4245 operand rxmm9() %{ 4246 constraint(ALLOC_IN_RC(xmm9_reg)); match(VecX); 4247 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4248 %} 4249 operand rxmm10() %{ 4250 constraint(ALLOC_IN_RC(xmm10_reg)); match(VecX); 4251 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4252 %} 4253 operand rxmm11() %{ 4254 constraint(ALLOC_IN_RC(xmm11_reg)); match(VecX); 4255 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4256 %} 4257 operand rxmm12() %{ 4258 constraint(ALLOC_IN_RC(xmm12_reg)); match(VecX); 4259 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4260 %} 4261 operand rxmm13() %{ 4262 constraint(ALLOC_IN_RC(xmm13_reg)); match(VecX); 4263 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4264 %} 4265 operand rxmm14() %{ 4266 constraint(ALLOC_IN_RC(xmm14_reg)); match(VecX); 4267 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4268 %} 4269 operand rxmm15() %{ 4270 constraint(ALLOC_IN_RC(xmm15_reg)); match(VecX); 4271 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4272 %} 4273 operand rxmm16() %{ 4274 constraint(ALLOC_IN_RC(xmm16_reg)); match(VecX); 4275 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4276 %} 4277 operand rxmm17() %{ 4278 constraint(ALLOC_IN_RC(xmm17_reg)); match(VecX); 4279 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4280 %} 4281 operand rxmm18() %{ 4282 constraint(ALLOC_IN_RC(xmm18_reg)); match(VecX); 4283 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4284 %} 4285 operand rxmm19() %{ 4286 constraint(ALLOC_IN_RC(xmm19_reg)); match(VecX); 4287 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4288 %} 4289 operand rxmm20() %{ 4290 constraint(ALLOC_IN_RC(xmm20_reg)); match(VecX); 4291 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4292 %} 4293 operand rxmm21() %{ 4294 constraint(ALLOC_IN_RC(xmm21_reg)); match(VecX); 4295 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4296 %} 4297 operand rxmm22() %{ 4298 constraint(ALLOC_IN_RC(xmm22_reg)); match(VecX); 4299 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4300 %} 4301 operand rxmm23() %{ 4302 constraint(ALLOC_IN_RC(xmm23_reg)); match(VecX); 4303 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4304 %} 4305 operand rxmm24() %{ 4306 constraint(ALLOC_IN_RC(xmm24_reg)); match(VecX); 4307 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4308 %} 4309 operand rxmm25() %{ 4310 constraint(ALLOC_IN_RC(xmm25_reg)); match(VecX); 4311 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4312 %} 4313 operand rxmm26() %{ 4314 constraint(ALLOC_IN_RC(xmm26_reg)); match(VecX); 4315 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4316 %} 4317 operand rxmm27() %{ 4318 constraint(ALLOC_IN_RC(xmm27_reg)); match(VecX); 4319 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4320 %} 4321 operand rxmm28() %{ 4322 constraint(ALLOC_IN_RC(xmm28_reg)); match(VecX); 4323 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4324 %} 4325 operand rxmm29() %{ 4326 constraint(ALLOC_IN_RC(xmm29_reg)); match(VecX); 4327 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4328 %} 4329 operand rxmm30() %{ 4330 constraint(ALLOC_IN_RC(xmm30_reg)); match(VecX); 4331 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4332 %} 4333 operand rxmm31() %{ 4334 constraint(ALLOC_IN_RC(xmm31_reg)); match(VecX); 4335 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4336 %} 4337 4338 //----------OPERAND CLASSES---------------------------------------------------- 4339 // Operand Classes are groups of operands that are used as to simplify 4340 // instruction definitions by not requiring the AD writer to specify separate 4341 // instructions for every form of operand when the instruction accepts 4342 // multiple operand types with the same basic encoding and format. The classic 4343 // case of this is memory operands. 4344 4345 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4346 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4347 indCompressedOopOffset, 4348 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4349 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4350 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4351 4352 //----------PIPELINE----------------------------------------------------------- 4353 // Rules which define the behavior of the target architectures pipeline. 4354 pipeline %{ 4355 4356 //----------ATTRIBUTES--------------------------------------------------------- 4357 attributes %{ 4358 variable_size_instructions; // Fixed size instructions 4359 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4360 instruction_unit_size = 1; // An instruction is 1 bytes long 4361 instruction_fetch_unit_size = 16; // The processor fetches one line 4362 instruction_fetch_units = 1; // of 16 bytes 4363 4364 // List of nop instructions 4365 nops( MachNop ); 4366 %} 4367 4368 //----------RESOURCES---------------------------------------------------------- 4369 // Resources are the functional units available to the machine 4370 4371 // Generic P2/P3 pipeline 4372 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4373 // 3 instructions decoded per cycle. 4374 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4375 // 3 ALU op, only ALU0 handles mul instructions. 4376 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4377 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4378 BR, FPU, 4379 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4380 4381 //----------PIPELINE DESCRIPTION----------------------------------------------- 4382 // Pipeline Description specifies the stages in the machine's pipeline 4383 4384 // Generic P2/P3 pipeline 4385 pipe_desc(S0, S1, S2, S3, S4, S5); 4386 4387 //----------PIPELINE CLASSES--------------------------------------------------- 4388 // Pipeline Classes describe the stages in which input and output are 4389 // referenced by the hardware pipeline. 4390 4391 // Naming convention: ialu or fpu 4392 // Then: _reg 4393 // Then: _reg if there is a 2nd register 4394 // Then: _long if it's a pair of instructions implementing a long 4395 // Then: _fat if it requires the big decoder 4396 // Or: _mem if it requires the big decoder and a memory unit. 4397 4398 // Integer ALU reg operation 4399 pipe_class ialu_reg(rRegI dst) 4400 %{ 4401 single_instruction; 4402 dst : S4(write); 4403 dst : S3(read); 4404 DECODE : S0; // any decoder 4405 ALU : S3; // any alu 4406 %} 4407 4408 // Long ALU reg operation 4409 pipe_class ialu_reg_long(rRegL dst) 4410 %{ 4411 instruction_count(2); 4412 dst : S4(write); 4413 dst : S3(read); 4414 DECODE : S0(2); // any 2 decoders 4415 ALU : S3(2); // both alus 4416 %} 4417 4418 // Integer ALU reg operation using big decoder 4419 pipe_class ialu_reg_fat(rRegI dst) 4420 %{ 4421 single_instruction; 4422 dst : S4(write); 4423 dst : S3(read); 4424 D0 : S0; // big decoder only 4425 ALU : S3; // any alu 4426 %} 4427 4428 // Long ALU reg operation using big decoder 4429 pipe_class ialu_reg_long_fat(rRegL dst) 4430 %{ 4431 instruction_count(2); 4432 dst : S4(write); 4433 dst : S3(read); 4434 D0 : S0(2); // big decoder only; twice 4435 ALU : S3(2); // any 2 alus 4436 %} 4437 4438 // Integer ALU reg-reg operation 4439 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4440 %{ 4441 single_instruction; 4442 dst : S4(write); 4443 src : S3(read); 4444 DECODE : S0; // any decoder 4445 ALU : S3; // any alu 4446 %} 4447 4448 // Long ALU reg-reg operation 4449 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4450 %{ 4451 instruction_count(2); 4452 dst : S4(write); 4453 src : S3(read); 4454 DECODE : S0(2); // any 2 decoders 4455 ALU : S3(2); // both alus 4456 %} 4457 4458 // Integer ALU reg-reg operation 4459 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4460 %{ 4461 single_instruction; 4462 dst : S4(write); 4463 src : S3(read); 4464 D0 : S0; // big decoder only 4465 ALU : S3; // any alu 4466 %} 4467 4468 // Long ALU reg-reg operation 4469 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4470 %{ 4471 instruction_count(2); 4472 dst : S4(write); 4473 src : S3(read); 4474 D0 : S0(2); // big decoder only; twice 4475 ALU : S3(2); // both alus 4476 %} 4477 4478 // Integer ALU reg-mem operation 4479 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4480 %{ 4481 single_instruction; 4482 dst : S5(write); 4483 mem : S3(read); 4484 D0 : S0; // big decoder only 4485 ALU : S4; // any alu 4486 MEM : S3; // any mem 4487 %} 4488 4489 // Integer mem operation (prefetch) 4490 pipe_class ialu_mem(memory mem) 4491 %{ 4492 single_instruction; 4493 mem : S3(read); 4494 D0 : S0; // big decoder only 4495 MEM : S3; // any mem 4496 %} 4497 4498 // Integer Store to Memory 4499 pipe_class ialu_mem_reg(memory mem, rRegI src) 4500 %{ 4501 single_instruction; 4502 mem : S3(read); 4503 src : S5(read); 4504 D0 : S0; // big decoder only 4505 ALU : S4; // any alu 4506 MEM : S3; 4507 %} 4508 4509 // // Long Store to Memory 4510 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4511 // %{ 4512 // instruction_count(2); 4513 // mem : S3(read); 4514 // src : S5(read); 4515 // D0 : S0(2); // big decoder only; twice 4516 // ALU : S4(2); // any 2 alus 4517 // MEM : S3(2); // Both mems 4518 // %} 4519 4520 // Integer Store to Memory 4521 pipe_class ialu_mem_imm(memory mem) 4522 %{ 4523 single_instruction; 4524 mem : S3(read); 4525 D0 : S0; // big decoder only 4526 ALU : S4; // any alu 4527 MEM : S3; 4528 %} 4529 4530 // Integer ALU0 reg-reg operation 4531 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4532 %{ 4533 single_instruction; 4534 dst : S4(write); 4535 src : S3(read); 4536 D0 : S0; // Big decoder only 4537 ALU0 : S3; // only alu0 4538 %} 4539 4540 // Integer ALU0 reg-mem operation 4541 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4542 %{ 4543 single_instruction; 4544 dst : S5(write); 4545 mem : S3(read); 4546 D0 : S0; // big decoder only 4547 ALU0 : S4; // ALU0 only 4548 MEM : S3; // any mem 4549 %} 4550 4551 // Integer ALU reg-reg operation 4552 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4553 %{ 4554 single_instruction; 4555 cr : S4(write); 4556 src1 : S3(read); 4557 src2 : S3(read); 4558 DECODE : S0; // any decoder 4559 ALU : S3; // any alu 4560 %} 4561 4562 // Integer ALU reg-imm operation 4563 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4564 %{ 4565 single_instruction; 4566 cr : S4(write); 4567 src1 : S3(read); 4568 DECODE : S0; // any decoder 4569 ALU : S3; // any alu 4570 %} 4571 4572 // Integer ALU reg-mem operation 4573 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4574 %{ 4575 single_instruction; 4576 cr : S4(write); 4577 src1 : S3(read); 4578 src2 : S3(read); 4579 D0 : S0; // big decoder only 4580 ALU : S4; // any alu 4581 MEM : S3; 4582 %} 4583 4584 // Conditional move reg-reg 4585 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4586 %{ 4587 instruction_count(4); 4588 y : S4(read); 4589 q : S3(read); 4590 p : S3(read); 4591 DECODE : S0(4); // any decoder 4592 %} 4593 4594 // Conditional move reg-reg 4595 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4596 %{ 4597 single_instruction; 4598 dst : S4(write); 4599 src : S3(read); 4600 cr : S3(read); 4601 DECODE : S0; // any decoder 4602 %} 4603 4604 // Conditional move reg-mem 4605 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4606 %{ 4607 single_instruction; 4608 dst : S4(write); 4609 src : S3(read); 4610 cr : S3(read); 4611 DECODE : S0; // any decoder 4612 MEM : S3; 4613 %} 4614 4615 // Conditional move reg-reg long 4616 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4617 %{ 4618 single_instruction; 4619 dst : S4(write); 4620 src : S3(read); 4621 cr : S3(read); 4622 DECODE : S0(2); // any 2 decoders 4623 %} 4624 4625 // XXX 4626 // // Conditional move double reg-reg 4627 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4628 // %{ 4629 // single_instruction; 4630 // dst : S4(write); 4631 // src : S3(read); 4632 // cr : S3(read); 4633 // DECODE : S0; // any decoder 4634 // %} 4635 4636 // Float reg-reg operation 4637 pipe_class fpu_reg(regD dst) 4638 %{ 4639 instruction_count(2); 4640 dst : S3(read); 4641 DECODE : S0(2); // any 2 decoders 4642 FPU : S3; 4643 %} 4644 4645 // Float reg-reg operation 4646 pipe_class fpu_reg_reg(regD dst, regD src) 4647 %{ 4648 instruction_count(2); 4649 dst : S4(write); 4650 src : S3(read); 4651 DECODE : S0(2); // any 2 decoders 4652 FPU : S3; 4653 %} 4654 4655 // Float reg-reg operation 4656 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4657 %{ 4658 instruction_count(3); 4659 dst : S4(write); 4660 src1 : S3(read); 4661 src2 : S3(read); 4662 DECODE : S0(3); // any 3 decoders 4663 FPU : S3(2); 4664 %} 4665 4666 // Float reg-reg operation 4667 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4668 %{ 4669 instruction_count(4); 4670 dst : S4(write); 4671 src1 : S3(read); 4672 src2 : S3(read); 4673 src3 : S3(read); 4674 DECODE : S0(4); // any 3 decoders 4675 FPU : S3(2); 4676 %} 4677 4678 // Float reg-reg operation 4679 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4680 %{ 4681 instruction_count(4); 4682 dst : S4(write); 4683 src1 : S3(read); 4684 src2 : S3(read); 4685 src3 : S3(read); 4686 DECODE : S1(3); // any 3 decoders 4687 D0 : S0; // Big decoder only 4688 FPU : S3(2); 4689 MEM : S3; 4690 %} 4691 4692 // Float reg-mem operation 4693 pipe_class fpu_reg_mem(regD dst, memory mem) 4694 %{ 4695 instruction_count(2); 4696 dst : S5(write); 4697 mem : S3(read); 4698 D0 : S0; // big decoder only 4699 DECODE : S1; // any decoder for FPU POP 4700 FPU : S4; 4701 MEM : S3; // any mem 4702 %} 4703 4704 // Float reg-mem operation 4705 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4706 %{ 4707 instruction_count(3); 4708 dst : S5(write); 4709 src1 : S3(read); 4710 mem : S3(read); 4711 D0 : S0; // big decoder only 4712 DECODE : S1(2); // any decoder for FPU POP 4713 FPU : S4; 4714 MEM : S3; // any mem 4715 %} 4716 4717 // Float mem-reg operation 4718 pipe_class fpu_mem_reg(memory mem, regD src) 4719 %{ 4720 instruction_count(2); 4721 src : S5(read); 4722 mem : S3(read); 4723 DECODE : S0; // any decoder for FPU PUSH 4724 D0 : S1; // big decoder only 4725 FPU : S4; 4726 MEM : S3; // any mem 4727 %} 4728 4729 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4730 %{ 4731 instruction_count(3); 4732 src1 : S3(read); 4733 src2 : S3(read); 4734 mem : S3(read); 4735 DECODE : S0(2); // any decoder for FPU PUSH 4736 D0 : S1; // big decoder only 4737 FPU : S4; 4738 MEM : S3; // any mem 4739 %} 4740 4741 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4742 %{ 4743 instruction_count(3); 4744 src1 : S3(read); 4745 src2 : S3(read); 4746 mem : S4(read); 4747 DECODE : S0; // any decoder for FPU PUSH 4748 D0 : S0(2); // big decoder only 4749 FPU : S4; 4750 MEM : S3(2); // any mem 4751 %} 4752 4753 pipe_class fpu_mem_mem(memory dst, memory src1) 4754 %{ 4755 instruction_count(2); 4756 src1 : S3(read); 4757 dst : S4(read); 4758 D0 : S0(2); // big decoder only 4759 MEM : S3(2); // any mem 4760 %} 4761 4762 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4763 %{ 4764 instruction_count(3); 4765 src1 : S3(read); 4766 src2 : S3(read); 4767 dst : S4(read); 4768 D0 : S0(3); // big decoder only 4769 FPU : S4; 4770 MEM : S3(3); // any mem 4771 %} 4772 4773 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4774 %{ 4775 instruction_count(3); 4776 src1 : S4(read); 4777 mem : S4(read); 4778 DECODE : S0; // any decoder for FPU PUSH 4779 D0 : S0(2); // big decoder only 4780 FPU : S4; 4781 MEM : S3(2); // any mem 4782 %} 4783 4784 // Float load constant 4785 pipe_class fpu_reg_con(regD dst) 4786 %{ 4787 instruction_count(2); 4788 dst : S5(write); 4789 D0 : S0; // big decoder only for the load 4790 DECODE : S1; // any decoder for FPU POP 4791 FPU : S4; 4792 MEM : S3; // any mem 4793 %} 4794 4795 // Float load constant 4796 pipe_class fpu_reg_reg_con(regD dst, regD src) 4797 %{ 4798 instruction_count(3); 4799 dst : S5(write); 4800 src : S3(read); 4801 D0 : S0; // big decoder only for the load 4802 DECODE : S1(2); // any decoder for FPU POP 4803 FPU : S4; 4804 MEM : S3; // any mem 4805 %} 4806 4807 // UnConditional branch 4808 pipe_class pipe_jmp(label labl) 4809 %{ 4810 single_instruction; 4811 BR : S3; 4812 %} 4813 4814 // Conditional branch 4815 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4816 %{ 4817 single_instruction; 4818 cr : S1(read); 4819 BR : S3; 4820 %} 4821 4822 // Allocation idiom 4823 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4824 %{ 4825 instruction_count(1); force_serialization; 4826 fixed_latency(6); 4827 heap_ptr : S3(read); 4828 DECODE : S0(3); 4829 D0 : S2; 4830 MEM : S3; 4831 ALU : S3(2); 4832 dst : S5(write); 4833 BR : S5; 4834 %} 4835 4836 // Generic big/slow expanded idiom 4837 pipe_class pipe_slow() 4838 %{ 4839 instruction_count(10); multiple_bundles; force_serialization; 4840 fixed_latency(100); 4841 D0 : S0(2); 4842 MEM : S3(2); 4843 %} 4844 4845 // The real do-nothing guy 4846 pipe_class empty() 4847 %{ 4848 instruction_count(0); 4849 %} 4850 4851 // Define the class for the Nop node 4852 define 4853 %{ 4854 MachNop = empty; 4855 %} 4856 4857 %} 4858 4859 //----------INSTRUCTIONS------------------------------------------------------- 4860 // 4861 // match -- States which machine-independent subtree may be replaced 4862 // by this instruction. 4863 // ins_cost -- The estimated cost of this instruction is used by instruction 4864 // selection to identify a minimum cost tree of machine 4865 // instructions that matches a tree of machine-independent 4866 // instructions. 4867 // format -- A string providing the disassembly for this instruction. 4868 // The value of an instruction's operand may be inserted 4869 // by referring to it with a '$' prefix. 4870 // opcode -- Three instruction opcodes may be provided. These are referred 4871 // to within an encode class as $primary, $secondary, and $tertiary 4872 // rrspectively. The primary opcode is commonly used to 4873 // indicate the type of machine instruction, while secondary 4874 // and tertiary are often used for prefix options or addressing 4875 // modes. 4876 // ins_encode -- A list of encode classes with parameters. The encode class 4877 // name must have been defined in an 'enc_class' specification 4878 // in the encode section of the architecture description. 4879 4880 4881 //----------Load/Store/Move Instructions--------------------------------------- 4882 //----------Load Instructions-------------------------------------------------- 4883 4884 // Load Byte (8 bit signed) 4885 instruct loadB(rRegI dst, memory mem) 4886 %{ 4887 match(Set dst (LoadB mem)); 4888 4889 ins_cost(125); 4890 format %{ "movsbl $dst, $mem\t# byte" %} 4891 4892 ins_encode %{ 4893 __ movsbl($dst$$Register, $mem$$Address); 4894 %} 4895 4896 ins_pipe(ialu_reg_mem); 4897 %} 4898 4899 // Load Byte (8 bit signed) into Long Register 4900 instruct loadB2L(rRegL dst, memory mem) 4901 %{ 4902 match(Set dst (ConvI2L (LoadB mem))); 4903 4904 ins_cost(125); 4905 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4906 4907 ins_encode %{ 4908 __ movsbq($dst$$Register, $mem$$Address); 4909 %} 4910 4911 ins_pipe(ialu_reg_mem); 4912 %} 4913 4914 // Load Unsigned Byte (8 bit UNsigned) 4915 instruct loadUB(rRegI dst, memory mem) 4916 %{ 4917 match(Set dst (LoadUB mem)); 4918 4919 ins_cost(125); 4920 format %{ "movzbl $dst, $mem\t# ubyte" %} 4921 4922 ins_encode %{ 4923 __ movzbl($dst$$Register, $mem$$Address); 4924 %} 4925 4926 ins_pipe(ialu_reg_mem); 4927 %} 4928 4929 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4930 instruct loadUB2L(rRegL dst, memory mem) 4931 %{ 4932 match(Set dst (ConvI2L (LoadUB mem))); 4933 4934 ins_cost(125); 4935 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4936 4937 ins_encode %{ 4938 __ movzbq($dst$$Register, $mem$$Address); 4939 %} 4940 4941 ins_pipe(ialu_reg_mem); 4942 %} 4943 4944 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4945 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4946 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4947 effect(KILL cr); 4948 4949 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4950 "andl $dst, right_n_bits($mask, 8)" %} 4951 ins_encode %{ 4952 Register Rdst = $dst$$Register; 4953 __ movzbq(Rdst, $mem$$Address); 4954 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4955 %} 4956 ins_pipe(ialu_reg_mem); 4957 %} 4958 4959 // Load Short (16 bit signed) 4960 instruct loadS(rRegI dst, memory mem) 4961 %{ 4962 match(Set dst (LoadS mem)); 4963 4964 ins_cost(125); 4965 format %{ "movswl $dst, $mem\t# short" %} 4966 4967 ins_encode %{ 4968 __ movswl($dst$$Register, $mem$$Address); 4969 %} 4970 4971 ins_pipe(ialu_reg_mem); 4972 %} 4973 4974 // Load Short (16 bit signed) to Byte (8 bit signed) 4975 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4976 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4977 4978 ins_cost(125); 4979 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4980 ins_encode %{ 4981 __ movsbl($dst$$Register, $mem$$Address); 4982 %} 4983 ins_pipe(ialu_reg_mem); 4984 %} 4985 4986 // Load Short (16 bit signed) into Long Register 4987 instruct loadS2L(rRegL dst, memory mem) 4988 %{ 4989 match(Set dst (ConvI2L (LoadS mem))); 4990 4991 ins_cost(125); 4992 format %{ "movswq $dst, $mem\t# short -> long" %} 4993 4994 ins_encode %{ 4995 __ movswq($dst$$Register, $mem$$Address); 4996 %} 4997 4998 ins_pipe(ialu_reg_mem); 4999 %} 5000 5001 // Load Unsigned Short/Char (16 bit UNsigned) 5002 instruct loadUS(rRegI dst, memory mem) 5003 %{ 5004 match(Set dst (LoadUS mem)); 5005 5006 ins_cost(125); 5007 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5008 5009 ins_encode %{ 5010 __ movzwl($dst$$Register, $mem$$Address); 5011 %} 5012 5013 ins_pipe(ialu_reg_mem); 5014 %} 5015 5016 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5017 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5018 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5019 5020 ins_cost(125); 5021 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5022 ins_encode %{ 5023 __ movsbl($dst$$Register, $mem$$Address); 5024 %} 5025 ins_pipe(ialu_reg_mem); 5026 %} 5027 5028 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5029 instruct loadUS2L(rRegL dst, memory mem) 5030 %{ 5031 match(Set dst (ConvI2L (LoadUS mem))); 5032 5033 ins_cost(125); 5034 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5035 5036 ins_encode %{ 5037 __ movzwq($dst$$Register, $mem$$Address); 5038 %} 5039 5040 ins_pipe(ialu_reg_mem); 5041 %} 5042 5043 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5044 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5045 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5046 5047 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5048 ins_encode %{ 5049 __ movzbq($dst$$Register, $mem$$Address); 5050 %} 5051 ins_pipe(ialu_reg_mem); 5052 %} 5053 5054 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 5055 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5056 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5057 effect(KILL cr); 5058 5059 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 5060 "andl $dst, right_n_bits($mask, 16)" %} 5061 ins_encode %{ 5062 Register Rdst = $dst$$Register; 5063 __ movzwq(Rdst, $mem$$Address); 5064 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 5065 %} 5066 ins_pipe(ialu_reg_mem); 5067 %} 5068 5069 // Load Integer 5070 instruct loadI(rRegI dst, memory mem) 5071 %{ 5072 match(Set dst (LoadI mem)); 5073 5074 ins_cost(125); 5075 format %{ "movl $dst, $mem\t# int" %} 5076 5077 ins_encode %{ 5078 __ movl($dst$$Register, $mem$$Address); 5079 %} 5080 5081 ins_pipe(ialu_reg_mem); 5082 %} 5083 5084 // Load Integer (32 bit signed) to Byte (8 bit signed) 5085 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5086 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5087 5088 ins_cost(125); 5089 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5090 ins_encode %{ 5091 __ movsbl($dst$$Register, $mem$$Address); 5092 %} 5093 ins_pipe(ialu_reg_mem); 5094 %} 5095 5096 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5097 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5098 match(Set dst (AndI (LoadI mem) mask)); 5099 5100 ins_cost(125); 5101 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5102 ins_encode %{ 5103 __ movzbl($dst$$Register, $mem$$Address); 5104 %} 5105 ins_pipe(ialu_reg_mem); 5106 %} 5107 5108 // Load Integer (32 bit signed) to Short (16 bit signed) 5109 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5110 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5111 5112 ins_cost(125); 5113 format %{ "movswl $dst, $mem\t# int -> short" %} 5114 ins_encode %{ 5115 __ movswl($dst$$Register, $mem$$Address); 5116 %} 5117 ins_pipe(ialu_reg_mem); 5118 %} 5119 5120 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5121 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5122 match(Set dst (AndI (LoadI mem) mask)); 5123 5124 ins_cost(125); 5125 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5126 ins_encode %{ 5127 __ movzwl($dst$$Register, $mem$$Address); 5128 %} 5129 ins_pipe(ialu_reg_mem); 5130 %} 5131 5132 // Load Integer into Long Register 5133 instruct loadI2L(rRegL dst, memory mem) 5134 %{ 5135 match(Set dst (ConvI2L (LoadI mem))); 5136 5137 ins_cost(125); 5138 format %{ "movslq $dst, $mem\t# int -> long" %} 5139 5140 ins_encode %{ 5141 __ movslq($dst$$Register, $mem$$Address); 5142 %} 5143 5144 ins_pipe(ialu_reg_mem); 5145 %} 5146 5147 // Load Integer with mask 0xFF into Long Register 5148 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5149 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5150 5151 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5152 ins_encode %{ 5153 __ movzbq($dst$$Register, $mem$$Address); 5154 %} 5155 ins_pipe(ialu_reg_mem); 5156 %} 5157 5158 // Load Integer with mask 0xFFFF into Long Register 5159 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5160 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5161 5162 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5163 ins_encode %{ 5164 __ movzwq($dst$$Register, $mem$$Address); 5165 %} 5166 ins_pipe(ialu_reg_mem); 5167 %} 5168 5169 // Load Integer with a 31-bit mask into Long Register 5170 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5171 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5172 effect(KILL cr); 5173 5174 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5175 "andl $dst, $mask" %} 5176 ins_encode %{ 5177 Register Rdst = $dst$$Register; 5178 __ movl(Rdst, $mem$$Address); 5179 __ andl(Rdst, $mask$$constant); 5180 %} 5181 ins_pipe(ialu_reg_mem); 5182 %} 5183 5184 // Load Unsigned Integer into Long Register 5185 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5186 %{ 5187 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5188 5189 ins_cost(125); 5190 format %{ "movl $dst, $mem\t# uint -> long" %} 5191 5192 ins_encode %{ 5193 __ movl($dst$$Register, $mem$$Address); 5194 %} 5195 5196 ins_pipe(ialu_reg_mem); 5197 %} 5198 5199 // Load Long 5200 instruct loadL(rRegL dst, memory mem) 5201 %{ 5202 match(Set dst (LoadL mem)); 5203 5204 ins_cost(125); 5205 format %{ "movq $dst, $mem\t# long" %} 5206 5207 ins_encode %{ 5208 __ movq($dst$$Register, $mem$$Address); 5209 %} 5210 5211 ins_pipe(ialu_reg_mem); // XXX 5212 %} 5213 5214 // Load Range 5215 instruct loadRange(rRegI dst, memory mem) 5216 %{ 5217 match(Set dst (LoadRange mem)); 5218 5219 ins_cost(125); // XXX 5220 format %{ "movl $dst, $mem\t# range" %} 5221 opcode(0x8B); 5222 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5223 ins_pipe(ialu_reg_mem); 5224 %} 5225 5226 // Load Pointer 5227 instruct loadP(rRegP dst, memory mem) 5228 %{ 5229 match(Set dst (LoadP mem)); 5230 5231 ins_cost(125); // XXX 5232 format %{ "movq $dst, $mem\t# ptr" %} 5233 opcode(0x8B); 5234 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5235 ins_pipe(ialu_reg_mem); // XXX 5236 %} 5237 5238 // Load Compressed Pointer 5239 instruct loadN(rRegN dst, memory mem) 5240 %{ 5241 match(Set dst (LoadN mem)); 5242 5243 ins_cost(125); // XXX 5244 format %{ "movl $dst, $mem\t# compressed ptr" %} 5245 ins_encode %{ 5246 __ movl($dst$$Register, $mem$$Address); 5247 %} 5248 ins_pipe(ialu_reg_mem); // XXX 5249 %} 5250 5251 5252 // Load Klass Pointer 5253 instruct loadKlass(rRegP dst, memory mem) 5254 %{ 5255 match(Set dst (LoadKlass mem)); 5256 5257 ins_cost(125); // XXX 5258 format %{ "movq $dst, $mem\t# class" %} 5259 opcode(0x8B); 5260 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5261 ins_pipe(ialu_reg_mem); // XXX 5262 %} 5263 5264 // Load narrow Klass Pointer 5265 instruct loadNKlass(rRegN dst, memory mem) 5266 %{ 5267 match(Set dst (LoadNKlass mem)); 5268 5269 ins_cost(125); // XXX 5270 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5271 ins_encode %{ 5272 __ movl($dst$$Register, $mem$$Address); 5273 %} 5274 ins_pipe(ialu_reg_mem); // XXX 5275 %} 5276 5277 // Load Float 5278 instruct loadF(regF dst, memory mem) 5279 %{ 5280 match(Set dst (LoadF mem)); 5281 5282 ins_cost(145); // XXX 5283 format %{ "movss $dst, $mem\t# float" %} 5284 ins_encode %{ 5285 __ movflt($dst$$XMMRegister, $mem$$Address); 5286 %} 5287 ins_pipe(pipe_slow); // XXX 5288 %} 5289 5290 // Load Double 5291 instruct loadD_partial(regD dst, memory mem) 5292 %{ 5293 predicate(!UseXmmLoadAndClearUpper); 5294 match(Set dst (LoadD mem)); 5295 5296 ins_cost(145); // XXX 5297 format %{ "movlpd $dst, $mem\t# double" %} 5298 ins_encode %{ 5299 __ movdbl($dst$$XMMRegister, $mem$$Address); 5300 %} 5301 ins_pipe(pipe_slow); // XXX 5302 %} 5303 5304 instruct loadD(regD dst, memory mem) 5305 %{ 5306 predicate(UseXmmLoadAndClearUpper); 5307 match(Set dst (LoadD mem)); 5308 5309 ins_cost(145); // XXX 5310 format %{ "movsd $dst, $mem\t# double" %} 5311 ins_encode %{ 5312 __ movdbl($dst$$XMMRegister, $mem$$Address); 5313 %} 5314 ins_pipe(pipe_slow); // XXX 5315 %} 5316 5317 // Load Effective Address 5318 instruct leaP8(rRegP dst, indOffset8 mem) 5319 %{ 5320 match(Set dst mem); 5321 5322 ins_cost(110); // XXX 5323 format %{ "leaq $dst, $mem\t# ptr 8" %} 5324 opcode(0x8D); 5325 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5326 ins_pipe(ialu_reg_reg_fat); 5327 %} 5328 5329 instruct leaP32(rRegP dst, indOffset32 mem) 5330 %{ 5331 match(Set dst mem); 5332 5333 ins_cost(110); 5334 format %{ "leaq $dst, $mem\t# ptr 32" %} 5335 opcode(0x8D); 5336 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5337 ins_pipe(ialu_reg_reg_fat); 5338 %} 5339 5340 // instruct leaPIdx(rRegP dst, indIndex mem) 5341 // %{ 5342 // match(Set dst mem); 5343 5344 // ins_cost(110); 5345 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5346 // opcode(0x8D); 5347 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5348 // ins_pipe(ialu_reg_reg_fat); 5349 // %} 5350 5351 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5352 %{ 5353 match(Set dst mem); 5354 5355 ins_cost(110); 5356 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5357 opcode(0x8D); 5358 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5359 ins_pipe(ialu_reg_reg_fat); 5360 %} 5361 5362 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5363 %{ 5364 match(Set dst mem); 5365 5366 ins_cost(110); 5367 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5368 opcode(0x8D); 5369 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5370 ins_pipe(ialu_reg_reg_fat); 5371 %} 5372 5373 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5374 %{ 5375 match(Set dst mem); 5376 5377 ins_cost(110); 5378 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5379 opcode(0x8D); 5380 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5381 ins_pipe(ialu_reg_reg_fat); 5382 %} 5383 5384 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5385 %{ 5386 match(Set dst mem); 5387 5388 ins_cost(110); 5389 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5390 opcode(0x8D); 5391 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5392 ins_pipe(ialu_reg_reg_fat); 5393 %} 5394 5395 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5396 %{ 5397 match(Set dst mem); 5398 5399 ins_cost(110); 5400 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5401 opcode(0x8D); 5402 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5403 ins_pipe(ialu_reg_reg_fat); 5404 %} 5405 5406 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5407 %{ 5408 match(Set dst mem); 5409 5410 ins_cost(110); 5411 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5412 opcode(0x8D); 5413 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5414 ins_pipe(ialu_reg_reg_fat); 5415 %} 5416 5417 // Load Effective Address which uses Narrow (32-bits) oop 5418 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5419 %{ 5420 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5421 match(Set dst mem); 5422 5423 ins_cost(110); 5424 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5425 opcode(0x8D); 5426 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5427 ins_pipe(ialu_reg_reg_fat); 5428 %} 5429 5430 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5431 %{ 5432 predicate(Universe::narrow_oop_shift() == 0); 5433 match(Set dst mem); 5434 5435 ins_cost(110); // XXX 5436 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5437 opcode(0x8D); 5438 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5439 ins_pipe(ialu_reg_reg_fat); 5440 %} 5441 5442 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5443 %{ 5444 predicate(Universe::narrow_oop_shift() == 0); 5445 match(Set dst mem); 5446 5447 ins_cost(110); 5448 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5449 opcode(0x8D); 5450 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5451 ins_pipe(ialu_reg_reg_fat); 5452 %} 5453 5454 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5455 %{ 5456 predicate(Universe::narrow_oop_shift() == 0); 5457 match(Set dst mem); 5458 5459 ins_cost(110); 5460 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5461 opcode(0x8D); 5462 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5463 ins_pipe(ialu_reg_reg_fat); 5464 %} 5465 5466 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5467 %{ 5468 predicate(Universe::narrow_oop_shift() == 0); 5469 match(Set dst mem); 5470 5471 ins_cost(110); 5472 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5473 opcode(0x8D); 5474 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5475 ins_pipe(ialu_reg_reg_fat); 5476 %} 5477 5478 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5479 %{ 5480 predicate(Universe::narrow_oop_shift() == 0); 5481 match(Set dst mem); 5482 5483 ins_cost(110); 5484 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5485 opcode(0x8D); 5486 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5487 ins_pipe(ialu_reg_reg_fat); 5488 %} 5489 5490 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5491 %{ 5492 predicate(Universe::narrow_oop_shift() == 0); 5493 match(Set dst mem); 5494 5495 ins_cost(110); 5496 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5497 opcode(0x8D); 5498 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5499 ins_pipe(ialu_reg_reg_fat); 5500 %} 5501 5502 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5503 %{ 5504 predicate(Universe::narrow_oop_shift() == 0); 5505 match(Set dst mem); 5506 5507 ins_cost(110); 5508 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5509 opcode(0x8D); 5510 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5511 ins_pipe(ialu_reg_reg_fat); 5512 %} 5513 5514 instruct loadConI(rRegI dst, immI src) 5515 %{ 5516 match(Set dst src); 5517 5518 format %{ "movl $dst, $src\t# int" %} 5519 ins_encode(load_immI(dst, src)); 5520 ins_pipe(ialu_reg_fat); // XXX 5521 %} 5522 5523 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5524 %{ 5525 match(Set dst src); 5526 effect(KILL cr); 5527 5528 ins_cost(50); 5529 format %{ "xorl $dst, $dst\t# int" %} 5530 opcode(0x33); /* + rd */ 5531 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5532 ins_pipe(ialu_reg); 5533 %} 5534 5535 instruct loadConL(rRegL dst, immL src) 5536 %{ 5537 match(Set dst src); 5538 5539 ins_cost(150); 5540 format %{ "movq $dst, $src\t# long" %} 5541 ins_encode(load_immL(dst, src)); 5542 ins_pipe(ialu_reg); 5543 %} 5544 5545 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5546 %{ 5547 match(Set dst src); 5548 effect(KILL cr); 5549 5550 ins_cost(50); 5551 format %{ "xorl $dst, $dst\t# long" %} 5552 opcode(0x33); /* + rd */ 5553 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5554 ins_pipe(ialu_reg); // XXX 5555 %} 5556 5557 instruct loadConUL32(rRegL dst, immUL32 src) 5558 %{ 5559 match(Set dst src); 5560 5561 ins_cost(60); 5562 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5563 ins_encode(load_immUL32(dst, src)); 5564 ins_pipe(ialu_reg); 5565 %} 5566 5567 instruct loadConL32(rRegL dst, immL32 src) 5568 %{ 5569 match(Set dst src); 5570 5571 ins_cost(70); 5572 format %{ "movq $dst, $src\t# long (32-bit)" %} 5573 ins_encode(load_immL32(dst, src)); 5574 ins_pipe(ialu_reg); 5575 %} 5576 5577 instruct loadConP(rRegP dst, immP con) %{ 5578 match(Set dst con); 5579 5580 format %{ "movq $dst, $con\t# ptr" %} 5581 ins_encode(load_immP(dst, con)); 5582 ins_pipe(ialu_reg_fat); // XXX 5583 %} 5584 5585 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5586 %{ 5587 match(Set dst src); 5588 effect(KILL cr); 5589 5590 ins_cost(50); 5591 format %{ "xorl $dst, $dst\t# ptr" %} 5592 opcode(0x33); /* + rd */ 5593 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5594 ins_pipe(ialu_reg); 5595 %} 5596 5597 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5598 %{ 5599 match(Set dst src); 5600 effect(KILL cr); 5601 5602 ins_cost(60); 5603 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5604 ins_encode(load_immP31(dst, src)); 5605 ins_pipe(ialu_reg); 5606 %} 5607 5608 instruct loadConF(regF dst, immF con) %{ 5609 match(Set dst con); 5610 ins_cost(125); 5611 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5612 ins_encode %{ 5613 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5614 %} 5615 ins_pipe(pipe_slow); 5616 %} 5617 5618 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5619 match(Set dst src); 5620 effect(KILL cr); 5621 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5622 ins_encode %{ 5623 __ xorq($dst$$Register, $dst$$Register); 5624 %} 5625 ins_pipe(ialu_reg); 5626 %} 5627 5628 instruct loadConN(rRegN dst, immN src) %{ 5629 match(Set dst src); 5630 5631 ins_cost(125); 5632 format %{ "movl $dst, $src\t# compressed ptr" %} 5633 ins_encode %{ 5634 address con = (address)$src$$constant; 5635 if (con == NULL) { 5636 ShouldNotReachHere(); 5637 } else { 5638 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5639 } 5640 %} 5641 ins_pipe(ialu_reg_fat); // XXX 5642 %} 5643 5644 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5645 match(Set dst src); 5646 5647 ins_cost(125); 5648 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5649 ins_encode %{ 5650 address con = (address)$src$$constant; 5651 if (con == NULL) { 5652 ShouldNotReachHere(); 5653 } else { 5654 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5655 } 5656 %} 5657 ins_pipe(ialu_reg_fat); // XXX 5658 %} 5659 5660 instruct loadConF0(regF dst, immF0 src) 5661 %{ 5662 match(Set dst src); 5663 ins_cost(100); 5664 5665 format %{ "xorps $dst, $dst\t# float 0.0" %} 5666 ins_encode %{ 5667 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5668 %} 5669 ins_pipe(pipe_slow); 5670 %} 5671 5672 // Use the same format since predicate() can not be used here. 5673 instruct loadConD(regD dst, immD con) %{ 5674 match(Set dst con); 5675 ins_cost(125); 5676 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5677 ins_encode %{ 5678 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5679 %} 5680 ins_pipe(pipe_slow); 5681 %} 5682 5683 instruct loadConD0(regD dst, immD0 src) 5684 %{ 5685 match(Set dst src); 5686 ins_cost(100); 5687 5688 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5689 ins_encode %{ 5690 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5691 %} 5692 ins_pipe(pipe_slow); 5693 %} 5694 5695 instruct loadSSI(rRegI dst, stackSlotI src) 5696 %{ 5697 match(Set dst src); 5698 5699 ins_cost(125); 5700 format %{ "movl $dst, $src\t# int stk" %} 5701 opcode(0x8B); 5702 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5703 ins_pipe(ialu_reg_mem); 5704 %} 5705 5706 instruct loadSSL(rRegL dst, stackSlotL src) 5707 %{ 5708 match(Set dst src); 5709 5710 ins_cost(125); 5711 format %{ "movq $dst, $src\t# long stk" %} 5712 opcode(0x8B); 5713 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5714 ins_pipe(ialu_reg_mem); 5715 %} 5716 5717 instruct loadSSP(rRegP dst, stackSlotP src) 5718 %{ 5719 match(Set dst src); 5720 5721 ins_cost(125); 5722 format %{ "movq $dst, $src\t# ptr stk" %} 5723 opcode(0x8B); 5724 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5725 ins_pipe(ialu_reg_mem); 5726 %} 5727 5728 instruct loadSSF(regF dst, stackSlotF src) 5729 %{ 5730 match(Set dst src); 5731 5732 ins_cost(125); 5733 format %{ "movss $dst, $src\t# float stk" %} 5734 ins_encode %{ 5735 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5736 %} 5737 ins_pipe(pipe_slow); // XXX 5738 %} 5739 5740 // Use the same format since predicate() can not be used here. 5741 instruct loadSSD(regD dst, stackSlotD src) 5742 %{ 5743 match(Set dst src); 5744 5745 ins_cost(125); 5746 format %{ "movsd $dst, $src\t# double stk" %} 5747 ins_encode %{ 5748 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5749 %} 5750 ins_pipe(pipe_slow); // XXX 5751 %} 5752 5753 // Prefetch instructions for allocation. 5754 // Must be safe to execute with invalid address (cannot fault). 5755 5756 instruct prefetchAlloc( memory mem ) %{ 5757 predicate(AllocatePrefetchInstr==3); 5758 match(PrefetchAllocation mem); 5759 ins_cost(125); 5760 5761 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5762 ins_encode %{ 5763 __ prefetchw($mem$$Address); 5764 %} 5765 ins_pipe(ialu_mem); 5766 %} 5767 5768 instruct prefetchAllocNTA( memory mem ) %{ 5769 predicate(AllocatePrefetchInstr==0); 5770 match(PrefetchAllocation mem); 5771 ins_cost(125); 5772 5773 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5774 ins_encode %{ 5775 __ prefetchnta($mem$$Address); 5776 %} 5777 ins_pipe(ialu_mem); 5778 %} 5779 5780 instruct prefetchAllocT0( memory mem ) %{ 5781 predicate(AllocatePrefetchInstr==1); 5782 match(PrefetchAllocation mem); 5783 ins_cost(125); 5784 5785 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5786 ins_encode %{ 5787 __ prefetcht0($mem$$Address); 5788 %} 5789 ins_pipe(ialu_mem); 5790 %} 5791 5792 instruct prefetchAllocT2( memory mem ) %{ 5793 predicate(AllocatePrefetchInstr==2); 5794 match(PrefetchAllocation mem); 5795 ins_cost(125); 5796 5797 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5798 ins_encode %{ 5799 __ prefetcht2($mem$$Address); 5800 %} 5801 ins_pipe(ialu_mem); 5802 %} 5803 5804 //----------Store Instructions------------------------------------------------- 5805 5806 // Store Byte 5807 instruct storeB(memory mem, rRegI src) 5808 %{ 5809 match(Set mem (StoreB mem src)); 5810 5811 ins_cost(125); // XXX 5812 format %{ "movb $mem, $src\t# byte" %} 5813 opcode(0x88); 5814 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5815 ins_pipe(ialu_mem_reg); 5816 %} 5817 5818 // Store Char/Short 5819 instruct storeC(memory mem, rRegI src) 5820 %{ 5821 match(Set mem (StoreC mem src)); 5822 5823 ins_cost(125); // XXX 5824 format %{ "movw $mem, $src\t# char/short" %} 5825 opcode(0x89); 5826 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5827 ins_pipe(ialu_mem_reg); 5828 %} 5829 5830 // Store Integer 5831 instruct storeI(memory mem, rRegI src) 5832 %{ 5833 match(Set mem (StoreI mem src)); 5834 5835 ins_cost(125); // XXX 5836 format %{ "movl $mem, $src\t# int" %} 5837 opcode(0x89); 5838 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5839 ins_pipe(ialu_mem_reg); 5840 %} 5841 5842 // Store Long 5843 instruct storeL(memory mem, rRegL src) 5844 %{ 5845 match(Set mem (StoreL mem src)); 5846 5847 ins_cost(125); // XXX 5848 format %{ "movq $mem, $src\t# long" %} 5849 opcode(0x89); 5850 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5851 ins_pipe(ialu_mem_reg); // XXX 5852 %} 5853 5854 // Store Pointer 5855 instruct storeP(memory mem, any_RegP src) 5856 %{ 5857 match(Set mem (StoreP mem src)); 5858 5859 ins_cost(125); // XXX 5860 format %{ "movq $mem, $src\t# ptr" %} 5861 opcode(0x89); 5862 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5863 ins_pipe(ialu_mem_reg); 5864 %} 5865 5866 instruct storeImmP0(memory mem, immP0 zero) 5867 %{ 5868 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5869 match(Set mem (StoreP mem zero)); 5870 5871 ins_cost(125); // XXX 5872 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5873 ins_encode %{ 5874 __ movq($mem$$Address, r12); 5875 %} 5876 ins_pipe(ialu_mem_reg); 5877 %} 5878 5879 // Store NULL Pointer, mark word, or other simple pointer constant. 5880 instruct storeImmP(memory mem, immP31 src) 5881 %{ 5882 match(Set mem (StoreP mem src)); 5883 5884 ins_cost(150); // XXX 5885 format %{ "movq $mem, $src\t# ptr" %} 5886 opcode(0xC7); /* C7 /0 */ 5887 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5888 ins_pipe(ialu_mem_imm); 5889 %} 5890 5891 // Store Compressed Pointer 5892 instruct storeN(memory mem, rRegN src) 5893 %{ 5894 match(Set mem (StoreN mem src)); 5895 5896 ins_cost(125); // XXX 5897 format %{ "movl $mem, $src\t# compressed ptr" %} 5898 ins_encode %{ 5899 __ movl($mem$$Address, $src$$Register); 5900 %} 5901 ins_pipe(ialu_mem_reg); 5902 %} 5903 5904 instruct storeNKlass(memory mem, rRegN src) 5905 %{ 5906 match(Set mem (StoreNKlass mem src)); 5907 5908 ins_cost(125); // XXX 5909 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5910 ins_encode %{ 5911 __ movl($mem$$Address, $src$$Register); 5912 %} 5913 ins_pipe(ialu_mem_reg); 5914 %} 5915 5916 instruct storeImmN0(memory mem, immN0 zero) 5917 %{ 5918 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5919 match(Set mem (StoreN mem zero)); 5920 5921 ins_cost(125); // XXX 5922 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5923 ins_encode %{ 5924 __ movl($mem$$Address, r12); 5925 %} 5926 ins_pipe(ialu_mem_reg); 5927 %} 5928 5929 instruct storeImmN(memory mem, immN src) 5930 %{ 5931 match(Set mem (StoreN mem src)); 5932 5933 ins_cost(150); // XXX 5934 format %{ "movl $mem, $src\t# compressed ptr" %} 5935 ins_encode %{ 5936 address con = (address)$src$$constant; 5937 if (con == NULL) { 5938 __ movl($mem$$Address, (int32_t)0); 5939 } else { 5940 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5941 } 5942 %} 5943 ins_pipe(ialu_mem_imm); 5944 %} 5945 5946 instruct storeImmNKlass(memory mem, immNKlass src) 5947 %{ 5948 match(Set mem (StoreNKlass mem src)); 5949 5950 ins_cost(150); // XXX 5951 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5952 ins_encode %{ 5953 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5954 %} 5955 ins_pipe(ialu_mem_imm); 5956 %} 5957 5958 // Store Integer Immediate 5959 instruct storeImmI0(memory mem, immI0 zero) 5960 %{ 5961 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5962 match(Set mem (StoreI mem zero)); 5963 5964 ins_cost(125); // XXX 5965 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5966 ins_encode %{ 5967 __ movl($mem$$Address, r12); 5968 %} 5969 ins_pipe(ialu_mem_reg); 5970 %} 5971 5972 instruct storeImmI(memory mem, immI src) 5973 %{ 5974 match(Set mem (StoreI mem src)); 5975 5976 ins_cost(150); 5977 format %{ "movl $mem, $src\t# int" %} 5978 opcode(0xC7); /* C7 /0 */ 5979 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5980 ins_pipe(ialu_mem_imm); 5981 %} 5982 5983 // Store Long Immediate 5984 instruct storeImmL0(memory mem, immL0 zero) 5985 %{ 5986 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5987 match(Set mem (StoreL mem zero)); 5988 5989 ins_cost(125); // XXX 5990 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5991 ins_encode %{ 5992 __ movq($mem$$Address, r12); 5993 %} 5994 ins_pipe(ialu_mem_reg); 5995 %} 5996 5997 instruct storeImmL(memory mem, immL32 src) 5998 %{ 5999 match(Set mem (StoreL mem src)); 6000 6001 ins_cost(150); 6002 format %{ "movq $mem, $src\t# long" %} 6003 opcode(0xC7); /* C7 /0 */ 6004 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6005 ins_pipe(ialu_mem_imm); 6006 %} 6007 6008 // Store Short/Char Immediate 6009 instruct storeImmC0(memory mem, immI0 zero) 6010 %{ 6011 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6012 match(Set mem (StoreC mem zero)); 6013 6014 ins_cost(125); // XXX 6015 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6016 ins_encode %{ 6017 __ movw($mem$$Address, r12); 6018 %} 6019 ins_pipe(ialu_mem_reg); 6020 %} 6021 6022 instruct storeImmI16(memory mem, immI16 src) 6023 %{ 6024 predicate(UseStoreImmI16); 6025 match(Set mem (StoreC mem src)); 6026 6027 ins_cost(150); 6028 format %{ "movw $mem, $src\t# short/char" %} 6029 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6030 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6031 ins_pipe(ialu_mem_imm); 6032 %} 6033 6034 // Store Byte Immediate 6035 instruct storeImmB0(memory mem, immI0 zero) 6036 %{ 6037 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6038 match(Set mem (StoreB mem zero)); 6039 6040 ins_cost(125); // XXX 6041 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6042 ins_encode %{ 6043 __ movb($mem$$Address, r12); 6044 %} 6045 ins_pipe(ialu_mem_reg); 6046 %} 6047 6048 instruct storeImmB(memory mem, immI8 src) 6049 %{ 6050 match(Set mem (StoreB mem src)); 6051 6052 ins_cost(150); // XXX 6053 format %{ "movb $mem, $src\t# byte" %} 6054 opcode(0xC6); /* C6 /0 */ 6055 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6056 ins_pipe(ialu_mem_imm); 6057 %} 6058 6059 // Store CMS card-mark Immediate 6060 instruct storeImmCM0_reg(memory mem, immI0 zero) 6061 %{ 6062 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6063 match(Set mem (StoreCM mem zero)); 6064 6065 ins_cost(125); // XXX 6066 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6067 ins_encode %{ 6068 __ movb($mem$$Address, r12); 6069 %} 6070 ins_pipe(ialu_mem_reg); 6071 %} 6072 6073 instruct storeImmCM0(memory mem, immI0 src) 6074 %{ 6075 match(Set mem (StoreCM mem src)); 6076 6077 ins_cost(150); // XXX 6078 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6079 opcode(0xC6); /* C6 /0 */ 6080 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6081 ins_pipe(ialu_mem_imm); 6082 %} 6083 6084 // Store Float 6085 instruct storeF(memory mem, regF src) 6086 %{ 6087 match(Set mem (StoreF mem src)); 6088 6089 ins_cost(95); // XXX 6090 format %{ "movss $mem, $src\t# float" %} 6091 ins_encode %{ 6092 __ movflt($mem$$Address, $src$$XMMRegister); 6093 %} 6094 ins_pipe(pipe_slow); // XXX 6095 %} 6096 6097 // Store immediate Float value (it is faster than store from XMM register) 6098 instruct storeF0(memory mem, immF0 zero) 6099 %{ 6100 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6101 match(Set mem (StoreF mem zero)); 6102 6103 ins_cost(25); // XXX 6104 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6105 ins_encode %{ 6106 __ movl($mem$$Address, r12); 6107 %} 6108 ins_pipe(ialu_mem_reg); 6109 %} 6110 6111 instruct storeF_imm(memory mem, immF src) 6112 %{ 6113 match(Set mem (StoreF mem src)); 6114 6115 ins_cost(50); 6116 format %{ "movl $mem, $src\t# float" %} 6117 opcode(0xC7); /* C7 /0 */ 6118 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6119 ins_pipe(ialu_mem_imm); 6120 %} 6121 6122 // Store Double 6123 instruct storeD(memory mem, regD src) 6124 %{ 6125 match(Set mem (StoreD mem src)); 6126 6127 ins_cost(95); // XXX 6128 format %{ "movsd $mem, $src\t# double" %} 6129 ins_encode %{ 6130 __ movdbl($mem$$Address, $src$$XMMRegister); 6131 %} 6132 ins_pipe(pipe_slow); // XXX 6133 %} 6134 6135 // Store immediate double 0.0 (it is faster than store from XMM register) 6136 instruct storeD0_imm(memory mem, immD0 src) 6137 %{ 6138 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6139 match(Set mem (StoreD mem src)); 6140 6141 ins_cost(50); 6142 format %{ "movq $mem, $src\t# double 0." %} 6143 opcode(0xC7); /* C7 /0 */ 6144 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6145 ins_pipe(ialu_mem_imm); 6146 %} 6147 6148 instruct storeD0(memory mem, immD0 zero) 6149 %{ 6150 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6151 match(Set mem (StoreD mem zero)); 6152 6153 ins_cost(25); // XXX 6154 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6155 ins_encode %{ 6156 __ movq($mem$$Address, r12); 6157 %} 6158 ins_pipe(ialu_mem_reg); 6159 %} 6160 6161 instruct storeSSI(stackSlotI dst, rRegI src) 6162 %{ 6163 match(Set dst src); 6164 6165 ins_cost(100); 6166 format %{ "movl $dst, $src\t# int stk" %} 6167 opcode(0x89); 6168 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6169 ins_pipe( ialu_mem_reg ); 6170 %} 6171 6172 instruct storeSSL(stackSlotL dst, rRegL src) 6173 %{ 6174 match(Set dst src); 6175 6176 ins_cost(100); 6177 format %{ "movq $dst, $src\t# long stk" %} 6178 opcode(0x89); 6179 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6180 ins_pipe(ialu_mem_reg); 6181 %} 6182 6183 instruct storeSSP(stackSlotP dst, rRegP src) 6184 %{ 6185 match(Set dst src); 6186 6187 ins_cost(100); 6188 format %{ "movq $dst, $src\t# ptr stk" %} 6189 opcode(0x89); 6190 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6191 ins_pipe(ialu_mem_reg); 6192 %} 6193 6194 instruct storeSSF(stackSlotF dst, regF src) 6195 %{ 6196 match(Set dst src); 6197 6198 ins_cost(95); // XXX 6199 format %{ "movss $dst, $src\t# float stk" %} 6200 ins_encode %{ 6201 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6202 %} 6203 ins_pipe(pipe_slow); // XXX 6204 %} 6205 6206 instruct storeSSD(stackSlotD dst, regD src) 6207 %{ 6208 match(Set dst src); 6209 6210 ins_cost(95); // XXX 6211 format %{ "movsd $dst, $src\t# double stk" %} 6212 ins_encode %{ 6213 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6214 %} 6215 ins_pipe(pipe_slow); // XXX 6216 %} 6217 6218 //----------BSWAP Instructions------------------------------------------------- 6219 instruct bytes_reverse_int(rRegI dst) %{ 6220 match(Set dst (ReverseBytesI dst)); 6221 6222 format %{ "bswapl $dst" %} 6223 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6224 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6225 ins_pipe( ialu_reg ); 6226 %} 6227 6228 instruct bytes_reverse_long(rRegL dst) %{ 6229 match(Set dst (ReverseBytesL dst)); 6230 6231 format %{ "bswapq $dst" %} 6232 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6233 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6234 ins_pipe( ialu_reg); 6235 %} 6236 6237 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6238 match(Set dst (ReverseBytesUS dst)); 6239 effect(KILL cr); 6240 6241 format %{ "bswapl $dst\n\t" 6242 "shrl $dst,16\n\t" %} 6243 ins_encode %{ 6244 __ bswapl($dst$$Register); 6245 __ shrl($dst$$Register, 16); 6246 %} 6247 ins_pipe( ialu_reg ); 6248 %} 6249 6250 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6251 match(Set dst (ReverseBytesS dst)); 6252 effect(KILL cr); 6253 6254 format %{ "bswapl $dst\n\t" 6255 "sar $dst,16\n\t" %} 6256 ins_encode %{ 6257 __ bswapl($dst$$Register); 6258 __ sarl($dst$$Register, 16); 6259 %} 6260 ins_pipe( ialu_reg ); 6261 %} 6262 6263 //---------- Zeros Count Instructions ------------------------------------------ 6264 6265 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6266 predicate(UseCountLeadingZerosInstruction); 6267 match(Set dst (CountLeadingZerosI src)); 6268 effect(KILL cr); 6269 6270 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6271 ins_encode %{ 6272 __ lzcntl($dst$$Register, $src$$Register); 6273 %} 6274 ins_pipe(ialu_reg); 6275 %} 6276 6277 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6278 predicate(!UseCountLeadingZerosInstruction); 6279 match(Set dst (CountLeadingZerosI src)); 6280 effect(KILL cr); 6281 6282 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6283 "jnz skip\n\t" 6284 "movl $dst, -1\n" 6285 "skip:\n\t" 6286 "negl $dst\n\t" 6287 "addl $dst, 31" %} 6288 ins_encode %{ 6289 Register Rdst = $dst$$Register; 6290 Register Rsrc = $src$$Register; 6291 Label skip; 6292 __ bsrl(Rdst, Rsrc); 6293 __ jccb(Assembler::notZero, skip); 6294 __ movl(Rdst, -1); 6295 __ bind(skip); 6296 __ negl(Rdst); 6297 __ addl(Rdst, BitsPerInt - 1); 6298 %} 6299 ins_pipe(ialu_reg); 6300 %} 6301 6302 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6303 predicate(UseCountLeadingZerosInstruction); 6304 match(Set dst (CountLeadingZerosL src)); 6305 effect(KILL cr); 6306 6307 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6308 ins_encode %{ 6309 __ lzcntq($dst$$Register, $src$$Register); 6310 %} 6311 ins_pipe(ialu_reg); 6312 %} 6313 6314 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6315 predicate(!UseCountLeadingZerosInstruction); 6316 match(Set dst (CountLeadingZerosL src)); 6317 effect(KILL cr); 6318 6319 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6320 "jnz skip\n\t" 6321 "movl $dst, -1\n" 6322 "skip:\n\t" 6323 "negl $dst\n\t" 6324 "addl $dst, 63" %} 6325 ins_encode %{ 6326 Register Rdst = $dst$$Register; 6327 Register Rsrc = $src$$Register; 6328 Label skip; 6329 __ bsrq(Rdst, Rsrc); 6330 __ jccb(Assembler::notZero, skip); 6331 __ movl(Rdst, -1); 6332 __ bind(skip); 6333 __ negl(Rdst); 6334 __ addl(Rdst, BitsPerLong - 1); 6335 %} 6336 ins_pipe(ialu_reg); 6337 %} 6338 6339 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6340 predicate(UseCountTrailingZerosInstruction); 6341 match(Set dst (CountTrailingZerosI src)); 6342 effect(KILL cr); 6343 6344 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6345 ins_encode %{ 6346 __ tzcntl($dst$$Register, $src$$Register); 6347 %} 6348 ins_pipe(ialu_reg); 6349 %} 6350 6351 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6352 predicate(!UseCountTrailingZerosInstruction); 6353 match(Set dst (CountTrailingZerosI src)); 6354 effect(KILL cr); 6355 6356 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6357 "jnz done\n\t" 6358 "movl $dst, 32\n" 6359 "done:" %} 6360 ins_encode %{ 6361 Register Rdst = $dst$$Register; 6362 Label done; 6363 __ bsfl(Rdst, $src$$Register); 6364 __ jccb(Assembler::notZero, done); 6365 __ movl(Rdst, BitsPerInt); 6366 __ bind(done); 6367 %} 6368 ins_pipe(ialu_reg); 6369 %} 6370 6371 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6372 predicate(UseCountTrailingZerosInstruction); 6373 match(Set dst (CountTrailingZerosL src)); 6374 effect(KILL cr); 6375 6376 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6377 ins_encode %{ 6378 __ tzcntq($dst$$Register, $src$$Register); 6379 %} 6380 ins_pipe(ialu_reg); 6381 %} 6382 6383 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6384 predicate(!UseCountTrailingZerosInstruction); 6385 match(Set dst (CountTrailingZerosL src)); 6386 effect(KILL cr); 6387 6388 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6389 "jnz done\n\t" 6390 "movl $dst, 64\n" 6391 "done:" %} 6392 ins_encode %{ 6393 Register Rdst = $dst$$Register; 6394 Label done; 6395 __ bsfq(Rdst, $src$$Register); 6396 __ jccb(Assembler::notZero, done); 6397 __ movl(Rdst, BitsPerLong); 6398 __ bind(done); 6399 %} 6400 ins_pipe(ialu_reg); 6401 %} 6402 6403 6404 //---------- Population Count Instructions ------------------------------------- 6405 6406 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6407 predicate(UsePopCountInstruction); 6408 match(Set dst (PopCountI src)); 6409 effect(KILL cr); 6410 6411 format %{ "popcnt $dst, $src" %} 6412 ins_encode %{ 6413 __ popcntl($dst$$Register, $src$$Register); 6414 %} 6415 ins_pipe(ialu_reg); 6416 %} 6417 6418 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6419 predicate(UsePopCountInstruction); 6420 match(Set dst (PopCountI (LoadI mem))); 6421 effect(KILL cr); 6422 6423 format %{ "popcnt $dst, $mem" %} 6424 ins_encode %{ 6425 __ popcntl($dst$$Register, $mem$$Address); 6426 %} 6427 ins_pipe(ialu_reg); 6428 %} 6429 6430 // Note: Long.bitCount(long) returns an int. 6431 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6432 predicate(UsePopCountInstruction); 6433 match(Set dst (PopCountL src)); 6434 effect(KILL cr); 6435 6436 format %{ "popcnt $dst, $src" %} 6437 ins_encode %{ 6438 __ popcntq($dst$$Register, $src$$Register); 6439 %} 6440 ins_pipe(ialu_reg); 6441 %} 6442 6443 // Note: Long.bitCount(long) returns an int. 6444 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6445 predicate(UsePopCountInstruction); 6446 match(Set dst (PopCountL (LoadL mem))); 6447 effect(KILL cr); 6448 6449 format %{ "popcnt $dst, $mem" %} 6450 ins_encode %{ 6451 __ popcntq($dst$$Register, $mem$$Address); 6452 %} 6453 ins_pipe(ialu_reg); 6454 %} 6455 6456 6457 //----------MemBar Instructions----------------------------------------------- 6458 // Memory barrier flavors 6459 6460 instruct membar_acquire() 6461 %{ 6462 match(MemBarAcquire); 6463 match(LoadFence); 6464 ins_cost(0); 6465 6466 size(0); 6467 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6468 ins_encode(); 6469 ins_pipe(empty); 6470 %} 6471 6472 instruct membar_acquire_lock() 6473 %{ 6474 match(MemBarAcquireLock); 6475 ins_cost(0); 6476 6477 size(0); 6478 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6479 ins_encode(); 6480 ins_pipe(empty); 6481 %} 6482 6483 instruct membar_release() 6484 %{ 6485 match(MemBarRelease); 6486 match(StoreFence); 6487 ins_cost(0); 6488 6489 size(0); 6490 format %{ "MEMBAR-release ! (empty encoding)" %} 6491 ins_encode(); 6492 ins_pipe(empty); 6493 %} 6494 6495 instruct membar_release_lock() 6496 %{ 6497 match(MemBarReleaseLock); 6498 ins_cost(0); 6499 6500 size(0); 6501 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6502 ins_encode(); 6503 ins_pipe(empty); 6504 %} 6505 6506 instruct membar_volatile(rFlagsReg cr) %{ 6507 match(MemBarVolatile); 6508 effect(KILL cr); 6509 ins_cost(400); 6510 6511 format %{ 6512 $$template 6513 if (os::is_MP()) { 6514 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6515 } else { 6516 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6517 } 6518 %} 6519 ins_encode %{ 6520 __ membar(Assembler::StoreLoad); 6521 %} 6522 ins_pipe(pipe_slow); 6523 %} 6524 6525 instruct unnecessary_membar_volatile() 6526 %{ 6527 match(MemBarVolatile); 6528 predicate(Matcher::post_store_load_barrier(n)); 6529 ins_cost(0); 6530 6531 size(0); 6532 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6533 ins_encode(); 6534 ins_pipe(empty); 6535 %} 6536 6537 instruct membar_storestore() %{ 6538 match(MemBarStoreStore); 6539 ins_cost(0); 6540 6541 size(0); 6542 format %{ "MEMBAR-storestore (empty encoding)" %} 6543 ins_encode( ); 6544 ins_pipe(empty); 6545 %} 6546 6547 //----------Move Instructions-------------------------------------------------- 6548 6549 instruct castX2P(rRegP dst, rRegL src) 6550 %{ 6551 match(Set dst (CastX2P src)); 6552 6553 format %{ "movq $dst, $src\t# long->ptr" %} 6554 ins_encode %{ 6555 if ($dst$$reg != $src$$reg) { 6556 __ movptr($dst$$Register, $src$$Register); 6557 } 6558 %} 6559 ins_pipe(ialu_reg_reg); // XXX 6560 %} 6561 6562 instruct castP2X(rRegL dst, rRegP src) 6563 %{ 6564 match(Set dst (CastP2X src)); 6565 6566 format %{ "movq $dst, $src\t# ptr -> long" %} 6567 ins_encode %{ 6568 if ($dst$$reg != $src$$reg) { 6569 __ movptr($dst$$Register, $src$$Register); 6570 } 6571 %} 6572 ins_pipe(ialu_reg_reg); // XXX 6573 %} 6574 6575 // Convert oop into int for vectors alignment masking 6576 instruct convP2I(rRegI dst, rRegP src) 6577 %{ 6578 match(Set dst (ConvL2I (CastP2X src))); 6579 6580 format %{ "movl $dst, $src\t# ptr -> int" %} 6581 ins_encode %{ 6582 __ movl($dst$$Register, $src$$Register); 6583 %} 6584 ins_pipe(ialu_reg_reg); // XXX 6585 %} 6586 6587 // Convert compressed oop into int for vectors alignment masking 6588 // in case of 32bit oops (heap < 4Gb). 6589 instruct convN2I(rRegI dst, rRegN src) 6590 %{ 6591 predicate(Universe::narrow_oop_shift() == 0); 6592 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6593 6594 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6595 ins_encode %{ 6596 __ movl($dst$$Register, $src$$Register); 6597 %} 6598 ins_pipe(ialu_reg_reg); // XXX 6599 %} 6600 6601 // Convert oop pointer into compressed form 6602 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6603 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6604 match(Set dst (EncodeP src)); 6605 effect(KILL cr); 6606 format %{ "encode_heap_oop $dst,$src" %} 6607 ins_encode %{ 6608 Register s = $src$$Register; 6609 Register d = $dst$$Register; 6610 if (s != d) { 6611 __ movq(d, s); 6612 } 6613 __ encode_heap_oop(d); 6614 %} 6615 ins_pipe(ialu_reg_long); 6616 %} 6617 6618 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6619 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6620 match(Set dst (EncodeP src)); 6621 effect(KILL cr); 6622 format %{ "encode_heap_oop_not_null $dst,$src" %} 6623 ins_encode %{ 6624 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6625 %} 6626 ins_pipe(ialu_reg_long); 6627 %} 6628 6629 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6630 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6631 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6632 match(Set dst (DecodeN src)); 6633 effect(KILL cr); 6634 format %{ "decode_heap_oop $dst,$src" %} 6635 ins_encode %{ 6636 Register s = $src$$Register; 6637 Register d = $dst$$Register; 6638 if (s != d) { 6639 __ movq(d, s); 6640 } 6641 __ decode_heap_oop(d); 6642 %} 6643 ins_pipe(ialu_reg_long); 6644 %} 6645 6646 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6647 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6648 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6649 match(Set dst (DecodeN src)); 6650 effect(KILL cr); 6651 format %{ "decode_heap_oop_not_null $dst,$src" %} 6652 ins_encode %{ 6653 Register s = $src$$Register; 6654 Register d = $dst$$Register; 6655 if (s != d) { 6656 __ decode_heap_oop_not_null(d, s); 6657 } else { 6658 __ decode_heap_oop_not_null(d); 6659 } 6660 %} 6661 ins_pipe(ialu_reg_long); 6662 %} 6663 6664 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6665 match(Set dst (EncodePKlass src)); 6666 effect(KILL cr); 6667 format %{ "encode_klass_not_null $dst,$src" %} 6668 ins_encode %{ 6669 __ encode_klass_not_null($dst$$Register, $src$$Register); 6670 %} 6671 ins_pipe(ialu_reg_long); 6672 %} 6673 6674 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6675 match(Set dst (DecodeNKlass src)); 6676 effect(KILL cr); 6677 format %{ "decode_klass_not_null $dst,$src" %} 6678 ins_encode %{ 6679 Register s = $src$$Register; 6680 Register d = $dst$$Register; 6681 if (s != d) { 6682 __ decode_klass_not_null(d, s); 6683 } else { 6684 __ decode_klass_not_null(d); 6685 } 6686 %} 6687 ins_pipe(ialu_reg_long); 6688 %} 6689 6690 6691 //----------Conditional Move--------------------------------------------------- 6692 // Jump 6693 // dummy instruction for generating temp registers 6694 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6695 match(Jump (LShiftL switch_val shift)); 6696 ins_cost(350); 6697 predicate(false); 6698 effect(TEMP dest); 6699 6700 format %{ "leaq $dest, [$constantaddress]\n\t" 6701 "jmp [$dest + $switch_val << $shift]\n\t" %} 6702 ins_encode %{ 6703 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6704 // to do that and the compiler is using that register as one it can allocate. 6705 // So we build it all by hand. 6706 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6707 // ArrayAddress dispatch(table, index); 6708 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6709 __ lea($dest$$Register, $constantaddress); 6710 __ jmp(dispatch); 6711 %} 6712 ins_pipe(pipe_jmp); 6713 %} 6714 6715 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6716 match(Jump (AddL (LShiftL switch_val shift) offset)); 6717 ins_cost(350); 6718 effect(TEMP dest); 6719 6720 format %{ "leaq $dest, [$constantaddress]\n\t" 6721 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6722 ins_encode %{ 6723 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6724 // to do that and the compiler is using that register as one it can allocate. 6725 // So we build it all by hand. 6726 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6727 // ArrayAddress dispatch(table, index); 6728 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6729 __ lea($dest$$Register, $constantaddress); 6730 __ jmp(dispatch); 6731 %} 6732 ins_pipe(pipe_jmp); 6733 %} 6734 6735 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6736 match(Jump switch_val); 6737 ins_cost(350); 6738 effect(TEMP dest); 6739 6740 format %{ "leaq $dest, [$constantaddress]\n\t" 6741 "jmp [$dest + $switch_val]\n\t" %} 6742 ins_encode %{ 6743 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6744 // to do that and the compiler is using that register as one it can allocate. 6745 // So we build it all by hand. 6746 // Address index(noreg, switch_reg, Address::times_1); 6747 // ArrayAddress dispatch(table, index); 6748 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6749 __ lea($dest$$Register, $constantaddress); 6750 __ jmp(dispatch); 6751 %} 6752 ins_pipe(pipe_jmp); 6753 %} 6754 6755 // Conditional move 6756 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6757 %{ 6758 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6759 6760 ins_cost(200); // XXX 6761 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6762 opcode(0x0F, 0x40); 6763 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6764 ins_pipe(pipe_cmov_reg); 6765 %} 6766 6767 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6768 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6769 6770 ins_cost(200); // XXX 6771 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6772 opcode(0x0F, 0x40); 6773 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6774 ins_pipe(pipe_cmov_reg); 6775 %} 6776 6777 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6778 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6779 ins_cost(200); 6780 expand %{ 6781 cmovI_regU(cop, cr, dst, src); 6782 %} 6783 %} 6784 6785 // Conditional move 6786 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6787 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6788 6789 ins_cost(250); // XXX 6790 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6791 opcode(0x0F, 0x40); 6792 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6793 ins_pipe(pipe_cmov_mem); 6794 %} 6795 6796 // Conditional move 6797 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6798 %{ 6799 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6800 6801 ins_cost(250); // XXX 6802 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6803 opcode(0x0F, 0x40); 6804 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6805 ins_pipe(pipe_cmov_mem); 6806 %} 6807 6808 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6809 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6810 ins_cost(250); 6811 expand %{ 6812 cmovI_memU(cop, cr, dst, src); 6813 %} 6814 %} 6815 6816 // Conditional move 6817 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6818 %{ 6819 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6820 6821 ins_cost(200); // XXX 6822 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6823 opcode(0x0F, 0x40); 6824 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6825 ins_pipe(pipe_cmov_reg); 6826 %} 6827 6828 // Conditional move 6829 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6830 %{ 6831 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6832 6833 ins_cost(200); // XXX 6834 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6835 opcode(0x0F, 0x40); 6836 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6837 ins_pipe(pipe_cmov_reg); 6838 %} 6839 6840 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6841 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6842 ins_cost(200); 6843 expand %{ 6844 cmovN_regU(cop, cr, dst, src); 6845 %} 6846 %} 6847 6848 // Conditional move 6849 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6850 %{ 6851 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6852 6853 ins_cost(200); // XXX 6854 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6855 opcode(0x0F, 0x40); 6856 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6857 ins_pipe(pipe_cmov_reg); // XXX 6858 %} 6859 6860 // Conditional move 6861 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6862 %{ 6863 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6864 6865 ins_cost(200); // XXX 6866 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6867 opcode(0x0F, 0x40); 6868 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6869 ins_pipe(pipe_cmov_reg); // XXX 6870 %} 6871 6872 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6873 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6874 ins_cost(200); 6875 expand %{ 6876 cmovP_regU(cop, cr, dst, src); 6877 %} 6878 %} 6879 6880 // DISABLED: Requires the ADLC to emit a bottom_type call that 6881 // correctly meets the two pointer arguments; one is an incoming 6882 // register but the other is a memory operand. ALSO appears to 6883 // be buggy with implicit null checks. 6884 // 6885 //// Conditional move 6886 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6887 //%{ 6888 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6889 // ins_cost(250); 6890 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6891 // opcode(0x0F,0x40); 6892 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6893 // ins_pipe( pipe_cmov_mem ); 6894 //%} 6895 // 6896 //// Conditional move 6897 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6898 //%{ 6899 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6900 // ins_cost(250); 6901 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6902 // opcode(0x0F,0x40); 6903 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6904 // ins_pipe( pipe_cmov_mem ); 6905 //%} 6906 6907 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6908 %{ 6909 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6910 6911 ins_cost(200); // XXX 6912 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6913 opcode(0x0F, 0x40); 6914 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6915 ins_pipe(pipe_cmov_reg); // XXX 6916 %} 6917 6918 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6919 %{ 6920 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6921 6922 ins_cost(200); // XXX 6923 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6924 opcode(0x0F, 0x40); 6925 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6926 ins_pipe(pipe_cmov_mem); // XXX 6927 %} 6928 6929 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6930 %{ 6931 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6932 6933 ins_cost(200); // XXX 6934 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6935 opcode(0x0F, 0x40); 6936 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6937 ins_pipe(pipe_cmov_reg); // XXX 6938 %} 6939 6940 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6941 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6942 ins_cost(200); 6943 expand %{ 6944 cmovL_regU(cop, cr, dst, src); 6945 %} 6946 %} 6947 6948 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6949 %{ 6950 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6951 6952 ins_cost(200); // XXX 6953 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6954 opcode(0x0F, 0x40); 6955 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6956 ins_pipe(pipe_cmov_mem); // XXX 6957 %} 6958 6959 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6960 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6961 ins_cost(200); 6962 expand %{ 6963 cmovL_memU(cop, cr, dst, src); 6964 %} 6965 %} 6966 6967 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6968 %{ 6969 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6970 6971 ins_cost(200); // XXX 6972 format %{ "jn$cop skip\t# signed cmove float\n\t" 6973 "movss $dst, $src\n" 6974 "skip:" %} 6975 ins_encode %{ 6976 Label Lskip; 6977 // Invert sense of branch from sense of CMOV 6978 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6979 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6980 __ bind(Lskip); 6981 %} 6982 ins_pipe(pipe_slow); 6983 %} 6984 6985 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6986 // %{ 6987 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 6988 6989 // ins_cost(200); // XXX 6990 // format %{ "jn$cop skip\t# signed cmove float\n\t" 6991 // "movss $dst, $src\n" 6992 // "skip:" %} 6993 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 6994 // ins_pipe(pipe_slow); 6995 // %} 6996 6997 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6998 %{ 6999 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7000 7001 ins_cost(200); // XXX 7002 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7003 "movss $dst, $src\n" 7004 "skip:" %} 7005 ins_encode %{ 7006 Label Lskip; 7007 // Invert sense of branch from sense of CMOV 7008 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7009 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7010 __ bind(Lskip); 7011 %} 7012 ins_pipe(pipe_slow); 7013 %} 7014 7015 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7016 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7017 ins_cost(200); 7018 expand %{ 7019 cmovF_regU(cop, cr, dst, src); 7020 %} 7021 %} 7022 7023 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7024 %{ 7025 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7026 7027 ins_cost(200); // XXX 7028 format %{ "jn$cop skip\t# signed cmove double\n\t" 7029 "movsd $dst, $src\n" 7030 "skip:" %} 7031 ins_encode %{ 7032 Label Lskip; 7033 // Invert sense of branch from sense of CMOV 7034 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7035 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7036 __ bind(Lskip); 7037 %} 7038 ins_pipe(pipe_slow); 7039 %} 7040 7041 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7042 %{ 7043 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7044 7045 ins_cost(200); // XXX 7046 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7047 "movsd $dst, $src\n" 7048 "skip:" %} 7049 ins_encode %{ 7050 Label Lskip; 7051 // Invert sense of branch from sense of CMOV 7052 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7053 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7054 __ bind(Lskip); 7055 %} 7056 ins_pipe(pipe_slow); 7057 %} 7058 7059 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7060 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7061 ins_cost(200); 7062 expand %{ 7063 cmovD_regU(cop, cr, dst, src); 7064 %} 7065 %} 7066 7067 //----------Arithmetic Instructions-------------------------------------------- 7068 //----------Addition Instructions---------------------------------------------- 7069 7070 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7071 %{ 7072 match(Set dst (AddI dst src)); 7073 effect(KILL cr); 7074 7075 format %{ "addl $dst, $src\t# int" %} 7076 opcode(0x03); 7077 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7078 ins_pipe(ialu_reg_reg); 7079 %} 7080 7081 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7082 %{ 7083 match(Set dst (AddI dst src)); 7084 effect(KILL cr); 7085 7086 format %{ "addl $dst, $src\t# int" %} 7087 opcode(0x81, 0x00); /* /0 id */ 7088 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7089 ins_pipe( ialu_reg ); 7090 %} 7091 7092 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7093 %{ 7094 match(Set dst (AddI dst (LoadI src))); 7095 effect(KILL cr); 7096 7097 ins_cost(125); // XXX 7098 format %{ "addl $dst, $src\t# int" %} 7099 opcode(0x03); 7100 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7101 ins_pipe(ialu_reg_mem); 7102 %} 7103 7104 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7105 %{ 7106 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7107 effect(KILL cr); 7108 7109 ins_cost(150); // XXX 7110 format %{ "addl $dst, $src\t# int" %} 7111 opcode(0x01); /* Opcode 01 /r */ 7112 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7113 ins_pipe(ialu_mem_reg); 7114 %} 7115 7116 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7117 %{ 7118 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7119 effect(KILL cr); 7120 7121 ins_cost(125); // XXX 7122 format %{ "addl $dst, $src\t# int" %} 7123 opcode(0x81); /* Opcode 81 /0 id */ 7124 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7125 ins_pipe(ialu_mem_imm); 7126 %} 7127 7128 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7129 %{ 7130 predicate(UseIncDec); 7131 match(Set dst (AddI dst src)); 7132 effect(KILL cr); 7133 7134 format %{ "incl $dst\t# int" %} 7135 opcode(0xFF, 0x00); // FF /0 7136 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7137 ins_pipe(ialu_reg); 7138 %} 7139 7140 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7141 %{ 7142 predicate(UseIncDec); 7143 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7144 effect(KILL cr); 7145 7146 ins_cost(125); // XXX 7147 format %{ "incl $dst\t# int" %} 7148 opcode(0xFF); /* Opcode FF /0 */ 7149 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7150 ins_pipe(ialu_mem_imm); 7151 %} 7152 7153 // XXX why does that use AddI 7154 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7155 %{ 7156 predicate(UseIncDec); 7157 match(Set dst (AddI dst src)); 7158 effect(KILL cr); 7159 7160 format %{ "decl $dst\t# int" %} 7161 opcode(0xFF, 0x01); // FF /1 7162 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7163 ins_pipe(ialu_reg); 7164 %} 7165 7166 // XXX why does that use AddI 7167 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7168 %{ 7169 predicate(UseIncDec); 7170 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7171 effect(KILL cr); 7172 7173 ins_cost(125); // XXX 7174 format %{ "decl $dst\t# int" %} 7175 opcode(0xFF); /* Opcode FF /1 */ 7176 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7177 ins_pipe(ialu_mem_imm); 7178 %} 7179 7180 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7181 %{ 7182 match(Set dst (AddI src0 src1)); 7183 7184 ins_cost(110); 7185 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7186 opcode(0x8D); /* 0x8D /r */ 7187 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7188 ins_pipe(ialu_reg_reg); 7189 %} 7190 7191 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7192 %{ 7193 match(Set dst (AddL dst src)); 7194 effect(KILL cr); 7195 7196 format %{ "addq $dst, $src\t# long" %} 7197 opcode(0x03); 7198 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7199 ins_pipe(ialu_reg_reg); 7200 %} 7201 7202 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7203 %{ 7204 match(Set dst (AddL dst src)); 7205 effect(KILL cr); 7206 7207 format %{ "addq $dst, $src\t# long" %} 7208 opcode(0x81, 0x00); /* /0 id */ 7209 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7210 ins_pipe( ialu_reg ); 7211 %} 7212 7213 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7214 %{ 7215 match(Set dst (AddL dst (LoadL src))); 7216 effect(KILL cr); 7217 7218 ins_cost(125); // XXX 7219 format %{ "addq $dst, $src\t# long" %} 7220 opcode(0x03); 7221 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7222 ins_pipe(ialu_reg_mem); 7223 %} 7224 7225 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7226 %{ 7227 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7228 effect(KILL cr); 7229 7230 ins_cost(150); // XXX 7231 format %{ "addq $dst, $src\t# long" %} 7232 opcode(0x01); /* Opcode 01 /r */ 7233 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7234 ins_pipe(ialu_mem_reg); 7235 %} 7236 7237 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7238 %{ 7239 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7240 effect(KILL cr); 7241 7242 ins_cost(125); // XXX 7243 format %{ "addq $dst, $src\t# long" %} 7244 opcode(0x81); /* Opcode 81 /0 id */ 7245 ins_encode(REX_mem_wide(dst), 7246 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7247 ins_pipe(ialu_mem_imm); 7248 %} 7249 7250 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7251 %{ 7252 predicate(UseIncDec); 7253 match(Set dst (AddL dst src)); 7254 effect(KILL cr); 7255 7256 format %{ "incq $dst\t# long" %} 7257 opcode(0xFF, 0x00); // FF /0 7258 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7259 ins_pipe(ialu_reg); 7260 %} 7261 7262 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7263 %{ 7264 predicate(UseIncDec); 7265 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7266 effect(KILL cr); 7267 7268 ins_cost(125); // XXX 7269 format %{ "incq $dst\t# long" %} 7270 opcode(0xFF); /* Opcode FF /0 */ 7271 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7272 ins_pipe(ialu_mem_imm); 7273 %} 7274 7275 // XXX why does that use AddL 7276 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7277 %{ 7278 predicate(UseIncDec); 7279 match(Set dst (AddL dst src)); 7280 effect(KILL cr); 7281 7282 format %{ "decq $dst\t# long" %} 7283 opcode(0xFF, 0x01); // FF /1 7284 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7285 ins_pipe(ialu_reg); 7286 %} 7287 7288 // XXX why does that use AddL 7289 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7290 %{ 7291 predicate(UseIncDec); 7292 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7293 effect(KILL cr); 7294 7295 ins_cost(125); // XXX 7296 format %{ "decq $dst\t# long" %} 7297 opcode(0xFF); /* Opcode FF /1 */ 7298 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7299 ins_pipe(ialu_mem_imm); 7300 %} 7301 7302 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7303 %{ 7304 match(Set dst (AddL src0 src1)); 7305 7306 ins_cost(110); 7307 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7308 opcode(0x8D); /* 0x8D /r */ 7309 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7310 ins_pipe(ialu_reg_reg); 7311 %} 7312 7313 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7314 %{ 7315 match(Set dst (AddP dst src)); 7316 effect(KILL cr); 7317 7318 format %{ "addq $dst, $src\t# ptr" %} 7319 opcode(0x03); 7320 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7321 ins_pipe(ialu_reg_reg); 7322 %} 7323 7324 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7325 %{ 7326 match(Set dst (AddP dst src)); 7327 effect(KILL cr); 7328 7329 format %{ "addq $dst, $src\t# ptr" %} 7330 opcode(0x81, 0x00); /* /0 id */ 7331 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7332 ins_pipe( ialu_reg ); 7333 %} 7334 7335 // XXX addP mem ops ???? 7336 7337 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7338 %{ 7339 match(Set dst (AddP src0 src1)); 7340 7341 ins_cost(110); 7342 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7343 opcode(0x8D); /* 0x8D /r */ 7344 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7345 ins_pipe(ialu_reg_reg); 7346 %} 7347 7348 instruct checkCastPP(rRegP dst) 7349 %{ 7350 match(Set dst (CheckCastPP dst)); 7351 7352 size(0); 7353 format %{ "# checkcastPP of $dst" %} 7354 ins_encode(/* empty encoding */); 7355 ins_pipe(empty); 7356 %} 7357 7358 instruct castPP(rRegP dst) 7359 %{ 7360 match(Set dst (CastPP dst)); 7361 7362 size(0); 7363 format %{ "# castPP of $dst" %} 7364 ins_encode(/* empty encoding */); 7365 ins_pipe(empty); 7366 %} 7367 7368 instruct castII(rRegI dst) 7369 %{ 7370 match(Set dst (CastII dst)); 7371 7372 size(0); 7373 format %{ "# castII of $dst" %} 7374 ins_encode(/* empty encoding */); 7375 ins_cost(0); 7376 ins_pipe(empty); 7377 %} 7378 7379 // LoadP-locked same as a regular LoadP when used with compare-swap 7380 instruct loadPLocked(rRegP dst, memory mem) 7381 %{ 7382 match(Set dst (LoadPLocked mem)); 7383 7384 ins_cost(125); // XXX 7385 format %{ "movq $dst, $mem\t# ptr locked" %} 7386 opcode(0x8B); 7387 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7388 ins_pipe(ialu_reg_mem); // XXX 7389 %} 7390 7391 // Conditional-store of the updated heap-top. 7392 // Used during allocation of the shared heap. 7393 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7394 7395 instruct storePConditional(memory heap_top_ptr, 7396 rax_RegP oldval, rRegP newval, 7397 rFlagsReg cr) 7398 %{ 7399 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7400 7401 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7402 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7403 opcode(0x0F, 0xB1); 7404 ins_encode(lock_prefix, 7405 REX_reg_mem_wide(newval, heap_top_ptr), 7406 OpcP, OpcS, 7407 reg_mem(newval, heap_top_ptr)); 7408 ins_pipe(pipe_cmpxchg); 7409 %} 7410 7411 // Conditional-store of an int value. 7412 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7413 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7414 %{ 7415 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7416 effect(KILL oldval); 7417 7418 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7419 opcode(0x0F, 0xB1); 7420 ins_encode(lock_prefix, 7421 REX_reg_mem(newval, mem), 7422 OpcP, OpcS, 7423 reg_mem(newval, mem)); 7424 ins_pipe(pipe_cmpxchg); 7425 %} 7426 7427 // Conditional-store of a long value. 7428 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7429 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7430 %{ 7431 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7432 effect(KILL oldval); 7433 7434 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7435 opcode(0x0F, 0xB1); 7436 ins_encode(lock_prefix, 7437 REX_reg_mem_wide(newval, mem), 7438 OpcP, OpcS, 7439 reg_mem(newval, mem)); 7440 ins_pipe(pipe_cmpxchg); 7441 %} 7442 7443 7444 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7445 instruct compareAndSwapP(rRegI res, 7446 memory mem_ptr, 7447 rax_RegP oldval, rRegP newval, 7448 rFlagsReg cr) 7449 %{ 7450 predicate(VM_Version::supports_cx8() && 7451 !BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop()); 7452 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7453 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7454 effect(KILL cr, KILL oldval); 7455 7456 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7457 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7458 "sete $res\n\t" 7459 "movzbl $res, $res" %} 7460 opcode(0x0F, 0xB1); 7461 ins_encode(lock_prefix, 7462 REX_reg_mem_wide(newval, mem_ptr), 7463 OpcP, OpcS, 7464 reg_mem(newval, mem_ptr), 7465 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7466 REX_reg_breg(res, res), // movzbl 7467 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7468 ins_pipe( pipe_cmpxchg ); 7469 %} 7470 7471 instruct compareAndSwapP_BS(rRegI res, 7472 memory mem_ptr, 7473 rRegP tmp1, rRegP tmp2, 7474 rax_RegP oldval, rRegP newval, 7475 rFlagsReg cr) 7476 %{ 7477 predicate(VM_Version::supports_cx8() && 7478 BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop() && 7479 n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR); 7480 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7481 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7482 effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 7483 7484 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7485 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7486 "sete $res\n\t" 7487 "movzbl $res, $res" %} 7488 ins_encode %{ 7489 __ access_cmpxchg_oop_c2($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7490 $tmp1$$Register, $tmp2$$Register, 7491 false /* narrow */, false /* exchange */, false /* expect-null */); 7492 %} 7493 ins_pipe( pipe_cmpxchg ); 7494 %} 7495 7496 instruct compareAndSwapP_BS_ExpNull(rRegI res, 7497 memory mem_ptr, 7498 rax_RegP oldval, rRegP newval, 7499 rFlagsReg cr) 7500 %{ 7501 predicate(VM_Version::supports_cx8() && 7502 BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop() && 7503 n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR); 7504 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7505 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7506 effect(KILL cr, KILL oldval); 7507 7508 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7509 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7510 "sete $res\n\t" 7511 "movzbl $res, $res" %} 7512 ins_encode %{ 7513 __ access_cmpxchg_oop_c2($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7514 noreg, noreg, 7515 false /* narrow */, false /* exchange */, true /* expect-null */); 7516 %} 7517 ins_pipe( pipe_cmpxchg ); 7518 %} 7519 7520 instruct compareAndSwapL(rRegI res, 7521 memory mem_ptr, 7522 rax_RegL oldval, rRegL newval, 7523 rFlagsReg cr) 7524 %{ 7525 predicate(VM_Version::supports_cx8()); 7526 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7527 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7528 effect(KILL cr, KILL oldval); 7529 7530 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7531 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7532 "sete $res\n\t" 7533 "movzbl $res, $res" %} 7534 opcode(0x0F, 0xB1); 7535 ins_encode(lock_prefix, 7536 REX_reg_mem_wide(newval, mem_ptr), 7537 OpcP, OpcS, 7538 reg_mem(newval, mem_ptr), 7539 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7540 REX_reg_breg(res, res), // movzbl 7541 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7542 ins_pipe( pipe_cmpxchg ); 7543 %} 7544 7545 instruct compareAndSwapI(rRegI res, 7546 memory mem_ptr, 7547 rax_RegI oldval, rRegI newval, 7548 rFlagsReg cr) 7549 %{ 7550 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7551 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7552 effect(KILL cr, KILL oldval); 7553 7554 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7555 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7556 "sete $res\n\t" 7557 "movzbl $res, $res" %} 7558 opcode(0x0F, 0xB1); 7559 ins_encode(lock_prefix, 7560 REX_reg_mem(newval, mem_ptr), 7561 OpcP, OpcS, 7562 reg_mem(newval, mem_ptr), 7563 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7564 REX_reg_breg(res, res), // movzbl 7565 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7566 ins_pipe( pipe_cmpxchg ); 7567 %} 7568 7569 instruct compareAndSwapB(rRegI res, 7570 memory mem_ptr, 7571 rax_RegI oldval, rRegI newval, 7572 rFlagsReg cr) 7573 %{ 7574 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7575 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7576 effect(KILL cr, KILL oldval); 7577 7578 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7579 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7580 "sete $res\n\t" 7581 "movzbl $res, $res" %} 7582 opcode(0x0F, 0xB0); 7583 ins_encode(lock_prefix, 7584 REX_breg_mem(newval, mem_ptr), 7585 OpcP, OpcS, 7586 reg_mem(newval, mem_ptr), 7587 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7588 REX_reg_breg(res, res), // movzbl 7589 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7590 ins_pipe( pipe_cmpxchg ); 7591 %} 7592 7593 instruct compareAndSwapS(rRegI res, 7594 memory mem_ptr, 7595 rax_RegI oldval, rRegI newval, 7596 rFlagsReg cr) 7597 %{ 7598 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7599 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7600 effect(KILL cr, KILL oldval); 7601 7602 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7603 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7604 "sete $res\n\t" 7605 "movzbl $res, $res" %} 7606 opcode(0x0F, 0xB1); 7607 ins_encode(lock_prefix, 7608 SizePrefix, 7609 REX_reg_mem(newval, mem_ptr), 7610 OpcP, OpcS, 7611 reg_mem(newval, mem_ptr), 7612 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7613 REX_reg_breg(res, res), // movzbl 7614 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7615 ins_pipe( pipe_cmpxchg ); 7616 %} 7617 7618 instruct compareAndSwapN(rRegI res, 7619 memory mem_ptr, 7620 rax_RegN oldval, rRegN newval, 7621 rFlagsReg cr) %{ 7622 predicate(!BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop()); 7623 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7624 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7625 effect(KILL cr, KILL oldval); 7626 7627 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7628 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7629 "sete $res\n\t" 7630 "movzbl $res, $res" %} 7631 opcode(0x0F, 0xB1); 7632 ins_encode(lock_prefix, 7633 REX_reg_mem(newval, mem_ptr), 7634 OpcP, OpcS, 7635 reg_mem(newval, mem_ptr), 7636 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7637 REX_reg_breg(res, res), // movzbl 7638 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7639 ins_pipe( pipe_cmpxchg ); 7640 %} 7641 7642 instruct compareAndSwapN_BS(rRegI res, 7643 memory mem_ptr, 7644 rRegP tmp1, rRegP tmp2, 7645 rax_RegN oldval, rRegN newval, 7646 rFlagsReg cr) %{ 7647 predicate(BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop() && 7648 n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR); 7649 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7650 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7651 effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 7652 7653 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7654 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7655 "sete $res\n\t" 7656 "movzbl $res, $res" %} 7657 ins_encode %{ 7658 __ access_cmpxchg_oop_c2($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7659 $tmp1$$Register, $tmp2$$Register, 7660 true /* narrow */, false /* exchange */, false /* expect-null */); 7661 %} 7662 ins_pipe( pipe_cmpxchg ); 7663 %} 7664 7665 instruct compareAndSwapN_BS_ExpNull(rRegI res, 7666 memory mem_ptr, 7667 rax_RegN oldval, rRegN newval, 7668 rFlagsReg cr) %{ 7669 predicate(BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop() && 7670 n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR); 7671 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7672 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7673 effect(KILL cr, KILL oldval); 7674 7675 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7676 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7677 "sete $res\n\t" 7678 "movzbl $res, $res" %} 7679 ins_encode %{ 7680 __ access_cmpxchg_oop_c2($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7681 noreg, noreg, 7682 true /* narrow */, false /* exchange */, true /* expect-null */); 7683 %} 7684 ins_pipe( pipe_cmpxchg ); 7685 %} 7686 7687 instruct compareAndExchangeB( 7688 memory mem_ptr, 7689 rax_RegI oldval, rRegI newval, 7690 rFlagsReg cr) 7691 %{ 7692 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7693 effect(KILL cr); 7694 7695 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7696 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7697 opcode(0x0F, 0xB0); 7698 ins_encode(lock_prefix, 7699 REX_breg_mem(newval, mem_ptr), 7700 OpcP, OpcS, 7701 reg_mem(newval, mem_ptr) // lock cmpxchg 7702 ); 7703 ins_pipe( pipe_cmpxchg ); 7704 %} 7705 7706 instruct compareAndExchangeS( 7707 memory mem_ptr, 7708 rax_RegI oldval, rRegI newval, 7709 rFlagsReg cr) 7710 %{ 7711 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7712 effect(KILL cr); 7713 7714 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7715 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7716 opcode(0x0F, 0xB1); 7717 ins_encode(lock_prefix, 7718 SizePrefix, 7719 REX_reg_mem(newval, mem_ptr), 7720 OpcP, OpcS, 7721 reg_mem(newval, mem_ptr) // lock cmpxchg 7722 ); 7723 ins_pipe( pipe_cmpxchg ); 7724 %} 7725 7726 instruct compareAndExchangeI( 7727 memory mem_ptr, 7728 rax_RegI oldval, rRegI newval, 7729 rFlagsReg cr) 7730 %{ 7731 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7732 effect(KILL cr); 7733 7734 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7735 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7736 opcode(0x0F, 0xB1); 7737 ins_encode(lock_prefix, 7738 REX_reg_mem(newval, mem_ptr), 7739 OpcP, OpcS, 7740 reg_mem(newval, mem_ptr) // lock cmpxchg 7741 ); 7742 ins_pipe( pipe_cmpxchg ); 7743 %} 7744 7745 instruct compareAndExchangeL( 7746 memory mem_ptr, 7747 rax_RegL oldval, rRegL newval, 7748 rFlagsReg cr) 7749 %{ 7750 predicate(VM_Version::supports_cx8()); 7751 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7752 effect(KILL cr); 7753 7754 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7755 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7756 opcode(0x0F, 0xB1); 7757 ins_encode(lock_prefix, 7758 REX_reg_mem_wide(newval, mem_ptr), 7759 OpcP, OpcS, 7760 reg_mem(newval, mem_ptr) // lock cmpxchg 7761 ); 7762 ins_pipe( pipe_cmpxchg ); 7763 %} 7764 7765 instruct compareAndExchangeN( 7766 memory mem_ptr, 7767 rax_RegN oldval, rRegN newval, 7768 rFlagsReg cr) %{ 7769 predicate(!BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop()); 7770 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7771 effect(KILL cr); 7772 7773 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7774 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7775 opcode(0x0F, 0xB1); 7776 ins_encode(lock_prefix, 7777 REX_reg_mem(newval, mem_ptr), 7778 OpcP, OpcS, 7779 reg_mem(newval, mem_ptr) // lock cmpxchg 7780 ); 7781 ins_pipe( pipe_cmpxchg ); 7782 %} 7783 7784 instruct compareAndExchangeN_BS(memory mem_ptr, 7785 rRegP tmp1, rRegP tmp2, 7786 rax_RegN oldval, rRegN newval, 7787 rFlagsReg cr) %{ 7788 predicate(BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop() && 7789 n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR); 7790 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7791 effect(TEMP tmp1, TEMP tmp2, KILL cr); 7792 7793 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7794 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7795 ins_encode %{ 7796 __ access_cmpxchg_oop_c2(noreg, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7797 $tmp1$$Register, $tmp2$$Register, 7798 true /* narrow */, true /* exchange */, false /* expect-null */); 7799 %} 7800 ins_pipe( pipe_cmpxchg ); 7801 %} 7802 7803 instruct compareAndExchangeN_BS_ExpNull(memory mem_ptr, 7804 rax_RegN oldval, rRegN newval, 7805 rFlagsReg cr) %{ 7806 predicate(BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop() && 7807 n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR); 7808 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7809 effect(KILL cr); 7810 7811 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7812 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7813 ins_encode %{ 7814 __ access_cmpxchg_oop_c2(noreg, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7815 noreg, noreg, 7816 true /* narrow */, true /* exchange */, true /* expect-null */); 7817 %} 7818 ins_pipe( pipe_cmpxchg ); 7819 %} 7820 7821 instruct compareAndExchangeP( 7822 memory mem_ptr, 7823 rax_RegP oldval, rRegP newval, 7824 rFlagsReg cr) 7825 %{ 7826 predicate(VM_Version::supports_cx8() && 7827 !BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop()); 7828 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7829 effect(KILL cr); 7830 7831 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7832 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7833 opcode(0x0F, 0xB1); 7834 ins_encode(lock_prefix, 7835 REX_reg_mem_wide(newval, mem_ptr), 7836 OpcP, OpcS, 7837 reg_mem(newval, mem_ptr) // lock cmpxchg 7838 ); 7839 ins_pipe( pipe_cmpxchg ); 7840 %} 7841 7842 instruct compareAndExchangeP_BS(memory mem_ptr, 7843 rRegP tmp1, rRegP tmp2, 7844 rax_RegP oldval, rRegP newval, 7845 rFlagsReg cr) 7846 %{ 7847 predicate(VM_Version::supports_cx8() && 7848 BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop() && 7849 n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR); 7850 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7851 effect(TEMP tmp1, TEMP tmp2, KILL cr); 7852 7853 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7854 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7855 ins_encode %{ 7856 __ access_cmpxchg_oop_c2(noreg, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7857 $tmp1$$Register, $tmp2$$Register, 7858 false /* narrow */, true /* exchange */, false /* expect-null */); 7859 %} 7860 ins_pipe( pipe_cmpxchg ); 7861 %} 7862 7863 instruct compareAndExchangeP_BS_ExpNull(memory mem_ptr, 7864 rax_RegP oldval, rRegP newval, 7865 rFlagsReg cr) 7866 %{ 7867 predicate(VM_Version::supports_cx8() && 7868 BarrierSet::barrier_set()->barrier_set_assembler()->handle_cmpxchg_oop() && 7869 n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR); 7870 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7871 effect(KILL cr); 7872 7873 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7874 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7875 ins_encode %{ 7876 __ access_cmpxchg_oop_c2(noreg, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7877 noreg, noreg, 7878 false /* narrow */, true /* exchange */, true /* expect-null */); 7879 %} 7880 ins_pipe( pipe_cmpxchg ); 7881 %} 7882 7883 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7884 predicate(n->as_LoadStore()->result_not_used()); 7885 match(Set dummy (GetAndAddB mem add)); 7886 effect(KILL cr); 7887 format %{ "ADDB [$mem],$add" %} 7888 ins_encode %{ 7889 if (os::is_MP()) { __ lock(); } 7890 __ addb($mem$$Address, $add$$constant); 7891 %} 7892 ins_pipe( pipe_cmpxchg ); 7893 %} 7894 7895 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7896 match(Set newval (GetAndAddB mem newval)); 7897 effect(KILL cr); 7898 format %{ "XADDB [$mem],$newval" %} 7899 ins_encode %{ 7900 if (os::is_MP()) { __ lock(); } 7901 __ xaddb($mem$$Address, $newval$$Register); 7902 %} 7903 ins_pipe( pipe_cmpxchg ); 7904 %} 7905 7906 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7907 predicate(n->as_LoadStore()->result_not_used()); 7908 match(Set dummy (GetAndAddS mem add)); 7909 effect(KILL cr); 7910 format %{ "ADDW [$mem],$add" %} 7911 ins_encode %{ 7912 if (os::is_MP()) { __ lock(); } 7913 __ addw($mem$$Address, $add$$constant); 7914 %} 7915 ins_pipe( pipe_cmpxchg ); 7916 %} 7917 7918 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7919 match(Set newval (GetAndAddS mem newval)); 7920 effect(KILL cr); 7921 format %{ "XADDW [$mem],$newval" %} 7922 ins_encode %{ 7923 if (os::is_MP()) { __ lock(); } 7924 __ xaddw($mem$$Address, $newval$$Register); 7925 %} 7926 ins_pipe( pipe_cmpxchg ); 7927 %} 7928 7929 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7930 predicate(n->as_LoadStore()->result_not_used()); 7931 match(Set dummy (GetAndAddI mem add)); 7932 effect(KILL cr); 7933 format %{ "ADDL [$mem],$add" %} 7934 ins_encode %{ 7935 if (os::is_MP()) { __ lock(); } 7936 __ addl($mem$$Address, $add$$constant); 7937 %} 7938 ins_pipe( pipe_cmpxchg ); 7939 %} 7940 7941 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7942 match(Set newval (GetAndAddI mem newval)); 7943 effect(KILL cr); 7944 format %{ "XADDL [$mem],$newval" %} 7945 ins_encode %{ 7946 if (os::is_MP()) { __ lock(); } 7947 __ xaddl($mem$$Address, $newval$$Register); 7948 %} 7949 ins_pipe( pipe_cmpxchg ); 7950 %} 7951 7952 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7953 predicate(n->as_LoadStore()->result_not_used()); 7954 match(Set dummy (GetAndAddL mem add)); 7955 effect(KILL cr); 7956 format %{ "ADDQ [$mem],$add" %} 7957 ins_encode %{ 7958 if (os::is_MP()) { __ lock(); } 7959 __ addq($mem$$Address, $add$$constant); 7960 %} 7961 ins_pipe( pipe_cmpxchg ); 7962 %} 7963 7964 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7965 match(Set newval (GetAndAddL mem newval)); 7966 effect(KILL cr); 7967 format %{ "XADDQ [$mem],$newval" %} 7968 ins_encode %{ 7969 if (os::is_MP()) { __ lock(); } 7970 __ xaddq($mem$$Address, $newval$$Register); 7971 %} 7972 ins_pipe( pipe_cmpxchg ); 7973 %} 7974 7975 instruct xchgB( memory mem, rRegI newval) %{ 7976 match(Set newval (GetAndSetB mem newval)); 7977 format %{ "XCHGB $newval,[$mem]" %} 7978 ins_encode %{ 7979 __ xchgb($newval$$Register, $mem$$Address); 7980 %} 7981 ins_pipe( pipe_cmpxchg ); 7982 %} 7983 7984 instruct xchgS( memory mem, rRegI newval) %{ 7985 match(Set newval (GetAndSetS mem newval)); 7986 format %{ "XCHGW $newval,[$mem]" %} 7987 ins_encode %{ 7988 __ xchgw($newval$$Register, $mem$$Address); 7989 %} 7990 ins_pipe( pipe_cmpxchg ); 7991 %} 7992 7993 instruct xchgI( memory mem, rRegI newval) %{ 7994 match(Set newval (GetAndSetI mem newval)); 7995 format %{ "XCHGL $newval,[$mem]" %} 7996 ins_encode %{ 7997 __ xchgl($newval$$Register, $mem$$Address); 7998 %} 7999 ins_pipe( pipe_cmpxchg ); 8000 %} 8001 8002 instruct xchgL( memory mem, rRegL newval) %{ 8003 match(Set newval (GetAndSetL mem newval)); 8004 format %{ "XCHGL $newval,[$mem]" %} 8005 ins_encode %{ 8006 __ xchgq($newval$$Register, $mem$$Address); 8007 %} 8008 ins_pipe( pipe_cmpxchg ); 8009 %} 8010 8011 instruct xchgP( memory mem, rRegP newval) %{ 8012 match(Set newval (GetAndSetP mem newval)); 8013 format %{ "XCHGQ $newval,[$mem]" %} 8014 ins_encode %{ 8015 __ xchgq($newval$$Register, $mem$$Address); 8016 %} 8017 ins_pipe( pipe_cmpxchg ); 8018 %} 8019 8020 instruct xchgN( memory mem, rRegN newval) %{ 8021 match(Set newval (GetAndSetN mem newval)); 8022 format %{ "XCHGL $newval,$mem]" %} 8023 ins_encode %{ 8024 __ xchgl($newval$$Register, $mem$$Address); 8025 %} 8026 ins_pipe( pipe_cmpxchg ); 8027 %} 8028 8029 //----------Subtraction Instructions------------------------------------------- 8030 8031 // Integer Subtraction Instructions 8032 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8033 %{ 8034 match(Set dst (SubI dst src)); 8035 effect(KILL cr); 8036 8037 format %{ "subl $dst, $src\t# int" %} 8038 opcode(0x2B); 8039 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8040 ins_pipe(ialu_reg_reg); 8041 %} 8042 8043 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8044 %{ 8045 match(Set dst (SubI dst src)); 8046 effect(KILL cr); 8047 8048 format %{ "subl $dst, $src\t# int" %} 8049 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8050 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8051 ins_pipe(ialu_reg); 8052 %} 8053 8054 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8055 %{ 8056 match(Set dst (SubI dst (LoadI src))); 8057 effect(KILL cr); 8058 8059 ins_cost(125); 8060 format %{ "subl $dst, $src\t# int" %} 8061 opcode(0x2B); 8062 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8063 ins_pipe(ialu_reg_mem); 8064 %} 8065 8066 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8067 %{ 8068 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8069 effect(KILL cr); 8070 8071 ins_cost(150); 8072 format %{ "subl $dst, $src\t# int" %} 8073 opcode(0x29); /* Opcode 29 /r */ 8074 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8075 ins_pipe(ialu_mem_reg); 8076 %} 8077 8078 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8079 %{ 8080 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8081 effect(KILL cr); 8082 8083 ins_cost(125); // XXX 8084 format %{ "subl $dst, $src\t# int" %} 8085 opcode(0x81); /* Opcode 81 /5 id */ 8086 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8087 ins_pipe(ialu_mem_imm); 8088 %} 8089 8090 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8091 %{ 8092 match(Set dst (SubL dst src)); 8093 effect(KILL cr); 8094 8095 format %{ "subq $dst, $src\t# long" %} 8096 opcode(0x2B); 8097 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8098 ins_pipe(ialu_reg_reg); 8099 %} 8100 8101 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8102 %{ 8103 match(Set dst (SubL dst src)); 8104 effect(KILL cr); 8105 8106 format %{ "subq $dst, $src\t# long" %} 8107 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8108 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8109 ins_pipe(ialu_reg); 8110 %} 8111 8112 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8113 %{ 8114 match(Set dst (SubL dst (LoadL src))); 8115 effect(KILL cr); 8116 8117 ins_cost(125); 8118 format %{ "subq $dst, $src\t# long" %} 8119 opcode(0x2B); 8120 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8121 ins_pipe(ialu_reg_mem); 8122 %} 8123 8124 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8125 %{ 8126 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8127 effect(KILL cr); 8128 8129 ins_cost(150); 8130 format %{ "subq $dst, $src\t# long" %} 8131 opcode(0x29); /* Opcode 29 /r */ 8132 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8133 ins_pipe(ialu_mem_reg); 8134 %} 8135 8136 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8137 %{ 8138 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8139 effect(KILL cr); 8140 8141 ins_cost(125); // XXX 8142 format %{ "subq $dst, $src\t# long" %} 8143 opcode(0x81); /* Opcode 81 /5 id */ 8144 ins_encode(REX_mem_wide(dst), 8145 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8146 ins_pipe(ialu_mem_imm); 8147 %} 8148 8149 // Subtract from a pointer 8150 // XXX hmpf??? 8151 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8152 %{ 8153 match(Set dst (AddP dst (SubI zero src))); 8154 effect(KILL cr); 8155 8156 format %{ "subq $dst, $src\t# ptr - int" %} 8157 opcode(0x2B); 8158 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8159 ins_pipe(ialu_reg_reg); 8160 %} 8161 8162 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8163 %{ 8164 match(Set dst (SubI zero dst)); 8165 effect(KILL cr); 8166 8167 format %{ "negl $dst\t# int" %} 8168 opcode(0xF7, 0x03); // Opcode F7 /3 8169 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8170 ins_pipe(ialu_reg); 8171 %} 8172 8173 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8174 %{ 8175 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8176 effect(KILL cr); 8177 8178 format %{ "negl $dst\t# int" %} 8179 opcode(0xF7, 0x03); // Opcode F7 /3 8180 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8181 ins_pipe(ialu_reg); 8182 %} 8183 8184 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8185 %{ 8186 match(Set dst (SubL zero dst)); 8187 effect(KILL cr); 8188 8189 format %{ "negq $dst\t# long" %} 8190 opcode(0xF7, 0x03); // Opcode F7 /3 8191 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8192 ins_pipe(ialu_reg); 8193 %} 8194 8195 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8196 %{ 8197 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8198 effect(KILL cr); 8199 8200 format %{ "negq $dst\t# long" %} 8201 opcode(0xF7, 0x03); // Opcode F7 /3 8202 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8203 ins_pipe(ialu_reg); 8204 %} 8205 8206 //----------Multiplication/Division Instructions------------------------------- 8207 // Integer Multiplication Instructions 8208 // Multiply Register 8209 8210 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8211 %{ 8212 match(Set dst (MulI dst src)); 8213 effect(KILL cr); 8214 8215 ins_cost(300); 8216 format %{ "imull $dst, $src\t# int" %} 8217 opcode(0x0F, 0xAF); 8218 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8219 ins_pipe(ialu_reg_reg_alu0); 8220 %} 8221 8222 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8223 %{ 8224 match(Set dst (MulI src imm)); 8225 effect(KILL cr); 8226 8227 ins_cost(300); 8228 format %{ "imull $dst, $src, $imm\t# int" %} 8229 opcode(0x69); /* 69 /r id */ 8230 ins_encode(REX_reg_reg(dst, src), 8231 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8232 ins_pipe(ialu_reg_reg_alu0); 8233 %} 8234 8235 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8236 %{ 8237 match(Set dst (MulI dst (LoadI src))); 8238 effect(KILL cr); 8239 8240 ins_cost(350); 8241 format %{ "imull $dst, $src\t# int" %} 8242 opcode(0x0F, 0xAF); 8243 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8244 ins_pipe(ialu_reg_mem_alu0); 8245 %} 8246 8247 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8248 %{ 8249 match(Set dst (MulI (LoadI src) imm)); 8250 effect(KILL cr); 8251 8252 ins_cost(300); 8253 format %{ "imull $dst, $src, $imm\t# int" %} 8254 opcode(0x69); /* 69 /r id */ 8255 ins_encode(REX_reg_mem(dst, src), 8256 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8257 ins_pipe(ialu_reg_mem_alu0); 8258 %} 8259 8260 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8261 %{ 8262 match(Set dst (MulL dst src)); 8263 effect(KILL cr); 8264 8265 ins_cost(300); 8266 format %{ "imulq $dst, $src\t# long" %} 8267 opcode(0x0F, 0xAF); 8268 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8269 ins_pipe(ialu_reg_reg_alu0); 8270 %} 8271 8272 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8273 %{ 8274 match(Set dst (MulL src imm)); 8275 effect(KILL cr); 8276 8277 ins_cost(300); 8278 format %{ "imulq $dst, $src, $imm\t# long" %} 8279 opcode(0x69); /* 69 /r id */ 8280 ins_encode(REX_reg_reg_wide(dst, src), 8281 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8282 ins_pipe(ialu_reg_reg_alu0); 8283 %} 8284 8285 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8286 %{ 8287 match(Set dst (MulL dst (LoadL src))); 8288 effect(KILL cr); 8289 8290 ins_cost(350); 8291 format %{ "imulq $dst, $src\t# long" %} 8292 opcode(0x0F, 0xAF); 8293 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8294 ins_pipe(ialu_reg_mem_alu0); 8295 %} 8296 8297 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8298 %{ 8299 match(Set dst (MulL (LoadL src) imm)); 8300 effect(KILL cr); 8301 8302 ins_cost(300); 8303 format %{ "imulq $dst, $src, $imm\t# long" %} 8304 opcode(0x69); /* 69 /r id */ 8305 ins_encode(REX_reg_mem_wide(dst, src), 8306 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8307 ins_pipe(ialu_reg_mem_alu0); 8308 %} 8309 8310 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8311 %{ 8312 match(Set dst (MulHiL src rax)); 8313 effect(USE_KILL rax, KILL cr); 8314 8315 ins_cost(300); 8316 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8317 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8318 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8319 ins_pipe(ialu_reg_reg_alu0); 8320 %} 8321 8322 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8323 rFlagsReg cr) 8324 %{ 8325 match(Set rax (DivI rax div)); 8326 effect(KILL rdx, KILL cr); 8327 8328 ins_cost(30*100+10*100); // XXX 8329 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8330 "jne,s normal\n\t" 8331 "xorl rdx, rdx\n\t" 8332 "cmpl $div, -1\n\t" 8333 "je,s done\n" 8334 "normal: cdql\n\t" 8335 "idivl $div\n" 8336 "done:" %} 8337 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8338 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8339 ins_pipe(ialu_reg_reg_alu0); 8340 %} 8341 8342 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8343 rFlagsReg cr) 8344 %{ 8345 match(Set rax (DivL rax div)); 8346 effect(KILL rdx, KILL cr); 8347 8348 ins_cost(30*100+10*100); // XXX 8349 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8350 "cmpq rax, rdx\n\t" 8351 "jne,s normal\n\t" 8352 "xorl rdx, rdx\n\t" 8353 "cmpq $div, -1\n\t" 8354 "je,s done\n" 8355 "normal: cdqq\n\t" 8356 "idivq $div\n" 8357 "done:" %} 8358 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8359 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8360 ins_pipe(ialu_reg_reg_alu0); 8361 %} 8362 8363 // Integer DIVMOD with Register, both quotient and mod results 8364 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8365 rFlagsReg cr) 8366 %{ 8367 match(DivModI rax div); 8368 effect(KILL cr); 8369 8370 ins_cost(30*100+10*100); // XXX 8371 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8372 "jne,s normal\n\t" 8373 "xorl rdx, rdx\n\t" 8374 "cmpl $div, -1\n\t" 8375 "je,s done\n" 8376 "normal: cdql\n\t" 8377 "idivl $div\n" 8378 "done:" %} 8379 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8380 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8381 ins_pipe(pipe_slow); 8382 %} 8383 8384 // Long DIVMOD with Register, both quotient and mod results 8385 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8386 rFlagsReg cr) 8387 %{ 8388 match(DivModL rax div); 8389 effect(KILL cr); 8390 8391 ins_cost(30*100+10*100); // XXX 8392 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8393 "cmpq rax, rdx\n\t" 8394 "jne,s normal\n\t" 8395 "xorl rdx, rdx\n\t" 8396 "cmpq $div, -1\n\t" 8397 "je,s done\n" 8398 "normal: cdqq\n\t" 8399 "idivq $div\n" 8400 "done:" %} 8401 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8402 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8403 ins_pipe(pipe_slow); 8404 %} 8405 8406 //----------- DivL-By-Constant-Expansions-------------------------------------- 8407 // DivI cases are handled by the compiler 8408 8409 // Magic constant, reciprocal of 10 8410 instruct loadConL_0x6666666666666667(rRegL dst) 8411 %{ 8412 effect(DEF dst); 8413 8414 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8415 ins_encode(load_immL(dst, 0x6666666666666667)); 8416 ins_pipe(ialu_reg); 8417 %} 8418 8419 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8420 %{ 8421 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8422 8423 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8424 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8425 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8426 ins_pipe(ialu_reg_reg_alu0); 8427 %} 8428 8429 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8430 %{ 8431 effect(USE_DEF dst, KILL cr); 8432 8433 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8434 opcode(0xC1, 0x7); /* C1 /7 ib */ 8435 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8436 ins_pipe(ialu_reg); 8437 %} 8438 8439 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8440 %{ 8441 effect(USE_DEF dst, KILL cr); 8442 8443 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8444 opcode(0xC1, 0x7); /* C1 /7 ib */ 8445 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8446 ins_pipe(ialu_reg); 8447 %} 8448 8449 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8450 %{ 8451 match(Set dst (DivL src div)); 8452 8453 ins_cost((5+8)*100); 8454 expand %{ 8455 rax_RegL rax; // Killed temp 8456 rFlagsReg cr; // Killed 8457 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8458 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8459 sarL_rReg_63(src, cr); // sarq src, 63 8460 sarL_rReg_2(dst, cr); // sarq rdx, 2 8461 subL_rReg(dst, src, cr); // subl rdx, src 8462 %} 8463 %} 8464 8465 //----------------------------------------------------------------------------- 8466 8467 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8468 rFlagsReg cr) 8469 %{ 8470 match(Set rdx (ModI rax div)); 8471 effect(KILL rax, KILL cr); 8472 8473 ins_cost(300); // XXX 8474 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8475 "jne,s normal\n\t" 8476 "xorl rdx, rdx\n\t" 8477 "cmpl $div, -1\n\t" 8478 "je,s done\n" 8479 "normal: cdql\n\t" 8480 "idivl $div\n" 8481 "done:" %} 8482 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8483 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8484 ins_pipe(ialu_reg_reg_alu0); 8485 %} 8486 8487 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8488 rFlagsReg cr) 8489 %{ 8490 match(Set rdx (ModL rax div)); 8491 effect(KILL rax, KILL cr); 8492 8493 ins_cost(300); // XXX 8494 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8495 "cmpq rax, rdx\n\t" 8496 "jne,s normal\n\t" 8497 "xorl rdx, rdx\n\t" 8498 "cmpq $div, -1\n\t" 8499 "je,s done\n" 8500 "normal: cdqq\n\t" 8501 "idivq $div\n" 8502 "done:" %} 8503 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8504 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8505 ins_pipe(ialu_reg_reg_alu0); 8506 %} 8507 8508 // Integer Shift Instructions 8509 // Shift Left by one 8510 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8511 %{ 8512 match(Set dst (LShiftI dst shift)); 8513 effect(KILL cr); 8514 8515 format %{ "sall $dst, $shift" %} 8516 opcode(0xD1, 0x4); /* D1 /4 */ 8517 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8518 ins_pipe(ialu_reg); 8519 %} 8520 8521 // Shift Left by one 8522 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8523 %{ 8524 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8525 effect(KILL cr); 8526 8527 format %{ "sall $dst, $shift\t" %} 8528 opcode(0xD1, 0x4); /* D1 /4 */ 8529 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8530 ins_pipe(ialu_mem_imm); 8531 %} 8532 8533 // Shift Left by 8-bit immediate 8534 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8535 %{ 8536 match(Set dst (LShiftI dst shift)); 8537 effect(KILL cr); 8538 8539 format %{ "sall $dst, $shift" %} 8540 opcode(0xC1, 0x4); /* C1 /4 ib */ 8541 ins_encode(reg_opc_imm(dst, shift)); 8542 ins_pipe(ialu_reg); 8543 %} 8544 8545 // Shift Left by 8-bit immediate 8546 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8547 %{ 8548 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8549 effect(KILL cr); 8550 8551 format %{ "sall $dst, $shift" %} 8552 opcode(0xC1, 0x4); /* C1 /4 ib */ 8553 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8554 ins_pipe(ialu_mem_imm); 8555 %} 8556 8557 // Shift Left by variable 8558 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8559 %{ 8560 match(Set dst (LShiftI dst shift)); 8561 effect(KILL cr); 8562 8563 format %{ "sall $dst, $shift" %} 8564 opcode(0xD3, 0x4); /* D3 /4 */ 8565 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8566 ins_pipe(ialu_reg_reg); 8567 %} 8568 8569 // Shift Left by variable 8570 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8571 %{ 8572 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8573 effect(KILL cr); 8574 8575 format %{ "sall $dst, $shift" %} 8576 opcode(0xD3, 0x4); /* D3 /4 */ 8577 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8578 ins_pipe(ialu_mem_reg); 8579 %} 8580 8581 // Arithmetic shift right by one 8582 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8583 %{ 8584 match(Set dst (RShiftI dst shift)); 8585 effect(KILL cr); 8586 8587 format %{ "sarl $dst, $shift" %} 8588 opcode(0xD1, 0x7); /* D1 /7 */ 8589 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8590 ins_pipe(ialu_reg); 8591 %} 8592 8593 // Arithmetic shift right by one 8594 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8595 %{ 8596 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8597 effect(KILL cr); 8598 8599 format %{ "sarl $dst, $shift" %} 8600 opcode(0xD1, 0x7); /* D1 /7 */ 8601 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8602 ins_pipe(ialu_mem_imm); 8603 %} 8604 8605 // Arithmetic Shift Right by 8-bit immediate 8606 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8607 %{ 8608 match(Set dst (RShiftI dst shift)); 8609 effect(KILL cr); 8610 8611 format %{ "sarl $dst, $shift" %} 8612 opcode(0xC1, 0x7); /* C1 /7 ib */ 8613 ins_encode(reg_opc_imm(dst, shift)); 8614 ins_pipe(ialu_mem_imm); 8615 %} 8616 8617 // Arithmetic Shift Right by 8-bit immediate 8618 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8619 %{ 8620 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8621 effect(KILL cr); 8622 8623 format %{ "sarl $dst, $shift" %} 8624 opcode(0xC1, 0x7); /* C1 /7 ib */ 8625 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8626 ins_pipe(ialu_mem_imm); 8627 %} 8628 8629 // Arithmetic Shift Right by variable 8630 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8631 %{ 8632 match(Set dst (RShiftI dst shift)); 8633 effect(KILL cr); 8634 8635 format %{ "sarl $dst, $shift" %} 8636 opcode(0xD3, 0x7); /* D3 /7 */ 8637 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8638 ins_pipe(ialu_reg_reg); 8639 %} 8640 8641 // Arithmetic Shift Right by variable 8642 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8643 %{ 8644 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8645 effect(KILL cr); 8646 8647 format %{ "sarl $dst, $shift" %} 8648 opcode(0xD3, 0x7); /* D3 /7 */ 8649 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8650 ins_pipe(ialu_mem_reg); 8651 %} 8652 8653 // Logical shift right by one 8654 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8655 %{ 8656 match(Set dst (URShiftI dst shift)); 8657 effect(KILL cr); 8658 8659 format %{ "shrl $dst, $shift" %} 8660 opcode(0xD1, 0x5); /* D1 /5 */ 8661 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8662 ins_pipe(ialu_reg); 8663 %} 8664 8665 // Logical shift right by one 8666 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8667 %{ 8668 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8669 effect(KILL cr); 8670 8671 format %{ "shrl $dst, $shift" %} 8672 opcode(0xD1, 0x5); /* D1 /5 */ 8673 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8674 ins_pipe(ialu_mem_imm); 8675 %} 8676 8677 // Logical Shift Right by 8-bit immediate 8678 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8679 %{ 8680 match(Set dst (URShiftI dst shift)); 8681 effect(KILL cr); 8682 8683 format %{ "shrl $dst, $shift" %} 8684 opcode(0xC1, 0x5); /* C1 /5 ib */ 8685 ins_encode(reg_opc_imm(dst, shift)); 8686 ins_pipe(ialu_reg); 8687 %} 8688 8689 // Logical Shift Right by 8-bit immediate 8690 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8691 %{ 8692 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8693 effect(KILL cr); 8694 8695 format %{ "shrl $dst, $shift" %} 8696 opcode(0xC1, 0x5); /* C1 /5 ib */ 8697 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8698 ins_pipe(ialu_mem_imm); 8699 %} 8700 8701 // Logical Shift Right by variable 8702 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8703 %{ 8704 match(Set dst (URShiftI dst shift)); 8705 effect(KILL cr); 8706 8707 format %{ "shrl $dst, $shift" %} 8708 opcode(0xD3, 0x5); /* D3 /5 */ 8709 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8710 ins_pipe(ialu_reg_reg); 8711 %} 8712 8713 // Logical Shift Right by variable 8714 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8715 %{ 8716 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8717 effect(KILL cr); 8718 8719 format %{ "shrl $dst, $shift" %} 8720 opcode(0xD3, 0x5); /* D3 /5 */ 8721 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8722 ins_pipe(ialu_mem_reg); 8723 %} 8724 8725 // Long Shift Instructions 8726 // Shift Left by one 8727 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8728 %{ 8729 match(Set dst (LShiftL dst shift)); 8730 effect(KILL cr); 8731 8732 format %{ "salq $dst, $shift" %} 8733 opcode(0xD1, 0x4); /* D1 /4 */ 8734 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8735 ins_pipe(ialu_reg); 8736 %} 8737 8738 // Shift Left by one 8739 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8740 %{ 8741 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8742 effect(KILL cr); 8743 8744 format %{ "salq $dst, $shift" %} 8745 opcode(0xD1, 0x4); /* D1 /4 */ 8746 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8747 ins_pipe(ialu_mem_imm); 8748 %} 8749 8750 // Shift Left by 8-bit immediate 8751 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8752 %{ 8753 match(Set dst (LShiftL dst shift)); 8754 effect(KILL cr); 8755 8756 format %{ "salq $dst, $shift" %} 8757 opcode(0xC1, 0x4); /* C1 /4 ib */ 8758 ins_encode(reg_opc_imm_wide(dst, shift)); 8759 ins_pipe(ialu_reg); 8760 %} 8761 8762 // Shift Left by 8-bit immediate 8763 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8764 %{ 8765 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8766 effect(KILL cr); 8767 8768 format %{ "salq $dst, $shift" %} 8769 opcode(0xC1, 0x4); /* C1 /4 ib */ 8770 ins_encode(REX_mem_wide(dst), OpcP, 8771 RM_opc_mem(secondary, dst), Con8or32(shift)); 8772 ins_pipe(ialu_mem_imm); 8773 %} 8774 8775 // Shift Left by variable 8776 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8777 %{ 8778 match(Set dst (LShiftL dst shift)); 8779 effect(KILL cr); 8780 8781 format %{ "salq $dst, $shift" %} 8782 opcode(0xD3, 0x4); /* D3 /4 */ 8783 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8784 ins_pipe(ialu_reg_reg); 8785 %} 8786 8787 // Shift Left by variable 8788 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8789 %{ 8790 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8791 effect(KILL cr); 8792 8793 format %{ "salq $dst, $shift" %} 8794 opcode(0xD3, 0x4); /* D3 /4 */ 8795 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8796 ins_pipe(ialu_mem_reg); 8797 %} 8798 8799 // Arithmetic shift right by one 8800 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8801 %{ 8802 match(Set dst (RShiftL dst shift)); 8803 effect(KILL cr); 8804 8805 format %{ "sarq $dst, $shift" %} 8806 opcode(0xD1, 0x7); /* D1 /7 */ 8807 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8808 ins_pipe(ialu_reg); 8809 %} 8810 8811 // Arithmetic shift right by one 8812 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8813 %{ 8814 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8815 effect(KILL cr); 8816 8817 format %{ "sarq $dst, $shift" %} 8818 opcode(0xD1, 0x7); /* D1 /7 */ 8819 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8820 ins_pipe(ialu_mem_imm); 8821 %} 8822 8823 // Arithmetic Shift Right by 8-bit immediate 8824 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8825 %{ 8826 match(Set dst (RShiftL dst shift)); 8827 effect(KILL cr); 8828 8829 format %{ "sarq $dst, $shift" %} 8830 opcode(0xC1, 0x7); /* C1 /7 ib */ 8831 ins_encode(reg_opc_imm_wide(dst, shift)); 8832 ins_pipe(ialu_mem_imm); 8833 %} 8834 8835 // Arithmetic Shift Right by 8-bit immediate 8836 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8837 %{ 8838 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8839 effect(KILL cr); 8840 8841 format %{ "sarq $dst, $shift" %} 8842 opcode(0xC1, 0x7); /* C1 /7 ib */ 8843 ins_encode(REX_mem_wide(dst), OpcP, 8844 RM_opc_mem(secondary, dst), Con8or32(shift)); 8845 ins_pipe(ialu_mem_imm); 8846 %} 8847 8848 // Arithmetic Shift Right by variable 8849 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8850 %{ 8851 match(Set dst (RShiftL dst shift)); 8852 effect(KILL cr); 8853 8854 format %{ "sarq $dst, $shift" %} 8855 opcode(0xD3, 0x7); /* D3 /7 */ 8856 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8857 ins_pipe(ialu_reg_reg); 8858 %} 8859 8860 // Arithmetic Shift Right by variable 8861 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8862 %{ 8863 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8864 effect(KILL cr); 8865 8866 format %{ "sarq $dst, $shift" %} 8867 opcode(0xD3, 0x7); /* D3 /7 */ 8868 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8869 ins_pipe(ialu_mem_reg); 8870 %} 8871 8872 // Logical shift right by one 8873 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8874 %{ 8875 match(Set dst (URShiftL dst shift)); 8876 effect(KILL cr); 8877 8878 format %{ "shrq $dst, $shift" %} 8879 opcode(0xD1, 0x5); /* D1 /5 */ 8880 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8881 ins_pipe(ialu_reg); 8882 %} 8883 8884 // Logical shift right by one 8885 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8886 %{ 8887 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8888 effect(KILL cr); 8889 8890 format %{ "shrq $dst, $shift" %} 8891 opcode(0xD1, 0x5); /* D1 /5 */ 8892 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8893 ins_pipe(ialu_mem_imm); 8894 %} 8895 8896 // Logical Shift Right by 8-bit immediate 8897 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8898 %{ 8899 match(Set dst (URShiftL dst shift)); 8900 effect(KILL cr); 8901 8902 format %{ "shrq $dst, $shift" %} 8903 opcode(0xC1, 0x5); /* C1 /5 ib */ 8904 ins_encode(reg_opc_imm_wide(dst, shift)); 8905 ins_pipe(ialu_reg); 8906 %} 8907 8908 8909 // Logical Shift Right by 8-bit immediate 8910 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8911 %{ 8912 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8913 effect(KILL cr); 8914 8915 format %{ "shrq $dst, $shift" %} 8916 opcode(0xC1, 0x5); /* C1 /5 ib */ 8917 ins_encode(REX_mem_wide(dst), OpcP, 8918 RM_opc_mem(secondary, dst), Con8or32(shift)); 8919 ins_pipe(ialu_mem_imm); 8920 %} 8921 8922 // Logical Shift Right by variable 8923 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8924 %{ 8925 match(Set dst (URShiftL dst shift)); 8926 effect(KILL cr); 8927 8928 format %{ "shrq $dst, $shift" %} 8929 opcode(0xD3, 0x5); /* D3 /5 */ 8930 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8931 ins_pipe(ialu_reg_reg); 8932 %} 8933 8934 // Logical Shift Right by variable 8935 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8936 %{ 8937 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8938 effect(KILL cr); 8939 8940 format %{ "shrq $dst, $shift" %} 8941 opcode(0xD3, 0x5); /* D3 /5 */ 8942 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8943 ins_pipe(ialu_mem_reg); 8944 %} 8945 8946 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8947 // This idiom is used by the compiler for the i2b bytecode. 8948 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8949 %{ 8950 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8951 8952 format %{ "movsbl $dst, $src\t# i2b" %} 8953 opcode(0x0F, 0xBE); 8954 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8955 ins_pipe(ialu_reg_reg); 8956 %} 8957 8958 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8959 // This idiom is used by the compiler the i2s bytecode. 8960 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8961 %{ 8962 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8963 8964 format %{ "movswl $dst, $src\t# i2s" %} 8965 opcode(0x0F, 0xBF); 8966 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8967 ins_pipe(ialu_reg_reg); 8968 %} 8969 8970 // ROL/ROR instructions 8971 8972 // ROL expand 8973 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8974 effect(KILL cr, USE_DEF dst); 8975 8976 format %{ "roll $dst" %} 8977 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8978 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8979 ins_pipe(ialu_reg); 8980 %} 8981 8982 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8983 effect(USE_DEF dst, USE shift, KILL cr); 8984 8985 format %{ "roll $dst, $shift" %} 8986 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8987 ins_encode( reg_opc_imm(dst, shift) ); 8988 ins_pipe(ialu_reg); 8989 %} 8990 8991 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8992 %{ 8993 effect(USE_DEF dst, USE shift, KILL cr); 8994 8995 format %{ "roll $dst, $shift" %} 8996 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8997 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8998 ins_pipe(ialu_reg_reg); 8999 %} 9000 // end of ROL expand 9001 9002 // Rotate Left by one 9003 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9004 %{ 9005 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9006 9007 expand %{ 9008 rolI_rReg_imm1(dst, cr); 9009 %} 9010 %} 9011 9012 // Rotate Left by 8-bit immediate 9013 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9014 %{ 9015 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9016 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9017 9018 expand %{ 9019 rolI_rReg_imm8(dst, lshift, cr); 9020 %} 9021 %} 9022 9023 // Rotate Left by variable 9024 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9025 %{ 9026 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9027 9028 expand %{ 9029 rolI_rReg_CL(dst, shift, cr); 9030 %} 9031 %} 9032 9033 // Rotate Left by variable 9034 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9035 %{ 9036 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9037 9038 expand %{ 9039 rolI_rReg_CL(dst, shift, cr); 9040 %} 9041 %} 9042 9043 // ROR expand 9044 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9045 %{ 9046 effect(USE_DEF dst, KILL cr); 9047 9048 format %{ "rorl $dst" %} 9049 opcode(0xD1, 0x1); /* D1 /1 */ 9050 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9051 ins_pipe(ialu_reg); 9052 %} 9053 9054 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9055 %{ 9056 effect(USE_DEF dst, USE shift, KILL cr); 9057 9058 format %{ "rorl $dst, $shift" %} 9059 opcode(0xC1, 0x1); /* C1 /1 ib */ 9060 ins_encode(reg_opc_imm(dst, shift)); 9061 ins_pipe(ialu_reg); 9062 %} 9063 9064 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9065 %{ 9066 effect(USE_DEF dst, USE shift, KILL cr); 9067 9068 format %{ "rorl $dst, $shift" %} 9069 opcode(0xD3, 0x1); /* D3 /1 */ 9070 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9071 ins_pipe(ialu_reg_reg); 9072 %} 9073 // end of ROR expand 9074 9075 // Rotate Right by one 9076 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9077 %{ 9078 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9079 9080 expand %{ 9081 rorI_rReg_imm1(dst, cr); 9082 %} 9083 %} 9084 9085 // Rotate Right by 8-bit immediate 9086 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9087 %{ 9088 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9089 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9090 9091 expand %{ 9092 rorI_rReg_imm8(dst, rshift, cr); 9093 %} 9094 %} 9095 9096 // Rotate Right by variable 9097 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9098 %{ 9099 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9100 9101 expand %{ 9102 rorI_rReg_CL(dst, shift, cr); 9103 %} 9104 %} 9105 9106 // Rotate Right by variable 9107 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9108 %{ 9109 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9110 9111 expand %{ 9112 rorI_rReg_CL(dst, shift, cr); 9113 %} 9114 %} 9115 9116 // for long rotate 9117 // ROL expand 9118 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9119 effect(USE_DEF dst, KILL cr); 9120 9121 format %{ "rolq $dst" %} 9122 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9123 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9124 ins_pipe(ialu_reg); 9125 %} 9126 9127 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9128 effect(USE_DEF dst, USE shift, KILL cr); 9129 9130 format %{ "rolq $dst, $shift" %} 9131 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9132 ins_encode( reg_opc_imm_wide(dst, shift) ); 9133 ins_pipe(ialu_reg); 9134 %} 9135 9136 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9137 %{ 9138 effect(USE_DEF dst, USE shift, KILL cr); 9139 9140 format %{ "rolq $dst, $shift" %} 9141 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9142 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9143 ins_pipe(ialu_reg_reg); 9144 %} 9145 // end of ROL expand 9146 9147 // Rotate Left by one 9148 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9149 %{ 9150 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9151 9152 expand %{ 9153 rolL_rReg_imm1(dst, cr); 9154 %} 9155 %} 9156 9157 // Rotate Left by 8-bit immediate 9158 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9159 %{ 9160 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9161 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9162 9163 expand %{ 9164 rolL_rReg_imm8(dst, lshift, cr); 9165 %} 9166 %} 9167 9168 // Rotate Left by variable 9169 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9170 %{ 9171 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9172 9173 expand %{ 9174 rolL_rReg_CL(dst, shift, cr); 9175 %} 9176 %} 9177 9178 // Rotate Left by variable 9179 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9180 %{ 9181 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9182 9183 expand %{ 9184 rolL_rReg_CL(dst, shift, cr); 9185 %} 9186 %} 9187 9188 // ROR expand 9189 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9190 %{ 9191 effect(USE_DEF dst, KILL cr); 9192 9193 format %{ "rorq $dst" %} 9194 opcode(0xD1, 0x1); /* D1 /1 */ 9195 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9196 ins_pipe(ialu_reg); 9197 %} 9198 9199 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9200 %{ 9201 effect(USE_DEF dst, USE shift, KILL cr); 9202 9203 format %{ "rorq $dst, $shift" %} 9204 opcode(0xC1, 0x1); /* C1 /1 ib */ 9205 ins_encode(reg_opc_imm_wide(dst, shift)); 9206 ins_pipe(ialu_reg); 9207 %} 9208 9209 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9210 %{ 9211 effect(USE_DEF dst, USE shift, KILL cr); 9212 9213 format %{ "rorq $dst, $shift" %} 9214 opcode(0xD3, 0x1); /* D3 /1 */ 9215 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9216 ins_pipe(ialu_reg_reg); 9217 %} 9218 // end of ROR expand 9219 9220 // Rotate Right by one 9221 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9222 %{ 9223 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9224 9225 expand %{ 9226 rorL_rReg_imm1(dst, cr); 9227 %} 9228 %} 9229 9230 // Rotate Right by 8-bit immediate 9231 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9232 %{ 9233 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9234 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9235 9236 expand %{ 9237 rorL_rReg_imm8(dst, rshift, cr); 9238 %} 9239 %} 9240 9241 // Rotate Right by variable 9242 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9243 %{ 9244 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9245 9246 expand %{ 9247 rorL_rReg_CL(dst, shift, cr); 9248 %} 9249 %} 9250 9251 // Rotate Right by variable 9252 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9253 %{ 9254 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9255 9256 expand %{ 9257 rorL_rReg_CL(dst, shift, cr); 9258 %} 9259 %} 9260 9261 // Logical Instructions 9262 9263 // Integer Logical Instructions 9264 9265 // And Instructions 9266 // And Register with Register 9267 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9268 %{ 9269 match(Set dst (AndI dst src)); 9270 effect(KILL cr); 9271 9272 format %{ "andl $dst, $src\t# int" %} 9273 opcode(0x23); 9274 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9275 ins_pipe(ialu_reg_reg); 9276 %} 9277 9278 // And Register with Immediate 255 9279 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9280 %{ 9281 match(Set dst (AndI dst src)); 9282 9283 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9284 opcode(0x0F, 0xB6); 9285 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9286 ins_pipe(ialu_reg); 9287 %} 9288 9289 // And Register with Immediate 255 and promote to long 9290 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9291 %{ 9292 match(Set dst (ConvI2L (AndI src mask))); 9293 9294 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9295 opcode(0x0F, 0xB6); 9296 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9297 ins_pipe(ialu_reg); 9298 %} 9299 9300 // And Register with Immediate 65535 9301 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9302 %{ 9303 match(Set dst (AndI dst src)); 9304 9305 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9306 opcode(0x0F, 0xB7); 9307 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9308 ins_pipe(ialu_reg); 9309 %} 9310 9311 // And Register with Immediate 65535 and promote to long 9312 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9313 %{ 9314 match(Set dst (ConvI2L (AndI src mask))); 9315 9316 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9317 opcode(0x0F, 0xB7); 9318 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9319 ins_pipe(ialu_reg); 9320 %} 9321 9322 // And Register with Immediate 9323 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9324 %{ 9325 match(Set dst (AndI dst src)); 9326 effect(KILL cr); 9327 9328 format %{ "andl $dst, $src\t# int" %} 9329 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9330 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9331 ins_pipe(ialu_reg); 9332 %} 9333 9334 // And Register with Memory 9335 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9336 %{ 9337 match(Set dst (AndI dst (LoadI src))); 9338 effect(KILL cr); 9339 9340 ins_cost(125); 9341 format %{ "andl $dst, $src\t# int" %} 9342 opcode(0x23); 9343 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9344 ins_pipe(ialu_reg_mem); 9345 %} 9346 9347 // And Memory with Register 9348 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9349 %{ 9350 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9351 effect(KILL cr); 9352 9353 ins_cost(150); 9354 format %{ "andl $dst, $src\t# int" %} 9355 opcode(0x21); /* Opcode 21 /r */ 9356 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9357 ins_pipe(ialu_mem_reg); 9358 %} 9359 9360 // And Memory with Immediate 9361 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9362 %{ 9363 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9364 effect(KILL cr); 9365 9366 ins_cost(125); 9367 format %{ "andl $dst, $src\t# int" %} 9368 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9369 ins_encode(REX_mem(dst), OpcSE(src), 9370 RM_opc_mem(secondary, dst), Con8or32(src)); 9371 ins_pipe(ialu_mem_imm); 9372 %} 9373 9374 // BMI1 instructions 9375 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9376 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9377 predicate(UseBMI1Instructions); 9378 effect(KILL cr); 9379 9380 ins_cost(125); 9381 format %{ "andnl $dst, $src1, $src2" %} 9382 9383 ins_encode %{ 9384 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9385 %} 9386 ins_pipe(ialu_reg_mem); 9387 %} 9388 9389 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9390 match(Set dst (AndI (XorI src1 minus_1) src2)); 9391 predicate(UseBMI1Instructions); 9392 effect(KILL cr); 9393 9394 format %{ "andnl $dst, $src1, $src2" %} 9395 9396 ins_encode %{ 9397 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9398 %} 9399 ins_pipe(ialu_reg); 9400 %} 9401 9402 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9403 match(Set dst (AndI (SubI imm_zero src) src)); 9404 predicate(UseBMI1Instructions); 9405 effect(KILL cr); 9406 9407 format %{ "blsil $dst, $src" %} 9408 9409 ins_encode %{ 9410 __ blsil($dst$$Register, $src$$Register); 9411 %} 9412 ins_pipe(ialu_reg); 9413 %} 9414 9415 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9416 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9417 predicate(UseBMI1Instructions); 9418 effect(KILL cr); 9419 9420 ins_cost(125); 9421 format %{ "blsil $dst, $src" %} 9422 9423 ins_encode %{ 9424 __ blsil($dst$$Register, $src$$Address); 9425 %} 9426 ins_pipe(ialu_reg_mem); 9427 %} 9428 9429 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9430 %{ 9431 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9432 predicate(UseBMI1Instructions); 9433 effect(KILL cr); 9434 9435 ins_cost(125); 9436 format %{ "blsmskl $dst, $src" %} 9437 9438 ins_encode %{ 9439 __ blsmskl($dst$$Register, $src$$Address); 9440 %} 9441 ins_pipe(ialu_reg_mem); 9442 %} 9443 9444 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9445 %{ 9446 match(Set dst (XorI (AddI src minus_1) src)); 9447 predicate(UseBMI1Instructions); 9448 effect(KILL cr); 9449 9450 format %{ "blsmskl $dst, $src" %} 9451 9452 ins_encode %{ 9453 __ blsmskl($dst$$Register, $src$$Register); 9454 %} 9455 9456 ins_pipe(ialu_reg); 9457 %} 9458 9459 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9460 %{ 9461 match(Set dst (AndI (AddI src minus_1) src) ); 9462 predicate(UseBMI1Instructions); 9463 effect(KILL cr); 9464 9465 format %{ "blsrl $dst, $src" %} 9466 9467 ins_encode %{ 9468 __ blsrl($dst$$Register, $src$$Register); 9469 %} 9470 9471 ins_pipe(ialu_reg_mem); 9472 %} 9473 9474 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9475 %{ 9476 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9477 predicate(UseBMI1Instructions); 9478 effect(KILL cr); 9479 9480 ins_cost(125); 9481 format %{ "blsrl $dst, $src" %} 9482 9483 ins_encode %{ 9484 __ blsrl($dst$$Register, $src$$Address); 9485 %} 9486 9487 ins_pipe(ialu_reg); 9488 %} 9489 9490 // Or Instructions 9491 // Or Register with Register 9492 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9493 %{ 9494 match(Set dst (OrI dst src)); 9495 effect(KILL cr); 9496 9497 format %{ "orl $dst, $src\t# int" %} 9498 opcode(0x0B); 9499 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9500 ins_pipe(ialu_reg_reg); 9501 %} 9502 9503 // Or Register with Immediate 9504 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9505 %{ 9506 match(Set dst (OrI dst src)); 9507 effect(KILL cr); 9508 9509 format %{ "orl $dst, $src\t# int" %} 9510 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9511 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9512 ins_pipe(ialu_reg); 9513 %} 9514 9515 // Or Register with Memory 9516 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9517 %{ 9518 match(Set dst (OrI dst (LoadI src))); 9519 effect(KILL cr); 9520 9521 ins_cost(125); 9522 format %{ "orl $dst, $src\t# int" %} 9523 opcode(0x0B); 9524 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9525 ins_pipe(ialu_reg_mem); 9526 %} 9527 9528 // Or Memory with Register 9529 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9530 %{ 9531 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9532 effect(KILL cr); 9533 9534 ins_cost(150); 9535 format %{ "orl $dst, $src\t# int" %} 9536 opcode(0x09); /* Opcode 09 /r */ 9537 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9538 ins_pipe(ialu_mem_reg); 9539 %} 9540 9541 // Or Memory with Immediate 9542 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9543 %{ 9544 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9545 effect(KILL cr); 9546 9547 ins_cost(125); 9548 format %{ "orl $dst, $src\t# int" %} 9549 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9550 ins_encode(REX_mem(dst), OpcSE(src), 9551 RM_opc_mem(secondary, dst), Con8or32(src)); 9552 ins_pipe(ialu_mem_imm); 9553 %} 9554 9555 // Xor Instructions 9556 // Xor Register with Register 9557 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9558 %{ 9559 match(Set dst (XorI dst src)); 9560 effect(KILL cr); 9561 9562 format %{ "xorl $dst, $src\t# int" %} 9563 opcode(0x33); 9564 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9565 ins_pipe(ialu_reg_reg); 9566 %} 9567 9568 // Xor Register with Immediate -1 9569 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9570 match(Set dst (XorI dst imm)); 9571 9572 format %{ "not $dst" %} 9573 ins_encode %{ 9574 __ notl($dst$$Register); 9575 %} 9576 ins_pipe(ialu_reg); 9577 %} 9578 9579 // Xor Register with Immediate 9580 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9581 %{ 9582 match(Set dst (XorI dst src)); 9583 effect(KILL cr); 9584 9585 format %{ "xorl $dst, $src\t# int" %} 9586 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9587 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9588 ins_pipe(ialu_reg); 9589 %} 9590 9591 // Xor Register with Memory 9592 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9593 %{ 9594 match(Set dst (XorI dst (LoadI src))); 9595 effect(KILL cr); 9596 9597 ins_cost(125); 9598 format %{ "xorl $dst, $src\t# int" %} 9599 opcode(0x33); 9600 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9601 ins_pipe(ialu_reg_mem); 9602 %} 9603 9604 // Xor Memory with Register 9605 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9606 %{ 9607 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9608 effect(KILL cr); 9609 9610 ins_cost(150); 9611 format %{ "xorl $dst, $src\t# int" %} 9612 opcode(0x31); /* Opcode 31 /r */ 9613 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9614 ins_pipe(ialu_mem_reg); 9615 %} 9616 9617 // Xor Memory with Immediate 9618 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9619 %{ 9620 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9621 effect(KILL cr); 9622 9623 ins_cost(125); 9624 format %{ "xorl $dst, $src\t# int" %} 9625 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9626 ins_encode(REX_mem(dst), OpcSE(src), 9627 RM_opc_mem(secondary, dst), Con8or32(src)); 9628 ins_pipe(ialu_mem_imm); 9629 %} 9630 9631 9632 // Long Logical Instructions 9633 9634 // And Instructions 9635 // And Register with Register 9636 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9637 %{ 9638 match(Set dst (AndL dst src)); 9639 effect(KILL cr); 9640 9641 format %{ "andq $dst, $src\t# long" %} 9642 opcode(0x23); 9643 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9644 ins_pipe(ialu_reg_reg); 9645 %} 9646 9647 // And Register with Immediate 255 9648 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9649 %{ 9650 match(Set dst (AndL dst src)); 9651 9652 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9653 opcode(0x0F, 0xB6); 9654 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9655 ins_pipe(ialu_reg); 9656 %} 9657 9658 // And Register with Immediate 65535 9659 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9660 %{ 9661 match(Set dst (AndL dst src)); 9662 9663 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9664 opcode(0x0F, 0xB7); 9665 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9666 ins_pipe(ialu_reg); 9667 %} 9668 9669 // And Register with Immediate 9670 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9671 %{ 9672 match(Set dst (AndL dst src)); 9673 effect(KILL cr); 9674 9675 format %{ "andq $dst, $src\t# long" %} 9676 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9677 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9678 ins_pipe(ialu_reg); 9679 %} 9680 9681 // And Register with Memory 9682 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9683 %{ 9684 match(Set dst (AndL dst (LoadL src))); 9685 effect(KILL cr); 9686 9687 ins_cost(125); 9688 format %{ "andq $dst, $src\t# long" %} 9689 opcode(0x23); 9690 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9691 ins_pipe(ialu_reg_mem); 9692 %} 9693 9694 // And Memory with Register 9695 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9696 %{ 9697 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9698 effect(KILL cr); 9699 9700 ins_cost(150); 9701 format %{ "andq $dst, $src\t# long" %} 9702 opcode(0x21); /* Opcode 21 /r */ 9703 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9704 ins_pipe(ialu_mem_reg); 9705 %} 9706 9707 // And Memory with Immediate 9708 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9709 %{ 9710 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9711 effect(KILL cr); 9712 9713 ins_cost(125); 9714 format %{ "andq $dst, $src\t# long" %} 9715 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9716 ins_encode(REX_mem_wide(dst), OpcSE(src), 9717 RM_opc_mem(secondary, dst), Con8or32(src)); 9718 ins_pipe(ialu_mem_imm); 9719 %} 9720 9721 // BMI1 instructions 9722 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9723 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9724 predicate(UseBMI1Instructions); 9725 effect(KILL cr); 9726 9727 ins_cost(125); 9728 format %{ "andnq $dst, $src1, $src2" %} 9729 9730 ins_encode %{ 9731 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9732 %} 9733 ins_pipe(ialu_reg_mem); 9734 %} 9735 9736 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9737 match(Set dst (AndL (XorL src1 minus_1) src2)); 9738 predicate(UseBMI1Instructions); 9739 effect(KILL cr); 9740 9741 format %{ "andnq $dst, $src1, $src2" %} 9742 9743 ins_encode %{ 9744 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9745 %} 9746 ins_pipe(ialu_reg_mem); 9747 %} 9748 9749 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9750 match(Set dst (AndL (SubL imm_zero src) src)); 9751 predicate(UseBMI1Instructions); 9752 effect(KILL cr); 9753 9754 format %{ "blsiq $dst, $src" %} 9755 9756 ins_encode %{ 9757 __ blsiq($dst$$Register, $src$$Register); 9758 %} 9759 ins_pipe(ialu_reg); 9760 %} 9761 9762 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9763 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9764 predicate(UseBMI1Instructions); 9765 effect(KILL cr); 9766 9767 ins_cost(125); 9768 format %{ "blsiq $dst, $src" %} 9769 9770 ins_encode %{ 9771 __ blsiq($dst$$Register, $src$$Address); 9772 %} 9773 ins_pipe(ialu_reg_mem); 9774 %} 9775 9776 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9777 %{ 9778 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9779 predicate(UseBMI1Instructions); 9780 effect(KILL cr); 9781 9782 ins_cost(125); 9783 format %{ "blsmskq $dst, $src" %} 9784 9785 ins_encode %{ 9786 __ blsmskq($dst$$Register, $src$$Address); 9787 %} 9788 ins_pipe(ialu_reg_mem); 9789 %} 9790 9791 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9792 %{ 9793 match(Set dst (XorL (AddL src minus_1) src)); 9794 predicate(UseBMI1Instructions); 9795 effect(KILL cr); 9796 9797 format %{ "blsmskq $dst, $src" %} 9798 9799 ins_encode %{ 9800 __ blsmskq($dst$$Register, $src$$Register); 9801 %} 9802 9803 ins_pipe(ialu_reg); 9804 %} 9805 9806 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9807 %{ 9808 match(Set dst (AndL (AddL src minus_1) src) ); 9809 predicate(UseBMI1Instructions); 9810 effect(KILL cr); 9811 9812 format %{ "blsrq $dst, $src" %} 9813 9814 ins_encode %{ 9815 __ blsrq($dst$$Register, $src$$Register); 9816 %} 9817 9818 ins_pipe(ialu_reg); 9819 %} 9820 9821 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9822 %{ 9823 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9824 predicate(UseBMI1Instructions); 9825 effect(KILL cr); 9826 9827 ins_cost(125); 9828 format %{ "blsrq $dst, $src" %} 9829 9830 ins_encode %{ 9831 __ blsrq($dst$$Register, $src$$Address); 9832 %} 9833 9834 ins_pipe(ialu_reg); 9835 %} 9836 9837 // Or Instructions 9838 // Or Register with Register 9839 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9840 %{ 9841 match(Set dst (OrL dst src)); 9842 effect(KILL cr); 9843 9844 format %{ "orq $dst, $src\t# long" %} 9845 opcode(0x0B); 9846 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9847 ins_pipe(ialu_reg_reg); 9848 %} 9849 9850 // Use any_RegP to match R15 (TLS register) without spilling. 9851 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9852 match(Set dst (OrL dst (CastP2X src))); 9853 effect(KILL cr); 9854 9855 format %{ "orq $dst, $src\t# long" %} 9856 opcode(0x0B); 9857 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9858 ins_pipe(ialu_reg_reg); 9859 %} 9860 9861 9862 // Or Register with Immediate 9863 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9864 %{ 9865 match(Set dst (OrL dst src)); 9866 effect(KILL cr); 9867 9868 format %{ "orq $dst, $src\t# long" %} 9869 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9870 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9871 ins_pipe(ialu_reg); 9872 %} 9873 9874 // Or Register with Memory 9875 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9876 %{ 9877 match(Set dst (OrL dst (LoadL src))); 9878 effect(KILL cr); 9879 9880 ins_cost(125); 9881 format %{ "orq $dst, $src\t# long" %} 9882 opcode(0x0B); 9883 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9884 ins_pipe(ialu_reg_mem); 9885 %} 9886 9887 // Or Memory with Register 9888 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9889 %{ 9890 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9891 effect(KILL cr); 9892 9893 ins_cost(150); 9894 format %{ "orq $dst, $src\t# long" %} 9895 opcode(0x09); /* Opcode 09 /r */ 9896 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9897 ins_pipe(ialu_mem_reg); 9898 %} 9899 9900 // Or Memory with Immediate 9901 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9902 %{ 9903 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9904 effect(KILL cr); 9905 9906 ins_cost(125); 9907 format %{ "orq $dst, $src\t# long" %} 9908 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9909 ins_encode(REX_mem_wide(dst), OpcSE(src), 9910 RM_opc_mem(secondary, dst), Con8or32(src)); 9911 ins_pipe(ialu_mem_imm); 9912 %} 9913 9914 // Xor Instructions 9915 // Xor Register with Register 9916 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9917 %{ 9918 match(Set dst (XorL dst src)); 9919 effect(KILL cr); 9920 9921 format %{ "xorq $dst, $src\t# long" %} 9922 opcode(0x33); 9923 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9924 ins_pipe(ialu_reg_reg); 9925 %} 9926 9927 // Xor Register with Immediate -1 9928 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9929 match(Set dst (XorL dst imm)); 9930 9931 format %{ "notq $dst" %} 9932 ins_encode %{ 9933 __ notq($dst$$Register); 9934 %} 9935 ins_pipe(ialu_reg); 9936 %} 9937 9938 // Xor Register with Immediate 9939 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9940 %{ 9941 match(Set dst (XorL dst src)); 9942 effect(KILL cr); 9943 9944 format %{ "xorq $dst, $src\t# long" %} 9945 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9946 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9947 ins_pipe(ialu_reg); 9948 %} 9949 9950 // Xor Register with Memory 9951 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9952 %{ 9953 match(Set dst (XorL dst (LoadL src))); 9954 effect(KILL cr); 9955 9956 ins_cost(125); 9957 format %{ "xorq $dst, $src\t# long" %} 9958 opcode(0x33); 9959 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9960 ins_pipe(ialu_reg_mem); 9961 %} 9962 9963 // Xor Memory with Register 9964 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9965 %{ 9966 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9967 effect(KILL cr); 9968 9969 ins_cost(150); 9970 format %{ "xorq $dst, $src\t# long" %} 9971 opcode(0x31); /* Opcode 31 /r */ 9972 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9973 ins_pipe(ialu_mem_reg); 9974 %} 9975 9976 // Xor Memory with Immediate 9977 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9978 %{ 9979 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9980 effect(KILL cr); 9981 9982 ins_cost(125); 9983 format %{ "xorq $dst, $src\t# long" %} 9984 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9985 ins_encode(REX_mem_wide(dst), OpcSE(src), 9986 RM_opc_mem(secondary, dst), Con8or32(src)); 9987 ins_pipe(ialu_mem_imm); 9988 %} 9989 9990 // Convert Int to Boolean 9991 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9992 %{ 9993 match(Set dst (Conv2B src)); 9994 effect(KILL cr); 9995 9996 format %{ "testl $src, $src\t# ci2b\n\t" 9997 "setnz $dst\n\t" 9998 "movzbl $dst, $dst" %} 9999 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10000 setNZ_reg(dst), 10001 REX_reg_breg(dst, dst), // movzbl 10002 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10003 ins_pipe(pipe_slow); // XXX 10004 %} 10005 10006 // Convert Pointer to Boolean 10007 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10008 %{ 10009 match(Set dst (Conv2B src)); 10010 effect(KILL cr); 10011 10012 format %{ "testq $src, $src\t# cp2b\n\t" 10013 "setnz $dst\n\t" 10014 "movzbl $dst, $dst" %} 10015 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10016 setNZ_reg(dst), 10017 REX_reg_breg(dst, dst), // movzbl 10018 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10019 ins_pipe(pipe_slow); // XXX 10020 %} 10021 10022 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10023 %{ 10024 match(Set dst (CmpLTMask p q)); 10025 effect(KILL cr); 10026 10027 ins_cost(400); 10028 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10029 "setlt $dst\n\t" 10030 "movzbl $dst, $dst\n\t" 10031 "negl $dst" %} 10032 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10033 setLT_reg(dst), 10034 REX_reg_breg(dst, dst), // movzbl 10035 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10036 neg_reg(dst)); 10037 ins_pipe(pipe_slow); 10038 %} 10039 10040 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10041 %{ 10042 match(Set dst (CmpLTMask dst zero)); 10043 effect(KILL cr); 10044 10045 ins_cost(100); 10046 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10047 ins_encode %{ 10048 __ sarl($dst$$Register, 31); 10049 %} 10050 ins_pipe(ialu_reg); 10051 %} 10052 10053 /* Better to save a register than avoid a branch */ 10054 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10055 %{ 10056 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10057 effect(KILL cr); 10058 ins_cost(300); 10059 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10060 "jge done\n\t" 10061 "addl $p,$y\n" 10062 "done: " %} 10063 ins_encode %{ 10064 Register Rp = $p$$Register; 10065 Register Rq = $q$$Register; 10066 Register Ry = $y$$Register; 10067 Label done; 10068 __ subl(Rp, Rq); 10069 __ jccb(Assembler::greaterEqual, done); 10070 __ addl(Rp, Ry); 10071 __ bind(done); 10072 %} 10073 ins_pipe(pipe_cmplt); 10074 %} 10075 10076 /* Better to save a register than avoid a branch */ 10077 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10078 %{ 10079 match(Set y (AndI (CmpLTMask p q) y)); 10080 effect(KILL cr); 10081 10082 ins_cost(300); 10083 10084 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10085 "jlt done\n\t" 10086 "xorl $y, $y\n" 10087 "done: " %} 10088 ins_encode %{ 10089 Register Rp = $p$$Register; 10090 Register Rq = $q$$Register; 10091 Register Ry = $y$$Register; 10092 Label done; 10093 __ cmpl(Rp, Rq); 10094 __ jccb(Assembler::less, done); 10095 __ xorl(Ry, Ry); 10096 __ bind(done); 10097 %} 10098 ins_pipe(pipe_cmplt); 10099 %} 10100 10101 10102 //---------- FP Instructions------------------------------------------------ 10103 10104 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10105 %{ 10106 match(Set cr (CmpF src1 src2)); 10107 10108 ins_cost(145); 10109 format %{ "ucomiss $src1, $src2\n\t" 10110 "jnp,s exit\n\t" 10111 "pushfq\t# saw NaN, set CF\n\t" 10112 "andq [rsp], #0xffffff2b\n\t" 10113 "popfq\n" 10114 "exit:" %} 10115 ins_encode %{ 10116 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10117 emit_cmpfp_fixup(_masm); 10118 %} 10119 ins_pipe(pipe_slow); 10120 %} 10121 10122 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10123 match(Set cr (CmpF src1 src2)); 10124 10125 ins_cost(100); 10126 format %{ "ucomiss $src1, $src2" %} 10127 ins_encode %{ 10128 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10129 %} 10130 ins_pipe(pipe_slow); 10131 %} 10132 10133 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10134 %{ 10135 match(Set cr (CmpF src1 (LoadF src2))); 10136 10137 ins_cost(145); 10138 format %{ "ucomiss $src1, $src2\n\t" 10139 "jnp,s exit\n\t" 10140 "pushfq\t# saw NaN, set CF\n\t" 10141 "andq [rsp], #0xffffff2b\n\t" 10142 "popfq\n" 10143 "exit:" %} 10144 ins_encode %{ 10145 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10146 emit_cmpfp_fixup(_masm); 10147 %} 10148 ins_pipe(pipe_slow); 10149 %} 10150 10151 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10152 match(Set cr (CmpF src1 (LoadF src2))); 10153 10154 ins_cost(100); 10155 format %{ "ucomiss $src1, $src2" %} 10156 ins_encode %{ 10157 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10158 %} 10159 ins_pipe(pipe_slow); 10160 %} 10161 10162 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10163 match(Set cr (CmpF src con)); 10164 10165 ins_cost(145); 10166 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10167 "jnp,s exit\n\t" 10168 "pushfq\t# saw NaN, set CF\n\t" 10169 "andq [rsp], #0xffffff2b\n\t" 10170 "popfq\n" 10171 "exit:" %} 10172 ins_encode %{ 10173 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10174 emit_cmpfp_fixup(_masm); 10175 %} 10176 ins_pipe(pipe_slow); 10177 %} 10178 10179 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10180 match(Set cr (CmpF src con)); 10181 ins_cost(100); 10182 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10183 ins_encode %{ 10184 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10185 %} 10186 ins_pipe(pipe_slow); 10187 %} 10188 10189 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10190 %{ 10191 match(Set cr (CmpD src1 src2)); 10192 10193 ins_cost(145); 10194 format %{ "ucomisd $src1, $src2\n\t" 10195 "jnp,s exit\n\t" 10196 "pushfq\t# saw NaN, set CF\n\t" 10197 "andq [rsp], #0xffffff2b\n\t" 10198 "popfq\n" 10199 "exit:" %} 10200 ins_encode %{ 10201 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10202 emit_cmpfp_fixup(_masm); 10203 %} 10204 ins_pipe(pipe_slow); 10205 %} 10206 10207 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10208 match(Set cr (CmpD src1 src2)); 10209 10210 ins_cost(100); 10211 format %{ "ucomisd $src1, $src2 test" %} 10212 ins_encode %{ 10213 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10214 %} 10215 ins_pipe(pipe_slow); 10216 %} 10217 10218 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10219 %{ 10220 match(Set cr (CmpD src1 (LoadD src2))); 10221 10222 ins_cost(145); 10223 format %{ "ucomisd $src1, $src2\n\t" 10224 "jnp,s exit\n\t" 10225 "pushfq\t# saw NaN, set CF\n\t" 10226 "andq [rsp], #0xffffff2b\n\t" 10227 "popfq\n" 10228 "exit:" %} 10229 ins_encode %{ 10230 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10231 emit_cmpfp_fixup(_masm); 10232 %} 10233 ins_pipe(pipe_slow); 10234 %} 10235 10236 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10237 match(Set cr (CmpD src1 (LoadD src2))); 10238 10239 ins_cost(100); 10240 format %{ "ucomisd $src1, $src2" %} 10241 ins_encode %{ 10242 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10243 %} 10244 ins_pipe(pipe_slow); 10245 %} 10246 10247 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10248 match(Set cr (CmpD src con)); 10249 10250 ins_cost(145); 10251 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10252 "jnp,s exit\n\t" 10253 "pushfq\t# saw NaN, set CF\n\t" 10254 "andq [rsp], #0xffffff2b\n\t" 10255 "popfq\n" 10256 "exit:" %} 10257 ins_encode %{ 10258 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10259 emit_cmpfp_fixup(_masm); 10260 %} 10261 ins_pipe(pipe_slow); 10262 %} 10263 10264 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10265 match(Set cr (CmpD src con)); 10266 ins_cost(100); 10267 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10268 ins_encode %{ 10269 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10270 %} 10271 ins_pipe(pipe_slow); 10272 %} 10273 10274 // Compare into -1,0,1 10275 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10276 %{ 10277 match(Set dst (CmpF3 src1 src2)); 10278 effect(KILL cr); 10279 10280 ins_cost(275); 10281 format %{ "ucomiss $src1, $src2\n\t" 10282 "movl $dst, #-1\n\t" 10283 "jp,s done\n\t" 10284 "jb,s done\n\t" 10285 "setne $dst\n\t" 10286 "movzbl $dst, $dst\n" 10287 "done:" %} 10288 ins_encode %{ 10289 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10290 emit_cmpfp3(_masm, $dst$$Register); 10291 %} 10292 ins_pipe(pipe_slow); 10293 %} 10294 10295 // Compare into -1,0,1 10296 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10297 %{ 10298 match(Set dst (CmpF3 src1 (LoadF src2))); 10299 effect(KILL cr); 10300 10301 ins_cost(275); 10302 format %{ "ucomiss $src1, $src2\n\t" 10303 "movl $dst, #-1\n\t" 10304 "jp,s done\n\t" 10305 "jb,s done\n\t" 10306 "setne $dst\n\t" 10307 "movzbl $dst, $dst\n" 10308 "done:" %} 10309 ins_encode %{ 10310 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10311 emit_cmpfp3(_masm, $dst$$Register); 10312 %} 10313 ins_pipe(pipe_slow); 10314 %} 10315 10316 // Compare into -1,0,1 10317 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10318 match(Set dst (CmpF3 src con)); 10319 effect(KILL cr); 10320 10321 ins_cost(275); 10322 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10323 "movl $dst, #-1\n\t" 10324 "jp,s done\n\t" 10325 "jb,s done\n\t" 10326 "setne $dst\n\t" 10327 "movzbl $dst, $dst\n" 10328 "done:" %} 10329 ins_encode %{ 10330 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10331 emit_cmpfp3(_masm, $dst$$Register); 10332 %} 10333 ins_pipe(pipe_slow); 10334 %} 10335 10336 // Compare into -1,0,1 10337 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10338 %{ 10339 match(Set dst (CmpD3 src1 src2)); 10340 effect(KILL cr); 10341 10342 ins_cost(275); 10343 format %{ "ucomisd $src1, $src2\n\t" 10344 "movl $dst, #-1\n\t" 10345 "jp,s done\n\t" 10346 "jb,s done\n\t" 10347 "setne $dst\n\t" 10348 "movzbl $dst, $dst\n" 10349 "done:" %} 10350 ins_encode %{ 10351 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10352 emit_cmpfp3(_masm, $dst$$Register); 10353 %} 10354 ins_pipe(pipe_slow); 10355 %} 10356 10357 // Compare into -1,0,1 10358 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10359 %{ 10360 match(Set dst (CmpD3 src1 (LoadD src2))); 10361 effect(KILL cr); 10362 10363 ins_cost(275); 10364 format %{ "ucomisd $src1, $src2\n\t" 10365 "movl $dst, #-1\n\t" 10366 "jp,s done\n\t" 10367 "jb,s done\n\t" 10368 "setne $dst\n\t" 10369 "movzbl $dst, $dst\n" 10370 "done:" %} 10371 ins_encode %{ 10372 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10373 emit_cmpfp3(_masm, $dst$$Register); 10374 %} 10375 ins_pipe(pipe_slow); 10376 %} 10377 10378 // Compare into -1,0,1 10379 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10380 match(Set dst (CmpD3 src con)); 10381 effect(KILL cr); 10382 10383 ins_cost(275); 10384 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10385 "movl $dst, #-1\n\t" 10386 "jp,s done\n\t" 10387 "jb,s done\n\t" 10388 "setne $dst\n\t" 10389 "movzbl $dst, $dst\n" 10390 "done:" %} 10391 ins_encode %{ 10392 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10393 emit_cmpfp3(_masm, $dst$$Register); 10394 %} 10395 ins_pipe(pipe_slow); 10396 %} 10397 10398 //----------Arithmetic Conversion Instructions--------------------------------- 10399 10400 instruct roundFloat_nop(regF dst) 10401 %{ 10402 match(Set dst (RoundFloat dst)); 10403 10404 ins_cost(0); 10405 ins_encode(); 10406 ins_pipe(empty); 10407 %} 10408 10409 instruct roundDouble_nop(regD dst) 10410 %{ 10411 match(Set dst (RoundDouble dst)); 10412 10413 ins_cost(0); 10414 ins_encode(); 10415 ins_pipe(empty); 10416 %} 10417 10418 instruct convF2D_reg_reg(regD dst, regF src) 10419 %{ 10420 match(Set dst (ConvF2D src)); 10421 10422 format %{ "cvtss2sd $dst, $src" %} 10423 ins_encode %{ 10424 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10425 %} 10426 ins_pipe(pipe_slow); // XXX 10427 %} 10428 10429 instruct convF2D_reg_mem(regD dst, memory src) 10430 %{ 10431 match(Set dst (ConvF2D (LoadF src))); 10432 10433 format %{ "cvtss2sd $dst, $src" %} 10434 ins_encode %{ 10435 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10436 %} 10437 ins_pipe(pipe_slow); // XXX 10438 %} 10439 10440 instruct convD2F_reg_reg(regF dst, regD src) 10441 %{ 10442 match(Set dst (ConvD2F src)); 10443 10444 format %{ "cvtsd2ss $dst, $src" %} 10445 ins_encode %{ 10446 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10447 %} 10448 ins_pipe(pipe_slow); // XXX 10449 %} 10450 10451 instruct convD2F_reg_mem(regF dst, memory src) 10452 %{ 10453 match(Set dst (ConvD2F (LoadD src))); 10454 10455 format %{ "cvtsd2ss $dst, $src" %} 10456 ins_encode %{ 10457 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10458 %} 10459 ins_pipe(pipe_slow); // XXX 10460 %} 10461 10462 // XXX do mem variants 10463 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10464 %{ 10465 match(Set dst (ConvF2I src)); 10466 effect(KILL cr); 10467 10468 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10469 "cmpl $dst, #0x80000000\n\t" 10470 "jne,s done\n\t" 10471 "subq rsp, #8\n\t" 10472 "movss [rsp], $src\n\t" 10473 "call f2i_fixup\n\t" 10474 "popq $dst\n" 10475 "done: "%} 10476 ins_encode %{ 10477 Label done; 10478 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10479 __ cmpl($dst$$Register, 0x80000000); 10480 __ jccb(Assembler::notEqual, done); 10481 __ subptr(rsp, 8); 10482 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10483 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10484 __ pop($dst$$Register); 10485 __ bind(done); 10486 %} 10487 ins_pipe(pipe_slow); 10488 %} 10489 10490 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10491 %{ 10492 match(Set dst (ConvF2L src)); 10493 effect(KILL cr); 10494 10495 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10496 "cmpq $dst, [0x8000000000000000]\n\t" 10497 "jne,s done\n\t" 10498 "subq rsp, #8\n\t" 10499 "movss [rsp], $src\n\t" 10500 "call f2l_fixup\n\t" 10501 "popq $dst\n" 10502 "done: "%} 10503 ins_encode %{ 10504 Label done; 10505 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10506 __ cmp64($dst$$Register, 10507 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10508 __ jccb(Assembler::notEqual, done); 10509 __ subptr(rsp, 8); 10510 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10511 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10512 __ pop($dst$$Register); 10513 __ bind(done); 10514 %} 10515 ins_pipe(pipe_slow); 10516 %} 10517 10518 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10519 %{ 10520 match(Set dst (ConvD2I src)); 10521 effect(KILL cr); 10522 10523 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10524 "cmpl $dst, #0x80000000\n\t" 10525 "jne,s done\n\t" 10526 "subq rsp, #8\n\t" 10527 "movsd [rsp], $src\n\t" 10528 "call d2i_fixup\n\t" 10529 "popq $dst\n" 10530 "done: "%} 10531 ins_encode %{ 10532 Label done; 10533 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10534 __ cmpl($dst$$Register, 0x80000000); 10535 __ jccb(Assembler::notEqual, done); 10536 __ subptr(rsp, 8); 10537 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10538 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10539 __ pop($dst$$Register); 10540 __ bind(done); 10541 %} 10542 ins_pipe(pipe_slow); 10543 %} 10544 10545 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10546 %{ 10547 match(Set dst (ConvD2L src)); 10548 effect(KILL cr); 10549 10550 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10551 "cmpq $dst, [0x8000000000000000]\n\t" 10552 "jne,s done\n\t" 10553 "subq rsp, #8\n\t" 10554 "movsd [rsp], $src\n\t" 10555 "call d2l_fixup\n\t" 10556 "popq $dst\n" 10557 "done: "%} 10558 ins_encode %{ 10559 Label done; 10560 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10561 __ cmp64($dst$$Register, 10562 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10563 __ jccb(Assembler::notEqual, done); 10564 __ subptr(rsp, 8); 10565 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10566 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10567 __ pop($dst$$Register); 10568 __ bind(done); 10569 %} 10570 ins_pipe(pipe_slow); 10571 %} 10572 10573 instruct convI2F_reg_reg(regF dst, rRegI src) 10574 %{ 10575 predicate(!UseXmmI2F); 10576 match(Set dst (ConvI2F src)); 10577 10578 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10579 ins_encode %{ 10580 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10581 %} 10582 ins_pipe(pipe_slow); // XXX 10583 %} 10584 10585 instruct convI2F_reg_mem(regF dst, memory src) 10586 %{ 10587 match(Set dst (ConvI2F (LoadI src))); 10588 10589 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10590 ins_encode %{ 10591 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10592 %} 10593 ins_pipe(pipe_slow); // XXX 10594 %} 10595 10596 instruct convI2D_reg_reg(regD dst, rRegI src) 10597 %{ 10598 predicate(!UseXmmI2D); 10599 match(Set dst (ConvI2D src)); 10600 10601 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10602 ins_encode %{ 10603 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10604 %} 10605 ins_pipe(pipe_slow); // XXX 10606 %} 10607 10608 instruct convI2D_reg_mem(regD dst, memory src) 10609 %{ 10610 match(Set dst (ConvI2D (LoadI src))); 10611 10612 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10613 ins_encode %{ 10614 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10615 %} 10616 ins_pipe(pipe_slow); // XXX 10617 %} 10618 10619 instruct convXI2F_reg(regF dst, rRegI src) 10620 %{ 10621 predicate(UseXmmI2F); 10622 match(Set dst (ConvI2F src)); 10623 10624 format %{ "movdl $dst, $src\n\t" 10625 "cvtdq2psl $dst, $dst\t# i2f" %} 10626 ins_encode %{ 10627 __ movdl($dst$$XMMRegister, $src$$Register); 10628 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10629 %} 10630 ins_pipe(pipe_slow); // XXX 10631 %} 10632 10633 instruct convXI2D_reg(regD dst, rRegI src) 10634 %{ 10635 predicate(UseXmmI2D); 10636 match(Set dst (ConvI2D src)); 10637 10638 format %{ "movdl $dst, $src\n\t" 10639 "cvtdq2pdl $dst, $dst\t# i2d" %} 10640 ins_encode %{ 10641 __ movdl($dst$$XMMRegister, $src$$Register); 10642 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10643 %} 10644 ins_pipe(pipe_slow); // XXX 10645 %} 10646 10647 instruct convL2F_reg_reg(regF dst, rRegL src) 10648 %{ 10649 match(Set dst (ConvL2F src)); 10650 10651 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10652 ins_encode %{ 10653 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10654 %} 10655 ins_pipe(pipe_slow); // XXX 10656 %} 10657 10658 instruct convL2F_reg_mem(regF dst, memory src) 10659 %{ 10660 match(Set dst (ConvL2F (LoadL src))); 10661 10662 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10663 ins_encode %{ 10664 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10665 %} 10666 ins_pipe(pipe_slow); // XXX 10667 %} 10668 10669 instruct convL2D_reg_reg(regD dst, rRegL src) 10670 %{ 10671 match(Set dst (ConvL2D src)); 10672 10673 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10674 ins_encode %{ 10675 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10676 %} 10677 ins_pipe(pipe_slow); // XXX 10678 %} 10679 10680 instruct convL2D_reg_mem(regD dst, memory src) 10681 %{ 10682 match(Set dst (ConvL2D (LoadL src))); 10683 10684 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10685 ins_encode %{ 10686 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10687 %} 10688 ins_pipe(pipe_slow); // XXX 10689 %} 10690 10691 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10692 %{ 10693 match(Set dst (ConvI2L src)); 10694 10695 ins_cost(125); 10696 format %{ "movslq $dst, $src\t# i2l" %} 10697 ins_encode %{ 10698 __ movslq($dst$$Register, $src$$Register); 10699 %} 10700 ins_pipe(ialu_reg_reg); 10701 %} 10702 10703 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10704 // %{ 10705 // match(Set dst (ConvI2L src)); 10706 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10707 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10708 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10709 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10710 // ((const TypeNode*) n)->type()->is_long()->_lo == 10711 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10712 10713 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10714 // ins_encode(enc_copy(dst, src)); 10715 // // opcode(0x63); // needs REX.W 10716 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10717 // ins_pipe(ialu_reg_reg); 10718 // %} 10719 10720 // Zero-extend convert int to long 10721 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10722 %{ 10723 match(Set dst (AndL (ConvI2L src) mask)); 10724 10725 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10726 ins_encode %{ 10727 if ($dst$$reg != $src$$reg) { 10728 __ movl($dst$$Register, $src$$Register); 10729 } 10730 %} 10731 ins_pipe(ialu_reg_reg); 10732 %} 10733 10734 // Zero-extend convert int to long 10735 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10736 %{ 10737 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10738 10739 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10740 ins_encode %{ 10741 __ movl($dst$$Register, $src$$Address); 10742 %} 10743 ins_pipe(ialu_reg_mem); 10744 %} 10745 10746 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10747 %{ 10748 match(Set dst (AndL src mask)); 10749 10750 format %{ "movl $dst, $src\t# zero-extend long" %} 10751 ins_encode %{ 10752 __ movl($dst$$Register, $src$$Register); 10753 %} 10754 ins_pipe(ialu_reg_reg); 10755 %} 10756 10757 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10758 %{ 10759 match(Set dst (ConvL2I src)); 10760 10761 format %{ "movl $dst, $src\t# l2i" %} 10762 ins_encode %{ 10763 __ movl($dst$$Register, $src$$Register); 10764 %} 10765 ins_pipe(ialu_reg_reg); 10766 %} 10767 10768 10769 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10770 match(Set dst (MoveF2I src)); 10771 effect(DEF dst, USE src); 10772 10773 ins_cost(125); 10774 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10775 ins_encode %{ 10776 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10777 %} 10778 ins_pipe(ialu_reg_mem); 10779 %} 10780 10781 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10782 match(Set dst (MoveI2F src)); 10783 effect(DEF dst, USE src); 10784 10785 ins_cost(125); 10786 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10787 ins_encode %{ 10788 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10789 %} 10790 ins_pipe(pipe_slow); 10791 %} 10792 10793 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10794 match(Set dst (MoveD2L src)); 10795 effect(DEF dst, USE src); 10796 10797 ins_cost(125); 10798 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10799 ins_encode %{ 10800 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10801 %} 10802 ins_pipe(ialu_reg_mem); 10803 %} 10804 10805 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10806 predicate(!UseXmmLoadAndClearUpper); 10807 match(Set dst (MoveL2D src)); 10808 effect(DEF dst, USE src); 10809 10810 ins_cost(125); 10811 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10812 ins_encode %{ 10813 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10814 %} 10815 ins_pipe(pipe_slow); 10816 %} 10817 10818 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10819 predicate(UseXmmLoadAndClearUpper); 10820 match(Set dst (MoveL2D src)); 10821 effect(DEF dst, USE src); 10822 10823 ins_cost(125); 10824 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10825 ins_encode %{ 10826 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10827 %} 10828 ins_pipe(pipe_slow); 10829 %} 10830 10831 10832 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10833 match(Set dst (MoveF2I src)); 10834 effect(DEF dst, USE src); 10835 10836 ins_cost(95); // XXX 10837 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10838 ins_encode %{ 10839 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10840 %} 10841 ins_pipe(pipe_slow); 10842 %} 10843 10844 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10845 match(Set dst (MoveI2F src)); 10846 effect(DEF dst, USE src); 10847 10848 ins_cost(100); 10849 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10850 ins_encode %{ 10851 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10852 %} 10853 ins_pipe( ialu_mem_reg ); 10854 %} 10855 10856 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10857 match(Set dst (MoveD2L src)); 10858 effect(DEF dst, USE src); 10859 10860 ins_cost(95); // XXX 10861 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10862 ins_encode %{ 10863 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10864 %} 10865 ins_pipe(pipe_slow); 10866 %} 10867 10868 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10869 match(Set dst (MoveL2D src)); 10870 effect(DEF dst, USE src); 10871 10872 ins_cost(100); 10873 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10874 ins_encode %{ 10875 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10876 %} 10877 ins_pipe(ialu_mem_reg); 10878 %} 10879 10880 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10881 match(Set dst (MoveF2I src)); 10882 effect(DEF dst, USE src); 10883 ins_cost(85); 10884 format %{ "movd $dst,$src\t# MoveF2I" %} 10885 ins_encode %{ 10886 __ movdl($dst$$Register, $src$$XMMRegister); 10887 %} 10888 ins_pipe( pipe_slow ); 10889 %} 10890 10891 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10892 match(Set dst (MoveD2L src)); 10893 effect(DEF dst, USE src); 10894 ins_cost(85); 10895 format %{ "movd $dst,$src\t# MoveD2L" %} 10896 ins_encode %{ 10897 __ movdq($dst$$Register, $src$$XMMRegister); 10898 %} 10899 ins_pipe( pipe_slow ); 10900 %} 10901 10902 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10903 match(Set dst (MoveI2F src)); 10904 effect(DEF dst, USE src); 10905 ins_cost(100); 10906 format %{ "movd $dst,$src\t# MoveI2F" %} 10907 ins_encode %{ 10908 __ movdl($dst$$XMMRegister, $src$$Register); 10909 %} 10910 ins_pipe( pipe_slow ); 10911 %} 10912 10913 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10914 match(Set dst (MoveL2D src)); 10915 effect(DEF dst, USE src); 10916 ins_cost(100); 10917 format %{ "movd $dst,$src\t# MoveL2D" %} 10918 ins_encode %{ 10919 __ movdq($dst$$XMMRegister, $src$$Register); 10920 %} 10921 ins_pipe( pipe_slow ); 10922 %} 10923 10924 10925 // ======================================================================= 10926 // fast clearing of an array 10927 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10928 Universe dummy, rFlagsReg cr) 10929 %{ 10930 predicate(!((ClearArrayNode*)n)->is_large()); 10931 match(Set dummy (ClearArray cnt base)); 10932 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10933 10934 format %{ $$template 10935 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10936 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10937 $$emit$$"jg LARGE\n\t" 10938 $$emit$$"dec rcx\n\t" 10939 $$emit$$"js DONE\t# Zero length\n\t" 10940 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10941 $$emit$$"dec rcx\n\t" 10942 $$emit$$"jge LOOP\n\t" 10943 $$emit$$"jmp DONE\n\t" 10944 $$emit$$"# LARGE:\n\t" 10945 if (UseFastStosb) { 10946 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10947 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10948 } else if (UseXMMForObjInit) { 10949 $$emit$$"mov rdi,rax\n\t" 10950 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10951 $$emit$$"jmpq L_zero_64_bytes\n\t" 10952 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10953 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10954 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10955 $$emit$$"add 0x40,rax\n\t" 10956 $$emit$$"# L_zero_64_bytes:\n\t" 10957 $$emit$$"sub 0x8,rcx\n\t" 10958 $$emit$$"jge L_loop\n\t" 10959 $$emit$$"add 0x4,rcx\n\t" 10960 $$emit$$"jl L_tail\n\t" 10961 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10962 $$emit$$"add 0x20,rax\n\t" 10963 $$emit$$"sub 0x4,rcx\n\t" 10964 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10965 $$emit$$"add 0x4,rcx\n\t" 10966 $$emit$$"jle L_end\n\t" 10967 $$emit$$"dec rcx\n\t" 10968 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10969 $$emit$$"vmovq xmm0,(rax)\n\t" 10970 $$emit$$"add 0x8,rax\n\t" 10971 $$emit$$"dec rcx\n\t" 10972 $$emit$$"jge L_sloop\n\t" 10973 $$emit$$"# L_end:\n\t" 10974 } else { 10975 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10976 } 10977 $$emit$$"# DONE" 10978 %} 10979 ins_encode %{ 10980 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10981 $tmp$$XMMRegister, false); 10982 %} 10983 ins_pipe(pipe_slow); 10984 %} 10985 10986 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10987 Universe dummy, rFlagsReg cr) 10988 %{ 10989 predicate(((ClearArrayNode*)n)->is_large()); 10990 match(Set dummy (ClearArray cnt base)); 10991 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10992 10993 format %{ $$template 10994 if (UseFastStosb) { 10995 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10996 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10997 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10998 } else if (UseXMMForObjInit) { 10999 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 11000 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 11001 $$emit$$"jmpq L_zero_64_bytes\n\t" 11002 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11003 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11004 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11005 $$emit$$"add 0x40,rax\n\t" 11006 $$emit$$"# L_zero_64_bytes:\n\t" 11007 $$emit$$"sub 0x8,rcx\n\t" 11008 $$emit$$"jge L_loop\n\t" 11009 $$emit$$"add 0x4,rcx\n\t" 11010 $$emit$$"jl L_tail\n\t" 11011 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11012 $$emit$$"add 0x20,rax\n\t" 11013 $$emit$$"sub 0x4,rcx\n\t" 11014 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11015 $$emit$$"add 0x4,rcx\n\t" 11016 $$emit$$"jle L_end\n\t" 11017 $$emit$$"dec rcx\n\t" 11018 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11019 $$emit$$"vmovq xmm0,(rax)\n\t" 11020 $$emit$$"add 0x8,rax\n\t" 11021 $$emit$$"dec rcx\n\t" 11022 $$emit$$"jge L_sloop\n\t" 11023 $$emit$$"# L_end:\n\t" 11024 } else { 11025 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11026 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11027 } 11028 %} 11029 ins_encode %{ 11030 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11031 $tmp$$XMMRegister, true); 11032 %} 11033 ins_pipe(pipe_slow); 11034 %} 11035 11036 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11037 rax_RegI result, regD tmp1, rFlagsReg cr) 11038 %{ 11039 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11040 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11041 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11042 11043 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11044 ins_encode %{ 11045 __ string_compare($str1$$Register, $str2$$Register, 11046 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11047 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11048 %} 11049 ins_pipe( pipe_slow ); 11050 %} 11051 11052 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11053 rax_RegI result, regD tmp1, rFlagsReg cr) 11054 %{ 11055 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11056 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11057 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11058 11059 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11060 ins_encode %{ 11061 __ string_compare($str1$$Register, $str2$$Register, 11062 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11063 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11064 %} 11065 ins_pipe( pipe_slow ); 11066 %} 11067 11068 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11069 rax_RegI result, regD tmp1, rFlagsReg cr) 11070 %{ 11071 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11072 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11073 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11074 11075 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11076 ins_encode %{ 11077 __ string_compare($str1$$Register, $str2$$Register, 11078 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11079 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11080 %} 11081 ins_pipe( pipe_slow ); 11082 %} 11083 11084 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11085 rax_RegI result, regD tmp1, rFlagsReg cr) 11086 %{ 11087 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11088 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11089 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11090 11091 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11092 ins_encode %{ 11093 __ string_compare($str2$$Register, $str1$$Register, 11094 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11095 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11096 %} 11097 ins_pipe( pipe_slow ); 11098 %} 11099 11100 // fast search of substring with known size. 11101 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11102 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11103 %{ 11104 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11105 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11106 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11107 11108 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11109 ins_encode %{ 11110 int icnt2 = (int)$int_cnt2$$constant; 11111 if (icnt2 >= 16) { 11112 // IndexOf for constant substrings with size >= 16 elements 11113 // which don't need to be loaded through stack. 11114 __ string_indexofC8($str1$$Register, $str2$$Register, 11115 $cnt1$$Register, $cnt2$$Register, 11116 icnt2, $result$$Register, 11117 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11118 } else { 11119 // Small strings are loaded through stack if they cross page boundary. 11120 __ string_indexof($str1$$Register, $str2$$Register, 11121 $cnt1$$Register, $cnt2$$Register, 11122 icnt2, $result$$Register, 11123 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11124 } 11125 %} 11126 ins_pipe( pipe_slow ); 11127 %} 11128 11129 // fast search of substring with known size. 11130 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11131 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11132 %{ 11133 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11134 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11135 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11136 11137 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11138 ins_encode %{ 11139 int icnt2 = (int)$int_cnt2$$constant; 11140 if (icnt2 >= 8) { 11141 // IndexOf for constant substrings with size >= 8 elements 11142 // which don't need to be loaded through stack. 11143 __ string_indexofC8($str1$$Register, $str2$$Register, 11144 $cnt1$$Register, $cnt2$$Register, 11145 icnt2, $result$$Register, 11146 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11147 } else { 11148 // Small strings are loaded through stack if they cross page boundary. 11149 __ string_indexof($str1$$Register, $str2$$Register, 11150 $cnt1$$Register, $cnt2$$Register, 11151 icnt2, $result$$Register, 11152 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11153 } 11154 %} 11155 ins_pipe( pipe_slow ); 11156 %} 11157 11158 // fast search of substring with known size. 11159 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11160 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11161 %{ 11162 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11163 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11164 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11165 11166 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11167 ins_encode %{ 11168 int icnt2 = (int)$int_cnt2$$constant; 11169 if (icnt2 >= 8) { 11170 // IndexOf for constant substrings with size >= 8 elements 11171 // which don't need to be loaded through stack. 11172 __ string_indexofC8($str1$$Register, $str2$$Register, 11173 $cnt1$$Register, $cnt2$$Register, 11174 icnt2, $result$$Register, 11175 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11176 } else { 11177 // Small strings are loaded through stack if they cross page boundary. 11178 __ string_indexof($str1$$Register, $str2$$Register, 11179 $cnt1$$Register, $cnt2$$Register, 11180 icnt2, $result$$Register, 11181 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11182 } 11183 %} 11184 ins_pipe( pipe_slow ); 11185 %} 11186 11187 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11188 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11189 %{ 11190 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11191 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11192 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11193 11194 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11195 ins_encode %{ 11196 __ string_indexof($str1$$Register, $str2$$Register, 11197 $cnt1$$Register, $cnt2$$Register, 11198 (-1), $result$$Register, 11199 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11200 %} 11201 ins_pipe( pipe_slow ); 11202 %} 11203 11204 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11205 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11206 %{ 11207 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11208 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11209 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11210 11211 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11212 ins_encode %{ 11213 __ string_indexof($str1$$Register, $str2$$Register, 11214 $cnt1$$Register, $cnt2$$Register, 11215 (-1), $result$$Register, 11216 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11217 %} 11218 ins_pipe( pipe_slow ); 11219 %} 11220 11221 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11222 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11223 %{ 11224 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11225 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11226 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11227 11228 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11229 ins_encode %{ 11230 __ string_indexof($str1$$Register, $str2$$Register, 11231 $cnt1$$Register, $cnt2$$Register, 11232 (-1), $result$$Register, 11233 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11234 %} 11235 ins_pipe( pipe_slow ); 11236 %} 11237 11238 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11239 rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr) 11240 %{ 11241 predicate(UseSSE42Intrinsics); 11242 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11243 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11244 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11245 ins_encode %{ 11246 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11247 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11248 %} 11249 ins_pipe( pipe_slow ); 11250 %} 11251 11252 // fast string equals 11253 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11254 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11255 %{ 11256 match(Set result (StrEquals (Binary str1 str2) cnt)); 11257 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11258 11259 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11260 ins_encode %{ 11261 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11262 $cnt$$Register, $result$$Register, $tmp3$$Register, 11263 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11264 %} 11265 ins_pipe( pipe_slow ); 11266 %} 11267 11268 // fast array equals 11269 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11270 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11271 %{ 11272 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11273 match(Set result (AryEq ary1 ary2)); 11274 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11275 11276 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11277 ins_encode %{ 11278 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11279 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11280 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11281 %} 11282 ins_pipe( pipe_slow ); 11283 %} 11284 11285 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11286 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11287 %{ 11288 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11289 match(Set result (AryEq ary1 ary2)); 11290 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11291 11292 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11293 ins_encode %{ 11294 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11295 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11296 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11297 %} 11298 ins_pipe( pipe_slow ); 11299 %} 11300 11301 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11302 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11303 %{ 11304 match(Set result (HasNegatives ary1 len)); 11305 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11306 11307 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11308 ins_encode %{ 11309 __ has_negatives($ary1$$Register, $len$$Register, 11310 $result$$Register, $tmp3$$Register, 11311 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11312 %} 11313 ins_pipe( pipe_slow ); 11314 %} 11315 11316 // fast char[] to byte[] compression 11317 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11318 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11319 match(Set result (StrCompressedCopy src (Binary dst len))); 11320 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11321 11322 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11323 ins_encode %{ 11324 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11325 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11326 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11327 %} 11328 ins_pipe( pipe_slow ); 11329 %} 11330 11331 // fast byte[] to char[] inflation 11332 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11333 regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11334 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11335 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11336 11337 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11338 ins_encode %{ 11339 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11340 $tmp1$$XMMRegister, $tmp2$$Register); 11341 %} 11342 ins_pipe( pipe_slow ); 11343 %} 11344 11345 // encode char[] to byte[] in ISO_8859_1 11346 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11347 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11348 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11349 match(Set result (EncodeISOArray src (Binary dst len))); 11350 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11351 11352 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11353 ins_encode %{ 11354 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11355 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11356 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11357 %} 11358 ins_pipe( pipe_slow ); 11359 %} 11360 11361 //----------Overflow Math Instructions----------------------------------------- 11362 11363 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11364 %{ 11365 match(Set cr (OverflowAddI op1 op2)); 11366 effect(DEF cr, USE_KILL op1, USE op2); 11367 11368 format %{ "addl $op1, $op2\t# overflow check int" %} 11369 11370 ins_encode %{ 11371 __ addl($op1$$Register, $op2$$Register); 11372 %} 11373 ins_pipe(ialu_reg_reg); 11374 %} 11375 11376 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11377 %{ 11378 match(Set cr (OverflowAddI op1 op2)); 11379 effect(DEF cr, USE_KILL op1, USE op2); 11380 11381 format %{ "addl $op1, $op2\t# overflow check int" %} 11382 11383 ins_encode %{ 11384 __ addl($op1$$Register, $op2$$constant); 11385 %} 11386 ins_pipe(ialu_reg_reg); 11387 %} 11388 11389 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11390 %{ 11391 match(Set cr (OverflowAddL op1 op2)); 11392 effect(DEF cr, USE_KILL op1, USE op2); 11393 11394 format %{ "addq $op1, $op2\t# overflow check long" %} 11395 ins_encode %{ 11396 __ addq($op1$$Register, $op2$$Register); 11397 %} 11398 ins_pipe(ialu_reg_reg); 11399 %} 11400 11401 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11402 %{ 11403 match(Set cr (OverflowAddL op1 op2)); 11404 effect(DEF cr, USE_KILL op1, USE op2); 11405 11406 format %{ "addq $op1, $op2\t# overflow check long" %} 11407 ins_encode %{ 11408 __ addq($op1$$Register, $op2$$constant); 11409 %} 11410 ins_pipe(ialu_reg_reg); 11411 %} 11412 11413 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11414 %{ 11415 match(Set cr (OverflowSubI op1 op2)); 11416 11417 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11418 ins_encode %{ 11419 __ cmpl($op1$$Register, $op2$$Register); 11420 %} 11421 ins_pipe(ialu_reg_reg); 11422 %} 11423 11424 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11425 %{ 11426 match(Set cr (OverflowSubI op1 op2)); 11427 11428 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11429 ins_encode %{ 11430 __ cmpl($op1$$Register, $op2$$constant); 11431 %} 11432 ins_pipe(ialu_reg_reg); 11433 %} 11434 11435 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11436 %{ 11437 match(Set cr (OverflowSubL op1 op2)); 11438 11439 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11440 ins_encode %{ 11441 __ cmpq($op1$$Register, $op2$$Register); 11442 %} 11443 ins_pipe(ialu_reg_reg); 11444 %} 11445 11446 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11447 %{ 11448 match(Set cr (OverflowSubL op1 op2)); 11449 11450 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11451 ins_encode %{ 11452 __ cmpq($op1$$Register, $op2$$constant); 11453 %} 11454 ins_pipe(ialu_reg_reg); 11455 %} 11456 11457 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11458 %{ 11459 match(Set cr (OverflowSubI zero op2)); 11460 effect(DEF cr, USE_KILL op2); 11461 11462 format %{ "negl $op2\t# overflow check int" %} 11463 ins_encode %{ 11464 __ negl($op2$$Register); 11465 %} 11466 ins_pipe(ialu_reg_reg); 11467 %} 11468 11469 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11470 %{ 11471 match(Set cr (OverflowSubL zero op2)); 11472 effect(DEF cr, USE_KILL op2); 11473 11474 format %{ "negq $op2\t# overflow check long" %} 11475 ins_encode %{ 11476 __ negq($op2$$Register); 11477 %} 11478 ins_pipe(ialu_reg_reg); 11479 %} 11480 11481 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11482 %{ 11483 match(Set cr (OverflowMulI op1 op2)); 11484 effect(DEF cr, USE_KILL op1, USE op2); 11485 11486 format %{ "imull $op1, $op2\t# overflow check int" %} 11487 ins_encode %{ 11488 __ imull($op1$$Register, $op2$$Register); 11489 %} 11490 ins_pipe(ialu_reg_reg_alu0); 11491 %} 11492 11493 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11494 %{ 11495 match(Set cr (OverflowMulI op1 op2)); 11496 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11497 11498 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11499 ins_encode %{ 11500 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11501 %} 11502 ins_pipe(ialu_reg_reg_alu0); 11503 %} 11504 11505 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11506 %{ 11507 match(Set cr (OverflowMulL op1 op2)); 11508 effect(DEF cr, USE_KILL op1, USE op2); 11509 11510 format %{ "imulq $op1, $op2\t# overflow check long" %} 11511 ins_encode %{ 11512 __ imulq($op1$$Register, $op2$$Register); 11513 %} 11514 ins_pipe(ialu_reg_reg_alu0); 11515 %} 11516 11517 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11518 %{ 11519 match(Set cr (OverflowMulL op1 op2)); 11520 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11521 11522 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11523 ins_encode %{ 11524 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11525 %} 11526 ins_pipe(ialu_reg_reg_alu0); 11527 %} 11528 11529 11530 //----------Control Flow Instructions------------------------------------------ 11531 // Signed compare Instructions 11532 11533 // XXX more variants!! 11534 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11535 %{ 11536 match(Set cr (CmpI op1 op2)); 11537 effect(DEF cr, USE op1, USE op2); 11538 11539 format %{ "cmpl $op1, $op2" %} 11540 opcode(0x3B); /* Opcode 3B /r */ 11541 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11542 ins_pipe(ialu_cr_reg_reg); 11543 %} 11544 11545 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11546 %{ 11547 match(Set cr (CmpI op1 op2)); 11548 11549 format %{ "cmpl $op1, $op2" %} 11550 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11551 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11552 ins_pipe(ialu_cr_reg_imm); 11553 %} 11554 11555 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11556 %{ 11557 match(Set cr (CmpI op1 (LoadI op2))); 11558 11559 ins_cost(500); // XXX 11560 format %{ "cmpl $op1, $op2" %} 11561 opcode(0x3B); /* Opcode 3B /r */ 11562 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11563 ins_pipe(ialu_cr_reg_mem); 11564 %} 11565 11566 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11567 %{ 11568 match(Set cr (CmpI src zero)); 11569 11570 format %{ "testl $src, $src" %} 11571 opcode(0x85); 11572 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11573 ins_pipe(ialu_cr_reg_imm); 11574 %} 11575 11576 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11577 %{ 11578 match(Set cr (CmpI (AndI src con) zero)); 11579 11580 format %{ "testl $src, $con" %} 11581 opcode(0xF7, 0x00); 11582 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11583 ins_pipe(ialu_cr_reg_imm); 11584 %} 11585 11586 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11587 %{ 11588 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11589 11590 format %{ "testl $src, $mem" %} 11591 opcode(0x85); 11592 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11593 ins_pipe(ialu_cr_reg_mem); 11594 %} 11595 11596 // Unsigned compare Instructions; really, same as signed except they 11597 // produce an rFlagsRegU instead of rFlagsReg. 11598 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11599 %{ 11600 match(Set cr (CmpU op1 op2)); 11601 11602 format %{ "cmpl $op1, $op2\t# unsigned" %} 11603 opcode(0x3B); /* Opcode 3B /r */ 11604 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11605 ins_pipe(ialu_cr_reg_reg); 11606 %} 11607 11608 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11609 %{ 11610 match(Set cr (CmpU op1 op2)); 11611 11612 format %{ "cmpl $op1, $op2\t# unsigned" %} 11613 opcode(0x81,0x07); /* Opcode 81 /7 */ 11614 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11615 ins_pipe(ialu_cr_reg_imm); 11616 %} 11617 11618 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11619 %{ 11620 match(Set cr (CmpU op1 (LoadI op2))); 11621 11622 ins_cost(500); // XXX 11623 format %{ "cmpl $op1, $op2\t# unsigned" %} 11624 opcode(0x3B); /* Opcode 3B /r */ 11625 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11626 ins_pipe(ialu_cr_reg_mem); 11627 %} 11628 11629 // // // Cisc-spilled version of cmpU_rReg 11630 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11631 // //%{ 11632 // // match(Set cr (CmpU (LoadI op1) op2)); 11633 // // 11634 // // format %{ "CMPu $op1,$op2" %} 11635 // // ins_cost(500); 11636 // // opcode(0x39); /* Opcode 39 /r */ 11637 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11638 // //%} 11639 11640 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11641 %{ 11642 match(Set cr (CmpU src zero)); 11643 11644 format %{ "testl $src, $src\t# unsigned" %} 11645 opcode(0x85); 11646 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11647 ins_pipe(ialu_cr_reg_imm); 11648 %} 11649 11650 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11651 %{ 11652 match(Set cr (CmpP op1 op2)); 11653 11654 format %{ "cmpq $op1, $op2\t# ptr" %} 11655 opcode(0x3B); /* Opcode 3B /r */ 11656 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11657 ins_pipe(ialu_cr_reg_reg); 11658 %} 11659 11660 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11661 %{ 11662 match(Set cr (CmpP op1 (LoadP op2))); 11663 11664 ins_cost(500); // XXX 11665 format %{ "cmpq $op1, $op2\t# ptr" %} 11666 opcode(0x3B); /* Opcode 3B /r */ 11667 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11668 ins_pipe(ialu_cr_reg_mem); 11669 %} 11670 11671 // // // Cisc-spilled version of cmpP_rReg 11672 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11673 // //%{ 11674 // // match(Set cr (CmpP (LoadP op1) op2)); 11675 // // 11676 // // format %{ "CMPu $op1,$op2" %} 11677 // // ins_cost(500); 11678 // // opcode(0x39); /* Opcode 39 /r */ 11679 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11680 // //%} 11681 11682 // XXX this is generalized by compP_rReg_mem??? 11683 // Compare raw pointer (used in out-of-heap check). 11684 // Only works because non-oop pointers must be raw pointers 11685 // and raw pointers have no anti-dependencies. 11686 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11687 %{ 11688 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11689 match(Set cr (CmpP op1 (LoadP op2))); 11690 11691 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11692 opcode(0x3B); /* Opcode 3B /r */ 11693 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11694 ins_pipe(ialu_cr_reg_mem); 11695 %} 11696 11697 // This will generate a signed flags result. This should be OK since 11698 // any compare to a zero should be eq/neq. 11699 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11700 %{ 11701 match(Set cr (CmpP src zero)); 11702 11703 format %{ "testq $src, $src\t# ptr" %} 11704 opcode(0x85); 11705 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11706 ins_pipe(ialu_cr_reg_imm); 11707 %} 11708 11709 // This will generate a signed flags result. This should be OK since 11710 // any compare to a zero should be eq/neq. 11711 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11712 %{ 11713 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11714 match(Set cr (CmpP (LoadP op) zero)); 11715 11716 ins_cost(500); // XXX 11717 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11718 opcode(0xF7); /* Opcode F7 /0 */ 11719 ins_encode(REX_mem_wide(op), 11720 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11721 ins_pipe(ialu_cr_reg_imm); 11722 %} 11723 11724 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11725 %{ 11726 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11727 match(Set cr (CmpP (LoadP mem) zero)); 11728 11729 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11730 ins_encode %{ 11731 __ cmpq(r12, $mem$$Address); 11732 %} 11733 ins_pipe(ialu_cr_reg_mem); 11734 %} 11735 11736 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11737 %{ 11738 match(Set cr (CmpN op1 op2)); 11739 11740 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11741 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11742 ins_pipe(ialu_cr_reg_reg); 11743 %} 11744 11745 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11746 %{ 11747 match(Set cr (CmpN src (LoadN mem))); 11748 11749 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11750 ins_encode %{ 11751 __ cmpl($src$$Register, $mem$$Address); 11752 %} 11753 ins_pipe(ialu_cr_reg_mem); 11754 %} 11755 11756 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11757 match(Set cr (CmpN op1 op2)); 11758 11759 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11760 ins_encode %{ 11761 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11762 %} 11763 ins_pipe(ialu_cr_reg_imm); 11764 %} 11765 11766 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11767 %{ 11768 match(Set cr (CmpN src (LoadN mem))); 11769 11770 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11771 ins_encode %{ 11772 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11773 %} 11774 ins_pipe(ialu_cr_reg_mem); 11775 %} 11776 11777 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11778 match(Set cr (CmpN op1 op2)); 11779 11780 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11781 ins_encode %{ 11782 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11783 %} 11784 ins_pipe(ialu_cr_reg_imm); 11785 %} 11786 11787 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11788 %{ 11789 match(Set cr (CmpN src (LoadNKlass mem))); 11790 11791 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11792 ins_encode %{ 11793 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11794 %} 11795 ins_pipe(ialu_cr_reg_mem); 11796 %} 11797 11798 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11799 match(Set cr (CmpN src zero)); 11800 11801 format %{ "testl $src, $src\t# compressed ptr" %} 11802 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11803 ins_pipe(ialu_cr_reg_imm); 11804 %} 11805 11806 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11807 %{ 11808 predicate(Universe::narrow_oop_base() != NULL); 11809 match(Set cr (CmpN (LoadN mem) zero)); 11810 11811 ins_cost(500); // XXX 11812 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11813 ins_encode %{ 11814 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11815 %} 11816 ins_pipe(ialu_cr_reg_mem); 11817 %} 11818 11819 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11820 %{ 11821 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11822 match(Set cr (CmpN (LoadN mem) zero)); 11823 11824 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11825 ins_encode %{ 11826 __ cmpl(r12, $mem$$Address); 11827 %} 11828 ins_pipe(ialu_cr_reg_mem); 11829 %} 11830 11831 // Yanked all unsigned pointer compare operations. 11832 // Pointer compares are done with CmpP which is already unsigned. 11833 11834 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11835 %{ 11836 match(Set cr (CmpL op1 op2)); 11837 11838 format %{ "cmpq $op1, $op2" %} 11839 opcode(0x3B); /* Opcode 3B /r */ 11840 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11841 ins_pipe(ialu_cr_reg_reg); 11842 %} 11843 11844 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11845 %{ 11846 match(Set cr (CmpL op1 op2)); 11847 11848 format %{ "cmpq $op1, $op2" %} 11849 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11850 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11851 ins_pipe(ialu_cr_reg_imm); 11852 %} 11853 11854 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11855 %{ 11856 match(Set cr (CmpL op1 (LoadL op2))); 11857 11858 format %{ "cmpq $op1, $op2" %} 11859 opcode(0x3B); /* Opcode 3B /r */ 11860 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11861 ins_pipe(ialu_cr_reg_mem); 11862 %} 11863 11864 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11865 %{ 11866 match(Set cr (CmpL src zero)); 11867 11868 format %{ "testq $src, $src" %} 11869 opcode(0x85); 11870 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11871 ins_pipe(ialu_cr_reg_imm); 11872 %} 11873 11874 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11875 %{ 11876 match(Set cr (CmpL (AndL src con) zero)); 11877 11878 format %{ "testq $src, $con\t# long" %} 11879 opcode(0xF7, 0x00); 11880 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11881 ins_pipe(ialu_cr_reg_imm); 11882 %} 11883 11884 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11885 %{ 11886 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11887 11888 format %{ "testq $src, $mem" %} 11889 opcode(0x85); 11890 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11891 ins_pipe(ialu_cr_reg_mem); 11892 %} 11893 11894 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11895 %{ 11896 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11897 11898 format %{ "testq $src, $mem" %} 11899 opcode(0x85); 11900 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11901 ins_pipe(ialu_cr_reg_mem); 11902 %} 11903 11904 // Manifest a CmpL result in an integer register. Very painful. 11905 // This is the test to avoid. 11906 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11907 %{ 11908 match(Set dst (CmpL3 src1 src2)); 11909 effect(KILL flags); 11910 11911 ins_cost(275); // XXX 11912 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11913 "movl $dst, -1\n\t" 11914 "jl,s done\n\t" 11915 "setne $dst\n\t" 11916 "movzbl $dst, $dst\n\t" 11917 "done:" %} 11918 ins_encode(cmpl3_flag(src1, src2, dst)); 11919 ins_pipe(pipe_slow); 11920 %} 11921 11922 // Unsigned long compare Instructions; really, same as signed long except they 11923 // produce an rFlagsRegU instead of rFlagsReg. 11924 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11925 %{ 11926 match(Set cr (CmpUL op1 op2)); 11927 11928 format %{ "cmpq $op1, $op2\t# unsigned" %} 11929 opcode(0x3B); /* Opcode 3B /r */ 11930 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11931 ins_pipe(ialu_cr_reg_reg); 11932 %} 11933 11934 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11935 %{ 11936 match(Set cr (CmpUL op1 op2)); 11937 11938 format %{ "cmpq $op1, $op2\t# unsigned" %} 11939 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11940 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11941 ins_pipe(ialu_cr_reg_imm); 11942 %} 11943 11944 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11945 %{ 11946 match(Set cr (CmpUL op1 (LoadL op2))); 11947 11948 format %{ "cmpq $op1, $op2\t# unsigned" %} 11949 opcode(0x3B); /* Opcode 3B /r */ 11950 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11951 ins_pipe(ialu_cr_reg_mem); 11952 %} 11953 11954 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11955 %{ 11956 match(Set cr (CmpUL src zero)); 11957 11958 format %{ "testq $src, $src\t# unsigned" %} 11959 opcode(0x85); 11960 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11961 ins_pipe(ialu_cr_reg_imm); 11962 %} 11963 11964 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11965 %{ 11966 match(Set cr (CmpI (LoadB mem) imm)); 11967 11968 ins_cost(125); 11969 format %{ "cmpb $mem, $imm" %} 11970 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11971 ins_pipe(ialu_cr_reg_mem); 11972 %} 11973 11974 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 11975 %{ 11976 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11977 11978 ins_cost(125); 11979 format %{ "testb $mem, $imm" %} 11980 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11981 ins_pipe(ialu_cr_reg_mem); 11982 %} 11983 11984 //----------Max and Min-------------------------------------------------------- 11985 // Min Instructions 11986 11987 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11988 %{ 11989 effect(USE_DEF dst, USE src, USE cr); 11990 11991 format %{ "cmovlgt $dst, $src\t# min" %} 11992 opcode(0x0F, 0x4F); 11993 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11994 ins_pipe(pipe_cmov_reg); 11995 %} 11996 11997 11998 instruct minI_rReg(rRegI dst, rRegI src) 11999 %{ 12000 match(Set dst (MinI dst src)); 12001 12002 ins_cost(200); 12003 expand %{ 12004 rFlagsReg cr; 12005 compI_rReg(cr, dst, src); 12006 cmovI_reg_g(dst, src, cr); 12007 %} 12008 %} 12009 12010 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12011 %{ 12012 effect(USE_DEF dst, USE src, USE cr); 12013 12014 format %{ "cmovllt $dst, $src\t# max" %} 12015 opcode(0x0F, 0x4C); 12016 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12017 ins_pipe(pipe_cmov_reg); 12018 %} 12019 12020 12021 instruct maxI_rReg(rRegI dst, rRegI src) 12022 %{ 12023 match(Set dst (MaxI dst src)); 12024 12025 ins_cost(200); 12026 expand %{ 12027 rFlagsReg cr; 12028 compI_rReg(cr, dst, src); 12029 cmovI_reg_l(dst, src, cr); 12030 %} 12031 %} 12032 12033 // ============================================================================ 12034 // Branch Instructions 12035 12036 // Jump Direct - Label defines a relative address from JMP+1 12037 instruct jmpDir(label labl) 12038 %{ 12039 match(Goto); 12040 effect(USE labl); 12041 12042 ins_cost(300); 12043 format %{ "jmp $labl" %} 12044 size(5); 12045 ins_encode %{ 12046 Label* L = $labl$$label; 12047 __ jmp(*L, false); // Always long jump 12048 %} 12049 ins_pipe(pipe_jmp); 12050 %} 12051 12052 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12053 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12054 %{ 12055 match(If cop cr); 12056 effect(USE labl); 12057 12058 ins_cost(300); 12059 format %{ "j$cop $labl" %} 12060 size(6); 12061 ins_encode %{ 12062 Label* L = $labl$$label; 12063 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12064 %} 12065 ins_pipe(pipe_jcc); 12066 %} 12067 12068 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12069 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12070 %{ 12071 predicate(!n->has_vector_mask_set()); 12072 match(CountedLoopEnd cop cr); 12073 effect(USE labl); 12074 12075 ins_cost(300); 12076 format %{ "j$cop $labl\t# loop end" %} 12077 size(6); 12078 ins_encode %{ 12079 Label* L = $labl$$label; 12080 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12081 %} 12082 ins_pipe(pipe_jcc); 12083 %} 12084 12085 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12086 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12087 predicate(!n->has_vector_mask_set()); 12088 match(CountedLoopEnd cop cmp); 12089 effect(USE labl); 12090 12091 ins_cost(300); 12092 format %{ "j$cop,u $labl\t# loop end" %} 12093 size(6); 12094 ins_encode %{ 12095 Label* L = $labl$$label; 12096 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12097 %} 12098 ins_pipe(pipe_jcc); 12099 %} 12100 12101 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12102 predicate(!n->has_vector_mask_set()); 12103 match(CountedLoopEnd cop cmp); 12104 effect(USE labl); 12105 12106 ins_cost(200); 12107 format %{ "j$cop,u $labl\t# loop end" %} 12108 size(6); 12109 ins_encode %{ 12110 Label* L = $labl$$label; 12111 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12112 %} 12113 ins_pipe(pipe_jcc); 12114 %} 12115 12116 // mask version 12117 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12118 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12119 %{ 12120 predicate(n->has_vector_mask_set()); 12121 match(CountedLoopEnd cop cr); 12122 effect(USE labl); 12123 12124 ins_cost(400); 12125 format %{ "j$cop $labl\t# loop end\n\t" 12126 "restorevectmask \t# vector mask restore for loops" %} 12127 size(10); 12128 ins_encode %{ 12129 Label* L = $labl$$label; 12130 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12131 __ restorevectmask(); 12132 %} 12133 ins_pipe(pipe_jcc); 12134 %} 12135 12136 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12137 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12138 predicate(n->has_vector_mask_set()); 12139 match(CountedLoopEnd cop cmp); 12140 effect(USE labl); 12141 12142 ins_cost(400); 12143 format %{ "j$cop,u $labl\t# loop end\n\t" 12144 "restorevectmask \t# vector mask restore for loops" %} 12145 size(10); 12146 ins_encode %{ 12147 Label* L = $labl$$label; 12148 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12149 __ restorevectmask(); 12150 %} 12151 ins_pipe(pipe_jcc); 12152 %} 12153 12154 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12155 predicate(n->has_vector_mask_set()); 12156 match(CountedLoopEnd cop cmp); 12157 effect(USE labl); 12158 12159 ins_cost(300); 12160 format %{ "j$cop,u $labl\t# loop end\n\t" 12161 "restorevectmask \t# vector mask restore for loops" %} 12162 size(10); 12163 ins_encode %{ 12164 Label* L = $labl$$label; 12165 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12166 __ restorevectmask(); 12167 %} 12168 ins_pipe(pipe_jcc); 12169 %} 12170 12171 // Jump Direct Conditional - using unsigned comparison 12172 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12173 match(If cop cmp); 12174 effect(USE labl); 12175 12176 ins_cost(300); 12177 format %{ "j$cop,u $labl" %} 12178 size(6); 12179 ins_encode %{ 12180 Label* L = $labl$$label; 12181 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12182 %} 12183 ins_pipe(pipe_jcc); 12184 %} 12185 12186 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12187 match(If cop cmp); 12188 effect(USE labl); 12189 12190 ins_cost(200); 12191 format %{ "j$cop,u $labl" %} 12192 size(6); 12193 ins_encode %{ 12194 Label* L = $labl$$label; 12195 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12196 %} 12197 ins_pipe(pipe_jcc); 12198 %} 12199 12200 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12201 match(If cop cmp); 12202 effect(USE labl); 12203 12204 ins_cost(200); 12205 format %{ $$template 12206 if ($cop$$cmpcode == Assembler::notEqual) { 12207 $$emit$$"jp,u $labl\n\t" 12208 $$emit$$"j$cop,u $labl" 12209 } else { 12210 $$emit$$"jp,u done\n\t" 12211 $$emit$$"j$cop,u $labl\n\t" 12212 $$emit$$"done:" 12213 } 12214 %} 12215 ins_encode %{ 12216 Label* l = $labl$$label; 12217 if ($cop$$cmpcode == Assembler::notEqual) { 12218 __ jcc(Assembler::parity, *l, false); 12219 __ jcc(Assembler::notEqual, *l, false); 12220 } else if ($cop$$cmpcode == Assembler::equal) { 12221 Label done; 12222 __ jccb(Assembler::parity, done); 12223 __ jcc(Assembler::equal, *l, false); 12224 __ bind(done); 12225 } else { 12226 ShouldNotReachHere(); 12227 } 12228 %} 12229 ins_pipe(pipe_jcc); 12230 %} 12231 12232 // ============================================================================ 12233 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12234 // superklass array for an instance of the superklass. Set a hidden 12235 // internal cache on a hit (cache is checked with exposed code in 12236 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12237 // encoding ALSO sets flags. 12238 12239 instruct partialSubtypeCheck(rdi_RegP result, 12240 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12241 rFlagsReg cr) 12242 %{ 12243 match(Set result (PartialSubtypeCheck sub super)); 12244 effect(KILL rcx, KILL cr); 12245 12246 ins_cost(1100); // slightly larger than the next version 12247 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12248 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12249 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12250 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12251 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12252 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12253 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12254 "miss:\t" %} 12255 12256 opcode(0x1); // Force a XOR of RDI 12257 ins_encode(enc_PartialSubtypeCheck()); 12258 ins_pipe(pipe_slow); 12259 %} 12260 12261 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12262 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12263 immP0 zero, 12264 rdi_RegP result) 12265 %{ 12266 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12267 effect(KILL rcx, KILL result); 12268 12269 ins_cost(1000); 12270 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12271 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12272 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12273 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12274 "jne,s miss\t\t# Missed: flags nz\n\t" 12275 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12276 "miss:\t" %} 12277 12278 opcode(0x0); // No need to XOR RDI 12279 ins_encode(enc_PartialSubtypeCheck()); 12280 ins_pipe(pipe_slow); 12281 %} 12282 12283 // ============================================================================ 12284 // Branch Instructions -- short offset versions 12285 // 12286 // These instructions are used to replace jumps of a long offset (the default 12287 // match) with jumps of a shorter offset. These instructions are all tagged 12288 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12289 // match rules in general matching. Instead, the ADLC generates a conversion 12290 // method in the MachNode which can be used to do in-place replacement of the 12291 // long variant with the shorter variant. The compiler will determine if a 12292 // branch can be taken by the is_short_branch_offset() predicate in the machine 12293 // specific code section of the file. 12294 12295 // Jump Direct - Label defines a relative address from JMP+1 12296 instruct jmpDir_short(label labl) %{ 12297 match(Goto); 12298 effect(USE labl); 12299 12300 ins_cost(300); 12301 format %{ "jmp,s $labl" %} 12302 size(2); 12303 ins_encode %{ 12304 Label* L = $labl$$label; 12305 __ jmpb(*L); 12306 %} 12307 ins_pipe(pipe_jmp); 12308 ins_short_branch(1); 12309 %} 12310 12311 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12312 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12313 match(If cop cr); 12314 effect(USE labl); 12315 12316 ins_cost(300); 12317 format %{ "j$cop,s $labl" %} 12318 size(2); 12319 ins_encode %{ 12320 Label* L = $labl$$label; 12321 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12322 %} 12323 ins_pipe(pipe_jcc); 12324 ins_short_branch(1); 12325 %} 12326 12327 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12328 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12329 match(CountedLoopEnd cop cr); 12330 effect(USE labl); 12331 12332 ins_cost(300); 12333 format %{ "j$cop,s $labl\t# loop end" %} 12334 size(2); 12335 ins_encode %{ 12336 Label* L = $labl$$label; 12337 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12338 %} 12339 ins_pipe(pipe_jcc); 12340 ins_short_branch(1); 12341 %} 12342 12343 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12344 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12345 match(CountedLoopEnd cop cmp); 12346 effect(USE labl); 12347 12348 ins_cost(300); 12349 format %{ "j$cop,us $labl\t# loop end" %} 12350 size(2); 12351 ins_encode %{ 12352 Label* L = $labl$$label; 12353 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12354 %} 12355 ins_pipe(pipe_jcc); 12356 ins_short_branch(1); 12357 %} 12358 12359 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12360 match(CountedLoopEnd cop cmp); 12361 effect(USE labl); 12362 12363 ins_cost(300); 12364 format %{ "j$cop,us $labl\t# loop end" %} 12365 size(2); 12366 ins_encode %{ 12367 Label* L = $labl$$label; 12368 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12369 %} 12370 ins_pipe(pipe_jcc); 12371 ins_short_branch(1); 12372 %} 12373 12374 // Jump Direct Conditional - using unsigned comparison 12375 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12376 match(If cop cmp); 12377 effect(USE labl); 12378 12379 ins_cost(300); 12380 format %{ "j$cop,us $labl" %} 12381 size(2); 12382 ins_encode %{ 12383 Label* L = $labl$$label; 12384 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12385 %} 12386 ins_pipe(pipe_jcc); 12387 ins_short_branch(1); 12388 %} 12389 12390 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12391 match(If cop cmp); 12392 effect(USE labl); 12393 12394 ins_cost(300); 12395 format %{ "j$cop,us $labl" %} 12396 size(2); 12397 ins_encode %{ 12398 Label* L = $labl$$label; 12399 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12400 %} 12401 ins_pipe(pipe_jcc); 12402 ins_short_branch(1); 12403 %} 12404 12405 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12406 match(If cop cmp); 12407 effect(USE labl); 12408 12409 ins_cost(300); 12410 format %{ $$template 12411 if ($cop$$cmpcode == Assembler::notEqual) { 12412 $$emit$$"jp,u,s $labl\n\t" 12413 $$emit$$"j$cop,u,s $labl" 12414 } else { 12415 $$emit$$"jp,u,s done\n\t" 12416 $$emit$$"j$cop,u,s $labl\n\t" 12417 $$emit$$"done:" 12418 } 12419 %} 12420 size(4); 12421 ins_encode %{ 12422 Label* l = $labl$$label; 12423 if ($cop$$cmpcode == Assembler::notEqual) { 12424 __ jccb(Assembler::parity, *l); 12425 __ jccb(Assembler::notEqual, *l); 12426 } else if ($cop$$cmpcode == Assembler::equal) { 12427 Label done; 12428 __ jccb(Assembler::parity, done); 12429 __ jccb(Assembler::equal, *l); 12430 __ bind(done); 12431 } else { 12432 ShouldNotReachHere(); 12433 } 12434 %} 12435 ins_pipe(pipe_jcc); 12436 ins_short_branch(1); 12437 %} 12438 12439 // ============================================================================ 12440 // inlined locking and unlocking 12441 12442 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12443 predicate(Compile::current()->use_rtm()); 12444 match(Set cr (FastLock object box)); 12445 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12446 ins_cost(300); 12447 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12448 ins_encode %{ 12449 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12450 $scr$$Register, $cx1$$Register, $cx2$$Register, 12451 _counters, _rtm_counters, _stack_rtm_counters, 12452 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12453 true, ra_->C->profile_rtm()); 12454 %} 12455 ins_pipe(pipe_slow); 12456 %} 12457 12458 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12459 predicate(!Compile::current()->use_rtm()); 12460 match(Set cr (FastLock object box)); 12461 effect(TEMP tmp, TEMP scr, USE_KILL box); 12462 ins_cost(300); 12463 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12464 ins_encode %{ 12465 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12466 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12467 %} 12468 ins_pipe(pipe_slow); 12469 %} 12470 12471 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12472 match(Set cr (FastUnlock object box)); 12473 effect(TEMP tmp, USE_KILL box); 12474 ins_cost(300); 12475 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12476 ins_encode %{ 12477 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12478 %} 12479 ins_pipe(pipe_slow); 12480 %} 12481 12482 12483 // ============================================================================ 12484 // Safepoint Instructions 12485 instruct safePoint_poll(rFlagsReg cr) 12486 %{ 12487 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12488 match(SafePoint); 12489 effect(KILL cr); 12490 12491 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12492 "# Safepoint: poll for GC" %} 12493 ins_cost(125); 12494 ins_encode %{ 12495 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12496 __ testl(rax, addr); 12497 %} 12498 ins_pipe(ialu_reg_mem); 12499 %} 12500 12501 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12502 %{ 12503 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12504 match(SafePoint poll); 12505 effect(KILL cr, USE poll); 12506 12507 format %{ "testl rax, [$poll]\t" 12508 "# Safepoint: poll for GC" %} 12509 ins_cost(125); 12510 ins_encode %{ 12511 __ relocate(relocInfo::poll_type); 12512 __ testl(rax, Address($poll$$Register, 0)); 12513 %} 12514 ins_pipe(ialu_reg_mem); 12515 %} 12516 12517 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12518 %{ 12519 predicate(SafepointMechanism::uses_thread_local_poll()); 12520 match(SafePoint poll); 12521 effect(KILL cr, USE poll); 12522 12523 format %{ "testl rax, [$poll]\t" 12524 "# Safepoint: poll for GC" %} 12525 ins_cost(125); 12526 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12527 ins_encode %{ 12528 __ relocate(relocInfo::poll_type); 12529 address pre_pc = __ pc(); 12530 __ testl(rax, Address($poll$$Register, 0)); 12531 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12532 %} 12533 ins_pipe(ialu_reg_mem); 12534 %} 12535 12536 // ============================================================================ 12537 // Procedure Call/Return Instructions 12538 // Call Java Static Instruction 12539 // Note: If this code changes, the corresponding ret_addr_offset() and 12540 // compute_padding() functions will have to be adjusted. 12541 instruct CallStaticJavaDirect(method meth) %{ 12542 match(CallStaticJava); 12543 effect(USE meth); 12544 12545 ins_cost(300); 12546 format %{ "call,static " %} 12547 opcode(0xE8); /* E8 cd */ 12548 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12549 ins_pipe(pipe_slow); 12550 ins_alignment(4); 12551 %} 12552 12553 // Call Java Dynamic Instruction 12554 // Note: If this code changes, the corresponding ret_addr_offset() and 12555 // compute_padding() functions will have to be adjusted. 12556 instruct CallDynamicJavaDirect(method meth) 12557 %{ 12558 match(CallDynamicJava); 12559 effect(USE meth); 12560 12561 ins_cost(300); 12562 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12563 "call,dynamic " %} 12564 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12565 ins_pipe(pipe_slow); 12566 ins_alignment(4); 12567 %} 12568 12569 // Call Runtime Instruction 12570 instruct CallRuntimeDirect(method meth) 12571 %{ 12572 match(CallRuntime); 12573 effect(USE meth); 12574 12575 ins_cost(300); 12576 format %{ "call,runtime " %} 12577 ins_encode(clear_avx, Java_To_Runtime(meth)); 12578 ins_pipe(pipe_slow); 12579 %} 12580 12581 // Call runtime without safepoint 12582 instruct CallLeafDirect(method meth) 12583 %{ 12584 match(CallLeaf); 12585 effect(USE meth); 12586 12587 ins_cost(300); 12588 format %{ "call_leaf,runtime " %} 12589 ins_encode(clear_avx, Java_To_Runtime(meth)); 12590 ins_pipe(pipe_slow); 12591 %} 12592 12593 // Call runtime without safepoint 12594 instruct CallLeafNoFPDirect(method meth) 12595 %{ 12596 match(CallLeafNoFP); 12597 effect(USE meth); 12598 12599 ins_cost(300); 12600 format %{ "call_leaf_nofp,runtime " %} 12601 ins_encode(clear_avx, Java_To_Runtime(meth)); 12602 ins_pipe(pipe_slow); 12603 %} 12604 12605 // Return Instruction 12606 // Remove the return address & jump to it. 12607 // Notice: We always emit a nop after a ret to make sure there is room 12608 // for safepoint patching 12609 instruct Ret() 12610 %{ 12611 match(Return); 12612 12613 format %{ "ret" %} 12614 opcode(0xC3); 12615 ins_encode(OpcP); 12616 ins_pipe(pipe_jmp); 12617 %} 12618 12619 // Tail Call; Jump from runtime stub to Java code. 12620 // Also known as an 'interprocedural jump'. 12621 // Target of jump will eventually return to caller. 12622 // TailJump below removes the return address. 12623 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12624 %{ 12625 match(TailCall jump_target method_oop); 12626 12627 ins_cost(300); 12628 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12629 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12630 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12631 ins_pipe(pipe_jmp); 12632 %} 12633 12634 // Tail Jump; remove the return address; jump to target. 12635 // TailCall above leaves the return address around. 12636 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12637 %{ 12638 match(TailJump jump_target ex_oop); 12639 12640 ins_cost(300); 12641 format %{ "popq rdx\t# pop return address\n\t" 12642 "jmp $jump_target" %} 12643 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12644 ins_encode(Opcode(0x5a), // popq rdx 12645 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12646 ins_pipe(pipe_jmp); 12647 %} 12648 12649 // Create exception oop: created by stack-crawling runtime code. 12650 // Created exception is now available to this handler, and is setup 12651 // just prior to jumping to this handler. No code emitted. 12652 instruct CreateException(rax_RegP ex_oop) 12653 %{ 12654 match(Set ex_oop (CreateEx)); 12655 12656 size(0); 12657 // use the following format syntax 12658 format %{ "# exception oop is in rax; no code emitted" %} 12659 ins_encode(); 12660 ins_pipe(empty); 12661 %} 12662 12663 // Rethrow exception: 12664 // The exception oop will come in the first argument position. 12665 // Then JUMP (not call) to the rethrow stub code. 12666 instruct RethrowException() 12667 %{ 12668 match(Rethrow); 12669 12670 // use the following format syntax 12671 format %{ "jmp rethrow_stub" %} 12672 ins_encode(enc_rethrow); 12673 ins_pipe(pipe_jmp); 12674 %} 12675 12676 // 12677 // Execute ZGC load barrier (strong) slow path 12678 // 12679 12680 // When running without XMM regs 12681 instruct loadBarrierSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12682 12683 match(Set dst (LoadBarrierSlowReg mem)); 12684 predicate(MaxVectorSize < 16); 12685 12686 effect(DEF dst, KILL cr); 12687 12688 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12689 ins_encode %{ 12690 #if INCLUDE_ZGC 12691 Register d = $dst$$Register; 12692 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12693 12694 assert(d != r12, "Can't be R12!"); 12695 assert(d != r15, "Can't be R15!"); 12696 assert(d != rsp, "Can't be RSP!"); 12697 12698 __ lea(d, $mem$$Address); 12699 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12700 #else 12701 ShouldNotReachHere(); 12702 #endif 12703 %} 12704 ins_pipe(pipe_slow); 12705 %} 12706 12707 // For XMM and YMM enabled processors 12708 instruct loadBarrierSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12709 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12710 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12711 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12712 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12713 12714 match(Set dst (LoadBarrierSlowReg mem)); 12715 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12716 12717 effect(DEF dst, KILL cr, 12718 KILL x0, KILL x1, KILL x2, KILL x3, 12719 KILL x4, KILL x5, KILL x6, KILL x7, 12720 KILL x8, KILL x9, KILL x10, KILL x11, 12721 KILL x12, KILL x13, KILL x14, KILL x15); 12722 12723 format %{"LoadBarrierSlowRegXmm $dst, $mem" %} 12724 ins_encode %{ 12725 #if INCLUDE_ZGC 12726 Register d = $dst$$Register; 12727 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12728 12729 assert(d != r12, "Can't be R12!"); 12730 assert(d != r15, "Can't be R15!"); 12731 assert(d != rsp, "Can't be RSP!"); 12732 12733 __ lea(d, $mem$$Address); 12734 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12735 #else 12736 ShouldNotReachHere(); 12737 #endif 12738 %} 12739 ins_pipe(pipe_slow); 12740 %} 12741 12742 // For ZMM enabled processors 12743 instruct loadBarrierSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12744 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12745 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12746 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12747 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12748 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12749 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12750 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12751 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12752 12753 match(Set dst (LoadBarrierSlowReg mem)); 12754 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12755 12756 effect(DEF dst, KILL cr, 12757 KILL x0, KILL x1, KILL x2, KILL x3, 12758 KILL x4, KILL x5, KILL x6, KILL x7, 12759 KILL x8, KILL x9, KILL x10, KILL x11, 12760 KILL x12, KILL x13, KILL x14, KILL x15, 12761 KILL x16, KILL x17, KILL x18, KILL x19, 12762 KILL x20, KILL x21, KILL x22, KILL x23, 12763 KILL x24, KILL x25, KILL x26, KILL x27, 12764 KILL x28, KILL x29, KILL x30, KILL x31); 12765 12766 format %{"LoadBarrierSlowRegZmm $dst, $mem" %} 12767 ins_encode %{ 12768 #if INCLUDE_ZGC 12769 Register d = $dst$$Register; 12770 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12771 12772 assert(d != r12, "Can't be R12!"); 12773 assert(d != r15, "Can't be R15!"); 12774 assert(d != rsp, "Can't be RSP!"); 12775 12776 __ lea(d, $mem$$Address); 12777 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12778 #else 12779 ShouldNotReachHere(); 12780 #endif 12781 %} 12782 ins_pipe(pipe_slow); 12783 %} 12784 12785 // 12786 // Execute ZGC load barrier (weak) slow path 12787 // 12788 12789 // When running without XMM regs 12790 instruct loadBarrierWeakSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12791 12792 match(Set dst (LoadBarrierSlowReg mem)); 12793 predicate(MaxVectorSize < 16); 12794 12795 effect(DEF dst, KILL cr); 12796 12797 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12798 ins_encode %{ 12799 #if INCLUDE_ZGC 12800 Register d = $dst$$Register; 12801 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12802 12803 assert(d != r12, "Can't be R12!"); 12804 assert(d != r15, "Can't be R15!"); 12805 assert(d != rsp, "Can't be RSP!"); 12806 12807 __ lea(d, $mem$$Address); 12808 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12809 #else 12810 ShouldNotReachHere(); 12811 #endif 12812 %} 12813 ins_pipe(pipe_slow); 12814 %} 12815 12816 // For XMM and YMM enabled processors 12817 instruct loadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12818 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12819 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12820 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12821 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12822 12823 match(Set dst (LoadBarrierWeakSlowReg mem)); 12824 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12825 12826 effect(DEF dst, KILL cr, 12827 KILL x0, KILL x1, KILL x2, KILL x3, 12828 KILL x4, KILL x5, KILL x6, KILL x7, 12829 KILL x8, KILL x9, KILL x10, KILL x11, 12830 KILL x12, KILL x13, KILL x14, KILL x15); 12831 12832 format %{"LoadBarrierWeakSlowRegXmm $dst, $mem" %} 12833 ins_encode %{ 12834 #if INCLUDE_ZGC 12835 Register d = $dst$$Register; 12836 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12837 12838 assert(d != r12, "Can't be R12!"); 12839 assert(d != r15, "Can't be R15!"); 12840 assert(d != rsp, "Can't be RSP!"); 12841 12842 __ lea(d,$mem$$Address); 12843 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12844 #else 12845 ShouldNotReachHere(); 12846 #endif 12847 %} 12848 ins_pipe(pipe_slow); 12849 %} 12850 12851 // For ZMM enabled processors 12852 instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12853 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12854 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12855 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12856 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12857 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12858 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12859 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12860 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12861 12862 match(Set dst (LoadBarrierWeakSlowReg mem)); 12863 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12864 12865 effect(DEF dst, KILL cr, 12866 KILL x0, KILL x1, KILL x2, KILL x3, 12867 KILL x4, KILL x5, KILL x6, KILL x7, 12868 KILL x8, KILL x9, KILL x10, KILL x11, 12869 KILL x12, KILL x13, KILL x14, KILL x15, 12870 KILL x16, KILL x17, KILL x18, KILL x19, 12871 KILL x20, KILL x21, KILL x22, KILL x23, 12872 KILL x24, KILL x25, KILL x26, KILL x27, 12873 KILL x28, KILL x29, KILL x30, KILL x31); 12874 12875 format %{"LoadBarrierWeakSlowRegZmm $dst, $mem" %} 12876 ins_encode %{ 12877 #if INCLUDE_ZGC 12878 Register d = $dst$$Register; 12879 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12880 12881 assert(d != r12, "Can't be R12!"); 12882 assert(d != r15, "Can't be R15!"); 12883 assert(d != rsp, "Can't be RSP!"); 12884 12885 __ lea(d,$mem$$Address); 12886 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12887 #else 12888 ShouldNotReachHere(); 12889 #endif 12890 %} 12891 ins_pipe(pipe_slow); 12892 %} 12893 12894 // ============================================================================ 12895 // This name is KNOWN by the ADLC and cannot be changed. 12896 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12897 // for this guy. 12898 instruct tlsLoadP(r15_RegP dst) %{ 12899 match(Set dst (ThreadLocal)); 12900 effect(DEF dst); 12901 12902 size(0); 12903 format %{ "# TLS is in R15" %} 12904 ins_encode( /*empty encoding*/ ); 12905 ins_pipe(ialu_reg_reg); 12906 %} 12907 12908 12909 //----------PEEPHOLE RULES----------------------------------------------------- 12910 // These must follow all instruction definitions as they use the names 12911 // defined in the instructions definitions. 12912 // 12913 // peepmatch ( root_instr_name [preceding_instruction]* ); 12914 // 12915 // peepconstraint %{ 12916 // (instruction_number.operand_name relational_op instruction_number.operand_name 12917 // [, ...] ); 12918 // // instruction numbers are zero-based using left to right order in peepmatch 12919 // 12920 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12921 // // provide an instruction_number.operand_name for each operand that appears 12922 // // in the replacement instruction's match rule 12923 // 12924 // ---------VM FLAGS--------------------------------------------------------- 12925 // 12926 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12927 // 12928 // Each peephole rule is given an identifying number starting with zero and 12929 // increasing by one in the order seen by the parser. An individual peephole 12930 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12931 // on the command-line. 12932 // 12933 // ---------CURRENT LIMITATIONS---------------------------------------------- 12934 // 12935 // Only match adjacent instructions in same basic block 12936 // Only equality constraints 12937 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12938 // Only one replacement instruction 12939 // 12940 // ---------EXAMPLE---------------------------------------------------------- 12941 // 12942 // // pertinent parts of existing instructions in architecture description 12943 // instruct movI(rRegI dst, rRegI src) 12944 // %{ 12945 // match(Set dst (CopyI src)); 12946 // %} 12947 // 12948 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12949 // %{ 12950 // match(Set dst (AddI dst src)); 12951 // effect(KILL cr); 12952 // %} 12953 // 12954 // // Change (inc mov) to lea 12955 // peephole %{ 12956 // // increment preceeded by register-register move 12957 // peepmatch ( incI_rReg movI ); 12958 // // require that the destination register of the increment 12959 // // match the destination register of the move 12960 // peepconstraint ( 0.dst == 1.dst ); 12961 // // construct a replacement instruction that sets 12962 // // the destination to ( move's source register + one ) 12963 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12964 // %} 12965 // 12966 12967 // Implementation no longer uses movX instructions since 12968 // machine-independent system no longer uses CopyX nodes. 12969 // 12970 // peephole 12971 // %{ 12972 // peepmatch (incI_rReg movI); 12973 // peepconstraint (0.dst == 1.dst); 12974 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12975 // %} 12976 12977 // peephole 12978 // %{ 12979 // peepmatch (decI_rReg movI); 12980 // peepconstraint (0.dst == 1.dst); 12981 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12982 // %} 12983 12984 // peephole 12985 // %{ 12986 // peepmatch (addI_rReg_imm movI); 12987 // peepconstraint (0.dst == 1.dst); 12988 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12989 // %} 12990 12991 // peephole 12992 // %{ 12993 // peepmatch (incL_rReg movL); 12994 // peepconstraint (0.dst == 1.dst); 12995 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12996 // %} 12997 12998 // peephole 12999 // %{ 13000 // peepmatch (decL_rReg movL); 13001 // peepconstraint (0.dst == 1.dst); 13002 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13003 // %} 13004 13005 // peephole 13006 // %{ 13007 // peepmatch (addL_rReg_imm movL); 13008 // peepconstraint (0.dst == 1.dst); 13009 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13010 // %} 13011 13012 // peephole 13013 // %{ 13014 // peepmatch (addP_rReg_imm movP); 13015 // peepconstraint (0.dst == 1.dst); 13016 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 13017 // %} 13018 13019 // // Change load of spilled value to only a spill 13020 // instruct storeI(memory mem, rRegI src) 13021 // %{ 13022 // match(Set mem (StoreI mem src)); 13023 // %} 13024 // 13025 // instruct loadI(rRegI dst, memory mem) 13026 // %{ 13027 // match(Set dst (LoadI mem)); 13028 // %} 13029 // 13030 13031 peephole 13032 %{ 13033 peepmatch (loadI storeI); 13034 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13035 peepreplace (storeI(1.mem 1.mem 1.src)); 13036 %} 13037 13038 peephole 13039 %{ 13040 peepmatch (loadL storeL); 13041 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13042 peepreplace (storeL(1.mem 1.mem 1.src)); 13043 %} 13044 13045 //----------SMARTSPILL RULES--------------------------------------------------- 13046 // These must follow all instruction definitions as they use the names 13047 // defined in the instructions definitions.