1 // 2 // Copyright (c) 2003, 2018, 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 // Store Bit 5806 instruct storeZ0(memory mem, rRegI src) 5807 %{ 5808 match(Set mem (StoreZ0 mem src)); 5809 5810 ins_cost(125); 5811 format %{ "andb $mem, $src\t# byte" %} 5812 opcode(0x20); 5813 ins_encode(lock_prefix, REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5814 ins_pipe(ialu_mem_reg); 5815 %} 5816 5817 instruct storeZ1(memory mem, rRegI src) 5818 %{ 5819 match(Set mem (StoreZ1 mem src)); 5820 ins_cost(125); 5821 format %{ "orb $mem, $src\t# byte" %} 5822 opcode(0x08); 5823 ins_encode(lock_prefix, REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5824 ins_pipe(ialu_mem_reg); 5825 %} 5826 5827 // Store Byte 5828 instruct storeB(memory mem, rRegI src) 5829 %{ 5830 match(Set mem (StoreB mem src)); 5831 5832 ins_cost(125); // XXX 5833 format %{ "movb $mem, $src\t# byte" %} 5834 opcode(0x88); 5835 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5836 ins_pipe(ialu_mem_reg); 5837 %} 5838 5839 // Store Char/Short 5840 instruct storeC(memory mem, rRegI src) 5841 %{ 5842 match(Set mem (StoreC mem src)); 5843 5844 ins_cost(125); // XXX 5845 format %{ "movw $mem, $src\t# char/short" %} 5846 opcode(0x89); 5847 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5848 ins_pipe(ialu_mem_reg); 5849 %} 5850 5851 // Store Integer 5852 instruct storeI(memory mem, rRegI src) 5853 %{ 5854 match(Set mem (StoreI mem src)); 5855 5856 ins_cost(125); // XXX 5857 format %{ "movl $mem, $src\t# int" %} 5858 opcode(0x89); 5859 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5860 ins_pipe(ialu_mem_reg); 5861 %} 5862 5863 // Store Long 5864 instruct storeL(memory mem, rRegL src) 5865 %{ 5866 match(Set mem (StoreL mem src)); 5867 5868 ins_cost(125); // XXX 5869 format %{ "movq $mem, $src\t# long" %} 5870 opcode(0x89); 5871 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5872 ins_pipe(ialu_mem_reg); // XXX 5873 %} 5874 5875 // Store Pointer 5876 instruct storeP(memory mem, any_RegP src) 5877 %{ 5878 match(Set mem (StoreP mem src)); 5879 5880 ins_cost(125); // XXX 5881 format %{ "movq $mem, $src\t# ptr" %} 5882 opcode(0x89); 5883 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5884 ins_pipe(ialu_mem_reg); 5885 %} 5886 5887 instruct storeImmP0(memory mem, immP0 zero) 5888 %{ 5889 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5890 match(Set mem (StoreP mem zero)); 5891 5892 ins_cost(125); // XXX 5893 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5894 ins_encode %{ 5895 __ movq($mem$$Address, r12); 5896 %} 5897 ins_pipe(ialu_mem_reg); 5898 %} 5899 5900 // Store NULL Pointer, mark word, or other simple pointer constant. 5901 instruct storeImmP(memory mem, immP31 src) 5902 %{ 5903 match(Set mem (StoreP mem src)); 5904 5905 ins_cost(150); // XXX 5906 format %{ "movq $mem, $src\t# ptr" %} 5907 opcode(0xC7); /* C7 /0 */ 5908 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5909 ins_pipe(ialu_mem_imm); 5910 %} 5911 5912 // Store Compressed Pointer 5913 instruct storeN(memory mem, rRegN src) 5914 %{ 5915 match(Set mem (StoreN mem src)); 5916 5917 ins_cost(125); // XXX 5918 format %{ "movl $mem, $src\t# compressed ptr" %} 5919 ins_encode %{ 5920 __ movl($mem$$Address, $src$$Register); 5921 %} 5922 ins_pipe(ialu_mem_reg); 5923 %} 5924 5925 instruct storeNKlass(memory mem, rRegN src) 5926 %{ 5927 match(Set mem (StoreNKlass mem src)); 5928 5929 ins_cost(125); // XXX 5930 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5931 ins_encode %{ 5932 __ movl($mem$$Address, $src$$Register); 5933 %} 5934 ins_pipe(ialu_mem_reg); 5935 %} 5936 5937 instruct storeImmN0(memory mem, immN0 zero) 5938 %{ 5939 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5940 match(Set mem (StoreN mem zero)); 5941 5942 ins_cost(125); // XXX 5943 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5944 ins_encode %{ 5945 __ movl($mem$$Address, r12); 5946 %} 5947 ins_pipe(ialu_mem_reg); 5948 %} 5949 5950 instruct storeImmN(memory mem, immN src) 5951 %{ 5952 match(Set mem (StoreN mem src)); 5953 5954 ins_cost(150); // XXX 5955 format %{ "movl $mem, $src\t# compressed ptr" %} 5956 ins_encode %{ 5957 address con = (address)$src$$constant; 5958 if (con == NULL) { 5959 __ movl($mem$$Address, (int32_t)0); 5960 } else { 5961 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5962 } 5963 %} 5964 ins_pipe(ialu_mem_imm); 5965 %} 5966 5967 instruct storeImmNKlass(memory mem, immNKlass src) 5968 %{ 5969 match(Set mem (StoreNKlass mem src)); 5970 5971 ins_cost(150); // XXX 5972 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5973 ins_encode %{ 5974 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5975 %} 5976 ins_pipe(ialu_mem_imm); 5977 %} 5978 5979 // Store Integer Immediate 5980 instruct storeImmI0(memory mem, immI0 zero) 5981 %{ 5982 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5983 match(Set mem (StoreI mem zero)); 5984 5985 ins_cost(125); // XXX 5986 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5987 ins_encode %{ 5988 __ movl($mem$$Address, r12); 5989 %} 5990 ins_pipe(ialu_mem_reg); 5991 %} 5992 5993 instruct storeImmI(memory mem, immI src) 5994 %{ 5995 match(Set mem (StoreI mem src)); 5996 5997 ins_cost(150); 5998 format %{ "movl $mem, $src\t# int" %} 5999 opcode(0xC7); /* C7 /0 */ 6000 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6001 ins_pipe(ialu_mem_imm); 6002 %} 6003 6004 // Store Long Immediate 6005 instruct storeImmL0(memory mem, immL0 zero) 6006 %{ 6007 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6008 match(Set mem (StoreL mem zero)); 6009 6010 ins_cost(125); // XXX 6011 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6012 ins_encode %{ 6013 __ movq($mem$$Address, r12); 6014 %} 6015 ins_pipe(ialu_mem_reg); 6016 %} 6017 6018 instruct storeImmL(memory mem, immL32 src) 6019 %{ 6020 match(Set mem (StoreL mem src)); 6021 6022 ins_cost(150); 6023 format %{ "movq $mem, $src\t# long" %} 6024 opcode(0xC7); /* C7 /0 */ 6025 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6026 ins_pipe(ialu_mem_imm); 6027 %} 6028 6029 // Store Short/Char Immediate 6030 instruct storeImmC0(memory mem, immI0 zero) 6031 %{ 6032 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6033 match(Set mem (StoreC mem zero)); 6034 6035 ins_cost(125); // XXX 6036 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6037 ins_encode %{ 6038 __ movw($mem$$Address, r12); 6039 %} 6040 ins_pipe(ialu_mem_reg); 6041 %} 6042 6043 instruct storeImmI16(memory mem, immI16 src) 6044 %{ 6045 predicate(UseStoreImmI16); 6046 match(Set mem (StoreC mem src)); 6047 6048 ins_cost(150); 6049 format %{ "movw $mem, $src\t# short/char" %} 6050 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6051 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6052 ins_pipe(ialu_mem_imm); 6053 %} 6054 6055 // Store Byte Immediate 6056 instruct storeImmB0(memory mem, immI0 zero) 6057 %{ 6058 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6059 match(Set mem (StoreB mem zero)); 6060 6061 ins_cost(125); // XXX 6062 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6063 ins_encode %{ 6064 __ movb($mem$$Address, r12); 6065 %} 6066 ins_pipe(ialu_mem_reg); 6067 %} 6068 6069 instruct storeImmB(memory mem, immI8 src) 6070 %{ 6071 match(Set mem (StoreB mem src)); 6072 6073 ins_cost(150); // XXX 6074 format %{ "movb $mem, $src\t# byte" %} 6075 opcode(0xC6); /* C6 /0 */ 6076 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6077 ins_pipe(ialu_mem_imm); 6078 %} 6079 6080 // Store CMS card-mark Immediate 6081 instruct storeImmCM0_reg(memory mem, immI0 zero) 6082 %{ 6083 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6084 match(Set mem (StoreCM mem zero)); 6085 6086 ins_cost(125); // XXX 6087 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6088 ins_encode %{ 6089 __ movb($mem$$Address, r12); 6090 %} 6091 ins_pipe(ialu_mem_reg); 6092 %} 6093 6094 instruct storeImmCM0(memory mem, immI0 src) 6095 %{ 6096 match(Set mem (StoreCM mem src)); 6097 6098 ins_cost(150); // XXX 6099 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6100 opcode(0xC6); /* C6 /0 */ 6101 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6102 ins_pipe(ialu_mem_imm); 6103 %} 6104 6105 // Store Float 6106 instruct storeF(memory mem, regF src) 6107 %{ 6108 match(Set mem (StoreF mem src)); 6109 6110 ins_cost(95); // XXX 6111 format %{ "movss $mem, $src\t# float" %} 6112 ins_encode %{ 6113 __ movflt($mem$$Address, $src$$XMMRegister); 6114 %} 6115 ins_pipe(pipe_slow); // XXX 6116 %} 6117 6118 // Store immediate Float value (it is faster than store from XMM register) 6119 instruct storeF0(memory mem, immF0 zero) 6120 %{ 6121 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6122 match(Set mem (StoreF mem zero)); 6123 6124 ins_cost(25); // XXX 6125 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6126 ins_encode %{ 6127 __ movl($mem$$Address, r12); 6128 %} 6129 ins_pipe(ialu_mem_reg); 6130 %} 6131 6132 instruct storeF_imm(memory mem, immF src) 6133 %{ 6134 match(Set mem (StoreF mem src)); 6135 6136 ins_cost(50); 6137 format %{ "movl $mem, $src\t# float" %} 6138 opcode(0xC7); /* C7 /0 */ 6139 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6140 ins_pipe(ialu_mem_imm); 6141 %} 6142 6143 // Store Double 6144 instruct storeD(memory mem, regD src) 6145 %{ 6146 match(Set mem (StoreD mem src)); 6147 6148 ins_cost(95); // XXX 6149 format %{ "movsd $mem, $src\t# double" %} 6150 ins_encode %{ 6151 __ movdbl($mem$$Address, $src$$XMMRegister); 6152 %} 6153 ins_pipe(pipe_slow); // XXX 6154 %} 6155 6156 // Store immediate double 0.0 (it is faster than store from XMM register) 6157 instruct storeD0_imm(memory mem, immD0 src) 6158 %{ 6159 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6160 match(Set mem (StoreD mem src)); 6161 6162 ins_cost(50); 6163 format %{ "movq $mem, $src\t# double 0." %} 6164 opcode(0xC7); /* C7 /0 */ 6165 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6166 ins_pipe(ialu_mem_imm); 6167 %} 6168 6169 instruct storeD0(memory mem, immD0 zero) 6170 %{ 6171 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6172 match(Set mem (StoreD mem zero)); 6173 6174 ins_cost(25); // XXX 6175 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6176 ins_encode %{ 6177 __ movq($mem$$Address, r12); 6178 %} 6179 ins_pipe(ialu_mem_reg); 6180 %} 6181 6182 instruct storeSSI(stackSlotI dst, rRegI src) 6183 %{ 6184 match(Set dst src); 6185 6186 ins_cost(100); 6187 format %{ "movl $dst, $src\t# int stk" %} 6188 opcode(0x89); 6189 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6190 ins_pipe( ialu_mem_reg ); 6191 %} 6192 6193 instruct storeSSL(stackSlotL dst, rRegL src) 6194 %{ 6195 match(Set dst src); 6196 6197 ins_cost(100); 6198 format %{ "movq $dst, $src\t# long stk" %} 6199 opcode(0x89); 6200 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6201 ins_pipe(ialu_mem_reg); 6202 %} 6203 6204 instruct storeSSP(stackSlotP dst, rRegP src) 6205 %{ 6206 match(Set dst src); 6207 6208 ins_cost(100); 6209 format %{ "movq $dst, $src\t# ptr stk" %} 6210 opcode(0x89); 6211 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6212 ins_pipe(ialu_mem_reg); 6213 %} 6214 6215 instruct storeSSF(stackSlotF dst, regF src) 6216 %{ 6217 match(Set dst src); 6218 6219 ins_cost(95); // XXX 6220 format %{ "movss $dst, $src\t# float stk" %} 6221 ins_encode %{ 6222 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6223 %} 6224 ins_pipe(pipe_slow); // XXX 6225 %} 6226 6227 instruct storeSSD(stackSlotD dst, regD src) 6228 %{ 6229 match(Set dst src); 6230 6231 ins_cost(95); // XXX 6232 format %{ "movsd $dst, $src\t# double stk" %} 6233 ins_encode %{ 6234 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6235 %} 6236 ins_pipe(pipe_slow); // XXX 6237 %} 6238 6239 //----------BSWAP Instructions------------------------------------------------- 6240 instruct bytes_reverse_int(rRegI dst) %{ 6241 match(Set dst (ReverseBytesI dst)); 6242 6243 format %{ "bswapl $dst" %} 6244 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6245 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6246 ins_pipe( ialu_reg ); 6247 %} 6248 6249 instruct bytes_reverse_long(rRegL dst) %{ 6250 match(Set dst (ReverseBytesL dst)); 6251 6252 format %{ "bswapq $dst" %} 6253 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6254 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6255 ins_pipe( ialu_reg); 6256 %} 6257 6258 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6259 match(Set dst (ReverseBytesUS dst)); 6260 effect(KILL cr); 6261 6262 format %{ "bswapl $dst\n\t" 6263 "shrl $dst,16\n\t" %} 6264 ins_encode %{ 6265 __ bswapl($dst$$Register); 6266 __ shrl($dst$$Register, 16); 6267 %} 6268 ins_pipe( ialu_reg ); 6269 %} 6270 6271 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6272 match(Set dst (ReverseBytesS dst)); 6273 effect(KILL cr); 6274 6275 format %{ "bswapl $dst\n\t" 6276 "sar $dst,16\n\t" %} 6277 ins_encode %{ 6278 __ bswapl($dst$$Register); 6279 __ sarl($dst$$Register, 16); 6280 %} 6281 ins_pipe( ialu_reg ); 6282 %} 6283 6284 //---------- Zeros Count Instructions ------------------------------------------ 6285 6286 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6287 predicate(UseCountLeadingZerosInstruction); 6288 match(Set dst (CountLeadingZerosI src)); 6289 effect(KILL cr); 6290 6291 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6292 ins_encode %{ 6293 __ lzcntl($dst$$Register, $src$$Register); 6294 %} 6295 ins_pipe(ialu_reg); 6296 %} 6297 6298 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6299 predicate(!UseCountLeadingZerosInstruction); 6300 match(Set dst (CountLeadingZerosI src)); 6301 effect(KILL cr); 6302 6303 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6304 "jnz skip\n\t" 6305 "movl $dst, -1\n" 6306 "skip:\n\t" 6307 "negl $dst\n\t" 6308 "addl $dst, 31" %} 6309 ins_encode %{ 6310 Register Rdst = $dst$$Register; 6311 Register Rsrc = $src$$Register; 6312 Label skip; 6313 __ bsrl(Rdst, Rsrc); 6314 __ jccb(Assembler::notZero, skip); 6315 __ movl(Rdst, -1); 6316 __ bind(skip); 6317 __ negl(Rdst); 6318 __ addl(Rdst, BitsPerInt - 1); 6319 %} 6320 ins_pipe(ialu_reg); 6321 %} 6322 6323 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6324 predicate(UseCountLeadingZerosInstruction); 6325 match(Set dst (CountLeadingZerosL src)); 6326 effect(KILL cr); 6327 6328 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6329 ins_encode %{ 6330 __ lzcntq($dst$$Register, $src$$Register); 6331 %} 6332 ins_pipe(ialu_reg); 6333 %} 6334 6335 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6336 predicate(!UseCountLeadingZerosInstruction); 6337 match(Set dst (CountLeadingZerosL src)); 6338 effect(KILL cr); 6339 6340 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6341 "jnz skip\n\t" 6342 "movl $dst, -1\n" 6343 "skip:\n\t" 6344 "negl $dst\n\t" 6345 "addl $dst, 63" %} 6346 ins_encode %{ 6347 Register Rdst = $dst$$Register; 6348 Register Rsrc = $src$$Register; 6349 Label skip; 6350 __ bsrq(Rdst, Rsrc); 6351 __ jccb(Assembler::notZero, skip); 6352 __ movl(Rdst, -1); 6353 __ bind(skip); 6354 __ negl(Rdst); 6355 __ addl(Rdst, BitsPerLong - 1); 6356 %} 6357 ins_pipe(ialu_reg); 6358 %} 6359 6360 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6361 predicate(UseCountTrailingZerosInstruction); 6362 match(Set dst (CountTrailingZerosI src)); 6363 effect(KILL cr); 6364 6365 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6366 ins_encode %{ 6367 __ tzcntl($dst$$Register, $src$$Register); 6368 %} 6369 ins_pipe(ialu_reg); 6370 %} 6371 6372 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6373 predicate(!UseCountTrailingZerosInstruction); 6374 match(Set dst (CountTrailingZerosI src)); 6375 effect(KILL cr); 6376 6377 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6378 "jnz done\n\t" 6379 "movl $dst, 32\n" 6380 "done:" %} 6381 ins_encode %{ 6382 Register Rdst = $dst$$Register; 6383 Label done; 6384 __ bsfl(Rdst, $src$$Register); 6385 __ jccb(Assembler::notZero, done); 6386 __ movl(Rdst, BitsPerInt); 6387 __ bind(done); 6388 %} 6389 ins_pipe(ialu_reg); 6390 %} 6391 6392 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6393 predicate(UseCountTrailingZerosInstruction); 6394 match(Set dst (CountTrailingZerosL src)); 6395 effect(KILL cr); 6396 6397 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6398 ins_encode %{ 6399 __ tzcntq($dst$$Register, $src$$Register); 6400 %} 6401 ins_pipe(ialu_reg); 6402 %} 6403 6404 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6405 predicate(!UseCountTrailingZerosInstruction); 6406 match(Set dst (CountTrailingZerosL src)); 6407 effect(KILL cr); 6408 6409 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6410 "jnz done\n\t" 6411 "movl $dst, 64\n" 6412 "done:" %} 6413 ins_encode %{ 6414 Register Rdst = $dst$$Register; 6415 Label done; 6416 __ bsfq(Rdst, $src$$Register); 6417 __ jccb(Assembler::notZero, done); 6418 __ movl(Rdst, BitsPerLong); 6419 __ bind(done); 6420 %} 6421 ins_pipe(ialu_reg); 6422 %} 6423 6424 6425 //---------- Population Count Instructions ------------------------------------- 6426 6427 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6428 predicate(UsePopCountInstruction); 6429 match(Set dst (PopCountI src)); 6430 effect(KILL cr); 6431 6432 format %{ "popcnt $dst, $src" %} 6433 ins_encode %{ 6434 __ popcntl($dst$$Register, $src$$Register); 6435 %} 6436 ins_pipe(ialu_reg); 6437 %} 6438 6439 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6440 predicate(UsePopCountInstruction); 6441 match(Set dst (PopCountI (LoadI mem))); 6442 effect(KILL cr); 6443 6444 format %{ "popcnt $dst, $mem" %} 6445 ins_encode %{ 6446 __ popcntl($dst$$Register, $mem$$Address); 6447 %} 6448 ins_pipe(ialu_reg); 6449 %} 6450 6451 // Note: Long.bitCount(long) returns an int. 6452 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6453 predicate(UsePopCountInstruction); 6454 match(Set dst (PopCountL src)); 6455 effect(KILL cr); 6456 6457 format %{ "popcnt $dst, $src" %} 6458 ins_encode %{ 6459 __ popcntq($dst$$Register, $src$$Register); 6460 %} 6461 ins_pipe(ialu_reg); 6462 %} 6463 6464 // Note: Long.bitCount(long) returns an int. 6465 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6466 predicate(UsePopCountInstruction); 6467 match(Set dst (PopCountL (LoadL mem))); 6468 effect(KILL cr); 6469 6470 format %{ "popcnt $dst, $mem" %} 6471 ins_encode %{ 6472 __ popcntq($dst$$Register, $mem$$Address); 6473 %} 6474 ins_pipe(ialu_reg); 6475 %} 6476 6477 6478 //----------MemBar Instructions----------------------------------------------- 6479 // Memory barrier flavors 6480 6481 instruct membar_acquire() 6482 %{ 6483 match(MemBarAcquire); 6484 match(LoadFence); 6485 ins_cost(0); 6486 6487 size(0); 6488 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6489 ins_encode(); 6490 ins_pipe(empty); 6491 %} 6492 6493 instruct membar_acquire_lock() 6494 %{ 6495 match(MemBarAcquireLock); 6496 ins_cost(0); 6497 6498 size(0); 6499 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6500 ins_encode(); 6501 ins_pipe(empty); 6502 %} 6503 6504 instruct membar_release() 6505 %{ 6506 match(MemBarRelease); 6507 match(StoreFence); 6508 ins_cost(0); 6509 6510 size(0); 6511 format %{ "MEMBAR-release ! (empty encoding)" %} 6512 ins_encode(); 6513 ins_pipe(empty); 6514 %} 6515 6516 instruct membar_release_lock() 6517 %{ 6518 match(MemBarReleaseLock); 6519 ins_cost(0); 6520 6521 size(0); 6522 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6523 ins_encode(); 6524 ins_pipe(empty); 6525 %} 6526 6527 instruct membar_volatile(rFlagsReg cr) %{ 6528 match(MemBarVolatile); 6529 effect(KILL cr); 6530 ins_cost(400); 6531 6532 format %{ 6533 $$template 6534 if (os::is_MP()) { 6535 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6536 } else { 6537 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6538 } 6539 %} 6540 ins_encode %{ 6541 __ membar(Assembler::StoreLoad); 6542 %} 6543 ins_pipe(pipe_slow); 6544 %} 6545 6546 instruct unnecessary_membar_volatile() 6547 %{ 6548 match(MemBarVolatile); 6549 predicate(Matcher::post_store_load_barrier(n)); 6550 ins_cost(0); 6551 6552 size(0); 6553 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6554 ins_encode(); 6555 ins_pipe(empty); 6556 %} 6557 6558 instruct membar_storestore() %{ 6559 match(MemBarStoreStore); 6560 ins_cost(0); 6561 6562 size(0); 6563 format %{ "MEMBAR-storestore (empty encoding)" %} 6564 ins_encode( ); 6565 ins_pipe(empty); 6566 %} 6567 6568 //----------Move Instructions-------------------------------------------------- 6569 6570 instruct castX2P(rRegP dst, rRegL src) 6571 %{ 6572 match(Set dst (CastX2P src)); 6573 6574 format %{ "movq $dst, $src\t# long->ptr" %} 6575 ins_encode %{ 6576 if ($dst$$reg != $src$$reg) { 6577 __ movptr($dst$$Register, $src$$Register); 6578 } 6579 %} 6580 ins_pipe(ialu_reg_reg); // XXX 6581 %} 6582 6583 instruct castP2X(rRegL dst, rRegP src) 6584 %{ 6585 match(Set dst (CastP2X src)); 6586 6587 format %{ "movq $dst, $src\t# ptr -> long" %} 6588 ins_encode %{ 6589 if ($dst$$reg != $src$$reg) { 6590 __ movptr($dst$$Register, $src$$Register); 6591 } 6592 %} 6593 ins_pipe(ialu_reg_reg); // XXX 6594 %} 6595 6596 // Convert oop into int for vectors alignment masking 6597 instruct convP2I(rRegI dst, rRegP src) 6598 %{ 6599 match(Set dst (ConvL2I (CastP2X src))); 6600 6601 format %{ "movl $dst, $src\t# ptr -> int" %} 6602 ins_encode %{ 6603 __ movl($dst$$Register, $src$$Register); 6604 %} 6605 ins_pipe(ialu_reg_reg); // XXX 6606 %} 6607 6608 // Convert compressed oop into int for vectors alignment masking 6609 // in case of 32bit oops (heap < 4Gb). 6610 instruct convN2I(rRegI dst, rRegN src) 6611 %{ 6612 predicate(Universe::narrow_oop_shift() == 0); 6613 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6614 6615 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6616 ins_encode %{ 6617 __ movl($dst$$Register, $src$$Register); 6618 %} 6619 ins_pipe(ialu_reg_reg); // XXX 6620 %} 6621 6622 // Convert oop pointer into compressed form 6623 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6624 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6625 match(Set dst (EncodeP src)); 6626 effect(KILL cr); 6627 format %{ "encode_heap_oop $dst,$src" %} 6628 ins_encode %{ 6629 Register s = $src$$Register; 6630 Register d = $dst$$Register; 6631 if (s != d) { 6632 __ movq(d, s); 6633 } 6634 __ encode_heap_oop(d); 6635 %} 6636 ins_pipe(ialu_reg_long); 6637 %} 6638 6639 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6640 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6641 match(Set dst (EncodeP src)); 6642 effect(KILL cr); 6643 format %{ "encode_heap_oop_not_null $dst,$src" %} 6644 ins_encode %{ 6645 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6646 %} 6647 ins_pipe(ialu_reg_long); 6648 %} 6649 6650 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6651 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6652 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6653 match(Set dst (DecodeN src)); 6654 effect(KILL cr); 6655 format %{ "decode_heap_oop $dst,$src" %} 6656 ins_encode %{ 6657 Register s = $src$$Register; 6658 Register d = $dst$$Register; 6659 if (s != d) { 6660 __ movq(d, s); 6661 } 6662 __ decode_heap_oop(d); 6663 %} 6664 ins_pipe(ialu_reg_long); 6665 %} 6666 6667 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6668 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6669 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6670 match(Set dst (DecodeN src)); 6671 effect(KILL cr); 6672 format %{ "decode_heap_oop_not_null $dst,$src" %} 6673 ins_encode %{ 6674 Register s = $src$$Register; 6675 Register d = $dst$$Register; 6676 if (s != d) { 6677 __ decode_heap_oop_not_null(d, s); 6678 } else { 6679 __ decode_heap_oop_not_null(d); 6680 } 6681 %} 6682 ins_pipe(ialu_reg_long); 6683 %} 6684 6685 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6686 match(Set dst (EncodePKlass src)); 6687 effect(KILL cr); 6688 format %{ "encode_klass_not_null $dst,$src" %} 6689 ins_encode %{ 6690 __ encode_klass_not_null($dst$$Register, $src$$Register); 6691 %} 6692 ins_pipe(ialu_reg_long); 6693 %} 6694 6695 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6696 match(Set dst (DecodeNKlass src)); 6697 effect(KILL cr); 6698 format %{ "decode_klass_not_null $dst,$src" %} 6699 ins_encode %{ 6700 Register s = $src$$Register; 6701 Register d = $dst$$Register; 6702 if (s != d) { 6703 __ decode_klass_not_null(d, s); 6704 } else { 6705 __ decode_klass_not_null(d); 6706 } 6707 %} 6708 ins_pipe(ialu_reg_long); 6709 %} 6710 6711 6712 //----------Conditional Move--------------------------------------------------- 6713 // Jump 6714 // dummy instruction for generating temp registers 6715 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6716 match(Jump (LShiftL switch_val shift)); 6717 ins_cost(350); 6718 predicate(false); 6719 effect(TEMP dest); 6720 6721 format %{ "leaq $dest, [$constantaddress]\n\t" 6722 "jmp [$dest + $switch_val << $shift]\n\t" %} 6723 ins_encode %{ 6724 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6725 // to do that and the compiler is using that register as one it can allocate. 6726 // So we build it all by hand. 6727 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6728 // ArrayAddress dispatch(table, index); 6729 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6730 __ lea($dest$$Register, $constantaddress); 6731 __ jmp(dispatch); 6732 %} 6733 ins_pipe(pipe_jmp); 6734 %} 6735 6736 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6737 match(Jump (AddL (LShiftL switch_val shift) offset)); 6738 ins_cost(350); 6739 effect(TEMP dest); 6740 6741 format %{ "leaq $dest, [$constantaddress]\n\t" 6742 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6743 ins_encode %{ 6744 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6745 // to do that and the compiler is using that register as one it can allocate. 6746 // So we build it all by hand. 6747 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6748 // ArrayAddress dispatch(table, index); 6749 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6750 __ lea($dest$$Register, $constantaddress); 6751 __ jmp(dispatch); 6752 %} 6753 ins_pipe(pipe_jmp); 6754 %} 6755 6756 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6757 match(Jump switch_val); 6758 ins_cost(350); 6759 effect(TEMP dest); 6760 6761 format %{ "leaq $dest, [$constantaddress]\n\t" 6762 "jmp [$dest + $switch_val]\n\t" %} 6763 ins_encode %{ 6764 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6765 // to do that and the compiler is using that register as one it can allocate. 6766 // So we build it all by hand. 6767 // Address index(noreg, switch_reg, Address::times_1); 6768 // ArrayAddress dispatch(table, index); 6769 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6770 __ lea($dest$$Register, $constantaddress); 6771 __ jmp(dispatch); 6772 %} 6773 ins_pipe(pipe_jmp); 6774 %} 6775 6776 // Conditional move 6777 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6778 %{ 6779 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6780 6781 ins_cost(200); // XXX 6782 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6783 opcode(0x0F, 0x40); 6784 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6785 ins_pipe(pipe_cmov_reg); 6786 %} 6787 6788 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6789 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6790 6791 ins_cost(200); // XXX 6792 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6793 opcode(0x0F, 0x40); 6794 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6795 ins_pipe(pipe_cmov_reg); 6796 %} 6797 6798 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6799 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6800 ins_cost(200); 6801 expand %{ 6802 cmovI_regU(cop, cr, dst, src); 6803 %} 6804 %} 6805 6806 // Conditional move 6807 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6808 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6809 6810 ins_cost(250); // XXX 6811 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6812 opcode(0x0F, 0x40); 6813 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6814 ins_pipe(pipe_cmov_mem); 6815 %} 6816 6817 // Conditional move 6818 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6819 %{ 6820 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6821 6822 ins_cost(250); // XXX 6823 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6824 opcode(0x0F, 0x40); 6825 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6826 ins_pipe(pipe_cmov_mem); 6827 %} 6828 6829 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6830 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6831 ins_cost(250); 6832 expand %{ 6833 cmovI_memU(cop, cr, dst, src); 6834 %} 6835 %} 6836 6837 // Conditional move 6838 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6839 %{ 6840 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6841 6842 ins_cost(200); // XXX 6843 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6844 opcode(0x0F, 0x40); 6845 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6846 ins_pipe(pipe_cmov_reg); 6847 %} 6848 6849 // Conditional move 6850 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6851 %{ 6852 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6853 6854 ins_cost(200); // XXX 6855 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6856 opcode(0x0F, 0x40); 6857 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6858 ins_pipe(pipe_cmov_reg); 6859 %} 6860 6861 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6862 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6863 ins_cost(200); 6864 expand %{ 6865 cmovN_regU(cop, cr, dst, src); 6866 %} 6867 %} 6868 6869 // Conditional move 6870 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6871 %{ 6872 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6873 6874 ins_cost(200); // XXX 6875 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6876 opcode(0x0F, 0x40); 6877 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6878 ins_pipe(pipe_cmov_reg); // XXX 6879 %} 6880 6881 // Conditional move 6882 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6883 %{ 6884 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6885 6886 ins_cost(200); // XXX 6887 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6888 opcode(0x0F, 0x40); 6889 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6890 ins_pipe(pipe_cmov_reg); // XXX 6891 %} 6892 6893 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6894 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6895 ins_cost(200); 6896 expand %{ 6897 cmovP_regU(cop, cr, dst, src); 6898 %} 6899 %} 6900 6901 // DISABLED: Requires the ADLC to emit a bottom_type call that 6902 // correctly meets the two pointer arguments; one is an incoming 6903 // register but the other is a memory operand. ALSO appears to 6904 // be buggy with implicit null checks. 6905 // 6906 //// Conditional move 6907 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6908 //%{ 6909 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6910 // ins_cost(250); 6911 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6912 // opcode(0x0F,0x40); 6913 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6914 // ins_pipe( pipe_cmov_mem ); 6915 //%} 6916 // 6917 //// Conditional move 6918 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6919 //%{ 6920 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6921 // ins_cost(250); 6922 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6923 // opcode(0x0F,0x40); 6924 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6925 // ins_pipe( pipe_cmov_mem ); 6926 //%} 6927 6928 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6929 %{ 6930 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6931 6932 ins_cost(200); // XXX 6933 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6934 opcode(0x0F, 0x40); 6935 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6936 ins_pipe(pipe_cmov_reg); // XXX 6937 %} 6938 6939 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6940 %{ 6941 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6942 6943 ins_cost(200); // XXX 6944 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6945 opcode(0x0F, 0x40); 6946 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6947 ins_pipe(pipe_cmov_mem); // XXX 6948 %} 6949 6950 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6951 %{ 6952 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6953 6954 ins_cost(200); // XXX 6955 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6956 opcode(0x0F, 0x40); 6957 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6958 ins_pipe(pipe_cmov_reg); // XXX 6959 %} 6960 6961 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6962 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6963 ins_cost(200); 6964 expand %{ 6965 cmovL_regU(cop, cr, dst, src); 6966 %} 6967 %} 6968 6969 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6970 %{ 6971 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6972 6973 ins_cost(200); // XXX 6974 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6975 opcode(0x0F, 0x40); 6976 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6977 ins_pipe(pipe_cmov_mem); // XXX 6978 %} 6979 6980 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6981 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6982 ins_cost(200); 6983 expand %{ 6984 cmovL_memU(cop, cr, dst, src); 6985 %} 6986 %} 6987 6988 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6989 %{ 6990 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6991 6992 ins_cost(200); // XXX 6993 format %{ "jn$cop skip\t# signed cmove float\n\t" 6994 "movss $dst, $src\n" 6995 "skip:" %} 6996 ins_encode %{ 6997 Label Lskip; 6998 // Invert sense of branch from sense of CMOV 6999 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7000 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7001 __ bind(Lskip); 7002 %} 7003 ins_pipe(pipe_slow); 7004 %} 7005 7006 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7007 // %{ 7008 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7009 7010 // ins_cost(200); // XXX 7011 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7012 // "movss $dst, $src\n" 7013 // "skip:" %} 7014 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7015 // ins_pipe(pipe_slow); 7016 // %} 7017 7018 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7019 %{ 7020 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7021 7022 ins_cost(200); // XXX 7023 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7024 "movss $dst, $src\n" 7025 "skip:" %} 7026 ins_encode %{ 7027 Label Lskip; 7028 // Invert sense of branch from sense of CMOV 7029 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7030 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7031 __ bind(Lskip); 7032 %} 7033 ins_pipe(pipe_slow); 7034 %} 7035 7036 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7037 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7038 ins_cost(200); 7039 expand %{ 7040 cmovF_regU(cop, cr, dst, src); 7041 %} 7042 %} 7043 7044 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7045 %{ 7046 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7047 7048 ins_cost(200); // XXX 7049 format %{ "jn$cop skip\t# signed cmove double\n\t" 7050 "movsd $dst, $src\n" 7051 "skip:" %} 7052 ins_encode %{ 7053 Label Lskip; 7054 // Invert sense of branch from sense of CMOV 7055 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7056 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7057 __ bind(Lskip); 7058 %} 7059 ins_pipe(pipe_slow); 7060 %} 7061 7062 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7063 %{ 7064 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7065 7066 ins_cost(200); // XXX 7067 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7068 "movsd $dst, $src\n" 7069 "skip:" %} 7070 ins_encode %{ 7071 Label Lskip; 7072 // Invert sense of branch from sense of CMOV 7073 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7074 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7075 __ bind(Lskip); 7076 %} 7077 ins_pipe(pipe_slow); 7078 %} 7079 7080 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7081 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7082 ins_cost(200); 7083 expand %{ 7084 cmovD_regU(cop, cr, dst, src); 7085 %} 7086 %} 7087 7088 //----------Arithmetic Instructions-------------------------------------------- 7089 //----------Addition Instructions---------------------------------------------- 7090 7091 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7092 %{ 7093 match(Set dst (AddI dst src)); 7094 effect(KILL cr); 7095 7096 format %{ "addl $dst, $src\t# int" %} 7097 opcode(0x03); 7098 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7099 ins_pipe(ialu_reg_reg); 7100 %} 7101 7102 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7103 %{ 7104 match(Set dst (AddI dst src)); 7105 effect(KILL cr); 7106 7107 format %{ "addl $dst, $src\t# int" %} 7108 opcode(0x81, 0x00); /* /0 id */ 7109 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7110 ins_pipe( ialu_reg ); 7111 %} 7112 7113 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7114 %{ 7115 match(Set dst (AddI dst (LoadI src))); 7116 effect(KILL cr); 7117 7118 ins_cost(125); // XXX 7119 format %{ "addl $dst, $src\t# int" %} 7120 opcode(0x03); 7121 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7122 ins_pipe(ialu_reg_mem); 7123 %} 7124 7125 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7126 %{ 7127 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7128 effect(KILL cr); 7129 7130 ins_cost(150); // XXX 7131 format %{ "addl $dst, $src\t# int" %} 7132 opcode(0x01); /* Opcode 01 /r */ 7133 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7134 ins_pipe(ialu_mem_reg); 7135 %} 7136 7137 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7138 %{ 7139 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7140 effect(KILL cr); 7141 7142 ins_cost(125); // XXX 7143 format %{ "addl $dst, $src\t# int" %} 7144 opcode(0x81); /* Opcode 81 /0 id */ 7145 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7146 ins_pipe(ialu_mem_imm); 7147 %} 7148 7149 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7150 %{ 7151 predicate(UseIncDec); 7152 match(Set dst (AddI dst src)); 7153 effect(KILL cr); 7154 7155 format %{ "incl $dst\t# int" %} 7156 opcode(0xFF, 0x00); // FF /0 7157 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7158 ins_pipe(ialu_reg); 7159 %} 7160 7161 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7162 %{ 7163 predicate(UseIncDec); 7164 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7165 effect(KILL cr); 7166 7167 ins_cost(125); // XXX 7168 format %{ "incl $dst\t# int" %} 7169 opcode(0xFF); /* Opcode FF /0 */ 7170 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7171 ins_pipe(ialu_mem_imm); 7172 %} 7173 7174 // XXX why does that use AddI 7175 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7176 %{ 7177 predicate(UseIncDec); 7178 match(Set dst (AddI dst src)); 7179 effect(KILL cr); 7180 7181 format %{ "decl $dst\t# int" %} 7182 opcode(0xFF, 0x01); // FF /1 7183 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7184 ins_pipe(ialu_reg); 7185 %} 7186 7187 // XXX why does that use AddI 7188 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7189 %{ 7190 predicate(UseIncDec); 7191 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7192 effect(KILL cr); 7193 7194 ins_cost(125); // XXX 7195 format %{ "decl $dst\t# int" %} 7196 opcode(0xFF); /* Opcode FF /1 */ 7197 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7198 ins_pipe(ialu_mem_imm); 7199 %} 7200 7201 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7202 %{ 7203 match(Set dst (AddI src0 src1)); 7204 7205 ins_cost(110); 7206 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7207 opcode(0x8D); /* 0x8D /r */ 7208 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7209 ins_pipe(ialu_reg_reg); 7210 %} 7211 7212 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7213 %{ 7214 match(Set dst (AddL dst src)); 7215 effect(KILL cr); 7216 7217 format %{ "addq $dst, $src\t# long" %} 7218 opcode(0x03); 7219 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7220 ins_pipe(ialu_reg_reg); 7221 %} 7222 7223 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7224 %{ 7225 match(Set dst (AddL dst src)); 7226 effect(KILL cr); 7227 7228 format %{ "addq $dst, $src\t# long" %} 7229 opcode(0x81, 0x00); /* /0 id */ 7230 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7231 ins_pipe( ialu_reg ); 7232 %} 7233 7234 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7235 %{ 7236 match(Set dst (AddL dst (LoadL src))); 7237 effect(KILL cr); 7238 7239 ins_cost(125); // XXX 7240 format %{ "addq $dst, $src\t# long" %} 7241 opcode(0x03); 7242 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7243 ins_pipe(ialu_reg_mem); 7244 %} 7245 7246 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7247 %{ 7248 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7249 effect(KILL cr); 7250 7251 ins_cost(150); // XXX 7252 format %{ "addq $dst, $src\t# long" %} 7253 opcode(0x01); /* Opcode 01 /r */ 7254 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7255 ins_pipe(ialu_mem_reg); 7256 %} 7257 7258 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7259 %{ 7260 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7261 effect(KILL cr); 7262 7263 ins_cost(125); // XXX 7264 format %{ "addq $dst, $src\t# long" %} 7265 opcode(0x81); /* Opcode 81 /0 id */ 7266 ins_encode(REX_mem_wide(dst), 7267 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7268 ins_pipe(ialu_mem_imm); 7269 %} 7270 7271 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7272 %{ 7273 predicate(UseIncDec); 7274 match(Set dst (AddL dst src)); 7275 effect(KILL cr); 7276 7277 format %{ "incq $dst\t# long" %} 7278 opcode(0xFF, 0x00); // FF /0 7279 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7280 ins_pipe(ialu_reg); 7281 %} 7282 7283 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7284 %{ 7285 predicate(UseIncDec); 7286 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7287 effect(KILL cr); 7288 7289 ins_cost(125); // XXX 7290 format %{ "incq $dst\t# long" %} 7291 opcode(0xFF); /* Opcode FF /0 */ 7292 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7293 ins_pipe(ialu_mem_imm); 7294 %} 7295 7296 // XXX why does that use AddL 7297 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7298 %{ 7299 predicate(UseIncDec); 7300 match(Set dst (AddL dst src)); 7301 effect(KILL cr); 7302 7303 format %{ "decq $dst\t# long" %} 7304 opcode(0xFF, 0x01); // FF /1 7305 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7306 ins_pipe(ialu_reg); 7307 %} 7308 7309 // XXX why does that use AddL 7310 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7311 %{ 7312 predicate(UseIncDec); 7313 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7314 effect(KILL cr); 7315 7316 ins_cost(125); // XXX 7317 format %{ "decq $dst\t# long" %} 7318 opcode(0xFF); /* Opcode FF /1 */ 7319 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7320 ins_pipe(ialu_mem_imm); 7321 %} 7322 7323 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7324 %{ 7325 match(Set dst (AddL src0 src1)); 7326 7327 ins_cost(110); 7328 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7329 opcode(0x8D); /* 0x8D /r */ 7330 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7331 ins_pipe(ialu_reg_reg); 7332 %} 7333 7334 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7335 %{ 7336 match(Set dst (AddP dst src)); 7337 effect(KILL cr); 7338 7339 format %{ "addq $dst, $src\t# ptr" %} 7340 opcode(0x03); 7341 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7342 ins_pipe(ialu_reg_reg); 7343 %} 7344 7345 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7346 %{ 7347 match(Set dst (AddP dst src)); 7348 effect(KILL cr); 7349 7350 format %{ "addq $dst, $src\t# ptr" %} 7351 opcode(0x81, 0x00); /* /0 id */ 7352 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7353 ins_pipe( ialu_reg ); 7354 %} 7355 7356 // XXX addP mem ops ???? 7357 7358 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7359 %{ 7360 match(Set dst (AddP src0 src1)); 7361 7362 ins_cost(110); 7363 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7364 opcode(0x8D); /* 0x8D /r */ 7365 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7366 ins_pipe(ialu_reg_reg); 7367 %} 7368 7369 instruct checkCastPP(rRegP dst) 7370 %{ 7371 match(Set dst (CheckCastPP dst)); 7372 7373 size(0); 7374 format %{ "# checkcastPP of $dst" %} 7375 ins_encode(/* empty encoding */); 7376 ins_pipe(empty); 7377 %} 7378 7379 instruct castPP(rRegP dst) 7380 %{ 7381 match(Set dst (CastPP dst)); 7382 7383 size(0); 7384 format %{ "# castPP of $dst" %} 7385 ins_encode(/* empty encoding */); 7386 ins_pipe(empty); 7387 %} 7388 7389 instruct castII(rRegI dst) 7390 %{ 7391 match(Set dst (CastII dst)); 7392 7393 size(0); 7394 format %{ "# castII of $dst" %} 7395 ins_encode(/* empty encoding */); 7396 ins_cost(0); 7397 ins_pipe(empty); 7398 %} 7399 7400 // LoadP-locked same as a regular LoadP when used with compare-swap 7401 instruct loadPLocked(rRegP dst, memory mem) 7402 %{ 7403 match(Set dst (LoadPLocked mem)); 7404 7405 ins_cost(125); // XXX 7406 format %{ "movq $dst, $mem\t# ptr locked" %} 7407 opcode(0x8B); 7408 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7409 ins_pipe(ialu_reg_mem); // XXX 7410 %} 7411 7412 // Conditional-store of the updated heap-top. 7413 // Used during allocation of the shared heap. 7414 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7415 7416 instruct storePConditional(memory heap_top_ptr, 7417 rax_RegP oldval, rRegP newval, 7418 rFlagsReg cr) 7419 %{ 7420 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7421 7422 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7423 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7424 opcode(0x0F, 0xB1); 7425 ins_encode(lock_prefix, 7426 REX_reg_mem_wide(newval, heap_top_ptr), 7427 OpcP, OpcS, 7428 reg_mem(newval, heap_top_ptr)); 7429 ins_pipe(pipe_cmpxchg); 7430 %} 7431 7432 // Conditional-store of an int value. 7433 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7434 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7435 %{ 7436 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7437 effect(KILL oldval); 7438 7439 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7440 opcode(0x0F, 0xB1); 7441 ins_encode(lock_prefix, 7442 REX_reg_mem(newval, mem), 7443 OpcP, OpcS, 7444 reg_mem(newval, mem)); 7445 ins_pipe(pipe_cmpxchg); 7446 %} 7447 7448 // Conditional-store of a long value. 7449 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7450 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7451 %{ 7452 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7453 effect(KILL oldval); 7454 7455 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7456 opcode(0x0F, 0xB1); 7457 ins_encode(lock_prefix, 7458 REX_reg_mem_wide(newval, mem), 7459 OpcP, OpcS, 7460 reg_mem(newval, mem)); 7461 ins_pipe(pipe_cmpxchg); 7462 %} 7463 7464 7465 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7466 instruct compareAndSwapP(rRegI res, 7467 memory mem_ptr, 7468 rax_RegP oldval, rRegP newval, 7469 rFlagsReg cr) 7470 %{ 7471 predicate(VM_Version::supports_cx8()); 7472 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7473 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7474 effect(KILL cr, KILL oldval); 7475 7476 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7477 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7478 "sete $res\n\t" 7479 "movzbl $res, $res" %} 7480 opcode(0x0F, 0xB1); 7481 ins_encode(lock_prefix, 7482 REX_reg_mem_wide(newval, mem_ptr), 7483 OpcP, OpcS, 7484 reg_mem(newval, mem_ptr), 7485 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7486 REX_reg_breg(res, res), // movzbl 7487 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7488 ins_pipe( pipe_cmpxchg ); 7489 %} 7490 7491 instruct compareAndSwapL(rRegI res, 7492 memory mem_ptr, 7493 rax_RegL oldval, rRegL newval, 7494 rFlagsReg cr) 7495 %{ 7496 predicate(VM_Version::supports_cx8()); 7497 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7498 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7499 effect(KILL cr, KILL oldval); 7500 7501 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7502 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7503 "sete $res\n\t" 7504 "movzbl $res, $res" %} 7505 opcode(0x0F, 0xB1); 7506 ins_encode(lock_prefix, 7507 REX_reg_mem_wide(newval, mem_ptr), 7508 OpcP, OpcS, 7509 reg_mem(newval, mem_ptr), 7510 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7511 REX_reg_breg(res, res), // movzbl 7512 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7513 ins_pipe( pipe_cmpxchg ); 7514 %} 7515 7516 instruct compareAndSwapI(rRegI res, 7517 memory mem_ptr, 7518 rax_RegI oldval, rRegI newval, 7519 rFlagsReg cr) 7520 %{ 7521 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7522 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7523 effect(KILL cr, KILL oldval); 7524 7525 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7526 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7527 "sete $res\n\t" 7528 "movzbl $res, $res" %} 7529 opcode(0x0F, 0xB1); 7530 ins_encode(lock_prefix, 7531 REX_reg_mem(newval, mem_ptr), 7532 OpcP, OpcS, 7533 reg_mem(newval, mem_ptr), 7534 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7535 REX_reg_breg(res, res), // movzbl 7536 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7537 ins_pipe( pipe_cmpxchg ); 7538 %} 7539 7540 instruct compareAndSwapB(rRegI res, 7541 memory mem_ptr, 7542 rax_RegI oldval, rRegI newval, 7543 rFlagsReg cr) 7544 %{ 7545 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7546 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7547 effect(KILL cr, KILL oldval); 7548 7549 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7550 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7551 "sete $res\n\t" 7552 "movzbl $res, $res" %} 7553 opcode(0x0F, 0xB0); 7554 ins_encode(lock_prefix, 7555 REX_breg_mem(newval, mem_ptr), 7556 OpcP, OpcS, 7557 reg_mem(newval, mem_ptr), 7558 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7559 REX_reg_breg(res, res), // movzbl 7560 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7561 ins_pipe( pipe_cmpxchg ); 7562 %} 7563 7564 instruct compareAndSwapS(rRegI res, 7565 memory mem_ptr, 7566 rax_RegI oldval, rRegI newval, 7567 rFlagsReg cr) 7568 %{ 7569 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7570 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7571 effect(KILL cr, KILL oldval); 7572 7573 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7574 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7575 "sete $res\n\t" 7576 "movzbl $res, $res" %} 7577 opcode(0x0F, 0xB1); 7578 ins_encode(lock_prefix, 7579 SizePrefix, 7580 REX_reg_mem(newval, mem_ptr), 7581 OpcP, OpcS, 7582 reg_mem(newval, mem_ptr), 7583 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7584 REX_reg_breg(res, res), // movzbl 7585 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7586 ins_pipe( pipe_cmpxchg ); 7587 %} 7588 7589 instruct compareAndSwapN(rRegI res, 7590 memory mem_ptr, 7591 rax_RegN oldval, rRegN newval, 7592 rFlagsReg cr) %{ 7593 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7594 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7595 effect(KILL cr, KILL oldval); 7596 7597 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7598 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7599 "sete $res\n\t" 7600 "movzbl $res, $res" %} 7601 opcode(0x0F, 0xB1); 7602 ins_encode(lock_prefix, 7603 REX_reg_mem(newval, mem_ptr), 7604 OpcP, OpcS, 7605 reg_mem(newval, mem_ptr), 7606 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7607 REX_reg_breg(res, res), // movzbl 7608 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7609 ins_pipe( pipe_cmpxchg ); 7610 %} 7611 7612 instruct compareAndExchangeB( 7613 memory mem_ptr, 7614 rax_RegI oldval, rRegI newval, 7615 rFlagsReg cr) 7616 %{ 7617 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7618 effect(KILL cr); 7619 7620 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7621 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7622 opcode(0x0F, 0xB0); 7623 ins_encode(lock_prefix, 7624 REX_breg_mem(newval, mem_ptr), 7625 OpcP, OpcS, 7626 reg_mem(newval, mem_ptr) // lock cmpxchg 7627 ); 7628 ins_pipe( pipe_cmpxchg ); 7629 %} 7630 7631 instruct compareAndExchangeS( 7632 memory mem_ptr, 7633 rax_RegI oldval, rRegI newval, 7634 rFlagsReg cr) 7635 %{ 7636 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7637 effect(KILL cr); 7638 7639 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7640 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7641 opcode(0x0F, 0xB1); 7642 ins_encode(lock_prefix, 7643 SizePrefix, 7644 REX_reg_mem(newval, mem_ptr), 7645 OpcP, OpcS, 7646 reg_mem(newval, mem_ptr) // lock cmpxchg 7647 ); 7648 ins_pipe( pipe_cmpxchg ); 7649 %} 7650 7651 instruct compareAndExchangeI( 7652 memory mem_ptr, 7653 rax_RegI oldval, rRegI newval, 7654 rFlagsReg cr) 7655 %{ 7656 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7657 effect(KILL cr); 7658 7659 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7660 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7661 opcode(0x0F, 0xB1); 7662 ins_encode(lock_prefix, 7663 REX_reg_mem(newval, mem_ptr), 7664 OpcP, OpcS, 7665 reg_mem(newval, mem_ptr) // lock cmpxchg 7666 ); 7667 ins_pipe( pipe_cmpxchg ); 7668 %} 7669 7670 instruct compareAndExchangeL( 7671 memory mem_ptr, 7672 rax_RegL oldval, rRegL newval, 7673 rFlagsReg cr) 7674 %{ 7675 predicate(VM_Version::supports_cx8()); 7676 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7677 effect(KILL cr); 7678 7679 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7680 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7681 opcode(0x0F, 0xB1); 7682 ins_encode(lock_prefix, 7683 REX_reg_mem_wide(newval, mem_ptr), 7684 OpcP, OpcS, 7685 reg_mem(newval, mem_ptr) // lock cmpxchg 7686 ); 7687 ins_pipe( pipe_cmpxchg ); 7688 %} 7689 7690 instruct compareAndExchangeN( 7691 memory mem_ptr, 7692 rax_RegN oldval, rRegN newval, 7693 rFlagsReg cr) %{ 7694 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7695 effect(KILL cr); 7696 7697 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7698 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7699 opcode(0x0F, 0xB1); 7700 ins_encode(lock_prefix, 7701 REX_reg_mem(newval, mem_ptr), 7702 OpcP, OpcS, 7703 reg_mem(newval, mem_ptr) // lock cmpxchg 7704 ); 7705 ins_pipe( pipe_cmpxchg ); 7706 %} 7707 7708 instruct compareAndExchangeP( 7709 memory mem_ptr, 7710 rax_RegP oldval, rRegP newval, 7711 rFlagsReg cr) 7712 %{ 7713 predicate(VM_Version::supports_cx8()); 7714 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7715 effect(KILL cr); 7716 7717 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7718 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7719 opcode(0x0F, 0xB1); 7720 ins_encode(lock_prefix, 7721 REX_reg_mem_wide(newval, mem_ptr), 7722 OpcP, OpcS, 7723 reg_mem(newval, mem_ptr) // lock cmpxchg 7724 ); 7725 ins_pipe( pipe_cmpxchg ); 7726 %} 7727 7728 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7729 predicate(n->as_LoadStore()->result_not_used()); 7730 match(Set dummy (GetAndAddB mem add)); 7731 effect(KILL cr); 7732 format %{ "ADDB [$mem],$add" %} 7733 ins_encode %{ 7734 if (os::is_MP()) { __ lock(); } 7735 __ addb($mem$$Address, $add$$constant); 7736 %} 7737 ins_pipe( pipe_cmpxchg ); 7738 %} 7739 7740 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7741 match(Set newval (GetAndAddB mem newval)); 7742 effect(KILL cr); 7743 format %{ "XADDB [$mem],$newval" %} 7744 ins_encode %{ 7745 if (os::is_MP()) { __ lock(); } 7746 __ xaddb($mem$$Address, $newval$$Register); 7747 %} 7748 ins_pipe( pipe_cmpxchg ); 7749 %} 7750 7751 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7752 predicate(n->as_LoadStore()->result_not_used()); 7753 match(Set dummy (GetAndAddS mem add)); 7754 effect(KILL cr); 7755 format %{ "ADDW [$mem],$add" %} 7756 ins_encode %{ 7757 if (os::is_MP()) { __ lock(); } 7758 __ addw($mem$$Address, $add$$constant); 7759 %} 7760 ins_pipe( pipe_cmpxchg ); 7761 %} 7762 7763 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7764 match(Set newval (GetAndAddS mem newval)); 7765 effect(KILL cr); 7766 format %{ "XADDW [$mem],$newval" %} 7767 ins_encode %{ 7768 if (os::is_MP()) { __ lock(); } 7769 __ xaddw($mem$$Address, $newval$$Register); 7770 %} 7771 ins_pipe( pipe_cmpxchg ); 7772 %} 7773 7774 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7775 predicate(n->as_LoadStore()->result_not_used()); 7776 match(Set dummy (GetAndAddI mem add)); 7777 effect(KILL cr); 7778 format %{ "ADDL [$mem],$add" %} 7779 ins_encode %{ 7780 if (os::is_MP()) { __ lock(); } 7781 __ addl($mem$$Address, $add$$constant); 7782 %} 7783 ins_pipe( pipe_cmpxchg ); 7784 %} 7785 7786 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7787 match(Set newval (GetAndAddI mem newval)); 7788 effect(KILL cr); 7789 format %{ "XADDL [$mem],$newval" %} 7790 ins_encode %{ 7791 if (os::is_MP()) { __ lock(); } 7792 __ xaddl($mem$$Address, $newval$$Register); 7793 %} 7794 ins_pipe( pipe_cmpxchg ); 7795 %} 7796 7797 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7798 predicate(n->as_LoadStore()->result_not_used()); 7799 match(Set dummy (GetAndAddL mem add)); 7800 effect(KILL cr); 7801 format %{ "ADDQ [$mem],$add" %} 7802 ins_encode %{ 7803 if (os::is_MP()) { __ lock(); } 7804 __ addq($mem$$Address, $add$$constant); 7805 %} 7806 ins_pipe( pipe_cmpxchg ); 7807 %} 7808 7809 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7810 match(Set newval (GetAndAddL mem newval)); 7811 effect(KILL cr); 7812 format %{ "XADDQ [$mem],$newval" %} 7813 ins_encode %{ 7814 if (os::is_MP()) { __ lock(); } 7815 __ xaddq($mem$$Address, $newval$$Register); 7816 %} 7817 ins_pipe( pipe_cmpxchg ); 7818 %} 7819 7820 instruct xchgB( memory mem, rRegI newval) %{ 7821 match(Set newval (GetAndSetB mem newval)); 7822 format %{ "XCHGB $newval,[$mem]" %} 7823 ins_encode %{ 7824 __ xchgb($newval$$Register, $mem$$Address); 7825 %} 7826 ins_pipe( pipe_cmpxchg ); 7827 %} 7828 7829 instruct xchgS( memory mem, rRegI newval) %{ 7830 match(Set newval (GetAndSetS mem newval)); 7831 format %{ "XCHGW $newval,[$mem]" %} 7832 ins_encode %{ 7833 __ xchgw($newval$$Register, $mem$$Address); 7834 %} 7835 ins_pipe( pipe_cmpxchg ); 7836 %} 7837 7838 instruct xchgI( memory mem, rRegI newval) %{ 7839 match(Set newval (GetAndSetI mem newval)); 7840 format %{ "XCHGL $newval,[$mem]" %} 7841 ins_encode %{ 7842 __ xchgl($newval$$Register, $mem$$Address); 7843 %} 7844 ins_pipe( pipe_cmpxchg ); 7845 %} 7846 7847 instruct xchgL( memory mem, rRegL newval) %{ 7848 match(Set newval (GetAndSetL mem newval)); 7849 format %{ "XCHGL $newval,[$mem]" %} 7850 ins_encode %{ 7851 __ xchgq($newval$$Register, $mem$$Address); 7852 %} 7853 ins_pipe( pipe_cmpxchg ); 7854 %} 7855 7856 instruct xchgP( memory mem, rRegP newval) %{ 7857 match(Set newval (GetAndSetP mem newval)); 7858 format %{ "XCHGQ $newval,[$mem]" %} 7859 ins_encode %{ 7860 __ xchgq($newval$$Register, $mem$$Address); 7861 %} 7862 ins_pipe( pipe_cmpxchg ); 7863 %} 7864 7865 instruct xchgN( memory mem, rRegN newval) %{ 7866 match(Set newval (GetAndSetN mem newval)); 7867 format %{ "XCHGL $newval,$mem]" %} 7868 ins_encode %{ 7869 __ xchgl($newval$$Register, $mem$$Address); 7870 %} 7871 ins_pipe( pipe_cmpxchg ); 7872 %} 7873 7874 //----------Subtraction Instructions------------------------------------------- 7875 7876 // Integer Subtraction Instructions 7877 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7878 %{ 7879 match(Set dst (SubI dst src)); 7880 effect(KILL cr); 7881 7882 format %{ "subl $dst, $src\t# int" %} 7883 opcode(0x2B); 7884 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7885 ins_pipe(ialu_reg_reg); 7886 %} 7887 7888 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7889 %{ 7890 match(Set dst (SubI dst src)); 7891 effect(KILL cr); 7892 7893 format %{ "subl $dst, $src\t# int" %} 7894 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7895 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7896 ins_pipe(ialu_reg); 7897 %} 7898 7899 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7900 %{ 7901 match(Set dst (SubI dst (LoadI src))); 7902 effect(KILL cr); 7903 7904 ins_cost(125); 7905 format %{ "subl $dst, $src\t# int" %} 7906 opcode(0x2B); 7907 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7908 ins_pipe(ialu_reg_mem); 7909 %} 7910 7911 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7912 %{ 7913 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7914 effect(KILL cr); 7915 7916 ins_cost(150); 7917 format %{ "subl $dst, $src\t# int" %} 7918 opcode(0x29); /* Opcode 29 /r */ 7919 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7920 ins_pipe(ialu_mem_reg); 7921 %} 7922 7923 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7924 %{ 7925 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7926 effect(KILL cr); 7927 7928 ins_cost(125); // XXX 7929 format %{ "subl $dst, $src\t# int" %} 7930 opcode(0x81); /* Opcode 81 /5 id */ 7931 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7932 ins_pipe(ialu_mem_imm); 7933 %} 7934 7935 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7936 %{ 7937 match(Set dst (SubL dst src)); 7938 effect(KILL cr); 7939 7940 format %{ "subq $dst, $src\t# long" %} 7941 opcode(0x2B); 7942 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7943 ins_pipe(ialu_reg_reg); 7944 %} 7945 7946 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7947 %{ 7948 match(Set dst (SubL dst src)); 7949 effect(KILL cr); 7950 7951 format %{ "subq $dst, $src\t# long" %} 7952 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7953 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7954 ins_pipe(ialu_reg); 7955 %} 7956 7957 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7958 %{ 7959 match(Set dst (SubL dst (LoadL src))); 7960 effect(KILL cr); 7961 7962 ins_cost(125); 7963 format %{ "subq $dst, $src\t# long" %} 7964 opcode(0x2B); 7965 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7966 ins_pipe(ialu_reg_mem); 7967 %} 7968 7969 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7970 %{ 7971 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7972 effect(KILL cr); 7973 7974 ins_cost(150); 7975 format %{ "subq $dst, $src\t# long" %} 7976 opcode(0x29); /* Opcode 29 /r */ 7977 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7978 ins_pipe(ialu_mem_reg); 7979 %} 7980 7981 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7982 %{ 7983 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7984 effect(KILL cr); 7985 7986 ins_cost(125); // XXX 7987 format %{ "subq $dst, $src\t# long" %} 7988 opcode(0x81); /* Opcode 81 /5 id */ 7989 ins_encode(REX_mem_wide(dst), 7990 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7991 ins_pipe(ialu_mem_imm); 7992 %} 7993 7994 // Subtract from a pointer 7995 // XXX hmpf??? 7996 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7997 %{ 7998 match(Set dst (AddP dst (SubI zero src))); 7999 effect(KILL cr); 8000 8001 format %{ "subq $dst, $src\t# ptr - int" %} 8002 opcode(0x2B); 8003 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8004 ins_pipe(ialu_reg_reg); 8005 %} 8006 8007 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8008 %{ 8009 match(Set dst (SubI zero dst)); 8010 effect(KILL cr); 8011 8012 format %{ "negl $dst\t# int" %} 8013 opcode(0xF7, 0x03); // Opcode F7 /3 8014 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8015 ins_pipe(ialu_reg); 8016 %} 8017 8018 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8019 %{ 8020 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8021 effect(KILL cr); 8022 8023 format %{ "negl $dst\t# int" %} 8024 opcode(0xF7, 0x03); // Opcode F7 /3 8025 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8026 ins_pipe(ialu_reg); 8027 %} 8028 8029 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8030 %{ 8031 match(Set dst (SubL zero dst)); 8032 effect(KILL cr); 8033 8034 format %{ "negq $dst\t# long" %} 8035 opcode(0xF7, 0x03); // Opcode F7 /3 8036 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8037 ins_pipe(ialu_reg); 8038 %} 8039 8040 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8041 %{ 8042 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8043 effect(KILL cr); 8044 8045 format %{ "negq $dst\t# long" %} 8046 opcode(0xF7, 0x03); // Opcode F7 /3 8047 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8048 ins_pipe(ialu_reg); 8049 %} 8050 8051 //----------Multiplication/Division Instructions------------------------------- 8052 // Integer Multiplication Instructions 8053 // Multiply Register 8054 8055 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8056 %{ 8057 match(Set dst (MulI dst src)); 8058 effect(KILL cr); 8059 8060 ins_cost(300); 8061 format %{ "imull $dst, $src\t# int" %} 8062 opcode(0x0F, 0xAF); 8063 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8064 ins_pipe(ialu_reg_reg_alu0); 8065 %} 8066 8067 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8068 %{ 8069 match(Set dst (MulI src imm)); 8070 effect(KILL cr); 8071 8072 ins_cost(300); 8073 format %{ "imull $dst, $src, $imm\t# int" %} 8074 opcode(0x69); /* 69 /r id */ 8075 ins_encode(REX_reg_reg(dst, src), 8076 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8077 ins_pipe(ialu_reg_reg_alu0); 8078 %} 8079 8080 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8081 %{ 8082 match(Set dst (MulI dst (LoadI src))); 8083 effect(KILL cr); 8084 8085 ins_cost(350); 8086 format %{ "imull $dst, $src\t# int" %} 8087 opcode(0x0F, 0xAF); 8088 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8089 ins_pipe(ialu_reg_mem_alu0); 8090 %} 8091 8092 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8093 %{ 8094 match(Set dst (MulI (LoadI src) imm)); 8095 effect(KILL cr); 8096 8097 ins_cost(300); 8098 format %{ "imull $dst, $src, $imm\t# int" %} 8099 opcode(0x69); /* 69 /r id */ 8100 ins_encode(REX_reg_mem(dst, src), 8101 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8102 ins_pipe(ialu_reg_mem_alu0); 8103 %} 8104 8105 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8106 %{ 8107 match(Set dst (MulL dst src)); 8108 effect(KILL cr); 8109 8110 ins_cost(300); 8111 format %{ "imulq $dst, $src\t# long" %} 8112 opcode(0x0F, 0xAF); 8113 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8114 ins_pipe(ialu_reg_reg_alu0); 8115 %} 8116 8117 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8118 %{ 8119 match(Set dst (MulL src imm)); 8120 effect(KILL cr); 8121 8122 ins_cost(300); 8123 format %{ "imulq $dst, $src, $imm\t# long" %} 8124 opcode(0x69); /* 69 /r id */ 8125 ins_encode(REX_reg_reg_wide(dst, src), 8126 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8127 ins_pipe(ialu_reg_reg_alu0); 8128 %} 8129 8130 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8131 %{ 8132 match(Set dst (MulL dst (LoadL src))); 8133 effect(KILL cr); 8134 8135 ins_cost(350); 8136 format %{ "imulq $dst, $src\t# long" %} 8137 opcode(0x0F, 0xAF); 8138 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8139 ins_pipe(ialu_reg_mem_alu0); 8140 %} 8141 8142 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8143 %{ 8144 match(Set dst (MulL (LoadL src) imm)); 8145 effect(KILL cr); 8146 8147 ins_cost(300); 8148 format %{ "imulq $dst, $src, $imm\t# long" %} 8149 opcode(0x69); /* 69 /r id */ 8150 ins_encode(REX_reg_mem_wide(dst, src), 8151 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8152 ins_pipe(ialu_reg_mem_alu0); 8153 %} 8154 8155 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8156 %{ 8157 match(Set dst (MulHiL src rax)); 8158 effect(USE_KILL rax, KILL cr); 8159 8160 ins_cost(300); 8161 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8162 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8163 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8164 ins_pipe(ialu_reg_reg_alu0); 8165 %} 8166 8167 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8168 rFlagsReg cr) 8169 %{ 8170 match(Set rax (DivI rax div)); 8171 effect(KILL rdx, KILL cr); 8172 8173 ins_cost(30*100+10*100); // XXX 8174 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8175 "jne,s normal\n\t" 8176 "xorl rdx, rdx\n\t" 8177 "cmpl $div, -1\n\t" 8178 "je,s done\n" 8179 "normal: cdql\n\t" 8180 "idivl $div\n" 8181 "done:" %} 8182 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8183 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8184 ins_pipe(ialu_reg_reg_alu0); 8185 %} 8186 8187 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8188 rFlagsReg cr) 8189 %{ 8190 match(Set rax (DivL rax div)); 8191 effect(KILL rdx, KILL cr); 8192 8193 ins_cost(30*100+10*100); // XXX 8194 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8195 "cmpq rax, rdx\n\t" 8196 "jne,s normal\n\t" 8197 "xorl rdx, rdx\n\t" 8198 "cmpq $div, -1\n\t" 8199 "je,s done\n" 8200 "normal: cdqq\n\t" 8201 "idivq $div\n" 8202 "done:" %} 8203 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8204 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8205 ins_pipe(ialu_reg_reg_alu0); 8206 %} 8207 8208 // Integer DIVMOD with Register, both quotient and mod results 8209 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8210 rFlagsReg cr) 8211 %{ 8212 match(DivModI rax div); 8213 effect(KILL cr); 8214 8215 ins_cost(30*100+10*100); // XXX 8216 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8217 "jne,s normal\n\t" 8218 "xorl rdx, rdx\n\t" 8219 "cmpl $div, -1\n\t" 8220 "je,s done\n" 8221 "normal: cdql\n\t" 8222 "idivl $div\n" 8223 "done:" %} 8224 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8225 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8226 ins_pipe(pipe_slow); 8227 %} 8228 8229 // Long DIVMOD with Register, both quotient and mod results 8230 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8231 rFlagsReg cr) 8232 %{ 8233 match(DivModL rax div); 8234 effect(KILL cr); 8235 8236 ins_cost(30*100+10*100); // XXX 8237 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8238 "cmpq rax, rdx\n\t" 8239 "jne,s normal\n\t" 8240 "xorl rdx, rdx\n\t" 8241 "cmpq $div, -1\n\t" 8242 "je,s done\n" 8243 "normal: cdqq\n\t" 8244 "idivq $div\n" 8245 "done:" %} 8246 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8247 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8248 ins_pipe(pipe_slow); 8249 %} 8250 8251 //----------- DivL-By-Constant-Expansions-------------------------------------- 8252 // DivI cases are handled by the compiler 8253 8254 // Magic constant, reciprocal of 10 8255 instruct loadConL_0x6666666666666667(rRegL dst) 8256 %{ 8257 effect(DEF dst); 8258 8259 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8260 ins_encode(load_immL(dst, 0x6666666666666667)); 8261 ins_pipe(ialu_reg); 8262 %} 8263 8264 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8265 %{ 8266 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8267 8268 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8269 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8270 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8271 ins_pipe(ialu_reg_reg_alu0); 8272 %} 8273 8274 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8275 %{ 8276 effect(USE_DEF dst, KILL cr); 8277 8278 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8279 opcode(0xC1, 0x7); /* C1 /7 ib */ 8280 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8281 ins_pipe(ialu_reg); 8282 %} 8283 8284 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8285 %{ 8286 effect(USE_DEF dst, KILL cr); 8287 8288 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8289 opcode(0xC1, 0x7); /* C1 /7 ib */ 8290 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8291 ins_pipe(ialu_reg); 8292 %} 8293 8294 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8295 %{ 8296 match(Set dst (DivL src div)); 8297 8298 ins_cost((5+8)*100); 8299 expand %{ 8300 rax_RegL rax; // Killed temp 8301 rFlagsReg cr; // Killed 8302 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8303 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8304 sarL_rReg_63(src, cr); // sarq src, 63 8305 sarL_rReg_2(dst, cr); // sarq rdx, 2 8306 subL_rReg(dst, src, cr); // subl rdx, src 8307 %} 8308 %} 8309 8310 //----------------------------------------------------------------------------- 8311 8312 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8313 rFlagsReg cr) 8314 %{ 8315 match(Set rdx (ModI rax div)); 8316 effect(KILL rax, KILL cr); 8317 8318 ins_cost(300); // XXX 8319 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8320 "jne,s normal\n\t" 8321 "xorl rdx, rdx\n\t" 8322 "cmpl $div, -1\n\t" 8323 "je,s done\n" 8324 "normal: cdql\n\t" 8325 "idivl $div\n" 8326 "done:" %} 8327 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8328 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8329 ins_pipe(ialu_reg_reg_alu0); 8330 %} 8331 8332 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8333 rFlagsReg cr) 8334 %{ 8335 match(Set rdx (ModL rax div)); 8336 effect(KILL rax, KILL cr); 8337 8338 ins_cost(300); // XXX 8339 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8340 "cmpq rax, rdx\n\t" 8341 "jne,s normal\n\t" 8342 "xorl rdx, rdx\n\t" 8343 "cmpq $div, -1\n\t" 8344 "je,s done\n" 8345 "normal: cdqq\n\t" 8346 "idivq $div\n" 8347 "done:" %} 8348 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8349 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8350 ins_pipe(ialu_reg_reg_alu0); 8351 %} 8352 8353 // Integer Shift Instructions 8354 // Shift Left by one 8355 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8356 %{ 8357 match(Set dst (LShiftI dst shift)); 8358 effect(KILL cr); 8359 8360 format %{ "sall $dst, $shift" %} 8361 opcode(0xD1, 0x4); /* D1 /4 */ 8362 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8363 ins_pipe(ialu_reg); 8364 %} 8365 8366 // Shift Left by one 8367 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8368 %{ 8369 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8370 effect(KILL cr); 8371 8372 format %{ "sall $dst, $shift\t" %} 8373 opcode(0xD1, 0x4); /* D1 /4 */ 8374 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8375 ins_pipe(ialu_mem_imm); 8376 %} 8377 8378 // Shift Left by 8-bit immediate 8379 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8380 %{ 8381 match(Set dst (LShiftI dst shift)); 8382 effect(KILL cr); 8383 8384 format %{ "sall $dst, $shift" %} 8385 opcode(0xC1, 0x4); /* C1 /4 ib */ 8386 ins_encode(reg_opc_imm(dst, shift)); 8387 ins_pipe(ialu_reg); 8388 %} 8389 8390 // Shift Left by 8-bit immediate 8391 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8392 %{ 8393 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8394 effect(KILL cr); 8395 8396 format %{ "sall $dst, $shift" %} 8397 opcode(0xC1, 0x4); /* C1 /4 ib */ 8398 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8399 ins_pipe(ialu_mem_imm); 8400 %} 8401 8402 // Shift Left by variable 8403 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8404 %{ 8405 match(Set dst (LShiftI dst shift)); 8406 effect(KILL cr); 8407 8408 format %{ "sall $dst, $shift" %} 8409 opcode(0xD3, 0x4); /* D3 /4 */ 8410 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8411 ins_pipe(ialu_reg_reg); 8412 %} 8413 8414 // Shift Left by variable 8415 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8416 %{ 8417 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8418 effect(KILL cr); 8419 8420 format %{ "sall $dst, $shift" %} 8421 opcode(0xD3, 0x4); /* D3 /4 */ 8422 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8423 ins_pipe(ialu_mem_reg); 8424 %} 8425 8426 // Arithmetic shift right by one 8427 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8428 %{ 8429 match(Set dst (RShiftI dst shift)); 8430 effect(KILL cr); 8431 8432 format %{ "sarl $dst, $shift" %} 8433 opcode(0xD1, 0x7); /* D1 /7 */ 8434 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8435 ins_pipe(ialu_reg); 8436 %} 8437 8438 // Arithmetic shift right by one 8439 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8440 %{ 8441 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8442 effect(KILL cr); 8443 8444 format %{ "sarl $dst, $shift" %} 8445 opcode(0xD1, 0x7); /* D1 /7 */ 8446 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8447 ins_pipe(ialu_mem_imm); 8448 %} 8449 8450 // Arithmetic Shift Right by 8-bit immediate 8451 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8452 %{ 8453 match(Set dst (RShiftI dst shift)); 8454 effect(KILL cr); 8455 8456 format %{ "sarl $dst, $shift" %} 8457 opcode(0xC1, 0x7); /* C1 /7 ib */ 8458 ins_encode(reg_opc_imm(dst, shift)); 8459 ins_pipe(ialu_mem_imm); 8460 %} 8461 8462 // Arithmetic Shift Right by 8-bit immediate 8463 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8464 %{ 8465 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8466 effect(KILL cr); 8467 8468 format %{ "sarl $dst, $shift" %} 8469 opcode(0xC1, 0x7); /* C1 /7 ib */ 8470 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8471 ins_pipe(ialu_mem_imm); 8472 %} 8473 8474 // Arithmetic Shift Right by variable 8475 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8476 %{ 8477 match(Set dst (RShiftI dst shift)); 8478 effect(KILL cr); 8479 8480 format %{ "sarl $dst, $shift" %} 8481 opcode(0xD3, 0x7); /* D3 /7 */ 8482 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8483 ins_pipe(ialu_reg_reg); 8484 %} 8485 8486 // Arithmetic Shift Right by variable 8487 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8488 %{ 8489 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8490 effect(KILL cr); 8491 8492 format %{ "sarl $dst, $shift" %} 8493 opcode(0xD3, 0x7); /* D3 /7 */ 8494 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8495 ins_pipe(ialu_mem_reg); 8496 %} 8497 8498 // Logical shift right by one 8499 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8500 %{ 8501 match(Set dst (URShiftI dst shift)); 8502 effect(KILL cr); 8503 8504 format %{ "shrl $dst, $shift" %} 8505 opcode(0xD1, 0x5); /* D1 /5 */ 8506 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8507 ins_pipe(ialu_reg); 8508 %} 8509 8510 // Logical shift right by one 8511 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8512 %{ 8513 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8514 effect(KILL cr); 8515 8516 format %{ "shrl $dst, $shift" %} 8517 opcode(0xD1, 0x5); /* D1 /5 */ 8518 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8519 ins_pipe(ialu_mem_imm); 8520 %} 8521 8522 // Logical Shift Right by 8-bit immediate 8523 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8524 %{ 8525 match(Set dst (URShiftI dst shift)); 8526 effect(KILL cr); 8527 8528 format %{ "shrl $dst, $shift" %} 8529 opcode(0xC1, 0x5); /* C1 /5 ib */ 8530 ins_encode(reg_opc_imm(dst, shift)); 8531 ins_pipe(ialu_reg); 8532 %} 8533 8534 // Logical Shift Right by 8-bit immediate 8535 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8536 %{ 8537 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8538 effect(KILL cr); 8539 8540 format %{ "shrl $dst, $shift" %} 8541 opcode(0xC1, 0x5); /* C1 /5 ib */ 8542 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8543 ins_pipe(ialu_mem_imm); 8544 %} 8545 8546 // Logical Shift Right by variable 8547 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8548 %{ 8549 match(Set dst (URShiftI dst shift)); 8550 effect(KILL cr); 8551 8552 format %{ "shrl $dst, $shift" %} 8553 opcode(0xD3, 0x5); /* D3 /5 */ 8554 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8555 ins_pipe(ialu_reg_reg); 8556 %} 8557 8558 // Logical Shift Right by variable 8559 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8560 %{ 8561 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8562 effect(KILL cr); 8563 8564 format %{ "shrl $dst, $shift" %} 8565 opcode(0xD3, 0x5); /* D3 /5 */ 8566 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8567 ins_pipe(ialu_mem_reg); 8568 %} 8569 8570 // Long Shift Instructions 8571 // Shift Left by one 8572 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8573 %{ 8574 match(Set dst (LShiftL dst shift)); 8575 effect(KILL cr); 8576 8577 format %{ "salq $dst, $shift" %} 8578 opcode(0xD1, 0x4); /* D1 /4 */ 8579 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8580 ins_pipe(ialu_reg); 8581 %} 8582 8583 // Shift Left by one 8584 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8585 %{ 8586 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8587 effect(KILL cr); 8588 8589 format %{ "salq $dst, $shift" %} 8590 opcode(0xD1, 0x4); /* D1 /4 */ 8591 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8592 ins_pipe(ialu_mem_imm); 8593 %} 8594 8595 // Shift Left by 8-bit immediate 8596 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8597 %{ 8598 match(Set dst (LShiftL dst shift)); 8599 effect(KILL cr); 8600 8601 format %{ "salq $dst, $shift" %} 8602 opcode(0xC1, 0x4); /* C1 /4 ib */ 8603 ins_encode(reg_opc_imm_wide(dst, shift)); 8604 ins_pipe(ialu_reg); 8605 %} 8606 8607 // Shift Left by 8-bit immediate 8608 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8609 %{ 8610 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8611 effect(KILL cr); 8612 8613 format %{ "salq $dst, $shift" %} 8614 opcode(0xC1, 0x4); /* C1 /4 ib */ 8615 ins_encode(REX_mem_wide(dst), OpcP, 8616 RM_opc_mem(secondary, dst), Con8or32(shift)); 8617 ins_pipe(ialu_mem_imm); 8618 %} 8619 8620 // Shift Left by variable 8621 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8622 %{ 8623 match(Set dst (LShiftL dst shift)); 8624 effect(KILL cr); 8625 8626 format %{ "salq $dst, $shift" %} 8627 opcode(0xD3, 0x4); /* D3 /4 */ 8628 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8629 ins_pipe(ialu_reg_reg); 8630 %} 8631 8632 // Shift Left by variable 8633 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8634 %{ 8635 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8636 effect(KILL cr); 8637 8638 format %{ "salq $dst, $shift" %} 8639 opcode(0xD3, 0x4); /* D3 /4 */ 8640 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8641 ins_pipe(ialu_mem_reg); 8642 %} 8643 8644 // Arithmetic shift right by one 8645 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8646 %{ 8647 match(Set dst (RShiftL dst shift)); 8648 effect(KILL cr); 8649 8650 format %{ "sarq $dst, $shift" %} 8651 opcode(0xD1, 0x7); /* D1 /7 */ 8652 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8653 ins_pipe(ialu_reg); 8654 %} 8655 8656 // Arithmetic shift right by one 8657 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8658 %{ 8659 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8660 effect(KILL cr); 8661 8662 format %{ "sarq $dst, $shift" %} 8663 opcode(0xD1, 0x7); /* D1 /7 */ 8664 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8665 ins_pipe(ialu_mem_imm); 8666 %} 8667 8668 // Arithmetic Shift Right by 8-bit immediate 8669 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8670 %{ 8671 match(Set dst (RShiftL dst shift)); 8672 effect(KILL cr); 8673 8674 format %{ "sarq $dst, $shift" %} 8675 opcode(0xC1, 0x7); /* C1 /7 ib */ 8676 ins_encode(reg_opc_imm_wide(dst, shift)); 8677 ins_pipe(ialu_mem_imm); 8678 %} 8679 8680 // Arithmetic Shift Right by 8-bit immediate 8681 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8682 %{ 8683 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8684 effect(KILL cr); 8685 8686 format %{ "sarq $dst, $shift" %} 8687 opcode(0xC1, 0x7); /* C1 /7 ib */ 8688 ins_encode(REX_mem_wide(dst), OpcP, 8689 RM_opc_mem(secondary, dst), Con8or32(shift)); 8690 ins_pipe(ialu_mem_imm); 8691 %} 8692 8693 // Arithmetic Shift Right by variable 8694 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8695 %{ 8696 match(Set dst (RShiftL dst shift)); 8697 effect(KILL cr); 8698 8699 format %{ "sarq $dst, $shift" %} 8700 opcode(0xD3, 0x7); /* D3 /7 */ 8701 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8702 ins_pipe(ialu_reg_reg); 8703 %} 8704 8705 // Arithmetic Shift Right by variable 8706 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8707 %{ 8708 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8709 effect(KILL cr); 8710 8711 format %{ "sarq $dst, $shift" %} 8712 opcode(0xD3, 0x7); /* D3 /7 */ 8713 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8714 ins_pipe(ialu_mem_reg); 8715 %} 8716 8717 // Logical shift right by one 8718 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8719 %{ 8720 match(Set dst (URShiftL dst shift)); 8721 effect(KILL cr); 8722 8723 format %{ "shrq $dst, $shift" %} 8724 opcode(0xD1, 0x5); /* D1 /5 */ 8725 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8726 ins_pipe(ialu_reg); 8727 %} 8728 8729 // Logical shift right by one 8730 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8731 %{ 8732 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8733 effect(KILL cr); 8734 8735 format %{ "shrq $dst, $shift" %} 8736 opcode(0xD1, 0x5); /* D1 /5 */ 8737 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8738 ins_pipe(ialu_mem_imm); 8739 %} 8740 8741 // Logical Shift Right by 8-bit immediate 8742 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8743 %{ 8744 match(Set dst (URShiftL dst shift)); 8745 effect(KILL cr); 8746 8747 format %{ "shrq $dst, $shift" %} 8748 opcode(0xC1, 0x5); /* C1 /5 ib */ 8749 ins_encode(reg_opc_imm_wide(dst, shift)); 8750 ins_pipe(ialu_reg); 8751 %} 8752 8753 8754 // Logical Shift Right by 8-bit immediate 8755 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8756 %{ 8757 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8758 effect(KILL cr); 8759 8760 format %{ "shrq $dst, $shift" %} 8761 opcode(0xC1, 0x5); /* C1 /5 ib */ 8762 ins_encode(REX_mem_wide(dst), OpcP, 8763 RM_opc_mem(secondary, dst), Con8or32(shift)); 8764 ins_pipe(ialu_mem_imm); 8765 %} 8766 8767 // Logical Shift Right by variable 8768 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8769 %{ 8770 match(Set dst (URShiftL dst shift)); 8771 effect(KILL cr); 8772 8773 format %{ "shrq $dst, $shift" %} 8774 opcode(0xD3, 0x5); /* D3 /5 */ 8775 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8776 ins_pipe(ialu_reg_reg); 8777 %} 8778 8779 // Logical Shift Right by variable 8780 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8781 %{ 8782 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8783 effect(KILL cr); 8784 8785 format %{ "shrq $dst, $shift" %} 8786 opcode(0xD3, 0x5); /* D3 /5 */ 8787 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8788 ins_pipe(ialu_mem_reg); 8789 %} 8790 8791 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8792 // This idiom is used by the compiler for the i2b bytecode. 8793 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8794 %{ 8795 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8796 8797 format %{ "movsbl $dst, $src\t# i2b" %} 8798 opcode(0x0F, 0xBE); 8799 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8800 ins_pipe(ialu_reg_reg); 8801 %} 8802 8803 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8804 // This idiom is used by the compiler the i2s bytecode. 8805 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8806 %{ 8807 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8808 8809 format %{ "movswl $dst, $src\t# i2s" %} 8810 opcode(0x0F, 0xBF); 8811 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8812 ins_pipe(ialu_reg_reg); 8813 %} 8814 8815 // ROL/ROR instructions 8816 8817 // ROL expand 8818 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8819 effect(KILL cr, USE_DEF dst); 8820 8821 format %{ "roll $dst" %} 8822 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8823 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8824 ins_pipe(ialu_reg); 8825 %} 8826 8827 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8828 effect(USE_DEF dst, USE shift, KILL cr); 8829 8830 format %{ "roll $dst, $shift" %} 8831 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8832 ins_encode( reg_opc_imm(dst, shift) ); 8833 ins_pipe(ialu_reg); 8834 %} 8835 8836 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8837 %{ 8838 effect(USE_DEF dst, USE shift, KILL cr); 8839 8840 format %{ "roll $dst, $shift" %} 8841 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8842 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8843 ins_pipe(ialu_reg_reg); 8844 %} 8845 // end of ROL expand 8846 8847 // Rotate Left by one 8848 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8849 %{ 8850 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8851 8852 expand %{ 8853 rolI_rReg_imm1(dst, cr); 8854 %} 8855 %} 8856 8857 // Rotate Left by 8-bit immediate 8858 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8859 %{ 8860 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8861 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8862 8863 expand %{ 8864 rolI_rReg_imm8(dst, lshift, cr); 8865 %} 8866 %} 8867 8868 // Rotate Left by variable 8869 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8870 %{ 8871 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8872 8873 expand %{ 8874 rolI_rReg_CL(dst, shift, cr); 8875 %} 8876 %} 8877 8878 // Rotate Left by variable 8879 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8880 %{ 8881 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8882 8883 expand %{ 8884 rolI_rReg_CL(dst, shift, cr); 8885 %} 8886 %} 8887 8888 // ROR expand 8889 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8890 %{ 8891 effect(USE_DEF dst, KILL cr); 8892 8893 format %{ "rorl $dst" %} 8894 opcode(0xD1, 0x1); /* D1 /1 */ 8895 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8896 ins_pipe(ialu_reg); 8897 %} 8898 8899 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8900 %{ 8901 effect(USE_DEF dst, USE shift, KILL cr); 8902 8903 format %{ "rorl $dst, $shift" %} 8904 opcode(0xC1, 0x1); /* C1 /1 ib */ 8905 ins_encode(reg_opc_imm(dst, shift)); 8906 ins_pipe(ialu_reg); 8907 %} 8908 8909 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8910 %{ 8911 effect(USE_DEF dst, USE shift, KILL cr); 8912 8913 format %{ "rorl $dst, $shift" %} 8914 opcode(0xD3, 0x1); /* D3 /1 */ 8915 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8916 ins_pipe(ialu_reg_reg); 8917 %} 8918 // end of ROR expand 8919 8920 // Rotate Right by one 8921 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8922 %{ 8923 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8924 8925 expand %{ 8926 rorI_rReg_imm1(dst, cr); 8927 %} 8928 %} 8929 8930 // Rotate Right by 8-bit immediate 8931 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8932 %{ 8933 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8934 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8935 8936 expand %{ 8937 rorI_rReg_imm8(dst, rshift, cr); 8938 %} 8939 %} 8940 8941 // Rotate Right by variable 8942 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8943 %{ 8944 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8945 8946 expand %{ 8947 rorI_rReg_CL(dst, shift, cr); 8948 %} 8949 %} 8950 8951 // Rotate Right by variable 8952 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8953 %{ 8954 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8955 8956 expand %{ 8957 rorI_rReg_CL(dst, shift, cr); 8958 %} 8959 %} 8960 8961 // for long rotate 8962 // ROL expand 8963 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8964 effect(USE_DEF dst, KILL cr); 8965 8966 format %{ "rolq $dst" %} 8967 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8968 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8969 ins_pipe(ialu_reg); 8970 %} 8971 8972 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8973 effect(USE_DEF dst, USE shift, KILL cr); 8974 8975 format %{ "rolq $dst, $shift" %} 8976 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8977 ins_encode( reg_opc_imm_wide(dst, shift) ); 8978 ins_pipe(ialu_reg); 8979 %} 8980 8981 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8982 %{ 8983 effect(USE_DEF dst, USE shift, KILL cr); 8984 8985 format %{ "rolq $dst, $shift" %} 8986 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8987 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8988 ins_pipe(ialu_reg_reg); 8989 %} 8990 // end of ROL expand 8991 8992 // Rotate Left by one 8993 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8994 %{ 8995 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8996 8997 expand %{ 8998 rolL_rReg_imm1(dst, cr); 8999 %} 9000 %} 9001 9002 // Rotate Left by 8-bit immediate 9003 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9004 %{ 9005 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9006 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9007 9008 expand %{ 9009 rolL_rReg_imm8(dst, lshift, cr); 9010 %} 9011 %} 9012 9013 // Rotate Left by variable 9014 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9015 %{ 9016 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9017 9018 expand %{ 9019 rolL_rReg_CL(dst, shift, cr); 9020 %} 9021 %} 9022 9023 // Rotate Left by variable 9024 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9025 %{ 9026 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9027 9028 expand %{ 9029 rolL_rReg_CL(dst, shift, cr); 9030 %} 9031 %} 9032 9033 // ROR expand 9034 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9035 %{ 9036 effect(USE_DEF dst, KILL cr); 9037 9038 format %{ "rorq $dst" %} 9039 opcode(0xD1, 0x1); /* D1 /1 */ 9040 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9041 ins_pipe(ialu_reg); 9042 %} 9043 9044 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9045 %{ 9046 effect(USE_DEF dst, USE shift, KILL cr); 9047 9048 format %{ "rorq $dst, $shift" %} 9049 opcode(0xC1, 0x1); /* C1 /1 ib */ 9050 ins_encode(reg_opc_imm_wide(dst, shift)); 9051 ins_pipe(ialu_reg); 9052 %} 9053 9054 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9055 %{ 9056 effect(USE_DEF dst, USE shift, KILL cr); 9057 9058 format %{ "rorq $dst, $shift" %} 9059 opcode(0xD3, 0x1); /* D3 /1 */ 9060 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9061 ins_pipe(ialu_reg_reg); 9062 %} 9063 // end of ROR expand 9064 9065 // Rotate Right by one 9066 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9067 %{ 9068 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9069 9070 expand %{ 9071 rorL_rReg_imm1(dst, cr); 9072 %} 9073 %} 9074 9075 // Rotate Right by 8-bit immediate 9076 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9077 %{ 9078 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9079 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9080 9081 expand %{ 9082 rorL_rReg_imm8(dst, rshift, cr); 9083 %} 9084 %} 9085 9086 // Rotate Right by variable 9087 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9088 %{ 9089 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9090 9091 expand %{ 9092 rorL_rReg_CL(dst, shift, cr); 9093 %} 9094 %} 9095 9096 // Rotate Right by variable 9097 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9098 %{ 9099 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9100 9101 expand %{ 9102 rorL_rReg_CL(dst, shift, cr); 9103 %} 9104 %} 9105 9106 // Logical Instructions 9107 9108 // Integer Logical Instructions 9109 9110 // And Instructions 9111 // And Register with Register 9112 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9113 %{ 9114 match(Set dst (AndI dst src)); 9115 effect(KILL cr); 9116 9117 format %{ "andl $dst, $src\t# int" %} 9118 opcode(0x23); 9119 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9120 ins_pipe(ialu_reg_reg); 9121 %} 9122 9123 // And Register with Immediate 255 9124 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9125 %{ 9126 match(Set dst (AndI dst src)); 9127 9128 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9129 opcode(0x0F, 0xB6); 9130 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9131 ins_pipe(ialu_reg); 9132 %} 9133 9134 // And Register with Immediate 255 and promote to long 9135 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9136 %{ 9137 match(Set dst (ConvI2L (AndI src mask))); 9138 9139 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9140 opcode(0x0F, 0xB6); 9141 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9142 ins_pipe(ialu_reg); 9143 %} 9144 9145 // And Register with Immediate 65535 9146 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9147 %{ 9148 match(Set dst (AndI dst src)); 9149 9150 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9151 opcode(0x0F, 0xB7); 9152 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9153 ins_pipe(ialu_reg); 9154 %} 9155 9156 // And Register with Immediate 65535 and promote to long 9157 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9158 %{ 9159 match(Set dst (ConvI2L (AndI src mask))); 9160 9161 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9162 opcode(0x0F, 0xB7); 9163 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9164 ins_pipe(ialu_reg); 9165 %} 9166 9167 // And Register with Immediate 9168 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9169 %{ 9170 match(Set dst (AndI dst src)); 9171 effect(KILL cr); 9172 9173 format %{ "andl $dst, $src\t# int" %} 9174 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9175 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9176 ins_pipe(ialu_reg); 9177 %} 9178 9179 // And Register with Memory 9180 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9181 %{ 9182 match(Set dst (AndI dst (LoadI src))); 9183 effect(KILL cr); 9184 9185 ins_cost(125); 9186 format %{ "andl $dst, $src\t# int" %} 9187 opcode(0x23); 9188 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9189 ins_pipe(ialu_reg_mem); 9190 %} 9191 9192 // And Memory with Register 9193 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9194 %{ 9195 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9196 effect(KILL cr); 9197 9198 ins_cost(150); 9199 format %{ "andl $dst, $src\t# int" %} 9200 opcode(0x21); /* Opcode 21 /r */ 9201 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9202 ins_pipe(ialu_mem_reg); 9203 %} 9204 9205 // And Memory with Immediate 9206 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9207 %{ 9208 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9209 effect(KILL cr); 9210 9211 ins_cost(125); 9212 format %{ "andl $dst, $src\t# int" %} 9213 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9214 ins_encode(REX_mem(dst), OpcSE(src), 9215 RM_opc_mem(secondary, dst), Con8or32(src)); 9216 ins_pipe(ialu_mem_imm); 9217 %} 9218 9219 // BMI1 instructions 9220 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9221 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9222 predicate(UseBMI1Instructions); 9223 effect(KILL cr); 9224 9225 ins_cost(125); 9226 format %{ "andnl $dst, $src1, $src2" %} 9227 9228 ins_encode %{ 9229 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9230 %} 9231 ins_pipe(ialu_reg_mem); 9232 %} 9233 9234 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9235 match(Set dst (AndI (XorI src1 minus_1) src2)); 9236 predicate(UseBMI1Instructions); 9237 effect(KILL cr); 9238 9239 format %{ "andnl $dst, $src1, $src2" %} 9240 9241 ins_encode %{ 9242 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9243 %} 9244 ins_pipe(ialu_reg); 9245 %} 9246 9247 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9248 match(Set dst (AndI (SubI imm_zero src) src)); 9249 predicate(UseBMI1Instructions); 9250 effect(KILL cr); 9251 9252 format %{ "blsil $dst, $src" %} 9253 9254 ins_encode %{ 9255 __ blsil($dst$$Register, $src$$Register); 9256 %} 9257 ins_pipe(ialu_reg); 9258 %} 9259 9260 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9261 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9262 predicate(UseBMI1Instructions); 9263 effect(KILL cr); 9264 9265 ins_cost(125); 9266 format %{ "blsil $dst, $src" %} 9267 9268 ins_encode %{ 9269 __ blsil($dst$$Register, $src$$Address); 9270 %} 9271 ins_pipe(ialu_reg_mem); 9272 %} 9273 9274 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9275 %{ 9276 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9277 predicate(UseBMI1Instructions); 9278 effect(KILL cr); 9279 9280 ins_cost(125); 9281 format %{ "blsmskl $dst, $src" %} 9282 9283 ins_encode %{ 9284 __ blsmskl($dst$$Register, $src$$Address); 9285 %} 9286 ins_pipe(ialu_reg_mem); 9287 %} 9288 9289 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9290 %{ 9291 match(Set dst (XorI (AddI src minus_1) src)); 9292 predicate(UseBMI1Instructions); 9293 effect(KILL cr); 9294 9295 format %{ "blsmskl $dst, $src" %} 9296 9297 ins_encode %{ 9298 __ blsmskl($dst$$Register, $src$$Register); 9299 %} 9300 9301 ins_pipe(ialu_reg); 9302 %} 9303 9304 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9305 %{ 9306 match(Set dst (AndI (AddI src minus_1) src) ); 9307 predicate(UseBMI1Instructions); 9308 effect(KILL cr); 9309 9310 format %{ "blsrl $dst, $src" %} 9311 9312 ins_encode %{ 9313 __ blsrl($dst$$Register, $src$$Register); 9314 %} 9315 9316 ins_pipe(ialu_reg_mem); 9317 %} 9318 9319 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9320 %{ 9321 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9322 predicate(UseBMI1Instructions); 9323 effect(KILL cr); 9324 9325 ins_cost(125); 9326 format %{ "blsrl $dst, $src" %} 9327 9328 ins_encode %{ 9329 __ blsrl($dst$$Register, $src$$Address); 9330 %} 9331 9332 ins_pipe(ialu_reg); 9333 %} 9334 9335 // Or Instructions 9336 // Or Register with Register 9337 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9338 %{ 9339 match(Set dst (OrI dst src)); 9340 effect(KILL cr); 9341 9342 format %{ "orl $dst, $src\t# int" %} 9343 opcode(0x0B); 9344 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9345 ins_pipe(ialu_reg_reg); 9346 %} 9347 9348 // Or Register with Immediate 9349 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9350 %{ 9351 match(Set dst (OrI dst src)); 9352 effect(KILL cr); 9353 9354 format %{ "orl $dst, $src\t# int" %} 9355 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9356 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9357 ins_pipe(ialu_reg); 9358 %} 9359 9360 // Or Register with Memory 9361 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9362 %{ 9363 match(Set dst (OrI dst (LoadI src))); 9364 effect(KILL cr); 9365 9366 ins_cost(125); 9367 format %{ "orl $dst, $src\t# int" %} 9368 opcode(0x0B); 9369 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9370 ins_pipe(ialu_reg_mem); 9371 %} 9372 9373 // Or Memory with Register 9374 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9375 %{ 9376 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9377 effect(KILL cr); 9378 9379 ins_cost(150); 9380 format %{ "orl $dst, $src\t# int" %} 9381 opcode(0x09); /* Opcode 09 /r */ 9382 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9383 ins_pipe(ialu_mem_reg); 9384 %} 9385 9386 // Or Memory with Immediate 9387 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9388 %{ 9389 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9390 effect(KILL cr); 9391 9392 ins_cost(125); 9393 format %{ "orl $dst, $src\t# int" %} 9394 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9395 ins_encode(REX_mem(dst), OpcSE(src), 9396 RM_opc_mem(secondary, dst), Con8or32(src)); 9397 ins_pipe(ialu_mem_imm); 9398 %} 9399 9400 // Xor Instructions 9401 // Xor Register with Register 9402 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9403 %{ 9404 match(Set dst (XorI dst src)); 9405 effect(KILL cr); 9406 9407 format %{ "xorl $dst, $src\t# int" %} 9408 opcode(0x33); 9409 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9410 ins_pipe(ialu_reg_reg); 9411 %} 9412 9413 // Xor Register with Immediate -1 9414 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9415 match(Set dst (XorI dst imm)); 9416 9417 format %{ "not $dst" %} 9418 ins_encode %{ 9419 __ notl($dst$$Register); 9420 %} 9421 ins_pipe(ialu_reg); 9422 %} 9423 9424 // Xor Register with Immediate 9425 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9426 %{ 9427 match(Set dst (XorI dst src)); 9428 effect(KILL cr); 9429 9430 format %{ "xorl $dst, $src\t# int" %} 9431 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9432 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9433 ins_pipe(ialu_reg); 9434 %} 9435 9436 // Xor Register with Memory 9437 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9438 %{ 9439 match(Set dst (XorI dst (LoadI src))); 9440 effect(KILL cr); 9441 9442 ins_cost(125); 9443 format %{ "xorl $dst, $src\t# int" %} 9444 opcode(0x33); 9445 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9446 ins_pipe(ialu_reg_mem); 9447 %} 9448 9449 // Xor Memory with Register 9450 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9451 %{ 9452 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9453 effect(KILL cr); 9454 9455 ins_cost(150); 9456 format %{ "xorl $dst, $src\t# int" %} 9457 opcode(0x31); /* Opcode 31 /r */ 9458 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9459 ins_pipe(ialu_mem_reg); 9460 %} 9461 9462 // Xor Memory with Immediate 9463 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9464 %{ 9465 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9466 effect(KILL cr); 9467 9468 ins_cost(125); 9469 format %{ "xorl $dst, $src\t# int" %} 9470 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9471 ins_encode(REX_mem(dst), OpcSE(src), 9472 RM_opc_mem(secondary, dst), Con8or32(src)); 9473 ins_pipe(ialu_mem_imm); 9474 %} 9475 9476 9477 // Long Logical Instructions 9478 9479 // And Instructions 9480 // And Register with Register 9481 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9482 %{ 9483 match(Set dst (AndL dst src)); 9484 effect(KILL cr); 9485 9486 format %{ "andq $dst, $src\t# long" %} 9487 opcode(0x23); 9488 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9489 ins_pipe(ialu_reg_reg); 9490 %} 9491 9492 // And Register with Immediate 255 9493 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9494 %{ 9495 match(Set dst (AndL dst src)); 9496 9497 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9498 opcode(0x0F, 0xB6); 9499 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9500 ins_pipe(ialu_reg); 9501 %} 9502 9503 // And Register with Immediate 65535 9504 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9505 %{ 9506 match(Set dst (AndL dst src)); 9507 9508 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9509 opcode(0x0F, 0xB7); 9510 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9511 ins_pipe(ialu_reg); 9512 %} 9513 9514 // And Register with Immediate 9515 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9516 %{ 9517 match(Set dst (AndL dst src)); 9518 effect(KILL cr); 9519 9520 format %{ "andq $dst, $src\t# long" %} 9521 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9522 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9523 ins_pipe(ialu_reg); 9524 %} 9525 9526 // And Register with Memory 9527 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9528 %{ 9529 match(Set dst (AndL dst (LoadL src))); 9530 effect(KILL cr); 9531 9532 ins_cost(125); 9533 format %{ "andq $dst, $src\t# long" %} 9534 opcode(0x23); 9535 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9536 ins_pipe(ialu_reg_mem); 9537 %} 9538 9539 // And Memory with Register 9540 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9541 %{ 9542 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9543 effect(KILL cr); 9544 9545 ins_cost(150); 9546 format %{ "andq $dst, $src\t# long" %} 9547 opcode(0x21); /* Opcode 21 /r */ 9548 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9549 ins_pipe(ialu_mem_reg); 9550 %} 9551 9552 // And Memory with Immediate 9553 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9554 %{ 9555 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9556 effect(KILL cr); 9557 9558 ins_cost(125); 9559 format %{ "andq $dst, $src\t# long" %} 9560 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9561 ins_encode(REX_mem_wide(dst), OpcSE(src), 9562 RM_opc_mem(secondary, dst), Con8or32(src)); 9563 ins_pipe(ialu_mem_imm); 9564 %} 9565 9566 // BMI1 instructions 9567 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9568 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9569 predicate(UseBMI1Instructions); 9570 effect(KILL cr); 9571 9572 ins_cost(125); 9573 format %{ "andnq $dst, $src1, $src2" %} 9574 9575 ins_encode %{ 9576 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9577 %} 9578 ins_pipe(ialu_reg_mem); 9579 %} 9580 9581 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9582 match(Set dst (AndL (XorL src1 minus_1) src2)); 9583 predicate(UseBMI1Instructions); 9584 effect(KILL cr); 9585 9586 format %{ "andnq $dst, $src1, $src2" %} 9587 9588 ins_encode %{ 9589 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9590 %} 9591 ins_pipe(ialu_reg_mem); 9592 %} 9593 9594 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9595 match(Set dst (AndL (SubL imm_zero src) src)); 9596 predicate(UseBMI1Instructions); 9597 effect(KILL cr); 9598 9599 format %{ "blsiq $dst, $src" %} 9600 9601 ins_encode %{ 9602 __ blsiq($dst$$Register, $src$$Register); 9603 %} 9604 ins_pipe(ialu_reg); 9605 %} 9606 9607 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9608 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9609 predicate(UseBMI1Instructions); 9610 effect(KILL cr); 9611 9612 ins_cost(125); 9613 format %{ "blsiq $dst, $src" %} 9614 9615 ins_encode %{ 9616 __ blsiq($dst$$Register, $src$$Address); 9617 %} 9618 ins_pipe(ialu_reg_mem); 9619 %} 9620 9621 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9622 %{ 9623 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9624 predicate(UseBMI1Instructions); 9625 effect(KILL cr); 9626 9627 ins_cost(125); 9628 format %{ "blsmskq $dst, $src" %} 9629 9630 ins_encode %{ 9631 __ blsmskq($dst$$Register, $src$$Address); 9632 %} 9633 ins_pipe(ialu_reg_mem); 9634 %} 9635 9636 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9637 %{ 9638 match(Set dst (XorL (AddL src minus_1) src)); 9639 predicate(UseBMI1Instructions); 9640 effect(KILL cr); 9641 9642 format %{ "blsmskq $dst, $src" %} 9643 9644 ins_encode %{ 9645 __ blsmskq($dst$$Register, $src$$Register); 9646 %} 9647 9648 ins_pipe(ialu_reg); 9649 %} 9650 9651 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9652 %{ 9653 match(Set dst (AndL (AddL src minus_1) src) ); 9654 predicate(UseBMI1Instructions); 9655 effect(KILL cr); 9656 9657 format %{ "blsrq $dst, $src" %} 9658 9659 ins_encode %{ 9660 __ blsrq($dst$$Register, $src$$Register); 9661 %} 9662 9663 ins_pipe(ialu_reg); 9664 %} 9665 9666 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9667 %{ 9668 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9669 predicate(UseBMI1Instructions); 9670 effect(KILL cr); 9671 9672 ins_cost(125); 9673 format %{ "blsrq $dst, $src" %} 9674 9675 ins_encode %{ 9676 __ blsrq($dst$$Register, $src$$Address); 9677 %} 9678 9679 ins_pipe(ialu_reg); 9680 %} 9681 9682 // Or Instructions 9683 // Or Register with Register 9684 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9685 %{ 9686 match(Set dst (OrL dst src)); 9687 effect(KILL cr); 9688 9689 format %{ "orq $dst, $src\t# long" %} 9690 opcode(0x0B); 9691 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9692 ins_pipe(ialu_reg_reg); 9693 %} 9694 9695 // Use any_RegP to match R15 (TLS register) without spilling. 9696 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9697 match(Set dst (OrL dst (CastP2X src))); 9698 effect(KILL cr); 9699 9700 format %{ "orq $dst, $src\t# long" %} 9701 opcode(0x0B); 9702 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9703 ins_pipe(ialu_reg_reg); 9704 %} 9705 9706 9707 // Or Register with Immediate 9708 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9709 %{ 9710 match(Set dst (OrL dst src)); 9711 effect(KILL cr); 9712 9713 format %{ "orq $dst, $src\t# long" %} 9714 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9715 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9716 ins_pipe(ialu_reg); 9717 %} 9718 9719 // Or Register with Memory 9720 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9721 %{ 9722 match(Set dst (OrL dst (LoadL src))); 9723 effect(KILL cr); 9724 9725 ins_cost(125); 9726 format %{ "orq $dst, $src\t# long" %} 9727 opcode(0x0B); 9728 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9729 ins_pipe(ialu_reg_mem); 9730 %} 9731 9732 // Or Memory with Register 9733 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9734 %{ 9735 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9736 effect(KILL cr); 9737 9738 ins_cost(150); 9739 format %{ "orq $dst, $src\t# long" %} 9740 opcode(0x09); /* Opcode 09 /r */ 9741 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9742 ins_pipe(ialu_mem_reg); 9743 %} 9744 9745 // Or Memory with Immediate 9746 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9747 %{ 9748 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9749 effect(KILL cr); 9750 9751 ins_cost(125); 9752 format %{ "orq $dst, $src\t# long" %} 9753 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9754 ins_encode(REX_mem_wide(dst), OpcSE(src), 9755 RM_opc_mem(secondary, dst), Con8or32(src)); 9756 ins_pipe(ialu_mem_imm); 9757 %} 9758 9759 // Xor Instructions 9760 // Xor Register with Register 9761 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9762 %{ 9763 match(Set dst (XorL dst src)); 9764 effect(KILL cr); 9765 9766 format %{ "xorq $dst, $src\t# long" %} 9767 opcode(0x33); 9768 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9769 ins_pipe(ialu_reg_reg); 9770 %} 9771 9772 // Xor Register with Immediate -1 9773 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9774 match(Set dst (XorL dst imm)); 9775 9776 format %{ "notq $dst" %} 9777 ins_encode %{ 9778 __ notq($dst$$Register); 9779 %} 9780 ins_pipe(ialu_reg); 9781 %} 9782 9783 // Xor Register with Immediate 9784 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9785 %{ 9786 match(Set dst (XorL dst src)); 9787 effect(KILL cr); 9788 9789 format %{ "xorq $dst, $src\t# long" %} 9790 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9791 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9792 ins_pipe(ialu_reg); 9793 %} 9794 9795 // Xor Register with Memory 9796 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9797 %{ 9798 match(Set dst (XorL dst (LoadL src))); 9799 effect(KILL cr); 9800 9801 ins_cost(125); 9802 format %{ "xorq $dst, $src\t# long" %} 9803 opcode(0x33); 9804 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9805 ins_pipe(ialu_reg_mem); 9806 %} 9807 9808 // Xor Memory with Register 9809 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9810 %{ 9811 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9812 effect(KILL cr); 9813 9814 ins_cost(150); 9815 format %{ "xorq $dst, $src\t# long" %} 9816 opcode(0x31); /* Opcode 31 /r */ 9817 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9818 ins_pipe(ialu_mem_reg); 9819 %} 9820 9821 // Xor Memory with Immediate 9822 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9823 %{ 9824 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9825 effect(KILL cr); 9826 9827 ins_cost(125); 9828 format %{ "xorq $dst, $src\t# long" %} 9829 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9830 ins_encode(REX_mem_wide(dst), OpcSE(src), 9831 RM_opc_mem(secondary, dst), Con8or32(src)); 9832 ins_pipe(ialu_mem_imm); 9833 %} 9834 9835 // Convert Int to Boolean 9836 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9837 %{ 9838 match(Set dst (Conv2B src)); 9839 effect(KILL cr); 9840 9841 format %{ "testl $src, $src\t# ci2b\n\t" 9842 "setnz $dst\n\t" 9843 "movzbl $dst, $dst" %} 9844 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9845 setNZ_reg(dst), 9846 REX_reg_breg(dst, dst), // movzbl 9847 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9848 ins_pipe(pipe_slow); // XXX 9849 %} 9850 9851 // Convert Pointer to Boolean 9852 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9853 %{ 9854 match(Set dst (Conv2B src)); 9855 effect(KILL cr); 9856 9857 format %{ "testq $src, $src\t# cp2b\n\t" 9858 "setnz $dst\n\t" 9859 "movzbl $dst, $dst" %} 9860 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9861 setNZ_reg(dst), 9862 REX_reg_breg(dst, dst), // movzbl 9863 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9864 ins_pipe(pipe_slow); // XXX 9865 %} 9866 9867 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9868 %{ 9869 match(Set dst (CmpLTMask p q)); 9870 effect(KILL cr); 9871 9872 ins_cost(400); 9873 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9874 "setlt $dst\n\t" 9875 "movzbl $dst, $dst\n\t" 9876 "negl $dst" %} 9877 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9878 setLT_reg(dst), 9879 REX_reg_breg(dst, dst), // movzbl 9880 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9881 neg_reg(dst)); 9882 ins_pipe(pipe_slow); 9883 %} 9884 9885 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9886 %{ 9887 match(Set dst (CmpLTMask dst zero)); 9888 effect(KILL cr); 9889 9890 ins_cost(100); 9891 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9892 ins_encode %{ 9893 __ sarl($dst$$Register, 31); 9894 %} 9895 ins_pipe(ialu_reg); 9896 %} 9897 9898 /* Better to save a register than avoid a branch */ 9899 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9900 %{ 9901 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9902 effect(KILL cr); 9903 ins_cost(300); 9904 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9905 "jge done\n\t" 9906 "addl $p,$y\n" 9907 "done: " %} 9908 ins_encode %{ 9909 Register Rp = $p$$Register; 9910 Register Rq = $q$$Register; 9911 Register Ry = $y$$Register; 9912 Label done; 9913 __ subl(Rp, Rq); 9914 __ jccb(Assembler::greaterEqual, done); 9915 __ addl(Rp, Ry); 9916 __ bind(done); 9917 %} 9918 ins_pipe(pipe_cmplt); 9919 %} 9920 9921 /* Better to save a register than avoid a branch */ 9922 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9923 %{ 9924 match(Set y (AndI (CmpLTMask p q) y)); 9925 effect(KILL cr); 9926 9927 ins_cost(300); 9928 9929 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9930 "jlt done\n\t" 9931 "xorl $y, $y\n" 9932 "done: " %} 9933 ins_encode %{ 9934 Register Rp = $p$$Register; 9935 Register Rq = $q$$Register; 9936 Register Ry = $y$$Register; 9937 Label done; 9938 __ cmpl(Rp, Rq); 9939 __ jccb(Assembler::less, done); 9940 __ xorl(Ry, Ry); 9941 __ bind(done); 9942 %} 9943 ins_pipe(pipe_cmplt); 9944 %} 9945 9946 9947 //---------- FP Instructions------------------------------------------------ 9948 9949 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9950 %{ 9951 match(Set cr (CmpF src1 src2)); 9952 9953 ins_cost(145); 9954 format %{ "ucomiss $src1, $src2\n\t" 9955 "jnp,s exit\n\t" 9956 "pushfq\t# saw NaN, set CF\n\t" 9957 "andq [rsp], #0xffffff2b\n\t" 9958 "popfq\n" 9959 "exit:" %} 9960 ins_encode %{ 9961 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9962 emit_cmpfp_fixup(_masm); 9963 %} 9964 ins_pipe(pipe_slow); 9965 %} 9966 9967 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9968 match(Set cr (CmpF src1 src2)); 9969 9970 ins_cost(100); 9971 format %{ "ucomiss $src1, $src2" %} 9972 ins_encode %{ 9973 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9974 %} 9975 ins_pipe(pipe_slow); 9976 %} 9977 9978 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9979 %{ 9980 match(Set cr (CmpF src1 (LoadF src2))); 9981 9982 ins_cost(145); 9983 format %{ "ucomiss $src1, $src2\n\t" 9984 "jnp,s exit\n\t" 9985 "pushfq\t# saw NaN, set CF\n\t" 9986 "andq [rsp], #0xffffff2b\n\t" 9987 "popfq\n" 9988 "exit:" %} 9989 ins_encode %{ 9990 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9991 emit_cmpfp_fixup(_masm); 9992 %} 9993 ins_pipe(pipe_slow); 9994 %} 9995 9996 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9997 match(Set cr (CmpF src1 (LoadF src2))); 9998 9999 ins_cost(100); 10000 format %{ "ucomiss $src1, $src2" %} 10001 ins_encode %{ 10002 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10003 %} 10004 ins_pipe(pipe_slow); 10005 %} 10006 10007 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10008 match(Set cr (CmpF src con)); 10009 10010 ins_cost(145); 10011 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10012 "jnp,s exit\n\t" 10013 "pushfq\t# saw NaN, set CF\n\t" 10014 "andq [rsp], #0xffffff2b\n\t" 10015 "popfq\n" 10016 "exit:" %} 10017 ins_encode %{ 10018 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10019 emit_cmpfp_fixup(_masm); 10020 %} 10021 ins_pipe(pipe_slow); 10022 %} 10023 10024 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10025 match(Set cr (CmpF src con)); 10026 ins_cost(100); 10027 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10028 ins_encode %{ 10029 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10030 %} 10031 ins_pipe(pipe_slow); 10032 %} 10033 10034 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10035 %{ 10036 match(Set cr (CmpD src1 src2)); 10037 10038 ins_cost(145); 10039 format %{ "ucomisd $src1, $src2\n\t" 10040 "jnp,s exit\n\t" 10041 "pushfq\t# saw NaN, set CF\n\t" 10042 "andq [rsp], #0xffffff2b\n\t" 10043 "popfq\n" 10044 "exit:" %} 10045 ins_encode %{ 10046 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10047 emit_cmpfp_fixup(_masm); 10048 %} 10049 ins_pipe(pipe_slow); 10050 %} 10051 10052 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10053 match(Set cr (CmpD src1 src2)); 10054 10055 ins_cost(100); 10056 format %{ "ucomisd $src1, $src2 test" %} 10057 ins_encode %{ 10058 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10059 %} 10060 ins_pipe(pipe_slow); 10061 %} 10062 10063 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10064 %{ 10065 match(Set cr (CmpD src1 (LoadD src2))); 10066 10067 ins_cost(145); 10068 format %{ "ucomisd $src1, $src2\n\t" 10069 "jnp,s exit\n\t" 10070 "pushfq\t# saw NaN, set CF\n\t" 10071 "andq [rsp], #0xffffff2b\n\t" 10072 "popfq\n" 10073 "exit:" %} 10074 ins_encode %{ 10075 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10076 emit_cmpfp_fixup(_masm); 10077 %} 10078 ins_pipe(pipe_slow); 10079 %} 10080 10081 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10082 match(Set cr (CmpD src1 (LoadD src2))); 10083 10084 ins_cost(100); 10085 format %{ "ucomisd $src1, $src2" %} 10086 ins_encode %{ 10087 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10088 %} 10089 ins_pipe(pipe_slow); 10090 %} 10091 10092 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10093 match(Set cr (CmpD src con)); 10094 10095 ins_cost(145); 10096 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10097 "jnp,s exit\n\t" 10098 "pushfq\t# saw NaN, set CF\n\t" 10099 "andq [rsp], #0xffffff2b\n\t" 10100 "popfq\n" 10101 "exit:" %} 10102 ins_encode %{ 10103 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10104 emit_cmpfp_fixup(_masm); 10105 %} 10106 ins_pipe(pipe_slow); 10107 %} 10108 10109 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10110 match(Set cr (CmpD src con)); 10111 ins_cost(100); 10112 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10113 ins_encode %{ 10114 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10115 %} 10116 ins_pipe(pipe_slow); 10117 %} 10118 10119 // Compare into -1,0,1 10120 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10121 %{ 10122 match(Set dst (CmpF3 src1 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$$XMMRegister); 10135 emit_cmpfp3(_masm, $dst$$Register); 10136 %} 10137 ins_pipe(pipe_slow); 10138 %} 10139 10140 // Compare into -1,0,1 10141 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10142 %{ 10143 match(Set dst (CmpF3 src1 (LoadF src2))); 10144 effect(KILL cr); 10145 10146 ins_cost(275); 10147 format %{ "ucomiss $src1, $src2\n\t" 10148 "movl $dst, #-1\n\t" 10149 "jp,s done\n\t" 10150 "jb,s done\n\t" 10151 "setne $dst\n\t" 10152 "movzbl $dst, $dst\n" 10153 "done:" %} 10154 ins_encode %{ 10155 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10156 emit_cmpfp3(_masm, $dst$$Register); 10157 %} 10158 ins_pipe(pipe_slow); 10159 %} 10160 10161 // Compare into -1,0,1 10162 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10163 match(Set dst (CmpF3 src con)); 10164 effect(KILL cr); 10165 10166 ins_cost(275); 10167 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\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 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10176 emit_cmpfp3(_masm, $dst$$Register); 10177 %} 10178 ins_pipe(pipe_slow); 10179 %} 10180 10181 // Compare into -1,0,1 10182 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10183 %{ 10184 match(Set dst (CmpD3 src1 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$$XMMRegister); 10197 emit_cmpfp3(_masm, $dst$$Register); 10198 %} 10199 ins_pipe(pipe_slow); 10200 %} 10201 10202 // Compare into -1,0,1 10203 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10204 %{ 10205 match(Set dst (CmpD3 src1 (LoadD src2))); 10206 effect(KILL cr); 10207 10208 ins_cost(275); 10209 format %{ "ucomisd $src1, $src2\n\t" 10210 "movl $dst, #-1\n\t" 10211 "jp,s done\n\t" 10212 "jb,s done\n\t" 10213 "setne $dst\n\t" 10214 "movzbl $dst, $dst\n" 10215 "done:" %} 10216 ins_encode %{ 10217 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10218 emit_cmpfp3(_masm, $dst$$Register); 10219 %} 10220 ins_pipe(pipe_slow); 10221 %} 10222 10223 // Compare into -1,0,1 10224 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10225 match(Set dst (CmpD3 src con)); 10226 effect(KILL cr); 10227 10228 ins_cost(275); 10229 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10230 "movl $dst, #-1\n\t" 10231 "jp,s done\n\t" 10232 "jb,s done\n\t" 10233 "setne $dst\n\t" 10234 "movzbl $dst, $dst\n" 10235 "done:" %} 10236 ins_encode %{ 10237 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10238 emit_cmpfp3(_masm, $dst$$Register); 10239 %} 10240 ins_pipe(pipe_slow); 10241 %} 10242 10243 //----------Arithmetic Conversion Instructions--------------------------------- 10244 10245 instruct roundFloat_nop(regF dst) 10246 %{ 10247 match(Set dst (RoundFloat dst)); 10248 10249 ins_cost(0); 10250 ins_encode(); 10251 ins_pipe(empty); 10252 %} 10253 10254 instruct roundDouble_nop(regD dst) 10255 %{ 10256 match(Set dst (RoundDouble dst)); 10257 10258 ins_cost(0); 10259 ins_encode(); 10260 ins_pipe(empty); 10261 %} 10262 10263 instruct convF2D_reg_reg(regD dst, regF src) 10264 %{ 10265 match(Set dst (ConvF2D src)); 10266 10267 format %{ "cvtss2sd $dst, $src" %} 10268 ins_encode %{ 10269 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10270 %} 10271 ins_pipe(pipe_slow); // XXX 10272 %} 10273 10274 instruct convF2D_reg_mem(regD dst, memory src) 10275 %{ 10276 match(Set dst (ConvF2D (LoadF src))); 10277 10278 format %{ "cvtss2sd $dst, $src" %} 10279 ins_encode %{ 10280 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10281 %} 10282 ins_pipe(pipe_slow); // XXX 10283 %} 10284 10285 instruct convD2F_reg_reg(regF dst, regD src) 10286 %{ 10287 match(Set dst (ConvD2F src)); 10288 10289 format %{ "cvtsd2ss $dst, $src" %} 10290 ins_encode %{ 10291 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10292 %} 10293 ins_pipe(pipe_slow); // XXX 10294 %} 10295 10296 instruct convD2F_reg_mem(regF dst, memory src) 10297 %{ 10298 match(Set dst (ConvD2F (LoadD src))); 10299 10300 format %{ "cvtsd2ss $dst, $src" %} 10301 ins_encode %{ 10302 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10303 %} 10304 ins_pipe(pipe_slow); // XXX 10305 %} 10306 10307 // XXX do mem variants 10308 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10309 %{ 10310 match(Set dst (ConvF2I src)); 10311 effect(KILL cr); 10312 10313 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10314 "cmpl $dst, #0x80000000\n\t" 10315 "jne,s done\n\t" 10316 "subq rsp, #8\n\t" 10317 "movss [rsp], $src\n\t" 10318 "call f2i_fixup\n\t" 10319 "popq $dst\n" 10320 "done: "%} 10321 ins_encode %{ 10322 Label done; 10323 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10324 __ cmpl($dst$$Register, 0x80000000); 10325 __ jccb(Assembler::notEqual, done); 10326 __ subptr(rsp, 8); 10327 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10328 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10329 __ pop($dst$$Register); 10330 __ bind(done); 10331 %} 10332 ins_pipe(pipe_slow); 10333 %} 10334 10335 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10336 %{ 10337 match(Set dst (ConvF2L src)); 10338 effect(KILL cr); 10339 10340 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10341 "cmpq $dst, [0x8000000000000000]\n\t" 10342 "jne,s done\n\t" 10343 "subq rsp, #8\n\t" 10344 "movss [rsp], $src\n\t" 10345 "call f2l_fixup\n\t" 10346 "popq $dst\n" 10347 "done: "%} 10348 ins_encode %{ 10349 Label done; 10350 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10351 __ cmp64($dst$$Register, 10352 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10353 __ jccb(Assembler::notEqual, done); 10354 __ subptr(rsp, 8); 10355 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10356 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10357 __ pop($dst$$Register); 10358 __ bind(done); 10359 %} 10360 ins_pipe(pipe_slow); 10361 %} 10362 10363 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10364 %{ 10365 match(Set dst (ConvD2I src)); 10366 effect(KILL cr); 10367 10368 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10369 "cmpl $dst, #0x80000000\n\t" 10370 "jne,s done\n\t" 10371 "subq rsp, #8\n\t" 10372 "movsd [rsp], $src\n\t" 10373 "call d2i_fixup\n\t" 10374 "popq $dst\n" 10375 "done: "%} 10376 ins_encode %{ 10377 Label done; 10378 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10379 __ cmpl($dst$$Register, 0x80000000); 10380 __ jccb(Assembler::notEqual, done); 10381 __ subptr(rsp, 8); 10382 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10383 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10384 __ pop($dst$$Register); 10385 __ bind(done); 10386 %} 10387 ins_pipe(pipe_slow); 10388 %} 10389 10390 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10391 %{ 10392 match(Set dst (ConvD2L src)); 10393 effect(KILL cr); 10394 10395 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10396 "cmpq $dst, [0x8000000000000000]\n\t" 10397 "jne,s done\n\t" 10398 "subq rsp, #8\n\t" 10399 "movsd [rsp], $src\n\t" 10400 "call d2l_fixup\n\t" 10401 "popq $dst\n" 10402 "done: "%} 10403 ins_encode %{ 10404 Label done; 10405 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10406 __ cmp64($dst$$Register, 10407 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10408 __ jccb(Assembler::notEqual, done); 10409 __ subptr(rsp, 8); 10410 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10411 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10412 __ pop($dst$$Register); 10413 __ bind(done); 10414 %} 10415 ins_pipe(pipe_slow); 10416 %} 10417 10418 instruct convI2F_reg_reg(regF dst, rRegI src) 10419 %{ 10420 predicate(!UseXmmI2F); 10421 match(Set dst (ConvI2F src)); 10422 10423 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10424 ins_encode %{ 10425 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10426 %} 10427 ins_pipe(pipe_slow); // XXX 10428 %} 10429 10430 instruct convI2F_reg_mem(regF dst, memory src) 10431 %{ 10432 match(Set dst (ConvI2F (LoadI src))); 10433 10434 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10435 ins_encode %{ 10436 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10437 %} 10438 ins_pipe(pipe_slow); // XXX 10439 %} 10440 10441 instruct convI2D_reg_reg(regD dst, rRegI src) 10442 %{ 10443 predicate(!UseXmmI2D); 10444 match(Set dst (ConvI2D src)); 10445 10446 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10447 ins_encode %{ 10448 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10449 %} 10450 ins_pipe(pipe_slow); // XXX 10451 %} 10452 10453 instruct convI2D_reg_mem(regD dst, memory src) 10454 %{ 10455 match(Set dst (ConvI2D (LoadI src))); 10456 10457 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10458 ins_encode %{ 10459 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10460 %} 10461 ins_pipe(pipe_slow); // XXX 10462 %} 10463 10464 instruct convXI2F_reg(regF dst, rRegI src) 10465 %{ 10466 predicate(UseXmmI2F); 10467 match(Set dst (ConvI2F src)); 10468 10469 format %{ "movdl $dst, $src\n\t" 10470 "cvtdq2psl $dst, $dst\t# i2f" %} 10471 ins_encode %{ 10472 __ movdl($dst$$XMMRegister, $src$$Register); 10473 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10474 %} 10475 ins_pipe(pipe_slow); // XXX 10476 %} 10477 10478 instruct convXI2D_reg(regD dst, rRegI src) 10479 %{ 10480 predicate(UseXmmI2D); 10481 match(Set dst (ConvI2D src)); 10482 10483 format %{ "movdl $dst, $src\n\t" 10484 "cvtdq2pdl $dst, $dst\t# i2d" %} 10485 ins_encode %{ 10486 __ movdl($dst$$XMMRegister, $src$$Register); 10487 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10488 %} 10489 ins_pipe(pipe_slow); // XXX 10490 %} 10491 10492 instruct convL2F_reg_reg(regF dst, rRegL src) 10493 %{ 10494 match(Set dst (ConvL2F src)); 10495 10496 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10497 ins_encode %{ 10498 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10499 %} 10500 ins_pipe(pipe_slow); // XXX 10501 %} 10502 10503 instruct convL2F_reg_mem(regF dst, memory src) 10504 %{ 10505 match(Set dst (ConvL2F (LoadL src))); 10506 10507 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10508 ins_encode %{ 10509 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10510 %} 10511 ins_pipe(pipe_slow); // XXX 10512 %} 10513 10514 instruct convL2D_reg_reg(regD dst, rRegL src) 10515 %{ 10516 match(Set dst (ConvL2D src)); 10517 10518 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10519 ins_encode %{ 10520 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10521 %} 10522 ins_pipe(pipe_slow); // XXX 10523 %} 10524 10525 instruct convL2D_reg_mem(regD dst, memory src) 10526 %{ 10527 match(Set dst (ConvL2D (LoadL src))); 10528 10529 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10530 ins_encode %{ 10531 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10532 %} 10533 ins_pipe(pipe_slow); // XXX 10534 %} 10535 10536 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10537 %{ 10538 match(Set dst (ConvI2L src)); 10539 10540 ins_cost(125); 10541 format %{ "movslq $dst, $src\t# i2l" %} 10542 ins_encode %{ 10543 __ movslq($dst$$Register, $src$$Register); 10544 %} 10545 ins_pipe(ialu_reg_reg); 10546 %} 10547 10548 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10549 // %{ 10550 // match(Set dst (ConvI2L src)); 10551 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10552 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10553 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10554 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10555 // ((const TypeNode*) n)->type()->is_long()->_lo == 10556 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10557 10558 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10559 // ins_encode(enc_copy(dst, src)); 10560 // // opcode(0x63); // needs REX.W 10561 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10562 // ins_pipe(ialu_reg_reg); 10563 // %} 10564 10565 // Zero-extend convert int to long 10566 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10567 %{ 10568 match(Set dst (AndL (ConvI2L src) mask)); 10569 10570 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10571 ins_encode %{ 10572 if ($dst$$reg != $src$$reg) { 10573 __ movl($dst$$Register, $src$$Register); 10574 } 10575 %} 10576 ins_pipe(ialu_reg_reg); 10577 %} 10578 10579 // Zero-extend convert int to long 10580 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10581 %{ 10582 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10583 10584 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10585 ins_encode %{ 10586 __ movl($dst$$Register, $src$$Address); 10587 %} 10588 ins_pipe(ialu_reg_mem); 10589 %} 10590 10591 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10592 %{ 10593 match(Set dst (AndL src mask)); 10594 10595 format %{ "movl $dst, $src\t# zero-extend long" %} 10596 ins_encode %{ 10597 __ movl($dst$$Register, $src$$Register); 10598 %} 10599 ins_pipe(ialu_reg_reg); 10600 %} 10601 10602 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10603 %{ 10604 match(Set dst (ConvL2I src)); 10605 10606 format %{ "movl $dst, $src\t# l2i" %} 10607 ins_encode %{ 10608 __ movl($dst$$Register, $src$$Register); 10609 %} 10610 ins_pipe(ialu_reg_reg); 10611 %} 10612 10613 10614 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10615 match(Set dst (MoveF2I src)); 10616 effect(DEF dst, USE src); 10617 10618 ins_cost(125); 10619 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10620 ins_encode %{ 10621 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10622 %} 10623 ins_pipe(ialu_reg_mem); 10624 %} 10625 10626 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10627 match(Set dst (MoveI2F src)); 10628 effect(DEF dst, USE src); 10629 10630 ins_cost(125); 10631 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10632 ins_encode %{ 10633 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10634 %} 10635 ins_pipe(pipe_slow); 10636 %} 10637 10638 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10639 match(Set dst (MoveD2L src)); 10640 effect(DEF dst, USE src); 10641 10642 ins_cost(125); 10643 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10644 ins_encode %{ 10645 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10646 %} 10647 ins_pipe(ialu_reg_mem); 10648 %} 10649 10650 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10651 predicate(!UseXmmLoadAndClearUpper); 10652 match(Set dst (MoveL2D src)); 10653 effect(DEF dst, USE src); 10654 10655 ins_cost(125); 10656 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10657 ins_encode %{ 10658 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10659 %} 10660 ins_pipe(pipe_slow); 10661 %} 10662 10663 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10664 predicate(UseXmmLoadAndClearUpper); 10665 match(Set dst (MoveL2D src)); 10666 effect(DEF dst, USE src); 10667 10668 ins_cost(125); 10669 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10670 ins_encode %{ 10671 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10672 %} 10673 ins_pipe(pipe_slow); 10674 %} 10675 10676 10677 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10678 match(Set dst (MoveF2I src)); 10679 effect(DEF dst, USE src); 10680 10681 ins_cost(95); // XXX 10682 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10683 ins_encode %{ 10684 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10685 %} 10686 ins_pipe(pipe_slow); 10687 %} 10688 10689 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10690 match(Set dst (MoveI2F src)); 10691 effect(DEF dst, USE src); 10692 10693 ins_cost(100); 10694 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10695 ins_encode %{ 10696 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10697 %} 10698 ins_pipe( ialu_mem_reg ); 10699 %} 10700 10701 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10702 match(Set dst (MoveD2L src)); 10703 effect(DEF dst, USE src); 10704 10705 ins_cost(95); // XXX 10706 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10707 ins_encode %{ 10708 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10709 %} 10710 ins_pipe(pipe_slow); 10711 %} 10712 10713 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10714 match(Set dst (MoveL2D src)); 10715 effect(DEF dst, USE src); 10716 10717 ins_cost(100); 10718 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10719 ins_encode %{ 10720 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10721 %} 10722 ins_pipe(ialu_mem_reg); 10723 %} 10724 10725 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10726 match(Set dst (MoveF2I src)); 10727 effect(DEF dst, USE src); 10728 ins_cost(85); 10729 format %{ "movd $dst,$src\t# MoveF2I" %} 10730 ins_encode %{ 10731 __ movdl($dst$$Register, $src$$XMMRegister); 10732 %} 10733 ins_pipe( pipe_slow ); 10734 %} 10735 10736 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10737 match(Set dst (MoveD2L src)); 10738 effect(DEF dst, USE src); 10739 ins_cost(85); 10740 format %{ "movd $dst,$src\t# MoveD2L" %} 10741 ins_encode %{ 10742 __ movdq($dst$$Register, $src$$XMMRegister); 10743 %} 10744 ins_pipe( pipe_slow ); 10745 %} 10746 10747 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10748 match(Set dst (MoveI2F src)); 10749 effect(DEF dst, USE src); 10750 ins_cost(100); 10751 format %{ "movd $dst,$src\t# MoveI2F" %} 10752 ins_encode %{ 10753 __ movdl($dst$$XMMRegister, $src$$Register); 10754 %} 10755 ins_pipe( pipe_slow ); 10756 %} 10757 10758 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10759 match(Set dst (MoveL2D src)); 10760 effect(DEF dst, USE src); 10761 ins_cost(100); 10762 format %{ "movd $dst,$src\t# MoveL2D" %} 10763 ins_encode %{ 10764 __ movdq($dst$$XMMRegister, $src$$Register); 10765 %} 10766 ins_pipe( pipe_slow ); 10767 %} 10768 10769 10770 // ======================================================================= 10771 // fast clearing of an array 10772 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10773 Universe dummy, rFlagsReg cr) 10774 %{ 10775 predicate(!((ClearArrayNode*)n)->is_large()); 10776 match(Set dummy (ClearArray cnt base)); 10777 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10778 10779 format %{ $$template 10780 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10781 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10782 $$emit$$"jg LARGE\n\t" 10783 $$emit$$"dec rcx\n\t" 10784 $$emit$$"js DONE\t# Zero length\n\t" 10785 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10786 $$emit$$"dec rcx\n\t" 10787 $$emit$$"jge LOOP\n\t" 10788 $$emit$$"jmp DONE\n\t" 10789 $$emit$$"# LARGE:\n\t" 10790 if (UseFastStosb) { 10791 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10792 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10793 } else if (UseXMMForObjInit) { 10794 $$emit$$"mov rdi,rax\n\t" 10795 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10796 $$emit$$"jmpq L_zero_64_bytes\n\t" 10797 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10798 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10799 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10800 $$emit$$"add 0x40,rax\n\t" 10801 $$emit$$"# L_zero_64_bytes:\n\t" 10802 $$emit$$"sub 0x8,rcx\n\t" 10803 $$emit$$"jge L_loop\n\t" 10804 $$emit$$"add 0x4,rcx\n\t" 10805 $$emit$$"jl L_tail\n\t" 10806 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10807 $$emit$$"add 0x20,rax\n\t" 10808 $$emit$$"sub 0x4,rcx\n\t" 10809 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10810 $$emit$$"add 0x4,rcx\n\t" 10811 $$emit$$"jle L_end\n\t" 10812 $$emit$$"dec rcx\n\t" 10813 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10814 $$emit$$"vmovq xmm0,(rax)\n\t" 10815 $$emit$$"add 0x8,rax\n\t" 10816 $$emit$$"dec rcx\n\t" 10817 $$emit$$"jge L_sloop\n\t" 10818 $$emit$$"# L_end:\n\t" 10819 } else { 10820 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10821 } 10822 $$emit$$"# DONE" 10823 %} 10824 ins_encode %{ 10825 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10826 $tmp$$XMMRegister, false); 10827 %} 10828 ins_pipe(pipe_slow); 10829 %} 10830 10831 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10832 Universe dummy, rFlagsReg cr) 10833 %{ 10834 predicate(((ClearArrayNode*)n)->is_large()); 10835 match(Set dummy (ClearArray cnt base)); 10836 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10837 10838 format %{ $$template 10839 if (UseFastStosb) { 10840 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10841 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10842 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10843 } else if (UseXMMForObjInit) { 10844 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10845 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10846 $$emit$$"jmpq L_zero_64_bytes\n\t" 10847 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10848 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10849 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10850 $$emit$$"add 0x40,rax\n\t" 10851 $$emit$$"# L_zero_64_bytes:\n\t" 10852 $$emit$$"sub 0x8,rcx\n\t" 10853 $$emit$$"jge L_loop\n\t" 10854 $$emit$$"add 0x4,rcx\n\t" 10855 $$emit$$"jl L_tail\n\t" 10856 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10857 $$emit$$"add 0x20,rax\n\t" 10858 $$emit$$"sub 0x4,rcx\n\t" 10859 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10860 $$emit$$"add 0x4,rcx\n\t" 10861 $$emit$$"jle L_end\n\t" 10862 $$emit$$"dec rcx\n\t" 10863 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10864 $$emit$$"vmovq xmm0,(rax)\n\t" 10865 $$emit$$"add 0x8,rax\n\t" 10866 $$emit$$"dec rcx\n\t" 10867 $$emit$$"jge L_sloop\n\t" 10868 $$emit$$"# L_end:\n\t" 10869 } else { 10870 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10871 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10872 } 10873 %} 10874 ins_encode %{ 10875 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10876 $tmp$$XMMRegister, true); 10877 %} 10878 ins_pipe(pipe_slow); 10879 %} 10880 10881 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10882 rax_RegI result, regD tmp1, rFlagsReg cr) 10883 %{ 10884 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10885 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10886 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10887 10888 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10889 ins_encode %{ 10890 __ string_compare($str1$$Register, $str2$$Register, 10891 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10892 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 10893 %} 10894 ins_pipe( pipe_slow ); 10895 %} 10896 10897 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10898 rax_RegI result, regD tmp1, rFlagsReg cr) 10899 %{ 10900 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10901 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10902 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10903 10904 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10905 ins_encode %{ 10906 __ string_compare($str1$$Register, $str2$$Register, 10907 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10908 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 10909 %} 10910 ins_pipe( pipe_slow ); 10911 %} 10912 10913 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10914 rax_RegI result, regD tmp1, rFlagsReg cr) 10915 %{ 10916 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10917 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10918 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10919 10920 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10921 ins_encode %{ 10922 __ string_compare($str1$$Register, $str2$$Register, 10923 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10924 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 10925 %} 10926 ins_pipe( pipe_slow ); 10927 %} 10928 10929 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10930 rax_RegI result, regD tmp1, rFlagsReg cr) 10931 %{ 10932 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10933 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10934 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10935 10936 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10937 ins_encode %{ 10938 __ string_compare($str2$$Register, $str1$$Register, 10939 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10940 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 10941 %} 10942 ins_pipe( pipe_slow ); 10943 %} 10944 10945 // fast search of substring with known size. 10946 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10947 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10948 %{ 10949 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10950 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10951 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10952 10953 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10954 ins_encode %{ 10955 int icnt2 = (int)$int_cnt2$$constant; 10956 if (icnt2 >= 16) { 10957 // IndexOf for constant substrings with size >= 16 elements 10958 // which don't need to be loaded through stack. 10959 __ string_indexofC8($str1$$Register, $str2$$Register, 10960 $cnt1$$Register, $cnt2$$Register, 10961 icnt2, $result$$Register, 10962 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10963 } else { 10964 // Small strings are loaded through stack if they cross page boundary. 10965 __ string_indexof($str1$$Register, $str2$$Register, 10966 $cnt1$$Register, $cnt2$$Register, 10967 icnt2, $result$$Register, 10968 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10969 } 10970 %} 10971 ins_pipe( pipe_slow ); 10972 %} 10973 10974 // fast search of substring with known size. 10975 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10976 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10977 %{ 10978 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10979 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10980 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10981 10982 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10983 ins_encode %{ 10984 int icnt2 = (int)$int_cnt2$$constant; 10985 if (icnt2 >= 8) { 10986 // IndexOf for constant substrings with size >= 8 elements 10987 // which don't need to be loaded through stack. 10988 __ string_indexofC8($str1$$Register, $str2$$Register, 10989 $cnt1$$Register, $cnt2$$Register, 10990 icnt2, $result$$Register, 10991 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10992 } else { 10993 // Small strings are loaded through stack if they cross page boundary. 10994 __ string_indexof($str1$$Register, $str2$$Register, 10995 $cnt1$$Register, $cnt2$$Register, 10996 icnt2, $result$$Register, 10997 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10998 } 10999 %} 11000 ins_pipe( pipe_slow ); 11001 %} 11002 11003 // fast search of substring with known size. 11004 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11005 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11006 %{ 11007 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11008 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11009 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11010 11011 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11012 ins_encode %{ 11013 int icnt2 = (int)$int_cnt2$$constant; 11014 if (icnt2 >= 8) { 11015 // IndexOf for constant substrings with size >= 8 elements 11016 // which don't need to be loaded through stack. 11017 __ string_indexofC8($str1$$Register, $str2$$Register, 11018 $cnt1$$Register, $cnt2$$Register, 11019 icnt2, $result$$Register, 11020 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11021 } else { 11022 // Small strings are loaded through stack if they cross page boundary. 11023 __ string_indexof($str1$$Register, $str2$$Register, 11024 $cnt1$$Register, $cnt2$$Register, 11025 icnt2, $result$$Register, 11026 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11027 } 11028 %} 11029 ins_pipe( pipe_slow ); 11030 %} 11031 11032 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11033 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11034 %{ 11035 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11036 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11037 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11038 11039 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11040 ins_encode %{ 11041 __ string_indexof($str1$$Register, $str2$$Register, 11042 $cnt1$$Register, $cnt2$$Register, 11043 (-1), $result$$Register, 11044 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11045 %} 11046 ins_pipe( pipe_slow ); 11047 %} 11048 11049 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11050 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11051 %{ 11052 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11053 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11054 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11055 11056 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11057 ins_encode %{ 11058 __ string_indexof($str1$$Register, $str2$$Register, 11059 $cnt1$$Register, $cnt2$$Register, 11060 (-1), $result$$Register, 11061 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11062 %} 11063 ins_pipe( pipe_slow ); 11064 %} 11065 11066 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11067 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11068 %{ 11069 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11070 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11071 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11072 11073 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11074 ins_encode %{ 11075 __ string_indexof($str1$$Register, $str2$$Register, 11076 $cnt1$$Register, $cnt2$$Register, 11077 (-1), $result$$Register, 11078 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11079 %} 11080 ins_pipe( pipe_slow ); 11081 %} 11082 11083 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11084 rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr) 11085 %{ 11086 predicate(UseSSE42Intrinsics); 11087 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11088 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11089 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11090 ins_encode %{ 11091 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11092 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11093 %} 11094 ins_pipe( pipe_slow ); 11095 %} 11096 11097 // fast string equals 11098 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11099 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11100 %{ 11101 match(Set result (StrEquals (Binary str1 str2) cnt)); 11102 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11103 11104 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11105 ins_encode %{ 11106 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11107 $cnt$$Register, $result$$Register, $tmp3$$Register, 11108 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11109 %} 11110 ins_pipe( pipe_slow ); 11111 %} 11112 11113 // fast array equals 11114 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11115 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11116 %{ 11117 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11118 match(Set result (AryEq ary1 ary2)); 11119 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11120 11121 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11122 ins_encode %{ 11123 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11124 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11125 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11126 %} 11127 ins_pipe( pipe_slow ); 11128 %} 11129 11130 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11131 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11132 %{ 11133 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11134 match(Set result (AryEq ary1 ary2)); 11135 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11136 11137 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11138 ins_encode %{ 11139 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11140 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11141 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11142 %} 11143 ins_pipe( pipe_slow ); 11144 %} 11145 11146 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11147 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11148 %{ 11149 match(Set result (HasNegatives ary1 len)); 11150 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11151 11152 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11153 ins_encode %{ 11154 __ has_negatives($ary1$$Register, $len$$Register, 11155 $result$$Register, $tmp3$$Register, 11156 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11157 %} 11158 ins_pipe( pipe_slow ); 11159 %} 11160 11161 // fast char[] to byte[] compression 11162 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11163 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11164 match(Set result (StrCompressedCopy src (Binary dst len))); 11165 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11166 11167 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11168 ins_encode %{ 11169 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11170 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11171 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11172 %} 11173 ins_pipe( pipe_slow ); 11174 %} 11175 11176 // fast byte[] to char[] inflation 11177 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11178 regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11179 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11180 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11181 11182 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11183 ins_encode %{ 11184 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11185 $tmp1$$XMMRegister, $tmp2$$Register); 11186 %} 11187 ins_pipe( pipe_slow ); 11188 %} 11189 11190 // encode char[] to byte[] in ISO_8859_1 11191 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11192 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11193 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11194 match(Set result (EncodeISOArray src (Binary dst len))); 11195 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11196 11197 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11198 ins_encode %{ 11199 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11200 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11201 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11202 %} 11203 ins_pipe( pipe_slow ); 11204 %} 11205 11206 //----------Overflow Math Instructions----------------------------------------- 11207 11208 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11209 %{ 11210 match(Set cr (OverflowAddI op1 op2)); 11211 effect(DEF cr, USE_KILL op1, USE op2); 11212 11213 format %{ "addl $op1, $op2\t# overflow check int" %} 11214 11215 ins_encode %{ 11216 __ addl($op1$$Register, $op2$$Register); 11217 %} 11218 ins_pipe(ialu_reg_reg); 11219 %} 11220 11221 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11222 %{ 11223 match(Set cr (OverflowAddI op1 op2)); 11224 effect(DEF cr, USE_KILL op1, USE op2); 11225 11226 format %{ "addl $op1, $op2\t# overflow check int" %} 11227 11228 ins_encode %{ 11229 __ addl($op1$$Register, $op2$$constant); 11230 %} 11231 ins_pipe(ialu_reg_reg); 11232 %} 11233 11234 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11235 %{ 11236 match(Set cr (OverflowAddL op1 op2)); 11237 effect(DEF cr, USE_KILL op1, USE op2); 11238 11239 format %{ "addq $op1, $op2\t# overflow check long" %} 11240 ins_encode %{ 11241 __ addq($op1$$Register, $op2$$Register); 11242 %} 11243 ins_pipe(ialu_reg_reg); 11244 %} 11245 11246 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11247 %{ 11248 match(Set cr (OverflowAddL op1 op2)); 11249 effect(DEF cr, USE_KILL op1, USE op2); 11250 11251 format %{ "addq $op1, $op2\t# overflow check long" %} 11252 ins_encode %{ 11253 __ addq($op1$$Register, $op2$$constant); 11254 %} 11255 ins_pipe(ialu_reg_reg); 11256 %} 11257 11258 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11259 %{ 11260 match(Set cr (OverflowSubI op1 op2)); 11261 11262 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11263 ins_encode %{ 11264 __ cmpl($op1$$Register, $op2$$Register); 11265 %} 11266 ins_pipe(ialu_reg_reg); 11267 %} 11268 11269 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11270 %{ 11271 match(Set cr (OverflowSubI op1 op2)); 11272 11273 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11274 ins_encode %{ 11275 __ cmpl($op1$$Register, $op2$$constant); 11276 %} 11277 ins_pipe(ialu_reg_reg); 11278 %} 11279 11280 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11281 %{ 11282 match(Set cr (OverflowSubL op1 op2)); 11283 11284 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11285 ins_encode %{ 11286 __ cmpq($op1$$Register, $op2$$Register); 11287 %} 11288 ins_pipe(ialu_reg_reg); 11289 %} 11290 11291 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11292 %{ 11293 match(Set cr (OverflowSubL op1 op2)); 11294 11295 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11296 ins_encode %{ 11297 __ cmpq($op1$$Register, $op2$$constant); 11298 %} 11299 ins_pipe(ialu_reg_reg); 11300 %} 11301 11302 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11303 %{ 11304 match(Set cr (OverflowSubI zero op2)); 11305 effect(DEF cr, USE_KILL op2); 11306 11307 format %{ "negl $op2\t# overflow check int" %} 11308 ins_encode %{ 11309 __ negl($op2$$Register); 11310 %} 11311 ins_pipe(ialu_reg_reg); 11312 %} 11313 11314 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11315 %{ 11316 match(Set cr (OverflowSubL zero op2)); 11317 effect(DEF cr, USE_KILL op2); 11318 11319 format %{ "negq $op2\t# overflow check long" %} 11320 ins_encode %{ 11321 __ negq($op2$$Register); 11322 %} 11323 ins_pipe(ialu_reg_reg); 11324 %} 11325 11326 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11327 %{ 11328 match(Set cr (OverflowMulI op1 op2)); 11329 effect(DEF cr, USE_KILL op1, USE op2); 11330 11331 format %{ "imull $op1, $op2\t# overflow check int" %} 11332 ins_encode %{ 11333 __ imull($op1$$Register, $op2$$Register); 11334 %} 11335 ins_pipe(ialu_reg_reg_alu0); 11336 %} 11337 11338 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11339 %{ 11340 match(Set cr (OverflowMulI op1 op2)); 11341 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11342 11343 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11344 ins_encode %{ 11345 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11346 %} 11347 ins_pipe(ialu_reg_reg_alu0); 11348 %} 11349 11350 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11351 %{ 11352 match(Set cr (OverflowMulL op1 op2)); 11353 effect(DEF cr, USE_KILL op1, USE op2); 11354 11355 format %{ "imulq $op1, $op2\t# overflow check long" %} 11356 ins_encode %{ 11357 __ imulq($op1$$Register, $op2$$Register); 11358 %} 11359 ins_pipe(ialu_reg_reg_alu0); 11360 %} 11361 11362 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11363 %{ 11364 match(Set cr (OverflowMulL op1 op2)); 11365 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11366 11367 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11368 ins_encode %{ 11369 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11370 %} 11371 ins_pipe(ialu_reg_reg_alu0); 11372 %} 11373 11374 11375 //----------Control Flow Instructions------------------------------------------ 11376 // Signed compare Instructions 11377 11378 // XXX more variants!! 11379 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11380 %{ 11381 match(Set cr (CmpI op1 op2)); 11382 effect(DEF cr, USE op1, USE op2); 11383 11384 format %{ "cmpl $op1, $op2" %} 11385 opcode(0x3B); /* Opcode 3B /r */ 11386 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11387 ins_pipe(ialu_cr_reg_reg); 11388 %} 11389 11390 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11391 %{ 11392 match(Set cr (CmpI op1 op2)); 11393 11394 format %{ "cmpl $op1, $op2" %} 11395 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11396 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11397 ins_pipe(ialu_cr_reg_imm); 11398 %} 11399 11400 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11401 %{ 11402 match(Set cr (CmpI op1 (LoadI op2))); 11403 11404 ins_cost(500); // XXX 11405 format %{ "cmpl $op1, $op2" %} 11406 opcode(0x3B); /* Opcode 3B /r */ 11407 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11408 ins_pipe(ialu_cr_reg_mem); 11409 %} 11410 11411 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11412 %{ 11413 match(Set cr (CmpI src zero)); 11414 11415 format %{ "testl $src, $src" %} 11416 opcode(0x85); 11417 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11418 ins_pipe(ialu_cr_reg_imm); 11419 %} 11420 11421 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11422 %{ 11423 match(Set cr (CmpI (AndI src con) zero)); 11424 11425 format %{ "testl $src, $con" %} 11426 opcode(0xF7, 0x00); 11427 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11428 ins_pipe(ialu_cr_reg_imm); 11429 %} 11430 11431 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11432 %{ 11433 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11434 11435 format %{ "testl $src, $mem" %} 11436 opcode(0x85); 11437 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11438 ins_pipe(ialu_cr_reg_mem); 11439 %} 11440 11441 // Unsigned compare Instructions; really, same as signed except they 11442 // produce an rFlagsRegU instead of rFlagsReg. 11443 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11444 %{ 11445 match(Set cr (CmpU op1 op2)); 11446 11447 format %{ "cmpl $op1, $op2\t# unsigned" %} 11448 opcode(0x3B); /* Opcode 3B /r */ 11449 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11450 ins_pipe(ialu_cr_reg_reg); 11451 %} 11452 11453 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11454 %{ 11455 match(Set cr (CmpU op1 op2)); 11456 11457 format %{ "cmpl $op1, $op2\t# unsigned" %} 11458 opcode(0x81,0x07); /* Opcode 81 /7 */ 11459 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11460 ins_pipe(ialu_cr_reg_imm); 11461 %} 11462 11463 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11464 %{ 11465 match(Set cr (CmpU op1 (LoadI op2))); 11466 11467 ins_cost(500); // XXX 11468 format %{ "cmpl $op1, $op2\t# unsigned" %} 11469 opcode(0x3B); /* Opcode 3B /r */ 11470 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11471 ins_pipe(ialu_cr_reg_mem); 11472 %} 11473 11474 // // // Cisc-spilled version of cmpU_rReg 11475 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11476 // //%{ 11477 // // match(Set cr (CmpU (LoadI op1) op2)); 11478 // // 11479 // // format %{ "CMPu $op1,$op2" %} 11480 // // ins_cost(500); 11481 // // opcode(0x39); /* Opcode 39 /r */ 11482 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11483 // //%} 11484 11485 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11486 %{ 11487 match(Set cr (CmpU src zero)); 11488 11489 format %{ "testl $src, $src\t# unsigned" %} 11490 opcode(0x85); 11491 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11492 ins_pipe(ialu_cr_reg_imm); 11493 %} 11494 11495 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11496 %{ 11497 match(Set cr (CmpP op1 op2)); 11498 11499 format %{ "cmpq $op1, $op2\t# ptr" %} 11500 opcode(0x3B); /* Opcode 3B /r */ 11501 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11502 ins_pipe(ialu_cr_reg_reg); 11503 %} 11504 11505 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11506 %{ 11507 match(Set cr (CmpP op1 (LoadP op2))); 11508 11509 ins_cost(500); // XXX 11510 format %{ "cmpq $op1, $op2\t# ptr" %} 11511 opcode(0x3B); /* Opcode 3B /r */ 11512 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11513 ins_pipe(ialu_cr_reg_mem); 11514 %} 11515 11516 // // // Cisc-spilled version of cmpP_rReg 11517 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11518 // //%{ 11519 // // match(Set cr (CmpP (LoadP op1) op2)); 11520 // // 11521 // // format %{ "CMPu $op1,$op2" %} 11522 // // ins_cost(500); 11523 // // opcode(0x39); /* Opcode 39 /r */ 11524 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11525 // //%} 11526 11527 // XXX this is generalized by compP_rReg_mem??? 11528 // Compare raw pointer (used in out-of-heap check). 11529 // Only works because non-oop pointers must be raw pointers 11530 // and raw pointers have no anti-dependencies. 11531 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11532 %{ 11533 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11534 match(Set cr (CmpP op1 (LoadP op2))); 11535 11536 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11537 opcode(0x3B); /* Opcode 3B /r */ 11538 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11539 ins_pipe(ialu_cr_reg_mem); 11540 %} 11541 11542 // This will generate a signed flags result. This should be OK since 11543 // any compare to a zero should be eq/neq. 11544 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11545 %{ 11546 match(Set cr (CmpP src zero)); 11547 11548 format %{ "testq $src, $src\t# ptr" %} 11549 opcode(0x85); 11550 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11551 ins_pipe(ialu_cr_reg_imm); 11552 %} 11553 11554 // This will generate a signed flags result. This should be OK since 11555 // any compare to a zero should be eq/neq. 11556 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11557 %{ 11558 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11559 match(Set cr (CmpP (LoadP op) zero)); 11560 11561 ins_cost(500); // XXX 11562 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11563 opcode(0xF7); /* Opcode F7 /0 */ 11564 ins_encode(REX_mem_wide(op), 11565 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11566 ins_pipe(ialu_cr_reg_imm); 11567 %} 11568 11569 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11570 %{ 11571 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11572 match(Set cr (CmpP (LoadP mem) zero)); 11573 11574 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11575 ins_encode %{ 11576 __ cmpq(r12, $mem$$Address); 11577 %} 11578 ins_pipe(ialu_cr_reg_mem); 11579 %} 11580 11581 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11582 %{ 11583 match(Set cr (CmpN op1 op2)); 11584 11585 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11586 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11587 ins_pipe(ialu_cr_reg_reg); 11588 %} 11589 11590 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11591 %{ 11592 match(Set cr (CmpN src (LoadN mem))); 11593 11594 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11595 ins_encode %{ 11596 __ cmpl($src$$Register, $mem$$Address); 11597 %} 11598 ins_pipe(ialu_cr_reg_mem); 11599 %} 11600 11601 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11602 match(Set cr (CmpN op1 op2)); 11603 11604 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11605 ins_encode %{ 11606 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11607 %} 11608 ins_pipe(ialu_cr_reg_imm); 11609 %} 11610 11611 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11612 %{ 11613 match(Set cr (CmpN src (LoadN mem))); 11614 11615 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11616 ins_encode %{ 11617 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11618 %} 11619 ins_pipe(ialu_cr_reg_mem); 11620 %} 11621 11622 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11623 match(Set cr (CmpN op1 op2)); 11624 11625 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11626 ins_encode %{ 11627 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11628 %} 11629 ins_pipe(ialu_cr_reg_imm); 11630 %} 11631 11632 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11633 %{ 11634 match(Set cr (CmpN src (LoadNKlass mem))); 11635 11636 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11637 ins_encode %{ 11638 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11639 %} 11640 ins_pipe(ialu_cr_reg_mem); 11641 %} 11642 11643 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11644 match(Set cr (CmpN src zero)); 11645 11646 format %{ "testl $src, $src\t# compressed ptr" %} 11647 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11648 ins_pipe(ialu_cr_reg_imm); 11649 %} 11650 11651 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11652 %{ 11653 predicate(Universe::narrow_oop_base() != NULL); 11654 match(Set cr (CmpN (LoadN mem) zero)); 11655 11656 ins_cost(500); // XXX 11657 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11658 ins_encode %{ 11659 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11660 %} 11661 ins_pipe(ialu_cr_reg_mem); 11662 %} 11663 11664 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11665 %{ 11666 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11667 match(Set cr (CmpN (LoadN mem) zero)); 11668 11669 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11670 ins_encode %{ 11671 __ cmpl(r12, $mem$$Address); 11672 %} 11673 ins_pipe(ialu_cr_reg_mem); 11674 %} 11675 11676 // Yanked all unsigned pointer compare operations. 11677 // Pointer compares are done with CmpP which is already unsigned. 11678 11679 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11680 %{ 11681 match(Set cr (CmpL op1 op2)); 11682 11683 format %{ "cmpq $op1, $op2" %} 11684 opcode(0x3B); /* Opcode 3B /r */ 11685 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11686 ins_pipe(ialu_cr_reg_reg); 11687 %} 11688 11689 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11690 %{ 11691 match(Set cr (CmpL op1 op2)); 11692 11693 format %{ "cmpq $op1, $op2" %} 11694 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11695 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11696 ins_pipe(ialu_cr_reg_imm); 11697 %} 11698 11699 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11700 %{ 11701 match(Set cr (CmpL op1 (LoadL op2))); 11702 11703 format %{ "cmpq $op1, $op2" %} 11704 opcode(0x3B); /* Opcode 3B /r */ 11705 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11706 ins_pipe(ialu_cr_reg_mem); 11707 %} 11708 11709 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11710 %{ 11711 match(Set cr (CmpL src zero)); 11712 11713 format %{ "testq $src, $src" %} 11714 opcode(0x85); 11715 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11716 ins_pipe(ialu_cr_reg_imm); 11717 %} 11718 11719 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11720 %{ 11721 match(Set cr (CmpL (AndL src con) zero)); 11722 11723 format %{ "testq $src, $con\t# long" %} 11724 opcode(0xF7, 0x00); 11725 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11726 ins_pipe(ialu_cr_reg_imm); 11727 %} 11728 11729 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11730 %{ 11731 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11732 11733 format %{ "testq $src, $mem" %} 11734 opcode(0x85); 11735 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11736 ins_pipe(ialu_cr_reg_mem); 11737 %} 11738 11739 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11740 %{ 11741 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11742 11743 format %{ "testq $src, $mem" %} 11744 opcode(0x85); 11745 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11746 ins_pipe(ialu_cr_reg_mem); 11747 %} 11748 11749 // Manifest a CmpL result in an integer register. Very painful. 11750 // This is the test to avoid. 11751 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11752 %{ 11753 match(Set dst (CmpL3 src1 src2)); 11754 effect(KILL flags); 11755 11756 ins_cost(275); // XXX 11757 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11758 "movl $dst, -1\n\t" 11759 "jl,s done\n\t" 11760 "setne $dst\n\t" 11761 "movzbl $dst, $dst\n\t" 11762 "done:" %} 11763 ins_encode(cmpl3_flag(src1, src2, dst)); 11764 ins_pipe(pipe_slow); 11765 %} 11766 11767 // Unsigned long compare Instructions; really, same as signed long except they 11768 // produce an rFlagsRegU instead of rFlagsReg. 11769 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11770 %{ 11771 match(Set cr (CmpUL op1 op2)); 11772 11773 format %{ "cmpq $op1, $op2\t# unsigned" %} 11774 opcode(0x3B); /* Opcode 3B /r */ 11775 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11776 ins_pipe(ialu_cr_reg_reg); 11777 %} 11778 11779 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11780 %{ 11781 match(Set cr (CmpUL op1 op2)); 11782 11783 format %{ "cmpq $op1, $op2\t# unsigned" %} 11784 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11785 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11786 ins_pipe(ialu_cr_reg_imm); 11787 %} 11788 11789 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11790 %{ 11791 match(Set cr (CmpUL op1 (LoadL op2))); 11792 11793 format %{ "cmpq $op1, $op2\t# unsigned" %} 11794 opcode(0x3B); /* Opcode 3B /r */ 11795 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11796 ins_pipe(ialu_cr_reg_mem); 11797 %} 11798 11799 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11800 %{ 11801 match(Set cr (CmpUL src zero)); 11802 11803 format %{ "testq $src, $src\t# unsigned" %} 11804 opcode(0x85); 11805 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11806 ins_pipe(ialu_cr_reg_imm); 11807 %} 11808 11809 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11810 %{ 11811 match(Set cr (CmpI (LoadB mem) imm)); 11812 11813 ins_cost(125); 11814 format %{ "cmpb $mem, $imm" %} 11815 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11816 ins_pipe(ialu_cr_reg_mem); 11817 %} 11818 11819 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 11820 %{ 11821 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11822 11823 ins_cost(125); 11824 format %{ "testb $mem, $imm" %} 11825 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11826 ins_pipe(ialu_cr_reg_mem); 11827 %} 11828 11829 //----------Max and Min-------------------------------------------------------- 11830 // Min Instructions 11831 11832 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11833 %{ 11834 effect(USE_DEF dst, USE src, USE cr); 11835 11836 format %{ "cmovlgt $dst, $src\t# min" %} 11837 opcode(0x0F, 0x4F); 11838 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11839 ins_pipe(pipe_cmov_reg); 11840 %} 11841 11842 11843 instruct minI_rReg(rRegI dst, rRegI src) 11844 %{ 11845 match(Set dst (MinI dst src)); 11846 11847 ins_cost(200); 11848 expand %{ 11849 rFlagsReg cr; 11850 compI_rReg(cr, dst, src); 11851 cmovI_reg_g(dst, src, cr); 11852 %} 11853 %} 11854 11855 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11856 %{ 11857 effect(USE_DEF dst, USE src, USE cr); 11858 11859 format %{ "cmovllt $dst, $src\t# max" %} 11860 opcode(0x0F, 0x4C); 11861 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11862 ins_pipe(pipe_cmov_reg); 11863 %} 11864 11865 11866 instruct maxI_rReg(rRegI dst, rRegI src) 11867 %{ 11868 match(Set dst (MaxI dst src)); 11869 11870 ins_cost(200); 11871 expand %{ 11872 rFlagsReg cr; 11873 compI_rReg(cr, dst, src); 11874 cmovI_reg_l(dst, src, cr); 11875 %} 11876 %} 11877 11878 // ============================================================================ 11879 // Branch Instructions 11880 11881 // Jump Direct - Label defines a relative address from JMP+1 11882 instruct jmpDir(label labl) 11883 %{ 11884 match(Goto); 11885 effect(USE labl); 11886 11887 ins_cost(300); 11888 format %{ "jmp $labl" %} 11889 size(5); 11890 ins_encode %{ 11891 Label* L = $labl$$label; 11892 __ jmp(*L, false); // Always long jump 11893 %} 11894 ins_pipe(pipe_jmp); 11895 %} 11896 11897 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11898 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11899 %{ 11900 match(If cop cr); 11901 effect(USE labl); 11902 11903 ins_cost(300); 11904 format %{ "j$cop $labl" %} 11905 size(6); 11906 ins_encode %{ 11907 Label* L = $labl$$label; 11908 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11909 %} 11910 ins_pipe(pipe_jcc); 11911 %} 11912 11913 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11914 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11915 %{ 11916 predicate(!n->has_vector_mask_set()); 11917 match(CountedLoopEnd cop cr); 11918 effect(USE labl); 11919 11920 ins_cost(300); 11921 format %{ "j$cop $labl\t# loop end" %} 11922 size(6); 11923 ins_encode %{ 11924 Label* L = $labl$$label; 11925 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11926 %} 11927 ins_pipe(pipe_jcc); 11928 %} 11929 11930 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11931 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11932 predicate(!n->has_vector_mask_set()); 11933 match(CountedLoopEnd cop cmp); 11934 effect(USE labl); 11935 11936 ins_cost(300); 11937 format %{ "j$cop,u $labl\t# loop end" %} 11938 size(6); 11939 ins_encode %{ 11940 Label* L = $labl$$label; 11941 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11942 %} 11943 ins_pipe(pipe_jcc); 11944 %} 11945 11946 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11947 predicate(!n->has_vector_mask_set()); 11948 match(CountedLoopEnd cop cmp); 11949 effect(USE labl); 11950 11951 ins_cost(200); 11952 format %{ "j$cop,u $labl\t# loop end" %} 11953 size(6); 11954 ins_encode %{ 11955 Label* L = $labl$$label; 11956 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11957 %} 11958 ins_pipe(pipe_jcc); 11959 %} 11960 11961 // mask version 11962 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11963 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 11964 %{ 11965 predicate(n->has_vector_mask_set()); 11966 match(CountedLoopEnd cop cr); 11967 effect(USE labl); 11968 11969 ins_cost(400); 11970 format %{ "j$cop $labl\t# loop end\n\t" 11971 "restorevectmask \t# vector mask restore for loops" %} 11972 size(10); 11973 ins_encode %{ 11974 Label* L = $labl$$label; 11975 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11976 __ restorevectmask(); 11977 %} 11978 ins_pipe(pipe_jcc); 11979 %} 11980 11981 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11982 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11983 predicate(n->has_vector_mask_set()); 11984 match(CountedLoopEnd cop cmp); 11985 effect(USE labl); 11986 11987 ins_cost(400); 11988 format %{ "j$cop,u $labl\t# loop end\n\t" 11989 "restorevectmask \t# vector mask restore for loops" %} 11990 size(10); 11991 ins_encode %{ 11992 Label* L = $labl$$label; 11993 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11994 __ restorevectmask(); 11995 %} 11996 ins_pipe(pipe_jcc); 11997 %} 11998 11999 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12000 predicate(n->has_vector_mask_set()); 12001 match(CountedLoopEnd cop cmp); 12002 effect(USE labl); 12003 12004 ins_cost(300); 12005 format %{ "j$cop,u $labl\t# loop end\n\t" 12006 "restorevectmask \t# vector mask restore for loops" %} 12007 size(10); 12008 ins_encode %{ 12009 Label* L = $labl$$label; 12010 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12011 __ restorevectmask(); 12012 %} 12013 ins_pipe(pipe_jcc); 12014 %} 12015 12016 // Jump Direct Conditional - using unsigned comparison 12017 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12018 match(If cop cmp); 12019 effect(USE labl); 12020 12021 ins_cost(300); 12022 format %{ "j$cop,u $labl" %} 12023 size(6); 12024 ins_encode %{ 12025 Label* L = $labl$$label; 12026 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12027 %} 12028 ins_pipe(pipe_jcc); 12029 %} 12030 12031 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12032 match(If cop cmp); 12033 effect(USE labl); 12034 12035 ins_cost(200); 12036 format %{ "j$cop,u $labl" %} 12037 size(6); 12038 ins_encode %{ 12039 Label* L = $labl$$label; 12040 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12041 %} 12042 ins_pipe(pipe_jcc); 12043 %} 12044 12045 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12046 match(If cop cmp); 12047 effect(USE labl); 12048 12049 ins_cost(200); 12050 format %{ $$template 12051 if ($cop$$cmpcode == Assembler::notEqual) { 12052 $$emit$$"jp,u $labl\n\t" 12053 $$emit$$"j$cop,u $labl" 12054 } else { 12055 $$emit$$"jp,u done\n\t" 12056 $$emit$$"j$cop,u $labl\n\t" 12057 $$emit$$"done:" 12058 } 12059 %} 12060 ins_encode %{ 12061 Label* l = $labl$$label; 12062 if ($cop$$cmpcode == Assembler::notEqual) { 12063 __ jcc(Assembler::parity, *l, false); 12064 __ jcc(Assembler::notEqual, *l, false); 12065 } else if ($cop$$cmpcode == Assembler::equal) { 12066 Label done; 12067 __ jccb(Assembler::parity, done); 12068 __ jcc(Assembler::equal, *l, false); 12069 __ bind(done); 12070 } else { 12071 ShouldNotReachHere(); 12072 } 12073 %} 12074 ins_pipe(pipe_jcc); 12075 %} 12076 12077 // ============================================================================ 12078 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12079 // superklass array for an instance of the superklass. Set a hidden 12080 // internal cache on a hit (cache is checked with exposed code in 12081 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12082 // encoding ALSO sets flags. 12083 12084 instruct partialSubtypeCheck(rdi_RegP result, 12085 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12086 rFlagsReg cr) 12087 %{ 12088 match(Set result (PartialSubtypeCheck sub super)); 12089 effect(KILL rcx, KILL cr); 12090 12091 ins_cost(1100); // slightly larger than the next version 12092 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12093 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12094 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12095 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12096 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12097 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12098 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12099 "miss:\t" %} 12100 12101 opcode(0x1); // Force a XOR of RDI 12102 ins_encode(enc_PartialSubtypeCheck()); 12103 ins_pipe(pipe_slow); 12104 %} 12105 12106 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12107 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12108 immP0 zero, 12109 rdi_RegP result) 12110 %{ 12111 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12112 effect(KILL rcx, KILL result); 12113 12114 ins_cost(1000); 12115 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12116 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12117 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12118 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12119 "jne,s miss\t\t# Missed: flags nz\n\t" 12120 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12121 "miss:\t" %} 12122 12123 opcode(0x0); // No need to XOR RDI 12124 ins_encode(enc_PartialSubtypeCheck()); 12125 ins_pipe(pipe_slow); 12126 %} 12127 12128 // ============================================================================ 12129 // Branch Instructions -- short offset versions 12130 // 12131 // These instructions are used to replace jumps of a long offset (the default 12132 // match) with jumps of a shorter offset. These instructions are all tagged 12133 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12134 // match rules in general matching. Instead, the ADLC generates a conversion 12135 // method in the MachNode which can be used to do in-place replacement of the 12136 // long variant with the shorter variant. The compiler will determine if a 12137 // branch can be taken by the is_short_branch_offset() predicate in the machine 12138 // specific code section of the file. 12139 12140 // Jump Direct - Label defines a relative address from JMP+1 12141 instruct jmpDir_short(label labl) %{ 12142 match(Goto); 12143 effect(USE labl); 12144 12145 ins_cost(300); 12146 format %{ "jmp,s $labl" %} 12147 size(2); 12148 ins_encode %{ 12149 Label* L = $labl$$label; 12150 __ jmpb(*L); 12151 %} 12152 ins_pipe(pipe_jmp); 12153 ins_short_branch(1); 12154 %} 12155 12156 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12157 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12158 match(If cop cr); 12159 effect(USE labl); 12160 12161 ins_cost(300); 12162 format %{ "j$cop,s $labl" %} 12163 size(2); 12164 ins_encode %{ 12165 Label* L = $labl$$label; 12166 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12167 %} 12168 ins_pipe(pipe_jcc); 12169 ins_short_branch(1); 12170 %} 12171 12172 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12173 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12174 match(CountedLoopEnd cop cr); 12175 effect(USE labl); 12176 12177 ins_cost(300); 12178 format %{ "j$cop,s $labl\t# loop end" %} 12179 size(2); 12180 ins_encode %{ 12181 Label* L = $labl$$label; 12182 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12183 %} 12184 ins_pipe(pipe_jcc); 12185 ins_short_branch(1); 12186 %} 12187 12188 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12189 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12190 match(CountedLoopEnd cop cmp); 12191 effect(USE labl); 12192 12193 ins_cost(300); 12194 format %{ "j$cop,us $labl\t# loop end" %} 12195 size(2); 12196 ins_encode %{ 12197 Label* L = $labl$$label; 12198 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12199 %} 12200 ins_pipe(pipe_jcc); 12201 ins_short_branch(1); 12202 %} 12203 12204 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12205 match(CountedLoopEnd cop cmp); 12206 effect(USE labl); 12207 12208 ins_cost(300); 12209 format %{ "j$cop,us $labl\t# loop end" %} 12210 size(2); 12211 ins_encode %{ 12212 Label* L = $labl$$label; 12213 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12214 %} 12215 ins_pipe(pipe_jcc); 12216 ins_short_branch(1); 12217 %} 12218 12219 // Jump Direct Conditional - using unsigned comparison 12220 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12221 match(If cop cmp); 12222 effect(USE labl); 12223 12224 ins_cost(300); 12225 format %{ "j$cop,us $labl" %} 12226 size(2); 12227 ins_encode %{ 12228 Label* L = $labl$$label; 12229 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12230 %} 12231 ins_pipe(pipe_jcc); 12232 ins_short_branch(1); 12233 %} 12234 12235 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12236 match(If cop cmp); 12237 effect(USE labl); 12238 12239 ins_cost(300); 12240 format %{ "j$cop,us $labl" %} 12241 size(2); 12242 ins_encode %{ 12243 Label* L = $labl$$label; 12244 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12245 %} 12246 ins_pipe(pipe_jcc); 12247 ins_short_branch(1); 12248 %} 12249 12250 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12251 match(If cop cmp); 12252 effect(USE labl); 12253 12254 ins_cost(300); 12255 format %{ $$template 12256 if ($cop$$cmpcode == Assembler::notEqual) { 12257 $$emit$$"jp,u,s $labl\n\t" 12258 $$emit$$"j$cop,u,s $labl" 12259 } else { 12260 $$emit$$"jp,u,s done\n\t" 12261 $$emit$$"j$cop,u,s $labl\n\t" 12262 $$emit$$"done:" 12263 } 12264 %} 12265 size(4); 12266 ins_encode %{ 12267 Label* l = $labl$$label; 12268 if ($cop$$cmpcode == Assembler::notEqual) { 12269 __ jccb(Assembler::parity, *l); 12270 __ jccb(Assembler::notEqual, *l); 12271 } else if ($cop$$cmpcode == Assembler::equal) { 12272 Label done; 12273 __ jccb(Assembler::parity, done); 12274 __ jccb(Assembler::equal, *l); 12275 __ bind(done); 12276 } else { 12277 ShouldNotReachHere(); 12278 } 12279 %} 12280 ins_pipe(pipe_jcc); 12281 ins_short_branch(1); 12282 %} 12283 12284 // ============================================================================ 12285 // inlined locking and unlocking 12286 12287 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12288 predicate(Compile::current()->use_rtm()); 12289 match(Set cr (FastLock object box)); 12290 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12291 ins_cost(300); 12292 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12293 ins_encode %{ 12294 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12295 $scr$$Register, $cx1$$Register, $cx2$$Register, 12296 _counters, _rtm_counters, _stack_rtm_counters, 12297 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12298 true, ra_->C->profile_rtm()); 12299 %} 12300 ins_pipe(pipe_slow); 12301 %} 12302 12303 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12304 predicate(!Compile::current()->use_rtm()); 12305 match(Set cr (FastLock object box)); 12306 effect(TEMP tmp, TEMP scr, USE_KILL box); 12307 ins_cost(300); 12308 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12309 ins_encode %{ 12310 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12311 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12312 %} 12313 ins_pipe(pipe_slow); 12314 %} 12315 12316 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12317 match(Set cr (FastUnlock object box)); 12318 effect(TEMP tmp, USE_KILL box); 12319 ins_cost(300); 12320 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12321 ins_encode %{ 12322 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12323 %} 12324 ins_pipe(pipe_slow); 12325 %} 12326 12327 12328 // ============================================================================ 12329 // Safepoint Instructions 12330 instruct safePoint_poll(rFlagsReg cr) 12331 %{ 12332 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12333 match(SafePoint); 12334 effect(KILL cr); 12335 12336 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12337 "# Safepoint: poll for GC" %} 12338 ins_cost(125); 12339 ins_encode %{ 12340 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12341 __ testl(rax, addr); 12342 %} 12343 ins_pipe(ialu_reg_mem); 12344 %} 12345 12346 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12347 %{ 12348 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12349 match(SafePoint poll); 12350 effect(KILL cr, USE poll); 12351 12352 format %{ "testl rax, [$poll]\t" 12353 "# Safepoint: poll for GC" %} 12354 ins_cost(125); 12355 ins_encode %{ 12356 __ relocate(relocInfo::poll_type); 12357 __ testl(rax, Address($poll$$Register, 0)); 12358 %} 12359 ins_pipe(ialu_reg_mem); 12360 %} 12361 12362 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12363 %{ 12364 predicate(SafepointMechanism::uses_thread_local_poll()); 12365 match(SafePoint poll); 12366 effect(KILL cr, USE poll); 12367 12368 format %{ "testl rax, [$poll]\t" 12369 "# Safepoint: poll for GC" %} 12370 ins_cost(125); 12371 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12372 ins_encode %{ 12373 __ relocate(relocInfo::poll_type); 12374 address pre_pc = __ pc(); 12375 __ testl(rax, Address($poll$$Register, 0)); 12376 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12377 %} 12378 ins_pipe(ialu_reg_mem); 12379 %} 12380 12381 // ============================================================================ 12382 // Procedure Call/Return Instructions 12383 // Call Java Static Instruction 12384 // Note: If this code changes, the corresponding ret_addr_offset() and 12385 // compute_padding() functions will have to be adjusted. 12386 instruct CallStaticJavaDirect(method meth) %{ 12387 match(CallStaticJava); 12388 effect(USE meth); 12389 12390 ins_cost(300); 12391 format %{ "call,static " %} 12392 opcode(0xE8); /* E8 cd */ 12393 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12394 ins_pipe(pipe_slow); 12395 ins_alignment(4); 12396 %} 12397 12398 // Call Java Dynamic Instruction 12399 // Note: If this code changes, the corresponding ret_addr_offset() and 12400 // compute_padding() functions will have to be adjusted. 12401 instruct CallDynamicJavaDirect(method meth) 12402 %{ 12403 match(CallDynamicJava); 12404 effect(USE meth); 12405 12406 ins_cost(300); 12407 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12408 "call,dynamic " %} 12409 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12410 ins_pipe(pipe_slow); 12411 ins_alignment(4); 12412 %} 12413 12414 // Call Runtime Instruction 12415 instruct CallRuntimeDirect(method meth) 12416 %{ 12417 match(CallRuntime); 12418 effect(USE meth); 12419 12420 ins_cost(300); 12421 format %{ "call,runtime " %} 12422 ins_encode(clear_avx, Java_To_Runtime(meth)); 12423 ins_pipe(pipe_slow); 12424 %} 12425 12426 // Call runtime without safepoint 12427 instruct CallLeafDirect(method meth) 12428 %{ 12429 match(CallLeaf); 12430 effect(USE meth); 12431 12432 ins_cost(300); 12433 format %{ "call_leaf,runtime " %} 12434 ins_encode(clear_avx, Java_To_Runtime(meth)); 12435 ins_pipe(pipe_slow); 12436 %} 12437 12438 // Call runtime without safepoint 12439 instruct CallLeafNoFPDirect(method meth) 12440 %{ 12441 match(CallLeafNoFP); 12442 effect(USE meth); 12443 12444 ins_cost(300); 12445 format %{ "call_leaf_nofp,runtime " %} 12446 ins_encode(clear_avx, Java_To_Runtime(meth)); 12447 ins_pipe(pipe_slow); 12448 %} 12449 12450 // Return Instruction 12451 // Remove the return address & jump to it. 12452 // Notice: We always emit a nop after a ret to make sure there is room 12453 // for safepoint patching 12454 instruct Ret() 12455 %{ 12456 match(Return); 12457 12458 format %{ "ret" %} 12459 opcode(0xC3); 12460 ins_encode(OpcP); 12461 ins_pipe(pipe_jmp); 12462 %} 12463 12464 // Tail Call; Jump from runtime stub to Java code. 12465 // Also known as an 'interprocedural jump'. 12466 // Target of jump will eventually return to caller. 12467 // TailJump below removes the return address. 12468 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12469 %{ 12470 match(TailCall jump_target method_oop); 12471 12472 ins_cost(300); 12473 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12474 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12475 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12476 ins_pipe(pipe_jmp); 12477 %} 12478 12479 // Tail Jump; remove the return address; jump to target. 12480 // TailCall above leaves the return address around. 12481 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12482 %{ 12483 match(TailJump jump_target ex_oop); 12484 12485 ins_cost(300); 12486 format %{ "popq rdx\t# pop return address\n\t" 12487 "jmp $jump_target" %} 12488 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12489 ins_encode(Opcode(0x5a), // popq rdx 12490 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12491 ins_pipe(pipe_jmp); 12492 %} 12493 12494 // Create exception oop: created by stack-crawling runtime code. 12495 // Created exception is now available to this handler, and is setup 12496 // just prior to jumping to this handler. No code emitted. 12497 instruct CreateException(rax_RegP ex_oop) 12498 %{ 12499 match(Set ex_oop (CreateEx)); 12500 12501 size(0); 12502 // use the following format syntax 12503 format %{ "# exception oop is in rax; no code emitted" %} 12504 ins_encode(); 12505 ins_pipe(empty); 12506 %} 12507 12508 // Rethrow exception: 12509 // The exception oop will come in the first argument position. 12510 // Then JUMP (not call) to the rethrow stub code. 12511 instruct RethrowException() 12512 %{ 12513 match(Rethrow); 12514 12515 // use the following format syntax 12516 format %{ "jmp rethrow_stub" %} 12517 ins_encode(enc_rethrow); 12518 ins_pipe(pipe_jmp); 12519 %} 12520 12521 // 12522 // Execute ZGC load barrier (strong) slow path 12523 // 12524 12525 // When running without XMM regs 12526 instruct loadBarrierSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12527 12528 match(Set dst (LoadBarrierSlowReg mem)); 12529 predicate(MaxVectorSize < 16); 12530 12531 effect(DEF dst, KILL cr); 12532 12533 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12534 ins_encode %{ 12535 #if INCLUDE_ZGC 12536 Register d = $dst$$Register; 12537 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12538 12539 assert(d != r12, "Can't be R12!"); 12540 assert(d != r15, "Can't be R15!"); 12541 assert(d != rsp, "Can't be RSP!"); 12542 12543 __ lea(d, $mem$$Address); 12544 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12545 #else 12546 ShouldNotReachHere(); 12547 #endif 12548 %} 12549 ins_pipe(pipe_slow); 12550 %} 12551 12552 // For XMM and YMM enabled processors 12553 instruct loadBarrierSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12554 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12555 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12556 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12557 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12558 12559 match(Set dst (LoadBarrierSlowReg mem)); 12560 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12561 12562 effect(DEF dst, KILL cr, 12563 KILL x0, KILL x1, KILL x2, KILL x3, 12564 KILL x4, KILL x5, KILL x6, KILL x7, 12565 KILL x8, KILL x9, KILL x10, KILL x11, 12566 KILL x12, KILL x13, KILL x14, KILL x15); 12567 12568 format %{"LoadBarrierSlowRegXmm $dst, $mem" %} 12569 ins_encode %{ 12570 #if INCLUDE_ZGC 12571 Register d = $dst$$Register; 12572 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12573 12574 assert(d != r12, "Can't be R12!"); 12575 assert(d != r15, "Can't be R15!"); 12576 assert(d != rsp, "Can't be RSP!"); 12577 12578 __ lea(d, $mem$$Address); 12579 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12580 #else 12581 ShouldNotReachHere(); 12582 #endif 12583 %} 12584 ins_pipe(pipe_slow); 12585 %} 12586 12587 // For ZMM enabled processors 12588 instruct loadBarrierSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12589 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12590 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12591 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12592 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12593 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12594 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12595 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12596 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12597 12598 match(Set dst (LoadBarrierSlowReg mem)); 12599 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12600 12601 effect(DEF dst, KILL cr, 12602 KILL x0, KILL x1, KILL x2, KILL x3, 12603 KILL x4, KILL x5, KILL x6, KILL x7, 12604 KILL x8, KILL x9, KILL x10, KILL x11, 12605 KILL x12, KILL x13, KILL x14, KILL x15, 12606 KILL x16, KILL x17, KILL x18, KILL x19, 12607 KILL x20, KILL x21, KILL x22, KILL x23, 12608 KILL x24, KILL x25, KILL x26, KILL x27, 12609 KILL x28, KILL x29, KILL x30, KILL x31); 12610 12611 format %{"LoadBarrierSlowRegZmm $dst, $mem" %} 12612 ins_encode %{ 12613 #if INCLUDE_ZGC 12614 Register d = $dst$$Register; 12615 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12616 12617 assert(d != r12, "Can't be R12!"); 12618 assert(d != r15, "Can't be R15!"); 12619 assert(d != rsp, "Can't be RSP!"); 12620 12621 __ lea(d, $mem$$Address); 12622 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12623 #else 12624 ShouldNotReachHere(); 12625 #endif 12626 %} 12627 ins_pipe(pipe_slow); 12628 %} 12629 12630 // 12631 // Execute ZGC load barrier (weak) slow path 12632 // 12633 12634 // When running without XMM regs 12635 instruct loadBarrierWeakSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12636 12637 match(Set dst (LoadBarrierSlowReg mem)); 12638 predicate(MaxVectorSize < 16); 12639 12640 effect(DEF dst, KILL cr); 12641 12642 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12643 ins_encode %{ 12644 #if INCLUDE_ZGC 12645 Register d = $dst$$Register; 12646 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12647 12648 assert(d != r12, "Can't be R12!"); 12649 assert(d != r15, "Can't be R15!"); 12650 assert(d != rsp, "Can't be RSP!"); 12651 12652 __ lea(d, $mem$$Address); 12653 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12654 #else 12655 ShouldNotReachHere(); 12656 #endif 12657 %} 12658 ins_pipe(pipe_slow); 12659 %} 12660 12661 // For XMM and YMM enabled processors 12662 instruct loadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12663 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12664 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12665 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12666 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12667 12668 match(Set dst (LoadBarrierWeakSlowReg mem)); 12669 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12670 12671 effect(DEF dst, KILL cr, 12672 KILL x0, KILL x1, KILL x2, KILL x3, 12673 KILL x4, KILL x5, KILL x6, KILL x7, 12674 KILL x8, KILL x9, KILL x10, KILL x11, 12675 KILL x12, KILL x13, KILL x14, KILL x15); 12676 12677 format %{"LoadBarrierWeakSlowRegXmm $dst, $mem" %} 12678 ins_encode %{ 12679 #if INCLUDE_ZGC 12680 Register d = $dst$$Register; 12681 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12682 12683 assert(d != r12, "Can't be R12!"); 12684 assert(d != r15, "Can't be R15!"); 12685 assert(d != rsp, "Can't be RSP!"); 12686 12687 __ lea(d,$mem$$Address); 12688 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12689 #else 12690 ShouldNotReachHere(); 12691 #endif 12692 %} 12693 ins_pipe(pipe_slow); 12694 %} 12695 12696 // For ZMM enabled processors 12697 instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12698 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12699 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12700 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12701 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12702 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12703 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12704 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12705 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12706 12707 match(Set dst (LoadBarrierWeakSlowReg mem)); 12708 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12709 12710 effect(DEF dst, KILL cr, 12711 KILL x0, KILL x1, KILL x2, KILL x3, 12712 KILL x4, KILL x5, KILL x6, KILL x7, 12713 KILL x8, KILL x9, KILL x10, KILL x11, 12714 KILL x12, KILL x13, KILL x14, KILL x15, 12715 KILL x16, KILL x17, KILL x18, KILL x19, 12716 KILL x20, KILL x21, KILL x22, KILL x23, 12717 KILL x24, KILL x25, KILL x26, KILL x27, 12718 KILL x28, KILL x29, KILL x30, KILL x31); 12719 12720 format %{"LoadBarrierWeakSlowRegZmm $dst, $mem" %} 12721 ins_encode %{ 12722 #if INCLUDE_ZGC 12723 Register d = $dst$$Register; 12724 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12725 12726 assert(d != r12, "Can't be R12!"); 12727 assert(d != r15, "Can't be R15!"); 12728 assert(d != rsp, "Can't be RSP!"); 12729 12730 __ lea(d,$mem$$Address); 12731 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12732 #else 12733 ShouldNotReachHere(); 12734 #endif 12735 %} 12736 ins_pipe(pipe_slow); 12737 %} 12738 12739 // ============================================================================ 12740 // This name is KNOWN by the ADLC and cannot be changed. 12741 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12742 // for this guy. 12743 instruct tlsLoadP(r15_RegP dst) %{ 12744 match(Set dst (ThreadLocal)); 12745 effect(DEF dst); 12746 12747 size(0); 12748 format %{ "# TLS is in R15" %} 12749 ins_encode( /*empty encoding*/ ); 12750 ins_pipe(ialu_reg_reg); 12751 %} 12752 12753 12754 //----------PEEPHOLE RULES----------------------------------------------------- 12755 // These must follow all instruction definitions as they use the names 12756 // defined in the instructions definitions. 12757 // 12758 // peepmatch ( root_instr_name [preceding_instruction]* ); 12759 // 12760 // peepconstraint %{ 12761 // (instruction_number.operand_name relational_op instruction_number.operand_name 12762 // [, ...] ); 12763 // // instruction numbers are zero-based using left to right order in peepmatch 12764 // 12765 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12766 // // provide an instruction_number.operand_name for each operand that appears 12767 // // in the replacement instruction's match rule 12768 // 12769 // ---------VM FLAGS--------------------------------------------------------- 12770 // 12771 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12772 // 12773 // Each peephole rule is given an identifying number starting with zero and 12774 // increasing by one in the order seen by the parser. An individual peephole 12775 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12776 // on the command-line. 12777 // 12778 // ---------CURRENT LIMITATIONS---------------------------------------------- 12779 // 12780 // Only match adjacent instructions in same basic block 12781 // Only equality constraints 12782 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12783 // Only one replacement instruction 12784 // 12785 // ---------EXAMPLE---------------------------------------------------------- 12786 // 12787 // // pertinent parts of existing instructions in architecture description 12788 // instruct movI(rRegI dst, rRegI src) 12789 // %{ 12790 // match(Set dst (CopyI src)); 12791 // %} 12792 // 12793 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12794 // %{ 12795 // match(Set dst (AddI dst src)); 12796 // effect(KILL cr); 12797 // %} 12798 // 12799 // // Change (inc mov) to lea 12800 // peephole %{ 12801 // // increment preceeded by register-register move 12802 // peepmatch ( incI_rReg movI ); 12803 // // require that the destination register of the increment 12804 // // match the destination register of the move 12805 // peepconstraint ( 0.dst == 1.dst ); 12806 // // construct a replacement instruction that sets 12807 // // the destination to ( move's source register + one ) 12808 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12809 // %} 12810 // 12811 12812 // Implementation no longer uses movX instructions since 12813 // machine-independent system no longer uses CopyX nodes. 12814 // 12815 // peephole 12816 // %{ 12817 // peepmatch (incI_rReg movI); 12818 // peepconstraint (0.dst == 1.dst); 12819 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12820 // %} 12821 12822 // peephole 12823 // %{ 12824 // peepmatch (decI_rReg movI); 12825 // peepconstraint (0.dst == 1.dst); 12826 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12827 // %} 12828 12829 // peephole 12830 // %{ 12831 // peepmatch (addI_rReg_imm movI); 12832 // peepconstraint (0.dst == 1.dst); 12833 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12834 // %} 12835 12836 // peephole 12837 // %{ 12838 // peepmatch (incL_rReg movL); 12839 // peepconstraint (0.dst == 1.dst); 12840 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12841 // %} 12842 12843 // peephole 12844 // %{ 12845 // peepmatch (decL_rReg movL); 12846 // peepconstraint (0.dst == 1.dst); 12847 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12848 // %} 12849 12850 // peephole 12851 // %{ 12852 // peepmatch (addL_rReg_imm movL); 12853 // peepconstraint (0.dst == 1.dst); 12854 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12855 // %} 12856 12857 // peephole 12858 // %{ 12859 // peepmatch (addP_rReg_imm movP); 12860 // peepconstraint (0.dst == 1.dst); 12861 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12862 // %} 12863 12864 // // Change load of spilled value to only a spill 12865 // instruct storeI(memory mem, rRegI src) 12866 // %{ 12867 // match(Set mem (StoreI mem src)); 12868 // %} 12869 // 12870 // instruct loadI(rRegI dst, memory mem) 12871 // %{ 12872 // match(Set dst (LoadI mem)); 12873 // %} 12874 // 12875 12876 peephole 12877 %{ 12878 peepmatch (loadI storeI); 12879 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12880 peepreplace (storeI(1.mem 1.mem 1.src)); 12881 %} 12882 12883 peephole 12884 %{ 12885 peepmatch (loadL storeL); 12886 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12887 peepreplace (storeL(1.mem 1.mem 1.src)); 12888 %} 12889 12890 //----------SMARTSPILL RULES--------------------------------------------------- 12891 // These must follow all instruction definitions as they use the names 12892 // defined in the instructions definitions.