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 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7452 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7453 effect(KILL cr, KILL oldval); 7454 7455 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7456 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7457 "sete $res\n\t" 7458 "movzbl $res, $res" %} 7459 opcode(0x0F, 0xB1); 7460 ins_encode(lock_prefix, 7461 REX_reg_mem_wide(newval, mem_ptr), 7462 OpcP, OpcS, 7463 reg_mem(newval, mem_ptr), 7464 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7465 REX_reg_breg(res, res), // movzbl 7466 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7467 ins_pipe( pipe_cmpxchg ); 7468 %} 7469 7470 instruct compareAndSwapL(rRegI res, 7471 memory mem_ptr, 7472 rax_RegL oldval, rRegL newval, 7473 rFlagsReg cr) 7474 %{ 7475 predicate(VM_Version::supports_cx8()); 7476 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7477 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7478 effect(KILL cr, KILL oldval); 7479 7480 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7481 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7482 "sete $res\n\t" 7483 "movzbl $res, $res" %} 7484 opcode(0x0F, 0xB1); 7485 ins_encode(lock_prefix, 7486 REX_reg_mem_wide(newval, mem_ptr), 7487 OpcP, OpcS, 7488 reg_mem(newval, mem_ptr), 7489 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7490 REX_reg_breg(res, res), // movzbl 7491 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7492 ins_pipe( pipe_cmpxchg ); 7493 %} 7494 7495 instruct compareAndSwapI(rRegI res, 7496 memory mem_ptr, 7497 rax_RegI oldval, rRegI newval, 7498 rFlagsReg cr) 7499 %{ 7500 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7501 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7502 effect(KILL cr, KILL oldval); 7503 7504 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7505 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7506 "sete $res\n\t" 7507 "movzbl $res, $res" %} 7508 opcode(0x0F, 0xB1); 7509 ins_encode(lock_prefix, 7510 REX_reg_mem(newval, mem_ptr), 7511 OpcP, OpcS, 7512 reg_mem(newval, mem_ptr), 7513 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7514 REX_reg_breg(res, res), // movzbl 7515 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7516 ins_pipe( pipe_cmpxchg ); 7517 %} 7518 7519 instruct compareAndSwapB(rRegI res, 7520 memory mem_ptr, 7521 rax_RegI oldval, rRegI newval, 7522 rFlagsReg cr) 7523 %{ 7524 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7525 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7526 effect(KILL cr, KILL oldval); 7527 7528 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7529 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7530 "sete $res\n\t" 7531 "movzbl $res, $res" %} 7532 opcode(0x0F, 0xB0); 7533 ins_encode(lock_prefix, 7534 REX_breg_mem(newval, mem_ptr), 7535 OpcP, OpcS, 7536 reg_mem(newval, mem_ptr), 7537 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7538 REX_reg_breg(res, res), // movzbl 7539 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7540 ins_pipe( pipe_cmpxchg ); 7541 %} 7542 7543 instruct compareAndSwapS(rRegI res, 7544 memory mem_ptr, 7545 rax_RegI oldval, rRegI newval, 7546 rFlagsReg cr) 7547 %{ 7548 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7549 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7550 effect(KILL cr, KILL oldval); 7551 7552 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7553 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7554 "sete $res\n\t" 7555 "movzbl $res, $res" %} 7556 opcode(0x0F, 0xB1); 7557 ins_encode(lock_prefix, 7558 SizePrefix, 7559 REX_reg_mem(newval, mem_ptr), 7560 OpcP, OpcS, 7561 reg_mem(newval, mem_ptr), 7562 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7563 REX_reg_breg(res, res), // movzbl 7564 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7565 ins_pipe( pipe_cmpxchg ); 7566 %} 7567 7568 instruct compareAndSwapN(rRegI res, 7569 memory mem_ptr, 7570 rax_RegN oldval, rRegN newval, 7571 rFlagsReg cr) %{ 7572 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7573 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7574 effect(KILL cr, KILL oldval); 7575 7576 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7577 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7578 "sete $res\n\t" 7579 "movzbl $res, $res" %} 7580 opcode(0x0F, 0xB1); 7581 ins_encode(lock_prefix, 7582 REX_reg_mem(newval, mem_ptr), 7583 OpcP, OpcS, 7584 reg_mem(newval, mem_ptr), 7585 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7586 REX_reg_breg(res, res), // movzbl 7587 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7588 ins_pipe( pipe_cmpxchg ); 7589 %} 7590 7591 instruct compareAndExchangeB( 7592 memory mem_ptr, 7593 rax_RegI oldval, rRegI newval, 7594 rFlagsReg cr) 7595 %{ 7596 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7597 effect(KILL cr); 7598 7599 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7600 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7601 opcode(0x0F, 0xB0); 7602 ins_encode(lock_prefix, 7603 REX_breg_mem(newval, mem_ptr), 7604 OpcP, OpcS, 7605 reg_mem(newval, mem_ptr) // lock cmpxchg 7606 ); 7607 ins_pipe( pipe_cmpxchg ); 7608 %} 7609 7610 instruct compareAndExchangeS( 7611 memory mem_ptr, 7612 rax_RegI oldval, rRegI newval, 7613 rFlagsReg cr) 7614 %{ 7615 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7616 effect(KILL cr); 7617 7618 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7619 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7620 opcode(0x0F, 0xB1); 7621 ins_encode(lock_prefix, 7622 SizePrefix, 7623 REX_reg_mem(newval, mem_ptr), 7624 OpcP, OpcS, 7625 reg_mem(newval, mem_ptr) // lock cmpxchg 7626 ); 7627 ins_pipe( pipe_cmpxchg ); 7628 %} 7629 7630 instruct compareAndExchangeI( 7631 memory mem_ptr, 7632 rax_RegI oldval, rRegI newval, 7633 rFlagsReg cr) 7634 %{ 7635 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7636 effect(KILL cr); 7637 7638 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7639 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7640 opcode(0x0F, 0xB1); 7641 ins_encode(lock_prefix, 7642 REX_reg_mem(newval, mem_ptr), 7643 OpcP, OpcS, 7644 reg_mem(newval, mem_ptr) // lock cmpxchg 7645 ); 7646 ins_pipe( pipe_cmpxchg ); 7647 %} 7648 7649 instruct compareAndExchangeL( 7650 memory mem_ptr, 7651 rax_RegL oldval, rRegL newval, 7652 rFlagsReg cr) 7653 %{ 7654 predicate(VM_Version::supports_cx8()); 7655 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7656 effect(KILL cr); 7657 7658 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7659 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7660 opcode(0x0F, 0xB1); 7661 ins_encode(lock_prefix, 7662 REX_reg_mem_wide(newval, mem_ptr), 7663 OpcP, OpcS, 7664 reg_mem(newval, mem_ptr) // lock cmpxchg 7665 ); 7666 ins_pipe( pipe_cmpxchg ); 7667 %} 7668 7669 instruct compareAndExchangeN( 7670 memory mem_ptr, 7671 rax_RegN oldval, rRegN newval, 7672 rFlagsReg cr) %{ 7673 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7674 effect(KILL cr); 7675 7676 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7677 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7678 opcode(0x0F, 0xB1); 7679 ins_encode(lock_prefix, 7680 REX_reg_mem(newval, mem_ptr), 7681 OpcP, OpcS, 7682 reg_mem(newval, mem_ptr) // lock cmpxchg 7683 ); 7684 ins_pipe( pipe_cmpxchg ); 7685 %} 7686 7687 instruct compareAndExchangeP( 7688 memory mem_ptr, 7689 rax_RegP oldval, rRegP newval, 7690 rFlagsReg cr) 7691 %{ 7692 predicate(VM_Version::supports_cx8()); 7693 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7694 effect(KILL cr); 7695 7696 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7697 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7698 opcode(0x0F, 0xB1); 7699 ins_encode(lock_prefix, 7700 REX_reg_mem_wide(newval, mem_ptr), 7701 OpcP, OpcS, 7702 reg_mem(newval, mem_ptr) // lock cmpxchg 7703 ); 7704 ins_pipe( pipe_cmpxchg ); 7705 %} 7706 7707 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7708 predicate(n->as_LoadStore()->result_not_used()); 7709 match(Set dummy (GetAndAddB mem add)); 7710 effect(KILL cr); 7711 format %{ "ADDB [$mem],$add" %} 7712 ins_encode %{ 7713 if (os::is_MP()) { __ lock(); } 7714 __ addb($mem$$Address, $add$$constant); 7715 %} 7716 ins_pipe( pipe_cmpxchg ); 7717 %} 7718 7719 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7720 match(Set newval (GetAndAddB mem newval)); 7721 effect(KILL cr); 7722 format %{ "XADDB [$mem],$newval" %} 7723 ins_encode %{ 7724 if (os::is_MP()) { __ lock(); } 7725 __ xaddb($mem$$Address, $newval$$Register); 7726 %} 7727 ins_pipe( pipe_cmpxchg ); 7728 %} 7729 7730 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7731 predicate(n->as_LoadStore()->result_not_used()); 7732 match(Set dummy (GetAndAddS mem add)); 7733 effect(KILL cr); 7734 format %{ "ADDW [$mem],$add" %} 7735 ins_encode %{ 7736 if (os::is_MP()) { __ lock(); } 7737 __ addw($mem$$Address, $add$$constant); 7738 %} 7739 ins_pipe( pipe_cmpxchg ); 7740 %} 7741 7742 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7743 match(Set newval (GetAndAddS mem newval)); 7744 effect(KILL cr); 7745 format %{ "XADDW [$mem],$newval" %} 7746 ins_encode %{ 7747 if (os::is_MP()) { __ lock(); } 7748 __ xaddw($mem$$Address, $newval$$Register); 7749 %} 7750 ins_pipe( pipe_cmpxchg ); 7751 %} 7752 7753 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7754 predicate(n->as_LoadStore()->result_not_used()); 7755 match(Set dummy (GetAndAddI mem add)); 7756 effect(KILL cr); 7757 format %{ "ADDL [$mem],$add" %} 7758 ins_encode %{ 7759 if (os::is_MP()) { __ lock(); } 7760 __ addl($mem$$Address, $add$$constant); 7761 %} 7762 ins_pipe( pipe_cmpxchg ); 7763 %} 7764 7765 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7766 match(Set newval (GetAndAddI mem newval)); 7767 effect(KILL cr); 7768 format %{ "XADDL [$mem],$newval" %} 7769 ins_encode %{ 7770 if (os::is_MP()) { __ lock(); } 7771 __ xaddl($mem$$Address, $newval$$Register); 7772 %} 7773 ins_pipe( pipe_cmpxchg ); 7774 %} 7775 7776 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7777 predicate(n->as_LoadStore()->result_not_used()); 7778 match(Set dummy (GetAndAddL mem add)); 7779 effect(KILL cr); 7780 format %{ "ADDQ [$mem],$add" %} 7781 ins_encode %{ 7782 if (os::is_MP()) { __ lock(); } 7783 __ addq($mem$$Address, $add$$constant); 7784 %} 7785 ins_pipe( pipe_cmpxchg ); 7786 %} 7787 7788 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7789 match(Set newval (GetAndAddL mem newval)); 7790 effect(KILL cr); 7791 format %{ "XADDQ [$mem],$newval" %} 7792 ins_encode %{ 7793 if (os::is_MP()) { __ lock(); } 7794 __ xaddq($mem$$Address, $newval$$Register); 7795 %} 7796 ins_pipe( pipe_cmpxchg ); 7797 %} 7798 7799 instruct xchgB( memory mem, rRegI newval) %{ 7800 match(Set newval (GetAndSetB mem newval)); 7801 format %{ "XCHGB $newval,[$mem]" %} 7802 ins_encode %{ 7803 __ xchgb($newval$$Register, $mem$$Address); 7804 %} 7805 ins_pipe( pipe_cmpxchg ); 7806 %} 7807 7808 instruct xchgS( memory mem, rRegI newval) %{ 7809 match(Set newval (GetAndSetS mem newval)); 7810 format %{ "XCHGW $newval,[$mem]" %} 7811 ins_encode %{ 7812 __ xchgw($newval$$Register, $mem$$Address); 7813 %} 7814 ins_pipe( pipe_cmpxchg ); 7815 %} 7816 7817 instruct xchgI( memory mem, rRegI newval) %{ 7818 match(Set newval (GetAndSetI mem newval)); 7819 format %{ "XCHGL $newval,[$mem]" %} 7820 ins_encode %{ 7821 __ xchgl($newval$$Register, $mem$$Address); 7822 %} 7823 ins_pipe( pipe_cmpxchg ); 7824 %} 7825 7826 instruct xchgL( memory mem, rRegL newval) %{ 7827 match(Set newval (GetAndSetL mem newval)); 7828 format %{ "XCHGL $newval,[$mem]" %} 7829 ins_encode %{ 7830 __ xchgq($newval$$Register, $mem$$Address); 7831 %} 7832 ins_pipe( pipe_cmpxchg ); 7833 %} 7834 7835 instruct xchgP( memory mem, rRegP newval) %{ 7836 match(Set newval (GetAndSetP mem newval)); 7837 format %{ "XCHGQ $newval,[$mem]" %} 7838 ins_encode %{ 7839 __ xchgq($newval$$Register, $mem$$Address); 7840 %} 7841 ins_pipe( pipe_cmpxchg ); 7842 %} 7843 7844 instruct xchgN( memory mem, rRegN newval) %{ 7845 match(Set newval (GetAndSetN mem newval)); 7846 format %{ "XCHGL $newval,$mem]" %} 7847 ins_encode %{ 7848 __ xchgl($newval$$Register, $mem$$Address); 7849 %} 7850 ins_pipe( pipe_cmpxchg ); 7851 %} 7852 7853 //----------Subtraction Instructions------------------------------------------- 7854 7855 // Integer Subtraction Instructions 7856 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7857 %{ 7858 match(Set dst (SubI dst src)); 7859 effect(KILL cr); 7860 7861 format %{ "subl $dst, $src\t# int" %} 7862 opcode(0x2B); 7863 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7864 ins_pipe(ialu_reg_reg); 7865 %} 7866 7867 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7868 %{ 7869 match(Set dst (SubI dst src)); 7870 effect(KILL cr); 7871 7872 format %{ "subl $dst, $src\t# int" %} 7873 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7874 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7875 ins_pipe(ialu_reg); 7876 %} 7877 7878 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7879 %{ 7880 match(Set dst (SubI dst (LoadI src))); 7881 effect(KILL cr); 7882 7883 ins_cost(125); 7884 format %{ "subl $dst, $src\t# int" %} 7885 opcode(0x2B); 7886 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7887 ins_pipe(ialu_reg_mem); 7888 %} 7889 7890 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7891 %{ 7892 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7893 effect(KILL cr); 7894 7895 ins_cost(150); 7896 format %{ "subl $dst, $src\t# int" %} 7897 opcode(0x29); /* Opcode 29 /r */ 7898 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7899 ins_pipe(ialu_mem_reg); 7900 %} 7901 7902 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7903 %{ 7904 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7905 effect(KILL cr); 7906 7907 ins_cost(125); // XXX 7908 format %{ "subl $dst, $src\t# int" %} 7909 opcode(0x81); /* Opcode 81 /5 id */ 7910 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7911 ins_pipe(ialu_mem_imm); 7912 %} 7913 7914 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7915 %{ 7916 match(Set dst (SubL dst src)); 7917 effect(KILL cr); 7918 7919 format %{ "subq $dst, $src\t# long" %} 7920 opcode(0x2B); 7921 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7922 ins_pipe(ialu_reg_reg); 7923 %} 7924 7925 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7926 %{ 7927 match(Set dst (SubL dst src)); 7928 effect(KILL cr); 7929 7930 format %{ "subq $dst, $src\t# long" %} 7931 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7932 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7933 ins_pipe(ialu_reg); 7934 %} 7935 7936 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7937 %{ 7938 match(Set dst (SubL dst (LoadL src))); 7939 effect(KILL cr); 7940 7941 ins_cost(125); 7942 format %{ "subq $dst, $src\t# long" %} 7943 opcode(0x2B); 7944 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7945 ins_pipe(ialu_reg_mem); 7946 %} 7947 7948 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7949 %{ 7950 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7951 effect(KILL cr); 7952 7953 ins_cost(150); 7954 format %{ "subq $dst, $src\t# long" %} 7955 opcode(0x29); /* Opcode 29 /r */ 7956 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7957 ins_pipe(ialu_mem_reg); 7958 %} 7959 7960 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7961 %{ 7962 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7963 effect(KILL cr); 7964 7965 ins_cost(125); // XXX 7966 format %{ "subq $dst, $src\t# long" %} 7967 opcode(0x81); /* Opcode 81 /5 id */ 7968 ins_encode(REX_mem_wide(dst), 7969 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7970 ins_pipe(ialu_mem_imm); 7971 %} 7972 7973 // Subtract from a pointer 7974 // XXX hmpf??? 7975 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7976 %{ 7977 match(Set dst (AddP dst (SubI zero src))); 7978 effect(KILL cr); 7979 7980 format %{ "subq $dst, $src\t# ptr - int" %} 7981 opcode(0x2B); 7982 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7983 ins_pipe(ialu_reg_reg); 7984 %} 7985 7986 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7987 %{ 7988 match(Set dst (SubI zero dst)); 7989 effect(KILL cr); 7990 7991 format %{ "negl $dst\t# int" %} 7992 opcode(0xF7, 0x03); // Opcode F7 /3 7993 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7994 ins_pipe(ialu_reg); 7995 %} 7996 7997 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7998 %{ 7999 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8000 effect(KILL cr); 8001 8002 format %{ "negl $dst\t# int" %} 8003 opcode(0xF7, 0x03); // Opcode F7 /3 8004 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8005 ins_pipe(ialu_reg); 8006 %} 8007 8008 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8009 %{ 8010 match(Set dst (SubL zero dst)); 8011 effect(KILL cr); 8012 8013 format %{ "negq $dst\t# long" %} 8014 opcode(0xF7, 0x03); // Opcode F7 /3 8015 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8016 ins_pipe(ialu_reg); 8017 %} 8018 8019 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8020 %{ 8021 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8022 effect(KILL cr); 8023 8024 format %{ "negq $dst\t# long" %} 8025 opcode(0xF7, 0x03); // Opcode F7 /3 8026 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8027 ins_pipe(ialu_reg); 8028 %} 8029 8030 //----------Multiplication/Division Instructions------------------------------- 8031 // Integer Multiplication Instructions 8032 // Multiply Register 8033 8034 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8035 %{ 8036 match(Set dst (MulI dst src)); 8037 effect(KILL cr); 8038 8039 ins_cost(300); 8040 format %{ "imull $dst, $src\t# int" %} 8041 opcode(0x0F, 0xAF); 8042 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8043 ins_pipe(ialu_reg_reg_alu0); 8044 %} 8045 8046 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8047 %{ 8048 match(Set dst (MulI src imm)); 8049 effect(KILL cr); 8050 8051 ins_cost(300); 8052 format %{ "imull $dst, $src, $imm\t# int" %} 8053 opcode(0x69); /* 69 /r id */ 8054 ins_encode(REX_reg_reg(dst, src), 8055 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8056 ins_pipe(ialu_reg_reg_alu0); 8057 %} 8058 8059 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8060 %{ 8061 match(Set dst (MulI dst (LoadI src))); 8062 effect(KILL cr); 8063 8064 ins_cost(350); 8065 format %{ "imull $dst, $src\t# int" %} 8066 opcode(0x0F, 0xAF); 8067 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8068 ins_pipe(ialu_reg_mem_alu0); 8069 %} 8070 8071 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8072 %{ 8073 match(Set dst (MulI (LoadI src) imm)); 8074 effect(KILL cr); 8075 8076 ins_cost(300); 8077 format %{ "imull $dst, $src, $imm\t# int" %} 8078 opcode(0x69); /* 69 /r id */ 8079 ins_encode(REX_reg_mem(dst, src), 8080 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8081 ins_pipe(ialu_reg_mem_alu0); 8082 %} 8083 8084 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8085 %{ 8086 match(Set dst (MulL dst src)); 8087 effect(KILL cr); 8088 8089 ins_cost(300); 8090 format %{ "imulq $dst, $src\t# long" %} 8091 opcode(0x0F, 0xAF); 8092 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8093 ins_pipe(ialu_reg_reg_alu0); 8094 %} 8095 8096 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8097 %{ 8098 match(Set dst (MulL src imm)); 8099 effect(KILL cr); 8100 8101 ins_cost(300); 8102 format %{ "imulq $dst, $src, $imm\t# long" %} 8103 opcode(0x69); /* 69 /r id */ 8104 ins_encode(REX_reg_reg_wide(dst, src), 8105 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8106 ins_pipe(ialu_reg_reg_alu0); 8107 %} 8108 8109 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8110 %{ 8111 match(Set dst (MulL dst (LoadL src))); 8112 effect(KILL cr); 8113 8114 ins_cost(350); 8115 format %{ "imulq $dst, $src\t# long" %} 8116 opcode(0x0F, 0xAF); 8117 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8118 ins_pipe(ialu_reg_mem_alu0); 8119 %} 8120 8121 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8122 %{ 8123 match(Set dst (MulL (LoadL src) imm)); 8124 effect(KILL cr); 8125 8126 ins_cost(300); 8127 format %{ "imulq $dst, $src, $imm\t# long" %} 8128 opcode(0x69); /* 69 /r id */ 8129 ins_encode(REX_reg_mem_wide(dst, src), 8130 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8131 ins_pipe(ialu_reg_mem_alu0); 8132 %} 8133 8134 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8135 %{ 8136 match(Set dst (MulHiL src rax)); 8137 effect(USE_KILL rax, KILL cr); 8138 8139 ins_cost(300); 8140 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8141 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8142 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8143 ins_pipe(ialu_reg_reg_alu0); 8144 %} 8145 8146 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8147 rFlagsReg cr) 8148 %{ 8149 match(Set rax (DivI rax div)); 8150 effect(KILL rdx, KILL cr); 8151 8152 ins_cost(30*100+10*100); // XXX 8153 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8154 "jne,s normal\n\t" 8155 "xorl rdx, rdx\n\t" 8156 "cmpl $div, -1\n\t" 8157 "je,s done\n" 8158 "normal: cdql\n\t" 8159 "idivl $div\n" 8160 "done:" %} 8161 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8162 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8163 ins_pipe(ialu_reg_reg_alu0); 8164 %} 8165 8166 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8167 rFlagsReg cr) 8168 %{ 8169 match(Set rax (DivL rax div)); 8170 effect(KILL rdx, KILL cr); 8171 8172 ins_cost(30*100+10*100); // XXX 8173 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8174 "cmpq rax, rdx\n\t" 8175 "jne,s normal\n\t" 8176 "xorl rdx, rdx\n\t" 8177 "cmpq $div, -1\n\t" 8178 "je,s done\n" 8179 "normal: cdqq\n\t" 8180 "idivq $div\n" 8181 "done:" %} 8182 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8183 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8184 ins_pipe(ialu_reg_reg_alu0); 8185 %} 8186 8187 // Integer DIVMOD with Register, both quotient and mod results 8188 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8189 rFlagsReg cr) 8190 %{ 8191 match(DivModI rax div); 8192 effect(KILL cr); 8193 8194 ins_cost(30*100+10*100); // XXX 8195 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8196 "jne,s normal\n\t" 8197 "xorl rdx, rdx\n\t" 8198 "cmpl $div, -1\n\t" 8199 "je,s done\n" 8200 "normal: cdql\n\t" 8201 "idivl $div\n" 8202 "done:" %} 8203 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8204 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8205 ins_pipe(pipe_slow); 8206 %} 8207 8208 // Long DIVMOD with Register, both quotient and mod results 8209 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8210 rFlagsReg cr) 8211 %{ 8212 match(DivModL rax div); 8213 effect(KILL cr); 8214 8215 ins_cost(30*100+10*100); // XXX 8216 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8217 "cmpq rax, rdx\n\t" 8218 "jne,s normal\n\t" 8219 "xorl rdx, rdx\n\t" 8220 "cmpq $div, -1\n\t" 8221 "je,s done\n" 8222 "normal: cdqq\n\t" 8223 "idivq $div\n" 8224 "done:" %} 8225 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8226 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8227 ins_pipe(pipe_slow); 8228 %} 8229 8230 //----------- DivL-By-Constant-Expansions-------------------------------------- 8231 // DivI cases are handled by the compiler 8232 8233 // Magic constant, reciprocal of 10 8234 instruct loadConL_0x6666666666666667(rRegL dst) 8235 %{ 8236 effect(DEF dst); 8237 8238 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8239 ins_encode(load_immL(dst, 0x6666666666666667)); 8240 ins_pipe(ialu_reg); 8241 %} 8242 8243 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8244 %{ 8245 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8246 8247 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8248 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8249 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8250 ins_pipe(ialu_reg_reg_alu0); 8251 %} 8252 8253 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8254 %{ 8255 effect(USE_DEF dst, KILL cr); 8256 8257 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8258 opcode(0xC1, 0x7); /* C1 /7 ib */ 8259 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8260 ins_pipe(ialu_reg); 8261 %} 8262 8263 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8264 %{ 8265 effect(USE_DEF dst, KILL cr); 8266 8267 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8268 opcode(0xC1, 0x7); /* C1 /7 ib */ 8269 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8270 ins_pipe(ialu_reg); 8271 %} 8272 8273 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8274 %{ 8275 match(Set dst (DivL src div)); 8276 8277 ins_cost((5+8)*100); 8278 expand %{ 8279 rax_RegL rax; // Killed temp 8280 rFlagsReg cr; // Killed 8281 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8282 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8283 sarL_rReg_63(src, cr); // sarq src, 63 8284 sarL_rReg_2(dst, cr); // sarq rdx, 2 8285 subL_rReg(dst, src, cr); // subl rdx, src 8286 %} 8287 %} 8288 8289 //----------------------------------------------------------------------------- 8290 8291 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8292 rFlagsReg cr) 8293 %{ 8294 match(Set rdx (ModI rax div)); 8295 effect(KILL rax, KILL cr); 8296 8297 ins_cost(300); // XXX 8298 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8299 "jne,s normal\n\t" 8300 "xorl rdx, rdx\n\t" 8301 "cmpl $div, -1\n\t" 8302 "je,s done\n" 8303 "normal: cdql\n\t" 8304 "idivl $div\n" 8305 "done:" %} 8306 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8307 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8308 ins_pipe(ialu_reg_reg_alu0); 8309 %} 8310 8311 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8312 rFlagsReg cr) 8313 %{ 8314 match(Set rdx (ModL rax div)); 8315 effect(KILL rax, KILL cr); 8316 8317 ins_cost(300); // XXX 8318 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8319 "cmpq rax, rdx\n\t" 8320 "jne,s normal\n\t" 8321 "xorl rdx, rdx\n\t" 8322 "cmpq $div, -1\n\t" 8323 "je,s done\n" 8324 "normal: cdqq\n\t" 8325 "idivq $div\n" 8326 "done:" %} 8327 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8328 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8329 ins_pipe(ialu_reg_reg_alu0); 8330 %} 8331 8332 // Integer Shift Instructions 8333 // Shift Left by one 8334 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8335 %{ 8336 match(Set dst (LShiftI dst shift)); 8337 effect(KILL cr); 8338 8339 format %{ "sall $dst, $shift" %} 8340 opcode(0xD1, 0x4); /* D1 /4 */ 8341 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8342 ins_pipe(ialu_reg); 8343 %} 8344 8345 // Shift Left by one 8346 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8347 %{ 8348 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8349 effect(KILL cr); 8350 8351 format %{ "sall $dst, $shift\t" %} 8352 opcode(0xD1, 0x4); /* D1 /4 */ 8353 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8354 ins_pipe(ialu_mem_imm); 8355 %} 8356 8357 // Shift Left by 8-bit immediate 8358 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8359 %{ 8360 match(Set dst (LShiftI dst shift)); 8361 effect(KILL cr); 8362 8363 format %{ "sall $dst, $shift" %} 8364 opcode(0xC1, 0x4); /* C1 /4 ib */ 8365 ins_encode(reg_opc_imm(dst, shift)); 8366 ins_pipe(ialu_reg); 8367 %} 8368 8369 // Shift Left by 8-bit immediate 8370 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8371 %{ 8372 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8373 effect(KILL cr); 8374 8375 format %{ "sall $dst, $shift" %} 8376 opcode(0xC1, 0x4); /* C1 /4 ib */ 8377 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8378 ins_pipe(ialu_mem_imm); 8379 %} 8380 8381 // Shift Left by variable 8382 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8383 %{ 8384 match(Set dst (LShiftI dst shift)); 8385 effect(KILL cr); 8386 8387 format %{ "sall $dst, $shift" %} 8388 opcode(0xD3, 0x4); /* D3 /4 */ 8389 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8390 ins_pipe(ialu_reg_reg); 8391 %} 8392 8393 // Shift Left by variable 8394 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8395 %{ 8396 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8397 effect(KILL cr); 8398 8399 format %{ "sall $dst, $shift" %} 8400 opcode(0xD3, 0x4); /* D3 /4 */ 8401 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8402 ins_pipe(ialu_mem_reg); 8403 %} 8404 8405 // Arithmetic shift right by one 8406 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8407 %{ 8408 match(Set dst (RShiftI dst shift)); 8409 effect(KILL cr); 8410 8411 format %{ "sarl $dst, $shift" %} 8412 opcode(0xD1, 0x7); /* D1 /7 */ 8413 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8414 ins_pipe(ialu_reg); 8415 %} 8416 8417 // Arithmetic shift right by one 8418 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8419 %{ 8420 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8421 effect(KILL cr); 8422 8423 format %{ "sarl $dst, $shift" %} 8424 opcode(0xD1, 0x7); /* D1 /7 */ 8425 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8426 ins_pipe(ialu_mem_imm); 8427 %} 8428 8429 // Arithmetic Shift Right by 8-bit immediate 8430 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8431 %{ 8432 match(Set dst (RShiftI dst shift)); 8433 effect(KILL cr); 8434 8435 format %{ "sarl $dst, $shift" %} 8436 opcode(0xC1, 0x7); /* C1 /7 ib */ 8437 ins_encode(reg_opc_imm(dst, shift)); 8438 ins_pipe(ialu_mem_imm); 8439 %} 8440 8441 // Arithmetic Shift Right by 8-bit immediate 8442 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8443 %{ 8444 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8445 effect(KILL cr); 8446 8447 format %{ "sarl $dst, $shift" %} 8448 opcode(0xC1, 0x7); /* C1 /7 ib */ 8449 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8450 ins_pipe(ialu_mem_imm); 8451 %} 8452 8453 // Arithmetic Shift Right by variable 8454 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8455 %{ 8456 match(Set dst (RShiftI dst shift)); 8457 effect(KILL cr); 8458 8459 format %{ "sarl $dst, $shift" %} 8460 opcode(0xD3, 0x7); /* D3 /7 */ 8461 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8462 ins_pipe(ialu_reg_reg); 8463 %} 8464 8465 // Arithmetic Shift Right by variable 8466 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8467 %{ 8468 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8469 effect(KILL cr); 8470 8471 format %{ "sarl $dst, $shift" %} 8472 opcode(0xD3, 0x7); /* D3 /7 */ 8473 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8474 ins_pipe(ialu_mem_reg); 8475 %} 8476 8477 // Logical shift right by one 8478 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8479 %{ 8480 match(Set dst (URShiftI dst shift)); 8481 effect(KILL cr); 8482 8483 format %{ "shrl $dst, $shift" %} 8484 opcode(0xD1, 0x5); /* D1 /5 */ 8485 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8486 ins_pipe(ialu_reg); 8487 %} 8488 8489 // Logical shift right by one 8490 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8491 %{ 8492 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8493 effect(KILL cr); 8494 8495 format %{ "shrl $dst, $shift" %} 8496 opcode(0xD1, 0x5); /* D1 /5 */ 8497 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8498 ins_pipe(ialu_mem_imm); 8499 %} 8500 8501 // Logical Shift Right by 8-bit immediate 8502 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8503 %{ 8504 match(Set dst (URShiftI dst shift)); 8505 effect(KILL cr); 8506 8507 format %{ "shrl $dst, $shift" %} 8508 opcode(0xC1, 0x5); /* C1 /5 ib */ 8509 ins_encode(reg_opc_imm(dst, shift)); 8510 ins_pipe(ialu_reg); 8511 %} 8512 8513 // Logical Shift Right by 8-bit immediate 8514 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8515 %{ 8516 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8517 effect(KILL cr); 8518 8519 format %{ "shrl $dst, $shift" %} 8520 opcode(0xC1, 0x5); /* C1 /5 ib */ 8521 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8522 ins_pipe(ialu_mem_imm); 8523 %} 8524 8525 // Logical Shift Right by variable 8526 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8527 %{ 8528 match(Set dst (URShiftI dst shift)); 8529 effect(KILL cr); 8530 8531 format %{ "shrl $dst, $shift" %} 8532 opcode(0xD3, 0x5); /* D3 /5 */ 8533 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8534 ins_pipe(ialu_reg_reg); 8535 %} 8536 8537 // Logical Shift Right by variable 8538 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8539 %{ 8540 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8541 effect(KILL cr); 8542 8543 format %{ "shrl $dst, $shift" %} 8544 opcode(0xD3, 0x5); /* D3 /5 */ 8545 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8546 ins_pipe(ialu_mem_reg); 8547 %} 8548 8549 // Long Shift Instructions 8550 // Shift Left by one 8551 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8552 %{ 8553 match(Set dst (LShiftL dst shift)); 8554 effect(KILL cr); 8555 8556 format %{ "salq $dst, $shift" %} 8557 opcode(0xD1, 0x4); /* D1 /4 */ 8558 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8559 ins_pipe(ialu_reg); 8560 %} 8561 8562 // Shift Left by one 8563 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8564 %{ 8565 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8566 effect(KILL cr); 8567 8568 format %{ "salq $dst, $shift" %} 8569 opcode(0xD1, 0x4); /* D1 /4 */ 8570 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8571 ins_pipe(ialu_mem_imm); 8572 %} 8573 8574 // Shift Left by 8-bit immediate 8575 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8576 %{ 8577 match(Set dst (LShiftL dst shift)); 8578 effect(KILL cr); 8579 8580 format %{ "salq $dst, $shift" %} 8581 opcode(0xC1, 0x4); /* C1 /4 ib */ 8582 ins_encode(reg_opc_imm_wide(dst, shift)); 8583 ins_pipe(ialu_reg); 8584 %} 8585 8586 // Shift Left by 8-bit immediate 8587 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8588 %{ 8589 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8590 effect(KILL cr); 8591 8592 format %{ "salq $dst, $shift" %} 8593 opcode(0xC1, 0x4); /* C1 /4 ib */ 8594 ins_encode(REX_mem_wide(dst), OpcP, 8595 RM_opc_mem(secondary, dst), Con8or32(shift)); 8596 ins_pipe(ialu_mem_imm); 8597 %} 8598 8599 // Shift Left by variable 8600 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8601 %{ 8602 match(Set dst (LShiftL dst shift)); 8603 effect(KILL cr); 8604 8605 format %{ "salq $dst, $shift" %} 8606 opcode(0xD3, 0x4); /* D3 /4 */ 8607 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8608 ins_pipe(ialu_reg_reg); 8609 %} 8610 8611 // Shift Left by variable 8612 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8613 %{ 8614 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8615 effect(KILL cr); 8616 8617 format %{ "salq $dst, $shift" %} 8618 opcode(0xD3, 0x4); /* D3 /4 */ 8619 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8620 ins_pipe(ialu_mem_reg); 8621 %} 8622 8623 // Arithmetic shift right by one 8624 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8625 %{ 8626 match(Set dst (RShiftL dst shift)); 8627 effect(KILL cr); 8628 8629 format %{ "sarq $dst, $shift" %} 8630 opcode(0xD1, 0x7); /* D1 /7 */ 8631 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8632 ins_pipe(ialu_reg); 8633 %} 8634 8635 // Arithmetic shift right by one 8636 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8637 %{ 8638 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8639 effect(KILL cr); 8640 8641 format %{ "sarq $dst, $shift" %} 8642 opcode(0xD1, 0x7); /* D1 /7 */ 8643 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8644 ins_pipe(ialu_mem_imm); 8645 %} 8646 8647 // Arithmetic Shift Right by 8-bit immediate 8648 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8649 %{ 8650 match(Set dst (RShiftL dst shift)); 8651 effect(KILL cr); 8652 8653 format %{ "sarq $dst, $shift" %} 8654 opcode(0xC1, 0x7); /* C1 /7 ib */ 8655 ins_encode(reg_opc_imm_wide(dst, shift)); 8656 ins_pipe(ialu_mem_imm); 8657 %} 8658 8659 // Arithmetic Shift Right by 8-bit immediate 8660 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8661 %{ 8662 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8663 effect(KILL cr); 8664 8665 format %{ "sarq $dst, $shift" %} 8666 opcode(0xC1, 0x7); /* C1 /7 ib */ 8667 ins_encode(REX_mem_wide(dst), OpcP, 8668 RM_opc_mem(secondary, dst), Con8or32(shift)); 8669 ins_pipe(ialu_mem_imm); 8670 %} 8671 8672 // Arithmetic Shift Right by variable 8673 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8674 %{ 8675 match(Set dst (RShiftL dst shift)); 8676 effect(KILL cr); 8677 8678 format %{ "sarq $dst, $shift" %} 8679 opcode(0xD3, 0x7); /* D3 /7 */ 8680 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8681 ins_pipe(ialu_reg_reg); 8682 %} 8683 8684 // Arithmetic Shift Right by variable 8685 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8686 %{ 8687 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8688 effect(KILL cr); 8689 8690 format %{ "sarq $dst, $shift" %} 8691 opcode(0xD3, 0x7); /* D3 /7 */ 8692 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8693 ins_pipe(ialu_mem_reg); 8694 %} 8695 8696 // Logical shift right by one 8697 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8698 %{ 8699 match(Set dst (URShiftL dst shift)); 8700 effect(KILL cr); 8701 8702 format %{ "shrq $dst, $shift" %} 8703 opcode(0xD1, 0x5); /* D1 /5 */ 8704 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8705 ins_pipe(ialu_reg); 8706 %} 8707 8708 // Logical shift right by one 8709 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8710 %{ 8711 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8712 effect(KILL cr); 8713 8714 format %{ "shrq $dst, $shift" %} 8715 opcode(0xD1, 0x5); /* D1 /5 */ 8716 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8717 ins_pipe(ialu_mem_imm); 8718 %} 8719 8720 // Logical Shift Right by 8-bit immediate 8721 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8722 %{ 8723 match(Set dst (URShiftL dst shift)); 8724 effect(KILL cr); 8725 8726 format %{ "shrq $dst, $shift" %} 8727 opcode(0xC1, 0x5); /* C1 /5 ib */ 8728 ins_encode(reg_opc_imm_wide(dst, shift)); 8729 ins_pipe(ialu_reg); 8730 %} 8731 8732 8733 // Logical Shift Right by 8-bit immediate 8734 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8735 %{ 8736 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8737 effect(KILL cr); 8738 8739 format %{ "shrq $dst, $shift" %} 8740 opcode(0xC1, 0x5); /* C1 /5 ib */ 8741 ins_encode(REX_mem_wide(dst), OpcP, 8742 RM_opc_mem(secondary, dst), Con8or32(shift)); 8743 ins_pipe(ialu_mem_imm); 8744 %} 8745 8746 // Logical Shift Right by variable 8747 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8748 %{ 8749 match(Set dst (URShiftL dst shift)); 8750 effect(KILL cr); 8751 8752 format %{ "shrq $dst, $shift" %} 8753 opcode(0xD3, 0x5); /* D3 /5 */ 8754 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8755 ins_pipe(ialu_reg_reg); 8756 %} 8757 8758 // Logical Shift Right by variable 8759 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8760 %{ 8761 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8762 effect(KILL cr); 8763 8764 format %{ "shrq $dst, $shift" %} 8765 opcode(0xD3, 0x5); /* D3 /5 */ 8766 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8767 ins_pipe(ialu_mem_reg); 8768 %} 8769 8770 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8771 // This idiom is used by the compiler for the i2b bytecode. 8772 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8773 %{ 8774 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8775 8776 format %{ "movsbl $dst, $src\t# i2b" %} 8777 opcode(0x0F, 0xBE); 8778 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8779 ins_pipe(ialu_reg_reg); 8780 %} 8781 8782 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8783 // This idiom is used by the compiler the i2s bytecode. 8784 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8785 %{ 8786 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8787 8788 format %{ "movswl $dst, $src\t# i2s" %} 8789 opcode(0x0F, 0xBF); 8790 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8791 ins_pipe(ialu_reg_reg); 8792 %} 8793 8794 // ROL/ROR instructions 8795 8796 // ROL expand 8797 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8798 effect(KILL cr, USE_DEF dst); 8799 8800 format %{ "roll $dst" %} 8801 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8802 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8803 ins_pipe(ialu_reg); 8804 %} 8805 8806 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8807 effect(USE_DEF dst, USE shift, KILL cr); 8808 8809 format %{ "roll $dst, $shift" %} 8810 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8811 ins_encode( reg_opc_imm(dst, shift) ); 8812 ins_pipe(ialu_reg); 8813 %} 8814 8815 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8816 %{ 8817 effect(USE_DEF dst, USE shift, KILL cr); 8818 8819 format %{ "roll $dst, $shift" %} 8820 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8821 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8822 ins_pipe(ialu_reg_reg); 8823 %} 8824 // end of ROL expand 8825 8826 // Rotate Left by one 8827 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8828 %{ 8829 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8830 8831 expand %{ 8832 rolI_rReg_imm1(dst, cr); 8833 %} 8834 %} 8835 8836 // Rotate Left by 8-bit immediate 8837 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8838 %{ 8839 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8840 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8841 8842 expand %{ 8843 rolI_rReg_imm8(dst, lshift, cr); 8844 %} 8845 %} 8846 8847 // Rotate Left by variable 8848 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8849 %{ 8850 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8851 8852 expand %{ 8853 rolI_rReg_CL(dst, shift, cr); 8854 %} 8855 %} 8856 8857 // Rotate Left by variable 8858 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8859 %{ 8860 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8861 8862 expand %{ 8863 rolI_rReg_CL(dst, shift, cr); 8864 %} 8865 %} 8866 8867 // ROR expand 8868 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8869 %{ 8870 effect(USE_DEF dst, KILL cr); 8871 8872 format %{ "rorl $dst" %} 8873 opcode(0xD1, 0x1); /* D1 /1 */ 8874 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8875 ins_pipe(ialu_reg); 8876 %} 8877 8878 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8879 %{ 8880 effect(USE_DEF dst, USE shift, KILL cr); 8881 8882 format %{ "rorl $dst, $shift" %} 8883 opcode(0xC1, 0x1); /* C1 /1 ib */ 8884 ins_encode(reg_opc_imm(dst, shift)); 8885 ins_pipe(ialu_reg); 8886 %} 8887 8888 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8889 %{ 8890 effect(USE_DEF dst, USE shift, KILL cr); 8891 8892 format %{ "rorl $dst, $shift" %} 8893 opcode(0xD3, 0x1); /* D3 /1 */ 8894 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8895 ins_pipe(ialu_reg_reg); 8896 %} 8897 // end of ROR expand 8898 8899 // Rotate Right by one 8900 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8901 %{ 8902 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8903 8904 expand %{ 8905 rorI_rReg_imm1(dst, cr); 8906 %} 8907 %} 8908 8909 // Rotate Right by 8-bit immediate 8910 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8911 %{ 8912 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8913 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8914 8915 expand %{ 8916 rorI_rReg_imm8(dst, rshift, cr); 8917 %} 8918 %} 8919 8920 // Rotate Right by variable 8921 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8922 %{ 8923 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8924 8925 expand %{ 8926 rorI_rReg_CL(dst, shift, cr); 8927 %} 8928 %} 8929 8930 // Rotate Right by variable 8931 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8932 %{ 8933 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8934 8935 expand %{ 8936 rorI_rReg_CL(dst, shift, cr); 8937 %} 8938 %} 8939 8940 // for long rotate 8941 // ROL expand 8942 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8943 effect(USE_DEF dst, KILL cr); 8944 8945 format %{ "rolq $dst" %} 8946 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8947 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8948 ins_pipe(ialu_reg); 8949 %} 8950 8951 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8952 effect(USE_DEF dst, USE shift, KILL cr); 8953 8954 format %{ "rolq $dst, $shift" %} 8955 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8956 ins_encode( reg_opc_imm_wide(dst, shift) ); 8957 ins_pipe(ialu_reg); 8958 %} 8959 8960 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8961 %{ 8962 effect(USE_DEF dst, USE shift, KILL cr); 8963 8964 format %{ "rolq $dst, $shift" %} 8965 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8966 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8967 ins_pipe(ialu_reg_reg); 8968 %} 8969 // end of ROL expand 8970 8971 // Rotate Left by one 8972 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8973 %{ 8974 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8975 8976 expand %{ 8977 rolL_rReg_imm1(dst, cr); 8978 %} 8979 %} 8980 8981 // Rotate Left by 8-bit immediate 8982 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8983 %{ 8984 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8985 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8986 8987 expand %{ 8988 rolL_rReg_imm8(dst, lshift, cr); 8989 %} 8990 %} 8991 8992 // Rotate Left by variable 8993 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8994 %{ 8995 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8996 8997 expand %{ 8998 rolL_rReg_CL(dst, shift, cr); 8999 %} 9000 %} 9001 9002 // Rotate Left by variable 9003 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9004 %{ 9005 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9006 9007 expand %{ 9008 rolL_rReg_CL(dst, shift, cr); 9009 %} 9010 %} 9011 9012 // ROR expand 9013 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9014 %{ 9015 effect(USE_DEF dst, KILL cr); 9016 9017 format %{ "rorq $dst" %} 9018 opcode(0xD1, 0x1); /* D1 /1 */ 9019 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9020 ins_pipe(ialu_reg); 9021 %} 9022 9023 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9024 %{ 9025 effect(USE_DEF dst, USE shift, KILL cr); 9026 9027 format %{ "rorq $dst, $shift" %} 9028 opcode(0xC1, 0x1); /* C1 /1 ib */ 9029 ins_encode(reg_opc_imm_wide(dst, shift)); 9030 ins_pipe(ialu_reg); 9031 %} 9032 9033 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9034 %{ 9035 effect(USE_DEF dst, USE shift, KILL cr); 9036 9037 format %{ "rorq $dst, $shift" %} 9038 opcode(0xD3, 0x1); /* D3 /1 */ 9039 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9040 ins_pipe(ialu_reg_reg); 9041 %} 9042 // end of ROR expand 9043 9044 // Rotate Right by one 9045 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9046 %{ 9047 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9048 9049 expand %{ 9050 rorL_rReg_imm1(dst, cr); 9051 %} 9052 %} 9053 9054 // Rotate Right by 8-bit immediate 9055 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9056 %{ 9057 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9058 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9059 9060 expand %{ 9061 rorL_rReg_imm8(dst, rshift, cr); 9062 %} 9063 %} 9064 9065 // Rotate Right by variable 9066 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9067 %{ 9068 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9069 9070 expand %{ 9071 rorL_rReg_CL(dst, shift, cr); 9072 %} 9073 %} 9074 9075 // Rotate Right by variable 9076 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9077 %{ 9078 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9079 9080 expand %{ 9081 rorL_rReg_CL(dst, shift, cr); 9082 %} 9083 %} 9084 9085 // Logical Instructions 9086 9087 // Integer Logical Instructions 9088 9089 // And Instructions 9090 // And Register with Register 9091 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9092 %{ 9093 match(Set dst (AndI dst src)); 9094 effect(KILL cr); 9095 9096 format %{ "andl $dst, $src\t# int" %} 9097 opcode(0x23); 9098 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9099 ins_pipe(ialu_reg_reg); 9100 %} 9101 9102 // And Register with Immediate 255 9103 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9104 %{ 9105 match(Set dst (AndI dst src)); 9106 9107 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9108 opcode(0x0F, 0xB6); 9109 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9110 ins_pipe(ialu_reg); 9111 %} 9112 9113 // And Register with Immediate 255 and promote to long 9114 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9115 %{ 9116 match(Set dst (ConvI2L (AndI src mask))); 9117 9118 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9119 opcode(0x0F, 0xB6); 9120 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9121 ins_pipe(ialu_reg); 9122 %} 9123 9124 // And Register with Immediate 65535 9125 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9126 %{ 9127 match(Set dst (AndI dst src)); 9128 9129 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9130 opcode(0x0F, 0xB7); 9131 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9132 ins_pipe(ialu_reg); 9133 %} 9134 9135 // And Register with Immediate 65535 and promote to long 9136 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9137 %{ 9138 match(Set dst (ConvI2L (AndI src mask))); 9139 9140 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9141 opcode(0x0F, 0xB7); 9142 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9143 ins_pipe(ialu_reg); 9144 %} 9145 9146 // And Register with Immediate 9147 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9148 %{ 9149 match(Set dst (AndI dst src)); 9150 effect(KILL cr); 9151 9152 format %{ "andl $dst, $src\t# int" %} 9153 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9154 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9155 ins_pipe(ialu_reg); 9156 %} 9157 9158 // And Register with Memory 9159 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9160 %{ 9161 match(Set dst (AndI dst (LoadI src))); 9162 effect(KILL cr); 9163 9164 ins_cost(125); 9165 format %{ "andl $dst, $src\t# int" %} 9166 opcode(0x23); 9167 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9168 ins_pipe(ialu_reg_mem); 9169 %} 9170 9171 // And Memory with Register 9172 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9173 %{ 9174 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9175 effect(KILL cr); 9176 9177 ins_cost(150); 9178 format %{ "andl $dst, $src\t# int" %} 9179 opcode(0x21); /* Opcode 21 /r */ 9180 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9181 ins_pipe(ialu_mem_reg); 9182 %} 9183 9184 // And Memory with Immediate 9185 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9186 %{ 9187 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9188 effect(KILL cr); 9189 9190 ins_cost(125); 9191 format %{ "andl $dst, $src\t# int" %} 9192 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9193 ins_encode(REX_mem(dst), OpcSE(src), 9194 RM_opc_mem(secondary, dst), Con8or32(src)); 9195 ins_pipe(ialu_mem_imm); 9196 %} 9197 9198 // BMI1 instructions 9199 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9200 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9201 predicate(UseBMI1Instructions); 9202 effect(KILL cr); 9203 9204 ins_cost(125); 9205 format %{ "andnl $dst, $src1, $src2" %} 9206 9207 ins_encode %{ 9208 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9209 %} 9210 ins_pipe(ialu_reg_mem); 9211 %} 9212 9213 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9214 match(Set dst (AndI (XorI src1 minus_1) src2)); 9215 predicate(UseBMI1Instructions); 9216 effect(KILL cr); 9217 9218 format %{ "andnl $dst, $src1, $src2" %} 9219 9220 ins_encode %{ 9221 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9222 %} 9223 ins_pipe(ialu_reg); 9224 %} 9225 9226 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9227 match(Set dst (AndI (SubI imm_zero src) src)); 9228 predicate(UseBMI1Instructions); 9229 effect(KILL cr); 9230 9231 format %{ "blsil $dst, $src" %} 9232 9233 ins_encode %{ 9234 __ blsil($dst$$Register, $src$$Register); 9235 %} 9236 ins_pipe(ialu_reg); 9237 %} 9238 9239 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9240 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9241 predicate(UseBMI1Instructions); 9242 effect(KILL cr); 9243 9244 ins_cost(125); 9245 format %{ "blsil $dst, $src" %} 9246 9247 ins_encode %{ 9248 __ blsil($dst$$Register, $src$$Address); 9249 %} 9250 ins_pipe(ialu_reg_mem); 9251 %} 9252 9253 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9254 %{ 9255 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9256 predicate(UseBMI1Instructions); 9257 effect(KILL cr); 9258 9259 ins_cost(125); 9260 format %{ "blsmskl $dst, $src" %} 9261 9262 ins_encode %{ 9263 __ blsmskl($dst$$Register, $src$$Address); 9264 %} 9265 ins_pipe(ialu_reg_mem); 9266 %} 9267 9268 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9269 %{ 9270 match(Set dst (XorI (AddI src minus_1) src)); 9271 predicate(UseBMI1Instructions); 9272 effect(KILL cr); 9273 9274 format %{ "blsmskl $dst, $src" %} 9275 9276 ins_encode %{ 9277 __ blsmskl($dst$$Register, $src$$Register); 9278 %} 9279 9280 ins_pipe(ialu_reg); 9281 %} 9282 9283 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9284 %{ 9285 match(Set dst (AndI (AddI src minus_1) src) ); 9286 predicate(UseBMI1Instructions); 9287 effect(KILL cr); 9288 9289 format %{ "blsrl $dst, $src" %} 9290 9291 ins_encode %{ 9292 __ blsrl($dst$$Register, $src$$Register); 9293 %} 9294 9295 ins_pipe(ialu_reg_mem); 9296 %} 9297 9298 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9299 %{ 9300 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9301 predicate(UseBMI1Instructions); 9302 effect(KILL cr); 9303 9304 ins_cost(125); 9305 format %{ "blsrl $dst, $src" %} 9306 9307 ins_encode %{ 9308 __ blsrl($dst$$Register, $src$$Address); 9309 %} 9310 9311 ins_pipe(ialu_reg); 9312 %} 9313 9314 // Or Instructions 9315 // Or Register with Register 9316 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9317 %{ 9318 match(Set dst (OrI dst src)); 9319 effect(KILL cr); 9320 9321 format %{ "orl $dst, $src\t# int" %} 9322 opcode(0x0B); 9323 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9324 ins_pipe(ialu_reg_reg); 9325 %} 9326 9327 // Or Register with Immediate 9328 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9329 %{ 9330 match(Set dst (OrI dst src)); 9331 effect(KILL cr); 9332 9333 format %{ "orl $dst, $src\t# int" %} 9334 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9335 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9336 ins_pipe(ialu_reg); 9337 %} 9338 9339 // Or Register with Memory 9340 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9341 %{ 9342 match(Set dst (OrI dst (LoadI src))); 9343 effect(KILL cr); 9344 9345 ins_cost(125); 9346 format %{ "orl $dst, $src\t# int" %} 9347 opcode(0x0B); 9348 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9349 ins_pipe(ialu_reg_mem); 9350 %} 9351 9352 // Or Memory with Register 9353 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9354 %{ 9355 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9356 effect(KILL cr); 9357 9358 ins_cost(150); 9359 format %{ "orl $dst, $src\t# int" %} 9360 opcode(0x09); /* Opcode 09 /r */ 9361 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9362 ins_pipe(ialu_mem_reg); 9363 %} 9364 9365 // Or Memory with Immediate 9366 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9367 %{ 9368 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9369 effect(KILL cr); 9370 9371 ins_cost(125); 9372 format %{ "orl $dst, $src\t# int" %} 9373 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9374 ins_encode(REX_mem(dst), OpcSE(src), 9375 RM_opc_mem(secondary, dst), Con8or32(src)); 9376 ins_pipe(ialu_mem_imm); 9377 %} 9378 9379 // Xor Instructions 9380 // Xor Register with Register 9381 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9382 %{ 9383 match(Set dst (XorI dst src)); 9384 effect(KILL cr); 9385 9386 format %{ "xorl $dst, $src\t# int" %} 9387 opcode(0x33); 9388 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9389 ins_pipe(ialu_reg_reg); 9390 %} 9391 9392 // Xor Register with Immediate -1 9393 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9394 match(Set dst (XorI dst imm)); 9395 9396 format %{ "not $dst" %} 9397 ins_encode %{ 9398 __ notl($dst$$Register); 9399 %} 9400 ins_pipe(ialu_reg); 9401 %} 9402 9403 // Xor Register with Immediate 9404 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9405 %{ 9406 match(Set dst (XorI dst src)); 9407 effect(KILL cr); 9408 9409 format %{ "xorl $dst, $src\t# int" %} 9410 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9411 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9412 ins_pipe(ialu_reg); 9413 %} 9414 9415 // Xor Register with Memory 9416 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9417 %{ 9418 match(Set dst (XorI dst (LoadI src))); 9419 effect(KILL cr); 9420 9421 ins_cost(125); 9422 format %{ "xorl $dst, $src\t# int" %} 9423 opcode(0x33); 9424 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9425 ins_pipe(ialu_reg_mem); 9426 %} 9427 9428 // Xor Memory with Register 9429 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9430 %{ 9431 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9432 effect(KILL cr); 9433 9434 ins_cost(150); 9435 format %{ "xorl $dst, $src\t# int" %} 9436 opcode(0x31); /* Opcode 31 /r */ 9437 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9438 ins_pipe(ialu_mem_reg); 9439 %} 9440 9441 // Xor Memory with Immediate 9442 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9443 %{ 9444 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9445 effect(KILL cr); 9446 9447 ins_cost(125); 9448 format %{ "xorl $dst, $src\t# int" %} 9449 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9450 ins_encode(REX_mem(dst), OpcSE(src), 9451 RM_opc_mem(secondary, dst), Con8or32(src)); 9452 ins_pipe(ialu_mem_imm); 9453 %} 9454 9455 9456 // Long Logical Instructions 9457 9458 // And Instructions 9459 // And Register with Register 9460 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9461 %{ 9462 match(Set dst (AndL dst src)); 9463 effect(KILL cr); 9464 9465 format %{ "andq $dst, $src\t# long" %} 9466 opcode(0x23); 9467 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9468 ins_pipe(ialu_reg_reg); 9469 %} 9470 9471 // And Register with Immediate 255 9472 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9473 %{ 9474 match(Set dst (AndL dst src)); 9475 9476 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9477 opcode(0x0F, 0xB6); 9478 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9479 ins_pipe(ialu_reg); 9480 %} 9481 9482 // And Register with Immediate 65535 9483 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9484 %{ 9485 match(Set dst (AndL dst src)); 9486 9487 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9488 opcode(0x0F, 0xB7); 9489 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9490 ins_pipe(ialu_reg); 9491 %} 9492 9493 // And Register with Immediate 9494 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9495 %{ 9496 match(Set dst (AndL dst src)); 9497 effect(KILL cr); 9498 9499 format %{ "andq $dst, $src\t# long" %} 9500 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9501 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9502 ins_pipe(ialu_reg); 9503 %} 9504 9505 // And Register with Memory 9506 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9507 %{ 9508 match(Set dst (AndL dst (LoadL src))); 9509 effect(KILL cr); 9510 9511 ins_cost(125); 9512 format %{ "andq $dst, $src\t# long" %} 9513 opcode(0x23); 9514 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9515 ins_pipe(ialu_reg_mem); 9516 %} 9517 9518 // And Memory with Register 9519 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9520 %{ 9521 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9522 effect(KILL cr); 9523 9524 ins_cost(150); 9525 format %{ "andq $dst, $src\t# long" %} 9526 opcode(0x21); /* Opcode 21 /r */ 9527 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9528 ins_pipe(ialu_mem_reg); 9529 %} 9530 9531 // And Memory with Immediate 9532 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9533 %{ 9534 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9535 effect(KILL cr); 9536 9537 ins_cost(125); 9538 format %{ "andq $dst, $src\t# long" %} 9539 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9540 ins_encode(REX_mem_wide(dst), OpcSE(src), 9541 RM_opc_mem(secondary, dst), Con8or32(src)); 9542 ins_pipe(ialu_mem_imm); 9543 %} 9544 9545 // BMI1 instructions 9546 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9547 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9548 predicate(UseBMI1Instructions); 9549 effect(KILL cr); 9550 9551 ins_cost(125); 9552 format %{ "andnq $dst, $src1, $src2" %} 9553 9554 ins_encode %{ 9555 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9556 %} 9557 ins_pipe(ialu_reg_mem); 9558 %} 9559 9560 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9561 match(Set dst (AndL (XorL src1 minus_1) src2)); 9562 predicate(UseBMI1Instructions); 9563 effect(KILL cr); 9564 9565 format %{ "andnq $dst, $src1, $src2" %} 9566 9567 ins_encode %{ 9568 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9569 %} 9570 ins_pipe(ialu_reg_mem); 9571 %} 9572 9573 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9574 match(Set dst (AndL (SubL imm_zero src) src)); 9575 predicate(UseBMI1Instructions); 9576 effect(KILL cr); 9577 9578 format %{ "blsiq $dst, $src" %} 9579 9580 ins_encode %{ 9581 __ blsiq($dst$$Register, $src$$Register); 9582 %} 9583 ins_pipe(ialu_reg); 9584 %} 9585 9586 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9587 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9588 predicate(UseBMI1Instructions); 9589 effect(KILL cr); 9590 9591 ins_cost(125); 9592 format %{ "blsiq $dst, $src" %} 9593 9594 ins_encode %{ 9595 __ blsiq($dst$$Register, $src$$Address); 9596 %} 9597 ins_pipe(ialu_reg_mem); 9598 %} 9599 9600 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9601 %{ 9602 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9603 predicate(UseBMI1Instructions); 9604 effect(KILL cr); 9605 9606 ins_cost(125); 9607 format %{ "blsmskq $dst, $src" %} 9608 9609 ins_encode %{ 9610 __ blsmskq($dst$$Register, $src$$Address); 9611 %} 9612 ins_pipe(ialu_reg_mem); 9613 %} 9614 9615 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9616 %{ 9617 match(Set dst (XorL (AddL src minus_1) src)); 9618 predicate(UseBMI1Instructions); 9619 effect(KILL cr); 9620 9621 format %{ "blsmskq $dst, $src" %} 9622 9623 ins_encode %{ 9624 __ blsmskq($dst$$Register, $src$$Register); 9625 %} 9626 9627 ins_pipe(ialu_reg); 9628 %} 9629 9630 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9631 %{ 9632 match(Set dst (AndL (AddL src minus_1) src) ); 9633 predicate(UseBMI1Instructions); 9634 effect(KILL cr); 9635 9636 format %{ "blsrq $dst, $src" %} 9637 9638 ins_encode %{ 9639 __ blsrq($dst$$Register, $src$$Register); 9640 %} 9641 9642 ins_pipe(ialu_reg); 9643 %} 9644 9645 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9646 %{ 9647 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9648 predicate(UseBMI1Instructions); 9649 effect(KILL cr); 9650 9651 ins_cost(125); 9652 format %{ "blsrq $dst, $src" %} 9653 9654 ins_encode %{ 9655 __ blsrq($dst$$Register, $src$$Address); 9656 %} 9657 9658 ins_pipe(ialu_reg); 9659 %} 9660 9661 // Or Instructions 9662 // Or Register with Register 9663 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9664 %{ 9665 match(Set dst (OrL dst src)); 9666 effect(KILL cr); 9667 9668 format %{ "orq $dst, $src\t# long" %} 9669 opcode(0x0B); 9670 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9671 ins_pipe(ialu_reg_reg); 9672 %} 9673 9674 // Use any_RegP to match R15 (TLS register) without spilling. 9675 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9676 match(Set dst (OrL dst (CastP2X src))); 9677 effect(KILL cr); 9678 9679 format %{ "orq $dst, $src\t# long" %} 9680 opcode(0x0B); 9681 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9682 ins_pipe(ialu_reg_reg); 9683 %} 9684 9685 9686 // Or Register with Immediate 9687 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9688 %{ 9689 match(Set dst (OrL dst src)); 9690 effect(KILL cr); 9691 9692 format %{ "orq $dst, $src\t# long" %} 9693 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9694 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9695 ins_pipe(ialu_reg); 9696 %} 9697 9698 // Or Register with Memory 9699 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9700 %{ 9701 match(Set dst (OrL dst (LoadL src))); 9702 effect(KILL cr); 9703 9704 ins_cost(125); 9705 format %{ "orq $dst, $src\t# long" %} 9706 opcode(0x0B); 9707 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9708 ins_pipe(ialu_reg_mem); 9709 %} 9710 9711 // Or Memory with Register 9712 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9713 %{ 9714 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9715 effect(KILL cr); 9716 9717 ins_cost(150); 9718 format %{ "orq $dst, $src\t# long" %} 9719 opcode(0x09); /* Opcode 09 /r */ 9720 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9721 ins_pipe(ialu_mem_reg); 9722 %} 9723 9724 // Or Memory with Immediate 9725 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9726 %{ 9727 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9728 effect(KILL cr); 9729 9730 ins_cost(125); 9731 format %{ "orq $dst, $src\t# long" %} 9732 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9733 ins_encode(REX_mem_wide(dst), OpcSE(src), 9734 RM_opc_mem(secondary, dst), Con8or32(src)); 9735 ins_pipe(ialu_mem_imm); 9736 %} 9737 9738 // Xor Instructions 9739 // Xor Register with Register 9740 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9741 %{ 9742 match(Set dst (XorL dst src)); 9743 effect(KILL cr); 9744 9745 format %{ "xorq $dst, $src\t# long" %} 9746 opcode(0x33); 9747 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9748 ins_pipe(ialu_reg_reg); 9749 %} 9750 9751 // Xor Register with Immediate -1 9752 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9753 match(Set dst (XorL dst imm)); 9754 9755 format %{ "notq $dst" %} 9756 ins_encode %{ 9757 __ notq($dst$$Register); 9758 %} 9759 ins_pipe(ialu_reg); 9760 %} 9761 9762 // Xor Register with Immediate 9763 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9764 %{ 9765 match(Set dst (XorL dst src)); 9766 effect(KILL cr); 9767 9768 format %{ "xorq $dst, $src\t# long" %} 9769 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9770 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9771 ins_pipe(ialu_reg); 9772 %} 9773 9774 // Xor Register with Memory 9775 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9776 %{ 9777 match(Set dst (XorL dst (LoadL src))); 9778 effect(KILL cr); 9779 9780 ins_cost(125); 9781 format %{ "xorq $dst, $src\t# long" %} 9782 opcode(0x33); 9783 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9784 ins_pipe(ialu_reg_mem); 9785 %} 9786 9787 // Xor Memory with Register 9788 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9789 %{ 9790 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9791 effect(KILL cr); 9792 9793 ins_cost(150); 9794 format %{ "xorq $dst, $src\t# long" %} 9795 opcode(0x31); /* Opcode 31 /r */ 9796 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9797 ins_pipe(ialu_mem_reg); 9798 %} 9799 9800 // Xor Memory with Immediate 9801 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9802 %{ 9803 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9804 effect(KILL cr); 9805 9806 ins_cost(125); 9807 format %{ "xorq $dst, $src\t# long" %} 9808 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9809 ins_encode(REX_mem_wide(dst), OpcSE(src), 9810 RM_opc_mem(secondary, dst), Con8or32(src)); 9811 ins_pipe(ialu_mem_imm); 9812 %} 9813 9814 // Convert Int to Boolean 9815 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9816 %{ 9817 match(Set dst (Conv2B src)); 9818 effect(KILL cr); 9819 9820 format %{ "testl $src, $src\t# ci2b\n\t" 9821 "setnz $dst\n\t" 9822 "movzbl $dst, $dst" %} 9823 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9824 setNZ_reg(dst), 9825 REX_reg_breg(dst, dst), // movzbl 9826 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9827 ins_pipe(pipe_slow); // XXX 9828 %} 9829 9830 // Convert Pointer to Boolean 9831 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9832 %{ 9833 match(Set dst (Conv2B src)); 9834 effect(KILL cr); 9835 9836 format %{ "testq $src, $src\t# cp2b\n\t" 9837 "setnz $dst\n\t" 9838 "movzbl $dst, $dst" %} 9839 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9840 setNZ_reg(dst), 9841 REX_reg_breg(dst, dst), // movzbl 9842 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9843 ins_pipe(pipe_slow); // XXX 9844 %} 9845 9846 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9847 %{ 9848 match(Set dst (CmpLTMask p q)); 9849 effect(KILL cr); 9850 9851 ins_cost(400); 9852 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9853 "setlt $dst\n\t" 9854 "movzbl $dst, $dst\n\t" 9855 "negl $dst" %} 9856 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9857 setLT_reg(dst), 9858 REX_reg_breg(dst, dst), // movzbl 9859 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9860 neg_reg(dst)); 9861 ins_pipe(pipe_slow); 9862 %} 9863 9864 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9865 %{ 9866 match(Set dst (CmpLTMask dst zero)); 9867 effect(KILL cr); 9868 9869 ins_cost(100); 9870 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9871 ins_encode %{ 9872 __ sarl($dst$$Register, 31); 9873 %} 9874 ins_pipe(ialu_reg); 9875 %} 9876 9877 /* Better to save a register than avoid a branch */ 9878 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9879 %{ 9880 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9881 effect(KILL cr); 9882 ins_cost(300); 9883 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9884 "jge done\n\t" 9885 "addl $p,$y\n" 9886 "done: " %} 9887 ins_encode %{ 9888 Register Rp = $p$$Register; 9889 Register Rq = $q$$Register; 9890 Register Ry = $y$$Register; 9891 Label done; 9892 __ subl(Rp, Rq); 9893 __ jccb(Assembler::greaterEqual, done); 9894 __ addl(Rp, Ry); 9895 __ bind(done); 9896 %} 9897 ins_pipe(pipe_cmplt); 9898 %} 9899 9900 /* Better to save a register than avoid a branch */ 9901 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9902 %{ 9903 match(Set y (AndI (CmpLTMask p q) y)); 9904 effect(KILL cr); 9905 9906 ins_cost(300); 9907 9908 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9909 "jlt done\n\t" 9910 "xorl $y, $y\n" 9911 "done: " %} 9912 ins_encode %{ 9913 Register Rp = $p$$Register; 9914 Register Rq = $q$$Register; 9915 Register Ry = $y$$Register; 9916 Label done; 9917 __ cmpl(Rp, Rq); 9918 __ jccb(Assembler::less, done); 9919 __ xorl(Ry, Ry); 9920 __ bind(done); 9921 %} 9922 ins_pipe(pipe_cmplt); 9923 %} 9924 9925 9926 //---------- FP Instructions------------------------------------------------ 9927 9928 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9929 %{ 9930 match(Set cr (CmpF src1 src2)); 9931 9932 ins_cost(145); 9933 format %{ "ucomiss $src1, $src2\n\t" 9934 "jnp,s exit\n\t" 9935 "pushfq\t# saw NaN, set CF\n\t" 9936 "andq [rsp], #0xffffff2b\n\t" 9937 "popfq\n" 9938 "exit:" %} 9939 ins_encode %{ 9940 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9941 emit_cmpfp_fixup(_masm); 9942 %} 9943 ins_pipe(pipe_slow); 9944 %} 9945 9946 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9947 match(Set cr (CmpF src1 src2)); 9948 9949 ins_cost(100); 9950 format %{ "ucomiss $src1, $src2" %} 9951 ins_encode %{ 9952 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9953 %} 9954 ins_pipe(pipe_slow); 9955 %} 9956 9957 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9958 %{ 9959 match(Set cr (CmpF src1 (LoadF src2))); 9960 9961 ins_cost(145); 9962 format %{ "ucomiss $src1, $src2\n\t" 9963 "jnp,s exit\n\t" 9964 "pushfq\t# saw NaN, set CF\n\t" 9965 "andq [rsp], #0xffffff2b\n\t" 9966 "popfq\n" 9967 "exit:" %} 9968 ins_encode %{ 9969 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9970 emit_cmpfp_fixup(_masm); 9971 %} 9972 ins_pipe(pipe_slow); 9973 %} 9974 9975 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9976 match(Set cr (CmpF src1 (LoadF src2))); 9977 9978 ins_cost(100); 9979 format %{ "ucomiss $src1, $src2" %} 9980 ins_encode %{ 9981 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9982 %} 9983 ins_pipe(pipe_slow); 9984 %} 9985 9986 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9987 match(Set cr (CmpF src con)); 9988 9989 ins_cost(145); 9990 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9991 "jnp,s exit\n\t" 9992 "pushfq\t# saw NaN, set CF\n\t" 9993 "andq [rsp], #0xffffff2b\n\t" 9994 "popfq\n" 9995 "exit:" %} 9996 ins_encode %{ 9997 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9998 emit_cmpfp_fixup(_masm); 9999 %} 10000 ins_pipe(pipe_slow); 10001 %} 10002 10003 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10004 match(Set cr (CmpF src con)); 10005 ins_cost(100); 10006 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10007 ins_encode %{ 10008 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10009 %} 10010 ins_pipe(pipe_slow); 10011 %} 10012 10013 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10014 %{ 10015 match(Set cr (CmpD src1 src2)); 10016 10017 ins_cost(145); 10018 format %{ "ucomisd $src1, $src2\n\t" 10019 "jnp,s exit\n\t" 10020 "pushfq\t# saw NaN, set CF\n\t" 10021 "andq [rsp], #0xffffff2b\n\t" 10022 "popfq\n" 10023 "exit:" %} 10024 ins_encode %{ 10025 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10026 emit_cmpfp_fixup(_masm); 10027 %} 10028 ins_pipe(pipe_slow); 10029 %} 10030 10031 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10032 match(Set cr (CmpD src1 src2)); 10033 10034 ins_cost(100); 10035 format %{ "ucomisd $src1, $src2 test" %} 10036 ins_encode %{ 10037 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10038 %} 10039 ins_pipe(pipe_slow); 10040 %} 10041 10042 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10043 %{ 10044 match(Set cr (CmpD src1 (LoadD src2))); 10045 10046 ins_cost(145); 10047 format %{ "ucomisd $src1, $src2\n\t" 10048 "jnp,s exit\n\t" 10049 "pushfq\t# saw NaN, set CF\n\t" 10050 "andq [rsp], #0xffffff2b\n\t" 10051 "popfq\n" 10052 "exit:" %} 10053 ins_encode %{ 10054 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10055 emit_cmpfp_fixup(_masm); 10056 %} 10057 ins_pipe(pipe_slow); 10058 %} 10059 10060 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10061 match(Set cr (CmpD src1 (LoadD src2))); 10062 10063 ins_cost(100); 10064 format %{ "ucomisd $src1, $src2" %} 10065 ins_encode %{ 10066 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10067 %} 10068 ins_pipe(pipe_slow); 10069 %} 10070 10071 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10072 match(Set cr (CmpD src con)); 10073 10074 ins_cost(145); 10075 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10076 "jnp,s exit\n\t" 10077 "pushfq\t# saw NaN, set CF\n\t" 10078 "andq [rsp], #0xffffff2b\n\t" 10079 "popfq\n" 10080 "exit:" %} 10081 ins_encode %{ 10082 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10083 emit_cmpfp_fixup(_masm); 10084 %} 10085 ins_pipe(pipe_slow); 10086 %} 10087 10088 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10089 match(Set cr (CmpD src con)); 10090 ins_cost(100); 10091 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10092 ins_encode %{ 10093 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10094 %} 10095 ins_pipe(pipe_slow); 10096 %} 10097 10098 // Compare into -1,0,1 10099 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10100 %{ 10101 match(Set dst (CmpF3 src1 src2)); 10102 effect(KILL cr); 10103 10104 ins_cost(275); 10105 format %{ "ucomiss $src1, $src2\n\t" 10106 "movl $dst, #-1\n\t" 10107 "jp,s done\n\t" 10108 "jb,s done\n\t" 10109 "setne $dst\n\t" 10110 "movzbl $dst, $dst\n" 10111 "done:" %} 10112 ins_encode %{ 10113 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10114 emit_cmpfp3(_masm, $dst$$Register); 10115 %} 10116 ins_pipe(pipe_slow); 10117 %} 10118 10119 // Compare into -1,0,1 10120 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10121 %{ 10122 match(Set dst (CmpF3 src1 (LoadF src2))); 10123 effect(KILL cr); 10124 10125 ins_cost(275); 10126 format %{ "ucomiss $src1, $src2\n\t" 10127 "movl $dst, #-1\n\t" 10128 "jp,s done\n\t" 10129 "jb,s done\n\t" 10130 "setne $dst\n\t" 10131 "movzbl $dst, $dst\n" 10132 "done:" %} 10133 ins_encode %{ 10134 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10135 emit_cmpfp3(_masm, $dst$$Register); 10136 %} 10137 ins_pipe(pipe_slow); 10138 %} 10139 10140 // Compare into -1,0,1 10141 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10142 match(Set dst (CmpF3 src con)); 10143 effect(KILL cr); 10144 10145 ins_cost(275); 10146 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10147 "movl $dst, #-1\n\t" 10148 "jp,s done\n\t" 10149 "jb,s done\n\t" 10150 "setne $dst\n\t" 10151 "movzbl $dst, $dst\n" 10152 "done:" %} 10153 ins_encode %{ 10154 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10155 emit_cmpfp3(_masm, $dst$$Register); 10156 %} 10157 ins_pipe(pipe_slow); 10158 %} 10159 10160 // Compare into -1,0,1 10161 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10162 %{ 10163 match(Set dst (CmpD3 src1 src2)); 10164 effect(KILL cr); 10165 10166 ins_cost(275); 10167 format %{ "ucomisd $src1, $src2\n\t" 10168 "movl $dst, #-1\n\t" 10169 "jp,s done\n\t" 10170 "jb,s done\n\t" 10171 "setne $dst\n\t" 10172 "movzbl $dst, $dst\n" 10173 "done:" %} 10174 ins_encode %{ 10175 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10176 emit_cmpfp3(_masm, $dst$$Register); 10177 %} 10178 ins_pipe(pipe_slow); 10179 %} 10180 10181 // Compare into -1,0,1 10182 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10183 %{ 10184 match(Set dst (CmpD3 src1 (LoadD src2))); 10185 effect(KILL cr); 10186 10187 ins_cost(275); 10188 format %{ "ucomisd $src1, $src2\n\t" 10189 "movl $dst, #-1\n\t" 10190 "jp,s done\n\t" 10191 "jb,s done\n\t" 10192 "setne $dst\n\t" 10193 "movzbl $dst, $dst\n" 10194 "done:" %} 10195 ins_encode %{ 10196 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10197 emit_cmpfp3(_masm, $dst$$Register); 10198 %} 10199 ins_pipe(pipe_slow); 10200 %} 10201 10202 // Compare into -1,0,1 10203 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10204 match(Set dst (CmpD3 src con)); 10205 effect(KILL cr); 10206 10207 ins_cost(275); 10208 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10209 "movl $dst, #-1\n\t" 10210 "jp,s done\n\t" 10211 "jb,s done\n\t" 10212 "setne $dst\n\t" 10213 "movzbl $dst, $dst\n" 10214 "done:" %} 10215 ins_encode %{ 10216 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10217 emit_cmpfp3(_masm, $dst$$Register); 10218 %} 10219 ins_pipe(pipe_slow); 10220 %} 10221 10222 //----------Arithmetic Conversion Instructions--------------------------------- 10223 10224 instruct roundFloat_nop(regF dst) 10225 %{ 10226 match(Set dst (RoundFloat dst)); 10227 10228 ins_cost(0); 10229 ins_encode(); 10230 ins_pipe(empty); 10231 %} 10232 10233 instruct roundDouble_nop(regD dst) 10234 %{ 10235 match(Set dst (RoundDouble dst)); 10236 10237 ins_cost(0); 10238 ins_encode(); 10239 ins_pipe(empty); 10240 %} 10241 10242 instruct convF2D_reg_reg(regD dst, regF src) 10243 %{ 10244 match(Set dst (ConvF2D src)); 10245 10246 format %{ "cvtss2sd $dst, $src" %} 10247 ins_encode %{ 10248 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10249 %} 10250 ins_pipe(pipe_slow); // XXX 10251 %} 10252 10253 instruct convF2D_reg_mem(regD dst, memory src) 10254 %{ 10255 match(Set dst (ConvF2D (LoadF src))); 10256 10257 format %{ "cvtss2sd $dst, $src" %} 10258 ins_encode %{ 10259 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10260 %} 10261 ins_pipe(pipe_slow); // XXX 10262 %} 10263 10264 instruct convD2F_reg_reg(regF dst, regD src) 10265 %{ 10266 match(Set dst (ConvD2F src)); 10267 10268 format %{ "cvtsd2ss $dst, $src" %} 10269 ins_encode %{ 10270 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10271 %} 10272 ins_pipe(pipe_slow); // XXX 10273 %} 10274 10275 instruct convD2F_reg_mem(regF dst, memory src) 10276 %{ 10277 match(Set dst (ConvD2F (LoadD src))); 10278 10279 format %{ "cvtsd2ss $dst, $src" %} 10280 ins_encode %{ 10281 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10282 %} 10283 ins_pipe(pipe_slow); // XXX 10284 %} 10285 10286 // XXX do mem variants 10287 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10288 %{ 10289 match(Set dst (ConvF2I src)); 10290 effect(KILL cr); 10291 10292 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10293 "cmpl $dst, #0x80000000\n\t" 10294 "jne,s done\n\t" 10295 "subq rsp, #8\n\t" 10296 "movss [rsp], $src\n\t" 10297 "call f2i_fixup\n\t" 10298 "popq $dst\n" 10299 "done: "%} 10300 ins_encode %{ 10301 Label done; 10302 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10303 __ cmpl($dst$$Register, 0x80000000); 10304 __ jccb(Assembler::notEqual, done); 10305 __ subptr(rsp, 8); 10306 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10307 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10308 __ pop($dst$$Register); 10309 __ bind(done); 10310 %} 10311 ins_pipe(pipe_slow); 10312 %} 10313 10314 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10315 %{ 10316 match(Set dst (ConvF2L src)); 10317 effect(KILL cr); 10318 10319 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10320 "cmpq $dst, [0x8000000000000000]\n\t" 10321 "jne,s done\n\t" 10322 "subq rsp, #8\n\t" 10323 "movss [rsp], $src\n\t" 10324 "call f2l_fixup\n\t" 10325 "popq $dst\n" 10326 "done: "%} 10327 ins_encode %{ 10328 Label done; 10329 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10330 __ cmp64($dst$$Register, 10331 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10332 __ jccb(Assembler::notEqual, done); 10333 __ subptr(rsp, 8); 10334 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10335 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10336 __ pop($dst$$Register); 10337 __ bind(done); 10338 %} 10339 ins_pipe(pipe_slow); 10340 %} 10341 10342 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10343 %{ 10344 match(Set dst (ConvD2I src)); 10345 effect(KILL cr); 10346 10347 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10348 "cmpl $dst, #0x80000000\n\t" 10349 "jne,s done\n\t" 10350 "subq rsp, #8\n\t" 10351 "movsd [rsp], $src\n\t" 10352 "call d2i_fixup\n\t" 10353 "popq $dst\n" 10354 "done: "%} 10355 ins_encode %{ 10356 Label done; 10357 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10358 __ cmpl($dst$$Register, 0x80000000); 10359 __ jccb(Assembler::notEqual, done); 10360 __ subptr(rsp, 8); 10361 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10362 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10363 __ pop($dst$$Register); 10364 __ bind(done); 10365 %} 10366 ins_pipe(pipe_slow); 10367 %} 10368 10369 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10370 %{ 10371 match(Set dst (ConvD2L src)); 10372 effect(KILL cr); 10373 10374 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10375 "cmpq $dst, [0x8000000000000000]\n\t" 10376 "jne,s done\n\t" 10377 "subq rsp, #8\n\t" 10378 "movsd [rsp], $src\n\t" 10379 "call d2l_fixup\n\t" 10380 "popq $dst\n" 10381 "done: "%} 10382 ins_encode %{ 10383 Label done; 10384 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10385 __ cmp64($dst$$Register, 10386 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10387 __ jccb(Assembler::notEqual, done); 10388 __ subptr(rsp, 8); 10389 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10390 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10391 __ pop($dst$$Register); 10392 __ bind(done); 10393 %} 10394 ins_pipe(pipe_slow); 10395 %} 10396 10397 instruct convI2F_reg_reg(regF dst, rRegI src) 10398 %{ 10399 predicate(!UseXmmI2F); 10400 match(Set dst (ConvI2F src)); 10401 10402 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10403 ins_encode %{ 10404 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10405 %} 10406 ins_pipe(pipe_slow); // XXX 10407 %} 10408 10409 instruct convI2F_reg_mem(regF dst, memory src) 10410 %{ 10411 match(Set dst (ConvI2F (LoadI src))); 10412 10413 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10414 ins_encode %{ 10415 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10416 %} 10417 ins_pipe(pipe_slow); // XXX 10418 %} 10419 10420 instruct convI2D_reg_reg(regD dst, rRegI src) 10421 %{ 10422 predicate(!UseXmmI2D); 10423 match(Set dst (ConvI2D src)); 10424 10425 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10426 ins_encode %{ 10427 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10428 %} 10429 ins_pipe(pipe_slow); // XXX 10430 %} 10431 10432 instruct convI2D_reg_mem(regD dst, memory src) 10433 %{ 10434 match(Set dst (ConvI2D (LoadI src))); 10435 10436 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10437 ins_encode %{ 10438 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10439 %} 10440 ins_pipe(pipe_slow); // XXX 10441 %} 10442 10443 instruct convXI2F_reg(regF dst, rRegI src) 10444 %{ 10445 predicate(UseXmmI2F); 10446 match(Set dst (ConvI2F src)); 10447 10448 format %{ "movdl $dst, $src\n\t" 10449 "cvtdq2psl $dst, $dst\t# i2f" %} 10450 ins_encode %{ 10451 __ movdl($dst$$XMMRegister, $src$$Register); 10452 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10453 %} 10454 ins_pipe(pipe_slow); // XXX 10455 %} 10456 10457 instruct convXI2D_reg(regD dst, rRegI src) 10458 %{ 10459 predicate(UseXmmI2D); 10460 match(Set dst (ConvI2D src)); 10461 10462 format %{ "movdl $dst, $src\n\t" 10463 "cvtdq2pdl $dst, $dst\t# i2d" %} 10464 ins_encode %{ 10465 __ movdl($dst$$XMMRegister, $src$$Register); 10466 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10467 %} 10468 ins_pipe(pipe_slow); // XXX 10469 %} 10470 10471 instruct convL2F_reg_reg(regF dst, rRegL src) 10472 %{ 10473 match(Set dst (ConvL2F src)); 10474 10475 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10476 ins_encode %{ 10477 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10478 %} 10479 ins_pipe(pipe_slow); // XXX 10480 %} 10481 10482 instruct convL2F_reg_mem(regF dst, memory src) 10483 %{ 10484 match(Set dst (ConvL2F (LoadL src))); 10485 10486 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10487 ins_encode %{ 10488 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10489 %} 10490 ins_pipe(pipe_slow); // XXX 10491 %} 10492 10493 instruct convL2D_reg_reg(regD dst, rRegL src) 10494 %{ 10495 match(Set dst (ConvL2D src)); 10496 10497 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10498 ins_encode %{ 10499 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10500 %} 10501 ins_pipe(pipe_slow); // XXX 10502 %} 10503 10504 instruct convL2D_reg_mem(regD dst, memory src) 10505 %{ 10506 match(Set dst (ConvL2D (LoadL src))); 10507 10508 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10509 ins_encode %{ 10510 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10511 %} 10512 ins_pipe(pipe_slow); // XXX 10513 %} 10514 10515 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10516 %{ 10517 match(Set dst (ConvI2L src)); 10518 10519 ins_cost(125); 10520 format %{ "movslq $dst, $src\t# i2l" %} 10521 ins_encode %{ 10522 __ movslq($dst$$Register, $src$$Register); 10523 %} 10524 ins_pipe(ialu_reg_reg); 10525 %} 10526 10527 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10528 // %{ 10529 // match(Set dst (ConvI2L src)); 10530 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10531 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10532 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10533 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10534 // ((const TypeNode*) n)->type()->is_long()->_lo == 10535 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10536 10537 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10538 // ins_encode(enc_copy(dst, src)); 10539 // // opcode(0x63); // needs REX.W 10540 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10541 // ins_pipe(ialu_reg_reg); 10542 // %} 10543 10544 // Zero-extend convert int to long 10545 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10546 %{ 10547 match(Set dst (AndL (ConvI2L src) mask)); 10548 10549 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10550 ins_encode %{ 10551 if ($dst$$reg != $src$$reg) { 10552 __ movl($dst$$Register, $src$$Register); 10553 } 10554 %} 10555 ins_pipe(ialu_reg_reg); 10556 %} 10557 10558 // Zero-extend convert int to long 10559 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10560 %{ 10561 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10562 10563 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10564 ins_encode %{ 10565 __ movl($dst$$Register, $src$$Address); 10566 %} 10567 ins_pipe(ialu_reg_mem); 10568 %} 10569 10570 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10571 %{ 10572 match(Set dst (AndL src mask)); 10573 10574 format %{ "movl $dst, $src\t# zero-extend long" %} 10575 ins_encode %{ 10576 __ movl($dst$$Register, $src$$Register); 10577 %} 10578 ins_pipe(ialu_reg_reg); 10579 %} 10580 10581 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10582 %{ 10583 match(Set dst (ConvL2I src)); 10584 10585 format %{ "movl $dst, $src\t# l2i" %} 10586 ins_encode %{ 10587 __ movl($dst$$Register, $src$$Register); 10588 %} 10589 ins_pipe(ialu_reg_reg); 10590 %} 10591 10592 10593 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10594 match(Set dst (MoveF2I src)); 10595 effect(DEF dst, USE src); 10596 10597 ins_cost(125); 10598 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10599 ins_encode %{ 10600 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10601 %} 10602 ins_pipe(ialu_reg_mem); 10603 %} 10604 10605 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10606 match(Set dst (MoveI2F src)); 10607 effect(DEF dst, USE src); 10608 10609 ins_cost(125); 10610 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10611 ins_encode %{ 10612 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10613 %} 10614 ins_pipe(pipe_slow); 10615 %} 10616 10617 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10618 match(Set dst (MoveD2L src)); 10619 effect(DEF dst, USE src); 10620 10621 ins_cost(125); 10622 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10623 ins_encode %{ 10624 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10625 %} 10626 ins_pipe(ialu_reg_mem); 10627 %} 10628 10629 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10630 predicate(!UseXmmLoadAndClearUpper); 10631 match(Set dst (MoveL2D src)); 10632 effect(DEF dst, USE src); 10633 10634 ins_cost(125); 10635 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10636 ins_encode %{ 10637 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10638 %} 10639 ins_pipe(pipe_slow); 10640 %} 10641 10642 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10643 predicate(UseXmmLoadAndClearUpper); 10644 match(Set dst (MoveL2D src)); 10645 effect(DEF dst, USE src); 10646 10647 ins_cost(125); 10648 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10649 ins_encode %{ 10650 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10651 %} 10652 ins_pipe(pipe_slow); 10653 %} 10654 10655 10656 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10657 match(Set dst (MoveF2I src)); 10658 effect(DEF dst, USE src); 10659 10660 ins_cost(95); // XXX 10661 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10662 ins_encode %{ 10663 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10664 %} 10665 ins_pipe(pipe_slow); 10666 %} 10667 10668 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10669 match(Set dst (MoveI2F src)); 10670 effect(DEF dst, USE src); 10671 10672 ins_cost(100); 10673 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10674 ins_encode %{ 10675 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10676 %} 10677 ins_pipe( ialu_mem_reg ); 10678 %} 10679 10680 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10681 match(Set dst (MoveD2L src)); 10682 effect(DEF dst, USE src); 10683 10684 ins_cost(95); // XXX 10685 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10686 ins_encode %{ 10687 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10688 %} 10689 ins_pipe(pipe_slow); 10690 %} 10691 10692 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10693 match(Set dst (MoveL2D src)); 10694 effect(DEF dst, USE src); 10695 10696 ins_cost(100); 10697 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10698 ins_encode %{ 10699 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10700 %} 10701 ins_pipe(ialu_mem_reg); 10702 %} 10703 10704 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10705 match(Set dst (MoveF2I src)); 10706 effect(DEF dst, USE src); 10707 ins_cost(85); 10708 format %{ "movd $dst,$src\t# MoveF2I" %} 10709 ins_encode %{ 10710 __ movdl($dst$$Register, $src$$XMMRegister); 10711 %} 10712 ins_pipe( pipe_slow ); 10713 %} 10714 10715 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10716 match(Set dst (MoveD2L src)); 10717 effect(DEF dst, USE src); 10718 ins_cost(85); 10719 format %{ "movd $dst,$src\t# MoveD2L" %} 10720 ins_encode %{ 10721 __ movdq($dst$$Register, $src$$XMMRegister); 10722 %} 10723 ins_pipe( pipe_slow ); 10724 %} 10725 10726 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10727 match(Set dst (MoveI2F src)); 10728 effect(DEF dst, USE src); 10729 ins_cost(100); 10730 format %{ "movd $dst,$src\t# MoveI2F" %} 10731 ins_encode %{ 10732 __ movdl($dst$$XMMRegister, $src$$Register); 10733 %} 10734 ins_pipe( pipe_slow ); 10735 %} 10736 10737 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10738 match(Set dst (MoveL2D src)); 10739 effect(DEF dst, USE src); 10740 ins_cost(100); 10741 format %{ "movd $dst,$src\t# MoveL2D" %} 10742 ins_encode %{ 10743 __ movdq($dst$$XMMRegister, $src$$Register); 10744 %} 10745 ins_pipe( pipe_slow ); 10746 %} 10747 10748 10749 // ======================================================================= 10750 // fast clearing of an array 10751 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10752 Universe dummy, rFlagsReg cr) 10753 %{ 10754 predicate(!((ClearArrayNode*)n)->is_large()); 10755 match(Set dummy (ClearArray cnt base)); 10756 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10757 10758 format %{ $$template 10759 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10760 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10761 $$emit$$"jg LARGE\n\t" 10762 $$emit$$"dec rcx\n\t" 10763 $$emit$$"js DONE\t# Zero length\n\t" 10764 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10765 $$emit$$"dec rcx\n\t" 10766 $$emit$$"jge LOOP\n\t" 10767 $$emit$$"jmp DONE\n\t" 10768 $$emit$$"# LARGE:\n\t" 10769 if (UseFastStosb) { 10770 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10771 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10772 } else if (UseXMMForObjInit) { 10773 $$emit$$"mov rdi,rax\n\t" 10774 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10775 $$emit$$"jmpq L_zero_64_bytes\n\t" 10776 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10777 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10778 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10779 $$emit$$"add 0x40,rax\n\t" 10780 $$emit$$"# L_zero_64_bytes:\n\t" 10781 $$emit$$"sub 0x8,rcx\n\t" 10782 $$emit$$"jge L_loop\n\t" 10783 $$emit$$"add 0x4,rcx\n\t" 10784 $$emit$$"jl L_tail\n\t" 10785 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10786 $$emit$$"add 0x20,rax\n\t" 10787 $$emit$$"sub 0x4,rcx\n\t" 10788 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10789 $$emit$$"add 0x4,rcx\n\t" 10790 $$emit$$"jle L_end\n\t" 10791 $$emit$$"dec rcx\n\t" 10792 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10793 $$emit$$"vmovq xmm0,(rax)\n\t" 10794 $$emit$$"add 0x8,rax\n\t" 10795 $$emit$$"dec rcx\n\t" 10796 $$emit$$"jge L_sloop\n\t" 10797 $$emit$$"# L_end:\n\t" 10798 } else { 10799 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10800 } 10801 $$emit$$"# DONE" 10802 %} 10803 ins_encode %{ 10804 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10805 $tmp$$XMMRegister, false); 10806 %} 10807 ins_pipe(pipe_slow); 10808 %} 10809 10810 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10811 Universe dummy, rFlagsReg cr) 10812 %{ 10813 predicate(((ClearArrayNode*)n)->is_large()); 10814 match(Set dummy (ClearArray cnt base)); 10815 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10816 10817 format %{ $$template 10818 if (UseFastStosb) { 10819 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10820 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10821 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10822 } else if (UseXMMForObjInit) { 10823 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10824 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10825 $$emit$$"jmpq L_zero_64_bytes\n\t" 10826 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10827 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10828 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10829 $$emit$$"add 0x40,rax\n\t" 10830 $$emit$$"# L_zero_64_bytes:\n\t" 10831 $$emit$$"sub 0x8,rcx\n\t" 10832 $$emit$$"jge L_loop\n\t" 10833 $$emit$$"add 0x4,rcx\n\t" 10834 $$emit$$"jl L_tail\n\t" 10835 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10836 $$emit$$"add 0x20,rax\n\t" 10837 $$emit$$"sub 0x4,rcx\n\t" 10838 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10839 $$emit$$"add 0x4,rcx\n\t" 10840 $$emit$$"jle L_end\n\t" 10841 $$emit$$"dec rcx\n\t" 10842 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10843 $$emit$$"vmovq xmm0,(rax)\n\t" 10844 $$emit$$"add 0x8,rax\n\t" 10845 $$emit$$"dec rcx\n\t" 10846 $$emit$$"jge L_sloop\n\t" 10847 $$emit$$"# L_end:\n\t" 10848 } else { 10849 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10850 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10851 } 10852 %} 10853 ins_encode %{ 10854 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10855 $tmp$$XMMRegister, true); 10856 %} 10857 ins_pipe(pipe_slow); 10858 %} 10859 10860 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10861 rax_RegI result, regD tmp1, rFlagsReg cr) 10862 %{ 10863 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10864 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10865 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10866 10867 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10868 ins_encode %{ 10869 __ string_compare($str1$$Register, $str2$$Register, 10870 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10871 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 10872 %} 10873 ins_pipe( pipe_slow ); 10874 %} 10875 10876 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10877 rax_RegI result, regD tmp1, rFlagsReg cr) 10878 %{ 10879 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10880 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10881 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10882 10883 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10884 ins_encode %{ 10885 __ string_compare($str1$$Register, $str2$$Register, 10886 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10887 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 10888 %} 10889 ins_pipe( pipe_slow ); 10890 %} 10891 10892 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10893 rax_RegI result, regD tmp1, rFlagsReg cr) 10894 %{ 10895 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10896 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10897 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10898 10899 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10900 ins_encode %{ 10901 __ string_compare($str1$$Register, $str2$$Register, 10902 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10903 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 10904 %} 10905 ins_pipe( pipe_slow ); 10906 %} 10907 10908 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10909 rax_RegI result, regD tmp1, rFlagsReg cr) 10910 %{ 10911 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10912 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10913 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10914 10915 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10916 ins_encode %{ 10917 __ string_compare($str2$$Register, $str1$$Register, 10918 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10919 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 10920 %} 10921 ins_pipe( pipe_slow ); 10922 %} 10923 10924 // fast search of substring with known size. 10925 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10926 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10927 %{ 10928 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10929 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10930 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10931 10932 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10933 ins_encode %{ 10934 int icnt2 = (int)$int_cnt2$$constant; 10935 if (icnt2 >= 16) { 10936 // IndexOf for constant substrings with size >= 16 elements 10937 // which don't need to be loaded through stack. 10938 __ string_indexofC8($str1$$Register, $str2$$Register, 10939 $cnt1$$Register, $cnt2$$Register, 10940 icnt2, $result$$Register, 10941 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10942 } else { 10943 // Small strings are loaded through stack if they cross page boundary. 10944 __ string_indexof($str1$$Register, $str2$$Register, 10945 $cnt1$$Register, $cnt2$$Register, 10946 icnt2, $result$$Register, 10947 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10948 } 10949 %} 10950 ins_pipe( pipe_slow ); 10951 %} 10952 10953 // fast search of substring with known size. 10954 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10955 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10956 %{ 10957 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10958 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10959 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10960 10961 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10962 ins_encode %{ 10963 int icnt2 = (int)$int_cnt2$$constant; 10964 if (icnt2 >= 8) { 10965 // IndexOf for constant substrings with size >= 8 elements 10966 // which don't need to be loaded through stack. 10967 __ string_indexofC8($str1$$Register, $str2$$Register, 10968 $cnt1$$Register, $cnt2$$Register, 10969 icnt2, $result$$Register, 10970 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10971 } else { 10972 // Small strings are loaded through stack if they cross page boundary. 10973 __ string_indexof($str1$$Register, $str2$$Register, 10974 $cnt1$$Register, $cnt2$$Register, 10975 icnt2, $result$$Register, 10976 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10977 } 10978 %} 10979 ins_pipe( pipe_slow ); 10980 %} 10981 10982 // fast search of substring with known size. 10983 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10984 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10985 %{ 10986 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10987 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10988 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10989 10990 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10991 ins_encode %{ 10992 int icnt2 = (int)$int_cnt2$$constant; 10993 if (icnt2 >= 8) { 10994 // IndexOf for constant substrings with size >= 8 elements 10995 // which don't need to be loaded through stack. 10996 __ string_indexofC8($str1$$Register, $str2$$Register, 10997 $cnt1$$Register, $cnt2$$Register, 10998 icnt2, $result$$Register, 10999 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11000 } else { 11001 // Small strings are loaded through stack if they cross page boundary. 11002 __ string_indexof($str1$$Register, $str2$$Register, 11003 $cnt1$$Register, $cnt2$$Register, 11004 icnt2, $result$$Register, 11005 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11006 } 11007 %} 11008 ins_pipe( pipe_slow ); 11009 %} 11010 11011 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11012 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11013 %{ 11014 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11015 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11016 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11017 11018 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11019 ins_encode %{ 11020 __ string_indexof($str1$$Register, $str2$$Register, 11021 $cnt1$$Register, $cnt2$$Register, 11022 (-1), $result$$Register, 11023 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11024 %} 11025 ins_pipe( pipe_slow ); 11026 %} 11027 11028 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11029 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11030 %{ 11031 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11032 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11033 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11034 11035 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11036 ins_encode %{ 11037 __ string_indexof($str1$$Register, $str2$$Register, 11038 $cnt1$$Register, $cnt2$$Register, 11039 (-1), $result$$Register, 11040 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11041 %} 11042 ins_pipe( pipe_slow ); 11043 %} 11044 11045 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11046 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11047 %{ 11048 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11049 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11050 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11051 11052 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11053 ins_encode %{ 11054 __ string_indexof($str1$$Register, $str2$$Register, 11055 $cnt1$$Register, $cnt2$$Register, 11056 (-1), $result$$Register, 11057 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11058 %} 11059 ins_pipe( pipe_slow ); 11060 %} 11061 11062 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11063 rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr) 11064 %{ 11065 predicate(UseSSE42Intrinsics); 11066 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11067 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11068 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11069 ins_encode %{ 11070 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11071 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11072 %} 11073 ins_pipe( pipe_slow ); 11074 %} 11075 11076 // fast string equals 11077 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11078 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11079 %{ 11080 match(Set result (StrEquals (Binary str1 str2) cnt)); 11081 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11082 11083 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11084 ins_encode %{ 11085 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11086 $cnt$$Register, $result$$Register, $tmp3$$Register, 11087 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11088 %} 11089 ins_pipe( pipe_slow ); 11090 %} 11091 11092 // fast array equals 11093 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11094 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11095 %{ 11096 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11097 match(Set result (AryEq ary1 ary2)); 11098 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11099 11100 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11101 ins_encode %{ 11102 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11103 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11104 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11105 %} 11106 ins_pipe( pipe_slow ); 11107 %} 11108 11109 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11110 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11111 %{ 11112 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11113 match(Set result (AryEq ary1 ary2)); 11114 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11115 11116 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11117 ins_encode %{ 11118 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11119 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11120 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11121 %} 11122 ins_pipe( pipe_slow ); 11123 %} 11124 11125 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11126 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11127 %{ 11128 match(Set result (HasNegatives ary1 len)); 11129 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11130 11131 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11132 ins_encode %{ 11133 __ has_negatives($ary1$$Register, $len$$Register, 11134 $result$$Register, $tmp3$$Register, 11135 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11136 %} 11137 ins_pipe( pipe_slow ); 11138 %} 11139 11140 // fast char[] to byte[] compression 11141 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11142 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11143 match(Set result (StrCompressedCopy src (Binary dst len))); 11144 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11145 11146 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11147 ins_encode %{ 11148 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11149 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11150 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11151 %} 11152 ins_pipe( pipe_slow ); 11153 %} 11154 11155 // fast byte[] to char[] inflation 11156 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11157 regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11158 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11159 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11160 11161 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11162 ins_encode %{ 11163 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11164 $tmp1$$XMMRegister, $tmp2$$Register); 11165 %} 11166 ins_pipe( pipe_slow ); 11167 %} 11168 11169 // encode char[] to byte[] in ISO_8859_1 11170 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11171 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11172 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11173 match(Set result (EncodeISOArray src (Binary dst len))); 11174 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11175 11176 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11177 ins_encode %{ 11178 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11179 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11180 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11181 %} 11182 ins_pipe( pipe_slow ); 11183 %} 11184 11185 //----------Overflow Math Instructions----------------------------------------- 11186 11187 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11188 %{ 11189 match(Set cr (OverflowAddI op1 op2)); 11190 effect(DEF cr, USE_KILL op1, USE op2); 11191 11192 format %{ "addl $op1, $op2\t# overflow check int" %} 11193 11194 ins_encode %{ 11195 __ addl($op1$$Register, $op2$$Register); 11196 %} 11197 ins_pipe(ialu_reg_reg); 11198 %} 11199 11200 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11201 %{ 11202 match(Set cr (OverflowAddI op1 op2)); 11203 effect(DEF cr, USE_KILL op1, USE op2); 11204 11205 format %{ "addl $op1, $op2\t# overflow check int" %} 11206 11207 ins_encode %{ 11208 __ addl($op1$$Register, $op2$$constant); 11209 %} 11210 ins_pipe(ialu_reg_reg); 11211 %} 11212 11213 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11214 %{ 11215 match(Set cr (OverflowAddL op1 op2)); 11216 effect(DEF cr, USE_KILL op1, USE op2); 11217 11218 format %{ "addq $op1, $op2\t# overflow check long" %} 11219 ins_encode %{ 11220 __ addq($op1$$Register, $op2$$Register); 11221 %} 11222 ins_pipe(ialu_reg_reg); 11223 %} 11224 11225 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11226 %{ 11227 match(Set cr (OverflowAddL op1 op2)); 11228 effect(DEF cr, USE_KILL op1, USE op2); 11229 11230 format %{ "addq $op1, $op2\t# overflow check long" %} 11231 ins_encode %{ 11232 __ addq($op1$$Register, $op2$$constant); 11233 %} 11234 ins_pipe(ialu_reg_reg); 11235 %} 11236 11237 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11238 %{ 11239 match(Set cr (OverflowSubI op1 op2)); 11240 11241 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11242 ins_encode %{ 11243 __ cmpl($op1$$Register, $op2$$Register); 11244 %} 11245 ins_pipe(ialu_reg_reg); 11246 %} 11247 11248 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11249 %{ 11250 match(Set cr (OverflowSubI op1 op2)); 11251 11252 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11253 ins_encode %{ 11254 __ cmpl($op1$$Register, $op2$$constant); 11255 %} 11256 ins_pipe(ialu_reg_reg); 11257 %} 11258 11259 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11260 %{ 11261 match(Set cr (OverflowSubL op1 op2)); 11262 11263 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11264 ins_encode %{ 11265 __ cmpq($op1$$Register, $op2$$Register); 11266 %} 11267 ins_pipe(ialu_reg_reg); 11268 %} 11269 11270 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11271 %{ 11272 match(Set cr (OverflowSubL op1 op2)); 11273 11274 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11275 ins_encode %{ 11276 __ cmpq($op1$$Register, $op2$$constant); 11277 %} 11278 ins_pipe(ialu_reg_reg); 11279 %} 11280 11281 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11282 %{ 11283 match(Set cr (OverflowSubI zero op2)); 11284 effect(DEF cr, USE_KILL op2); 11285 11286 format %{ "negl $op2\t# overflow check int" %} 11287 ins_encode %{ 11288 __ negl($op2$$Register); 11289 %} 11290 ins_pipe(ialu_reg_reg); 11291 %} 11292 11293 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11294 %{ 11295 match(Set cr (OverflowSubL zero op2)); 11296 effect(DEF cr, USE_KILL op2); 11297 11298 format %{ "negq $op2\t# overflow check long" %} 11299 ins_encode %{ 11300 __ negq($op2$$Register); 11301 %} 11302 ins_pipe(ialu_reg_reg); 11303 %} 11304 11305 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11306 %{ 11307 match(Set cr (OverflowMulI op1 op2)); 11308 effect(DEF cr, USE_KILL op1, USE op2); 11309 11310 format %{ "imull $op1, $op2\t# overflow check int" %} 11311 ins_encode %{ 11312 __ imull($op1$$Register, $op2$$Register); 11313 %} 11314 ins_pipe(ialu_reg_reg_alu0); 11315 %} 11316 11317 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11318 %{ 11319 match(Set cr (OverflowMulI op1 op2)); 11320 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11321 11322 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11323 ins_encode %{ 11324 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11325 %} 11326 ins_pipe(ialu_reg_reg_alu0); 11327 %} 11328 11329 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11330 %{ 11331 match(Set cr (OverflowMulL op1 op2)); 11332 effect(DEF cr, USE_KILL op1, USE op2); 11333 11334 format %{ "imulq $op1, $op2\t# overflow check long" %} 11335 ins_encode %{ 11336 __ imulq($op1$$Register, $op2$$Register); 11337 %} 11338 ins_pipe(ialu_reg_reg_alu0); 11339 %} 11340 11341 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11342 %{ 11343 match(Set cr (OverflowMulL op1 op2)); 11344 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11345 11346 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11347 ins_encode %{ 11348 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11349 %} 11350 ins_pipe(ialu_reg_reg_alu0); 11351 %} 11352 11353 11354 //----------Control Flow Instructions------------------------------------------ 11355 // Signed compare Instructions 11356 11357 // XXX more variants!! 11358 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11359 %{ 11360 match(Set cr (CmpI op1 op2)); 11361 effect(DEF cr, USE op1, USE op2); 11362 11363 format %{ "cmpl $op1, $op2" %} 11364 opcode(0x3B); /* Opcode 3B /r */ 11365 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11366 ins_pipe(ialu_cr_reg_reg); 11367 %} 11368 11369 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11370 %{ 11371 match(Set cr (CmpI op1 op2)); 11372 11373 format %{ "cmpl $op1, $op2" %} 11374 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11375 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11376 ins_pipe(ialu_cr_reg_imm); 11377 %} 11378 11379 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11380 %{ 11381 match(Set cr (CmpI op1 (LoadI op2))); 11382 11383 ins_cost(500); // XXX 11384 format %{ "cmpl $op1, $op2" %} 11385 opcode(0x3B); /* Opcode 3B /r */ 11386 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11387 ins_pipe(ialu_cr_reg_mem); 11388 %} 11389 11390 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11391 %{ 11392 match(Set cr (CmpI src zero)); 11393 11394 format %{ "testl $src, $src" %} 11395 opcode(0x85); 11396 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11397 ins_pipe(ialu_cr_reg_imm); 11398 %} 11399 11400 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11401 %{ 11402 match(Set cr (CmpI (AndI src con) zero)); 11403 11404 format %{ "testl $src, $con" %} 11405 opcode(0xF7, 0x00); 11406 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11407 ins_pipe(ialu_cr_reg_imm); 11408 %} 11409 11410 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11411 %{ 11412 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11413 11414 format %{ "testl $src, $mem" %} 11415 opcode(0x85); 11416 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11417 ins_pipe(ialu_cr_reg_mem); 11418 %} 11419 11420 // Unsigned compare Instructions; really, same as signed except they 11421 // produce an rFlagsRegU instead of rFlagsReg. 11422 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11423 %{ 11424 match(Set cr (CmpU op1 op2)); 11425 11426 format %{ "cmpl $op1, $op2\t# unsigned" %} 11427 opcode(0x3B); /* Opcode 3B /r */ 11428 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11429 ins_pipe(ialu_cr_reg_reg); 11430 %} 11431 11432 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11433 %{ 11434 match(Set cr (CmpU op1 op2)); 11435 11436 format %{ "cmpl $op1, $op2\t# unsigned" %} 11437 opcode(0x81,0x07); /* Opcode 81 /7 */ 11438 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11439 ins_pipe(ialu_cr_reg_imm); 11440 %} 11441 11442 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11443 %{ 11444 match(Set cr (CmpU op1 (LoadI op2))); 11445 11446 ins_cost(500); // XXX 11447 format %{ "cmpl $op1, $op2\t# unsigned" %} 11448 opcode(0x3B); /* Opcode 3B /r */ 11449 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11450 ins_pipe(ialu_cr_reg_mem); 11451 %} 11452 11453 // // // Cisc-spilled version of cmpU_rReg 11454 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11455 // //%{ 11456 // // match(Set cr (CmpU (LoadI op1) op2)); 11457 // // 11458 // // format %{ "CMPu $op1,$op2" %} 11459 // // ins_cost(500); 11460 // // opcode(0x39); /* Opcode 39 /r */ 11461 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11462 // //%} 11463 11464 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11465 %{ 11466 match(Set cr (CmpU src zero)); 11467 11468 format %{ "testl $src, $src\t# unsigned" %} 11469 opcode(0x85); 11470 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11471 ins_pipe(ialu_cr_reg_imm); 11472 %} 11473 11474 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11475 %{ 11476 match(Set cr (CmpP op1 op2)); 11477 11478 format %{ "cmpq $op1, $op2\t# ptr" %} 11479 opcode(0x3B); /* Opcode 3B /r */ 11480 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11481 ins_pipe(ialu_cr_reg_reg); 11482 %} 11483 11484 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11485 %{ 11486 match(Set cr (CmpP op1 (LoadP op2))); 11487 11488 ins_cost(500); // XXX 11489 format %{ "cmpq $op1, $op2\t# ptr" %} 11490 opcode(0x3B); /* Opcode 3B /r */ 11491 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11492 ins_pipe(ialu_cr_reg_mem); 11493 %} 11494 11495 // // // Cisc-spilled version of cmpP_rReg 11496 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11497 // //%{ 11498 // // match(Set cr (CmpP (LoadP op1) op2)); 11499 // // 11500 // // format %{ "CMPu $op1,$op2" %} 11501 // // ins_cost(500); 11502 // // opcode(0x39); /* Opcode 39 /r */ 11503 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11504 // //%} 11505 11506 // XXX this is generalized by compP_rReg_mem??? 11507 // Compare raw pointer (used in out-of-heap check). 11508 // Only works because non-oop pointers must be raw pointers 11509 // and raw pointers have no anti-dependencies. 11510 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11511 %{ 11512 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11513 match(Set cr (CmpP op1 (LoadP op2))); 11514 11515 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11516 opcode(0x3B); /* Opcode 3B /r */ 11517 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11518 ins_pipe(ialu_cr_reg_mem); 11519 %} 11520 11521 // This will generate a signed flags result. This should be OK since 11522 // any compare to a zero should be eq/neq. 11523 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11524 %{ 11525 match(Set cr (CmpP src zero)); 11526 11527 format %{ "testq $src, $src\t# ptr" %} 11528 opcode(0x85); 11529 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11530 ins_pipe(ialu_cr_reg_imm); 11531 %} 11532 11533 // This will generate a signed flags result. This should be OK since 11534 // any compare to a zero should be eq/neq. 11535 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11536 %{ 11537 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11538 match(Set cr (CmpP (LoadP op) zero)); 11539 11540 ins_cost(500); // XXX 11541 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11542 opcode(0xF7); /* Opcode F7 /0 */ 11543 ins_encode(REX_mem_wide(op), 11544 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11545 ins_pipe(ialu_cr_reg_imm); 11546 %} 11547 11548 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11549 %{ 11550 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11551 match(Set cr (CmpP (LoadP mem) zero)); 11552 11553 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11554 ins_encode %{ 11555 __ cmpq(r12, $mem$$Address); 11556 %} 11557 ins_pipe(ialu_cr_reg_mem); 11558 %} 11559 11560 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11561 %{ 11562 match(Set cr (CmpN op1 op2)); 11563 11564 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11565 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11566 ins_pipe(ialu_cr_reg_reg); 11567 %} 11568 11569 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11570 %{ 11571 match(Set cr (CmpN src (LoadN mem))); 11572 11573 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11574 ins_encode %{ 11575 __ cmpl($src$$Register, $mem$$Address); 11576 %} 11577 ins_pipe(ialu_cr_reg_mem); 11578 %} 11579 11580 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11581 match(Set cr (CmpN op1 op2)); 11582 11583 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11584 ins_encode %{ 11585 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11586 %} 11587 ins_pipe(ialu_cr_reg_imm); 11588 %} 11589 11590 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11591 %{ 11592 match(Set cr (CmpN src (LoadN mem))); 11593 11594 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11595 ins_encode %{ 11596 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11597 %} 11598 ins_pipe(ialu_cr_reg_mem); 11599 %} 11600 11601 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11602 match(Set cr (CmpN op1 op2)); 11603 11604 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11605 ins_encode %{ 11606 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11607 %} 11608 ins_pipe(ialu_cr_reg_imm); 11609 %} 11610 11611 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11612 %{ 11613 match(Set cr (CmpN src (LoadNKlass mem))); 11614 11615 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11616 ins_encode %{ 11617 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11618 %} 11619 ins_pipe(ialu_cr_reg_mem); 11620 %} 11621 11622 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11623 match(Set cr (CmpN src zero)); 11624 11625 format %{ "testl $src, $src\t# compressed ptr" %} 11626 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11627 ins_pipe(ialu_cr_reg_imm); 11628 %} 11629 11630 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11631 %{ 11632 predicate(Universe::narrow_oop_base() != NULL); 11633 match(Set cr (CmpN (LoadN mem) zero)); 11634 11635 ins_cost(500); // XXX 11636 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11637 ins_encode %{ 11638 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11639 %} 11640 ins_pipe(ialu_cr_reg_mem); 11641 %} 11642 11643 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11644 %{ 11645 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11646 match(Set cr (CmpN (LoadN mem) zero)); 11647 11648 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11649 ins_encode %{ 11650 __ cmpl(r12, $mem$$Address); 11651 %} 11652 ins_pipe(ialu_cr_reg_mem); 11653 %} 11654 11655 // Yanked all unsigned pointer compare operations. 11656 // Pointer compares are done with CmpP which is already unsigned. 11657 11658 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11659 %{ 11660 match(Set cr (CmpL op1 op2)); 11661 11662 format %{ "cmpq $op1, $op2" %} 11663 opcode(0x3B); /* Opcode 3B /r */ 11664 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11665 ins_pipe(ialu_cr_reg_reg); 11666 %} 11667 11668 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11669 %{ 11670 match(Set cr (CmpL op1 op2)); 11671 11672 format %{ "cmpq $op1, $op2" %} 11673 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11674 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11675 ins_pipe(ialu_cr_reg_imm); 11676 %} 11677 11678 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11679 %{ 11680 match(Set cr (CmpL op1 (LoadL op2))); 11681 11682 format %{ "cmpq $op1, $op2" %} 11683 opcode(0x3B); /* Opcode 3B /r */ 11684 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11685 ins_pipe(ialu_cr_reg_mem); 11686 %} 11687 11688 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11689 %{ 11690 match(Set cr (CmpL src zero)); 11691 11692 format %{ "testq $src, $src" %} 11693 opcode(0x85); 11694 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11695 ins_pipe(ialu_cr_reg_imm); 11696 %} 11697 11698 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11699 %{ 11700 match(Set cr (CmpL (AndL src con) zero)); 11701 11702 format %{ "testq $src, $con\t# long" %} 11703 opcode(0xF7, 0x00); 11704 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11705 ins_pipe(ialu_cr_reg_imm); 11706 %} 11707 11708 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11709 %{ 11710 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11711 11712 format %{ "testq $src, $mem" %} 11713 opcode(0x85); 11714 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11715 ins_pipe(ialu_cr_reg_mem); 11716 %} 11717 11718 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11719 %{ 11720 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11721 11722 format %{ "testq $src, $mem" %} 11723 opcode(0x85); 11724 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11725 ins_pipe(ialu_cr_reg_mem); 11726 %} 11727 11728 // Manifest a CmpL result in an integer register. Very painful. 11729 // This is the test to avoid. 11730 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11731 %{ 11732 match(Set dst (CmpL3 src1 src2)); 11733 effect(KILL flags); 11734 11735 ins_cost(275); // XXX 11736 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11737 "movl $dst, -1\n\t" 11738 "jl,s done\n\t" 11739 "setne $dst\n\t" 11740 "movzbl $dst, $dst\n\t" 11741 "done:" %} 11742 ins_encode(cmpl3_flag(src1, src2, dst)); 11743 ins_pipe(pipe_slow); 11744 %} 11745 11746 // Unsigned long compare Instructions; really, same as signed long except they 11747 // produce an rFlagsRegU instead of rFlagsReg. 11748 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11749 %{ 11750 match(Set cr (CmpUL op1 op2)); 11751 11752 format %{ "cmpq $op1, $op2\t# unsigned" %} 11753 opcode(0x3B); /* Opcode 3B /r */ 11754 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11755 ins_pipe(ialu_cr_reg_reg); 11756 %} 11757 11758 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11759 %{ 11760 match(Set cr (CmpUL op1 op2)); 11761 11762 format %{ "cmpq $op1, $op2\t# unsigned" %} 11763 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11764 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11765 ins_pipe(ialu_cr_reg_imm); 11766 %} 11767 11768 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11769 %{ 11770 match(Set cr (CmpUL op1 (LoadL op2))); 11771 11772 format %{ "cmpq $op1, $op2\t# unsigned" %} 11773 opcode(0x3B); /* Opcode 3B /r */ 11774 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11775 ins_pipe(ialu_cr_reg_mem); 11776 %} 11777 11778 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11779 %{ 11780 match(Set cr (CmpUL src zero)); 11781 11782 format %{ "testq $src, $src\t# unsigned" %} 11783 opcode(0x85); 11784 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11785 ins_pipe(ialu_cr_reg_imm); 11786 %} 11787 11788 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11789 %{ 11790 match(Set cr (CmpI (LoadB mem) imm)); 11791 11792 ins_cost(125); 11793 format %{ "cmpb $mem, $imm" %} 11794 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11795 ins_pipe(ialu_cr_reg_mem); 11796 %} 11797 11798 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 11799 %{ 11800 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11801 11802 ins_cost(125); 11803 format %{ "testb $mem, $imm" %} 11804 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11805 ins_pipe(ialu_cr_reg_mem); 11806 %} 11807 11808 //----------Max and Min-------------------------------------------------------- 11809 // Min Instructions 11810 11811 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11812 %{ 11813 effect(USE_DEF dst, USE src, USE cr); 11814 11815 format %{ "cmovlgt $dst, $src\t# min" %} 11816 opcode(0x0F, 0x4F); 11817 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11818 ins_pipe(pipe_cmov_reg); 11819 %} 11820 11821 11822 instruct minI_rReg(rRegI dst, rRegI src) 11823 %{ 11824 match(Set dst (MinI dst src)); 11825 11826 ins_cost(200); 11827 expand %{ 11828 rFlagsReg cr; 11829 compI_rReg(cr, dst, src); 11830 cmovI_reg_g(dst, src, cr); 11831 %} 11832 %} 11833 11834 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11835 %{ 11836 effect(USE_DEF dst, USE src, USE cr); 11837 11838 format %{ "cmovllt $dst, $src\t# max" %} 11839 opcode(0x0F, 0x4C); 11840 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11841 ins_pipe(pipe_cmov_reg); 11842 %} 11843 11844 11845 instruct maxI_rReg(rRegI dst, rRegI src) 11846 %{ 11847 match(Set dst (MaxI dst src)); 11848 11849 ins_cost(200); 11850 expand %{ 11851 rFlagsReg cr; 11852 compI_rReg(cr, dst, src); 11853 cmovI_reg_l(dst, src, cr); 11854 %} 11855 %} 11856 11857 // ============================================================================ 11858 // Branch Instructions 11859 11860 // Jump Direct - Label defines a relative address from JMP+1 11861 instruct jmpDir(label labl) 11862 %{ 11863 match(Goto); 11864 effect(USE labl); 11865 11866 ins_cost(300); 11867 format %{ "jmp $labl" %} 11868 size(5); 11869 ins_encode %{ 11870 Label* L = $labl$$label; 11871 __ jmp(*L, false); // Always long jump 11872 %} 11873 ins_pipe(pipe_jmp); 11874 %} 11875 11876 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11877 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11878 %{ 11879 match(If cop cr); 11880 effect(USE labl); 11881 11882 ins_cost(300); 11883 format %{ "j$cop $labl" %} 11884 size(6); 11885 ins_encode %{ 11886 Label* L = $labl$$label; 11887 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11888 %} 11889 ins_pipe(pipe_jcc); 11890 %} 11891 11892 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11893 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11894 %{ 11895 predicate(!n->has_vector_mask_set()); 11896 match(CountedLoopEnd cop cr); 11897 effect(USE labl); 11898 11899 ins_cost(300); 11900 format %{ "j$cop $labl\t# loop end" %} 11901 size(6); 11902 ins_encode %{ 11903 Label* L = $labl$$label; 11904 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11905 %} 11906 ins_pipe(pipe_jcc); 11907 %} 11908 11909 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11910 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11911 predicate(!n->has_vector_mask_set()); 11912 match(CountedLoopEnd cop cmp); 11913 effect(USE labl); 11914 11915 ins_cost(300); 11916 format %{ "j$cop,u $labl\t# loop end" %} 11917 size(6); 11918 ins_encode %{ 11919 Label* L = $labl$$label; 11920 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11921 %} 11922 ins_pipe(pipe_jcc); 11923 %} 11924 11925 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11926 predicate(!n->has_vector_mask_set()); 11927 match(CountedLoopEnd cop cmp); 11928 effect(USE labl); 11929 11930 ins_cost(200); 11931 format %{ "j$cop,u $labl\t# loop end" %} 11932 size(6); 11933 ins_encode %{ 11934 Label* L = $labl$$label; 11935 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11936 %} 11937 ins_pipe(pipe_jcc); 11938 %} 11939 11940 // mask version 11941 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11942 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 11943 %{ 11944 predicate(n->has_vector_mask_set()); 11945 match(CountedLoopEnd cop cr); 11946 effect(USE labl); 11947 11948 ins_cost(400); 11949 format %{ "j$cop $labl\t# loop end\n\t" 11950 "restorevectmask \t# vector mask restore for loops" %} 11951 size(10); 11952 ins_encode %{ 11953 Label* L = $labl$$label; 11954 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11955 __ restorevectmask(); 11956 %} 11957 ins_pipe(pipe_jcc); 11958 %} 11959 11960 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11961 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11962 predicate(n->has_vector_mask_set()); 11963 match(CountedLoopEnd cop cmp); 11964 effect(USE labl); 11965 11966 ins_cost(400); 11967 format %{ "j$cop,u $labl\t# loop end\n\t" 11968 "restorevectmask \t# vector mask restore for loops" %} 11969 size(10); 11970 ins_encode %{ 11971 Label* L = $labl$$label; 11972 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11973 __ restorevectmask(); 11974 %} 11975 ins_pipe(pipe_jcc); 11976 %} 11977 11978 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11979 predicate(n->has_vector_mask_set()); 11980 match(CountedLoopEnd cop cmp); 11981 effect(USE labl); 11982 11983 ins_cost(300); 11984 format %{ "j$cop,u $labl\t# loop end\n\t" 11985 "restorevectmask \t# vector mask restore for loops" %} 11986 size(10); 11987 ins_encode %{ 11988 Label* L = $labl$$label; 11989 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11990 __ restorevectmask(); 11991 %} 11992 ins_pipe(pipe_jcc); 11993 %} 11994 11995 // Jump Direct Conditional - using unsigned comparison 11996 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11997 match(If cop cmp); 11998 effect(USE labl); 11999 12000 ins_cost(300); 12001 format %{ "j$cop,u $labl" %} 12002 size(6); 12003 ins_encode %{ 12004 Label* L = $labl$$label; 12005 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12006 %} 12007 ins_pipe(pipe_jcc); 12008 %} 12009 12010 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12011 match(If cop cmp); 12012 effect(USE labl); 12013 12014 ins_cost(200); 12015 format %{ "j$cop,u $labl" %} 12016 size(6); 12017 ins_encode %{ 12018 Label* L = $labl$$label; 12019 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12020 %} 12021 ins_pipe(pipe_jcc); 12022 %} 12023 12024 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12025 match(If cop cmp); 12026 effect(USE labl); 12027 12028 ins_cost(200); 12029 format %{ $$template 12030 if ($cop$$cmpcode == Assembler::notEqual) { 12031 $$emit$$"jp,u $labl\n\t" 12032 $$emit$$"j$cop,u $labl" 12033 } else { 12034 $$emit$$"jp,u done\n\t" 12035 $$emit$$"j$cop,u $labl\n\t" 12036 $$emit$$"done:" 12037 } 12038 %} 12039 ins_encode %{ 12040 Label* l = $labl$$label; 12041 if ($cop$$cmpcode == Assembler::notEqual) { 12042 __ jcc(Assembler::parity, *l, false); 12043 __ jcc(Assembler::notEqual, *l, false); 12044 } else if ($cop$$cmpcode == Assembler::equal) { 12045 Label done; 12046 __ jccb(Assembler::parity, done); 12047 __ jcc(Assembler::equal, *l, false); 12048 __ bind(done); 12049 } else { 12050 ShouldNotReachHere(); 12051 } 12052 %} 12053 ins_pipe(pipe_jcc); 12054 %} 12055 12056 // ============================================================================ 12057 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12058 // superklass array for an instance of the superklass. Set a hidden 12059 // internal cache on a hit (cache is checked with exposed code in 12060 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12061 // encoding ALSO sets flags. 12062 12063 instruct partialSubtypeCheck(rdi_RegP result, 12064 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12065 rFlagsReg cr) 12066 %{ 12067 match(Set result (PartialSubtypeCheck sub super)); 12068 effect(KILL rcx, KILL cr); 12069 12070 ins_cost(1100); // slightly larger than the next version 12071 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12072 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12073 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12074 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12075 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12076 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12077 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12078 "miss:\t" %} 12079 12080 opcode(0x1); // Force a XOR of RDI 12081 ins_encode(enc_PartialSubtypeCheck()); 12082 ins_pipe(pipe_slow); 12083 %} 12084 12085 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12086 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12087 immP0 zero, 12088 rdi_RegP result) 12089 %{ 12090 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12091 effect(KILL rcx, KILL result); 12092 12093 ins_cost(1000); 12094 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12095 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12096 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12097 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12098 "jne,s miss\t\t# Missed: flags nz\n\t" 12099 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12100 "miss:\t" %} 12101 12102 opcode(0x0); // No need to XOR RDI 12103 ins_encode(enc_PartialSubtypeCheck()); 12104 ins_pipe(pipe_slow); 12105 %} 12106 12107 // ============================================================================ 12108 // Branch Instructions -- short offset versions 12109 // 12110 // These instructions are used to replace jumps of a long offset (the default 12111 // match) with jumps of a shorter offset. These instructions are all tagged 12112 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12113 // match rules in general matching. Instead, the ADLC generates a conversion 12114 // method in the MachNode which can be used to do in-place replacement of the 12115 // long variant with the shorter variant. The compiler will determine if a 12116 // branch can be taken by the is_short_branch_offset() predicate in the machine 12117 // specific code section of the file. 12118 12119 // Jump Direct - Label defines a relative address from JMP+1 12120 instruct jmpDir_short(label labl) %{ 12121 match(Goto); 12122 effect(USE labl); 12123 12124 ins_cost(300); 12125 format %{ "jmp,s $labl" %} 12126 size(2); 12127 ins_encode %{ 12128 Label* L = $labl$$label; 12129 __ jmpb(*L); 12130 %} 12131 ins_pipe(pipe_jmp); 12132 ins_short_branch(1); 12133 %} 12134 12135 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12136 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12137 match(If cop cr); 12138 effect(USE labl); 12139 12140 ins_cost(300); 12141 format %{ "j$cop,s $labl" %} 12142 size(2); 12143 ins_encode %{ 12144 Label* L = $labl$$label; 12145 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12146 %} 12147 ins_pipe(pipe_jcc); 12148 ins_short_branch(1); 12149 %} 12150 12151 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12152 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12153 match(CountedLoopEnd cop cr); 12154 effect(USE labl); 12155 12156 ins_cost(300); 12157 format %{ "j$cop,s $labl\t# loop end" %} 12158 size(2); 12159 ins_encode %{ 12160 Label* L = $labl$$label; 12161 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12162 %} 12163 ins_pipe(pipe_jcc); 12164 ins_short_branch(1); 12165 %} 12166 12167 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12168 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12169 match(CountedLoopEnd cop cmp); 12170 effect(USE labl); 12171 12172 ins_cost(300); 12173 format %{ "j$cop,us $labl\t# loop end" %} 12174 size(2); 12175 ins_encode %{ 12176 Label* L = $labl$$label; 12177 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12178 %} 12179 ins_pipe(pipe_jcc); 12180 ins_short_branch(1); 12181 %} 12182 12183 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12184 match(CountedLoopEnd cop cmp); 12185 effect(USE labl); 12186 12187 ins_cost(300); 12188 format %{ "j$cop,us $labl\t# loop end" %} 12189 size(2); 12190 ins_encode %{ 12191 Label* L = $labl$$label; 12192 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12193 %} 12194 ins_pipe(pipe_jcc); 12195 ins_short_branch(1); 12196 %} 12197 12198 // Jump Direct Conditional - using unsigned comparison 12199 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12200 match(If cop cmp); 12201 effect(USE labl); 12202 12203 ins_cost(300); 12204 format %{ "j$cop,us $labl" %} 12205 size(2); 12206 ins_encode %{ 12207 Label* L = $labl$$label; 12208 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12209 %} 12210 ins_pipe(pipe_jcc); 12211 ins_short_branch(1); 12212 %} 12213 12214 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12215 match(If cop cmp); 12216 effect(USE labl); 12217 12218 ins_cost(300); 12219 format %{ "j$cop,us $labl" %} 12220 size(2); 12221 ins_encode %{ 12222 Label* L = $labl$$label; 12223 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12224 %} 12225 ins_pipe(pipe_jcc); 12226 ins_short_branch(1); 12227 %} 12228 12229 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12230 match(If cop cmp); 12231 effect(USE labl); 12232 12233 ins_cost(300); 12234 format %{ $$template 12235 if ($cop$$cmpcode == Assembler::notEqual) { 12236 $$emit$$"jp,u,s $labl\n\t" 12237 $$emit$$"j$cop,u,s $labl" 12238 } else { 12239 $$emit$$"jp,u,s done\n\t" 12240 $$emit$$"j$cop,u,s $labl\n\t" 12241 $$emit$$"done:" 12242 } 12243 %} 12244 size(4); 12245 ins_encode %{ 12246 Label* l = $labl$$label; 12247 if ($cop$$cmpcode == Assembler::notEqual) { 12248 __ jccb(Assembler::parity, *l); 12249 __ jccb(Assembler::notEqual, *l); 12250 } else if ($cop$$cmpcode == Assembler::equal) { 12251 Label done; 12252 __ jccb(Assembler::parity, done); 12253 __ jccb(Assembler::equal, *l); 12254 __ bind(done); 12255 } else { 12256 ShouldNotReachHere(); 12257 } 12258 %} 12259 ins_pipe(pipe_jcc); 12260 ins_short_branch(1); 12261 %} 12262 12263 // ============================================================================ 12264 // inlined locking and unlocking 12265 12266 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12267 predicate(Compile::current()->use_rtm()); 12268 match(Set cr (FastLock object box)); 12269 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12270 ins_cost(300); 12271 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12272 ins_encode %{ 12273 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12274 $scr$$Register, $cx1$$Register, $cx2$$Register, 12275 _counters, _rtm_counters, _stack_rtm_counters, 12276 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12277 true, ra_->C->profile_rtm()); 12278 %} 12279 ins_pipe(pipe_slow); 12280 %} 12281 12282 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12283 predicate(!Compile::current()->use_rtm()); 12284 match(Set cr (FastLock object box)); 12285 effect(TEMP tmp, TEMP scr, USE_KILL box); 12286 ins_cost(300); 12287 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12288 ins_encode %{ 12289 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12290 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12291 %} 12292 ins_pipe(pipe_slow); 12293 %} 12294 12295 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12296 match(Set cr (FastUnlock object box)); 12297 effect(TEMP tmp, USE_KILL box); 12298 ins_cost(300); 12299 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12300 ins_encode %{ 12301 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12302 %} 12303 ins_pipe(pipe_slow); 12304 %} 12305 12306 12307 // ============================================================================ 12308 // Safepoint Instructions 12309 instruct safePoint_poll(rFlagsReg cr) 12310 %{ 12311 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12312 match(SafePoint); 12313 effect(KILL cr); 12314 12315 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12316 "# Safepoint: poll for GC" %} 12317 ins_cost(125); 12318 ins_encode %{ 12319 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12320 __ testl(rax, addr); 12321 %} 12322 ins_pipe(ialu_reg_mem); 12323 %} 12324 12325 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12326 %{ 12327 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12328 match(SafePoint poll); 12329 effect(KILL cr, USE poll); 12330 12331 format %{ "testl rax, [$poll]\t" 12332 "# Safepoint: poll for GC" %} 12333 ins_cost(125); 12334 ins_encode %{ 12335 __ relocate(relocInfo::poll_type); 12336 __ testl(rax, Address($poll$$Register, 0)); 12337 %} 12338 ins_pipe(ialu_reg_mem); 12339 %} 12340 12341 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12342 %{ 12343 predicate(SafepointMechanism::uses_thread_local_poll()); 12344 match(SafePoint poll); 12345 effect(KILL cr, USE poll); 12346 12347 format %{ "testl rax, [$poll]\t" 12348 "# Safepoint: poll for GC" %} 12349 ins_cost(125); 12350 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12351 ins_encode %{ 12352 __ relocate(relocInfo::poll_type); 12353 address pre_pc = __ pc(); 12354 __ testl(rax, Address($poll$$Register, 0)); 12355 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12356 %} 12357 ins_pipe(ialu_reg_mem); 12358 %} 12359 12360 // ============================================================================ 12361 // Procedure Call/Return Instructions 12362 // Call Java Static Instruction 12363 // Note: If this code changes, the corresponding ret_addr_offset() and 12364 // compute_padding() functions will have to be adjusted. 12365 instruct CallStaticJavaDirect(method meth) %{ 12366 match(CallStaticJava); 12367 effect(USE meth); 12368 12369 ins_cost(300); 12370 format %{ "call,static " %} 12371 opcode(0xE8); /* E8 cd */ 12372 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12373 ins_pipe(pipe_slow); 12374 ins_alignment(4); 12375 %} 12376 12377 // Call Java Dynamic Instruction 12378 // Note: If this code changes, the corresponding ret_addr_offset() and 12379 // compute_padding() functions will have to be adjusted. 12380 instruct CallDynamicJavaDirect(method meth) 12381 %{ 12382 match(CallDynamicJava); 12383 effect(USE meth); 12384 12385 ins_cost(300); 12386 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12387 "call,dynamic " %} 12388 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12389 ins_pipe(pipe_slow); 12390 ins_alignment(4); 12391 %} 12392 12393 // Call Runtime Instruction 12394 instruct CallRuntimeDirect(method meth) 12395 %{ 12396 match(CallRuntime); 12397 effect(USE meth); 12398 12399 ins_cost(300); 12400 format %{ "call,runtime " %} 12401 ins_encode(clear_avx, Java_To_Runtime(meth)); 12402 ins_pipe(pipe_slow); 12403 %} 12404 12405 // Call runtime without safepoint 12406 instruct CallLeafDirect(method meth) 12407 %{ 12408 match(CallLeaf); 12409 effect(USE meth); 12410 12411 ins_cost(300); 12412 format %{ "call_leaf,runtime " %} 12413 ins_encode(clear_avx, Java_To_Runtime(meth)); 12414 ins_pipe(pipe_slow); 12415 %} 12416 12417 // Call runtime without safepoint 12418 instruct CallLeafNoFPDirect(method meth) 12419 %{ 12420 match(CallLeafNoFP); 12421 effect(USE meth); 12422 12423 ins_cost(300); 12424 format %{ "call_leaf_nofp,runtime " %} 12425 ins_encode(clear_avx, Java_To_Runtime(meth)); 12426 ins_pipe(pipe_slow); 12427 %} 12428 12429 // Return Instruction 12430 // Remove the return address & jump to it. 12431 // Notice: We always emit a nop after a ret to make sure there is room 12432 // for safepoint patching 12433 instruct Ret() 12434 %{ 12435 match(Return); 12436 12437 format %{ "ret" %} 12438 opcode(0xC3); 12439 ins_encode(OpcP); 12440 ins_pipe(pipe_jmp); 12441 %} 12442 12443 // Tail Call; Jump from runtime stub to Java code. 12444 // Also known as an 'interprocedural jump'. 12445 // Target of jump will eventually return to caller. 12446 // TailJump below removes the return address. 12447 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12448 %{ 12449 match(TailCall jump_target method_oop); 12450 12451 ins_cost(300); 12452 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12453 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12454 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12455 ins_pipe(pipe_jmp); 12456 %} 12457 12458 // Tail Jump; remove the return address; jump to target. 12459 // TailCall above leaves the return address around. 12460 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12461 %{ 12462 match(TailJump jump_target ex_oop); 12463 12464 ins_cost(300); 12465 format %{ "popq rdx\t# pop return address\n\t" 12466 "jmp $jump_target" %} 12467 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12468 ins_encode(Opcode(0x5a), // popq rdx 12469 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12470 ins_pipe(pipe_jmp); 12471 %} 12472 12473 // Create exception oop: created by stack-crawling runtime code. 12474 // Created exception is now available to this handler, and is setup 12475 // just prior to jumping to this handler. No code emitted. 12476 instruct CreateException(rax_RegP ex_oop) 12477 %{ 12478 match(Set ex_oop (CreateEx)); 12479 12480 size(0); 12481 // use the following format syntax 12482 format %{ "# exception oop is in rax; no code emitted" %} 12483 ins_encode(); 12484 ins_pipe(empty); 12485 %} 12486 12487 // Rethrow exception: 12488 // The exception oop will come in the first argument position. 12489 // Then JUMP (not call) to the rethrow stub code. 12490 instruct RethrowException() 12491 %{ 12492 match(Rethrow); 12493 12494 // use the following format syntax 12495 format %{ "jmp rethrow_stub" %} 12496 ins_encode(enc_rethrow); 12497 ins_pipe(pipe_jmp); 12498 %} 12499 12500 // 12501 // Execute ZGC load barrier (strong) slow path 12502 // 12503 12504 // When running without XMM regs 12505 instruct loadBarrierSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12506 12507 match(Set dst (LoadBarrierSlowReg mem)); 12508 predicate(MaxVectorSize < 16); 12509 12510 effect(DEF dst, KILL cr); 12511 12512 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12513 ins_encode %{ 12514 #if INCLUDE_ZGC 12515 Register d = $dst$$Register; 12516 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12517 12518 assert(d != r12, "Can't be R12!"); 12519 assert(d != r15, "Can't be R15!"); 12520 assert(d != rsp, "Can't be RSP!"); 12521 12522 __ lea(d, $mem$$Address); 12523 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12524 #else 12525 ShouldNotReachHere(); 12526 #endif 12527 %} 12528 ins_pipe(pipe_slow); 12529 %} 12530 12531 // For XMM and YMM enabled processors 12532 instruct loadBarrierSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12533 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12534 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12535 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12536 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12537 12538 match(Set dst (LoadBarrierSlowReg mem)); 12539 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12540 12541 effect(DEF dst, KILL cr, 12542 KILL x0, KILL x1, KILL x2, KILL x3, 12543 KILL x4, KILL x5, KILL x6, KILL x7, 12544 KILL x8, KILL x9, KILL x10, KILL x11, 12545 KILL x12, KILL x13, KILL x14, KILL x15); 12546 12547 format %{"LoadBarrierSlowRegXmm $dst, $mem" %} 12548 ins_encode %{ 12549 #if INCLUDE_ZGC 12550 Register d = $dst$$Register; 12551 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12552 12553 assert(d != r12, "Can't be R12!"); 12554 assert(d != r15, "Can't be R15!"); 12555 assert(d != rsp, "Can't be RSP!"); 12556 12557 __ lea(d, $mem$$Address); 12558 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12559 #else 12560 ShouldNotReachHere(); 12561 #endif 12562 %} 12563 ins_pipe(pipe_slow); 12564 %} 12565 12566 // For ZMM enabled processors 12567 instruct loadBarrierSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12568 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12569 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12570 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12571 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12572 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12573 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12574 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12575 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12576 12577 match(Set dst (LoadBarrierSlowReg mem)); 12578 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12579 12580 effect(DEF dst, KILL cr, 12581 KILL x0, KILL x1, KILL x2, KILL x3, 12582 KILL x4, KILL x5, KILL x6, KILL x7, 12583 KILL x8, KILL x9, KILL x10, KILL x11, 12584 KILL x12, KILL x13, KILL x14, KILL x15, 12585 KILL x16, KILL x17, KILL x18, KILL x19, 12586 KILL x20, KILL x21, KILL x22, KILL x23, 12587 KILL x24, KILL x25, KILL x26, KILL x27, 12588 KILL x28, KILL x29, KILL x30, KILL x31); 12589 12590 format %{"LoadBarrierSlowRegZmm $dst, $mem" %} 12591 ins_encode %{ 12592 #if INCLUDE_ZGC 12593 Register d = $dst$$Register; 12594 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12595 12596 assert(d != r12, "Can't be R12!"); 12597 assert(d != r15, "Can't be R15!"); 12598 assert(d != rsp, "Can't be RSP!"); 12599 12600 __ lea(d, $mem$$Address); 12601 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12602 #else 12603 ShouldNotReachHere(); 12604 #endif 12605 %} 12606 ins_pipe(pipe_slow); 12607 %} 12608 12609 // 12610 // Execute ZGC load barrier (weak) slow path 12611 // 12612 12613 // When running without XMM regs 12614 instruct loadBarrierWeakSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12615 12616 match(Set dst (LoadBarrierSlowReg mem)); 12617 predicate(MaxVectorSize < 16); 12618 12619 effect(DEF dst, KILL cr); 12620 12621 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12622 ins_encode %{ 12623 #if INCLUDE_ZGC 12624 Register d = $dst$$Register; 12625 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12626 12627 assert(d != r12, "Can't be R12!"); 12628 assert(d != r15, "Can't be R15!"); 12629 assert(d != rsp, "Can't be RSP!"); 12630 12631 __ lea(d, $mem$$Address); 12632 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12633 #else 12634 ShouldNotReachHere(); 12635 #endif 12636 %} 12637 ins_pipe(pipe_slow); 12638 %} 12639 12640 // For XMM and YMM enabled processors 12641 instruct loadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12642 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12643 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12644 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12645 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12646 12647 match(Set dst (LoadBarrierWeakSlowReg mem)); 12648 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12649 12650 effect(DEF dst, KILL cr, 12651 KILL x0, KILL x1, KILL x2, KILL x3, 12652 KILL x4, KILL x5, KILL x6, KILL x7, 12653 KILL x8, KILL x9, KILL x10, KILL x11, 12654 KILL x12, KILL x13, KILL x14, KILL x15); 12655 12656 format %{"LoadBarrierWeakSlowRegXmm $dst, $mem" %} 12657 ins_encode %{ 12658 #if INCLUDE_ZGC 12659 Register d = $dst$$Register; 12660 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12661 12662 assert(d != r12, "Can't be R12!"); 12663 assert(d != r15, "Can't be R15!"); 12664 assert(d != rsp, "Can't be RSP!"); 12665 12666 __ lea(d,$mem$$Address); 12667 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12668 #else 12669 ShouldNotReachHere(); 12670 #endif 12671 %} 12672 ins_pipe(pipe_slow); 12673 %} 12674 12675 // For ZMM enabled processors 12676 instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12677 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12678 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12679 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12680 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12681 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12682 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12683 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12684 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12685 12686 match(Set dst (LoadBarrierWeakSlowReg mem)); 12687 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12688 12689 effect(DEF dst, KILL cr, 12690 KILL x0, KILL x1, KILL x2, KILL x3, 12691 KILL x4, KILL x5, KILL x6, KILL x7, 12692 KILL x8, KILL x9, KILL x10, KILL x11, 12693 KILL x12, KILL x13, KILL x14, KILL x15, 12694 KILL x16, KILL x17, KILL x18, KILL x19, 12695 KILL x20, KILL x21, KILL x22, KILL x23, 12696 KILL x24, KILL x25, KILL x26, KILL x27, 12697 KILL x28, KILL x29, KILL x30, KILL x31); 12698 12699 format %{"LoadBarrierWeakSlowRegZmm $dst, $mem" %} 12700 ins_encode %{ 12701 #if INCLUDE_ZGC 12702 Register d = $dst$$Register; 12703 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12704 12705 assert(d != r12, "Can't be R12!"); 12706 assert(d != r15, "Can't be R15!"); 12707 assert(d != rsp, "Can't be RSP!"); 12708 12709 __ lea(d,$mem$$Address); 12710 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12711 #else 12712 ShouldNotReachHere(); 12713 #endif 12714 %} 12715 ins_pipe(pipe_slow); 12716 %} 12717 12718 // ============================================================================ 12719 // This name is KNOWN by the ADLC and cannot be changed. 12720 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12721 // for this guy. 12722 instruct tlsLoadP(r15_RegP dst) %{ 12723 match(Set dst (ThreadLocal)); 12724 effect(DEF dst); 12725 12726 size(0); 12727 format %{ "# TLS is in R15" %} 12728 ins_encode( /*empty encoding*/ ); 12729 ins_pipe(ialu_reg_reg); 12730 %} 12731 12732 12733 //----------PEEPHOLE RULES----------------------------------------------------- 12734 // These must follow all instruction definitions as they use the names 12735 // defined in the instructions definitions. 12736 // 12737 // peepmatch ( root_instr_name [preceding_instruction]* ); 12738 // 12739 // peepconstraint %{ 12740 // (instruction_number.operand_name relational_op instruction_number.operand_name 12741 // [, ...] ); 12742 // // instruction numbers are zero-based using left to right order in peepmatch 12743 // 12744 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12745 // // provide an instruction_number.operand_name for each operand that appears 12746 // // in the replacement instruction's match rule 12747 // 12748 // ---------VM FLAGS--------------------------------------------------------- 12749 // 12750 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12751 // 12752 // Each peephole rule is given an identifying number starting with zero and 12753 // increasing by one in the order seen by the parser. An individual peephole 12754 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12755 // on the command-line. 12756 // 12757 // ---------CURRENT LIMITATIONS---------------------------------------------- 12758 // 12759 // Only match adjacent instructions in same basic block 12760 // Only equality constraints 12761 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12762 // Only one replacement instruction 12763 // 12764 // ---------EXAMPLE---------------------------------------------------------- 12765 // 12766 // // pertinent parts of existing instructions in architecture description 12767 // instruct movI(rRegI dst, rRegI src) 12768 // %{ 12769 // match(Set dst (CopyI src)); 12770 // %} 12771 // 12772 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12773 // %{ 12774 // match(Set dst (AddI dst src)); 12775 // effect(KILL cr); 12776 // %} 12777 // 12778 // // Change (inc mov) to lea 12779 // peephole %{ 12780 // // increment preceeded by register-register move 12781 // peepmatch ( incI_rReg movI ); 12782 // // require that the destination register of the increment 12783 // // match the destination register of the move 12784 // peepconstraint ( 0.dst == 1.dst ); 12785 // // construct a replacement instruction that sets 12786 // // the destination to ( move's source register + one ) 12787 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12788 // %} 12789 // 12790 12791 // Implementation no longer uses movX instructions since 12792 // machine-independent system no longer uses CopyX nodes. 12793 // 12794 // peephole 12795 // %{ 12796 // peepmatch (incI_rReg movI); 12797 // peepconstraint (0.dst == 1.dst); 12798 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12799 // %} 12800 12801 // peephole 12802 // %{ 12803 // peepmatch (decI_rReg movI); 12804 // peepconstraint (0.dst == 1.dst); 12805 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12806 // %} 12807 12808 // peephole 12809 // %{ 12810 // peepmatch (addI_rReg_imm movI); 12811 // peepconstraint (0.dst == 1.dst); 12812 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12813 // %} 12814 12815 // peephole 12816 // %{ 12817 // peepmatch (incL_rReg movL); 12818 // peepconstraint (0.dst == 1.dst); 12819 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12820 // %} 12821 12822 // peephole 12823 // %{ 12824 // peepmatch (decL_rReg movL); 12825 // peepconstraint (0.dst == 1.dst); 12826 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12827 // %} 12828 12829 // peephole 12830 // %{ 12831 // peepmatch (addL_rReg_imm movL); 12832 // peepconstraint (0.dst == 1.dst); 12833 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12834 // %} 12835 12836 // peephole 12837 // %{ 12838 // peepmatch (addP_rReg_imm movP); 12839 // peepconstraint (0.dst == 1.dst); 12840 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12841 // %} 12842 12843 // // Change load of spilled value to only a spill 12844 // instruct storeI(memory mem, rRegI src) 12845 // %{ 12846 // match(Set mem (StoreI mem src)); 12847 // %} 12848 // 12849 // instruct loadI(rRegI dst, memory mem) 12850 // %{ 12851 // match(Set dst (LoadI mem)); 12852 // %} 12853 // 12854 12855 peephole 12856 %{ 12857 peepmatch (loadI storeI); 12858 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12859 peepreplace (storeI(1.mem 1.mem 1.src)); 12860 %} 12861 12862 peephole 12863 %{ 12864 peepmatch (loadL storeL); 12865 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12866 peepreplace (storeL(1.mem 1.mem 1.src)); 12867 %} 12868 12869 //----------SMARTSPILL RULES--------------------------------------------------- 12870 // These must follow all instruction definitions as they use the names 12871 // defined in the instructions definitions.