1 // 2 // Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // Specify priority of register selection within phases of register 135 // allocation. Highest priority is first. A useful heuristic is to 136 // give registers a low priority when they are required by machine 137 // instructions, like EAX and EDX on I486, and choose no-save registers 138 // before save-on-call, & save-on-call before save-on-entry. Registers 139 // which participate in fixed calling sequences should come last. 140 // Registers which are used as pairs must fall on an even boundary. 141 142 alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160 //----------Architecture Description Register Classes-------------------------- 161 // Several register classes are automatically defined based upon information in 162 // this architecture description. 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167 // 168 169 // Empty register class. 170 reg_class no_reg(); 171 172 // Class for all pointer registers (including RSP and RBP) 173 reg_class any_reg_with_rbp(RAX, RAX_H, 174 RDX, RDX_H, 175 RBP, RBP_H, 176 RDI, RDI_H, 177 RSI, RSI_H, 178 RCX, RCX_H, 179 RBX, RBX_H, 180 RSP, RSP_H, 181 R8, R8_H, 182 R9, R9_H, 183 R10, R10_H, 184 R11, R11_H, 185 R12, R12_H, 186 R13, R13_H, 187 R14, R14_H, 188 R15, R15_H); 189 190 // Class for all pointer registers (including RSP, but excluding RBP) 191 reg_class any_reg_no_rbp(RAX, RAX_H, 192 RDX, RDX_H, 193 RDI, RDI_H, 194 RSI, RSI_H, 195 RCX, RCX_H, 196 RBX, RBX_H, 197 RSP, RSP_H, 198 R8, R8_H, 199 R9, R9_H, 200 R10, R10_H, 201 R11, R11_H, 202 R12, R12_H, 203 R13, R13_H, 204 R14, R14_H, 205 R15, R15_H); 206 207 // Dynamic register class that selects at runtime between register classes 208 // any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer). 209 // Equivalent to: return PreserveFramePointer ? any_reg_no_rbp : any_reg_with_rbp; 210 reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %}); 211 212 // Class for all pointer registers (excluding RSP) 213 reg_class ptr_reg_with_rbp(RAX, RAX_H, 214 RDX, RDX_H, 215 RBP, RBP_H, 216 RDI, RDI_H, 217 RSI, RSI_H, 218 RCX, RCX_H, 219 RBX, RBX_H, 220 R8, R8_H, 221 R9, R9_H, 222 R10, R10_H, 223 R11, R11_H, 224 R13, R13_H, 225 R14, R14_H); 226 227 // Class for all pointer registers (excluding RSP and RBP) 228 reg_class ptr_reg_no_rbp(RAX, RAX_H, 229 RDX, RDX_H, 230 RDI, RDI_H, 231 RSI, RSI_H, 232 RCX, RCX_H, 233 RBX, RBX_H, 234 R8, R8_H, 235 R9, R9_H, 236 R10, R10_H, 237 R11, R11_H, 238 R13, R13_H, 239 R14, R14_H); 240 241 // Dynamic register class that selects between ptr_reg_no_rbp and ptr_reg_with_rbp. 242 reg_class_dynamic ptr_reg(ptr_reg_no_rbp, ptr_reg_with_rbp, %{ PreserveFramePointer %}); 243 244 // Class for all pointer registers (excluding RAX and RSP) 245 reg_class ptr_no_rax_reg_with_rbp(RDX, RDX_H, 246 RBP, RBP_H, 247 RDI, RDI_H, 248 RSI, RSI_H, 249 RCX, RCX_H, 250 RBX, RBX_H, 251 R8, R8_H, 252 R9, R9_H, 253 R10, R10_H, 254 R11, R11_H, 255 R13, R13_H, 256 R14, R14_H); 257 258 // Class for all pointer registers (excluding RAX, RSP, and RBP) 259 reg_class ptr_no_rax_reg_no_rbp(RDX, RDX_H, 260 RDI, RDI_H, 261 RSI, RSI_H, 262 RCX, RCX_H, 263 RBX, RBX_H, 264 R8, R8_H, 265 R9, R9_H, 266 R10, R10_H, 267 R11, R11_H, 268 R13, R13_H, 269 R14, R14_H); 270 271 // Dynamic register class that selects between ptr_no_rax_reg_no_rbp and ptr_no_rax_reg_with_rbp. 272 reg_class_dynamic ptr_no_rax_reg(ptr_no_rax_reg_no_rbp, ptr_no_rax_reg_with_rbp, %{ PreserveFramePointer %}); 273 274 // Class for all pointer registers (excluding RAX, RBX, and RSP) 275 reg_class ptr_no_rax_rbx_reg_with_rbp(RDX, RDX_H, 276 RBP, RBP_H, 277 RDI, RDI_H, 278 RSI, RSI_H, 279 RCX, RCX_H, 280 R8, R8_H, 281 R9, R9_H, 282 R10, R10_H, 283 R11, R11_H, 284 R13, R13_H, 285 R14, R14_H); 286 287 // Class for all pointer registers (excluding RAX, RBX, RSP, and RBP) 288 reg_class ptr_no_rax_rbx_reg_no_rbp(RDX, RDX_H, 289 RDI, RDI_H, 290 RSI, RSI_H, 291 RCX, RCX_H, 292 R8, R8_H, 293 R9, R9_H, 294 R10, R10_H, 295 R11, R11_H, 296 R13, R13_H, 297 R14, R14_H); 298 299 // Dynamic register class that selects between ptr_no_rax_rbx_reg_no_rbp and ptr_no_rax_rbx_reg_with_rbp. 300 reg_class_dynamic ptr_no_rax_rbx_reg(ptr_no_rax_rbx_reg_no_rbp, ptr_no_rax_rbx_reg_with_rbp, %{ PreserveFramePointer %}); 301 302 // Singleton class for RAX pointer register 303 reg_class ptr_rax_reg(RAX, RAX_H); 304 305 // Singleton class for RBX pointer register 306 reg_class ptr_rbx_reg(RBX, RBX_H); 307 308 // Singleton class for RSI pointer register 309 reg_class ptr_rsi_reg(RSI, RSI_H); 310 311 // Singleton class for RDI pointer register 312 reg_class ptr_rdi_reg(RDI, RDI_H); 313 314 // Singleton class for stack pointer 315 reg_class ptr_rsp_reg(RSP, RSP_H); 316 317 // Singleton class for TLS pointer 318 reg_class ptr_r15_reg(R15, R15_H); 319 320 // Class for all long registers (excluding RSP) 321 reg_class long_reg_with_rbp(RAX, RAX_H, 322 RDX, RDX_H, 323 RBP, RBP_H, 324 RDI, RDI_H, 325 RSI, RSI_H, 326 RCX, RCX_H, 327 RBX, RBX_H, 328 R8, R8_H, 329 R9, R9_H, 330 R10, R10_H, 331 R11, R11_H, 332 R13, R13_H, 333 R14, R14_H); 334 335 // Class for all long registers (excluding RSP and RBP) 336 reg_class long_reg_no_rbp(RAX, RAX_H, 337 RDX, RDX_H, 338 RDI, RDI_H, 339 RSI, RSI_H, 340 RCX, RCX_H, 341 RBX, RBX_H, 342 R8, R8_H, 343 R9, R9_H, 344 R10, R10_H, 345 R11, R11_H, 346 R13, R13_H, 347 R14, R14_H); 348 349 // Dynamic register class that selects between long_reg_no_rbp and long_reg_with_rbp. 350 reg_class_dynamic long_reg(long_reg_no_rbp, long_reg_with_rbp, %{ PreserveFramePointer %}); 351 352 // Class for all long registers (excluding RAX, RDX and RSP) 353 reg_class long_no_rax_rdx_reg_with_rbp(RBP, RBP_H, 354 RDI, RDI_H, 355 RSI, RSI_H, 356 RCX, RCX_H, 357 RBX, RBX_H, 358 R8, R8_H, 359 R9, R9_H, 360 R10, R10_H, 361 R11, R11_H, 362 R13, R13_H, 363 R14, R14_H); 364 365 // Class for all long registers (excluding RAX, RDX, RSP, and RBP) 366 reg_class long_no_rax_rdx_reg_no_rbp(RDI, RDI_H, 367 RSI, RSI_H, 368 RCX, RCX_H, 369 RBX, RBX_H, 370 R8, R8_H, 371 R9, R9_H, 372 R10, R10_H, 373 R11, R11_H, 374 R13, R13_H, 375 R14, R14_H); 376 377 // Dynamic register class that selects between long_no_rax_rdx_reg_no_rbp and long_no_rax_rdx_reg_with_rbp. 378 reg_class_dynamic long_no_rax_rdx_reg(long_no_rax_rdx_reg_no_rbp, long_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 379 380 // Class for all long registers (excluding RCX and RSP) 381 reg_class long_no_rcx_reg_with_rbp(RBP, RBP_H, 382 RDI, RDI_H, 383 RSI, RSI_H, 384 RAX, RAX_H, 385 RDX, RDX_H, 386 RBX, RBX_H, 387 R8, R8_H, 388 R9, R9_H, 389 R10, R10_H, 390 R11, R11_H, 391 R13, R13_H, 392 R14, R14_H); 393 394 // Class for all long registers (excluding RCX, RSP, and RBP) 395 reg_class long_no_rcx_reg_no_rbp(RDI, RDI_H, 396 RSI, RSI_H, 397 RAX, RAX_H, 398 RDX, RDX_H, 399 RBX, RBX_H, 400 R8, R8_H, 401 R9, R9_H, 402 R10, R10_H, 403 R11, R11_H, 404 R13, R13_H, 405 R14, R14_H); 406 407 // Dynamic register class that selects between long_no_rcx_reg_no_rbp and long_no_rcx_reg_with_rbp. 408 reg_class_dynamic long_no_rcx_reg(long_no_rcx_reg_no_rbp, long_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 409 410 // Singleton class for RAX long register 411 reg_class long_rax_reg(RAX, RAX_H); 412 413 // Singleton class for RCX long register 414 reg_class long_rcx_reg(RCX, RCX_H); 415 416 // Singleton class for RDX long register 417 reg_class long_rdx_reg(RDX, RDX_H); 418 419 // Class for all int registers (excluding RSP) 420 reg_class int_reg_with_rbp(RAX, 421 RDX, 422 RBP, 423 RDI, 424 RSI, 425 RCX, 426 RBX, 427 R8, 428 R9, 429 R10, 430 R11, 431 R13, 432 R14); 433 434 // Class for all int registers (excluding RSP and RBP) 435 reg_class int_reg_no_rbp(RAX, 436 RDX, 437 RDI, 438 RSI, 439 RCX, 440 RBX, 441 R8, 442 R9, 443 R10, 444 R11, 445 R13, 446 R14); 447 448 // Dynamic register class that selects between int_reg_no_rbp and int_reg_with_rbp. 449 reg_class_dynamic int_reg(int_reg_no_rbp, int_reg_with_rbp, %{ PreserveFramePointer %}); 450 451 // Class for all int registers (excluding RCX and RSP) 452 reg_class int_no_rcx_reg_with_rbp(RAX, 453 RDX, 454 RBP, 455 RDI, 456 RSI, 457 RBX, 458 R8, 459 R9, 460 R10, 461 R11, 462 R13, 463 R14); 464 465 // Class for all int registers (excluding RCX, RSP, and RBP) 466 reg_class int_no_rcx_reg_no_rbp(RAX, 467 RDX, 468 RDI, 469 RSI, 470 RBX, 471 R8, 472 R9, 473 R10, 474 R11, 475 R13, 476 R14); 477 478 // Dynamic register class that selects between int_no_rcx_reg_no_rbp and int_no_rcx_reg_with_rbp. 479 reg_class_dynamic int_no_rcx_reg(int_no_rcx_reg_no_rbp, int_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 480 481 // Class for all int registers (excluding RAX, RDX, and RSP) 482 reg_class int_no_rax_rdx_reg_with_rbp(RBP, 483 RDI, 484 RSI, 485 RCX, 486 RBX, 487 R8, 488 R9, 489 R10, 490 R11, 491 R13, 492 R14); 493 494 // Class for all int registers (excluding RAX, RDX, RSP, and RBP) 495 reg_class int_no_rax_rdx_reg_no_rbp(RDI, 496 RSI, 497 RCX, 498 RBX, 499 R8, 500 R9, 501 R10, 502 R11, 503 R13, 504 R14); 505 506 // Dynamic register class that selects between int_no_rax_rdx_reg_no_rbp and int_no_rax_rdx_reg_with_rbp. 507 reg_class_dynamic int_no_rax_rdx_reg(int_no_rax_rdx_reg_no_rbp, int_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 508 509 // Singleton class for RAX int register 510 reg_class int_rax_reg(RAX); 511 512 // Singleton class for RBX int register 513 reg_class int_rbx_reg(RBX); 514 515 // Singleton class for RCX int register 516 reg_class int_rcx_reg(RCX); 517 518 // Singleton class for RCX int register 519 reg_class int_rdx_reg(RDX); 520 521 // Singleton class for RCX int register 522 reg_class int_rdi_reg(RDI); 523 524 // Singleton class for instruction pointer 525 // reg_class ip_reg(RIP); 526 527 %} 528 529 source_hpp %{ 530 #if INCLUDE_ZGC 531 #include "gc/z/zBarrierSetAssembler.hpp" 532 #endif 533 %} 534 535 //----------SOURCE BLOCK------------------------------------------------------- 536 // This is a block of C++ code which provides values, functions, and 537 // definitions necessary in the rest of the architecture description 538 source %{ 539 #define RELOC_IMM64 Assembler::imm_operand 540 #define RELOC_DISP32 Assembler::disp32_operand 541 542 #define __ _masm. 543 544 static bool generate_vzeroupper(Compile* C) { 545 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 546 } 547 548 static int clear_avx_size() { 549 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 550 } 551 552 // !!!!! Special hack to get all types of calls to specify the byte offset 553 // from the start of the call to the point where the return address 554 // will point. 555 int MachCallStaticJavaNode::ret_addr_offset() 556 { 557 int offset = 5; // 5 bytes from start of call to where return address points 558 offset += clear_avx_size(); 559 return offset; 560 } 561 562 int MachCallDynamicJavaNode::ret_addr_offset() 563 { 564 int offset = 15; // 15 bytes from start of call to where return address points 565 offset += clear_avx_size(); 566 return offset; 567 } 568 569 int MachCallRuntimeNode::ret_addr_offset() { 570 int offset = 13; // movq r10,#addr; callq (r10) 571 offset += clear_avx_size(); 572 return offset; 573 } 574 575 // Indicate if the safepoint node needs the polling page as an input, 576 // it does if the polling page is more than disp32 away. 577 bool SafePointNode::needs_polling_address_input() 578 { 579 return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far(); 580 } 581 582 // 583 // Compute padding required for nodes which need alignment 584 // 585 586 // The address of the call instruction needs to be 4-byte aligned to 587 // ensure that it does not span a cache line so that it can be patched. 588 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 589 { 590 current_offset += clear_avx_size(); // skip vzeroupper 591 current_offset += 1; // skip call opcode byte 592 return align_up(current_offset, alignment_required()) - current_offset; 593 } 594 595 // The address of the call instruction needs to be 4-byte aligned to 596 // ensure that it does not span a cache line so that it can be patched. 597 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 598 { 599 current_offset += clear_avx_size(); // skip vzeroupper 600 current_offset += 11; // skip movq instruction + call opcode byte 601 return align_up(current_offset, alignment_required()) - current_offset; 602 } 603 604 // EMIT_RM() 605 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 606 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 607 cbuf.insts()->emit_int8(c); 608 } 609 610 // EMIT_CC() 611 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 612 unsigned char c = (unsigned char) (f1 | f2); 613 cbuf.insts()->emit_int8(c); 614 } 615 616 // EMIT_OPCODE() 617 void emit_opcode(CodeBuffer &cbuf, int code) { 618 cbuf.insts()->emit_int8((unsigned char) code); 619 } 620 621 // EMIT_OPCODE() w/ relocation information 622 void emit_opcode(CodeBuffer &cbuf, 623 int code, relocInfo::relocType reloc, int offset, int format) 624 { 625 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 626 emit_opcode(cbuf, code); 627 } 628 629 // EMIT_D8() 630 void emit_d8(CodeBuffer &cbuf, int d8) { 631 cbuf.insts()->emit_int8((unsigned char) d8); 632 } 633 634 // EMIT_D16() 635 void emit_d16(CodeBuffer &cbuf, int d16) { 636 cbuf.insts()->emit_int16(d16); 637 } 638 639 // EMIT_D32() 640 void emit_d32(CodeBuffer &cbuf, int d32) { 641 cbuf.insts()->emit_int32(d32); 642 } 643 644 // EMIT_D64() 645 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 646 cbuf.insts()->emit_int64(d64); 647 } 648 649 // emit 32 bit value and construct relocation entry from relocInfo::relocType 650 void emit_d32_reloc(CodeBuffer& cbuf, 651 int d32, 652 relocInfo::relocType reloc, 653 int format) 654 { 655 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 656 cbuf.relocate(cbuf.insts_mark(), reloc, format); 657 cbuf.insts()->emit_int32(d32); 658 } 659 660 // emit 32 bit value and construct relocation entry from RelocationHolder 661 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 662 #ifdef ASSERT 663 if (rspec.reloc()->type() == relocInfo::oop_type && 664 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 665 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 666 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop((intptr_t)d32))), "cannot embed scavengable oops in code"); 667 } 668 #endif 669 cbuf.relocate(cbuf.insts_mark(), rspec, format); 670 cbuf.insts()->emit_int32(d32); 671 } 672 673 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 674 address next_ip = cbuf.insts_end() + 4; 675 emit_d32_reloc(cbuf, (int) (addr - next_ip), 676 external_word_Relocation::spec(addr), 677 RELOC_DISP32); 678 } 679 680 681 // emit 64 bit value and construct relocation entry from relocInfo::relocType 682 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 683 cbuf.relocate(cbuf.insts_mark(), reloc, format); 684 cbuf.insts()->emit_int64(d64); 685 } 686 687 // emit 64 bit value and construct relocation entry from RelocationHolder 688 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 689 #ifdef ASSERT 690 if (rspec.reloc()->type() == relocInfo::oop_type && 691 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 692 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 693 assert(oopDesc::is_oop(cast_to_oop(d64)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop(d64))), 694 "cannot embed scavengable oops in code"); 695 } 696 #endif 697 cbuf.relocate(cbuf.insts_mark(), rspec, format); 698 cbuf.insts()->emit_int64(d64); 699 } 700 701 // Access stack slot for load or store 702 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 703 { 704 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 705 if (-0x80 <= disp && disp < 0x80) { 706 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 707 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 708 emit_d8(cbuf, disp); // Displacement // R/M byte 709 } else { 710 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 711 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 712 emit_d32(cbuf, disp); // Displacement // R/M byte 713 } 714 } 715 716 // rRegI ereg, memory mem) %{ // emit_reg_mem 717 void encode_RegMem(CodeBuffer &cbuf, 718 int reg, 719 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 720 { 721 assert(disp_reloc == relocInfo::none, "cannot have disp"); 722 int regenc = reg & 7; 723 int baseenc = base & 7; 724 int indexenc = index & 7; 725 726 // There is no index & no scale, use form without SIB byte 727 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 728 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 729 if (disp == 0 && base != RBP_enc && base != R13_enc) { 730 emit_rm(cbuf, 0x0, regenc, baseenc); // * 731 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 732 // If 8-bit displacement, mode 0x1 733 emit_rm(cbuf, 0x1, regenc, baseenc); // * 734 emit_d8(cbuf, disp); 735 } else { 736 // If 32-bit displacement 737 if (base == -1) { // Special flag for absolute address 738 emit_rm(cbuf, 0x0, regenc, 0x5); // * 739 if (disp_reloc != relocInfo::none) { 740 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 741 } else { 742 emit_d32(cbuf, disp); 743 } 744 } else { 745 // Normal base + offset 746 emit_rm(cbuf, 0x2, regenc, baseenc); // * 747 if (disp_reloc != relocInfo::none) { 748 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 749 } else { 750 emit_d32(cbuf, disp); 751 } 752 } 753 } 754 } else { 755 // Else, encode with the SIB byte 756 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 757 if (disp == 0 && base != RBP_enc && base != R13_enc) { 758 // If no displacement 759 emit_rm(cbuf, 0x0, regenc, 0x4); // * 760 emit_rm(cbuf, scale, indexenc, baseenc); 761 } else { 762 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 763 // If 8-bit displacement, mode 0x1 764 emit_rm(cbuf, 0x1, regenc, 0x4); // * 765 emit_rm(cbuf, scale, indexenc, baseenc); 766 emit_d8(cbuf, disp); 767 } else { 768 // If 32-bit displacement 769 if (base == 0x04 ) { 770 emit_rm(cbuf, 0x2, regenc, 0x4); 771 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 772 } else { 773 emit_rm(cbuf, 0x2, regenc, 0x4); 774 emit_rm(cbuf, scale, indexenc, baseenc); // * 775 } 776 if (disp_reloc != relocInfo::none) { 777 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 778 } else { 779 emit_d32(cbuf, disp); 780 } 781 } 782 } 783 } 784 } 785 786 // This could be in MacroAssembler but it's fairly C2 specific 787 void emit_cmpfp_fixup(MacroAssembler& _masm) { 788 Label exit; 789 __ jccb(Assembler::noParity, exit); 790 __ pushf(); 791 // 792 // comiss/ucomiss instructions set ZF,PF,CF flags and 793 // zero OF,AF,SF for NaN values. 794 // Fixup flags by zeroing ZF,PF so that compare of NaN 795 // values returns 'less than' result (CF is set). 796 // Leave the rest of flags unchanged. 797 // 798 // 7 6 5 4 3 2 1 0 799 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 800 // 0 0 1 0 1 0 1 1 (0x2B) 801 // 802 __ andq(Address(rsp, 0), 0xffffff2b); 803 __ popf(); 804 __ bind(exit); 805 } 806 807 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 808 Label done; 809 __ movl(dst, -1); 810 __ jcc(Assembler::parity, done); 811 __ jcc(Assembler::below, done); 812 __ setb(Assembler::notEqual, dst); 813 __ movzbl(dst, dst); 814 __ bind(done); 815 } 816 817 818 //============================================================================= 819 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 820 821 int Compile::ConstantTable::calculate_table_base_offset() const { 822 return 0; // absolute addressing, no offset 823 } 824 825 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 826 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 827 ShouldNotReachHere(); 828 } 829 830 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 831 // Empty encoding 832 } 833 834 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 835 return 0; 836 } 837 838 #ifndef PRODUCT 839 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 840 st->print("# MachConstantBaseNode (empty encoding)"); 841 } 842 #endif 843 844 845 //============================================================================= 846 #ifndef PRODUCT 847 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 848 Compile* C = ra_->C; 849 850 int framesize = C->frame_size_in_bytes(); 851 int bangsize = C->bang_size_in_bytes(); 852 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 853 // Remove wordSize for return addr which is already pushed. 854 framesize -= wordSize; 855 856 if (C->need_stack_bang(bangsize)) { 857 framesize -= wordSize; 858 st->print("# stack bang (%d bytes)", bangsize); 859 st->print("\n\t"); 860 st->print("pushq rbp\t# Save rbp"); 861 if (PreserveFramePointer) { 862 st->print("\n\t"); 863 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 864 } 865 if (framesize) { 866 st->print("\n\t"); 867 st->print("subq rsp, #%d\t# Create frame",framesize); 868 } 869 } else { 870 st->print("subq rsp, #%d\t# Create frame",framesize); 871 st->print("\n\t"); 872 framesize -= wordSize; 873 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 874 if (PreserveFramePointer) { 875 st->print("\n\t"); 876 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 877 if (framesize > 0) { 878 st->print("\n\t"); 879 st->print("addq rbp, #%d", framesize); 880 } 881 } 882 } 883 884 if (VerifyStackAtCalls) { 885 st->print("\n\t"); 886 framesize -= wordSize; 887 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 888 #ifdef ASSERT 889 st->print("\n\t"); 890 st->print("# stack alignment check"); 891 #endif 892 } 893 st->cr(); 894 } 895 #endif 896 897 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 898 Compile* C = ra_->C; 899 MacroAssembler _masm(&cbuf); 900 901 int framesize = C->frame_size_in_bytes(); 902 int bangsize = C->bang_size_in_bytes(); 903 904 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); 905 906 C->set_frame_complete(cbuf.insts_size()); 907 908 if (C->has_mach_constant_base_node()) { 909 // NOTE: We set the table base offset here because users might be 910 // emitted before MachConstantBaseNode. 911 Compile::ConstantTable& constant_table = C->constant_table(); 912 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 913 } 914 } 915 916 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 917 { 918 return MachNode::size(ra_); // too many variables; just compute it 919 // the hard way 920 } 921 922 int MachPrologNode::reloc() const 923 { 924 return 0; // a large enough number 925 } 926 927 //============================================================================= 928 #ifndef PRODUCT 929 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 930 { 931 Compile* C = ra_->C; 932 if (generate_vzeroupper(C)) { 933 st->print("vzeroupper"); 934 st->cr(); st->print("\t"); 935 } 936 937 int framesize = C->frame_size_in_bytes(); 938 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 939 // Remove word for return adr already pushed 940 // and RBP 941 framesize -= 2*wordSize; 942 943 if (framesize) { 944 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 945 st->print("\t"); 946 } 947 948 st->print_cr("popq rbp"); 949 if (do_polling() && C->is_method_compilation()) { 950 st->print("\t"); 951 if (SafepointMechanism::uses_thread_local_poll()) { 952 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 953 "testl rax, [rscratch1]\t" 954 "# Safepoint: poll for GC"); 955 } else if (Assembler::is_polling_page_far()) { 956 st->print_cr("movq rscratch1, #polling_page_address\n\t" 957 "testl rax, [rscratch1]\t" 958 "# Safepoint: poll for GC"); 959 } else { 960 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 961 "# Safepoint: poll for GC"); 962 } 963 } 964 } 965 #endif 966 967 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 968 { 969 Compile* C = ra_->C; 970 MacroAssembler _masm(&cbuf); 971 972 if (generate_vzeroupper(C)) { 973 // Clear upper bits of YMM registers when current compiled code uses 974 // wide vectors to avoid AVX <-> SSE transition penalty during call. 975 __ vzeroupper(); 976 } 977 978 int framesize = C->frame_size_in_bytes(); 979 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 980 // Remove word for return adr already pushed 981 // and RBP 982 framesize -= 2*wordSize; 983 984 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 985 986 if (framesize) { 987 emit_opcode(cbuf, Assembler::REX_W); 988 if (framesize < 0x80) { 989 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 990 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 991 emit_d8(cbuf, framesize); 992 } else { 993 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 994 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 995 emit_d32(cbuf, framesize); 996 } 997 } 998 999 // popq rbp 1000 emit_opcode(cbuf, 0x58 | RBP_enc); 1001 1002 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1003 __ reserved_stack_check(); 1004 } 1005 1006 if (do_polling() && C->is_method_compilation()) { 1007 MacroAssembler _masm(&cbuf); 1008 if (SafepointMechanism::uses_thread_local_poll()) { 1009 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 1010 __ relocate(relocInfo::poll_return_type); 1011 __ testl(rax, Address(rscratch1, 0)); 1012 } else { 1013 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1014 if (Assembler::is_polling_page_far()) { 1015 __ lea(rscratch1, polling_page); 1016 __ relocate(relocInfo::poll_return_type); 1017 __ testl(rax, Address(rscratch1, 0)); 1018 } else { 1019 __ testl(rax, polling_page); 1020 } 1021 } 1022 } 1023 } 1024 1025 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1026 { 1027 return MachNode::size(ra_); // too many variables; just compute it 1028 // the hard way 1029 } 1030 1031 int MachEpilogNode::reloc() const 1032 { 1033 return 2; // a large enough number 1034 } 1035 1036 const Pipeline* MachEpilogNode::pipeline() const 1037 { 1038 return MachNode::pipeline_class(); 1039 } 1040 1041 int MachEpilogNode::safepoint_offset() const 1042 { 1043 return 0; 1044 } 1045 1046 //============================================================================= 1047 1048 enum RC { 1049 rc_bad, 1050 rc_int, 1051 rc_float, 1052 rc_stack 1053 }; 1054 1055 static enum RC rc_class(OptoReg::Name reg) 1056 { 1057 if( !OptoReg::is_valid(reg) ) return rc_bad; 1058 1059 if (OptoReg::is_stack(reg)) return rc_stack; 1060 1061 VMReg r = OptoReg::as_VMReg(reg); 1062 1063 if (r->is_Register()) return rc_int; 1064 1065 assert(r->is_XMMRegister(), "must be"); 1066 return rc_float; 1067 } 1068 1069 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1070 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1071 int src_hi, int dst_hi, uint ireg, outputStream* st); 1072 1073 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1074 int stack_offset, int reg, uint ireg, outputStream* st); 1075 1076 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1077 int dst_offset, uint ireg, outputStream* st) { 1078 if (cbuf) { 1079 MacroAssembler _masm(cbuf); 1080 switch (ireg) { 1081 case Op_VecS: 1082 __ movq(Address(rsp, -8), rax); 1083 __ movl(rax, Address(rsp, src_offset)); 1084 __ movl(Address(rsp, dst_offset), rax); 1085 __ movq(rax, Address(rsp, -8)); 1086 break; 1087 case Op_VecD: 1088 __ pushq(Address(rsp, src_offset)); 1089 __ popq (Address(rsp, dst_offset)); 1090 break; 1091 case Op_VecX: 1092 __ pushq(Address(rsp, src_offset)); 1093 __ popq (Address(rsp, dst_offset)); 1094 __ pushq(Address(rsp, src_offset+8)); 1095 __ popq (Address(rsp, dst_offset+8)); 1096 break; 1097 case Op_VecY: 1098 __ vmovdqu(Address(rsp, -32), xmm0); 1099 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1100 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1101 __ vmovdqu(xmm0, Address(rsp, -32)); 1102 break; 1103 case Op_VecZ: 1104 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1105 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1106 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1107 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1108 break; 1109 default: 1110 ShouldNotReachHere(); 1111 } 1112 #ifndef PRODUCT 1113 } else { 1114 switch (ireg) { 1115 case Op_VecS: 1116 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1117 "movl rax, [rsp + #%d]\n\t" 1118 "movl [rsp + #%d], rax\n\t" 1119 "movq rax, [rsp - #8]", 1120 src_offset, dst_offset); 1121 break; 1122 case Op_VecD: 1123 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1124 "popq [rsp + #%d]", 1125 src_offset, dst_offset); 1126 break; 1127 case Op_VecX: 1128 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1129 "popq [rsp + #%d]\n\t" 1130 "pushq [rsp + #%d]\n\t" 1131 "popq [rsp + #%d]", 1132 src_offset, dst_offset, src_offset+8, dst_offset+8); 1133 break; 1134 case Op_VecY: 1135 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1136 "vmovdqu xmm0, [rsp + #%d]\n\t" 1137 "vmovdqu [rsp + #%d], xmm0\n\t" 1138 "vmovdqu xmm0, [rsp - #32]", 1139 src_offset, dst_offset); 1140 break; 1141 case Op_VecZ: 1142 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1143 "vmovdqu xmm0, [rsp + #%d]\n\t" 1144 "vmovdqu [rsp + #%d], xmm0\n\t" 1145 "vmovdqu xmm0, [rsp - #64]", 1146 src_offset, dst_offset); 1147 break; 1148 default: 1149 ShouldNotReachHere(); 1150 } 1151 #endif 1152 } 1153 } 1154 1155 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1156 PhaseRegAlloc* ra_, 1157 bool do_size, 1158 outputStream* st) const { 1159 assert(cbuf != NULL || st != NULL, "sanity"); 1160 // Get registers to move 1161 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1162 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1163 OptoReg::Name dst_second = ra_->get_reg_second(this); 1164 OptoReg::Name dst_first = ra_->get_reg_first(this); 1165 1166 enum RC src_second_rc = rc_class(src_second); 1167 enum RC src_first_rc = rc_class(src_first); 1168 enum RC dst_second_rc = rc_class(dst_second); 1169 enum RC dst_first_rc = rc_class(dst_first); 1170 1171 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1172 "must move at least 1 register" ); 1173 1174 if (src_first == dst_first && src_second == dst_second) { 1175 // Self copy, no move 1176 return 0; 1177 } 1178 if (bottom_type()->isa_vect() != NULL) { 1179 uint ireg = ideal_reg(); 1180 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1181 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1182 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1183 // mem -> mem 1184 int src_offset = ra_->reg2offset(src_first); 1185 int dst_offset = ra_->reg2offset(dst_first); 1186 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1187 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1188 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1189 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1190 int stack_offset = ra_->reg2offset(dst_first); 1191 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1192 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1193 int stack_offset = ra_->reg2offset(src_first); 1194 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1195 } else { 1196 ShouldNotReachHere(); 1197 } 1198 return 0; 1199 } 1200 if (src_first_rc == rc_stack) { 1201 // mem -> 1202 if (dst_first_rc == rc_stack) { 1203 // mem -> mem 1204 assert(src_second != dst_first, "overlap"); 1205 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1206 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1207 // 64-bit 1208 int src_offset = ra_->reg2offset(src_first); 1209 int dst_offset = ra_->reg2offset(dst_first); 1210 if (cbuf) { 1211 MacroAssembler _masm(cbuf); 1212 __ pushq(Address(rsp, src_offset)); 1213 __ popq (Address(rsp, dst_offset)); 1214 #ifndef PRODUCT 1215 } else { 1216 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1217 "popq [rsp + #%d]", 1218 src_offset, dst_offset); 1219 #endif 1220 } 1221 } else { 1222 // 32-bit 1223 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1224 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1225 // No pushl/popl, so: 1226 int src_offset = ra_->reg2offset(src_first); 1227 int dst_offset = ra_->reg2offset(dst_first); 1228 if (cbuf) { 1229 MacroAssembler _masm(cbuf); 1230 __ movq(Address(rsp, -8), rax); 1231 __ movl(rax, Address(rsp, src_offset)); 1232 __ movl(Address(rsp, dst_offset), rax); 1233 __ movq(rax, Address(rsp, -8)); 1234 #ifndef PRODUCT 1235 } else { 1236 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1237 "movl rax, [rsp + #%d]\n\t" 1238 "movl [rsp + #%d], rax\n\t" 1239 "movq rax, [rsp - #8]", 1240 src_offset, dst_offset); 1241 #endif 1242 } 1243 } 1244 return 0; 1245 } else if (dst_first_rc == rc_int) { 1246 // mem -> gpr 1247 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1248 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1249 // 64-bit 1250 int offset = ra_->reg2offset(src_first); 1251 if (cbuf) { 1252 MacroAssembler _masm(cbuf); 1253 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1254 #ifndef PRODUCT 1255 } else { 1256 st->print("movq %s, [rsp + #%d]\t# spill", 1257 Matcher::regName[dst_first], 1258 offset); 1259 #endif 1260 } 1261 } else { 1262 // 32-bit 1263 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1264 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1265 int offset = ra_->reg2offset(src_first); 1266 if (cbuf) { 1267 MacroAssembler _masm(cbuf); 1268 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1269 #ifndef PRODUCT 1270 } else { 1271 st->print("movl %s, [rsp + #%d]\t# spill", 1272 Matcher::regName[dst_first], 1273 offset); 1274 #endif 1275 } 1276 } 1277 return 0; 1278 } else if (dst_first_rc == rc_float) { 1279 // mem-> xmm 1280 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1281 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1282 // 64-bit 1283 int offset = ra_->reg2offset(src_first); 1284 if (cbuf) { 1285 MacroAssembler _masm(cbuf); 1286 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1287 #ifndef PRODUCT 1288 } else { 1289 st->print("%s %s, [rsp + #%d]\t# spill", 1290 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1291 Matcher::regName[dst_first], 1292 offset); 1293 #endif 1294 } 1295 } else { 1296 // 32-bit 1297 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1298 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1299 int offset = ra_->reg2offset(src_first); 1300 if (cbuf) { 1301 MacroAssembler _masm(cbuf); 1302 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1303 #ifndef PRODUCT 1304 } else { 1305 st->print("movss %s, [rsp + #%d]\t# spill", 1306 Matcher::regName[dst_first], 1307 offset); 1308 #endif 1309 } 1310 } 1311 return 0; 1312 } 1313 } else if (src_first_rc == rc_int) { 1314 // gpr -> 1315 if (dst_first_rc == rc_stack) { 1316 // gpr -> mem 1317 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1318 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1319 // 64-bit 1320 int offset = ra_->reg2offset(dst_first); 1321 if (cbuf) { 1322 MacroAssembler _masm(cbuf); 1323 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1324 #ifndef PRODUCT 1325 } else { 1326 st->print("movq [rsp + #%d], %s\t# spill", 1327 offset, 1328 Matcher::regName[src_first]); 1329 #endif 1330 } 1331 } else { 1332 // 32-bit 1333 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1334 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1335 int offset = ra_->reg2offset(dst_first); 1336 if (cbuf) { 1337 MacroAssembler _masm(cbuf); 1338 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1339 #ifndef PRODUCT 1340 } else { 1341 st->print("movl [rsp + #%d], %s\t# spill", 1342 offset, 1343 Matcher::regName[src_first]); 1344 #endif 1345 } 1346 } 1347 return 0; 1348 } else if (dst_first_rc == rc_int) { 1349 // gpr -> gpr 1350 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1351 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1352 // 64-bit 1353 if (cbuf) { 1354 MacroAssembler _masm(cbuf); 1355 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1356 as_Register(Matcher::_regEncode[src_first])); 1357 #ifndef PRODUCT 1358 } else { 1359 st->print("movq %s, %s\t# spill", 1360 Matcher::regName[dst_first], 1361 Matcher::regName[src_first]); 1362 #endif 1363 } 1364 return 0; 1365 } else { 1366 // 32-bit 1367 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1368 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1369 if (cbuf) { 1370 MacroAssembler _masm(cbuf); 1371 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1372 as_Register(Matcher::_regEncode[src_first])); 1373 #ifndef PRODUCT 1374 } else { 1375 st->print("movl %s, %s\t# spill", 1376 Matcher::regName[dst_first], 1377 Matcher::regName[src_first]); 1378 #endif 1379 } 1380 return 0; 1381 } 1382 } else if (dst_first_rc == rc_float) { 1383 // gpr -> xmm 1384 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1385 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1386 // 64-bit 1387 if (cbuf) { 1388 MacroAssembler _masm(cbuf); 1389 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1390 #ifndef PRODUCT 1391 } else { 1392 st->print("movdq %s, %s\t# spill", 1393 Matcher::regName[dst_first], 1394 Matcher::regName[src_first]); 1395 #endif 1396 } 1397 } else { 1398 // 32-bit 1399 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1400 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1401 if (cbuf) { 1402 MacroAssembler _masm(cbuf); 1403 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1404 #ifndef PRODUCT 1405 } else { 1406 st->print("movdl %s, %s\t# spill", 1407 Matcher::regName[dst_first], 1408 Matcher::regName[src_first]); 1409 #endif 1410 } 1411 } 1412 return 0; 1413 } 1414 } else if (src_first_rc == rc_float) { 1415 // xmm -> 1416 if (dst_first_rc == rc_stack) { 1417 // xmm -> mem 1418 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1419 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1420 // 64-bit 1421 int offset = ra_->reg2offset(dst_first); 1422 if (cbuf) { 1423 MacroAssembler _masm(cbuf); 1424 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1425 #ifndef PRODUCT 1426 } else { 1427 st->print("movsd [rsp + #%d], %s\t# spill", 1428 offset, 1429 Matcher::regName[src_first]); 1430 #endif 1431 } 1432 } else { 1433 // 32-bit 1434 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1435 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1436 int offset = ra_->reg2offset(dst_first); 1437 if (cbuf) { 1438 MacroAssembler _masm(cbuf); 1439 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1440 #ifndef PRODUCT 1441 } else { 1442 st->print("movss [rsp + #%d], %s\t# spill", 1443 offset, 1444 Matcher::regName[src_first]); 1445 #endif 1446 } 1447 } 1448 return 0; 1449 } else if (dst_first_rc == rc_int) { 1450 // xmm -> gpr 1451 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1452 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1453 // 64-bit 1454 if (cbuf) { 1455 MacroAssembler _masm(cbuf); 1456 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1457 #ifndef PRODUCT 1458 } else { 1459 st->print("movdq %s, %s\t# spill", 1460 Matcher::regName[dst_first], 1461 Matcher::regName[src_first]); 1462 #endif 1463 } 1464 } else { 1465 // 32-bit 1466 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1467 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1468 if (cbuf) { 1469 MacroAssembler _masm(cbuf); 1470 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1471 #ifndef PRODUCT 1472 } else { 1473 st->print("movdl %s, %s\t# spill", 1474 Matcher::regName[dst_first], 1475 Matcher::regName[src_first]); 1476 #endif 1477 } 1478 } 1479 return 0; 1480 } else if (dst_first_rc == rc_float) { 1481 // xmm -> xmm 1482 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1483 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1484 // 64-bit 1485 if (cbuf) { 1486 MacroAssembler _masm(cbuf); 1487 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1488 #ifndef PRODUCT 1489 } else { 1490 st->print("%s %s, %s\t# spill", 1491 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1492 Matcher::regName[dst_first], 1493 Matcher::regName[src_first]); 1494 #endif 1495 } 1496 } else { 1497 // 32-bit 1498 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1499 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1500 if (cbuf) { 1501 MacroAssembler _masm(cbuf); 1502 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1503 #ifndef PRODUCT 1504 } else { 1505 st->print("%s %s, %s\t# spill", 1506 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1507 Matcher::regName[dst_first], 1508 Matcher::regName[src_first]); 1509 #endif 1510 } 1511 } 1512 return 0; 1513 } 1514 } 1515 1516 assert(0," foo "); 1517 Unimplemented(); 1518 return 0; 1519 } 1520 1521 #ifndef PRODUCT 1522 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1523 implementation(NULL, ra_, false, st); 1524 } 1525 #endif 1526 1527 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1528 implementation(&cbuf, ra_, false, NULL); 1529 } 1530 1531 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1532 return MachNode::size(ra_); 1533 } 1534 1535 //============================================================================= 1536 #ifndef PRODUCT 1537 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1538 { 1539 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1540 int reg = ra_->get_reg_first(this); 1541 st->print("leaq %s, [rsp + #%d]\t# box lock", 1542 Matcher::regName[reg], offset); 1543 } 1544 #endif 1545 1546 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1547 { 1548 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1549 int reg = ra_->get_encode(this); 1550 if (offset >= 0x80) { 1551 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1552 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1553 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1554 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1555 emit_d32(cbuf, offset); 1556 } else { 1557 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1558 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1559 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1560 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1561 emit_d8(cbuf, offset); 1562 } 1563 } 1564 1565 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1566 { 1567 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1568 return (offset < 0x80) ? 5 : 8; // REX 1569 } 1570 1571 //============================================================================= 1572 #ifndef PRODUCT 1573 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1574 { 1575 if (UseCompressedClassPointers) { 1576 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1577 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1578 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1579 } else { 1580 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1581 "# Inline cache check"); 1582 } 1583 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1584 st->print_cr("\tnop\t# nops to align entry point"); 1585 } 1586 #endif 1587 1588 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1589 { 1590 MacroAssembler masm(&cbuf); 1591 uint insts_size = cbuf.insts_size(); 1592 if (UseCompressedClassPointers) { 1593 masm.load_klass(rscratch1, j_rarg0); 1594 masm.cmpptr(rax, rscratch1); 1595 } else { 1596 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1597 } 1598 1599 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1600 1601 /* WARNING these NOPs are critical so that verified entry point is properly 1602 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1603 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1604 if (OptoBreakpoint) { 1605 // Leave space for int3 1606 nops_cnt -= 1; 1607 } 1608 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1609 if (nops_cnt > 0) 1610 masm.nop(nops_cnt); 1611 } 1612 1613 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1614 { 1615 return MachNode::size(ra_); // too many variables; just compute it 1616 // the hard way 1617 } 1618 1619 1620 //============================================================================= 1621 1622 int Matcher::regnum_to_fpu_offset(int regnum) 1623 { 1624 return regnum - 32; // The FP registers are in the second chunk 1625 } 1626 1627 // This is UltraSparc specific, true just means we have fast l2f conversion 1628 const bool Matcher::convL2FSupported(void) { 1629 return true; 1630 } 1631 1632 // Is this branch offset short enough that a short branch can be used? 1633 // 1634 // NOTE: If the platform does not provide any short branch variants, then 1635 // this method should return false for offset 0. 1636 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1637 // The passed offset is relative to address of the branch. 1638 // On 86 a branch displacement is calculated relative to address 1639 // of a next instruction. 1640 offset -= br_size; 1641 1642 // the short version of jmpConUCF2 contains multiple branches, 1643 // making the reach slightly less 1644 if (rule == jmpConUCF2_rule) 1645 return (-126 <= offset && offset <= 125); 1646 return (-128 <= offset && offset <= 127); 1647 } 1648 1649 const bool Matcher::isSimpleConstant64(jlong value) { 1650 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1651 //return value == (int) value; // Cf. storeImmL and immL32. 1652 1653 // Probably always true, even if a temp register is required. 1654 return true; 1655 } 1656 1657 // The ecx parameter to rep stosq for the ClearArray node is in words. 1658 const bool Matcher::init_array_count_is_in_bytes = false; 1659 1660 // No additional cost for CMOVL. 1661 const int Matcher::long_cmove_cost() { return 0; } 1662 1663 // No CMOVF/CMOVD with SSE2 1664 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1665 1666 // Does the CPU require late expand (see block.cpp for description of late expand)? 1667 const bool Matcher::require_postalloc_expand = false; 1668 1669 // Do we need to mask the count passed to shift instructions or does 1670 // the cpu only look at the lower 5/6 bits anyway? 1671 const bool Matcher::need_masked_shift_count = false; 1672 1673 bool Matcher::narrow_oop_use_complex_address() { 1674 assert(UseCompressedOops, "only for compressed oops code"); 1675 return (LogMinObjAlignmentInBytes <= 3); 1676 } 1677 1678 bool Matcher::narrow_klass_use_complex_address() { 1679 assert(UseCompressedClassPointers, "only for compressed klass code"); 1680 return (LogKlassAlignmentInBytes <= 3); 1681 } 1682 1683 bool Matcher::const_oop_prefer_decode() { 1684 // Prefer ConN+DecodeN over ConP. 1685 return true; 1686 } 1687 1688 bool Matcher::const_klass_prefer_decode() { 1689 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1690 // or condisider the following: 1691 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1692 //return Universe::narrow_klass_base() == NULL; 1693 return true; 1694 } 1695 1696 // Is it better to copy float constants, or load them directly from 1697 // memory? Intel can load a float constant from a direct address, 1698 // requiring no extra registers. Most RISCs will have to materialize 1699 // an address into a register first, so they would do better to copy 1700 // the constant from stack. 1701 const bool Matcher::rematerialize_float_constants = true; // XXX 1702 1703 // If CPU can load and store mis-aligned doubles directly then no 1704 // fixup is needed. Else we split the double into 2 integer pieces 1705 // and move it piece-by-piece. Only happens when passing doubles into 1706 // C code as the Java calling convention forces doubles to be aligned. 1707 const bool Matcher::misaligned_doubles_ok = true; 1708 1709 // No-op on amd64 1710 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1711 1712 // Advertise here if the CPU requires explicit rounding operations to 1713 // implement the UseStrictFP mode. 1714 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1715 1716 // Are floats conerted to double when stored to stack during deoptimization? 1717 // On x64 it is stored without convertion so we can use normal access. 1718 bool Matcher::float_in_double() { return false; } 1719 1720 // Do ints take an entire long register or just half? 1721 const bool Matcher::int_in_long = true; 1722 1723 // Return whether or not this register is ever used as an argument. 1724 // This function is used on startup to build the trampoline stubs in 1725 // generateOptoStub. Registers not mentioned will be killed by the VM 1726 // call in the trampoline, and arguments in those registers not be 1727 // available to the callee. 1728 bool Matcher::can_be_java_arg(int reg) 1729 { 1730 return 1731 reg == RDI_num || reg == RDI_H_num || 1732 reg == RSI_num || reg == RSI_H_num || 1733 reg == RDX_num || reg == RDX_H_num || 1734 reg == RCX_num || reg == RCX_H_num || 1735 reg == R8_num || reg == R8_H_num || 1736 reg == R9_num || reg == R9_H_num || 1737 reg == R12_num || reg == R12_H_num || 1738 reg == XMM0_num || reg == XMM0b_num || 1739 reg == XMM1_num || reg == XMM1b_num || 1740 reg == XMM2_num || reg == XMM2b_num || 1741 reg == XMM3_num || reg == XMM3b_num || 1742 reg == XMM4_num || reg == XMM4b_num || 1743 reg == XMM5_num || reg == XMM5b_num || 1744 reg == XMM6_num || reg == XMM6b_num || 1745 reg == XMM7_num || reg == XMM7b_num; 1746 } 1747 1748 bool Matcher::is_spillable_arg(int reg) 1749 { 1750 return can_be_java_arg(reg); 1751 } 1752 1753 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1754 // In 64 bit mode a code which use multiply when 1755 // devisor is constant is faster than hardware 1756 // DIV instruction (it uses MulHiL). 1757 return false; 1758 } 1759 1760 // Register for DIVI projection of divmodI 1761 RegMask Matcher::divI_proj_mask() { 1762 return INT_RAX_REG_mask(); 1763 } 1764 1765 // Register for MODI projection of divmodI 1766 RegMask Matcher::modI_proj_mask() { 1767 return INT_RDX_REG_mask(); 1768 } 1769 1770 // Register for DIVL projection of divmodL 1771 RegMask Matcher::divL_proj_mask() { 1772 return LONG_RAX_REG_mask(); 1773 } 1774 1775 // Register for MODL projection of divmodL 1776 RegMask Matcher::modL_proj_mask() { 1777 return LONG_RDX_REG_mask(); 1778 } 1779 1780 // Register for saving SP into on method handle invokes. Not used on x86_64. 1781 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1782 return NO_REG_mask(); 1783 } 1784 1785 %} 1786 1787 //----------ENCODING BLOCK----------------------------------------------------- 1788 // This block specifies the encoding classes used by the compiler to 1789 // output byte streams. Encoding classes are parameterized macros 1790 // used by Machine Instruction Nodes in order to generate the bit 1791 // encoding of the instruction. Operands specify their base encoding 1792 // interface with the interface keyword. There are currently 1793 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1794 // COND_INTER. REG_INTER causes an operand to generate a function 1795 // which returns its register number when queried. CONST_INTER causes 1796 // an operand to generate a function which returns the value of the 1797 // constant when queried. MEMORY_INTER causes an operand to generate 1798 // four functions which return the Base Register, the Index Register, 1799 // the Scale Value, and the Offset Value of the operand when queried. 1800 // COND_INTER causes an operand to generate six functions which return 1801 // the encoding code (ie - encoding bits for the instruction) 1802 // associated with each basic boolean condition for a conditional 1803 // instruction. 1804 // 1805 // Instructions specify two basic values for encoding. Again, a 1806 // function is available to check if the constant displacement is an 1807 // oop. They use the ins_encode keyword to specify their encoding 1808 // classes (which must be a sequence of enc_class names, and their 1809 // parameters, specified in the encoding block), and they use the 1810 // opcode keyword to specify, in order, their primary, secondary, and 1811 // tertiary opcode. Only the opcode sections which a particular 1812 // instruction needs for encoding need to be specified. 1813 encode %{ 1814 // Build emit functions for each basic byte or larger field in the 1815 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1816 // from C++ code in the enc_class source block. Emit functions will 1817 // live in the main source block for now. In future, we can 1818 // generalize this by adding a syntax that specifies the sizes of 1819 // fields in an order, so that the adlc can build the emit functions 1820 // automagically 1821 1822 // Emit primary opcode 1823 enc_class OpcP 1824 %{ 1825 emit_opcode(cbuf, $primary); 1826 %} 1827 1828 // Emit secondary opcode 1829 enc_class OpcS 1830 %{ 1831 emit_opcode(cbuf, $secondary); 1832 %} 1833 1834 // Emit tertiary opcode 1835 enc_class OpcT 1836 %{ 1837 emit_opcode(cbuf, $tertiary); 1838 %} 1839 1840 // Emit opcode directly 1841 enc_class Opcode(immI d8) 1842 %{ 1843 emit_opcode(cbuf, $d8$$constant); 1844 %} 1845 1846 // Emit size prefix 1847 enc_class SizePrefix 1848 %{ 1849 emit_opcode(cbuf, 0x66); 1850 %} 1851 1852 enc_class reg(rRegI reg) 1853 %{ 1854 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1855 %} 1856 1857 enc_class reg_reg(rRegI dst, rRegI src) 1858 %{ 1859 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1860 %} 1861 1862 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1863 %{ 1864 emit_opcode(cbuf, $opcode$$constant); 1865 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1866 %} 1867 1868 enc_class cdql_enc(no_rax_rdx_RegI div) 1869 %{ 1870 // Full implementation of Java idiv and irem; checks for 1871 // special case as described in JVM spec., p.243 & p.271. 1872 // 1873 // normal case special case 1874 // 1875 // input : rax: dividend min_int 1876 // reg: divisor -1 1877 // 1878 // output: rax: quotient (= rax idiv reg) min_int 1879 // rdx: remainder (= rax irem reg) 0 1880 // 1881 // Code sequnce: 1882 // 1883 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1884 // 5: 75 07/08 jne e <normal> 1885 // 7: 33 d2 xor %edx,%edx 1886 // [div >= 8 -> offset + 1] 1887 // [REX_B] 1888 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1889 // c: 74 03/04 je 11 <done> 1890 // 000000000000000e <normal>: 1891 // e: 99 cltd 1892 // [div >= 8 -> offset + 1] 1893 // [REX_B] 1894 // f: f7 f9 idiv $div 1895 // 0000000000000011 <done>: 1896 1897 // cmp $0x80000000,%eax 1898 emit_opcode(cbuf, 0x3d); 1899 emit_d8(cbuf, 0x00); 1900 emit_d8(cbuf, 0x00); 1901 emit_d8(cbuf, 0x00); 1902 emit_d8(cbuf, 0x80); 1903 1904 // jne e <normal> 1905 emit_opcode(cbuf, 0x75); 1906 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1907 1908 // xor %edx,%edx 1909 emit_opcode(cbuf, 0x33); 1910 emit_d8(cbuf, 0xD2); 1911 1912 // cmp $0xffffffffffffffff,%ecx 1913 if ($div$$reg >= 8) { 1914 emit_opcode(cbuf, Assembler::REX_B); 1915 } 1916 emit_opcode(cbuf, 0x83); 1917 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1918 emit_d8(cbuf, 0xFF); 1919 1920 // je 11 <done> 1921 emit_opcode(cbuf, 0x74); 1922 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1923 1924 // <normal> 1925 // cltd 1926 emit_opcode(cbuf, 0x99); 1927 1928 // idivl (note: must be emitted by the user of this rule) 1929 // <done> 1930 %} 1931 1932 enc_class cdqq_enc(no_rax_rdx_RegL div) 1933 %{ 1934 // Full implementation of Java ldiv and lrem; checks for 1935 // special case as described in JVM spec., p.243 & p.271. 1936 // 1937 // normal case special case 1938 // 1939 // input : rax: dividend min_long 1940 // reg: divisor -1 1941 // 1942 // output: rax: quotient (= rax idiv reg) min_long 1943 // rdx: remainder (= rax irem reg) 0 1944 // 1945 // Code sequnce: 1946 // 1947 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1948 // 7: 00 00 80 1949 // a: 48 39 d0 cmp %rdx,%rax 1950 // d: 75 08 jne 17 <normal> 1951 // f: 33 d2 xor %edx,%edx 1952 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1953 // 15: 74 05 je 1c <done> 1954 // 0000000000000017 <normal>: 1955 // 17: 48 99 cqto 1956 // 19: 48 f7 f9 idiv $div 1957 // 000000000000001c <done>: 1958 1959 // mov $0x8000000000000000,%rdx 1960 emit_opcode(cbuf, Assembler::REX_W); 1961 emit_opcode(cbuf, 0xBA); 1962 emit_d8(cbuf, 0x00); 1963 emit_d8(cbuf, 0x00); 1964 emit_d8(cbuf, 0x00); 1965 emit_d8(cbuf, 0x00); 1966 emit_d8(cbuf, 0x00); 1967 emit_d8(cbuf, 0x00); 1968 emit_d8(cbuf, 0x00); 1969 emit_d8(cbuf, 0x80); 1970 1971 // cmp %rdx,%rax 1972 emit_opcode(cbuf, Assembler::REX_W); 1973 emit_opcode(cbuf, 0x39); 1974 emit_d8(cbuf, 0xD0); 1975 1976 // jne 17 <normal> 1977 emit_opcode(cbuf, 0x75); 1978 emit_d8(cbuf, 0x08); 1979 1980 // xor %edx,%edx 1981 emit_opcode(cbuf, 0x33); 1982 emit_d8(cbuf, 0xD2); 1983 1984 // cmp $0xffffffffffffffff,$div 1985 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1986 emit_opcode(cbuf, 0x83); 1987 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1988 emit_d8(cbuf, 0xFF); 1989 1990 // je 1e <done> 1991 emit_opcode(cbuf, 0x74); 1992 emit_d8(cbuf, 0x05); 1993 1994 // <normal> 1995 // cqto 1996 emit_opcode(cbuf, Assembler::REX_W); 1997 emit_opcode(cbuf, 0x99); 1998 1999 // idivq (note: must be emitted by the user of this rule) 2000 // <done> 2001 %} 2002 2003 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2004 enc_class OpcSE(immI imm) 2005 %{ 2006 // Emit primary opcode and set sign-extend bit 2007 // Check for 8-bit immediate, and set sign extend bit in opcode 2008 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2009 emit_opcode(cbuf, $primary | 0x02); 2010 } else { 2011 // 32-bit immediate 2012 emit_opcode(cbuf, $primary); 2013 } 2014 %} 2015 2016 enc_class OpcSErm(rRegI dst, immI imm) 2017 %{ 2018 // OpcSEr/m 2019 int dstenc = $dst$$reg; 2020 if (dstenc >= 8) { 2021 emit_opcode(cbuf, Assembler::REX_B); 2022 dstenc -= 8; 2023 } 2024 // Emit primary opcode and set sign-extend bit 2025 // Check for 8-bit immediate, and set sign extend bit in opcode 2026 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2027 emit_opcode(cbuf, $primary | 0x02); 2028 } else { 2029 // 32-bit immediate 2030 emit_opcode(cbuf, $primary); 2031 } 2032 // Emit r/m byte with secondary opcode, after primary opcode. 2033 emit_rm(cbuf, 0x3, $secondary, dstenc); 2034 %} 2035 2036 enc_class OpcSErm_wide(rRegL dst, immI imm) 2037 %{ 2038 // OpcSEr/m 2039 int dstenc = $dst$$reg; 2040 if (dstenc < 8) { 2041 emit_opcode(cbuf, Assembler::REX_W); 2042 } else { 2043 emit_opcode(cbuf, Assembler::REX_WB); 2044 dstenc -= 8; 2045 } 2046 // Emit primary opcode and set sign-extend bit 2047 // Check for 8-bit immediate, and set sign extend bit in opcode 2048 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2049 emit_opcode(cbuf, $primary | 0x02); 2050 } else { 2051 // 32-bit immediate 2052 emit_opcode(cbuf, $primary); 2053 } 2054 // Emit r/m byte with secondary opcode, after primary opcode. 2055 emit_rm(cbuf, 0x3, $secondary, dstenc); 2056 %} 2057 2058 enc_class Con8or32(immI imm) 2059 %{ 2060 // Check for 8-bit immediate, and set sign extend bit in opcode 2061 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2062 $$$emit8$imm$$constant; 2063 } else { 2064 // 32-bit immediate 2065 $$$emit32$imm$$constant; 2066 } 2067 %} 2068 2069 enc_class opc2_reg(rRegI dst) 2070 %{ 2071 // BSWAP 2072 emit_cc(cbuf, $secondary, $dst$$reg); 2073 %} 2074 2075 enc_class opc3_reg(rRegI dst) 2076 %{ 2077 // BSWAP 2078 emit_cc(cbuf, $tertiary, $dst$$reg); 2079 %} 2080 2081 enc_class reg_opc(rRegI div) 2082 %{ 2083 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2084 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2085 %} 2086 2087 enc_class enc_cmov(cmpOp cop) 2088 %{ 2089 // CMOV 2090 $$$emit8$primary; 2091 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2092 %} 2093 2094 enc_class enc_PartialSubtypeCheck() 2095 %{ 2096 Register Rrdi = as_Register(RDI_enc); // result register 2097 Register Rrax = as_Register(RAX_enc); // super class 2098 Register Rrcx = as_Register(RCX_enc); // killed 2099 Register Rrsi = as_Register(RSI_enc); // sub class 2100 Label miss; 2101 const bool set_cond_codes = true; 2102 2103 MacroAssembler _masm(&cbuf); 2104 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2105 NULL, &miss, 2106 /*set_cond_codes:*/ true); 2107 if ($primary) { 2108 __ xorptr(Rrdi, Rrdi); 2109 } 2110 __ bind(miss); 2111 %} 2112 2113 enc_class clear_avx %{ 2114 debug_only(int off0 = cbuf.insts_size()); 2115 if (generate_vzeroupper(Compile::current())) { 2116 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2117 // Clear upper bits of YMM registers when current compiled code uses 2118 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2119 MacroAssembler _masm(&cbuf); 2120 __ vzeroupper(); 2121 } 2122 debug_only(int off1 = cbuf.insts_size()); 2123 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2124 %} 2125 2126 enc_class Java_To_Runtime(method meth) %{ 2127 // No relocation needed 2128 MacroAssembler _masm(&cbuf); 2129 __ mov64(r10, (int64_t) $meth$$method); 2130 __ call(r10); 2131 %} 2132 2133 enc_class Java_To_Interpreter(method meth) 2134 %{ 2135 // CALL Java_To_Interpreter 2136 // This is the instruction starting address for relocation info. 2137 cbuf.set_insts_mark(); 2138 $$$emit8$primary; 2139 // CALL directly to the runtime 2140 emit_d32_reloc(cbuf, 2141 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2142 runtime_call_Relocation::spec(), 2143 RELOC_DISP32); 2144 %} 2145 2146 enc_class Java_Static_Call(method meth) 2147 %{ 2148 // JAVA STATIC CALL 2149 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2150 // determine who we intended to call. 2151 cbuf.set_insts_mark(); 2152 $$$emit8$primary; 2153 2154 if (!_method) { 2155 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2156 runtime_call_Relocation::spec(), 2157 RELOC_DISP32); 2158 } else { 2159 int method_index = resolved_method_index(cbuf); 2160 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2161 : static_call_Relocation::spec(method_index); 2162 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2163 rspec, RELOC_DISP32); 2164 // Emit stubs for static call. 2165 address mark = cbuf.insts_mark(); 2166 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2167 if (stub == NULL) { 2168 ciEnv::current()->record_failure("CodeCache is full"); 2169 return; 2170 } 2171 #if INCLUDE_AOT 2172 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2173 #endif 2174 } 2175 %} 2176 2177 enc_class Java_Dynamic_Call(method meth) %{ 2178 MacroAssembler _masm(&cbuf); 2179 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2180 %} 2181 2182 enc_class Java_Compiled_Call(method meth) 2183 %{ 2184 // JAVA COMPILED CALL 2185 int disp = in_bytes(Method:: from_compiled_offset()); 2186 2187 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2188 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2189 2190 // callq *disp(%rax) 2191 cbuf.set_insts_mark(); 2192 $$$emit8$primary; 2193 if (disp < 0x80) { 2194 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2195 emit_d8(cbuf, disp); // Displacement 2196 } else { 2197 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2198 emit_d32(cbuf, disp); // Displacement 2199 } 2200 %} 2201 2202 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2203 %{ 2204 // SAL, SAR, SHR 2205 int dstenc = $dst$$reg; 2206 if (dstenc >= 8) { 2207 emit_opcode(cbuf, Assembler::REX_B); 2208 dstenc -= 8; 2209 } 2210 $$$emit8$primary; 2211 emit_rm(cbuf, 0x3, $secondary, dstenc); 2212 $$$emit8$shift$$constant; 2213 %} 2214 2215 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2216 %{ 2217 // SAL, SAR, SHR 2218 int dstenc = $dst$$reg; 2219 if (dstenc < 8) { 2220 emit_opcode(cbuf, Assembler::REX_W); 2221 } else { 2222 emit_opcode(cbuf, Assembler::REX_WB); 2223 dstenc -= 8; 2224 } 2225 $$$emit8$primary; 2226 emit_rm(cbuf, 0x3, $secondary, dstenc); 2227 $$$emit8$shift$$constant; 2228 %} 2229 2230 enc_class load_immI(rRegI dst, immI src) 2231 %{ 2232 int dstenc = $dst$$reg; 2233 if (dstenc >= 8) { 2234 emit_opcode(cbuf, Assembler::REX_B); 2235 dstenc -= 8; 2236 } 2237 emit_opcode(cbuf, 0xB8 | dstenc); 2238 $$$emit32$src$$constant; 2239 %} 2240 2241 enc_class load_immL(rRegL dst, immL src) 2242 %{ 2243 int dstenc = $dst$$reg; 2244 if (dstenc < 8) { 2245 emit_opcode(cbuf, Assembler::REX_W); 2246 } else { 2247 emit_opcode(cbuf, Assembler::REX_WB); 2248 dstenc -= 8; 2249 } 2250 emit_opcode(cbuf, 0xB8 | dstenc); 2251 emit_d64(cbuf, $src$$constant); 2252 %} 2253 2254 enc_class load_immUL32(rRegL dst, immUL32 src) 2255 %{ 2256 // same as load_immI, but this time we care about zeroes in the high word 2257 int dstenc = $dst$$reg; 2258 if (dstenc >= 8) { 2259 emit_opcode(cbuf, Assembler::REX_B); 2260 dstenc -= 8; 2261 } 2262 emit_opcode(cbuf, 0xB8 | dstenc); 2263 $$$emit32$src$$constant; 2264 %} 2265 2266 enc_class load_immL32(rRegL dst, immL32 src) 2267 %{ 2268 int dstenc = $dst$$reg; 2269 if (dstenc < 8) { 2270 emit_opcode(cbuf, Assembler::REX_W); 2271 } else { 2272 emit_opcode(cbuf, Assembler::REX_WB); 2273 dstenc -= 8; 2274 } 2275 emit_opcode(cbuf, 0xC7); 2276 emit_rm(cbuf, 0x03, 0x00, dstenc); 2277 $$$emit32$src$$constant; 2278 %} 2279 2280 enc_class load_immP31(rRegP dst, immP32 src) 2281 %{ 2282 // same as load_immI, but this time we care about zeroes in the high word 2283 int dstenc = $dst$$reg; 2284 if (dstenc >= 8) { 2285 emit_opcode(cbuf, Assembler::REX_B); 2286 dstenc -= 8; 2287 } 2288 emit_opcode(cbuf, 0xB8 | dstenc); 2289 $$$emit32$src$$constant; 2290 %} 2291 2292 enc_class load_immP(rRegP dst, immP src) 2293 %{ 2294 int dstenc = $dst$$reg; 2295 if (dstenc < 8) { 2296 emit_opcode(cbuf, Assembler::REX_W); 2297 } else { 2298 emit_opcode(cbuf, Assembler::REX_WB); 2299 dstenc -= 8; 2300 } 2301 emit_opcode(cbuf, 0xB8 | dstenc); 2302 // This next line should be generated from ADLC 2303 if ($src->constant_reloc() != relocInfo::none) { 2304 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2305 } else { 2306 emit_d64(cbuf, $src$$constant); 2307 } 2308 %} 2309 2310 enc_class Con32(immI src) 2311 %{ 2312 // Output immediate 2313 $$$emit32$src$$constant; 2314 %} 2315 2316 enc_class Con32F_as_bits(immF src) 2317 %{ 2318 // Output Float immediate bits 2319 jfloat jf = $src$$constant; 2320 jint jf_as_bits = jint_cast(jf); 2321 emit_d32(cbuf, jf_as_bits); 2322 %} 2323 2324 enc_class Con16(immI src) 2325 %{ 2326 // Output immediate 2327 $$$emit16$src$$constant; 2328 %} 2329 2330 // How is this different from Con32??? XXX 2331 enc_class Con_d32(immI src) 2332 %{ 2333 emit_d32(cbuf,$src$$constant); 2334 %} 2335 2336 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2337 // Output immediate memory reference 2338 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2339 emit_d32(cbuf, 0x00); 2340 %} 2341 2342 enc_class lock_prefix() 2343 %{ 2344 if (os::is_MP()) { 2345 emit_opcode(cbuf, 0xF0); // lock 2346 } 2347 %} 2348 2349 enc_class REX_mem(memory mem) 2350 %{ 2351 if ($mem$$base >= 8) { 2352 if ($mem$$index < 8) { 2353 emit_opcode(cbuf, Assembler::REX_B); 2354 } else { 2355 emit_opcode(cbuf, Assembler::REX_XB); 2356 } 2357 } else { 2358 if ($mem$$index >= 8) { 2359 emit_opcode(cbuf, Assembler::REX_X); 2360 } 2361 } 2362 %} 2363 2364 enc_class REX_mem_wide(memory mem) 2365 %{ 2366 if ($mem$$base >= 8) { 2367 if ($mem$$index < 8) { 2368 emit_opcode(cbuf, Assembler::REX_WB); 2369 } else { 2370 emit_opcode(cbuf, Assembler::REX_WXB); 2371 } 2372 } else { 2373 if ($mem$$index < 8) { 2374 emit_opcode(cbuf, Assembler::REX_W); 2375 } else { 2376 emit_opcode(cbuf, Assembler::REX_WX); 2377 } 2378 } 2379 %} 2380 2381 // for byte regs 2382 enc_class REX_breg(rRegI reg) 2383 %{ 2384 if ($reg$$reg >= 4) { 2385 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2386 } 2387 %} 2388 2389 // for byte regs 2390 enc_class REX_reg_breg(rRegI dst, rRegI src) 2391 %{ 2392 if ($dst$$reg < 8) { 2393 if ($src$$reg >= 4) { 2394 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2395 } 2396 } else { 2397 if ($src$$reg < 8) { 2398 emit_opcode(cbuf, Assembler::REX_R); 2399 } else { 2400 emit_opcode(cbuf, Assembler::REX_RB); 2401 } 2402 } 2403 %} 2404 2405 // for byte regs 2406 enc_class REX_breg_mem(rRegI reg, memory mem) 2407 %{ 2408 if ($reg$$reg < 8) { 2409 if ($mem$$base < 8) { 2410 if ($mem$$index >= 8) { 2411 emit_opcode(cbuf, Assembler::REX_X); 2412 } else if ($reg$$reg >= 4) { 2413 emit_opcode(cbuf, Assembler::REX); 2414 } 2415 } else { 2416 if ($mem$$index < 8) { 2417 emit_opcode(cbuf, Assembler::REX_B); 2418 } else { 2419 emit_opcode(cbuf, Assembler::REX_XB); 2420 } 2421 } 2422 } else { 2423 if ($mem$$base < 8) { 2424 if ($mem$$index < 8) { 2425 emit_opcode(cbuf, Assembler::REX_R); 2426 } else { 2427 emit_opcode(cbuf, Assembler::REX_RX); 2428 } 2429 } else { 2430 if ($mem$$index < 8) { 2431 emit_opcode(cbuf, Assembler::REX_RB); 2432 } else { 2433 emit_opcode(cbuf, Assembler::REX_RXB); 2434 } 2435 } 2436 } 2437 %} 2438 2439 enc_class REX_reg(rRegI reg) 2440 %{ 2441 if ($reg$$reg >= 8) { 2442 emit_opcode(cbuf, Assembler::REX_B); 2443 } 2444 %} 2445 2446 enc_class REX_reg_wide(rRegI reg) 2447 %{ 2448 if ($reg$$reg < 8) { 2449 emit_opcode(cbuf, Assembler::REX_W); 2450 } else { 2451 emit_opcode(cbuf, Assembler::REX_WB); 2452 } 2453 %} 2454 2455 enc_class REX_reg_reg(rRegI dst, rRegI src) 2456 %{ 2457 if ($dst$$reg < 8) { 2458 if ($src$$reg >= 8) { 2459 emit_opcode(cbuf, Assembler::REX_B); 2460 } 2461 } else { 2462 if ($src$$reg < 8) { 2463 emit_opcode(cbuf, Assembler::REX_R); 2464 } else { 2465 emit_opcode(cbuf, Assembler::REX_RB); 2466 } 2467 } 2468 %} 2469 2470 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2471 %{ 2472 if ($dst$$reg < 8) { 2473 if ($src$$reg < 8) { 2474 emit_opcode(cbuf, Assembler::REX_W); 2475 } else { 2476 emit_opcode(cbuf, Assembler::REX_WB); 2477 } 2478 } else { 2479 if ($src$$reg < 8) { 2480 emit_opcode(cbuf, Assembler::REX_WR); 2481 } else { 2482 emit_opcode(cbuf, Assembler::REX_WRB); 2483 } 2484 } 2485 %} 2486 2487 enc_class REX_reg_mem(rRegI reg, memory mem) 2488 %{ 2489 if ($reg$$reg < 8) { 2490 if ($mem$$base < 8) { 2491 if ($mem$$index >= 8) { 2492 emit_opcode(cbuf, Assembler::REX_X); 2493 } 2494 } else { 2495 if ($mem$$index < 8) { 2496 emit_opcode(cbuf, Assembler::REX_B); 2497 } else { 2498 emit_opcode(cbuf, Assembler::REX_XB); 2499 } 2500 } 2501 } else { 2502 if ($mem$$base < 8) { 2503 if ($mem$$index < 8) { 2504 emit_opcode(cbuf, Assembler::REX_R); 2505 } else { 2506 emit_opcode(cbuf, Assembler::REX_RX); 2507 } 2508 } else { 2509 if ($mem$$index < 8) { 2510 emit_opcode(cbuf, Assembler::REX_RB); 2511 } else { 2512 emit_opcode(cbuf, Assembler::REX_RXB); 2513 } 2514 } 2515 } 2516 %} 2517 2518 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2519 %{ 2520 if ($reg$$reg < 8) { 2521 if ($mem$$base < 8) { 2522 if ($mem$$index < 8) { 2523 emit_opcode(cbuf, Assembler::REX_W); 2524 } else { 2525 emit_opcode(cbuf, Assembler::REX_WX); 2526 } 2527 } else { 2528 if ($mem$$index < 8) { 2529 emit_opcode(cbuf, Assembler::REX_WB); 2530 } else { 2531 emit_opcode(cbuf, Assembler::REX_WXB); 2532 } 2533 } 2534 } else { 2535 if ($mem$$base < 8) { 2536 if ($mem$$index < 8) { 2537 emit_opcode(cbuf, Assembler::REX_WR); 2538 } else { 2539 emit_opcode(cbuf, Assembler::REX_WRX); 2540 } 2541 } else { 2542 if ($mem$$index < 8) { 2543 emit_opcode(cbuf, Assembler::REX_WRB); 2544 } else { 2545 emit_opcode(cbuf, Assembler::REX_WRXB); 2546 } 2547 } 2548 } 2549 %} 2550 2551 enc_class reg_mem(rRegI ereg, memory mem) 2552 %{ 2553 // High registers handle in encode_RegMem 2554 int reg = $ereg$$reg; 2555 int base = $mem$$base; 2556 int index = $mem$$index; 2557 int scale = $mem$$scale; 2558 int disp = $mem$$disp; 2559 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2560 2561 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2562 %} 2563 2564 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2565 %{ 2566 int rm_byte_opcode = $rm_opcode$$constant; 2567 2568 // High registers handle in encode_RegMem 2569 int base = $mem$$base; 2570 int index = $mem$$index; 2571 int scale = $mem$$scale; 2572 int displace = $mem$$disp; 2573 2574 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2575 // working with static 2576 // globals 2577 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2578 disp_reloc); 2579 %} 2580 2581 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2582 %{ 2583 int reg_encoding = $dst$$reg; 2584 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2585 int index = 0x04; // 0x04 indicates no index 2586 int scale = 0x00; // 0x00 indicates no scale 2587 int displace = $src1$$constant; // 0x00 indicates no displacement 2588 relocInfo::relocType disp_reloc = relocInfo::none; 2589 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2590 disp_reloc); 2591 %} 2592 2593 enc_class neg_reg(rRegI dst) 2594 %{ 2595 int dstenc = $dst$$reg; 2596 if (dstenc >= 8) { 2597 emit_opcode(cbuf, Assembler::REX_B); 2598 dstenc -= 8; 2599 } 2600 // NEG $dst 2601 emit_opcode(cbuf, 0xF7); 2602 emit_rm(cbuf, 0x3, 0x03, dstenc); 2603 %} 2604 2605 enc_class neg_reg_wide(rRegI dst) 2606 %{ 2607 int dstenc = $dst$$reg; 2608 if (dstenc < 8) { 2609 emit_opcode(cbuf, Assembler::REX_W); 2610 } else { 2611 emit_opcode(cbuf, Assembler::REX_WB); 2612 dstenc -= 8; 2613 } 2614 // NEG $dst 2615 emit_opcode(cbuf, 0xF7); 2616 emit_rm(cbuf, 0x3, 0x03, dstenc); 2617 %} 2618 2619 enc_class setLT_reg(rRegI dst) 2620 %{ 2621 int dstenc = $dst$$reg; 2622 if (dstenc >= 8) { 2623 emit_opcode(cbuf, Assembler::REX_B); 2624 dstenc -= 8; 2625 } else if (dstenc >= 4) { 2626 emit_opcode(cbuf, Assembler::REX); 2627 } 2628 // SETLT $dst 2629 emit_opcode(cbuf, 0x0F); 2630 emit_opcode(cbuf, 0x9C); 2631 emit_rm(cbuf, 0x3, 0x0, dstenc); 2632 %} 2633 2634 enc_class setNZ_reg(rRegI dst) 2635 %{ 2636 int dstenc = $dst$$reg; 2637 if (dstenc >= 8) { 2638 emit_opcode(cbuf, Assembler::REX_B); 2639 dstenc -= 8; 2640 } else if (dstenc >= 4) { 2641 emit_opcode(cbuf, Assembler::REX); 2642 } 2643 // SETNZ $dst 2644 emit_opcode(cbuf, 0x0F); 2645 emit_opcode(cbuf, 0x95); 2646 emit_rm(cbuf, 0x3, 0x0, dstenc); 2647 %} 2648 2649 2650 // Compare the lonogs and set -1, 0, or 1 into dst 2651 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2652 %{ 2653 int src1enc = $src1$$reg; 2654 int src2enc = $src2$$reg; 2655 int dstenc = $dst$$reg; 2656 2657 // cmpq $src1, $src2 2658 if (src1enc < 8) { 2659 if (src2enc < 8) { 2660 emit_opcode(cbuf, Assembler::REX_W); 2661 } else { 2662 emit_opcode(cbuf, Assembler::REX_WB); 2663 } 2664 } else { 2665 if (src2enc < 8) { 2666 emit_opcode(cbuf, Assembler::REX_WR); 2667 } else { 2668 emit_opcode(cbuf, Assembler::REX_WRB); 2669 } 2670 } 2671 emit_opcode(cbuf, 0x3B); 2672 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2673 2674 // movl $dst, -1 2675 if (dstenc >= 8) { 2676 emit_opcode(cbuf, Assembler::REX_B); 2677 } 2678 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2679 emit_d32(cbuf, -1); 2680 2681 // jl,s done 2682 emit_opcode(cbuf, 0x7C); 2683 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2684 2685 // setne $dst 2686 if (dstenc >= 4) { 2687 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2688 } 2689 emit_opcode(cbuf, 0x0F); 2690 emit_opcode(cbuf, 0x95); 2691 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2692 2693 // movzbl $dst, $dst 2694 if (dstenc >= 4) { 2695 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2696 } 2697 emit_opcode(cbuf, 0x0F); 2698 emit_opcode(cbuf, 0xB6); 2699 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2700 %} 2701 2702 enc_class Push_ResultXD(regD dst) %{ 2703 MacroAssembler _masm(&cbuf); 2704 __ fstp_d(Address(rsp, 0)); 2705 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2706 __ addptr(rsp, 8); 2707 %} 2708 2709 enc_class Push_SrcXD(regD src) %{ 2710 MacroAssembler _masm(&cbuf); 2711 __ subptr(rsp, 8); 2712 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2713 __ fld_d(Address(rsp, 0)); 2714 %} 2715 2716 2717 enc_class enc_rethrow() 2718 %{ 2719 cbuf.set_insts_mark(); 2720 emit_opcode(cbuf, 0xE9); // jmp entry 2721 emit_d32_reloc(cbuf, 2722 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2723 runtime_call_Relocation::spec(), 2724 RELOC_DISP32); 2725 %} 2726 2727 %} 2728 2729 2730 2731 //----------FRAME-------------------------------------------------------------- 2732 // Definition of frame structure and management information. 2733 // 2734 // S T A C K L A Y O U T Allocators stack-slot number 2735 // | (to get allocators register number 2736 // G Owned by | | v add OptoReg::stack0()) 2737 // r CALLER | | 2738 // o | +--------+ pad to even-align allocators stack-slot 2739 // w V | pad0 | numbers; owned by CALLER 2740 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2741 // h ^ | in | 5 2742 // | | args | 4 Holes in incoming args owned by SELF 2743 // | | | | 3 2744 // | | +--------+ 2745 // V | | old out| Empty on Intel, window on Sparc 2746 // | old |preserve| Must be even aligned. 2747 // | SP-+--------+----> Matcher::_old_SP, even aligned 2748 // | | in | 3 area for Intel ret address 2749 // Owned by |preserve| Empty on Sparc. 2750 // SELF +--------+ 2751 // | | pad2 | 2 pad to align old SP 2752 // | +--------+ 1 2753 // | | locks | 0 2754 // | +--------+----> OptoReg::stack0(), even aligned 2755 // | | pad1 | 11 pad to align new SP 2756 // | +--------+ 2757 // | | | 10 2758 // | | spills | 9 spills 2759 // V | | 8 (pad0 slot for callee) 2760 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2761 // ^ | out | 7 2762 // | | args | 6 Holes in outgoing args owned by CALLEE 2763 // Owned by +--------+ 2764 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2765 // | new |preserve| Must be even-aligned. 2766 // | SP-+--------+----> Matcher::_new_SP, even aligned 2767 // | | | 2768 // 2769 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2770 // known from SELF's arguments and the Java calling convention. 2771 // Region 6-7 is determined per call site. 2772 // Note 2: If the calling convention leaves holes in the incoming argument 2773 // area, those holes are owned by SELF. Holes in the outgoing area 2774 // are owned by the CALLEE. Holes should not be nessecary in the 2775 // incoming area, as the Java calling convention is completely under 2776 // the control of the AD file. Doubles can be sorted and packed to 2777 // avoid holes. Holes in the outgoing arguments may be nessecary for 2778 // varargs C calling conventions. 2779 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2780 // even aligned with pad0 as needed. 2781 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2782 // region 6-11 is even aligned; it may be padded out more so that 2783 // the region from SP to FP meets the minimum stack alignment. 2784 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2785 // alignment. Region 11, pad1, may be dynamically extended so that 2786 // SP meets the minimum alignment. 2787 2788 frame 2789 %{ 2790 // What direction does stack grow in (assumed to be same for C & Java) 2791 stack_direction(TOWARDS_LOW); 2792 2793 // These three registers define part of the calling convention 2794 // between compiled code and the interpreter. 2795 inline_cache_reg(RAX); // Inline Cache Register 2796 interpreter_method_oop_reg(RBX); // Method Oop Register when 2797 // calling interpreter 2798 2799 // Optional: name the operand used by cisc-spilling to access 2800 // [stack_pointer + offset] 2801 cisc_spilling_operand_name(indOffset32); 2802 2803 // Number of stack slots consumed by locking an object 2804 sync_stack_slots(2); 2805 2806 // Compiled code's Frame Pointer 2807 frame_pointer(RSP); 2808 2809 // Interpreter stores its frame pointer in a register which is 2810 // stored to the stack by I2CAdaptors. 2811 // I2CAdaptors convert from interpreted java to compiled java. 2812 interpreter_frame_pointer(RBP); 2813 2814 // Stack alignment requirement 2815 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2816 2817 // Number of stack slots between incoming argument block and the start of 2818 // a new frame. The PROLOG must add this many slots to the stack. The 2819 // EPILOG must remove this many slots. amd64 needs two slots for 2820 // return address. 2821 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2822 2823 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2824 // for calls to C. Supports the var-args backing area for register parms. 2825 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2826 2827 // The after-PROLOG location of the return address. Location of 2828 // return address specifies a type (REG or STACK) and a number 2829 // representing the register number (i.e. - use a register name) or 2830 // stack slot. 2831 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2832 // Otherwise, it is above the locks and verification slot and alignment word 2833 return_addr(STACK - 2 + 2834 align_up((Compile::current()->in_preserve_stack_slots() + 2835 Compile::current()->fixed_slots()), 2836 stack_alignment_in_slots())); 2837 2838 // Body of function which returns an integer array locating 2839 // arguments either in registers or in stack slots. Passed an array 2840 // of ideal registers called "sig" and a "length" count. Stack-slot 2841 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2842 // arguments for a CALLEE. Incoming stack arguments are 2843 // automatically biased by the preserve_stack_slots field above. 2844 2845 calling_convention 2846 %{ 2847 // No difference between ingoing/outgoing just pass false 2848 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2849 %} 2850 2851 c_calling_convention 2852 %{ 2853 // This is obviously always outgoing 2854 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2855 %} 2856 2857 // Location of compiled Java return values. Same as C for now. 2858 return_value 2859 %{ 2860 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2861 "only return normal values"); 2862 2863 static const int lo[Op_RegL + 1] = { 2864 0, 2865 0, 2866 RAX_num, // Op_RegN 2867 RAX_num, // Op_RegI 2868 RAX_num, // Op_RegP 2869 XMM0_num, // Op_RegF 2870 XMM0_num, // Op_RegD 2871 RAX_num // Op_RegL 2872 }; 2873 static const int hi[Op_RegL + 1] = { 2874 0, 2875 0, 2876 OptoReg::Bad, // Op_RegN 2877 OptoReg::Bad, // Op_RegI 2878 RAX_H_num, // Op_RegP 2879 OptoReg::Bad, // Op_RegF 2880 XMM0b_num, // Op_RegD 2881 RAX_H_num // Op_RegL 2882 }; 2883 // Excluded flags and vector registers. 2884 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2885 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2886 %} 2887 %} 2888 2889 //----------ATTRIBUTES--------------------------------------------------------- 2890 //----------Operand Attributes------------------------------------------------- 2891 op_attrib op_cost(0); // Required cost attribute 2892 2893 //----------Instruction Attributes--------------------------------------------- 2894 ins_attrib ins_cost(100); // Required cost attribute 2895 ins_attrib ins_size(8); // Required size attribute (in bits) 2896 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2897 // a non-matching short branch variant 2898 // of some long branch? 2899 ins_attrib ins_alignment(1); // Required alignment attribute (must 2900 // be a power of 2) specifies the 2901 // alignment that some part of the 2902 // instruction (not necessarily the 2903 // start) requires. If > 1, a 2904 // compute_padding() function must be 2905 // provided for the instruction 2906 2907 //----------OPERANDS----------------------------------------------------------- 2908 // Operand definitions must precede instruction definitions for correct parsing 2909 // in the ADLC because operands constitute user defined types which are used in 2910 // instruction definitions. 2911 2912 //----------Simple Operands---------------------------------------------------- 2913 // Immediate Operands 2914 // Integer Immediate 2915 operand immI() 2916 %{ 2917 match(ConI); 2918 2919 op_cost(10); 2920 format %{ %} 2921 interface(CONST_INTER); 2922 %} 2923 2924 // Constant for test vs zero 2925 operand immI0() 2926 %{ 2927 predicate(n->get_int() == 0); 2928 match(ConI); 2929 2930 op_cost(0); 2931 format %{ %} 2932 interface(CONST_INTER); 2933 %} 2934 2935 // Constant for increment 2936 operand immI1() 2937 %{ 2938 predicate(n->get_int() == 1); 2939 match(ConI); 2940 2941 op_cost(0); 2942 format %{ %} 2943 interface(CONST_INTER); 2944 %} 2945 2946 // Constant for decrement 2947 operand immI_M1() 2948 %{ 2949 predicate(n->get_int() == -1); 2950 match(ConI); 2951 2952 op_cost(0); 2953 format %{ %} 2954 interface(CONST_INTER); 2955 %} 2956 2957 // Valid scale values for addressing modes 2958 operand immI2() 2959 %{ 2960 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2961 match(ConI); 2962 2963 format %{ %} 2964 interface(CONST_INTER); 2965 %} 2966 2967 operand immI8() 2968 %{ 2969 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2970 match(ConI); 2971 2972 op_cost(5); 2973 format %{ %} 2974 interface(CONST_INTER); 2975 %} 2976 2977 operand immU8() 2978 %{ 2979 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2980 match(ConI); 2981 2982 op_cost(5); 2983 format %{ %} 2984 interface(CONST_INTER); 2985 %} 2986 2987 operand immI16() 2988 %{ 2989 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2990 match(ConI); 2991 2992 op_cost(10); 2993 format %{ %} 2994 interface(CONST_INTER); 2995 %} 2996 2997 // Int Immediate non-negative 2998 operand immU31() 2999 %{ 3000 predicate(n->get_int() >= 0); 3001 match(ConI); 3002 3003 op_cost(0); 3004 format %{ %} 3005 interface(CONST_INTER); 3006 %} 3007 3008 // Constant for long shifts 3009 operand immI_32() 3010 %{ 3011 predicate( n->get_int() == 32 ); 3012 match(ConI); 3013 3014 op_cost(0); 3015 format %{ %} 3016 interface(CONST_INTER); 3017 %} 3018 3019 // Constant for long shifts 3020 operand immI_64() 3021 %{ 3022 predicate( n->get_int() == 64 ); 3023 match(ConI); 3024 3025 op_cost(0); 3026 format %{ %} 3027 interface(CONST_INTER); 3028 %} 3029 3030 // Pointer Immediate 3031 operand immP() 3032 %{ 3033 match(ConP); 3034 3035 op_cost(10); 3036 format %{ %} 3037 interface(CONST_INTER); 3038 %} 3039 3040 // NULL Pointer Immediate 3041 operand immP0() 3042 %{ 3043 predicate(n->get_ptr() == 0); 3044 match(ConP); 3045 3046 op_cost(5); 3047 format %{ %} 3048 interface(CONST_INTER); 3049 %} 3050 3051 // Pointer Immediate 3052 operand immN() %{ 3053 match(ConN); 3054 3055 op_cost(10); 3056 format %{ %} 3057 interface(CONST_INTER); 3058 %} 3059 3060 operand immNKlass() %{ 3061 match(ConNKlass); 3062 3063 op_cost(10); 3064 format %{ %} 3065 interface(CONST_INTER); 3066 %} 3067 3068 // NULL Pointer Immediate 3069 operand immN0() %{ 3070 predicate(n->get_narrowcon() == 0); 3071 match(ConN); 3072 3073 op_cost(5); 3074 format %{ %} 3075 interface(CONST_INTER); 3076 %} 3077 3078 operand immP31() 3079 %{ 3080 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3081 && (n->get_ptr() >> 31) == 0); 3082 match(ConP); 3083 3084 op_cost(5); 3085 format %{ %} 3086 interface(CONST_INTER); 3087 %} 3088 3089 3090 // Long Immediate 3091 operand immL() 3092 %{ 3093 match(ConL); 3094 3095 op_cost(20); 3096 format %{ %} 3097 interface(CONST_INTER); 3098 %} 3099 3100 // Long Immediate 8-bit 3101 operand immL8() 3102 %{ 3103 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3104 match(ConL); 3105 3106 op_cost(5); 3107 format %{ %} 3108 interface(CONST_INTER); 3109 %} 3110 3111 // Long Immediate 32-bit unsigned 3112 operand immUL32() 3113 %{ 3114 predicate(n->get_long() == (unsigned int) (n->get_long())); 3115 match(ConL); 3116 3117 op_cost(10); 3118 format %{ %} 3119 interface(CONST_INTER); 3120 %} 3121 3122 // Long Immediate 32-bit signed 3123 operand immL32() 3124 %{ 3125 predicate(n->get_long() == (int) (n->get_long())); 3126 match(ConL); 3127 3128 op_cost(15); 3129 format %{ %} 3130 interface(CONST_INTER); 3131 %} 3132 3133 // Long Immediate zero 3134 operand immL0() 3135 %{ 3136 predicate(n->get_long() == 0L); 3137 match(ConL); 3138 3139 op_cost(10); 3140 format %{ %} 3141 interface(CONST_INTER); 3142 %} 3143 3144 // Constant for increment 3145 operand immL1() 3146 %{ 3147 predicate(n->get_long() == 1); 3148 match(ConL); 3149 3150 format %{ %} 3151 interface(CONST_INTER); 3152 %} 3153 3154 // Constant for decrement 3155 operand immL_M1() 3156 %{ 3157 predicate(n->get_long() == -1); 3158 match(ConL); 3159 3160 format %{ %} 3161 interface(CONST_INTER); 3162 %} 3163 3164 // Long Immediate: the value 10 3165 operand immL10() 3166 %{ 3167 predicate(n->get_long() == 10); 3168 match(ConL); 3169 3170 format %{ %} 3171 interface(CONST_INTER); 3172 %} 3173 3174 // Long immediate from 0 to 127. 3175 // Used for a shorter form of long mul by 10. 3176 operand immL_127() 3177 %{ 3178 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3179 match(ConL); 3180 3181 op_cost(10); 3182 format %{ %} 3183 interface(CONST_INTER); 3184 %} 3185 3186 // Long Immediate: low 32-bit mask 3187 operand immL_32bits() 3188 %{ 3189 predicate(n->get_long() == 0xFFFFFFFFL); 3190 match(ConL); 3191 op_cost(20); 3192 3193 format %{ %} 3194 interface(CONST_INTER); 3195 %} 3196 3197 // Float Immediate zero 3198 operand immF0() 3199 %{ 3200 predicate(jint_cast(n->getf()) == 0); 3201 match(ConF); 3202 3203 op_cost(5); 3204 format %{ %} 3205 interface(CONST_INTER); 3206 %} 3207 3208 // Float Immediate 3209 operand immF() 3210 %{ 3211 match(ConF); 3212 3213 op_cost(15); 3214 format %{ %} 3215 interface(CONST_INTER); 3216 %} 3217 3218 // Double Immediate zero 3219 operand immD0() 3220 %{ 3221 predicate(jlong_cast(n->getd()) == 0); 3222 match(ConD); 3223 3224 op_cost(5); 3225 format %{ %} 3226 interface(CONST_INTER); 3227 %} 3228 3229 // Double Immediate 3230 operand immD() 3231 %{ 3232 match(ConD); 3233 3234 op_cost(15); 3235 format %{ %} 3236 interface(CONST_INTER); 3237 %} 3238 3239 // Immediates for special shifts (sign extend) 3240 3241 // Constants for increment 3242 operand immI_16() 3243 %{ 3244 predicate(n->get_int() == 16); 3245 match(ConI); 3246 3247 format %{ %} 3248 interface(CONST_INTER); 3249 %} 3250 3251 operand immI_24() 3252 %{ 3253 predicate(n->get_int() == 24); 3254 match(ConI); 3255 3256 format %{ %} 3257 interface(CONST_INTER); 3258 %} 3259 3260 // Constant for byte-wide masking 3261 operand immI_255() 3262 %{ 3263 predicate(n->get_int() == 255); 3264 match(ConI); 3265 3266 format %{ %} 3267 interface(CONST_INTER); 3268 %} 3269 3270 // Constant for short-wide masking 3271 operand immI_65535() 3272 %{ 3273 predicate(n->get_int() == 65535); 3274 match(ConI); 3275 3276 format %{ %} 3277 interface(CONST_INTER); 3278 %} 3279 3280 // Constant for byte-wide masking 3281 operand immL_255() 3282 %{ 3283 predicate(n->get_long() == 255); 3284 match(ConL); 3285 3286 format %{ %} 3287 interface(CONST_INTER); 3288 %} 3289 3290 // Constant for short-wide masking 3291 operand immL_65535() 3292 %{ 3293 predicate(n->get_long() == 65535); 3294 match(ConL); 3295 3296 format %{ %} 3297 interface(CONST_INTER); 3298 %} 3299 3300 // Register Operands 3301 // Integer Register 3302 operand rRegI() 3303 %{ 3304 constraint(ALLOC_IN_RC(int_reg)); 3305 match(RegI); 3306 3307 match(rax_RegI); 3308 match(rbx_RegI); 3309 match(rcx_RegI); 3310 match(rdx_RegI); 3311 match(rdi_RegI); 3312 3313 format %{ %} 3314 interface(REG_INTER); 3315 %} 3316 3317 // Special Registers 3318 operand rax_RegI() 3319 %{ 3320 constraint(ALLOC_IN_RC(int_rax_reg)); 3321 match(RegI); 3322 match(rRegI); 3323 3324 format %{ "RAX" %} 3325 interface(REG_INTER); 3326 %} 3327 3328 // Special Registers 3329 operand rbx_RegI() 3330 %{ 3331 constraint(ALLOC_IN_RC(int_rbx_reg)); 3332 match(RegI); 3333 match(rRegI); 3334 3335 format %{ "RBX" %} 3336 interface(REG_INTER); 3337 %} 3338 3339 operand rcx_RegI() 3340 %{ 3341 constraint(ALLOC_IN_RC(int_rcx_reg)); 3342 match(RegI); 3343 match(rRegI); 3344 3345 format %{ "RCX" %} 3346 interface(REG_INTER); 3347 %} 3348 3349 operand rdx_RegI() 3350 %{ 3351 constraint(ALLOC_IN_RC(int_rdx_reg)); 3352 match(RegI); 3353 match(rRegI); 3354 3355 format %{ "RDX" %} 3356 interface(REG_INTER); 3357 %} 3358 3359 operand rdi_RegI() 3360 %{ 3361 constraint(ALLOC_IN_RC(int_rdi_reg)); 3362 match(RegI); 3363 match(rRegI); 3364 3365 format %{ "RDI" %} 3366 interface(REG_INTER); 3367 %} 3368 3369 operand no_rcx_RegI() 3370 %{ 3371 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3372 match(RegI); 3373 match(rax_RegI); 3374 match(rbx_RegI); 3375 match(rdx_RegI); 3376 match(rdi_RegI); 3377 3378 format %{ %} 3379 interface(REG_INTER); 3380 %} 3381 3382 operand no_rax_rdx_RegI() 3383 %{ 3384 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3385 match(RegI); 3386 match(rbx_RegI); 3387 match(rcx_RegI); 3388 match(rdi_RegI); 3389 3390 format %{ %} 3391 interface(REG_INTER); 3392 %} 3393 3394 // Pointer Register 3395 operand any_RegP() 3396 %{ 3397 constraint(ALLOC_IN_RC(any_reg)); 3398 match(RegP); 3399 match(rax_RegP); 3400 match(rbx_RegP); 3401 match(rdi_RegP); 3402 match(rsi_RegP); 3403 match(rbp_RegP); 3404 match(r15_RegP); 3405 match(rRegP); 3406 3407 format %{ %} 3408 interface(REG_INTER); 3409 %} 3410 3411 operand rRegP() 3412 %{ 3413 constraint(ALLOC_IN_RC(ptr_reg)); 3414 match(RegP); 3415 match(rax_RegP); 3416 match(rbx_RegP); 3417 match(rdi_RegP); 3418 match(rsi_RegP); 3419 match(rbp_RegP); // See Q&A below about 3420 match(r15_RegP); // r15_RegP and rbp_RegP. 3421 3422 format %{ %} 3423 interface(REG_INTER); 3424 %} 3425 3426 operand rRegN() %{ 3427 constraint(ALLOC_IN_RC(int_reg)); 3428 match(RegN); 3429 3430 format %{ %} 3431 interface(REG_INTER); 3432 %} 3433 3434 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3435 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3436 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3437 // The output of an instruction is controlled by the allocator, which respects 3438 // register class masks, not match rules. Unless an instruction mentions 3439 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3440 // by the allocator as an input. 3441 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3442 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3443 // result, RBP is not included in the output of the instruction either. 3444 3445 operand no_rax_RegP() 3446 %{ 3447 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3448 match(RegP); 3449 match(rbx_RegP); 3450 match(rsi_RegP); 3451 match(rdi_RegP); 3452 3453 format %{ %} 3454 interface(REG_INTER); 3455 %} 3456 3457 // This operand is not allowed to use RBP even if 3458 // RBP is not used to hold the frame pointer. 3459 operand no_rbp_RegP() 3460 %{ 3461 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3462 match(RegP); 3463 match(rbx_RegP); 3464 match(rsi_RegP); 3465 match(rdi_RegP); 3466 3467 format %{ %} 3468 interface(REG_INTER); 3469 %} 3470 3471 operand no_rax_rbx_RegP() 3472 %{ 3473 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3474 match(RegP); 3475 match(rsi_RegP); 3476 match(rdi_RegP); 3477 3478 format %{ %} 3479 interface(REG_INTER); 3480 %} 3481 3482 // Special Registers 3483 // Return a pointer value 3484 operand rax_RegP() 3485 %{ 3486 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3487 match(RegP); 3488 match(rRegP); 3489 3490 format %{ %} 3491 interface(REG_INTER); 3492 %} 3493 3494 // Special Registers 3495 // Return a compressed pointer value 3496 operand rax_RegN() 3497 %{ 3498 constraint(ALLOC_IN_RC(int_rax_reg)); 3499 match(RegN); 3500 match(rRegN); 3501 3502 format %{ %} 3503 interface(REG_INTER); 3504 %} 3505 3506 // Used in AtomicAdd 3507 operand rbx_RegP() 3508 %{ 3509 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3510 match(RegP); 3511 match(rRegP); 3512 3513 format %{ %} 3514 interface(REG_INTER); 3515 %} 3516 3517 operand rsi_RegP() 3518 %{ 3519 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3520 match(RegP); 3521 match(rRegP); 3522 3523 format %{ %} 3524 interface(REG_INTER); 3525 %} 3526 3527 // Used in rep stosq 3528 operand rdi_RegP() 3529 %{ 3530 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3531 match(RegP); 3532 match(rRegP); 3533 3534 format %{ %} 3535 interface(REG_INTER); 3536 %} 3537 3538 operand r15_RegP() 3539 %{ 3540 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3541 match(RegP); 3542 match(rRegP); 3543 3544 format %{ %} 3545 interface(REG_INTER); 3546 %} 3547 3548 operand rRegL() 3549 %{ 3550 constraint(ALLOC_IN_RC(long_reg)); 3551 match(RegL); 3552 match(rax_RegL); 3553 match(rdx_RegL); 3554 3555 format %{ %} 3556 interface(REG_INTER); 3557 %} 3558 3559 // Special Registers 3560 operand no_rax_rdx_RegL() 3561 %{ 3562 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3563 match(RegL); 3564 match(rRegL); 3565 3566 format %{ %} 3567 interface(REG_INTER); 3568 %} 3569 3570 operand no_rax_RegL() 3571 %{ 3572 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3573 match(RegL); 3574 match(rRegL); 3575 match(rdx_RegL); 3576 3577 format %{ %} 3578 interface(REG_INTER); 3579 %} 3580 3581 operand no_rcx_RegL() 3582 %{ 3583 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3584 match(RegL); 3585 match(rRegL); 3586 3587 format %{ %} 3588 interface(REG_INTER); 3589 %} 3590 3591 operand rax_RegL() 3592 %{ 3593 constraint(ALLOC_IN_RC(long_rax_reg)); 3594 match(RegL); 3595 match(rRegL); 3596 3597 format %{ "RAX" %} 3598 interface(REG_INTER); 3599 %} 3600 3601 operand rcx_RegL() 3602 %{ 3603 constraint(ALLOC_IN_RC(long_rcx_reg)); 3604 match(RegL); 3605 match(rRegL); 3606 3607 format %{ %} 3608 interface(REG_INTER); 3609 %} 3610 3611 operand rdx_RegL() 3612 %{ 3613 constraint(ALLOC_IN_RC(long_rdx_reg)); 3614 match(RegL); 3615 match(rRegL); 3616 3617 format %{ %} 3618 interface(REG_INTER); 3619 %} 3620 3621 // Flags register, used as output of compare instructions 3622 operand rFlagsReg() 3623 %{ 3624 constraint(ALLOC_IN_RC(int_flags)); 3625 match(RegFlags); 3626 3627 format %{ "RFLAGS" %} 3628 interface(REG_INTER); 3629 %} 3630 3631 // Flags register, used as output of FLOATING POINT compare instructions 3632 operand rFlagsRegU() 3633 %{ 3634 constraint(ALLOC_IN_RC(int_flags)); 3635 match(RegFlags); 3636 3637 format %{ "RFLAGS_U" %} 3638 interface(REG_INTER); 3639 %} 3640 3641 operand rFlagsRegUCF() %{ 3642 constraint(ALLOC_IN_RC(int_flags)); 3643 match(RegFlags); 3644 predicate(false); 3645 3646 format %{ "RFLAGS_U_CF" %} 3647 interface(REG_INTER); 3648 %} 3649 3650 // Float register operands 3651 operand regF() %{ 3652 constraint(ALLOC_IN_RC(float_reg)); 3653 match(RegF); 3654 3655 format %{ %} 3656 interface(REG_INTER); 3657 %} 3658 3659 // Double register operands 3660 operand regD() %{ 3661 constraint(ALLOC_IN_RC(double_reg)); 3662 match(RegD); 3663 3664 format %{ %} 3665 interface(REG_INTER); 3666 %} 3667 3668 // Vectors 3669 operand vecS() %{ 3670 constraint(ALLOC_IN_RC(vectors_reg)); 3671 match(VecS); 3672 3673 format %{ %} 3674 interface(REG_INTER); 3675 %} 3676 3677 operand vecD() %{ 3678 constraint(ALLOC_IN_RC(vectord_reg)); 3679 match(VecD); 3680 3681 format %{ %} 3682 interface(REG_INTER); 3683 %} 3684 3685 operand vecX() %{ 3686 constraint(ALLOC_IN_RC(vectorx_reg)); 3687 match(VecX); 3688 3689 format %{ %} 3690 interface(REG_INTER); 3691 %} 3692 3693 operand vecY() %{ 3694 constraint(ALLOC_IN_RC(vectory_reg)); 3695 match(VecY); 3696 3697 format %{ %} 3698 interface(REG_INTER); 3699 %} 3700 3701 //----------Memory Operands---------------------------------------------------- 3702 // Direct Memory Operand 3703 // operand direct(immP addr) 3704 // %{ 3705 // match(addr); 3706 3707 // format %{ "[$addr]" %} 3708 // interface(MEMORY_INTER) %{ 3709 // base(0xFFFFFFFF); 3710 // index(0x4); 3711 // scale(0x0); 3712 // disp($addr); 3713 // %} 3714 // %} 3715 3716 // Indirect Memory Operand 3717 operand indirect(any_RegP reg) 3718 %{ 3719 constraint(ALLOC_IN_RC(ptr_reg)); 3720 match(reg); 3721 3722 format %{ "[$reg]" %} 3723 interface(MEMORY_INTER) %{ 3724 base($reg); 3725 index(0x4); 3726 scale(0x0); 3727 disp(0x0); 3728 %} 3729 %} 3730 3731 // Indirect Memory Plus Short Offset Operand 3732 operand indOffset8(any_RegP reg, immL8 off) 3733 %{ 3734 constraint(ALLOC_IN_RC(ptr_reg)); 3735 match(AddP reg off); 3736 3737 format %{ "[$reg + $off (8-bit)]" %} 3738 interface(MEMORY_INTER) %{ 3739 base($reg); 3740 index(0x4); 3741 scale(0x0); 3742 disp($off); 3743 %} 3744 %} 3745 3746 // Indirect Memory Plus Long Offset Operand 3747 operand indOffset32(any_RegP reg, immL32 off) 3748 %{ 3749 constraint(ALLOC_IN_RC(ptr_reg)); 3750 match(AddP reg off); 3751 3752 format %{ "[$reg + $off (32-bit)]" %} 3753 interface(MEMORY_INTER) %{ 3754 base($reg); 3755 index(0x4); 3756 scale(0x0); 3757 disp($off); 3758 %} 3759 %} 3760 3761 // Indirect Memory Plus Index Register Plus Offset Operand 3762 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3763 %{ 3764 constraint(ALLOC_IN_RC(ptr_reg)); 3765 match(AddP (AddP reg lreg) off); 3766 3767 op_cost(10); 3768 format %{"[$reg + $off + $lreg]" %} 3769 interface(MEMORY_INTER) %{ 3770 base($reg); 3771 index($lreg); 3772 scale(0x0); 3773 disp($off); 3774 %} 3775 %} 3776 3777 // Indirect Memory Plus Index Register Plus Offset Operand 3778 operand indIndex(any_RegP reg, rRegL lreg) 3779 %{ 3780 constraint(ALLOC_IN_RC(ptr_reg)); 3781 match(AddP reg lreg); 3782 3783 op_cost(10); 3784 format %{"[$reg + $lreg]" %} 3785 interface(MEMORY_INTER) %{ 3786 base($reg); 3787 index($lreg); 3788 scale(0x0); 3789 disp(0x0); 3790 %} 3791 %} 3792 3793 // Indirect Memory Times Scale Plus Index Register 3794 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3795 %{ 3796 constraint(ALLOC_IN_RC(ptr_reg)); 3797 match(AddP reg (LShiftL lreg scale)); 3798 3799 op_cost(10); 3800 format %{"[$reg + $lreg << $scale]" %} 3801 interface(MEMORY_INTER) %{ 3802 base($reg); 3803 index($lreg); 3804 scale($scale); 3805 disp(0x0); 3806 %} 3807 %} 3808 3809 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3810 %{ 3811 constraint(ALLOC_IN_RC(ptr_reg)); 3812 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3813 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3814 3815 op_cost(10); 3816 format %{"[$reg + pos $idx << $scale]" %} 3817 interface(MEMORY_INTER) %{ 3818 base($reg); 3819 index($idx); 3820 scale($scale); 3821 disp(0x0); 3822 %} 3823 %} 3824 3825 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3826 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3827 %{ 3828 constraint(ALLOC_IN_RC(ptr_reg)); 3829 match(AddP (AddP reg (LShiftL lreg scale)) off); 3830 3831 op_cost(10); 3832 format %{"[$reg + $off + $lreg << $scale]" %} 3833 interface(MEMORY_INTER) %{ 3834 base($reg); 3835 index($lreg); 3836 scale($scale); 3837 disp($off); 3838 %} 3839 %} 3840 3841 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3842 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3843 %{ 3844 constraint(ALLOC_IN_RC(ptr_reg)); 3845 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3846 match(AddP (AddP reg (ConvI2L idx)) off); 3847 3848 op_cost(10); 3849 format %{"[$reg + $off + $idx]" %} 3850 interface(MEMORY_INTER) %{ 3851 base($reg); 3852 index($idx); 3853 scale(0x0); 3854 disp($off); 3855 %} 3856 %} 3857 3858 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3859 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3860 %{ 3861 constraint(ALLOC_IN_RC(ptr_reg)); 3862 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3863 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3864 3865 op_cost(10); 3866 format %{"[$reg + $off + $idx << $scale]" %} 3867 interface(MEMORY_INTER) %{ 3868 base($reg); 3869 index($idx); 3870 scale($scale); 3871 disp($off); 3872 %} 3873 %} 3874 3875 // Indirect Narrow Oop Plus Offset Operand 3876 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3877 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3878 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3879 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3880 constraint(ALLOC_IN_RC(ptr_reg)); 3881 match(AddP (DecodeN reg) off); 3882 3883 op_cost(10); 3884 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3885 interface(MEMORY_INTER) %{ 3886 base(0xc); // R12 3887 index($reg); 3888 scale(0x3); 3889 disp($off); 3890 %} 3891 %} 3892 3893 // Indirect Memory Operand 3894 operand indirectNarrow(rRegN reg) 3895 %{ 3896 predicate(Universe::narrow_oop_shift() == 0); 3897 constraint(ALLOC_IN_RC(ptr_reg)); 3898 match(DecodeN reg); 3899 3900 format %{ "[$reg]" %} 3901 interface(MEMORY_INTER) %{ 3902 base($reg); 3903 index(0x4); 3904 scale(0x0); 3905 disp(0x0); 3906 %} 3907 %} 3908 3909 // Indirect Memory Plus Short Offset Operand 3910 operand indOffset8Narrow(rRegN reg, immL8 off) 3911 %{ 3912 predicate(Universe::narrow_oop_shift() == 0); 3913 constraint(ALLOC_IN_RC(ptr_reg)); 3914 match(AddP (DecodeN reg) off); 3915 3916 format %{ "[$reg + $off (8-bit)]" %} 3917 interface(MEMORY_INTER) %{ 3918 base($reg); 3919 index(0x4); 3920 scale(0x0); 3921 disp($off); 3922 %} 3923 %} 3924 3925 // Indirect Memory Plus Long Offset Operand 3926 operand indOffset32Narrow(rRegN reg, immL32 off) 3927 %{ 3928 predicate(Universe::narrow_oop_shift() == 0); 3929 constraint(ALLOC_IN_RC(ptr_reg)); 3930 match(AddP (DecodeN reg) off); 3931 3932 format %{ "[$reg + $off (32-bit)]" %} 3933 interface(MEMORY_INTER) %{ 3934 base($reg); 3935 index(0x4); 3936 scale(0x0); 3937 disp($off); 3938 %} 3939 %} 3940 3941 // Indirect Memory Plus Index Register Plus Offset Operand 3942 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3943 %{ 3944 predicate(Universe::narrow_oop_shift() == 0); 3945 constraint(ALLOC_IN_RC(ptr_reg)); 3946 match(AddP (AddP (DecodeN reg) lreg) off); 3947 3948 op_cost(10); 3949 format %{"[$reg + $off + $lreg]" %} 3950 interface(MEMORY_INTER) %{ 3951 base($reg); 3952 index($lreg); 3953 scale(0x0); 3954 disp($off); 3955 %} 3956 %} 3957 3958 // Indirect Memory Plus Index Register Plus Offset Operand 3959 operand indIndexNarrow(rRegN reg, rRegL lreg) 3960 %{ 3961 predicate(Universe::narrow_oop_shift() == 0); 3962 constraint(ALLOC_IN_RC(ptr_reg)); 3963 match(AddP (DecodeN reg) lreg); 3964 3965 op_cost(10); 3966 format %{"[$reg + $lreg]" %} 3967 interface(MEMORY_INTER) %{ 3968 base($reg); 3969 index($lreg); 3970 scale(0x0); 3971 disp(0x0); 3972 %} 3973 %} 3974 3975 // Indirect Memory Times Scale Plus Index Register 3976 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3977 %{ 3978 predicate(Universe::narrow_oop_shift() == 0); 3979 constraint(ALLOC_IN_RC(ptr_reg)); 3980 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3981 3982 op_cost(10); 3983 format %{"[$reg + $lreg << $scale]" %} 3984 interface(MEMORY_INTER) %{ 3985 base($reg); 3986 index($lreg); 3987 scale($scale); 3988 disp(0x0); 3989 %} 3990 %} 3991 3992 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3993 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3994 %{ 3995 predicate(Universe::narrow_oop_shift() == 0); 3996 constraint(ALLOC_IN_RC(ptr_reg)); 3997 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3998 3999 op_cost(10); 4000 format %{"[$reg + $off + $lreg << $scale]" %} 4001 interface(MEMORY_INTER) %{ 4002 base($reg); 4003 index($lreg); 4004 scale($scale); 4005 disp($off); 4006 %} 4007 %} 4008 4009 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4010 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4011 %{ 4012 constraint(ALLOC_IN_RC(ptr_reg)); 4013 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4014 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4015 4016 op_cost(10); 4017 format %{"[$reg + $off + $idx]" %} 4018 interface(MEMORY_INTER) %{ 4019 base($reg); 4020 index($idx); 4021 scale(0x0); 4022 disp($off); 4023 %} 4024 %} 4025 4026 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4027 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4028 %{ 4029 constraint(ALLOC_IN_RC(ptr_reg)); 4030 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4031 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4032 4033 op_cost(10); 4034 format %{"[$reg + $off + $idx << $scale]" %} 4035 interface(MEMORY_INTER) %{ 4036 base($reg); 4037 index($idx); 4038 scale($scale); 4039 disp($off); 4040 %} 4041 %} 4042 4043 //----------Special Memory Operands-------------------------------------------- 4044 // Stack Slot Operand - This operand is used for loading and storing temporary 4045 // values on the stack where a match requires a value to 4046 // flow through memory. 4047 operand stackSlotP(sRegP reg) 4048 %{ 4049 constraint(ALLOC_IN_RC(stack_slots)); 4050 // No match rule because this operand is only generated in matching 4051 4052 format %{ "[$reg]" %} 4053 interface(MEMORY_INTER) %{ 4054 base(0x4); // RSP 4055 index(0x4); // No Index 4056 scale(0x0); // No Scale 4057 disp($reg); // Stack Offset 4058 %} 4059 %} 4060 4061 operand stackSlotI(sRegI reg) 4062 %{ 4063 constraint(ALLOC_IN_RC(stack_slots)); 4064 // No match rule because this operand is only generated in matching 4065 4066 format %{ "[$reg]" %} 4067 interface(MEMORY_INTER) %{ 4068 base(0x4); // RSP 4069 index(0x4); // No Index 4070 scale(0x0); // No Scale 4071 disp($reg); // Stack Offset 4072 %} 4073 %} 4074 4075 operand stackSlotF(sRegF reg) 4076 %{ 4077 constraint(ALLOC_IN_RC(stack_slots)); 4078 // No match rule because this operand is only generated in matching 4079 4080 format %{ "[$reg]" %} 4081 interface(MEMORY_INTER) %{ 4082 base(0x4); // RSP 4083 index(0x4); // No Index 4084 scale(0x0); // No Scale 4085 disp($reg); // Stack Offset 4086 %} 4087 %} 4088 4089 operand stackSlotD(sRegD reg) 4090 %{ 4091 constraint(ALLOC_IN_RC(stack_slots)); 4092 // No match rule because this operand is only generated in matching 4093 4094 format %{ "[$reg]" %} 4095 interface(MEMORY_INTER) %{ 4096 base(0x4); // RSP 4097 index(0x4); // No Index 4098 scale(0x0); // No Scale 4099 disp($reg); // Stack Offset 4100 %} 4101 %} 4102 operand stackSlotL(sRegL reg) 4103 %{ 4104 constraint(ALLOC_IN_RC(stack_slots)); 4105 // No match rule because this operand is only generated in matching 4106 4107 format %{ "[$reg]" %} 4108 interface(MEMORY_INTER) %{ 4109 base(0x4); // RSP 4110 index(0x4); // No Index 4111 scale(0x0); // No Scale 4112 disp($reg); // Stack Offset 4113 %} 4114 %} 4115 4116 //----------Conditional Branch Operands---------------------------------------- 4117 // Comparison Op - This is the operation of the comparison, and is limited to 4118 // the following set of codes: 4119 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4120 // 4121 // Other attributes of the comparison, such as unsignedness, are specified 4122 // by the comparison instruction that sets a condition code flags register. 4123 // That result is represented by a flags operand whose subtype is appropriate 4124 // to the unsignedness (etc.) of the comparison. 4125 // 4126 // Later, the instruction which matches both the Comparison Op (a Bool) and 4127 // the flags (produced by the Cmp) specifies the coding of the comparison op 4128 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4129 4130 // Comparision Code 4131 operand cmpOp() 4132 %{ 4133 match(Bool); 4134 4135 format %{ "" %} 4136 interface(COND_INTER) %{ 4137 equal(0x4, "e"); 4138 not_equal(0x5, "ne"); 4139 less(0xC, "l"); 4140 greater_equal(0xD, "ge"); 4141 less_equal(0xE, "le"); 4142 greater(0xF, "g"); 4143 overflow(0x0, "o"); 4144 no_overflow(0x1, "no"); 4145 %} 4146 %} 4147 4148 // Comparison Code, unsigned compare. Used by FP also, with 4149 // C2 (unordered) turned into GT or LT already. The other bits 4150 // C0 and C3 are turned into Carry & Zero flags. 4151 operand cmpOpU() 4152 %{ 4153 match(Bool); 4154 4155 format %{ "" %} 4156 interface(COND_INTER) %{ 4157 equal(0x4, "e"); 4158 not_equal(0x5, "ne"); 4159 less(0x2, "b"); 4160 greater_equal(0x3, "nb"); 4161 less_equal(0x6, "be"); 4162 greater(0x7, "nbe"); 4163 overflow(0x0, "o"); 4164 no_overflow(0x1, "no"); 4165 %} 4166 %} 4167 4168 4169 // Floating comparisons that don't require any fixup for the unordered case 4170 operand cmpOpUCF() %{ 4171 match(Bool); 4172 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4173 n->as_Bool()->_test._test == BoolTest::ge || 4174 n->as_Bool()->_test._test == BoolTest::le || 4175 n->as_Bool()->_test._test == BoolTest::gt); 4176 format %{ "" %} 4177 interface(COND_INTER) %{ 4178 equal(0x4, "e"); 4179 not_equal(0x5, "ne"); 4180 less(0x2, "b"); 4181 greater_equal(0x3, "nb"); 4182 less_equal(0x6, "be"); 4183 greater(0x7, "nbe"); 4184 overflow(0x0, "o"); 4185 no_overflow(0x1, "no"); 4186 %} 4187 %} 4188 4189 4190 // Floating comparisons that can be fixed up with extra conditional jumps 4191 operand cmpOpUCF2() %{ 4192 match(Bool); 4193 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4194 n->as_Bool()->_test._test == BoolTest::eq); 4195 format %{ "" %} 4196 interface(COND_INTER) %{ 4197 equal(0x4, "e"); 4198 not_equal(0x5, "ne"); 4199 less(0x2, "b"); 4200 greater_equal(0x3, "nb"); 4201 less_equal(0x6, "be"); 4202 greater(0x7, "nbe"); 4203 overflow(0x0, "o"); 4204 no_overflow(0x1, "no"); 4205 %} 4206 %} 4207 4208 // Operands for bound floating pointer register arguments 4209 operand rxmm0() %{ 4210 constraint(ALLOC_IN_RC(xmm0_reg)); match(VecX); 4211 predicate((UseSSE > 0) && (UseAVX<= 2)); format%{%} interface(REG_INTER); 4212 %} 4213 operand rxmm1() %{ 4214 constraint(ALLOC_IN_RC(xmm1_reg)); match(VecX); 4215 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4216 %} 4217 operand rxmm2() %{ 4218 constraint(ALLOC_IN_RC(xmm2_reg)); match(VecX); 4219 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4220 %} 4221 operand rxmm3() %{ 4222 constraint(ALLOC_IN_RC(xmm3_reg)); match(VecX); 4223 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4224 %} 4225 operand rxmm4() %{ 4226 constraint(ALLOC_IN_RC(xmm4_reg)); match(VecX); 4227 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4228 %} 4229 operand rxmm5() %{ 4230 constraint(ALLOC_IN_RC(xmm5_reg)); match(VecX); 4231 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4232 %} 4233 operand rxmm6() %{ 4234 constraint(ALLOC_IN_RC(xmm6_reg)); match(VecX); 4235 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4236 %} 4237 operand rxmm7() %{ 4238 constraint(ALLOC_IN_RC(xmm7_reg)); match(VecX); 4239 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4240 %} 4241 operand rxmm8() %{ 4242 constraint(ALLOC_IN_RC(xmm8_reg)); match(VecX); 4243 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4244 %} 4245 operand rxmm9() %{ 4246 constraint(ALLOC_IN_RC(xmm9_reg)); match(VecX); 4247 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4248 %} 4249 operand rxmm10() %{ 4250 constraint(ALLOC_IN_RC(xmm10_reg)); match(VecX); 4251 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4252 %} 4253 operand rxmm11() %{ 4254 constraint(ALLOC_IN_RC(xmm11_reg)); match(VecX); 4255 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4256 %} 4257 operand rxmm12() %{ 4258 constraint(ALLOC_IN_RC(xmm12_reg)); match(VecX); 4259 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4260 %} 4261 operand rxmm13() %{ 4262 constraint(ALLOC_IN_RC(xmm13_reg)); match(VecX); 4263 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4264 %} 4265 operand rxmm14() %{ 4266 constraint(ALLOC_IN_RC(xmm14_reg)); match(VecX); 4267 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4268 %} 4269 operand rxmm15() %{ 4270 constraint(ALLOC_IN_RC(xmm15_reg)); match(VecX); 4271 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4272 %} 4273 operand rxmm16() %{ 4274 constraint(ALLOC_IN_RC(xmm16_reg)); match(VecX); 4275 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4276 %} 4277 operand rxmm17() %{ 4278 constraint(ALLOC_IN_RC(xmm17_reg)); match(VecX); 4279 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4280 %} 4281 operand rxmm18() %{ 4282 constraint(ALLOC_IN_RC(xmm18_reg)); match(VecX); 4283 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4284 %} 4285 operand rxmm19() %{ 4286 constraint(ALLOC_IN_RC(xmm19_reg)); match(VecX); 4287 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4288 %} 4289 operand rxmm20() %{ 4290 constraint(ALLOC_IN_RC(xmm20_reg)); match(VecX); 4291 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4292 %} 4293 operand rxmm21() %{ 4294 constraint(ALLOC_IN_RC(xmm21_reg)); match(VecX); 4295 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4296 %} 4297 operand rxmm22() %{ 4298 constraint(ALLOC_IN_RC(xmm22_reg)); match(VecX); 4299 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4300 %} 4301 operand rxmm23() %{ 4302 constraint(ALLOC_IN_RC(xmm23_reg)); match(VecX); 4303 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4304 %} 4305 operand rxmm24() %{ 4306 constraint(ALLOC_IN_RC(xmm24_reg)); match(VecX); 4307 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4308 %} 4309 operand rxmm25() %{ 4310 constraint(ALLOC_IN_RC(xmm25_reg)); match(VecX); 4311 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4312 %} 4313 operand rxmm26() %{ 4314 constraint(ALLOC_IN_RC(xmm26_reg)); match(VecX); 4315 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4316 %} 4317 operand rxmm27() %{ 4318 constraint(ALLOC_IN_RC(xmm27_reg)); match(VecX); 4319 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4320 %} 4321 operand rxmm28() %{ 4322 constraint(ALLOC_IN_RC(xmm28_reg)); match(VecX); 4323 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4324 %} 4325 operand rxmm29() %{ 4326 constraint(ALLOC_IN_RC(xmm29_reg)); match(VecX); 4327 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4328 %} 4329 operand rxmm30() %{ 4330 constraint(ALLOC_IN_RC(xmm30_reg)); match(VecX); 4331 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4332 %} 4333 operand rxmm31() %{ 4334 constraint(ALLOC_IN_RC(xmm31_reg)); match(VecX); 4335 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4336 %} 4337 4338 //----------OPERAND CLASSES---------------------------------------------------- 4339 // Operand Classes are groups of operands that are used as to simplify 4340 // instruction definitions by not requiring the AD writer to specify separate 4341 // instructions for every form of operand when the instruction accepts 4342 // multiple operand types with the same basic encoding and format. The classic 4343 // case of this is memory operands. 4344 4345 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4346 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4347 indCompressedOopOffset, 4348 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4349 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4350 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4351 4352 //----------PIPELINE----------------------------------------------------------- 4353 // Rules which define the behavior of the target architectures pipeline. 4354 pipeline %{ 4355 4356 //----------ATTRIBUTES--------------------------------------------------------- 4357 attributes %{ 4358 variable_size_instructions; // Fixed size instructions 4359 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4360 instruction_unit_size = 1; // An instruction is 1 bytes long 4361 instruction_fetch_unit_size = 16; // The processor fetches one line 4362 instruction_fetch_units = 1; // of 16 bytes 4363 4364 // List of nop instructions 4365 nops( MachNop ); 4366 %} 4367 4368 //----------RESOURCES---------------------------------------------------------- 4369 // Resources are the functional units available to the machine 4370 4371 // Generic P2/P3 pipeline 4372 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4373 // 3 instructions decoded per cycle. 4374 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4375 // 3 ALU op, only ALU0 handles mul instructions. 4376 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4377 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4378 BR, FPU, 4379 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4380 4381 //----------PIPELINE DESCRIPTION----------------------------------------------- 4382 // Pipeline Description specifies the stages in the machine's pipeline 4383 4384 // Generic P2/P3 pipeline 4385 pipe_desc(S0, S1, S2, S3, S4, S5); 4386 4387 //----------PIPELINE CLASSES--------------------------------------------------- 4388 // Pipeline Classes describe the stages in which input and output are 4389 // referenced by the hardware pipeline. 4390 4391 // Naming convention: ialu or fpu 4392 // Then: _reg 4393 // Then: _reg if there is a 2nd register 4394 // Then: _long if it's a pair of instructions implementing a long 4395 // Then: _fat if it requires the big decoder 4396 // Or: _mem if it requires the big decoder and a memory unit. 4397 4398 // Integer ALU reg operation 4399 pipe_class ialu_reg(rRegI dst) 4400 %{ 4401 single_instruction; 4402 dst : S4(write); 4403 dst : S3(read); 4404 DECODE : S0; // any decoder 4405 ALU : S3; // any alu 4406 %} 4407 4408 // Long ALU reg operation 4409 pipe_class ialu_reg_long(rRegL dst) 4410 %{ 4411 instruction_count(2); 4412 dst : S4(write); 4413 dst : S3(read); 4414 DECODE : S0(2); // any 2 decoders 4415 ALU : S3(2); // both alus 4416 %} 4417 4418 // Integer ALU reg operation using big decoder 4419 pipe_class ialu_reg_fat(rRegI dst) 4420 %{ 4421 single_instruction; 4422 dst : S4(write); 4423 dst : S3(read); 4424 D0 : S0; // big decoder only 4425 ALU : S3; // any alu 4426 %} 4427 4428 // Long ALU reg operation using big decoder 4429 pipe_class ialu_reg_long_fat(rRegL dst) 4430 %{ 4431 instruction_count(2); 4432 dst : S4(write); 4433 dst : S3(read); 4434 D0 : S0(2); // big decoder only; twice 4435 ALU : S3(2); // any 2 alus 4436 %} 4437 4438 // Integer ALU reg-reg operation 4439 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4440 %{ 4441 single_instruction; 4442 dst : S4(write); 4443 src : S3(read); 4444 DECODE : S0; // any decoder 4445 ALU : S3; // any alu 4446 %} 4447 4448 // Long ALU reg-reg operation 4449 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4450 %{ 4451 instruction_count(2); 4452 dst : S4(write); 4453 src : S3(read); 4454 DECODE : S0(2); // any 2 decoders 4455 ALU : S3(2); // both alus 4456 %} 4457 4458 // Integer ALU reg-reg operation 4459 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4460 %{ 4461 single_instruction; 4462 dst : S4(write); 4463 src : S3(read); 4464 D0 : S0; // big decoder only 4465 ALU : S3; // any alu 4466 %} 4467 4468 // Long ALU reg-reg operation 4469 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4470 %{ 4471 instruction_count(2); 4472 dst : S4(write); 4473 src : S3(read); 4474 D0 : S0(2); // big decoder only; twice 4475 ALU : S3(2); // both alus 4476 %} 4477 4478 // Integer ALU reg-mem operation 4479 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4480 %{ 4481 single_instruction; 4482 dst : S5(write); 4483 mem : S3(read); 4484 D0 : S0; // big decoder only 4485 ALU : S4; // any alu 4486 MEM : S3; // any mem 4487 %} 4488 4489 // Integer mem operation (prefetch) 4490 pipe_class ialu_mem(memory mem) 4491 %{ 4492 single_instruction; 4493 mem : S3(read); 4494 D0 : S0; // big decoder only 4495 MEM : S3; // any mem 4496 %} 4497 4498 // Integer Store to Memory 4499 pipe_class ialu_mem_reg(memory mem, rRegI src) 4500 %{ 4501 single_instruction; 4502 mem : S3(read); 4503 src : S5(read); 4504 D0 : S0; // big decoder only 4505 ALU : S4; // any alu 4506 MEM : S3; 4507 %} 4508 4509 // // Long Store to Memory 4510 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4511 // %{ 4512 // instruction_count(2); 4513 // mem : S3(read); 4514 // src : S5(read); 4515 // D0 : S0(2); // big decoder only; twice 4516 // ALU : S4(2); // any 2 alus 4517 // MEM : S3(2); // Both mems 4518 // %} 4519 4520 // Integer Store to Memory 4521 pipe_class ialu_mem_imm(memory mem) 4522 %{ 4523 single_instruction; 4524 mem : S3(read); 4525 D0 : S0; // big decoder only 4526 ALU : S4; // any alu 4527 MEM : S3; 4528 %} 4529 4530 // Integer ALU0 reg-reg operation 4531 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4532 %{ 4533 single_instruction; 4534 dst : S4(write); 4535 src : S3(read); 4536 D0 : S0; // Big decoder only 4537 ALU0 : S3; // only alu0 4538 %} 4539 4540 // Integer ALU0 reg-mem operation 4541 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4542 %{ 4543 single_instruction; 4544 dst : S5(write); 4545 mem : S3(read); 4546 D0 : S0; // big decoder only 4547 ALU0 : S4; // ALU0 only 4548 MEM : S3; // any mem 4549 %} 4550 4551 // Integer ALU reg-reg operation 4552 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4553 %{ 4554 single_instruction; 4555 cr : S4(write); 4556 src1 : S3(read); 4557 src2 : S3(read); 4558 DECODE : S0; // any decoder 4559 ALU : S3; // any alu 4560 %} 4561 4562 // Integer ALU reg-imm operation 4563 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4564 %{ 4565 single_instruction; 4566 cr : S4(write); 4567 src1 : S3(read); 4568 DECODE : S0; // any decoder 4569 ALU : S3; // any alu 4570 %} 4571 4572 // Integer ALU reg-mem operation 4573 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4574 %{ 4575 single_instruction; 4576 cr : S4(write); 4577 src1 : S3(read); 4578 src2 : S3(read); 4579 D0 : S0; // big decoder only 4580 ALU : S4; // any alu 4581 MEM : S3; 4582 %} 4583 4584 // Conditional move reg-reg 4585 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4586 %{ 4587 instruction_count(4); 4588 y : S4(read); 4589 q : S3(read); 4590 p : S3(read); 4591 DECODE : S0(4); // any decoder 4592 %} 4593 4594 // Conditional move reg-reg 4595 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4596 %{ 4597 single_instruction; 4598 dst : S4(write); 4599 src : S3(read); 4600 cr : S3(read); 4601 DECODE : S0; // any decoder 4602 %} 4603 4604 // Conditional move reg-mem 4605 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4606 %{ 4607 single_instruction; 4608 dst : S4(write); 4609 src : S3(read); 4610 cr : S3(read); 4611 DECODE : S0; // any decoder 4612 MEM : S3; 4613 %} 4614 4615 // Conditional move reg-reg long 4616 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4617 %{ 4618 single_instruction; 4619 dst : S4(write); 4620 src : S3(read); 4621 cr : S3(read); 4622 DECODE : S0(2); // any 2 decoders 4623 %} 4624 4625 // XXX 4626 // // Conditional move double reg-reg 4627 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4628 // %{ 4629 // single_instruction; 4630 // dst : S4(write); 4631 // src : S3(read); 4632 // cr : S3(read); 4633 // DECODE : S0; // any decoder 4634 // %} 4635 4636 // Float reg-reg operation 4637 pipe_class fpu_reg(regD dst) 4638 %{ 4639 instruction_count(2); 4640 dst : S3(read); 4641 DECODE : S0(2); // any 2 decoders 4642 FPU : S3; 4643 %} 4644 4645 // Float reg-reg operation 4646 pipe_class fpu_reg_reg(regD dst, regD src) 4647 %{ 4648 instruction_count(2); 4649 dst : S4(write); 4650 src : S3(read); 4651 DECODE : S0(2); // any 2 decoders 4652 FPU : S3; 4653 %} 4654 4655 // Float reg-reg operation 4656 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4657 %{ 4658 instruction_count(3); 4659 dst : S4(write); 4660 src1 : S3(read); 4661 src2 : S3(read); 4662 DECODE : S0(3); // any 3 decoders 4663 FPU : S3(2); 4664 %} 4665 4666 // Float reg-reg operation 4667 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4668 %{ 4669 instruction_count(4); 4670 dst : S4(write); 4671 src1 : S3(read); 4672 src2 : S3(read); 4673 src3 : S3(read); 4674 DECODE : S0(4); // any 3 decoders 4675 FPU : S3(2); 4676 %} 4677 4678 // Float reg-reg operation 4679 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4680 %{ 4681 instruction_count(4); 4682 dst : S4(write); 4683 src1 : S3(read); 4684 src2 : S3(read); 4685 src3 : S3(read); 4686 DECODE : S1(3); // any 3 decoders 4687 D0 : S0; // Big decoder only 4688 FPU : S3(2); 4689 MEM : S3; 4690 %} 4691 4692 // Float reg-mem operation 4693 pipe_class fpu_reg_mem(regD dst, memory mem) 4694 %{ 4695 instruction_count(2); 4696 dst : S5(write); 4697 mem : S3(read); 4698 D0 : S0; // big decoder only 4699 DECODE : S1; // any decoder for FPU POP 4700 FPU : S4; 4701 MEM : S3; // any mem 4702 %} 4703 4704 // Float reg-mem operation 4705 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4706 %{ 4707 instruction_count(3); 4708 dst : S5(write); 4709 src1 : S3(read); 4710 mem : S3(read); 4711 D0 : S0; // big decoder only 4712 DECODE : S1(2); // any decoder for FPU POP 4713 FPU : S4; 4714 MEM : S3; // any mem 4715 %} 4716 4717 // Float mem-reg operation 4718 pipe_class fpu_mem_reg(memory mem, regD src) 4719 %{ 4720 instruction_count(2); 4721 src : S5(read); 4722 mem : S3(read); 4723 DECODE : S0; // any decoder for FPU PUSH 4724 D0 : S1; // big decoder only 4725 FPU : S4; 4726 MEM : S3; // any mem 4727 %} 4728 4729 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4730 %{ 4731 instruction_count(3); 4732 src1 : S3(read); 4733 src2 : S3(read); 4734 mem : S3(read); 4735 DECODE : S0(2); // any decoder for FPU PUSH 4736 D0 : S1; // big decoder only 4737 FPU : S4; 4738 MEM : S3; // any mem 4739 %} 4740 4741 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4742 %{ 4743 instruction_count(3); 4744 src1 : S3(read); 4745 src2 : S3(read); 4746 mem : S4(read); 4747 DECODE : S0; // any decoder for FPU PUSH 4748 D0 : S0(2); // big decoder only 4749 FPU : S4; 4750 MEM : S3(2); // any mem 4751 %} 4752 4753 pipe_class fpu_mem_mem(memory dst, memory src1) 4754 %{ 4755 instruction_count(2); 4756 src1 : S3(read); 4757 dst : S4(read); 4758 D0 : S0(2); // big decoder only 4759 MEM : S3(2); // any mem 4760 %} 4761 4762 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4763 %{ 4764 instruction_count(3); 4765 src1 : S3(read); 4766 src2 : S3(read); 4767 dst : S4(read); 4768 D0 : S0(3); // big decoder only 4769 FPU : S4; 4770 MEM : S3(3); // any mem 4771 %} 4772 4773 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4774 %{ 4775 instruction_count(3); 4776 src1 : S4(read); 4777 mem : S4(read); 4778 DECODE : S0; // any decoder for FPU PUSH 4779 D0 : S0(2); // big decoder only 4780 FPU : S4; 4781 MEM : S3(2); // any mem 4782 %} 4783 4784 // Float load constant 4785 pipe_class fpu_reg_con(regD dst) 4786 %{ 4787 instruction_count(2); 4788 dst : S5(write); 4789 D0 : S0; // big decoder only for the load 4790 DECODE : S1; // any decoder for FPU POP 4791 FPU : S4; 4792 MEM : S3; // any mem 4793 %} 4794 4795 // Float load constant 4796 pipe_class fpu_reg_reg_con(regD dst, regD src) 4797 %{ 4798 instruction_count(3); 4799 dst : S5(write); 4800 src : S3(read); 4801 D0 : S0; // big decoder only for the load 4802 DECODE : S1(2); // any decoder for FPU POP 4803 FPU : S4; 4804 MEM : S3; // any mem 4805 %} 4806 4807 // UnConditional branch 4808 pipe_class pipe_jmp(label labl) 4809 %{ 4810 single_instruction; 4811 BR : S3; 4812 %} 4813 4814 // Conditional branch 4815 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4816 %{ 4817 single_instruction; 4818 cr : S1(read); 4819 BR : S3; 4820 %} 4821 4822 // Allocation idiom 4823 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4824 %{ 4825 instruction_count(1); force_serialization; 4826 fixed_latency(6); 4827 heap_ptr : S3(read); 4828 DECODE : S0(3); 4829 D0 : S2; 4830 MEM : S3; 4831 ALU : S3(2); 4832 dst : S5(write); 4833 BR : S5; 4834 %} 4835 4836 // Generic big/slow expanded idiom 4837 pipe_class pipe_slow() 4838 %{ 4839 instruction_count(10); multiple_bundles; force_serialization; 4840 fixed_latency(100); 4841 D0 : S0(2); 4842 MEM : S3(2); 4843 %} 4844 4845 // The real do-nothing guy 4846 pipe_class empty() 4847 %{ 4848 instruction_count(0); 4849 %} 4850 4851 // Define the class for the Nop node 4852 define 4853 %{ 4854 MachNop = empty; 4855 %} 4856 4857 %} 4858 4859 //----------INSTRUCTIONS------------------------------------------------------- 4860 // 4861 // match -- States which machine-independent subtree may be replaced 4862 // by this instruction. 4863 // ins_cost -- The estimated cost of this instruction is used by instruction 4864 // selection to identify a minimum cost tree of machine 4865 // instructions that matches a tree of machine-independent 4866 // instructions. 4867 // format -- A string providing the disassembly for this instruction. 4868 // The value of an instruction's operand may be inserted 4869 // by referring to it with a '$' prefix. 4870 // opcode -- Three instruction opcodes may be provided. These are referred 4871 // to within an encode class as $primary, $secondary, and $tertiary 4872 // rrspectively. The primary opcode is commonly used to 4873 // indicate the type of machine instruction, while secondary 4874 // and tertiary are often used for prefix options or addressing 4875 // modes. 4876 // ins_encode -- A list of encode classes with parameters. The encode class 4877 // name must have been defined in an 'enc_class' specification 4878 // in the encode section of the architecture description. 4879 4880 4881 //----------Load/Store/Move Instructions--------------------------------------- 4882 //----------Load Instructions-------------------------------------------------- 4883 4884 // Load Byte (8 bit signed) 4885 instruct loadB(rRegI dst, memory mem) 4886 %{ 4887 match(Set dst (LoadB mem)); 4888 4889 ins_cost(125); 4890 format %{ "movsbl $dst, $mem\t# byte" %} 4891 4892 ins_encode %{ 4893 __ movsbl($dst$$Register, $mem$$Address); 4894 %} 4895 4896 ins_pipe(ialu_reg_mem); 4897 %} 4898 4899 // Load Byte (8 bit signed) into Long Register 4900 instruct loadB2L(rRegL dst, memory mem) 4901 %{ 4902 match(Set dst (ConvI2L (LoadB mem))); 4903 4904 ins_cost(125); 4905 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4906 4907 ins_encode %{ 4908 __ movsbq($dst$$Register, $mem$$Address); 4909 %} 4910 4911 ins_pipe(ialu_reg_mem); 4912 %} 4913 4914 // Load Unsigned Byte (8 bit UNsigned) 4915 instruct loadUB(rRegI dst, memory mem) 4916 %{ 4917 match(Set dst (LoadUB mem)); 4918 4919 ins_cost(125); 4920 format %{ "movzbl $dst, $mem\t# ubyte" %} 4921 4922 ins_encode %{ 4923 __ movzbl($dst$$Register, $mem$$Address); 4924 %} 4925 4926 ins_pipe(ialu_reg_mem); 4927 %} 4928 4929 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4930 instruct loadUB2L(rRegL dst, memory mem) 4931 %{ 4932 match(Set dst (ConvI2L (LoadUB mem))); 4933 4934 ins_cost(125); 4935 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4936 4937 ins_encode %{ 4938 __ movzbq($dst$$Register, $mem$$Address); 4939 %} 4940 4941 ins_pipe(ialu_reg_mem); 4942 %} 4943 4944 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4945 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4946 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4947 effect(KILL cr); 4948 4949 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4950 "andl $dst, right_n_bits($mask, 8)" %} 4951 ins_encode %{ 4952 Register Rdst = $dst$$Register; 4953 __ movzbq(Rdst, $mem$$Address); 4954 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4955 %} 4956 ins_pipe(ialu_reg_mem); 4957 %} 4958 4959 // Load Short (16 bit signed) 4960 instruct loadS(rRegI dst, memory mem) 4961 %{ 4962 match(Set dst (LoadS mem)); 4963 4964 ins_cost(125); 4965 format %{ "movswl $dst, $mem\t# short" %} 4966 4967 ins_encode %{ 4968 __ movswl($dst$$Register, $mem$$Address); 4969 %} 4970 4971 ins_pipe(ialu_reg_mem); 4972 %} 4973 4974 // Load Short (16 bit signed) to Byte (8 bit signed) 4975 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4976 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4977 4978 ins_cost(125); 4979 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4980 ins_encode %{ 4981 __ movsbl($dst$$Register, $mem$$Address); 4982 %} 4983 ins_pipe(ialu_reg_mem); 4984 %} 4985 4986 // Load Short (16 bit signed) into Long Register 4987 instruct loadS2L(rRegL dst, memory mem) 4988 %{ 4989 match(Set dst (ConvI2L (LoadS mem))); 4990 4991 ins_cost(125); 4992 format %{ "movswq $dst, $mem\t# short -> long" %} 4993 4994 ins_encode %{ 4995 __ movswq($dst$$Register, $mem$$Address); 4996 %} 4997 4998 ins_pipe(ialu_reg_mem); 4999 %} 5000 5001 // Load Unsigned Short/Char (16 bit UNsigned) 5002 instruct loadUS(rRegI dst, memory mem) 5003 %{ 5004 match(Set dst (LoadUS mem)); 5005 5006 ins_cost(125); 5007 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5008 5009 ins_encode %{ 5010 __ movzwl($dst$$Register, $mem$$Address); 5011 %} 5012 5013 ins_pipe(ialu_reg_mem); 5014 %} 5015 5016 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5017 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5018 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5019 5020 ins_cost(125); 5021 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5022 ins_encode %{ 5023 __ movsbl($dst$$Register, $mem$$Address); 5024 %} 5025 ins_pipe(ialu_reg_mem); 5026 %} 5027 5028 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5029 instruct loadUS2L(rRegL dst, memory mem) 5030 %{ 5031 match(Set dst (ConvI2L (LoadUS mem))); 5032 5033 ins_cost(125); 5034 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5035 5036 ins_encode %{ 5037 __ movzwq($dst$$Register, $mem$$Address); 5038 %} 5039 5040 ins_pipe(ialu_reg_mem); 5041 %} 5042 5043 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5044 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5045 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5046 5047 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5048 ins_encode %{ 5049 __ movzbq($dst$$Register, $mem$$Address); 5050 %} 5051 ins_pipe(ialu_reg_mem); 5052 %} 5053 5054 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 5055 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5056 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5057 effect(KILL cr); 5058 5059 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 5060 "andl $dst, right_n_bits($mask, 16)" %} 5061 ins_encode %{ 5062 Register Rdst = $dst$$Register; 5063 __ movzwq(Rdst, $mem$$Address); 5064 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 5065 %} 5066 ins_pipe(ialu_reg_mem); 5067 %} 5068 5069 // Load Integer 5070 instruct loadI(rRegI dst, memory mem) 5071 %{ 5072 match(Set dst (LoadI mem)); 5073 5074 ins_cost(125); 5075 format %{ "movl $dst, $mem\t# int" %} 5076 5077 ins_encode %{ 5078 __ movl($dst$$Register, $mem$$Address); 5079 %} 5080 5081 ins_pipe(ialu_reg_mem); 5082 %} 5083 5084 // Load Integer (32 bit signed) to Byte (8 bit signed) 5085 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5086 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5087 5088 ins_cost(125); 5089 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5090 ins_encode %{ 5091 __ movsbl($dst$$Register, $mem$$Address); 5092 %} 5093 ins_pipe(ialu_reg_mem); 5094 %} 5095 5096 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5097 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5098 match(Set dst (AndI (LoadI mem) mask)); 5099 5100 ins_cost(125); 5101 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5102 ins_encode %{ 5103 __ movzbl($dst$$Register, $mem$$Address); 5104 %} 5105 ins_pipe(ialu_reg_mem); 5106 %} 5107 5108 // Load Integer (32 bit signed) to Short (16 bit signed) 5109 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5110 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5111 5112 ins_cost(125); 5113 format %{ "movswl $dst, $mem\t# int -> short" %} 5114 ins_encode %{ 5115 __ movswl($dst$$Register, $mem$$Address); 5116 %} 5117 ins_pipe(ialu_reg_mem); 5118 %} 5119 5120 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5121 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5122 match(Set dst (AndI (LoadI mem) mask)); 5123 5124 ins_cost(125); 5125 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5126 ins_encode %{ 5127 __ movzwl($dst$$Register, $mem$$Address); 5128 %} 5129 ins_pipe(ialu_reg_mem); 5130 %} 5131 5132 // Load Integer into Long Register 5133 instruct loadI2L(rRegL dst, memory mem) 5134 %{ 5135 match(Set dst (ConvI2L (LoadI mem))); 5136 5137 ins_cost(125); 5138 format %{ "movslq $dst, $mem\t# int -> long" %} 5139 5140 ins_encode %{ 5141 __ movslq($dst$$Register, $mem$$Address); 5142 %} 5143 5144 ins_pipe(ialu_reg_mem); 5145 %} 5146 5147 // Load Integer with mask 0xFF into Long Register 5148 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5149 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5150 5151 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5152 ins_encode %{ 5153 __ movzbq($dst$$Register, $mem$$Address); 5154 %} 5155 ins_pipe(ialu_reg_mem); 5156 %} 5157 5158 // Load Integer with mask 0xFFFF into Long Register 5159 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5160 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5161 5162 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5163 ins_encode %{ 5164 __ movzwq($dst$$Register, $mem$$Address); 5165 %} 5166 ins_pipe(ialu_reg_mem); 5167 %} 5168 5169 // Load Integer with a 31-bit mask into Long Register 5170 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5171 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5172 effect(KILL cr); 5173 5174 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5175 "andl $dst, $mask" %} 5176 ins_encode %{ 5177 Register Rdst = $dst$$Register; 5178 __ movl(Rdst, $mem$$Address); 5179 __ andl(Rdst, $mask$$constant); 5180 %} 5181 ins_pipe(ialu_reg_mem); 5182 %} 5183 5184 // Load Unsigned Integer into Long Register 5185 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5186 %{ 5187 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5188 5189 ins_cost(125); 5190 format %{ "movl $dst, $mem\t# uint -> long" %} 5191 5192 ins_encode %{ 5193 __ movl($dst$$Register, $mem$$Address); 5194 %} 5195 5196 ins_pipe(ialu_reg_mem); 5197 %} 5198 5199 // Load Long 5200 instruct loadL(rRegL dst, memory mem) 5201 %{ 5202 match(Set dst (LoadL mem)); 5203 5204 ins_cost(125); 5205 format %{ "movq $dst, $mem\t# long" %} 5206 5207 ins_encode %{ 5208 __ movq($dst$$Register, $mem$$Address); 5209 %} 5210 5211 ins_pipe(ialu_reg_mem); // XXX 5212 %} 5213 5214 // Load Range 5215 instruct loadRange(rRegI dst, memory mem) 5216 %{ 5217 match(Set dst (LoadRange mem)); 5218 5219 ins_cost(125); // XXX 5220 format %{ "movl $dst, $mem\t# range" %} 5221 opcode(0x8B); 5222 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5223 ins_pipe(ialu_reg_mem); 5224 %} 5225 5226 // Load Pointer 5227 instruct loadP(rRegP dst, memory mem) 5228 %{ 5229 match(Set dst (LoadP mem)); 5230 5231 ins_cost(125); // XXX 5232 format %{ "movq $dst, $mem\t# ptr" %} 5233 opcode(0x8B); 5234 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5235 ins_pipe(ialu_reg_mem); // XXX 5236 %} 5237 5238 // Load Compressed Pointer 5239 instruct loadN(rRegN dst, memory mem) 5240 %{ 5241 match(Set dst (LoadN mem)); 5242 5243 ins_cost(125); // XXX 5244 format %{ "movl $dst, $mem\t# compressed ptr" %} 5245 ins_encode %{ 5246 __ movl($dst$$Register, $mem$$Address); 5247 %} 5248 ins_pipe(ialu_reg_mem); // XXX 5249 %} 5250 5251 5252 // Load Klass Pointer 5253 instruct loadKlass(rRegP dst, memory mem) 5254 %{ 5255 match(Set dst (LoadKlass mem)); 5256 5257 ins_cost(125); // XXX 5258 format %{ "movq $dst, $mem\t# class" %} 5259 opcode(0x8B); 5260 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5261 ins_pipe(ialu_reg_mem); // XXX 5262 %} 5263 5264 // Load narrow Klass Pointer 5265 instruct loadNKlass(rRegN dst, memory mem) 5266 %{ 5267 match(Set dst (LoadNKlass mem)); 5268 5269 ins_cost(125); // XXX 5270 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5271 ins_encode %{ 5272 __ movl($dst$$Register, $mem$$Address); 5273 %} 5274 ins_pipe(ialu_reg_mem); // XXX 5275 %} 5276 5277 // Load Float 5278 instruct loadF(regF dst, memory mem) 5279 %{ 5280 match(Set dst (LoadF mem)); 5281 5282 ins_cost(145); // XXX 5283 format %{ "movss $dst, $mem\t# float" %} 5284 ins_encode %{ 5285 __ movflt($dst$$XMMRegister, $mem$$Address); 5286 %} 5287 ins_pipe(pipe_slow); // XXX 5288 %} 5289 5290 // Load Double 5291 instruct loadD_partial(regD dst, memory mem) 5292 %{ 5293 predicate(!UseXmmLoadAndClearUpper); 5294 match(Set dst (LoadD mem)); 5295 5296 ins_cost(145); // XXX 5297 format %{ "movlpd $dst, $mem\t# double" %} 5298 ins_encode %{ 5299 __ movdbl($dst$$XMMRegister, $mem$$Address); 5300 %} 5301 ins_pipe(pipe_slow); // XXX 5302 %} 5303 5304 instruct loadD(regD dst, memory mem) 5305 %{ 5306 predicate(UseXmmLoadAndClearUpper); 5307 match(Set dst (LoadD mem)); 5308 5309 ins_cost(145); // XXX 5310 format %{ "movsd $dst, $mem\t# double" %} 5311 ins_encode %{ 5312 __ movdbl($dst$$XMMRegister, $mem$$Address); 5313 %} 5314 ins_pipe(pipe_slow); // XXX 5315 %} 5316 5317 // Load Effective Address 5318 instruct leaP8(rRegP dst, indOffset8 mem) 5319 %{ 5320 match(Set dst mem); 5321 5322 ins_cost(110); // XXX 5323 format %{ "leaq $dst, $mem\t# ptr 8" %} 5324 opcode(0x8D); 5325 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5326 ins_pipe(ialu_reg_reg_fat); 5327 %} 5328 5329 instruct leaP32(rRegP dst, indOffset32 mem) 5330 %{ 5331 match(Set dst mem); 5332 5333 ins_cost(110); 5334 format %{ "leaq $dst, $mem\t# ptr 32" %} 5335 opcode(0x8D); 5336 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5337 ins_pipe(ialu_reg_reg_fat); 5338 %} 5339 5340 // instruct leaPIdx(rRegP dst, indIndex mem) 5341 // %{ 5342 // match(Set dst mem); 5343 5344 // ins_cost(110); 5345 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5346 // opcode(0x8D); 5347 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5348 // ins_pipe(ialu_reg_reg_fat); 5349 // %} 5350 5351 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5352 %{ 5353 match(Set dst mem); 5354 5355 ins_cost(110); 5356 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5357 opcode(0x8D); 5358 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5359 ins_pipe(ialu_reg_reg_fat); 5360 %} 5361 5362 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5363 %{ 5364 match(Set dst mem); 5365 5366 ins_cost(110); 5367 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5368 opcode(0x8D); 5369 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5370 ins_pipe(ialu_reg_reg_fat); 5371 %} 5372 5373 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5374 %{ 5375 match(Set dst mem); 5376 5377 ins_cost(110); 5378 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5379 opcode(0x8D); 5380 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5381 ins_pipe(ialu_reg_reg_fat); 5382 %} 5383 5384 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5385 %{ 5386 match(Set dst mem); 5387 5388 ins_cost(110); 5389 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5390 opcode(0x8D); 5391 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5392 ins_pipe(ialu_reg_reg_fat); 5393 %} 5394 5395 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5396 %{ 5397 match(Set dst mem); 5398 5399 ins_cost(110); 5400 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5401 opcode(0x8D); 5402 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5403 ins_pipe(ialu_reg_reg_fat); 5404 %} 5405 5406 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5407 %{ 5408 match(Set dst mem); 5409 5410 ins_cost(110); 5411 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5412 opcode(0x8D); 5413 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5414 ins_pipe(ialu_reg_reg_fat); 5415 %} 5416 5417 // Load Effective Address which uses Narrow (32-bits) oop 5418 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5419 %{ 5420 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5421 match(Set dst mem); 5422 5423 ins_cost(110); 5424 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5425 opcode(0x8D); 5426 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5427 ins_pipe(ialu_reg_reg_fat); 5428 %} 5429 5430 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5431 %{ 5432 predicate(Universe::narrow_oop_shift() == 0); 5433 match(Set dst mem); 5434 5435 ins_cost(110); // XXX 5436 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5437 opcode(0x8D); 5438 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5439 ins_pipe(ialu_reg_reg_fat); 5440 %} 5441 5442 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5443 %{ 5444 predicate(Universe::narrow_oop_shift() == 0); 5445 match(Set dst mem); 5446 5447 ins_cost(110); 5448 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5449 opcode(0x8D); 5450 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5451 ins_pipe(ialu_reg_reg_fat); 5452 %} 5453 5454 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5455 %{ 5456 predicate(Universe::narrow_oop_shift() == 0); 5457 match(Set dst mem); 5458 5459 ins_cost(110); 5460 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5461 opcode(0x8D); 5462 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5463 ins_pipe(ialu_reg_reg_fat); 5464 %} 5465 5466 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5467 %{ 5468 predicate(Universe::narrow_oop_shift() == 0); 5469 match(Set dst mem); 5470 5471 ins_cost(110); 5472 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5473 opcode(0x8D); 5474 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5475 ins_pipe(ialu_reg_reg_fat); 5476 %} 5477 5478 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5479 %{ 5480 predicate(Universe::narrow_oop_shift() == 0); 5481 match(Set dst mem); 5482 5483 ins_cost(110); 5484 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5485 opcode(0x8D); 5486 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5487 ins_pipe(ialu_reg_reg_fat); 5488 %} 5489 5490 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5491 %{ 5492 predicate(Universe::narrow_oop_shift() == 0); 5493 match(Set dst mem); 5494 5495 ins_cost(110); 5496 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5497 opcode(0x8D); 5498 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5499 ins_pipe(ialu_reg_reg_fat); 5500 %} 5501 5502 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5503 %{ 5504 predicate(Universe::narrow_oop_shift() == 0); 5505 match(Set dst mem); 5506 5507 ins_cost(110); 5508 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5509 opcode(0x8D); 5510 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5511 ins_pipe(ialu_reg_reg_fat); 5512 %} 5513 5514 instruct loadConI(rRegI dst, immI src) 5515 %{ 5516 match(Set dst src); 5517 5518 format %{ "movl $dst, $src\t# int" %} 5519 ins_encode(load_immI(dst, src)); 5520 ins_pipe(ialu_reg_fat); // XXX 5521 %} 5522 5523 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5524 %{ 5525 match(Set dst src); 5526 effect(KILL cr); 5527 5528 ins_cost(50); 5529 format %{ "xorl $dst, $dst\t# int" %} 5530 opcode(0x33); /* + rd */ 5531 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5532 ins_pipe(ialu_reg); 5533 %} 5534 5535 instruct loadConL(rRegL dst, immL src) 5536 %{ 5537 match(Set dst src); 5538 5539 ins_cost(150); 5540 format %{ "movq $dst, $src\t# long" %} 5541 ins_encode(load_immL(dst, src)); 5542 ins_pipe(ialu_reg); 5543 %} 5544 5545 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5546 %{ 5547 match(Set dst src); 5548 effect(KILL cr); 5549 5550 ins_cost(50); 5551 format %{ "xorl $dst, $dst\t# long" %} 5552 opcode(0x33); /* + rd */ 5553 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5554 ins_pipe(ialu_reg); // XXX 5555 %} 5556 5557 instruct loadConUL32(rRegL dst, immUL32 src) 5558 %{ 5559 match(Set dst src); 5560 5561 ins_cost(60); 5562 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5563 ins_encode(load_immUL32(dst, src)); 5564 ins_pipe(ialu_reg); 5565 %} 5566 5567 instruct loadConL32(rRegL dst, immL32 src) 5568 %{ 5569 match(Set dst src); 5570 5571 ins_cost(70); 5572 format %{ "movq $dst, $src\t# long (32-bit)" %} 5573 ins_encode(load_immL32(dst, src)); 5574 ins_pipe(ialu_reg); 5575 %} 5576 5577 instruct loadConP(rRegP dst, immP con) %{ 5578 match(Set dst con); 5579 5580 format %{ "movq $dst, $con\t# ptr" %} 5581 ins_encode(load_immP(dst, con)); 5582 ins_pipe(ialu_reg_fat); // XXX 5583 %} 5584 5585 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5586 %{ 5587 match(Set dst src); 5588 effect(KILL cr); 5589 5590 ins_cost(50); 5591 format %{ "xorl $dst, $dst\t# ptr" %} 5592 opcode(0x33); /* + rd */ 5593 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5594 ins_pipe(ialu_reg); 5595 %} 5596 5597 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5598 %{ 5599 match(Set dst src); 5600 effect(KILL cr); 5601 5602 ins_cost(60); 5603 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5604 ins_encode(load_immP31(dst, src)); 5605 ins_pipe(ialu_reg); 5606 %} 5607 5608 instruct loadConF(regF dst, immF con) %{ 5609 match(Set dst con); 5610 ins_cost(125); 5611 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5612 ins_encode %{ 5613 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5614 %} 5615 ins_pipe(pipe_slow); 5616 %} 5617 5618 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5619 match(Set dst src); 5620 effect(KILL cr); 5621 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5622 ins_encode %{ 5623 __ xorq($dst$$Register, $dst$$Register); 5624 %} 5625 ins_pipe(ialu_reg); 5626 %} 5627 5628 instruct loadConN(rRegN dst, immN src) %{ 5629 match(Set dst src); 5630 5631 ins_cost(125); 5632 format %{ "movl $dst, $src\t# compressed ptr" %} 5633 ins_encode %{ 5634 address con = (address)$src$$constant; 5635 if (con == NULL) { 5636 ShouldNotReachHere(); 5637 } else { 5638 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5639 } 5640 %} 5641 ins_pipe(ialu_reg_fat); // XXX 5642 %} 5643 5644 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5645 match(Set dst src); 5646 5647 ins_cost(125); 5648 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5649 ins_encode %{ 5650 address con = (address)$src$$constant; 5651 if (con == NULL) { 5652 ShouldNotReachHere(); 5653 } else { 5654 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5655 } 5656 %} 5657 ins_pipe(ialu_reg_fat); // XXX 5658 %} 5659 5660 instruct loadConF0(regF dst, immF0 src) 5661 %{ 5662 match(Set dst src); 5663 ins_cost(100); 5664 5665 format %{ "xorps $dst, $dst\t# float 0.0" %} 5666 ins_encode %{ 5667 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5668 %} 5669 ins_pipe(pipe_slow); 5670 %} 5671 5672 // Use the same format since predicate() can not be used here. 5673 instruct loadConD(regD dst, immD con) %{ 5674 match(Set dst con); 5675 ins_cost(125); 5676 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5677 ins_encode %{ 5678 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5679 %} 5680 ins_pipe(pipe_slow); 5681 %} 5682 5683 instruct loadConD0(regD dst, immD0 src) 5684 %{ 5685 match(Set dst src); 5686 ins_cost(100); 5687 5688 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5689 ins_encode %{ 5690 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5691 %} 5692 ins_pipe(pipe_slow); 5693 %} 5694 5695 instruct loadSSI(rRegI dst, stackSlotI src) 5696 %{ 5697 match(Set dst src); 5698 5699 ins_cost(125); 5700 format %{ "movl $dst, $src\t# int stk" %} 5701 opcode(0x8B); 5702 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5703 ins_pipe(ialu_reg_mem); 5704 %} 5705 5706 instruct loadSSL(rRegL dst, stackSlotL src) 5707 %{ 5708 match(Set dst src); 5709 5710 ins_cost(125); 5711 format %{ "movq $dst, $src\t# long stk" %} 5712 opcode(0x8B); 5713 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5714 ins_pipe(ialu_reg_mem); 5715 %} 5716 5717 instruct loadSSP(rRegP dst, stackSlotP src) 5718 %{ 5719 match(Set dst src); 5720 5721 ins_cost(125); 5722 format %{ "movq $dst, $src\t# ptr stk" %} 5723 opcode(0x8B); 5724 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5725 ins_pipe(ialu_reg_mem); 5726 %} 5727 5728 instruct loadSSF(regF dst, stackSlotF src) 5729 %{ 5730 match(Set dst src); 5731 5732 ins_cost(125); 5733 format %{ "movss $dst, $src\t# float stk" %} 5734 ins_encode %{ 5735 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5736 %} 5737 ins_pipe(pipe_slow); // XXX 5738 %} 5739 5740 // Use the same format since predicate() can not be used here. 5741 instruct loadSSD(regD dst, stackSlotD src) 5742 %{ 5743 match(Set dst src); 5744 5745 ins_cost(125); 5746 format %{ "movsd $dst, $src\t# double stk" %} 5747 ins_encode %{ 5748 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5749 %} 5750 ins_pipe(pipe_slow); // XXX 5751 %} 5752 5753 // Prefetch instructions for allocation. 5754 // Must be safe to execute with invalid address (cannot fault). 5755 5756 instruct prefetchAlloc( memory mem ) %{ 5757 predicate(AllocatePrefetchInstr==3); 5758 match(PrefetchAllocation mem); 5759 ins_cost(125); 5760 5761 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5762 ins_encode %{ 5763 __ prefetchw($mem$$Address); 5764 %} 5765 ins_pipe(ialu_mem); 5766 %} 5767 5768 instruct prefetchAllocNTA( memory mem ) %{ 5769 predicate(AllocatePrefetchInstr==0); 5770 match(PrefetchAllocation mem); 5771 ins_cost(125); 5772 5773 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5774 ins_encode %{ 5775 __ prefetchnta($mem$$Address); 5776 %} 5777 ins_pipe(ialu_mem); 5778 %} 5779 5780 instruct prefetchAllocT0( memory mem ) %{ 5781 predicate(AllocatePrefetchInstr==1); 5782 match(PrefetchAllocation mem); 5783 ins_cost(125); 5784 5785 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5786 ins_encode %{ 5787 __ prefetcht0($mem$$Address); 5788 %} 5789 ins_pipe(ialu_mem); 5790 %} 5791 5792 instruct prefetchAllocT2( memory mem ) %{ 5793 predicate(AllocatePrefetchInstr==2); 5794 match(PrefetchAllocation mem); 5795 ins_cost(125); 5796 5797 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5798 ins_encode %{ 5799 __ prefetcht2($mem$$Address); 5800 %} 5801 ins_pipe(ialu_mem); 5802 %} 5803 5804 //----------Store Instructions------------------------------------------------- 5805 5806 // Store Byte 5807 instruct storeB(memory mem, rRegI src) 5808 %{ 5809 match(Set mem (StoreB mem src)); 5810 5811 ins_cost(125); // XXX 5812 format %{ "movb $mem, $src\t# byte" %} 5813 opcode(0x88); 5814 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5815 ins_pipe(ialu_mem_reg); 5816 %} 5817 5818 // Store Char/Short 5819 instruct storeC(memory mem, rRegI src) 5820 %{ 5821 match(Set mem (StoreC mem src)); 5822 5823 ins_cost(125); // XXX 5824 format %{ "movw $mem, $src\t# char/short" %} 5825 opcode(0x89); 5826 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5827 ins_pipe(ialu_mem_reg); 5828 %} 5829 5830 // Store Integer 5831 instruct storeI(memory mem, rRegI src) 5832 %{ 5833 match(Set mem (StoreI mem src)); 5834 5835 ins_cost(125); // XXX 5836 format %{ "movl $mem, $src\t# int" %} 5837 opcode(0x89); 5838 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5839 ins_pipe(ialu_mem_reg); 5840 %} 5841 5842 // Store Long 5843 instruct storeL(memory mem, rRegL src) 5844 %{ 5845 match(Set mem (StoreL mem src)); 5846 5847 ins_cost(125); // XXX 5848 format %{ "movq $mem, $src\t# long" %} 5849 opcode(0x89); 5850 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5851 ins_pipe(ialu_mem_reg); // XXX 5852 %} 5853 5854 // Store Pointer 5855 instruct storeP(memory mem, any_RegP src) 5856 %{ 5857 match(Set mem (StoreP mem src)); 5858 5859 ins_cost(125); // XXX 5860 format %{ "movq $mem, $src\t# ptr" %} 5861 opcode(0x89); 5862 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5863 ins_pipe(ialu_mem_reg); 5864 %} 5865 5866 instruct storeImmP0(memory mem, immP0 zero) 5867 %{ 5868 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5869 match(Set mem (StoreP mem zero)); 5870 5871 ins_cost(125); // XXX 5872 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5873 ins_encode %{ 5874 __ movq($mem$$Address, r12); 5875 %} 5876 ins_pipe(ialu_mem_reg); 5877 %} 5878 5879 // Store NULL Pointer, mark word, or other simple pointer constant. 5880 instruct storeImmP(memory mem, immP31 src) 5881 %{ 5882 match(Set mem (StoreP mem src)); 5883 5884 ins_cost(150); // XXX 5885 format %{ "movq $mem, $src\t# ptr" %} 5886 opcode(0xC7); /* C7 /0 */ 5887 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5888 ins_pipe(ialu_mem_imm); 5889 %} 5890 5891 // Store Compressed Pointer 5892 instruct storeN(memory mem, rRegN src) 5893 %{ 5894 match(Set mem (StoreN mem src)); 5895 5896 ins_cost(125); // XXX 5897 format %{ "movl $mem, $src\t# compressed ptr" %} 5898 ins_encode %{ 5899 __ movl($mem$$Address, $src$$Register); 5900 %} 5901 ins_pipe(ialu_mem_reg); 5902 %} 5903 5904 instruct storeNKlass(memory mem, rRegN src) 5905 %{ 5906 match(Set mem (StoreNKlass mem src)); 5907 5908 ins_cost(125); // XXX 5909 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5910 ins_encode %{ 5911 __ movl($mem$$Address, $src$$Register); 5912 %} 5913 ins_pipe(ialu_mem_reg); 5914 %} 5915 5916 instruct storeImmN0(memory mem, immN0 zero) 5917 %{ 5918 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5919 match(Set mem (StoreN mem zero)); 5920 5921 ins_cost(125); // XXX 5922 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5923 ins_encode %{ 5924 __ movl($mem$$Address, r12); 5925 %} 5926 ins_pipe(ialu_mem_reg); 5927 %} 5928 5929 instruct storeImmN(memory mem, immN src) 5930 %{ 5931 match(Set mem (StoreN mem src)); 5932 5933 ins_cost(150); // XXX 5934 format %{ "movl $mem, $src\t# compressed ptr" %} 5935 ins_encode %{ 5936 address con = (address)$src$$constant; 5937 if (con == NULL) { 5938 __ movl($mem$$Address, (int32_t)0); 5939 } else { 5940 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5941 } 5942 %} 5943 ins_pipe(ialu_mem_imm); 5944 %} 5945 5946 instruct storeImmNKlass(memory mem, immNKlass src) 5947 %{ 5948 match(Set mem (StoreNKlass mem src)); 5949 5950 ins_cost(150); // XXX 5951 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5952 ins_encode %{ 5953 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5954 %} 5955 ins_pipe(ialu_mem_imm); 5956 %} 5957 5958 // Store Integer Immediate 5959 instruct storeImmI0(memory mem, immI0 zero) 5960 %{ 5961 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5962 match(Set mem (StoreI mem zero)); 5963 5964 ins_cost(125); // XXX 5965 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5966 ins_encode %{ 5967 __ movl($mem$$Address, r12); 5968 %} 5969 ins_pipe(ialu_mem_reg); 5970 %} 5971 5972 instruct storeImmI(memory mem, immI src) 5973 %{ 5974 match(Set mem (StoreI mem src)); 5975 5976 ins_cost(150); 5977 format %{ "movl $mem, $src\t# int" %} 5978 opcode(0xC7); /* C7 /0 */ 5979 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5980 ins_pipe(ialu_mem_imm); 5981 %} 5982 5983 // Store Long Immediate 5984 instruct storeImmL0(memory mem, immL0 zero) 5985 %{ 5986 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5987 match(Set mem (StoreL mem zero)); 5988 5989 ins_cost(125); // XXX 5990 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5991 ins_encode %{ 5992 __ movq($mem$$Address, r12); 5993 %} 5994 ins_pipe(ialu_mem_reg); 5995 %} 5996 5997 instruct storeImmL(memory mem, immL32 src) 5998 %{ 5999 match(Set mem (StoreL mem src)); 6000 6001 ins_cost(150); 6002 format %{ "movq $mem, $src\t# long" %} 6003 opcode(0xC7); /* C7 /0 */ 6004 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6005 ins_pipe(ialu_mem_imm); 6006 %} 6007 6008 // Store Short/Char Immediate 6009 instruct storeImmC0(memory mem, immI0 zero) 6010 %{ 6011 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6012 match(Set mem (StoreC mem zero)); 6013 6014 ins_cost(125); // XXX 6015 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6016 ins_encode %{ 6017 __ movw($mem$$Address, r12); 6018 %} 6019 ins_pipe(ialu_mem_reg); 6020 %} 6021 6022 instruct storeImmI16(memory mem, immI16 src) 6023 %{ 6024 predicate(UseStoreImmI16); 6025 match(Set mem (StoreC mem src)); 6026 6027 ins_cost(150); 6028 format %{ "movw $mem, $src\t# short/char" %} 6029 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6030 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6031 ins_pipe(ialu_mem_imm); 6032 %} 6033 6034 // Store Byte Immediate 6035 instruct storeImmB0(memory mem, immI0 zero) 6036 %{ 6037 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6038 match(Set mem (StoreB mem zero)); 6039 6040 ins_cost(125); // XXX 6041 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6042 ins_encode %{ 6043 __ movb($mem$$Address, r12); 6044 %} 6045 ins_pipe(ialu_mem_reg); 6046 %} 6047 6048 instruct storeImmB(memory mem, immI8 src) 6049 %{ 6050 match(Set mem (StoreB mem src)); 6051 6052 ins_cost(150); // XXX 6053 format %{ "movb $mem, $src\t# byte" %} 6054 opcode(0xC6); /* C6 /0 */ 6055 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6056 ins_pipe(ialu_mem_imm); 6057 %} 6058 6059 // Store CMS card-mark Immediate 6060 instruct storeImmCM0_reg(memory mem, immI0 zero) 6061 %{ 6062 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6063 match(Set mem (StoreCM mem zero)); 6064 6065 ins_cost(125); // XXX 6066 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6067 ins_encode %{ 6068 __ movb($mem$$Address, r12); 6069 %} 6070 ins_pipe(ialu_mem_reg); 6071 %} 6072 6073 instruct storeImmCM0(memory mem, immI0 src) 6074 %{ 6075 match(Set mem (StoreCM mem src)); 6076 6077 ins_cost(150); // XXX 6078 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6079 opcode(0xC6); /* C6 /0 */ 6080 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6081 ins_pipe(ialu_mem_imm); 6082 %} 6083 6084 // Store Float 6085 instruct storeF(memory mem, regF src) 6086 %{ 6087 match(Set mem (StoreF mem src)); 6088 6089 ins_cost(95); // XXX 6090 format %{ "movss $mem, $src\t# float" %} 6091 ins_encode %{ 6092 __ movflt($mem$$Address, $src$$XMMRegister); 6093 %} 6094 ins_pipe(pipe_slow); // XXX 6095 %} 6096 6097 // Store immediate Float value (it is faster than store from XMM register) 6098 instruct storeF0(memory mem, immF0 zero) 6099 %{ 6100 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6101 match(Set mem (StoreF mem zero)); 6102 6103 ins_cost(25); // XXX 6104 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6105 ins_encode %{ 6106 __ movl($mem$$Address, r12); 6107 %} 6108 ins_pipe(ialu_mem_reg); 6109 %} 6110 6111 instruct storeF_imm(memory mem, immF src) 6112 %{ 6113 match(Set mem (StoreF mem src)); 6114 6115 ins_cost(50); 6116 format %{ "movl $mem, $src\t# float" %} 6117 opcode(0xC7); /* C7 /0 */ 6118 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6119 ins_pipe(ialu_mem_imm); 6120 %} 6121 6122 // Store Double 6123 instruct storeD(memory mem, regD src) 6124 %{ 6125 match(Set mem (StoreD mem src)); 6126 6127 ins_cost(95); // XXX 6128 format %{ "movsd $mem, $src\t# double" %} 6129 ins_encode %{ 6130 __ movdbl($mem$$Address, $src$$XMMRegister); 6131 %} 6132 ins_pipe(pipe_slow); // XXX 6133 %} 6134 6135 // Store immediate double 0.0 (it is faster than store from XMM register) 6136 instruct storeD0_imm(memory mem, immD0 src) 6137 %{ 6138 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6139 match(Set mem (StoreD mem src)); 6140 6141 ins_cost(50); 6142 format %{ "movq $mem, $src\t# double 0." %} 6143 opcode(0xC7); /* C7 /0 */ 6144 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6145 ins_pipe(ialu_mem_imm); 6146 %} 6147 6148 instruct storeD0(memory mem, immD0 zero) 6149 %{ 6150 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6151 match(Set mem (StoreD mem zero)); 6152 6153 ins_cost(25); // XXX 6154 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6155 ins_encode %{ 6156 __ movq($mem$$Address, r12); 6157 %} 6158 ins_pipe(ialu_mem_reg); 6159 %} 6160 6161 instruct storeSSI(stackSlotI dst, rRegI src) 6162 %{ 6163 match(Set dst src); 6164 6165 ins_cost(100); 6166 format %{ "movl $dst, $src\t# int stk" %} 6167 opcode(0x89); 6168 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6169 ins_pipe( ialu_mem_reg ); 6170 %} 6171 6172 instruct storeSSL(stackSlotL dst, rRegL src) 6173 %{ 6174 match(Set dst src); 6175 6176 ins_cost(100); 6177 format %{ "movq $dst, $src\t# long stk" %} 6178 opcode(0x89); 6179 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6180 ins_pipe(ialu_mem_reg); 6181 %} 6182 6183 instruct storeSSP(stackSlotP dst, rRegP src) 6184 %{ 6185 match(Set dst src); 6186 6187 ins_cost(100); 6188 format %{ "movq $dst, $src\t# ptr stk" %} 6189 opcode(0x89); 6190 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6191 ins_pipe(ialu_mem_reg); 6192 %} 6193 6194 instruct storeSSF(stackSlotF dst, regF src) 6195 %{ 6196 match(Set dst src); 6197 6198 ins_cost(95); // XXX 6199 format %{ "movss $dst, $src\t# float stk" %} 6200 ins_encode %{ 6201 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6202 %} 6203 ins_pipe(pipe_slow); // XXX 6204 %} 6205 6206 instruct storeSSD(stackSlotD dst, regD src) 6207 %{ 6208 match(Set dst src); 6209 6210 ins_cost(95); // XXX 6211 format %{ "movsd $dst, $src\t# double stk" %} 6212 ins_encode %{ 6213 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6214 %} 6215 ins_pipe(pipe_slow); // XXX 6216 %} 6217 6218 //----------BSWAP Instructions------------------------------------------------- 6219 instruct bytes_reverse_int(rRegI dst) %{ 6220 match(Set dst (ReverseBytesI dst)); 6221 6222 format %{ "bswapl $dst" %} 6223 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6224 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6225 ins_pipe( ialu_reg ); 6226 %} 6227 6228 instruct bytes_reverse_long(rRegL dst) %{ 6229 match(Set dst (ReverseBytesL dst)); 6230 6231 format %{ "bswapq $dst" %} 6232 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6233 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6234 ins_pipe( ialu_reg); 6235 %} 6236 6237 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6238 match(Set dst (ReverseBytesUS dst)); 6239 effect(KILL cr); 6240 6241 format %{ "bswapl $dst\n\t" 6242 "shrl $dst,16\n\t" %} 6243 ins_encode %{ 6244 __ bswapl($dst$$Register); 6245 __ shrl($dst$$Register, 16); 6246 %} 6247 ins_pipe( ialu_reg ); 6248 %} 6249 6250 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6251 match(Set dst (ReverseBytesS dst)); 6252 effect(KILL cr); 6253 6254 format %{ "bswapl $dst\n\t" 6255 "sar $dst,16\n\t" %} 6256 ins_encode %{ 6257 __ bswapl($dst$$Register); 6258 __ sarl($dst$$Register, 16); 6259 %} 6260 ins_pipe( ialu_reg ); 6261 %} 6262 6263 //---------- Zeros Count Instructions ------------------------------------------ 6264 6265 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6266 predicate(UseCountLeadingZerosInstruction); 6267 match(Set dst (CountLeadingZerosI src)); 6268 effect(KILL cr); 6269 6270 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6271 ins_encode %{ 6272 __ lzcntl($dst$$Register, $src$$Register); 6273 %} 6274 ins_pipe(ialu_reg); 6275 %} 6276 6277 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6278 predicate(!UseCountLeadingZerosInstruction); 6279 match(Set dst (CountLeadingZerosI src)); 6280 effect(KILL cr); 6281 6282 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6283 "jnz skip\n\t" 6284 "movl $dst, -1\n" 6285 "skip:\n\t" 6286 "negl $dst\n\t" 6287 "addl $dst, 31" %} 6288 ins_encode %{ 6289 Register Rdst = $dst$$Register; 6290 Register Rsrc = $src$$Register; 6291 Label skip; 6292 __ bsrl(Rdst, Rsrc); 6293 __ jccb(Assembler::notZero, skip); 6294 __ movl(Rdst, -1); 6295 __ bind(skip); 6296 __ negl(Rdst); 6297 __ addl(Rdst, BitsPerInt - 1); 6298 %} 6299 ins_pipe(ialu_reg); 6300 %} 6301 6302 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6303 predicate(UseCountLeadingZerosInstruction); 6304 match(Set dst (CountLeadingZerosL src)); 6305 effect(KILL cr); 6306 6307 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6308 ins_encode %{ 6309 __ lzcntq($dst$$Register, $src$$Register); 6310 %} 6311 ins_pipe(ialu_reg); 6312 %} 6313 6314 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6315 predicate(!UseCountLeadingZerosInstruction); 6316 match(Set dst (CountLeadingZerosL src)); 6317 effect(KILL cr); 6318 6319 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6320 "jnz skip\n\t" 6321 "movl $dst, -1\n" 6322 "skip:\n\t" 6323 "negl $dst\n\t" 6324 "addl $dst, 63" %} 6325 ins_encode %{ 6326 Register Rdst = $dst$$Register; 6327 Register Rsrc = $src$$Register; 6328 Label skip; 6329 __ bsrq(Rdst, Rsrc); 6330 __ jccb(Assembler::notZero, skip); 6331 __ movl(Rdst, -1); 6332 __ bind(skip); 6333 __ negl(Rdst); 6334 __ addl(Rdst, BitsPerLong - 1); 6335 %} 6336 ins_pipe(ialu_reg); 6337 %} 6338 6339 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6340 predicate(UseCountTrailingZerosInstruction); 6341 match(Set dst (CountTrailingZerosI src)); 6342 effect(KILL cr); 6343 6344 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6345 ins_encode %{ 6346 __ tzcntl($dst$$Register, $src$$Register); 6347 %} 6348 ins_pipe(ialu_reg); 6349 %} 6350 6351 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6352 predicate(!UseCountTrailingZerosInstruction); 6353 match(Set dst (CountTrailingZerosI src)); 6354 effect(KILL cr); 6355 6356 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6357 "jnz done\n\t" 6358 "movl $dst, 32\n" 6359 "done:" %} 6360 ins_encode %{ 6361 Register Rdst = $dst$$Register; 6362 Label done; 6363 __ bsfl(Rdst, $src$$Register); 6364 __ jccb(Assembler::notZero, done); 6365 __ movl(Rdst, BitsPerInt); 6366 __ bind(done); 6367 %} 6368 ins_pipe(ialu_reg); 6369 %} 6370 6371 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6372 predicate(UseCountTrailingZerosInstruction); 6373 match(Set dst (CountTrailingZerosL src)); 6374 effect(KILL cr); 6375 6376 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6377 ins_encode %{ 6378 __ tzcntq($dst$$Register, $src$$Register); 6379 %} 6380 ins_pipe(ialu_reg); 6381 %} 6382 6383 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6384 predicate(!UseCountTrailingZerosInstruction); 6385 match(Set dst (CountTrailingZerosL src)); 6386 effect(KILL cr); 6387 6388 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6389 "jnz done\n\t" 6390 "movl $dst, 64\n" 6391 "done:" %} 6392 ins_encode %{ 6393 Register Rdst = $dst$$Register; 6394 Label done; 6395 __ bsfq(Rdst, $src$$Register); 6396 __ jccb(Assembler::notZero, done); 6397 __ movl(Rdst, BitsPerLong); 6398 __ bind(done); 6399 %} 6400 ins_pipe(ialu_reg); 6401 %} 6402 6403 6404 //---------- Population Count Instructions ------------------------------------- 6405 6406 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6407 predicate(UsePopCountInstruction); 6408 match(Set dst (PopCountI src)); 6409 effect(KILL cr); 6410 6411 format %{ "popcnt $dst, $src" %} 6412 ins_encode %{ 6413 __ popcntl($dst$$Register, $src$$Register); 6414 %} 6415 ins_pipe(ialu_reg); 6416 %} 6417 6418 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6419 predicate(UsePopCountInstruction); 6420 match(Set dst (PopCountI (LoadI mem))); 6421 effect(KILL cr); 6422 6423 format %{ "popcnt $dst, $mem" %} 6424 ins_encode %{ 6425 __ popcntl($dst$$Register, $mem$$Address); 6426 %} 6427 ins_pipe(ialu_reg); 6428 %} 6429 6430 // Note: Long.bitCount(long) returns an int. 6431 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6432 predicate(UsePopCountInstruction); 6433 match(Set dst (PopCountL src)); 6434 effect(KILL cr); 6435 6436 format %{ "popcnt $dst, $src" %} 6437 ins_encode %{ 6438 __ popcntq($dst$$Register, $src$$Register); 6439 %} 6440 ins_pipe(ialu_reg); 6441 %} 6442 6443 // Note: Long.bitCount(long) returns an int. 6444 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6445 predicate(UsePopCountInstruction); 6446 match(Set dst (PopCountL (LoadL mem))); 6447 effect(KILL cr); 6448 6449 format %{ "popcnt $dst, $mem" %} 6450 ins_encode %{ 6451 __ popcntq($dst$$Register, $mem$$Address); 6452 %} 6453 ins_pipe(ialu_reg); 6454 %} 6455 6456 6457 //----------MemBar Instructions----------------------------------------------- 6458 // Memory barrier flavors 6459 6460 instruct membar_acquire() 6461 %{ 6462 match(MemBarAcquire); 6463 match(LoadFence); 6464 ins_cost(0); 6465 6466 size(0); 6467 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6468 ins_encode(); 6469 ins_pipe(empty); 6470 %} 6471 6472 instruct membar_acquire_lock() 6473 %{ 6474 match(MemBarAcquireLock); 6475 ins_cost(0); 6476 6477 size(0); 6478 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6479 ins_encode(); 6480 ins_pipe(empty); 6481 %} 6482 6483 instruct membar_release() 6484 %{ 6485 match(MemBarRelease); 6486 match(StoreFence); 6487 ins_cost(0); 6488 6489 size(0); 6490 format %{ "MEMBAR-release ! (empty encoding)" %} 6491 ins_encode(); 6492 ins_pipe(empty); 6493 %} 6494 6495 instruct membar_release_lock() 6496 %{ 6497 match(MemBarReleaseLock); 6498 ins_cost(0); 6499 6500 size(0); 6501 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6502 ins_encode(); 6503 ins_pipe(empty); 6504 %} 6505 6506 instruct membar_volatile(rFlagsReg cr) %{ 6507 match(MemBarVolatile); 6508 effect(KILL cr); 6509 ins_cost(400); 6510 6511 format %{ 6512 $$template 6513 if (os::is_MP()) { 6514 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6515 } else { 6516 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6517 } 6518 %} 6519 ins_encode %{ 6520 __ membar(Assembler::StoreLoad); 6521 %} 6522 ins_pipe(pipe_slow); 6523 %} 6524 6525 instruct unnecessary_membar_volatile() 6526 %{ 6527 match(MemBarVolatile); 6528 predicate(Matcher::post_store_load_barrier(n)); 6529 ins_cost(0); 6530 6531 size(0); 6532 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6533 ins_encode(); 6534 ins_pipe(empty); 6535 %} 6536 6537 instruct membar_storestore() %{ 6538 match(MemBarStoreStore); 6539 ins_cost(0); 6540 6541 size(0); 6542 format %{ "MEMBAR-storestore (empty encoding)" %} 6543 ins_encode( ); 6544 ins_pipe(empty); 6545 %} 6546 6547 //----------Move Instructions-------------------------------------------------- 6548 6549 instruct castX2P(rRegP dst, rRegL src) 6550 %{ 6551 match(Set dst (CastX2P src)); 6552 6553 format %{ "movq $dst, $src\t# long->ptr" %} 6554 ins_encode %{ 6555 if ($dst$$reg != $src$$reg) { 6556 __ movptr($dst$$Register, $src$$Register); 6557 } 6558 %} 6559 ins_pipe(ialu_reg_reg); // XXX 6560 %} 6561 6562 instruct castN2X(rRegL dst, rRegN src) 6563 %{ 6564 match(Set dst (CastP2X src)); 6565 6566 format %{ "movq $dst, $src\t# ptr -> long" %} 6567 ins_encode %{ 6568 if ($dst$$reg != $src$$reg) { 6569 __ movptr($dst$$Register, $src$$Register); 6570 } 6571 %} 6572 ins_pipe(ialu_reg_reg); // XXX 6573 %} 6574 6575 instruct castP2X(rRegL dst, rRegP src) 6576 %{ 6577 match(Set dst (CastP2X src)); 6578 6579 format %{ "movq $dst, $src\t# ptr -> long" %} 6580 ins_encode %{ 6581 if ($dst$$reg != $src$$reg) { 6582 __ movptr($dst$$Register, $src$$Register); 6583 } 6584 %} 6585 ins_pipe(ialu_reg_reg); // XXX 6586 %} 6587 6588 // Convert oop into int for vectors alignment masking 6589 instruct convP2I(rRegI dst, rRegP src) 6590 %{ 6591 match(Set dst (ConvL2I (CastP2X src))); 6592 6593 format %{ "movl $dst, $src\t# ptr -> int" %} 6594 ins_encode %{ 6595 __ movl($dst$$Register, $src$$Register); 6596 %} 6597 ins_pipe(ialu_reg_reg); // XXX 6598 %} 6599 6600 // Convert compressed oop into int for vectors alignment masking 6601 // in case of 32bit oops (heap < 4Gb). 6602 instruct convN2I(rRegI dst, rRegN src) 6603 %{ 6604 predicate(Universe::narrow_oop_shift() == 0); 6605 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6606 6607 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6608 ins_encode %{ 6609 __ movl($dst$$Register, $src$$Register); 6610 %} 6611 ins_pipe(ialu_reg_reg); // XXX 6612 %} 6613 6614 // Convert oop pointer into compressed form 6615 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6616 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6617 match(Set dst (EncodeP src)); 6618 effect(KILL cr); 6619 format %{ "encode_heap_oop $dst,$src" %} 6620 ins_encode %{ 6621 Register s = $src$$Register; 6622 Register d = $dst$$Register; 6623 if (s != d) { 6624 __ movq(d, s); 6625 } 6626 __ encode_heap_oop(d); 6627 %} 6628 ins_pipe(ialu_reg_long); 6629 %} 6630 6631 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6632 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6633 match(Set dst (EncodeP src)); 6634 effect(KILL cr); 6635 format %{ "encode_heap_oop_not_null $dst,$src" %} 6636 ins_encode %{ 6637 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6638 %} 6639 ins_pipe(ialu_reg_long); 6640 %} 6641 6642 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6643 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6644 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6645 match(Set dst (DecodeN src)); 6646 effect(KILL cr); 6647 format %{ "decode_heap_oop $dst,$src" %} 6648 ins_encode %{ 6649 Register s = $src$$Register; 6650 Register d = $dst$$Register; 6651 if (s != d) { 6652 __ movq(d, s); 6653 } 6654 __ decode_heap_oop(d); 6655 %} 6656 ins_pipe(ialu_reg_long); 6657 %} 6658 6659 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6660 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6661 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6662 match(Set dst (DecodeN src)); 6663 effect(KILL cr); 6664 format %{ "decode_heap_oop_not_null $dst,$src" %} 6665 ins_encode %{ 6666 Register s = $src$$Register; 6667 Register d = $dst$$Register; 6668 if (s != d) { 6669 __ decode_heap_oop_not_null(d, s); 6670 } else { 6671 __ decode_heap_oop_not_null(d); 6672 } 6673 %} 6674 ins_pipe(ialu_reg_long); 6675 %} 6676 6677 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6678 match(Set dst (EncodePKlass src)); 6679 effect(KILL cr); 6680 format %{ "encode_klass_not_null $dst,$src" %} 6681 ins_encode %{ 6682 __ encode_klass_not_null($dst$$Register, $src$$Register); 6683 %} 6684 ins_pipe(ialu_reg_long); 6685 %} 6686 6687 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6688 match(Set dst (DecodeNKlass src)); 6689 effect(KILL cr); 6690 format %{ "decode_klass_not_null $dst,$src" %} 6691 ins_encode %{ 6692 Register s = $src$$Register; 6693 Register d = $dst$$Register; 6694 if (s != d) { 6695 __ decode_klass_not_null(d, s); 6696 } else { 6697 __ decode_klass_not_null(d); 6698 } 6699 %} 6700 ins_pipe(ialu_reg_long); 6701 %} 6702 6703 6704 //----------Conditional Move--------------------------------------------------- 6705 // Jump 6706 // dummy instruction for generating temp registers 6707 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6708 match(Jump (LShiftL switch_val shift)); 6709 ins_cost(350); 6710 predicate(false); 6711 effect(TEMP dest); 6712 6713 format %{ "leaq $dest, [$constantaddress]\n\t" 6714 "jmp [$dest + $switch_val << $shift]\n\t" %} 6715 ins_encode %{ 6716 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6717 // to do that and the compiler is using that register as one it can allocate. 6718 // So we build it all by hand. 6719 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6720 // ArrayAddress dispatch(table, index); 6721 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6722 __ lea($dest$$Register, $constantaddress); 6723 __ jmp(dispatch); 6724 %} 6725 ins_pipe(pipe_jmp); 6726 %} 6727 6728 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6729 match(Jump (AddL (LShiftL switch_val shift) offset)); 6730 ins_cost(350); 6731 effect(TEMP dest); 6732 6733 format %{ "leaq $dest, [$constantaddress]\n\t" 6734 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6735 ins_encode %{ 6736 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6737 // to do that and the compiler is using that register as one it can allocate. 6738 // So we build it all by hand. 6739 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6740 // ArrayAddress dispatch(table, index); 6741 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6742 __ lea($dest$$Register, $constantaddress); 6743 __ jmp(dispatch); 6744 %} 6745 ins_pipe(pipe_jmp); 6746 %} 6747 6748 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6749 match(Jump switch_val); 6750 ins_cost(350); 6751 effect(TEMP dest); 6752 6753 format %{ "leaq $dest, [$constantaddress]\n\t" 6754 "jmp [$dest + $switch_val]\n\t" %} 6755 ins_encode %{ 6756 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6757 // to do that and the compiler is using that register as one it can allocate. 6758 // So we build it all by hand. 6759 // Address index(noreg, switch_reg, Address::times_1); 6760 // ArrayAddress dispatch(table, index); 6761 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6762 __ lea($dest$$Register, $constantaddress); 6763 __ jmp(dispatch); 6764 %} 6765 ins_pipe(pipe_jmp); 6766 %} 6767 6768 // Conditional move 6769 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6770 %{ 6771 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6772 6773 ins_cost(200); // XXX 6774 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6775 opcode(0x0F, 0x40); 6776 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6777 ins_pipe(pipe_cmov_reg); 6778 %} 6779 6780 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6781 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6782 6783 ins_cost(200); // XXX 6784 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6785 opcode(0x0F, 0x40); 6786 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6787 ins_pipe(pipe_cmov_reg); 6788 %} 6789 6790 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6791 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6792 ins_cost(200); 6793 expand %{ 6794 cmovI_regU(cop, cr, dst, src); 6795 %} 6796 %} 6797 6798 // Conditional move 6799 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6800 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6801 6802 ins_cost(250); // XXX 6803 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6804 opcode(0x0F, 0x40); 6805 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6806 ins_pipe(pipe_cmov_mem); 6807 %} 6808 6809 // Conditional move 6810 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6811 %{ 6812 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6813 6814 ins_cost(250); // XXX 6815 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6816 opcode(0x0F, 0x40); 6817 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6818 ins_pipe(pipe_cmov_mem); 6819 %} 6820 6821 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6822 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6823 ins_cost(250); 6824 expand %{ 6825 cmovI_memU(cop, cr, dst, src); 6826 %} 6827 %} 6828 6829 // Conditional move 6830 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6831 %{ 6832 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6833 6834 ins_cost(200); // XXX 6835 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6836 opcode(0x0F, 0x40); 6837 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6838 ins_pipe(pipe_cmov_reg); 6839 %} 6840 6841 // Conditional move 6842 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6843 %{ 6844 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6845 6846 ins_cost(200); // XXX 6847 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6848 opcode(0x0F, 0x40); 6849 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6850 ins_pipe(pipe_cmov_reg); 6851 %} 6852 6853 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6854 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6855 ins_cost(200); 6856 expand %{ 6857 cmovN_regU(cop, cr, dst, src); 6858 %} 6859 %} 6860 6861 // Conditional move 6862 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6863 %{ 6864 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6865 6866 ins_cost(200); // XXX 6867 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6868 opcode(0x0F, 0x40); 6869 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6870 ins_pipe(pipe_cmov_reg); // XXX 6871 %} 6872 6873 // Conditional move 6874 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6875 %{ 6876 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6877 6878 ins_cost(200); // XXX 6879 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6880 opcode(0x0F, 0x40); 6881 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6882 ins_pipe(pipe_cmov_reg); // XXX 6883 %} 6884 6885 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6886 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6887 ins_cost(200); 6888 expand %{ 6889 cmovP_regU(cop, cr, dst, src); 6890 %} 6891 %} 6892 6893 // DISABLED: Requires the ADLC to emit a bottom_type call that 6894 // correctly meets the two pointer arguments; one is an incoming 6895 // register but the other is a memory operand. ALSO appears to 6896 // be buggy with implicit null checks. 6897 // 6898 //// Conditional move 6899 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6900 //%{ 6901 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6902 // ins_cost(250); 6903 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6904 // opcode(0x0F,0x40); 6905 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6906 // ins_pipe( pipe_cmov_mem ); 6907 //%} 6908 // 6909 //// Conditional move 6910 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6911 //%{ 6912 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6913 // ins_cost(250); 6914 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6915 // opcode(0x0F,0x40); 6916 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6917 // ins_pipe( pipe_cmov_mem ); 6918 //%} 6919 6920 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6921 %{ 6922 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6923 6924 ins_cost(200); // XXX 6925 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6926 opcode(0x0F, 0x40); 6927 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6928 ins_pipe(pipe_cmov_reg); // XXX 6929 %} 6930 6931 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6932 %{ 6933 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6934 6935 ins_cost(200); // XXX 6936 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6937 opcode(0x0F, 0x40); 6938 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6939 ins_pipe(pipe_cmov_mem); // XXX 6940 %} 6941 6942 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6943 %{ 6944 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6945 6946 ins_cost(200); // XXX 6947 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6948 opcode(0x0F, 0x40); 6949 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6950 ins_pipe(pipe_cmov_reg); // XXX 6951 %} 6952 6953 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6954 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6955 ins_cost(200); 6956 expand %{ 6957 cmovL_regU(cop, cr, dst, src); 6958 %} 6959 %} 6960 6961 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6962 %{ 6963 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6964 6965 ins_cost(200); // XXX 6966 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6967 opcode(0x0F, 0x40); 6968 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6969 ins_pipe(pipe_cmov_mem); // XXX 6970 %} 6971 6972 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6973 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6974 ins_cost(200); 6975 expand %{ 6976 cmovL_memU(cop, cr, dst, src); 6977 %} 6978 %} 6979 6980 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6981 %{ 6982 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6983 6984 ins_cost(200); // XXX 6985 format %{ "jn$cop skip\t# signed cmove float\n\t" 6986 "movss $dst, $src\n" 6987 "skip:" %} 6988 ins_encode %{ 6989 Label Lskip; 6990 // Invert sense of branch from sense of CMOV 6991 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6992 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6993 __ bind(Lskip); 6994 %} 6995 ins_pipe(pipe_slow); 6996 %} 6997 6998 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6999 // %{ 7000 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7001 7002 // ins_cost(200); // XXX 7003 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7004 // "movss $dst, $src\n" 7005 // "skip:" %} 7006 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7007 // ins_pipe(pipe_slow); 7008 // %} 7009 7010 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7011 %{ 7012 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7013 7014 ins_cost(200); // XXX 7015 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7016 "movss $dst, $src\n" 7017 "skip:" %} 7018 ins_encode %{ 7019 Label Lskip; 7020 // Invert sense of branch from sense of CMOV 7021 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7022 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7023 __ bind(Lskip); 7024 %} 7025 ins_pipe(pipe_slow); 7026 %} 7027 7028 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7029 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7030 ins_cost(200); 7031 expand %{ 7032 cmovF_regU(cop, cr, dst, src); 7033 %} 7034 %} 7035 7036 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7037 %{ 7038 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7039 7040 ins_cost(200); // XXX 7041 format %{ "jn$cop skip\t# signed cmove double\n\t" 7042 "movsd $dst, $src\n" 7043 "skip:" %} 7044 ins_encode %{ 7045 Label Lskip; 7046 // Invert sense of branch from sense of CMOV 7047 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7048 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7049 __ bind(Lskip); 7050 %} 7051 ins_pipe(pipe_slow); 7052 %} 7053 7054 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7055 %{ 7056 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7057 7058 ins_cost(200); // XXX 7059 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7060 "movsd $dst, $src\n" 7061 "skip:" %} 7062 ins_encode %{ 7063 Label Lskip; 7064 // Invert sense of branch from sense of CMOV 7065 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7066 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7067 __ bind(Lskip); 7068 %} 7069 ins_pipe(pipe_slow); 7070 %} 7071 7072 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7073 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7074 ins_cost(200); 7075 expand %{ 7076 cmovD_regU(cop, cr, dst, src); 7077 %} 7078 %} 7079 7080 //----------Arithmetic Instructions-------------------------------------------- 7081 //----------Addition Instructions---------------------------------------------- 7082 7083 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7084 %{ 7085 match(Set dst (AddI dst src)); 7086 effect(KILL cr); 7087 7088 format %{ "addl $dst, $src\t# int" %} 7089 opcode(0x03); 7090 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7091 ins_pipe(ialu_reg_reg); 7092 %} 7093 7094 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7095 %{ 7096 match(Set dst (AddI dst src)); 7097 effect(KILL cr); 7098 7099 format %{ "addl $dst, $src\t# int" %} 7100 opcode(0x81, 0x00); /* /0 id */ 7101 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7102 ins_pipe( ialu_reg ); 7103 %} 7104 7105 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7106 %{ 7107 match(Set dst (AddI dst (LoadI src))); 7108 effect(KILL cr); 7109 7110 ins_cost(125); // XXX 7111 format %{ "addl $dst, $src\t# int" %} 7112 opcode(0x03); 7113 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7114 ins_pipe(ialu_reg_mem); 7115 %} 7116 7117 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7118 %{ 7119 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7120 effect(KILL cr); 7121 7122 ins_cost(150); // XXX 7123 format %{ "addl $dst, $src\t# int" %} 7124 opcode(0x01); /* Opcode 01 /r */ 7125 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7126 ins_pipe(ialu_mem_reg); 7127 %} 7128 7129 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7130 %{ 7131 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7132 effect(KILL cr); 7133 7134 ins_cost(125); // XXX 7135 format %{ "addl $dst, $src\t# int" %} 7136 opcode(0x81); /* Opcode 81 /0 id */ 7137 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7138 ins_pipe(ialu_mem_imm); 7139 %} 7140 7141 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7142 %{ 7143 predicate(UseIncDec); 7144 match(Set dst (AddI dst src)); 7145 effect(KILL cr); 7146 7147 format %{ "incl $dst\t# int" %} 7148 opcode(0xFF, 0x00); // FF /0 7149 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7150 ins_pipe(ialu_reg); 7151 %} 7152 7153 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7154 %{ 7155 predicate(UseIncDec); 7156 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7157 effect(KILL cr); 7158 7159 ins_cost(125); // XXX 7160 format %{ "incl $dst\t# int" %} 7161 opcode(0xFF); /* Opcode FF /0 */ 7162 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7163 ins_pipe(ialu_mem_imm); 7164 %} 7165 7166 // XXX why does that use AddI 7167 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7168 %{ 7169 predicate(UseIncDec); 7170 match(Set dst (AddI dst src)); 7171 effect(KILL cr); 7172 7173 format %{ "decl $dst\t# int" %} 7174 opcode(0xFF, 0x01); // FF /1 7175 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7176 ins_pipe(ialu_reg); 7177 %} 7178 7179 // XXX why does that use AddI 7180 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7181 %{ 7182 predicate(UseIncDec); 7183 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7184 effect(KILL cr); 7185 7186 ins_cost(125); // XXX 7187 format %{ "decl $dst\t# int" %} 7188 opcode(0xFF); /* Opcode FF /1 */ 7189 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7190 ins_pipe(ialu_mem_imm); 7191 %} 7192 7193 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7194 %{ 7195 match(Set dst (AddI src0 src1)); 7196 7197 ins_cost(110); 7198 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7199 opcode(0x8D); /* 0x8D /r */ 7200 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7201 ins_pipe(ialu_reg_reg); 7202 %} 7203 7204 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7205 %{ 7206 match(Set dst (AddL dst src)); 7207 effect(KILL cr); 7208 7209 format %{ "addq $dst, $src\t# long" %} 7210 opcode(0x03); 7211 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7212 ins_pipe(ialu_reg_reg); 7213 %} 7214 7215 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7216 %{ 7217 match(Set dst (AddL dst src)); 7218 effect(KILL cr); 7219 7220 format %{ "addq $dst, $src\t# long" %} 7221 opcode(0x81, 0x00); /* /0 id */ 7222 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7223 ins_pipe( ialu_reg ); 7224 %} 7225 7226 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7227 %{ 7228 match(Set dst (AddL dst (LoadL src))); 7229 effect(KILL cr); 7230 7231 ins_cost(125); // XXX 7232 format %{ "addq $dst, $src\t# long" %} 7233 opcode(0x03); 7234 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7235 ins_pipe(ialu_reg_mem); 7236 %} 7237 7238 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7239 %{ 7240 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7241 effect(KILL cr); 7242 7243 ins_cost(150); // XXX 7244 format %{ "addq $dst, $src\t# long" %} 7245 opcode(0x01); /* Opcode 01 /r */ 7246 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7247 ins_pipe(ialu_mem_reg); 7248 %} 7249 7250 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7251 %{ 7252 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7253 effect(KILL cr); 7254 7255 ins_cost(125); // XXX 7256 format %{ "addq $dst, $src\t# long" %} 7257 opcode(0x81); /* Opcode 81 /0 id */ 7258 ins_encode(REX_mem_wide(dst), 7259 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7260 ins_pipe(ialu_mem_imm); 7261 %} 7262 7263 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7264 %{ 7265 predicate(UseIncDec); 7266 match(Set dst (AddL dst src)); 7267 effect(KILL cr); 7268 7269 format %{ "incq $dst\t# long" %} 7270 opcode(0xFF, 0x00); // FF /0 7271 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7272 ins_pipe(ialu_reg); 7273 %} 7274 7275 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7276 %{ 7277 predicate(UseIncDec); 7278 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7279 effect(KILL cr); 7280 7281 ins_cost(125); // XXX 7282 format %{ "incq $dst\t# long" %} 7283 opcode(0xFF); /* Opcode FF /0 */ 7284 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7285 ins_pipe(ialu_mem_imm); 7286 %} 7287 7288 // XXX why does that use AddL 7289 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7290 %{ 7291 predicate(UseIncDec); 7292 match(Set dst (AddL dst src)); 7293 effect(KILL cr); 7294 7295 format %{ "decq $dst\t# long" %} 7296 opcode(0xFF, 0x01); // FF /1 7297 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7298 ins_pipe(ialu_reg); 7299 %} 7300 7301 // XXX why does that use AddL 7302 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7303 %{ 7304 predicate(UseIncDec); 7305 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7306 effect(KILL cr); 7307 7308 ins_cost(125); // XXX 7309 format %{ "decq $dst\t# long" %} 7310 opcode(0xFF); /* Opcode FF /1 */ 7311 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7312 ins_pipe(ialu_mem_imm); 7313 %} 7314 7315 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7316 %{ 7317 match(Set dst (AddL src0 src1)); 7318 7319 ins_cost(110); 7320 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7321 opcode(0x8D); /* 0x8D /r */ 7322 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7323 ins_pipe(ialu_reg_reg); 7324 %} 7325 7326 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7327 %{ 7328 match(Set dst (AddP dst src)); 7329 effect(KILL cr); 7330 7331 format %{ "addq $dst, $src\t# ptr" %} 7332 opcode(0x03); 7333 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7334 ins_pipe(ialu_reg_reg); 7335 %} 7336 7337 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7338 %{ 7339 match(Set dst (AddP dst src)); 7340 effect(KILL cr); 7341 7342 format %{ "addq $dst, $src\t# ptr" %} 7343 opcode(0x81, 0x00); /* /0 id */ 7344 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7345 ins_pipe( ialu_reg ); 7346 %} 7347 7348 // XXX addP mem ops ???? 7349 7350 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7351 %{ 7352 match(Set dst (AddP src0 src1)); 7353 7354 ins_cost(110); 7355 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7356 opcode(0x8D); /* 0x8D /r */ 7357 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7358 ins_pipe(ialu_reg_reg); 7359 %} 7360 7361 instruct checkCastPP(rRegP dst) 7362 %{ 7363 match(Set dst (CheckCastPP dst)); 7364 7365 size(0); 7366 format %{ "# checkcastPP of $dst" %} 7367 ins_encode(/* empty encoding */); 7368 ins_pipe(empty); 7369 %} 7370 7371 instruct castPP(rRegP dst) 7372 %{ 7373 match(Set dst (CastPP dst)); 7374 7375 size(0); 7376 format %{ "# castPP of $dst" %} 7377 ins_encode(/* empty encoding */); 7378 ins_pipe(empty); 7379 %} 7380 7381 instruct castII(rRegI dst) 7382 %{ 7383 match(Set dst (CastII dst)); 7384 7385 size(0); 7386 format %{ "# castII of $dst" %} 7387 ins_encode(/* empty encoding */); 7388 ins_cost(0); 7389 ins_pipe(empty); 7390 %} 7391 7392 // LoadP-locked same as a regular LoadP when used with compare-swap 7393 instruct loadPLocked(rRegP dst, memory mem) 7394 %{ 7395 match(Set dst (LoadPLocked mem)); 7396 7397 ins_cost(125); // XXX 7398 format %{ "movq $dst, $mem\t# ptr locked" %} 7399 opcode(0x8B); 7400 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7401 ins_pipe(ialu_reg_mem); // XXX 7402 %} 7403 7404 // Conditional-store of the updated heap-top. 7405 // Used during allocation of the shared heap. 7406 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7407 7408 instruct storePConditional(memory heap_top_ptr, 7409 rax_RegP oldval, rRegP newval, 7410 rFlagsReg cr) 7411 %{ 7412 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7413 7414 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7415 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7416 opcode(0x0F, 0xB1); 7417 ins_encode(lock_prefix, 7418 REX_reg_mem_wide(newval, heap_top_ptr), 7419 OpcP, OpcS, 7420 reg_mem(newval, heap_top_ptr)); 7421 ins_pipe(pipe_cmpxchg); 7422 %} 7423 7424 // Conditional-store of an int value. 7425 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7426 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7427 %{ 7428 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7429 effect(KILL oldval); 7430 7431 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7432 opcode(0x0F, 0xB1); 7433 ins_encode(lock_prefix, 7434 REX_reg_mem(newval, mem), 7435 OpcP, OpcS, 7436 reg_mem(newval, mem)); 7437 ins_pipe(pipe_cmpxchg); 7438 %} 7439 7440 // Conditional-store of a long value. 7441 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7442 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7443 %{ 7444 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7445 effect(KILL oldval); 7446 7447 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7448 opcode(0x0F, 0xB1); 7449 ins_encode(lock_prefix, 7450 REX_reg_mem_wide(newval, mem), 7451 OpcP, OpcS, 7452 reg_mem(newval, mem)); 7453 ins_pipe(pipe_cmpxchg); 7454 %} 7455 7456 7457 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7458 instruct compareAndSwapP(rRegI res, 7459 memory mem_ptr, 7460 rax_RegP oldval, rRegP newval, 7461 rFlagsReg cr) 7462 %{ 7463 predicate(VM_Version::supports_cx8()); 7464 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7465 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7466 effect(KILL cr, KILL oldval); 7467 7468 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7469 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7470 "sete $res\n\t" 7471 "movzbl $res, $res" %} 7472 opcode(0x0F, 0xB1); 7473 ins_encode(lock_prefix, 7474 REX_reg_mem_wide(newval, mem_ptr), 7475 OpcP, OpcS, 7476 reg_mem(newval, mem_ptr), 7477 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7478 REX_reg_breg(res, res), // movzbl 7479 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7480 ins_pipe( pipe_cmpxchg ); 7481 %} 7482 7483 instruct compareAndSwapL(rRegI res, 7484 memory mem_ptr, 7485 rax_RegL oldval, rRegL newval, 7486 rFlagsReg cr) 7487 %{ 7488 predicate(VM_Version::supports_cx8()); 7489 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7490 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7491 effect(KILL cr, KILL oldval); 7492 7493 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7494 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7495 "sete $res\n\t" 7496 "movzbl $res, $res" %} 7497 opcode(0x0F, 0xB1); 7498 ins_encode(lock_prefix, 7499 REX_reg_mem_wide(newval, mem_ptr), 7500 OpcP, OpcS, 7501 reg_mem(newval, mem_ptr), 7502 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7503 REX_reg_breg(res, res), // movzbl 7504 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7505 ins_pipe( pipe_cmpxchg ); 7506 %} 7507 7508 instruct compareAndSwapI(rRegI res, 7509 memory mem_ptr, 7510 rax_RegI oldval, rRegI newval, 7511 rFlagsReg cr) 7512 %{ 7513 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7514 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7515 effect(KILL cr, KILL oldval); 7516 7517 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7518 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7519 "sete $res\n\t" 7520 "movzbl $res, $res" %} 7521 opcode(0x0F, 0xB1); 7522 ins_encode(lock_prefix, 7523 REX_reg_mem(newval, mem_ptr), 7524 OpcP, OpcS, 7525 reg_mem(newval, mem_ptr), 7526 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7527 REX_reg_breg(res, res), // movzbl 7528 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7529 ins_pipe( pipe_cmpxchg ); 7530 %} 7531 7532 instruct compareAndSwapB(rRegI res, 7533 memory mem_ptr, 7534 rax_RegI oldval, rRegI newval, 7535 rFlagsReg cr) 7536 %{ 7537 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7538 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7539 effect(KILL cr, KILL oldval); 7540 7541 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7542 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7543 "sete $res\n\t" 7544 "movzbl $res, $res" %} 7545 opcode(0x0F, 0xB0); 7546 ins_encode(lock_prefix, 7547 REX_breg_mem(newval, mem_ptr), 7548 OpcP, OpcS, 7549 reg_mem(newval, mem_ptr), 7550 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7551 REX_reg_breg(res, res), // movzbl 7552 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7553 ins_pipe( pipe_cmpxchg ); 7554 %} 7555 7556 instruct compareAndSwapS(rRegI res, 7557 memory mem_ptr, 7558 rax_RegI oldval, rRegI newval, 7559 rFlagsReg cr) 7560 %{ 7561 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7562 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7563 effect(KILL cr, KILL oldval); 7564 7565 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7566 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7567 "sete $res\n\t" 7568 "movzbl $res, $res" %} 7569 opcode(0x0F, 0xB1); 7570 ins_encode(lock_prefix, 7571 SizePrefix, 7572 REX_reg_mem(newval, mem_ptr), 7573 OpcP, OpcS, 7574 reg_mem(newval, mem_ptr), 7575 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7576 REX_reg_breg(res, res), // movzbl 7577 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7578 ins_pipe( pipe_cmpxchg ); 7579 %} 7580 7581 instruct compareAndSwapN(rRegI res, 7582 memory mem_ptr, 7583 rax_RegN oldval, rRegN newval, 7584 rFlagsReg cr) %{ 7585 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7586 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7587 effect(KILL cr, KILL oldval); 7588 7589 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7590 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7591 "sete $res\n\t" 7592 "movzbl $res, $res" %} 7593 opcode(0x0F, 0xB1); 7594 ins_encode(lock_prefix, 7595 REX_reg_mem(newval, mem_ptr), 7596 OpcP, OpcS, 7597 reg_mem(newval, mem_ptr), 7598 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7599 REX_reg_breg(res, res), // movzbl 7600 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7601 ins_pipe( pipe_cmpxchg ); 7602 %} 7603 7604 instruct compareAndExchangeB( 7605 memory mem_ptr, 7606 rax_RegI oldval, rRegI newval, 7607 rFlagsReg cr) 7608 %{ 7609 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7610 effect(KILL cr); 7611 7612 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7613 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7614 opcode(0x0F, 0xB0); 7615 ins_encode(lock_prefix, 7616 REX_breg_mem(newval, mem_ptr), 7617 OpcP, OpcS, 7618 reg_mem(newval, mem_ptr) // lock cmpxchg 7619 ); 7620 ins_pipe( pipe_cmpxchg ); 7621 %} 7622 7623 instruct compareAndExchangeS( 7624 memory mem_ptr, 7625 rax_RegI oldval, rRegI newval, 7626 rFlagsReg cr) 7627 %{ 7628 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7629 effect(KILL cr); 7630 7631 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7632 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7633 opcode(0x0F, 0xB1); 7634 ins_encode(lock_prefix, 7635 SizePrefix, 7636 REX_reg_mem(newval, mem_ptr), 7637 OpcP, OpcS, 7638 reg_mem(newval, mem_ptr) // lock cmpxchg 7639 ); 7640 ins_pipe( pipe_cmpxchg ); 7641 %} 7642 7643 instruct compareAndExchangeI( 7644 memory mem_ptr, 7645 rax_RegI oldval, rRegI newval, 7646 rFlagsReg cr) 7647 %{ 7648 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7649 effect(KILL cr); 7650 7651 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7652 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7653 opcode(0x0F, 0xB1); 7654 ins_encode(lock_prefix, 7655 REX_reg_mem(newval, mem_ptr), 7656 OpcP, OpcS, 7657 reg_mem(newval, mem_ptr) // lock cmpxchg 7658 ); 7659 ins_pipe( pipe_cmpxchg ); 7660 %} 7661 7662 instruct compareAndExchangeL( 7663 memory mem_ptr, 7664 rax_RegL oldval, rRegL newval, 7665 rFlagsReg cr) 7666 %{ 7667 predicate(VM_Version::supports_cx8()); 7668 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7669 effect(KILL cr); 7670 7671 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7672 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7673 opcode(0x0F, 0xB1); 7674 ins_encode(lock_prefix, 7675 REX_reg_mem_wide(newval, mem_ptr), 7676 OpcP, OpcS, 7677 reg_mem(newval, mem_ptr) // lock cmpxchg 7678 ); 7679 ins_pipe( pipe_cmpxchg ); 7680 %} 7681 7682 instruct compareAndExchangeN( 7683 memory mem_ptr, 7684 rax_RegN oldval, rRegN newval, 7685 rFlagsReg cr) %{ 7686 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7687 effect(KILL cr); 7688 7689 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7690 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7691 opcode(0x0F, 0xB1); 7692 ins_encode(lock_prefix, 7693 REX_reg_mem(newval, mem_ptr), 7694 OpcP, OpcS, 7695 reg_mem(newval, mem_ptr) // lock cmpxchg 7696 ); 7697 ins_pipe( pipe_cmpxchg ); 7698 %} 7699 7700 instruct compareAndExchangeP( 7701 memory mem_ptr, 7702 rax_RegP oldval, rRegP newval, 7703 rFlagsReg cr) 7704 %{ 7705 predicate(VM_Version::supports_cx8()); 7706 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7707 effect(KILL cr); 7708 7709 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7710 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7711 opcode(0x0F, 0xB1); 7712 ins_encode(lock_prefix, 7713 REX_reg_mem_wide(newval, mem_ptr), 7714 OpcP, OpcS, 7715 reg_mem(newval, mem_ptr) // lock cmpxchg 7716 ); 7717 ins_pipe( pipe_cmpxchg ); 7718 %} 7719 7720 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7721 predicate(n->as_LoadStore()->result_not_used()); 7722 match(Set dummy (GetAndAddB mem add)); 7723 effect(KILL cr); 7724 format %{ "ADDB [$mem],$add" %} 7725 ins_encode %{ 7726 if (os::is_MP()) { __ lock(); } 7727 __ addb($mem$$Address, $add$$constant); 7728 %} 7729 ins_pipe( pipe_cmpxchg ); 7730 %} 7731 7732 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7733 match(Set newval (GetAndAddB mem newval)); 7734 effect(KILL cr); 7735 format %{ "XADDB [$mem],$newval" %} 7736 ins_encode %{ 7737 if (os::is_MP()) { __ lock(); } 7738 __ xaddb($mem$$Address, $newval$$Register); 7739 %} 7740 ins_pipe( pipe_cmpxchg ); 7741 %} 7742 7743 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7744 predicate(n->as_LoadStore()->result_not_used()); 7745 match(Set dummy (GetAndAddS mem add)); 7746 effect(KILL cr); 7747 format %{ "ADDW [$mem],$add" %} 7748 ins_encode %{ 7749 if (os::is_MP()) { __ lock(); } 7750 __ addw($mem$$Address, $add$$constant); 7751 %} 7752 ins_pipe( pipe_cmpxchg ); 7753 %} 7754 7755 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7756 match(Set newval (GetAndAddS mem newval)); 7757 effect(KILL cr); 7758 format %{ "XADDW [$mem],$newval" %} 7759 ins_encode %{ 7760 if (os::is_MP()) { __ lock(); } 7761 __ xaddw($mem$$Address, $newval$$Register); 7762 %} 7763 ins_pipe( pipe_cmpxchg ); 7764 %} 7765 7766 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7767 predicate(n->as_LoadStore()->result_not_used()); 7768 match(Set dummy (GetAndAddI mem add)); 7769 effect(KILL cr); 7770 format %{ "ADDL [$mem],$add" %} 7771 ins_encode %{ 7772 if (os::is_MP()) { __ lock(); } 7773 __ addl($mem$$Address, $add$$constant); 7774 %} 7775 ins_pipe( pipe_cmpxchg ); 7776 %} 7777 7778 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7779 match(Set newval (GetAndAddI mem newval)); 7780 effect(KILL cr); 7781 format %{ "XADDL [$mem],$newval" %} 7782 ins_encode %{ 7783 if (os::is_MP()) { __ lock(); } 7784 __ xaddl($mem$$Address, $newval$$Register); 7785 %} 7786 ins_pipe( pipe_cmpxchg ); 7787 %} 7788 7789 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7790 predicate(n->as_LoadStore()->result_not_used()); 7791 match(Set dummy (GetAndAddL mem add)); 7792 effect(KILL cr); 7793 format %{ "ADDQ [$mem],$add" %} 7794 ins_encode %{ 7795 if (os::is_MP()) { __ lock(); } 7796 __ addq($mem$$Address, $add$$constant); 7797 %} 7798 ins_pipe( pipe_cmpxchg ); 7799 %} 7800 7801 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7802 match(Set newval (GetAndAddL mem newval)); 7803 effect(KILL cr); 7804 format %{ "XADDQ [$mem],$newval" %} 7805 ins_encode %{ 7806 if (os::is_MP()) { __ lock(); } 7807 __ xaddq($mem$$Address, $newval$$Register); 7808 %} 7809 ins_pipe( pipe_cmpxchg ); 7810 %} 7811 7812 instruct xchgB( memory mem, rRegI newval) %{ 7813 match(Set newval (GetAndSetB mem newval)); 7814 format %{ "XCHGB $newval,[$mem]" %} 7815 ins_encode %{ 7816 __ xchgb($newval$$Register, $mem$$Address); 7817 %} 7818 ins_pipe( pipe_cmpxchg ); 7819 %} 7820 7821 instruct xchgS( memory mem, rRegI newval) %{ 7822 match(Set newval (GetAndSetS mem newval)); 7823 format %{ "XCHGW $newval,[$mem]" %} 7824 ins_encode %{ 7825 __ xchgw($newval$$Register, $mem$$Address); 7826 %} 7827 ins_pipe( pipe_cmpxchg ); 7828 %} 7829 7830 instruct xchgI( memory mem, rRegI newval) %{ 7831 match(Set newval (GetAndSetI mem newval)); 7832 format %{ "XCHGL $newval,[$mem]" %} 7833 ins_encode %{ 7834 __ xchgl($newval$$Register, $mem$$Address); 7835 %} 7836 ins_pipe( pipe_cmpxchg ); 7837 %} 7838 7839 instruct xchgL( memory mem, rRegL newval) %{ 7840 match(Set newval (GetAndSetL mem newval)); 7841 format %{ "XCHGL $newval,[$mem]" %} 7842 ins_encode %{ 7843 __ xchgq($newval$$Register, $mem$$Address); 7844 %} 7845 ins_pipe( pipe_cmpxchg ); 7846 %} 7847 7848 instruct xchgP( memory mem, rRegP newval) %{ 7849 match(Set newval (GetAndSetP mem newval)); 7850 format %{ "XCHGQ $newval,[$mem]" %} 7851 ins_encode %{ 7852 __ xchgq($newval$$Register, $mem$$Address); 7853 %} 7854 ins_pipe( pipe_cmpxchg ); 7855 %} 7856 7857 instruct xchgN( memory mem, rRegN newval) %{ 7858 match(Set newval (GetAndSetN mem newval)); 7859 format %{ "XCHGL $newval,$mem]" %} 7860 ins_encode %{ 7861 __ xchgl($newval$$Register, $mem$$Address); 7862 %} 7863 ins_pipe( pipe_cmpxchg ); 7864 %} 7865 7866 //----------Subtraction Instructions------------------------------------------- 7867 7868 // Integer Subtraction Instructions 7869 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7870 %{ 7871 match(Set dst (SubI dst src)); 7872 effect(KILL cr); 7873 7874 format %{ "subl $dst, $src\t# int" %} 7875 opcode(0x2B); 7876 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7877 ins_pipe(ialu_reg_reg); 7878 %} 7879 7880 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7881 %{ 7882 match(Set dst (SubI dst src)); 7883 effect(KILL cr); 7884 7885 format %{ "subl $dst, $src\t# int" %} 7886 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7887 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7888 ins_pipe(ialu_reg); 7889 %} 7890 7891 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7892 %{ 7893 match(Set dst (SubI dst (LoadI src))); 7894 effect(KILL cr); 7895 7896 ins_cost(125); 7897 format %{ "subl $dst, $src\t# int" %} 7898 opcode(0x2B); 7899 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7900 ins_pipe(ialu_reg_mem); 7901 %} 7902 7903 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7904 %{ 7905 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7906 effect(KILL cr); 7907 7908 ins_cost(150); 7909 format %{ "subl $dst, $src\t# int" %} 7910 opcode(0x29); /* Opcode 29 /r */ 7911 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7912 ins_pipe(ialu_mem_reg); 7913 %} 7914 7915 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7916 %{ 7917 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7918 effect(KILL cr); 7919 7920 ins_cost(125); // XXX 7921 format %{ "subl $dst, $src\t# int" %} 7922 opcode(0x81); /* Opcode 81 /5 id */ 7923 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7924 ins_pipe(ialu_mem_imm); 7925 %} 7926 7927 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7928 %{ 7929 match(Set dst (SubL dst src)); 7930 effect(KILL cr); 7931 7932 format %{ "subq $dst, $src\t# long" %} 7933 opcode(0x2B); 7934 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7935 ins_pipe(ialu_reg_reg); 7936 %} 7937 7938 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7939 %{ 7940 match(Set dst (SubL dst src)); 7941 effect(KILL cr); 7942 7943 format %{ "subq $dst, $src\t# long" %} 7944 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7945 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7946 ins_pipe(ialu_reg); 7947 %} 7948 7949 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7950 %{ 7951 match(Set dst (SubL dst (LoadL src))); 7952 effect(KILL cr); 7953 7954 ins_cost(125); 7955 format %{ "subq $dst, $src\t# long" %} 7956 opcode(0x2B); 7957 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7958 ins_pipe(ialu_reg_mem); 7959 %} 7960 7961 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7962 %{ 7963 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7964 effect(KILL cr); 7965 7966 ins_cost(150); 7967 format %{ "subq $dst, $src\t# long" %} 7968 opcode(0x29); /* Opcode 29 /r */ 7969 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7970 ins_pipe(ialu_mem_reg); 7971 %} 7972 7973 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7974 %{ 7975 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7976 effect(KILL cr); 7977 7978 ins_cost(125); // XXX 7979 format %{ "subq $dst, $src\t# long" %} 7980 opcode(0x81); /* Opcode 81 /5 id */ 7981 ins_encode(REX_mem_wide(dst), 7982 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7983 ins_pipe(ialu_mem_imm); 7984 %} 7985 7986 // Subtract from a pointer 7987 // XXX hmpf??? 7988 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7989 %{ 7990 match(Set dst (AddP dst (SubI zero src))); 7991 effect(KILL cr); 7992 7993 format %{ "subq $dst, $src\t# ptr - int" %} 7994 opcode(0x2B); 7995 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7996 ins_pipe(ialu_reg_reg); 7997 %} 7998 7999 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8000 %{ 8001 match(Set dst (SubI zero dst)); 8002 effect(KILL cr); 8003 8004 format %{ "negl $dst\t# int" %} 8005 opcode(0xF7, 0x03); // Opcode F7 /3 8006 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8007 ins_pipe(ialu_reg); 8008 %} 8009 8010 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8011 %{ 8012 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8013 effect(KILL cr); 8014 8015 format %{ "negl $dst\t# int" %} 8016 opcode(0xF7, 0x03); // Opcode F7 /3 8017 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8018 ins_pipe(ialu_reg); 8019 %} 8020 8021 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8022 %{ 8023 match(Set dst (SubL zero dst)); 8024 effect(KILL cr); 8025 8026 format %{ "negq $dst\t# long" %} 8027 opcode(0xF7, 0x03); // Opcode F7 /3 8028 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8029 ins_pipe(ialu_reg); 8030 %} 8031 8032 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8033 %{ 8034 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8035 effect(KILL cr); 8036 8037 format %{ "negq $dst\t# long" %} 8038 opcode(0xF7, 0x03); // Opcode F7 /3 8039 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8040 ins_pipe(ialu_reg); 8041 %} 8042 8043 //----------Multiplication/Division Instructions------------------------------- 8044 // Integer Multiplication Instructions 8045 // Multiply Register 8046 8047 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8048 %{ 8049 match(Set dst (MulI dst src)); 8050 effect(KILL cr); 8051 8052 ins_cost(300); 8053 format %{ "imull $dst, $src\t# int" %} 8054 opcode(0x0F, 0xAF); 8055 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8056 ins_pipe(ialu_reg_reg_alu0); 8057 %} 8058 8059 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8060 %{ 8061 match(Set dst (MulI src imm)); 8062 effect(KILL cr); 8063 8064 ins_cost(300); 8065 format %{ "imull $dst, $src, $imm\t# int" %} 8066 opcode(0x69); /* 69 /r id */ 8067 ins_encode(REX_reg_reg(dst, src), 8068 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8069 ins_pipe(ialu_reg_reg_alu0); 8070 %} 8071 8072 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8073 %{ 8074 match(Set dst (MulI dst (LoadI src))); 8075 effect(KILL cr); 8076 8077 ins_cost(350); 8078 format %{ "imull $dst, $src\t# int" %} 8079 opcode(0x0F, 0xAF); 8080 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8081 ins_pipe(ialu_reg_mem_alu0); 8082 %} 8083 8084 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8085 %{ 8086 match(Set dst (MulI (LoadI src) imm)); 8087 effect(KILL cr); 8088 8089 ins_cost(300); 8090 format %{ "imull $dst, $src, $imm\t# int" %} 8091 opcode(0x69); /* 69 /r id */ 8092 ins_encode(REX_reg_mem(dst, src), 8093 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8094 ins_pipe(ialu_reg_mem_alu0); 8095 %} 8096 8097 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8098 %{ 8099 match(Set dst (MulL dst src)); 8100 effect(KILL cr); 8101 8102 ins_cost(300); 8103 format %{ "imulq $dst, $src\t# long" %} 8104 opcode(0x0F, 0xAF); 8105 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8106 ins_pipe(ialu_reg_reg_alu0); 8107 %} 8108 8109 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8110 %{ 8111 match(Set dst (MulL src imm)); 8112 effect(KILL cr); 8113 8114 ins_cost(300); 8115 format %{ "imulq $dst, $src, $imm\t# long" %} 8116 opcode(0x69); /* 69 /r id */ 8117 ins_encode(REX_reg_reg_wide(dst, src), 8118 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8119 ins_pipe(ialu_reg_reg_alu0); 8120 %} 8121 8122 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8123 %{ 8124 match(Set dst (MulL dst (LoadL src))); 8125 effect(KILL cr); 8126 8127 ins_cost(350); 8128 format %{ "imulq $dst, $src\t# long" %} 8129 opcode(0x0F, 0xAF); 8130 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8131 ins_pipe(ialu_reg_mem_alu0); 8132 %} 8133 8134 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8135 %{ 8136 match(Set dst (MulL (LoadL src) imm)); 8137 effect(KILL cr); 8138 8139 ins_cost(300); 8140 format %{ "imulq $dst, $src, $imm\t# long" %} 8141 opcode(0x69); /* 69 /r id */ 8142 ins_encode(REX_reg_mem_wide(dst, src), 8143 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8144 ins_pipe(ialu_reg_mem_alu0); 8145 %} 8146 8147 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8148 %{ 8149 match(Set dst (MulHiL src rax)); 8150 effect(USE_KILL rax, KILL cr); 8151 8152 ins_cost(300); 8153 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8154 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8155 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8156 ins_pipe(ialu_reg_reg_alu0); 8157 %} 8158 8159 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8160 rFlagsReg cr) 8161 %{ 8162 match(Set rax (DivI rax div)); 8163 effect(KILL rdx, KILL cr); 8164 8165 ins_cost(30*100+10*100); // XXX 8166 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8167 "jne,s normal\n\t" 8168 "xorl rdx, rdx\n\t" 8169 "cmpl $div, -1\n\t" 8170 "je,s done\n" 8171 "normal: cdql\n\t" 8172 "idivl $div\n" 8173 "done:" %} 8174 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8175 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8176 ins_pipe(ialu_reg_reg_alu0); 8177 %} 8178 8179 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8180 rFlagsReg cr) 8181 %{ 8182 match(Set rax (DivL rax div)); 8183 effect(KILL rdx, KILL cr); 8184 8185 ins_cost(30*100+10*100); // XXX 8186 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8187 "cmpq rax, rdx\n\t" 8188 "jne,s normal\n\t" 8189 "xorl rdx, rdx\n\t" 8190 "cmpq $div, -1\n\t" 8191 "je,s done\n" 8192 "normal: cdqq\n\t" 8193 "idivq $div\n" 8194 "done:" %} 8195 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8196 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8197 ins_pipe(ialu_reg_reg_alu0); 8198 %} 8199 8200 // Integer DIVMOD with Register, both quotient and mod results 8201 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8202 rFlagsReg cr) 8203 %{ 8204 match(DivModI rax div); 8205 effect(KILL cr); 8206 8207 ins_cost(30*100+10*100); // XXX 8208 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8209 "jne,s normal\n\t" 8210 "xorl rdx, rdx\n\t" 8211 "cmpl $div, -1\n\t" 8212 "je,s done\n" 8213 "normal: cdql\n\t" 8214 "idivl $div\n" 8215 "done:" %} 8216 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8217 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8218 ins_pipe(pipe_slow); 8219 %} 8220 8221 // Long DIVMOD with Register, both quotient and mod results 8222 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8223 rFlagsReg cr) 8224 %{ 8225 match(DivModL rax div); 8226 effect(KILL cr); 8227 8228 ins_cost(30*100+10*100); // XXX 8229 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8230 "cmpq rax, rdx\n\t" 8231 "jne,s normal\n\t" 8232 "xorl rdx, rdx\n\t" 8233 "cmpq $div, -1\n\t" 8234 "je,s done\n" 8235 "normal: cdqq\n\t" 8236 "idivq $div\n" 8237 "done:" %} 8238 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8239 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8240 ins_pipe(pipe_slow); 8241 %} 8242 8243 //----------- DivL-By-Constant-Expansions-------------------------------------- 8244 // DivI cases are handled by the compiler 8245 8246 // Magic constant, reciprocal of 10 8247 instruct loadConL_0x6666666666666667(rRegL dst) 8248 %{ 8249 effect(DEF dst); 8250 8251 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8252 ins_encode(load_immL(dst, 0x6666666666666667)); 8253 ins_pipe(ialu_reg); 8254 %} 8255 8256 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8257 %{ 8258 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8259 8260 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8261 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8262 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8263 ins_pipe(ialu_reg_reg_alu0); 8264 %} 8265 8266 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8267 %{ 8268 effect(USE_DEF dst, KILL cr); 8269 8270 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8271 opcode(0xC1, 0x7); /* C1 /7 ib */ 8272 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8273 ins_pipe(ialu_reg); 8274 %} 8275 8276 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8277 %{ 8278 effect(USE_DEF dst, KILL cr); 8279 8280 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8281 opcode(0xC1, 0x7); /* C1 /7 ib */ 8282 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8283 ins_pipe(ialu_reg); 8284 %} 8285 8286 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8287 %{ 8288 match(Set dst (DivL src div)); 8289 8290 ins_cost((5+8)*100); 8291 expand %{ 8292 rax_RegL rax; // Killed temp 8293 rFlagsReg cr; // Killed 8294 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8295 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8296 sarL_rReg_63(src, cr); // sarq src, 63 8297 sarL_rReg_2(dst, cr); // sarq rdx, 2 8298 subL_rReg(dst, src, cr); // subl rdx, src 8299 %} 8300 %} 8301 8302 //----------------------------------------------------------------------------- 8303 8304 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8305 rFlagsReg cr) 8306 %{ 8307 match(Set rdx (ModI rax div)); 8308 effect(KILL rax, KILL cr); 8309 8310 ins_cost(300); // XXX 8311 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8312 "jne,s normal\n\t" 8313 "xorl rdx, rdx\n\t" 8314 "cmpl $div, -1\n\t" 8315 "je,s done\n" 8316 "normal: cdql\n\t" 8317 "idivl $div\n" 8318 "done:" %} 8319 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8320 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8321 ins_pipe(ialu_reg_reg_alu0); 8322 %} 8323 8324 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8325 rFlagsReg cr) 8326 %{ 8327 match(Set rdx (ModL rax div)); 8328 effect(KILL rax, KILL cr); 8329 8330 ins_cost(300); // XXX 8331 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8332 "cmpq rax, rdx\n\t" 8333 "jne,s normal\n\t" 8334 "xorl rdx, rdx\n\t" 8335 "cmpq $div, -1\n\t" 8336 "je,s done\n" 8337 "normal: cdqq\n\t" 8338 "idivq $div\n" 8339 "done:" %} 8340 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8341 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8342 ins_pipe(ialu_reg_reg_alu0); 8343 %} 8344 8345 // Integer Shift Instructions 8346 // Shift Left by one 8347 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8348 %{ 8349 match(Set dst (LShiftI dst shift)); 8350 effect(KILL cr); 8351 8352 format %{ "sall $dst, $shift" %} 8353 opcode(0xD1, 0x4); /* D1 /4 */ 8354 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8355 ins_pipe(ialu_reg); 8356 %} 8357 8358 // Shift Left by one 8359 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8360 %{ 8361 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8362 effect(KILL cr); 8363 8364 format %{ "sall $dst, $shift\t" %} 8365 opcode(0xD1, 0x4); /* D1 /4 */ 8366 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8367 ins_pipe(ialu_mem_imm); 8368 %} 8369 8370 // Shift Left by 8-bit immediate 8371 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8372 %{ 8373 match(Set dst (LShiftI dst shift)); 8374 effect(KILL cr); 8375 8376 format %{ "sall $dst, $shift" %} 8377 opcode(0xC1, 0x4); /* C1 /4 ib */ 8378 ins_encode(reg_opc_imm(dst, shift)); 8379 ins_pipe(ialu_reg); 8380 %} 8381 8382 // Shift Left by 8-bit immediate 8383 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8384 %{ 8385 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8386 effect(KILL cr); 8387 8388 format %{ "sall $dst, $shift" %} 8389 opcode(0xC1, 0x4); /* C1 /4 ib */ 8390 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8391 ins_pipe(ialu_mem_imm); 8392 %} 8393 8394 // Shift Left by variable 8395 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8396 %{ 8397 match(Set dst (LShiftI dst shift)); 8398 effect(KILL cr); 8399 8400 format %{ "sall $dst, $shift" %} 8401 opcode(0xD3, 0x4); /* D3 /4 */ 8402 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8403 ins_pipe(ialu_reg_reg); 8404 %} 8405 8406 // Shift Left by variable 8407 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8408 %{ 8409 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8410 effect(KILL cr); 8411 8412 format %{ "sall $dst, $shift" %} 8413 opcode(0xD3, 0x4); /* D3 /4 */ 8414 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8415 ins_pipe(ialu_mem_reg); 8416 %} 8417 8418 // Arithmetic shift right by one 8419 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8420 %{ 8421 match(Set dst (RShiftI dst shift)); 8422 effect(KILL cr); 8423 8424 format %{ "sarl $dst, $shift" %} 8425 opcode(0xD1, 0x7); /* D1 /7 */ 8426 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8427 ins_pipe(ialu_reg); 8428 %} 8429 8430 // Arithmetic shift right by one 8431 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8432 %{ 8433 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8434 effect(KILL cr); 8435 8436 format %{ "sarl $dst, $shift" %} 8437 opcode(0xD1, 0x7); /* D1 /7 */ 8438 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8439 ins_pipe(ialu_mem_imm); 8440 %} 8441 8442 // Arithmetic Shift Right by 8-bit immediate 8443 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8444 %{ 8445 match(Set dst (RShiftI dst shift)); 8446 effect(KILL cr); 8447 8448 format %{ "sarl $dst, $shift" %} 8449 opcode(0xC1, 0x7); /* C1 /7 ib */ 8450 ins_encode(reg_opc_imm(dst, shift)); 8451 ins_pipe(ialu_mem_imm); 8452 %} 8453 8454 // Arithmetic Shift Right by 8-bit immediate 8455 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8456 %{ 8457 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8458 effect(KILL cr); 8459 8460 format %{ "sarl $dst, $shift" %} 8461 opcode(0xC1, 0x7); /* C1 /7 ib */ 8462 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8463 ins_pipe(ialu_mem_imm); 8464 %} 8465 8466 // Arithmetic Shift Right by variable 8467 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8468 %{ 8469 match(Set dst (RShiftI dst shift)); 8470 effect(KILL cr); 8471 8472 format %{ "sarl $dst, $shift" %} 8473 opcode(0xD3, 0x7); /* D3 /7 */ 8474 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8475 ins_pipe(ialu_reg_reg); 8476 %} 8477 8478 // Arithmetic Shift Right by variable 8479 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8480 %{ 8481 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8482 effect(KILL cr); 8483 8484 format %{ "sarl $dst, $shift" %} 8485 opcode(0xD3, 0x7); /* D3 /7 */ 8486 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8487 ins_pipe(ialu_mem_reg); 8488 %} 8489 8490 // Logical shift right by one 8491 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8492 %{ 8493 match(Set dst (URShiftI dst shift)); 8494 effect(KILL cr); 8495 8496 format %{ "shrl $dst, $shift" %} 8497 opcode(0xD1, 0x5); /* D1 /5 */ 8498 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8499 ins_pipe(ialu_reg); 8500 %} 8501 8502 // Logical shift right by one 8503 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8504 %{ 8505 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8506 effect(KILL cr); 8507 8508 format %{ "shrl $dst, $shift" %} 8509 opcode(0xD1, 0x5); /* D1 /5 */ 8510 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8511 ins_pipe(ialu_mem_imm); 8512 %} 8513 8514 // Logical Shift Right by 8-bit immediate 8515 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8516 %{ 8517 match(Set dst (URShiftI dst shift)); 8518 effect(KILL cr); 8519 8520 format %{ "shrl $dst, $shift" %} 8521 opcode(0xC1, 0x5); /* C1 /5 ib */ 8522 ins_encode(reg_opc_imm(dst, shift)); 8523 ins_pipe(ialu_reg); 8524 %} 8525 8526 // Logical Shift Right by 8-bit immediate 8527 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8528 %{ 8529 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8530 effect(KILL cr); 8531 8532 format %{ "shrl $dst, $shift" %} 8533 opcode(0xC1, 0x5); /* C1 /5 ib */ 8534 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8535 ins_pipe(ialu_mem_imm); 8536 %} 8537 8538 // Logical Shift Right by variable 8539 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8540 %{ 8541 match(Set dst (URShiftI dst shift)); 8542 effect(KILL cr); 8543 8544 format %{ "shrl $dst, $shift" %} 8545 opcode(0xD3, 0x5); /* D3 /5 */ 8546 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8547 ins_pipe(ialu_reg_reg); 8548 %} 8549 8550 // Logical Shift Right by variable 8551 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8552 %{ 8553 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8554 effect(KILL cr); 8555 8556 format %{ "shrl $dst, $shift" %} 8557 opcode(0xD3, 0x5); /* D3 /5 */ 8558 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8559 ins_pipe(ialu_mem_reg); 8560 %} 8561 8562 // Long Shift Instructions 8563 // Shift Left by one 8564 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8565 %{ 8566 match(Set dst (LShiftL dst shift)); 8567 effect(KILL cr); 8568 8569 format %{ "salq $dst, $shift" %} 8570 opcode(0xD1, 0x4); /* D1 /4 */ 8571 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8572 ins_pipe(ialu_reg); 8573 %} 8574 8575 // Shift Left by one 8576 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8577 %{ 8578 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8579 effect(KILL cr); 8580 8581 format %{ "salq $dst, $shift" %} 8582 opcode(0xD1, 0x4); /* D1 /4 */ 8583 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8584 ins_pipe(ialu_mem_imm); 8585 %} 8586 8587 // Shift Left by 8-bit immediate 8588 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8589 %{ 8590 match(Set dst (LShiftL dst shift)); 8591 effect(KILL cr); 8592 8593 format %{ "salq $dst, $shift" %} 8594 opcode(0xC1, 0x4); /* C1 /4 ib */ 8595 ins_encode(reg_opc_imm_wide(dst, shift)); 8596 ins_pipe(ialu_reg); 8597 %} 8598 8599 // Shift Left by 8-bit immediate 8600 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8601 %{ 8602 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8603 effect(KILL cr); 8604 8605 format %{ "salq $dst, $shift" %} 8606 opcode(0xC1, 0x4); /* C1 /4 ib */ 8607 ins_encode(REX_mem_wide(dst), OpcP, 8608 RM_opc_mem(secondary, dst), Con8or32(shift)); 8609 ins_pipe(ialu_mem_imm); 8610 %} 8611 8612 // Shift Left by variable 8613 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8614 %{ 8615 match(Set dst (LShiftL dst shift)); 8616 effect(KILL cr); 8617 8618 format %{ "salq $dst, $shift" %} 8619 opcode(0xD3, 0x4); /* D3 /4 */ 8620 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8621 ins_pipe(ialu_reg_reg); 8622 %} 8623 8624 // Shift Left by variable 8625 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8626 %{ 8627 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8628 effect(KILL cr); 8629 8630 format %{ "salq $dst, $shift" %} 8631 opcode(0xD3, 0x4); /* D3 /4 */ 8632 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8633 ins_pipe(ialu_mem_reg); 8634 %} 8635 8636 // Arithmetic shift right by one 8637 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8638 %{ 8639 match(Set dst (RShiftL dst shift)); 8640 effect(KILL cr); 8641 8642 format %{ "sarq $dst, $shift" %} 8643 opcode(0xD1, 0x7); /* D1 /7 */ 8644 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8645 ins_pipe(ialu_reg); 8646 %} 8647 8648 // Arithmetic shift right by one 8649 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8650 %{ 8651 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8652 effect(KILL cr); 8653 8654 format %{ "sarq $dst, $shift" %} 8655 opcode(0xD1, 0x7); /* D1 /7 */ 8656 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8657 ins_pipe(ialu_mem_imm); 8658 %} 8659 8660 // Arithmetic Shift Right by 8-bit immediate 8661 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8662 %{ 8663 match(Set dst (RShiftL dst shift)); 8664 effect(KILL cr); 8665 8666 format %{ "sarq $dst, $shift" %} 8667 opcode(0xC1, 0x7); /* C1 /7 ib */ 8668 ins_encode(reg_opc_imm_wide(dst, shift)); 8669 ins_pipe(ialu_mem_imm); 8670 %} 8671 8672 // Arithmetic Shift Right by 8-bit immediate 8673 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8674 %{ 8675 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8676 effect(KILL cr); 8677 8678 format %{ "sarq $dst, $shift" %} 8679 opcode(0xC1, 0x7); /* C1 /7 ib */ 8680 ins_encode(REX_mem_wide(dst), OpcP, 8681 RM_opc_mem(secondary, dst), Con8or32(shift)); 8682 ins_pipe(ialu_mem_imm); 8683 %} 8684 8685 // Arithmetic Shift Right by variable 8686 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8687 %{ 8688 match(Set dst (RShiftL dst shift)); 8689 effect(KILL cr); 8690 8691 format %{ "sarq $dst, $shift" %} 8692 opcode(0xD3, 0x7); /* D3 /7 */ 8693 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8694 ins_pipe(ialu_reg_reg); 8695 %} 8696 8697 // Arithmetic Shift Right by variable 8698 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8699 %{ 8700 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8701 effect(KILL cr); 8702 8703 format %{ "sarq $dst, $shift" %} 8704 opcode(0xD3, 0x7); /* D3 /7 */ 8705 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8706 ins_pipe(ialu_mem_reg); 8707 %} 8708 8709 // Logical shift right by one 8710 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8711 %{ 8712 match(Set dst (URShiftL dst shift)); 8713 effect(KILL cr); 8714 8715 format %{ "shrq $dst, $shift" %} 8716 opcode(0xD1, 0x5); /* D1 /5 */ 8717 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8718 ins_pipe(ialu_reg); 8719 %} 8720 8721 // Logical shift right by one 8722 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8723 %{ 8724 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8725 effect(KILL cr); 8726 8727 format %{ "shrq $dst, $shift" %} 8728 opcode(0xD1, 0x5); /* D1 /5 */ 8729 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8730 ins_pipe(ialu_mem_imm); 8731 %} 8732 8733 // Logical Shift Right by 8-bit immediate 8734 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8735 %{ 8736 match(Set dst (URShiftL dst shift)); 8737 effect(KILL cr); 8738 8739 format %{ "shrq $dst, $shift" %} 8740 opcode(0xC1, 0x5); /* C1 /5 ib */ 8741 ins_encode(reg_opc_imm_wide(dst, shift)); 8742 ins_pipe(ialu_reg); 8743 %} 8744 8745 8746 // Logical Shift Right by 8-bit immediate 8747 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8748 %{ 8749 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8750 effect(KILL cr); 8751 8752 format %{ "shrq $dst, $shift" %} 8753 opcode(0xC1, 0x5); /* C1 /5 ib */ 8754 ins_encode(REX_mem_wide(dst), OpcP, 8755 RM_opc_mem(secondary, dst), Con8or32(shift)); 8756 ins_pipe(ialu_mem_imm); 8757 %} 8758 8759 // Logical Shift Right by variable 8760 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8761 %{ 8762 match(Set dst (URShiftL dst shift)); 8763 effect(KILL cr); 8764 8765 format %{ "shrq $dst, $shift" %} 8766 opcode(0xD3, 0x5); /* D3 /5 */ 8767 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8768 ins_pipe(ialu_reg_reg); 8769 %} 8770 8771 // Logical Shift Right by variable 8772 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8773 %{ 8774 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8775 effect(KILL cr); 8776 8777 format %{ "shrq $dst, $shift" %} 8778 opcode(0xD3, 0x5); /* D3 /5 */ 8779 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8780 ins_pipe(ialu_mem_reg); 8781 %} 8782 8783 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8784 // This idiom is used by the compiler for the i2b bytecode. 8785 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8786 %{ 8787 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8788 8789 format %{ "movsbl $dst, $src\t# i2b" %} 8790 opcode(0x0F, 0xBE); 8791 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8792 ins_pipe(ialu_reg_reg); 8793 %} 8794 8795 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8796 // This idiom is used by the compiler the i2s bytecode. 8797 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8798 %{ 8799 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8800 8801 format %{ "movswl $dst, $src\t# i2s" %} 8802 opcode(0x0F, 0xBF); 8803 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8804 ins_pipe(ialu_reg_reg); 8805 %} 8806 8807 // ROL/ROR instructions 8808 8809 // ROL expand 8810 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8811 effect(KILL cr, USE_DEF dst); 8812 8813 format %{ "roll $dst" %} 8814 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8815 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8816 ins_pipe(ialu_reg); 8817 %} 8818 8819 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8820 effect(USE_DEF dst, USE shift, KILL cr); 8821 8822 format %{ "roll $dst, $shift" %} 8823 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8824 ins_encode( reg_opc_imm(dst, shift) ); 8825 ins_pipe(ialu_reg); 8826 %} 8827 8828 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8829 %{ 8830 effect(USE_DEF dst, USE shift, KILL cr); 8831 8832 format %{ "roll $dst, $shift" %} 8833 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8834 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8835 ins_pipe(ialu_reg_reg); 8836 %} 8837 // end of ROL expand 8838 8839 // Rotate Left by one 8840 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8841 %{ 8842 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8843 8844 expand %{ 8845 rolI_rReg_imm1(dst, cr); 8846 %} 8847 %} 8848 8849 // Rotate Left by 8-bit immediate 8850 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8851 %{ 8852 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8853 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8854 8855 expand %{ 8856 rolI_rReg_imm8(dst, lshift, cr); 8857 %} 8858 %} 8859 8860 // Rotate Left by variable 8861 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8862 %{ 8863 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8864 8865 expand %{ 8866 rolI_rReg_CL(dst, shift, cr); 8867 %} 8868 %} 8869 8870 // Rotate Left by variable 8871 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8872 %{ 8873 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8874 8875 expand %{ 8876 rolI_rReg_CL(dst, shift, cr); 8877 %} 8878 %} 8879 8880 // ROR expand 8881 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8882 %{ 8883 effect(USE_DEF dst, KILL cr); 8884 8885 format %{ "rorl $dst" %} 8886 opcode(0xD1, 0x1); /* D1 /1 */ 8887 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8888 ins_pipe(ialu_reg); 8889 %} 8890 8891 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8892 %{ 8893 effect(USE_DEF dst, USE shift, KILL cr); 8894 8895 format %{ "rorl $dst, $shift" %} 8896 opcode(0xC1, 0x1); /* C1 /1 ib */ 8897 ins_encode(reg_opc_imm(dst, shift)); 8898 ins_pipe(ialu_reg); 8899 %} 8900 8901 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8902 %{ 8903 effect(USE_DEF dst, USE shift, KILL cr); 8904 8905 format %{ "rorl $dst, $shift" %} 8906 opcode(0xD3, 0x1); /* D3 /1 */ 8907 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8908 ins_pipe(ialu_reg_reg); 8909 %} 8910 // end of ROR expand 8911 8912 // Rotate Right by one 8913 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8914 %{ 8915 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8916 8917 expand %{ 8918 rorI_rReg_imm1(dst, cr); 8919 %} 8920 %} 8921 8922 // Rotate Right by 8-bit immediate 8923 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8924 %{ 8925 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8926 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8927 8928 expand %{ 8929 rorI_rReg_imm8(dst, rshift, cr); 8930 %} 8931 %} 8932 8933 // Rotate Right by variable 8934 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8935 %{ 8936 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8937 8938 expand %{ 8939 rorI_rReg_CL(dst, shift, cr); 8940 %} 8941 %} 8942 8943 // Rotate Right by variable 8944 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8945 %{ 8946 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8947 8948 expand %{ 8949 rorI_rReg_CL(dst, shift, cr); 8950 %} 8951 %} 8952 8953 // for long rotate 8954 // ROL expand 8955 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8956 effect(USE_DEF dst, KILL cr); 8957 8958 format %{ "rolq $dst" %} 8959 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8960 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8961 ins_pipe(ialu_reg); 8962 %} 8963 8964 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8965 effect(USE_DEF dst, USE shift, KILL cr); 8966 8967 format %{ "rolq $dst, $shift" %} 8968 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8969 ins_encode( reg_opc_imm_wide(dst, shift) ); 8970 ins_pipe(ialu_reg); 8971 %} 8972 8973 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8974 %{ 8975 effect(USE_DEF dst, USE shift, KILL cr); 8976 8977 format %{ "rolq $dst, $shift" %} 8978 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8979 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8980 ins_pipe(ialu_reg_reg); 8981 %} 8982 // end of ROL expand 8983 8984 // Rotate Left by one 8985 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8986 %{ 8987 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8988 8989 expand %{ 8990 rolL_rReg_imm1(dst, cr); 8991 %} 8992 %} 8993 8994 // Rotate Left by 8-bit immediate 8995 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8996 %{ 8997 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8998 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8999 9000 expand %{ 9001 rolL_rReg_imm8(dst, lshift, cr); 9002 %} 9003 %} 9004 9005 // Rotate Left by variable 9006 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9007 %{ 9008 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9009 9010 expand %{ 9011 rolL_rReg_CL(dst, shift, cr); 9012 %} 9013 %} 9014 9015 // Rotate Left by variable 9016 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9017 %{ 9018 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9019 9020 expand %{ 9021 rolL_rReg_CL(dst, shift, cr); 9022 %} 9023 %} 9024 9025 // ROR expand 9026 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9027 %{ 9028 effect(USE_DEF dst, KILL cr); 9029 9030 format %{ "rorq $dst" %} 9031 opcode(0xD1, 0x1); /* D1 /1 */ 9032 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9033 ins_pipe(ialu_reg); 9034 %} 9035 9036 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9037 %{ 9038 effect(USE_DEF dst, USE shift, KILL cr); 9039 9040 format %{ "rorq $dst, $shift" %} 9041 opcode(0xC1, 0x1); /* C1 /1 ib */ 9042 ins_encode(reg_opc_imm_wide(dst, shift)); 9043 ins_pipe(ialu_reg); 9044 %} 9045 9046 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9047 %{ 9048 effect(USE_DEF dst, USE shift, KILL cr); 9049 9050 format %{ "rorq $dst, $shift" %} 9051 opcode(0xD3, 0x1); /* D3 /1 */ 9052 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9053 ins_pipe(ialu_reg_reg); 9054 %} 9055 // end of ROR expand 9056 9057 // Rotate Right by one 9058 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9059 %{ 9060 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9061 9062 expand %{ 9063 rorL_rReg_imm1(dst, cr); 9064 %} 9065 %} 9066 9067 // Rotate Right by 8-bit immediate 9068 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9069 %{ 9070 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9071 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9072 9073 expand %{ 9074 rorL_rReg_imm8(dst, rshift, cr); 9075 %} 9076 %} 9077 9078 // Rotate Right by variable 9079 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9080 %{ 9081 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9082 9083 expand %{ 9084 rorL_rReg_CL(dst, shift, cr); 9085 %} 9086 %} 9087 9088 // Rotate Right by variable 9089 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9090 %{ 9091 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9092 9093 expand %{ 9094 rorL_rReg_CL(dst, shift, cr); 9095 %} 9096 %} 9097 9098 // Logical Instructions 9099 9100 // Integer Logical Instructions 9101 9102 // And Instructions 9103 // And Register with Register 9104 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9105 %{ 9106 match(Set dst (AndI dst src)); 9107 effect(KILL cr); 9108 9109 format %{ "andl $dst, $src\t# int" %} 9110 opcode(0x23); 9111 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9112 ins_pipe(ialu_reg_reg); 9113 %} 9114 9115 // And Register with Immediate 255 9116 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9117 %{ 9118 match(Set dst (AndI dst src)); 9119 9120 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9121 opcode(0x0F, 0xB6); 9122 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9123 ins_pipe(ialu_reg); 9124 %} 9125 9126 // And Register with Immediate 255 and promote to long 9127 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9128 %{ 9129 match(Set dst (ConvI2L (AndI src mask))); 9130 9131 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9132 opcode(0x0F, 0xB6); 9133 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9134 ins_pipe(ialu_reg); 9135 %} 9136 9137 // And Register with Immediate 65535 9138 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9139 %{ 9140 match(Set dst (AndI dst src)); 9141 9142 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9143 opcode(0x0F, 0xB7); 9144 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9145 ins_pipe(ialu_reg); 9146 %} 9147 9148 // And Register with Immediate 65535 and promote to long 9149 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9150 %{ 9151 match(Set dst (ConvI2L (AndI src mask))); 9152 9153 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9154 opcode(0x0F, 0xB7); 9155 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9156 ins_pipe(ialu_reg); 9157 %} 9158 9159 // And Register with Immediate 9160 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9161 %{ 9162 match(Set dst (AndI dst src)); 9163 effect(KILL cr); 9164 9165 format %{ "andl $dst, $src\t# int" %} 9166 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9167 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9168 ins_pipe(ialu_reg); 9169 %} 9170 9171 // And Register with Memory 9172 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9173 %{ 9174 match(Set dst (AndI dst (LoadI src))); 9175 effect(KILL cr); 9176 9177 ins_cost(125); 9178 format %{ "andl $dst, $src\t# int" %} 9179 opcode(0x23); 9180 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9181 ins_pipe(ialu_reg_mem); 9182 %} 9183 9184 // And Memory with Register 9185 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9186 %{ 9187 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9188 effect(KILL cr); 9189 9190 ins_cost(150); 9191 format %{ "andl $dst, $src\t# int" %} 9192 opcode(0x21); /* Opcode 21 /r */ 9193 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9194 ins_pipe(ialu_mem_reg); 9195 %} 9196 9197 // And Memory with Immediate 9198 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9199 %{ 9200 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9201 effect(KILL cr); 9202 9203 ins_cost(125); 9204 format %{ "andl $dst, $src\t# int" %} 9205 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9206 ins_encode(REX_mem(dst), OpcSE(src), 9207 RM_opc_mem(secondary, dst), Con8or32(src)); 9208 ins_pipe(ialu_mem_imm); 9209 %} 9210 9211 // BMI1 instructions 9212 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9213 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9214 predicate(UseBMI1Instructions); 9215 effect(KILL cr); 9216 9217 ins_cost(125); 9218 format %{ "andnl $dst, $src1, $src2" %} 9219 9220 ins_encode %{ 9221 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9222 %} 9223 ins_pipe(ialu_reg_mem); 9224 %} 9225 9226 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9227 match(Set dst (AndI (XorI src1 minus_1) src2)); 9228 predicate(UseBMI1Instructions); 9229 effect(KILL cr); 9230 9231 format %{ "andnl $dst, $src1, $src2" %} 9232 9233 ins_encode %{ 9234 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9235 %} 9236 ins_pipe(ialu_reg); 9237 %} 9238 9239 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9240 match(Set dst (AndI (SubI imm_zero src) src)); 9241 predicate(UseBMI1Instructions); 9242 effect(KILL cr); 9243 9244 format %{ "blsil $dst, $src" %} 9245 9246 ins_encode %{ 9247 __ blsil($dst$$Register, $src$$Register); 9248 %} 9249 ins_pipe(ialu_reg); 9250 %} 9251 9252 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9253 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9254 predicate(UseBMI1Instructions); 9255 effect(KILL cr); 9256 9257 ins_cost(125); 9258 format %{ "blsil $dst, $src" %} 9259 9260 ins_encode %{ 9261 __ blsil($dst$$Register, $src$$Address); 9262 %} 9263 ins_pipe(ialu_reg_mem); 9264 %} 9265 9266 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9267 %{ 9268 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9269 predicate(UseBMI1Instructions); 9270 effect(KILL cr); 9271 9272 ins_cost(125); 9273 format %{ "blsmskl $dst, $src" %} 9274 9275 ins_encode %{ 9276 __ blsmskl($dst$$Register, $src$$Address); 9277 %} 9278 ins_pipe(ialu_reg_mem); 9279 %} 9280 9281 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9282 %{ 9283 match(Set dst (XorI (AddI src minus_1) src)); 9284 predicate(UseBMI1Instructions); 9285 effect(KILL cr); 9286 9287 format %{ "blsmskl $dst, $src" %} 9288 9289 ins_encode %{ 9290 __ blsmskl($dst$$Register, $src$$Register); 9291 %} 9292 9293 ins_pipe(ialu_reg); 9294 %} 9295 9296 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9297 %{ 9298 match(Set dst (AndI (AddI src minus_1) src) ); 9299 predicate(UseBMI1Instructions); 9300 effect(KILL cr); 9301 9302 format %{ "blsrl $dst, $src" %} 9303 9304 ins_encode %{ 9305 __ blsrl($dst$$Register, $src$$Register); 9306 %} 9307 9308 ins_pipe(ialu_reg_mem); 9309 %} 9310 9311 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9312 %{ 9313 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9314 predicate(UseBMI1Instructions); 9315 effect(KILL cr); 9316 9317 ins_cost(125); 9318 format %{ "blsrl $dst, $src" %} 9319 9320 ins_encode %{ 9321 __ blsrl($dst$$Register, $src$$Address); 9322 %} 9323 9324 ins_pipe(ialu_reg); 9325 %} 9326 9327 // Or Instructions 9328 // Or Register with Register 9329 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9330 %{ 9331 match(Set dst (OrI dst src)); 9332 effect(KILL cr); 9333 9334 format %{ "orl $dst, $src\t# int" %} 9335 opcode(0x0B); 9336 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9337 ins_pipe(ialu_reg_reg); 9338 %} 9339 9340 // Or Register with Immediate 9341 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9342 %{ 9343 match(Set dst (OrI dst src)); 9344 effect(KILL cr); 9345 9346 format %{ "orl $dst, $src\t# int" %} 9347 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9348 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9349 ins_pipe(ialu_reg); 9350 %} 9351 9352 // Or Register with Memory 9353 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9354 %{ 9355 match(Set dst (OrI dst (LoadI src))); 9356 effect(KILL cr); 9357 9358 ins_cost(125); 9359 format %{ "orl $dst, $src\t# int" %} 9360 opcode(0x0B); 9361 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9362 ins_pipe(ialu_reg_mem); 9363 %} 9364 9365 // Or Memory with Register 9366 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9367 %{ 9368 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9369 effect(KILL cr); 9370 9371 ins_cost(150); 9372 format %{ "orl $dst, $src\t# int" %} 9373 opcode(0x09); /* Opcode 09 /r */ 9374 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9375 ins_pipe(ialu_mem_reg); 9376 %} 9377 9378 // Or Memory with Immediate 9379 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9380 %{ 9381 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9382 effect(KILL cr); 9383 9384 ins_cost(125); 9385 format %{ "orl $dst, $src\t# int" %} 9386 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9387 ins_encode(REX_mem(dst), OpcSE(src), 9388 RM_opc_mem(secondary, dst), Con8or32(src)); 9389 ins_pipe(ialu_mem_imm); 9390 %} 9391 9392 // Xor Instructions 9393 // Xor Register with Register 9394 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9395 %{ 9396 match(Set dst (XorI dst src)); 9397 effect(KILL cr); 9398 9399 format %{ "xorl $dst, $src\t# int" %} 9400 opcode(0x33); 9401 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9402 ins_pipe(ialu_reg_reg); 9403 %} 9404 9405 // Xor Register with Immediate -1 9406 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9407 match(Set dst (XorI dst imm)); 9408 9409 format %{ "not $dst" %} 9410 ins_encode %{ 9411 __ notl($dst$$Register); 9412 %} 9413 ins_pipe(ialu_reg); 9414 %} 9415 9416 // Xor Register with Immediate 9417 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9418 %{ 9419 match(Set dst (XorI dst src)); 9420 effect(KILL cr); 9421 9422 format %{ "xorl $dst, $src\t# int" %} 9423 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9424 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9425 ins_pipe(ialu_reg); 9426 %} 9427 9428 // Xor Register with Memory 9429 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9430 %{ 9431 match(Set dst (XorI dst (LoadI src))); 9432 effect(KILL cr); 9433 9434 ins_cost(125); 9435 format %{ "xorl $dst, $src\t# int" %} 9436 opcode(0x33); 9437 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9438 ins_pipe(ialu_reg_mem); 9439 %} 9440 9441 // Xor Memory with Register 9442 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9443 %{ 9444 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9445 effect(KILL cr); 9446 9447 ins_cost(150); 9448 format %{ "xorl $dst, $src\t# int" %} 9449 opcode(0x31); /* Opcode 31 /r */ 9450 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9451 ins_pipe(ialu_mem_reg); 9452 %} 9453 9454 // Xor Memory with Immediate 9455 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9456 %{ 9457 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9458 effect(KILL cr); 9459 9460 ins_cost(125); 9461 format %{ "xorl $dst, $src\t# int" %} 9462 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9463 ins_encode(REX_mem(dst), OpcSE(src), 9464 RM_opc_mem(secondary, dst), Con8or32(src)); 9465 ins_pipe(ialu_mem_imm); 9466 %} 9467 9468 9469 // Long Logical Instructions 9470 9471 // And Instructions 9472 // And Register with Register 9473 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9474 %{ 9475 match(Set dst (AndL dst src)); 9476 effect(KILL cr); 9477 9478 format %{ "andq $dst, $src\t# long" %} 9479 opcode(0x23); 9480 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9481 ins_pipe(ialu_reg_reg); 9482 %} 9483 9484 // And Register with Immediate 255 9485 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9486 %{ 9487 match(Set dst (AndL dst src)); 9488 9489 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9490 opcode(0x0F, 0xB6); 9491 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9492 ins_pipe(ialu_reg); 9493 %} 9494 9495 // And Register with Immediate 65535 9496 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9497 %{ 9498 match(Set dst (AndL dst src)); 9499 9500 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9501 opcode(0x0F, 0xB7); 9502 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9503 ins_pipe(ialu_reg); 9504 %} 9505 9506 // And Register with Immediate 9507 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9508 %{ 9509 match(Set dst (AndL dst src)); 9510 effect(KILL cr); 9511 9512 format %{ "andq $dst, $src\t# long" %} 9513 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9514 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9515 ins_pipe(ialu_reg); 9516 %} 9517 9518 // And Register with Memory 9519 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9520 %{ 9521 match(Set dst (AndL dst (LoadL src))); 9522 effect(KILL cr); 9523 9524 ins_cost(125); 9525 format %{ "andq $dst, $src\t# long" %} 9526 opcode(0x23); 9527 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9528 ins_pipe(ialu_reg_mem); 9529 %} 9530 9531 // And Memory with Register 9532 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9533 %{ 9534 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9535 effect(KILL cr); 9536 9537 ins_cost(150); 9538 format %{ "andq $dst, $src\t# long" %} 9539 opcode(0x21); /* Opcode 21 /r */ 9540 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9541 ins_pipe(ialu_mem_reg); 9542 %} 9543 9544 // And Memory with Immediate 9545 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9546 %{ 9547 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9548 effect(KILL cr); 9549 9550 ins_cost(125); 9551 format %{ "andq $dst, $src\t# long" %} 9552 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9553 ins_encode(REX_mem_wide(dst), OpcSE(src), 9554 RM_opc_mem(secondary, dst), Con8or32(src)); 9555 ins_pipe(ialu_mem_imm); 9556 %} 9557 9558 // BMI1 instructions 9559 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9560 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9561 predicate(UseBMI1Instructions); 9562 effect(KILL cr); 9563 9564 ins_cost(125); 9565 format %{ "andnq $dst, $src1, $src2" %} 9566 9567 ins_encode %{ 9568 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9569 %} 9570 ins_pipe(ialu_reg_mem); 9571 %} 9572 9573 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9574 match(Set dst (AndL (XorL src1 minus_1) src2)); 9575 predicate(UseBMI1Instructions); 9576 effect(KILL cr); 9577 9578 format %{ "andnq $dst, $src1, $src2" %} 9579 9580 ins_encode %{ 9581 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9582 %} 9583 ins_pipe(ialu_reg_mem); 9584 %} 9585 9586 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9587 match(Set dst (AndL (SubL imm_zero src) src)); 9588 predicate(UseBMI1Instructions); 9589 effect(KILL cr); 9590 9591 format %{ "blsiq $dst, $src" %} 9592 9593 ins_encode %{ 9594 __ blsiq($dst$$Register, $src$$Register); 9595 %} 9596 ins_pipe(ialu_reg); 9597 %} 9598 9599 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9600 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9601 predicate(UseBMI1Instructions); 9602 effect(KILL cr); 9603 9604 ins_cost(125); 9605 format %{ "blsiq $dst, $src" %} 9606 9607 ins_encode %{ 9608 __ blsiq($dst$$Register, $src$$Address); 9609 %} 9610 ins_pipe(ialu_reg_mem); 9611 %} 9612 9613 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9614 %{ 9615 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9616 predicate(UseBMI1Instructions); 9617 effect(KILL cr); 9618 9619 ins_cost(125); 9620 format %{ "blsmskq $dst, $src" %} 9621 9622 ins_encode %{ 9623 __ blsmskq($dst$$Register, $src$$Address); 9624 %} 9625 ins_pipe(ialu_reg_mem); 9626 %} 9627 9628 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9629 %{ 9630 match(Set dst (XorL (AddL src minus_1) src)); 9631 predicate(UseBMI1Instructions); 9632 effect(KILL cr); 9633 9634 format %{ "blsmskq $dst, $src" %} 9635 9636 ins_encode %{ 9637 __ blsmskq($dst$$Register, $src$$Register); 9638 %} 9639 9640 ins_pipe(ialu_reg); 9641 %} 9642 9643 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9644 %{ 9645 match(Set dst (AndL (AddL src minus_1) src) ); 9646 predicate(UseBMI1Instructions); 9647 effect(KILL cr); 9648 9649 format %{ "blsrq $dst, $src" %} 9650 9651 ins_encode %{ 9652 __ blsrq($dst$$Register, $src$$Register); 9653 %} 9654 9655 ins_pipe(ialu_reg); 9656 %} 9657 9658 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9659 %{ 9660 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9661 predicate(UseBMI1Instructions); 9662 effect(KILL cr); 9663 9664 ins_cost(125); 9665 format %{ "blsrq $dst, $src" %} 9666 9667 ins_encode %{ 9668 __ blsrq($dst$$Register, $src$$Address); 9669 %} 9670 9671 ins_pipe(ialu_reg); 9672 %} 9673 9674 // Or Instructions 9675 // Or Register with Register 9676 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9677 %{ 9678 match(Set dst (OrL dst src)); 9679 effect(KILL cr); 9680 9681 format %{ "orq $dst, $src\t# long" %} 9682 opcode(0x0B); 9683 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9684 ins_pipe(ialu_reg_reg); 9685 %} 9686 9687 // Use any_RegP to match R15 (TLS register) without spilling. 9688 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9689 match(Set dst (OrL dst (CastP2X src))); 9690 effect(KILL cr); 9691 9692 format %{ "orq $dst, $src\t# long" %} 9693 opcode(0x0B); 9694 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9695 ins_pipe(ialu_reg_reg); 9696 %} 9697 9698 9699 // Or Register with Immediate 9700 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9701 %{ 9702 match(Set dst (OrL dst src)); 9703 effect(KILL cr); 9704 9705 format %{ "orq $dst, $src\t# long" %} 9706 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9707 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9708 ins_pipe(ialu_reg); 9709 %} 9710 9711 // Or Register with Memory 9712 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9713 %{ 9714 match(Set dst (OrL dst (LoadL src))); 9715 effect(KILL cr); 9716 9717 ins_cost(125); 9718 format %{ "orq $dst, $src\t# long" %} 9719 opcode(0x0B); 9720 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9721 ins_pipe(ialu_reg_mem); 9722 %} 9723 9724 // Or Memory with Register 9725 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9726 %{ 9727 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9728 effect(KILL cr); 9729 9730 ins_cost(150); 9731 format %{ "orq $dst, $src\t# long" %} 9732 opcode(0x09); /* Opcode 09 /r */ 9733 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9734 ins_pipe(ialu_mem_reg); 9735 %} 9736 9737 // Or Memory with Immediate 9738 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9739 %{ 9740 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9741 effect(KILL cr); 9742 9743 ins_cost(125); 9744 format %{ "orq $dst, $src\t# long" %} 9745 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9746 ins_encode(REX_mem_wide(dst), OpcSE(src), 9747 RM_opc_mem(secondary, dst), Con8or32(src)); 9748 ins_pipe(ialu_mem_imm); 9749 %} 9750 9751 // Xor Instructions 9752 // Xor Register with Register 9753 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9754 %{ 9755 match(Set dst (XorL dst src)); 9756 effect(KILL cr); 9757 9758 format %{ "xorq $dst, $src\t# long" %} 9759 opcode(0x33); 9760 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9761 ins_pipe(ialu_reg_reg); 9762 %} 9763 9764 // Xor Register with Immediate -1 9765 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9766 match(Set dst (XorL dst imm)); 9767 9768 format %{ "notq $dst" %} 9769 ins_encode %{ 9770 __ notq($dst$$Register); 9771 %} 9772 ins_pipe(ialu_reg); 9773 %} 9774 9775 // Xor Register with Immediate 9776 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9777 %{ 9778 match(Set dst (XorL dst src)); 9779 effect(KILL cr); 9780 9781 format %{ "xorq $dst, $src\t# long" %} 9782 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9783 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9784 ins_pipe(ialu_reg); 9785 %} 9786 9787 // Xor Register with Memory 9788 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9789 %{ 9790 match(Set dst (XorL dst (LoadL src))); 9791 effect(KILL cr); 9792 9793 ins_cost(125); 9794 format %{ "xorq $dst, $src\t# long" %} 9795 opcode(0x33); 9796 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9797 ins_pipe(ialu_reg_mem); 9798 %} 9799 9800 // Xor Memory with Register 9801 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9802 %{ 9803 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9804 effect(KILL cr); 9805 9806 ins_cost(150); 9807 format %{ "xorq $dst, $src\t# long" %} 9808 opcode(0x31); /* Opcode 31 /r */ 9809 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9810 ins_pipe(ialu_mem_reg); 9811 %} 9812 9813 // Xor Memory with Immediate 9814 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9815 %{ 9816 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9817 effect(KILL cr); 9818 9819 ins_cost(125); 9820 format %{ "xorq $dst, $src\t# long" %} 9821 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9822 ins_encode(REX_mem_wide(dst), OpcSE(src), 9823 RM_opc_mem(secondary, dst), Con8or32(src)); 9824 ins_pipe(ialu_mem_imm); 9825 %} 9826 9827 // Convert Int to Boolean 9828 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9829 %{ 9830 match(Set dst (Conv2B src)); 9831 effect(KILL cr); 9832 9833 format %{ "testl $src, $src\t# ci2b\n\t" 9834 "setnz $dst\n\t" 9835 "movzbl $dst, $dst" %} 9836 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9837 setNZ_reg(dst), 9838 REX_reg_breg(dst, dst), // movzbl 9839 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9840 ins_pipe(pipe_slow); // XXX 9841 %} 9842 9843 // Convert Pointer to Boolean 9844 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9845 %{ 9846 match(Set dst (Conv2B src)); 9847 effect(KILL cr); 9848 9849 format %{ "testq $src, $src\t# cp2b\n\t" 9850 "setnz $dst\n\t" 9851 "movzbl $dst, $dst" %} 9852 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9853 setNZ_reg(dst), 9854 REX_reg_breg(dst, dst), // movzbl 9855 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9856 ins_pipe(pipe_slow); // XXX 9857 %} 9858 9859 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9860 %{ 9861 match(Set dst (CmpLTMask p q)); 9862 effect(KILL cr); 9863 9864 ins_cost(400); 9865 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9866 "setlt $dst\n\t" 9867 "movzbl $dst, $dst\n\t" 9868 "negl $dst" %} 9869 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9870 setLT_reg(dst), 9871 REX_reg_breg(dst, dst), // movzbl 9872 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9873 neg_reg(dst)); 9874 ins_pipe(pipe_slow); 9875 %} 9876 9877 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9878 %{ 9879 match(Set dst (CmpLTMask dst zero)); 9880 effect(KILL cr); 9881 9882 ins_cost(100); 9883 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9884 ins_encode %{ 9885 __ sarl($dst$$Register, 31); 9886 %} 9887 ins_pipe(ialu_reg); 9888 %} 9889 9890 /* Better to save a register than avoid a branch */ 9891 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9892 %{ 9893 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9894 effect(KILL cr); 9895 ins_cost(300); 9896 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9897 "jge done\n\t" 9898 "addl $p,$y\n" 9899 "done: " %} 9900 ins_encode %{ 9901 Register Rp = $p$$Register; 9902 Register Rq = $q$$Register; 9903 Register Ry = $y$$Register; 9904 Label done; 9905 __ subl(Rp, Rq); 9906 __ jccb(Assembler::greaterEqual, done); 9907 __ addl(Rp, Ry); 9908 __ bind(done); 9909 %} 9910 ins_pipe(pipe_cmplt); 9911 %} 9912 9913 /* Better to save a register than avoid a branch */ 9914 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9915 %{ 9916 match(Set y (AndI (CmpLTMask p q) y)); 9917 effect(KILL cr); 9918 9919 ins_cost(300); 9920 9921 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9922 "jlt done\n\t" 9923 "xorl $y, $y\n" 9924 "done: " %} 9925 ins_encode %{ 9926 Register Rp = $p$$Register; 9927 Register Rq = $q$$Register; 9928 Register Ry = $y$$Register; 9929 Label done; 9930 __ cmpl(Rp, Rq); 9931 __ jccb(Assembler::less, done); 9932 __ xorl(Ry, Ry); 9933 __ bind(done); 9934 %} 9935 ins_pipe(pipe_cmplt); 9936 %} 9937 9938 9939 //---------- FP Instructions------------------------------------------------ 9940 9941 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9942 %{ 9943 match(Set cr (CmpF src1 src2)); 9944 9945 ins_cost(145); 9946 format %{ "ucomiss $src1, $src2\n\t" 9947 "jnp,s exit\n\t" 9948 "pushfq\t# saw NaN, set CF\n\t" 9949 "andq [rsp], #0xffffff2b\n\t" 9950 "popfq\n" 9951 "exit:" %} 9952 ins_encode %{ 9953 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9954 emit_cmpfp_fixup(_masm); 9955 %} 9956 ins_pipe(pipe_slow); 9957 %} 9958 9959 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9960 match(Set cr (CmpF src1 src2)); 9961 9962 ins_cost(100); 9963 format %{ "ucomiss $src1, $src2" %} 9964 ins_encode %{ 9965 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9966 %} 9967 ins_pipe(pipe_slow); 9968 %} 9969 9970 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9971 %{ 9972 match(Set cr (CmpF src1 (LoadF src2))); 9973 9974 ins_cost(145); 9975 format %{ "ucomiss $src1, $src2\n\t" 9976 "jnp,s exit\n\t" 9977 "pushfq\t# saw NaN, set CF\n\t" 9978 "andq [rsp], #0xffffff2b\n\t" 9979 "popfq\n" 9980 "exit:" %} 9981 ins_encode %{ 9982 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9983 emit_cmpfp_fixup(_masm); 9984 %} 9985 ins_pipe(pipe_slow); 9986 %} 9987 9988 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9989 match(Set cr (CmpF src1 (LoadF src2))); 9990 9991 ins_cost(100); 9992 format %{ "ucomiss $src1, $src2" %} 9993 ins_encode %{ 9994 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9995 %} 9996 ins_pipe(pipe_slow); 9997 %} 9998 9999 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10000 match(Set cr (CmpF src con)); 10001 10002 ins_cost(145); 10003 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10004 "jnp,s exit\n\t" 10005 "pushfq\t# saw NaN, set CF\n\t" 10006 "andq [rsp], #0xffffff2b\n\t" 10007 "popfq\n" 10008 "exit:" %} 10009 ins_encode %{ 10010 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10011 emit_cmpfp_fixup(_masm); 10012 %} 10013 ins_pipe(pipe_slow); 10014 %} 10015 10016 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10017 match(Set cr (CmpF src con)); 10018 ins_cost(100); 10019 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10020 ins_encode %{ 10021 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10022 %} 10023 ins_pipe(pipe_slow); 10024 %} 10025 10026 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10027 %{ 10028 match(Set cr (CmpD src1 src2)); 10029 10030 ins_cost(145); 10031 format %{ "ucomisd $src1, $src2\n\t" 10032 "jnp,s exit\n\t" 10033 "pushfq\t# saw NaN, set CF\n\t" 10034 "andq [rsp], #0xffffff2b\n\t" 10035 "popfq\n" 10036 "exit:" %} 10037 ins_encode %{ 10038 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10039 emit_cmpfp_fixup(_masm); 10040 %} 10041 ins_pipe(pipe_slow); 10042 %} 10043 10044 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10045 match(Set cr (CmpD src1 src2)); 10046 10047 ins_cost(100); 10048 format %{ "ucomisd $src1, $src2 test" %} 10049 ins_encode %{ 10050 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10051 %} 10052 ins_pipe(pipe_slow); 10053 %} 10054 10055 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10056 %{ 10057 match(Set cr (CmpD src1 (LoadD src2))); 10058 10059 ins_cost(145); 10060 format %{ "ucomisd $src1, $src2\n\t" 10061 "jnp,s exit\n\t" 10062 "pushfq\t# saw NaN, set CF\n\t" 10063 "andq [rsp], #0xffffff2b\n\t" 10064 "popfq\n" 10065 "exit:" %} 10066 ins_encode %{ 10067 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10068 emit_cmpfp_fixup(_masm); 10069 %} 10070 ins_pipe(pipe_slow); 10071 %} 10072 10073 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10074 match(Set cr (CmpD src1 (LoadD src2))); 10075 10076 ins_cost(100); 10077 format %{ "ucomisd $src1, $src2" %} 10078 ins_encode %{ 10079 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10080 %} 10081 ins_pipe(pipe_slow); 10082 %} 10083 10084 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10085 match(Set cr (CmpD src con)); 10086 10087 ins_cost(145); 10088 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10089 "jnp,s exit\n\t" 10090 "pushfq\t# saw NaN, set CF\n\t" 10091 "andq [rsp], #0xffffff2b\n\t" 10092 "popfq\n" 10093 "exit:" %} 10094 ins_encode %{ 10095 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10096 emit_cmpfp_fixup(_masm); 10097 %} 10098 ins_pipe(pipe_slow); 10099 %} 10100 10101 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10102 match(Set cr (CmpD src con)); 10103 ins_cost(100); 10104 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10105 ins_encode %{ 10106 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10107 %} 10108 ins_pipe(pipe_slow); 10109 %} 10110 10111 // Compare into -1,0,1 10112 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10113 %{ 10114 match(Set dst (CmpF3 src1 src2)); 10115 effect(KILL cr); 10116 10117 ins_cost(275); 10118 format %{ "ucomiss $src1, $src2\n\t" 10119 "movl $dst, #-1\n\t" 10120 "jp,s done\n\t" 10121 "jb,s done\n\t" 10122 "setne $dst\n\t" 10123 "movzbl $dst, $dst\n" 10124 "done:" %} 10125 ins_encode %{ 10126 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10127 emit_cmpfp3(_masm, $dst$$Register); 10128 %} 10129 ins_pipe(pipe_slow); 10130 %} 10131 10132 // Compare into -1,0,1 10133 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10134 %{ 10135 match(Set dst (CmpF3 src1 (LoadF src2))); 10136 effect(KILL cr); 10137 10138 ins_cost(275); 10139 format %{ "ucomiss $src1, $src2\n\t" 10140 "movl $dst, #-1\n\t" 10141 "jp,s done\n\t" 10142 "jb,s done\n\t" 10143 "setne $dst\n\t" 10144 "movzbl $dst, $dst\n" 10145 "done:" %} 10146 ins_encode %{ 10147 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10148 emit_cmpfp3(_masm, $dst$$Register); 10149 %} 10150 ins_pipe(pipe_slow); 10151 %} 10152 10153 // Compare into -1,0,1 10154 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10155 match(Set dst (CmpF3 src con)); 10156 effect(KILL cr); 10157 10158 ins_cost(275); 10159 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10160 "movl $dst, #-1\n\t" 10161 "jp,s done\n\t" 10162 "jb,s done\n\t" 10163 "setne $dst\n\t" 10164 "movzbl $dst, $dst\n" 10165 "done:" %} 10166 ins_encode %{ 10167 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10168 emit_cmpfp3(_masm, $dst$$Register); 10169 %} 10170 ins_pipe(pipe_slow); 10171 %} 10172 10173 // Compare into -1,0,1 10174 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10175 %{ 10176 match(Set dst (CmpD3 src1 src2)); 10177 effect(KILL cr); 10178 10179 ins_cost(275); 10180 format %{ "ucomisd $src1, $src2\n\t" 10181 "movl $dst, #-1\n\t" 10182 "jp,s done\n\t" 10183 "jb,s done\n\t" 10184 "setne $dst\n\t" 10185 "movzbl $dst, $dst\n" 10186 "done:" %} 10187 ins_encode %{ 10188 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10189 emit_cmpfp3(_masm, $dst$$Register); 10190 %} 10191 ins_pipe(pipe_slow); 10192 %} 10193 10194 // Compare into -1,0,1 10195 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10196 %{ 10197 match(Set dst (CmpD3 src1 (LoadD src2))); 10198 effect(KILL cr); 10199 10200 ins_cost(275); 10201 format %{ "ucomisd $src1, $src2\n\t" 10202 "movl $dst, #-1\n\t" 10203 "jp,s done\n\t" 10204 "jb,s done\n\t" 10205 "setne $dst\n\t" 10206 "movzbl $dst, $dst\n" 10207 "done:" %} 10208 ins_encode %{ 10209 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10210 emit_cmpfp3(_masm, $dst$$Register); 10211 %} 10212 ins_pipe(pipe_slow); 10213 %} 10214 10215 // Compare into -1,0,1 10216 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10217 match(Set dst (CmpD3 src con)); 10218 effect(KILL cr); 10219 10220 ins_cost(275); 10221 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10222 "movl $dst, #-1\n\t" 10223 "jp,s done\n\t" 10224 "jb,s done\n\t" 10225 "setne $dst\n\t" 10226 "movzbl $dst, $dst\n" 10227 "done:" %} 10228 ins_encode %{ 10229 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10230 emit_cmpfp3(_masm, $dst$$Register); 10231 %} 10232 ins_pipe(pipe_slow); 10233 %} 10234 10235 //----------Arithmetic Conversion Instructions--------------------------------- 10236 10237 instruct roundFloat_nop(regF dst) 10238 %{ 10239 match(Set dst (RoundFloat dst)); 10240 10241 ins_cost(0); 10242 ins_encode(); 10243 ins_pipe(empty); 10244 %} 10245 10246 instruct roundDouble_nop(regD dst) 10247 %{ 10248 match(Set dst (RoundDouble dst)); 10249 10250 ins_cost(0); 10251 ins_encode(); 10252 ins_pipe(empty); 10253 %} 10254 10255 instruct convF2D_reg_reg(regD dst, regF src) 10256 %{ 10257 match(Set dst (ConvF2D src)); 10258 10259 format %{ "cvtss2sd $dst, $src" %} 10260 ins_encode %{ 10261 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10262 %} 10263 ins_pipe(pipe_slow); // XXX 10264 %} 10265 10266 instruct convF2D_reg_mem(regD dst, memory src) 10267 %{ 10268 match(Set dst (ConvF2D (LoadF src))); 10269 10270 format %{ "cvtss2sd $dst, $src" %} 10271 ins_encode %{ 10272 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10273 %} 10274 ins_pipe(pipe_slow); // XXX 10275 %} 10276 10277 instruct convD2F_reg_reg(regF dst, regD src) 10278 %{ 10279 match(Set dst (ConvD2F src)); 10280 10281 format %{ "cvtsd2ss $dst, $src" %} 10282 ins_encode %{ 10283 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10284 %} 10285 ins_pipe(pipe_slow); // XXX 10286 %} 10287 10288 instruct convD2F_reg_mem(regF dst, memory src) 10289 %{ 10290 match(Set dst (ConvD2F (LoadD src))); 10291 10292 format %{ "cvtsd2ss $dst, $src" %} 10293 ins_encode %{ 10294 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10295 %} 10296 ins_pipe(pipe_slow); // XXX 10297 %} 10298 10299 // XXX do mem variants 10300 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10301 %{ 10302 match(Set dst (ConvF2I src)); 10303 effect(KILL cr); 10304 10305 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10306 "cmpl $dst, #0x80000000\n\t" 10307 "jne,s done\n\t" 10308 "subq rsp, #8\n\t" 10309 "movss [rsp], $src\n\t" 10310 "call f2i_fixup\n\t" 10311 "popq $dst\n" 10312 "done: "%} 10313 ins_encode %{ 10314 Label done; 10315 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10316 __ cmpl($dst$$Register, 0x80000000); 10317 __ jccb(Assembler::notEqual, done); 10318 __ subptr(rsp, 8); 10319 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10320 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10321 __ pop($dst$$Register); 10322 __ bind(done); 10323 %} 10324 ins_pipe(pipe_slow); 10325 %} 10326 10327 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10328 %{ 10329 match(Set dst (ConvF2L src)); 10330 effect(KILL cr); 10331 10332 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10333 "cmpq $dst, [0x8000000000000000]\n\t" 10334 "jne,s done\n\t" 10335 "subq rsp, #8\n\t" 10336 "movss [rsp], $src\n\t" 10337 "call f2l_fixup\n\t" 10338 "popq $dst\n" 10339 "done: "%} 10340 ins_encode %{ 10341 Label done; 10342 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10343 __ cmp64($dst$$Register, 10344 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10345 __ jccb(Assembler::notEqual, done); 10346 __ subptr(rsp, 8); 10347 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10348 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10349 __ pop($dst$$Register); 10350 __ bind(done); 10351 %} 10352 ins_pipe(pipe_slow); 10353 %} 10354 10355 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10356 %{ 10357 match(Set dst (ConvD2I src)); 10358 effect(KILL cr); 10359 10360 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10361 "cmpl $dst, #0x80000000\n\t" 10362 "jne,s done\n\t" 10363 "subq rsp, #8\n\t" 10364 "movsd [rsp], $src\n\t" 10365 "call d2i_fixup\n\t" 10366 "popq $dst\n" 10367 "done: "%} 10368 ins_encode %{ 10369 Label done; 10370 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10371 __ cmpl($dst$$Register, 0x80000000); 10372 __ jccb(Assembler::notEqual, done); 10373 __ subptr(rsp, 8); 10374 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10375 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10376 __ pop($dst$$Register); 10377 __ bind(done); 10378 %} 10379 ins_pipe(pipe_slow); 10380 %} 10381 10382 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10383 %{ 10384 match(Set dst (ConvD2L src)); 10385 effect(KILL cr); 10386 10387 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10388 "cmpq $dst, [0x8000000000000000]\n\t" 10389 "jne,s done\n\t" 10390 "subq rsp, #8\n\t" 10391 "movsd [rsp], $src\n\t" 10392 "call d2l_fixup\n\t" 10393 "popq $dst\n" 10394 "done: "%} 10395 ins_encode %{ 10396 Label done; 10397 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10398 __ cmp64($dst$$Register, 10399 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10400 __ jccb(Assembler::notEqual, done); 10401 __ subptr(rsp, 8); 10402 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10403 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10404 __ pop($dst$$Register); 10405 __ bind(done); 10406 %} 10407 ins_pipe(pipe_slow); 10408 %} 10409 10410 instruct convI2F_reg_reg(regF dst, rRegI src) 10411 %{ 10412 predicate(!UseXmmI2F); 10413 match(Set dst (ConvI2F src)); 10414 10415 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10416 ins_encode %{ 10417 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10418 %} 10419 ins_pipe(pipe_slow); // XXX 10420 %} 10421 10422 instruct convI2F_reg_mem(regF dst, memory src) 10423 %{ 10424 match(Set dst (ConvI2F (LoadI src))); 10425 10426 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10427 ins_encode %{ 10428 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10429 %} 10430 ins_pipe(pipe_slow); // XXX 10431 %} 10432 10433 instruct convI2D_reg_reg(regD dst, rRegI src) 10434 %{ 10435 predicate(!UseXmmI2D); 10436 match(Set dst (ConvI2D src)); 10437 10438 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10439 ins_encode %{ 10440 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10441 %} 10442 ins_pipe(pipe_slow); // XXX 10443 %} 10444 10445 instruct convI2D_reg_mem(regD dst, memory src) 10446 %{ 10447 match(Set dst (ConvI2D (LoadI src))); 10448 10449 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10450 ins_encode %{ 10451 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10452 %} 10453 ins_pipe(pipe_slow); // XXX 10454 %} 10455 10456 instruct convXI2F_reg(regF dst, rRegI src) 10457 %{ 10458 predicate(UseXmmI2F); 10459 match(Set dst (ConvI2F src)); 10460 10461 format %{ "movdl $dst, $src\n\t" 10462 "cvtdq2psl $dst, $dst\t# i2f" %} 10463 ins_encode %{ 10464 __ movdl($dst$$XMMRegister, $src$$Register); 10465 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10466 %} 10467 ins_pipe(pipe_slow); // XXX 10468 %} 10469 10470 instruct convXI2D_reg(regD dst, rRegI src) 10471 %{ 10472 predicate(UseXmmI2D); 10473 match(Set dst (ConvI2D src)); 10474 10475 format %{ "movdl $dst, $src\n\t" 10476 "cvtdq2pdl $dst, $dst\t# i2d" %} 10477 ins_encode %{ 10478 __ movdl($dst$$XMMRegister, $src$$Register); 10479 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10480 %} 10481 ins_pipe(pipe_slow); // XXX 10482 %} 10483 10484 instruct convL2F_reg_reg(regF dst, rRegL src) 10485 %{ 10486 match(Set dst (ConvL2F src)); 10487 10488 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10489 ins_encode %{ 10490 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10491 %} 10492 ins_pipe(pipe_slow); // XXX 10493 %} 10494 10495 instruct convL2F_reg_mem(regF dst, memory src) 10496 %{ 10497 match(Set dst (ConvL2F (LoadL src))); 10498 10499 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10500 ins_encode %{ 10501 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10502 %} 10503 ins_pipe(pipe_slow); // XXX 10504 %} 10505 10506 instruct convL2D_reg_reg(regD dst, rRegL src) 10507 %{ 10508 match(Set dst (ConvL2D src)); 10509 10510 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10511 ins_encode %{ 10512 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10513 %} 10514 ins_pipe(pipe_slow); // XXX 10515 %} 10516 10517 instruct convL2D_reg_mem(regD dst, memory src) 10518 %{ 10519 match(Set dst (ConvL2D (LoadL src))); 10520 10521 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10522 ins_encode %{ 10523 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10524 %} 10525 ins_pipe(pipe_slow); // XXX 10526 %} 10527 10528 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10529 %{ 10530 match(Set dst (ConvI2L src)); 10531 10532 ins_cost(125); 10533 format %{ "movslq $dst, $src\t# i2l" %} 10534 ins_encode %{ 10535 __ movslq($dst$$Register, $src$$Register); 10536 %} 10537 ins_pipe(ialu_reg_reg); 10538 %} 10539 10540 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10541 // %{ 10542 // match(Set dst (ConvI2L src)); 10543 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10544 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10545 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10546 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10547 // ((const TypeNode*) n)->type()->is_long()->_lo == 10548 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10549 10550 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10551 // ins_encode(enc_copy(dst, src)); 10552 // // opcode(0x63); // needs REX.W 10553 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10554 // ins_pipe(ialu_reg_reg); 10555 // %} 10556 10557 // Zero-extend convert int to long 10558 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10559 %{ 10560 match(Set dst (AndL (ConvI2L src) mask)); 10561 10562 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10563 ins_encode %{ 10564 if ($dst$$reg != $src$$reg) { 10565 __ movl($dst$$Register, $src$$Register); 10566 } 10567 %} 10568 ins_pipe(ialu_reg_reg); 10569 %} 10570 10571 // Zero-extend convert int to long 10572 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10573 %{ 10574 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10575 10576 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10577 ins_encode %{ 10578 __ movl($dst$$Register, $src$$Address); 10579 %} 10580 ins_pipe(ialu_reg_mem); 10581 %} 10582 10583 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10584 %{ 10585 match(Set dst (AndL src mask)); 10586 10587 format %{ "movl $dst, $src\t# zero-extend long" %} 10588 ins_encode %{ 10589 __ movl($dst$$Register, $src$$Register); 10590 %} 10591 ins_pipe(ialu_reg_reg); 10592 %} 10593 10594 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10595 %{ 10596 match(Set dst (ConvL2I src)); 10597 10598 format %{ "movl $dst, $src\t# l2i" %} 10599 ins_encode %{ 10600 __ movl($dst$$Register, $src$$Register); 10601 %} 10602 ins_pipe(ialu_reg_reg); 10603 %} 10604 10605 10606 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10607 match(Set dst (MoveF2I src)); 10608 effect(DEF dst, USE src); 10609 10610 ins_cost(125); 10611 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10612 ins_encode %{ 10613 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10614 %} 10615 ins_pipe(ialu_reg_mem); 10616 %} 10617 10618 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10619 match(Set dst (MoveI2F src)); 10620 effect(DEF dst, USE src); 10621 10622 ins_cost(125); 10623 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10624 ins_encode %{ 10625 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10626 %} 10627 ins_pipe(pipe_slow); 10628 %} 10629 10630 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10631 match(Set dst (MoveD2L src)); 10632 effect(DEF dst, USE src); 10633 10634 ins_cost(125); 10635 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10636 ins_encode %{ 10637 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10638 %} 10639 ins_pipe(ialu_reg_mem); 10640 %} 10641 10642 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10643 predicate(!UseXmmLoadAndClearUpper); 10644 match(Set dst (MoveL2D src)); 10645 effect(DEF dst, USE src); 10646 10647 ins_cost(125); 10648 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10649 ins_encode %{ 10650 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10651 %} 10652 ins_pipe(pipe_slow); 10653 %} 10654 10655 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10656 predicate(UseXmmLoadAndClearUpper); 10657 match(Set dst (MoveL2D src)); 10658 effect(DEF dst, USE src); 10659 10660 ins_cost(125); 10661 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10662 ins_encode %{ 10663 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10664 %} 10665 ins_pipe(pipe_slow); 10666 %} 10667 10668 10669 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10670 match(Set dst (MoveF2I src)); 10671 effect(DEF dst, USE src); 10672 10673 ins_cost(95); // XXX 10674 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10675 ins_encode %{ 10676 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10677 %} 10678 ins_pipe(pipe_slow); 10679 %} 10680 10681 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10682 match(Set dst (MoveI2F src)); 10683 effect(DEF dst, USE src); 10684 10685 ins_cost(100); 10686 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10687 ins_encode %{ 10688 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10689 %} 10690 ins_pipe( ialu_mem_reg ); 10691 %} 10692 10693 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10694 match(Set dst (MoveD2L src)); 10695 effect(DEF dst, USE src); 10696 10697 ins_cost(95); // XXX 10698 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10699 ins_encode %{ 10700 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10701 %} 10702 ins_pipe(pipe_slow); 10703 %} 10704 10705 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10706 match(Set dst (MoveL2D src)); 10707 effect(DEF dst, USE src); 10708 10709 ins_cost(100); 10710 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10711 ins_encode %{ 10712 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10713 %} 10714 ins_pipe(ialu_mem_reg); 10715 %} 10716 10717 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10718 match(Set dst (MoveF2I src)); 10719 effect(DEF dst, USE src); 10720 ins_cost(85); 10721 format %{ "movd $dst,$src\t# MoveF2I" %} 10722 ins_encode %{ 10723 __ movdl($dst$$Register, $src$$XMMRegister); 10724 %} 10725 ins_pipe( pipe_slow ); 10726 %} 10727 10728 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10729 match(Set dst (MoveD2L src)); 10730 effect(DEF dst, USE src); 10731 ins_cost(85); 10732 format %{ "movd $dst,$src\t# MoveD2L" %} 10733 ins_encode %{ 10734 __ movdq($dst$$Register, $src$$XMMRegister); 10735 %} 10736 ins_pipe( pipe_slow ); 10737 %} 10738 10739 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10740 match(Set dst (MoveI2F src)); 10741 effect(DEF dst, USE src); 10742 ins_cost(100); 10743 format %{ "movd $dst,$src\t# MoveI2F" %} 10744 ins_encode %{ 10745 __ movdl($dst$$XMMRegister, $src$$Register); 10746 %} 10747 ins_pipe( pipe_slow ); 10748 %} 10749 10750 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10751 match(Set dst (MoveL2D src)); 10752 effect(DEF dst, USE src); 10753 ins_cost(100); 10754 format %{ "movd $dst,$src\t# MoveL2D" %} 10755 ins_encode %{ 10756 __ movdq($dst$$XMMRegister, $src$$Register); 10757 %} 10758 ins_pipe( pipe_slow ); 10759 %} 10760 10761 10762 // ======================================================================= 10763 // fast clearing of an array 10764 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10765 Universe dummy, rFlagsReg cr) 10766 %{ 10767 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only()); 10768 match(Set dummy (ClearArray (Binary cnt base) val)); 10769 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 10770 10771 format %{ $$template 10772 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10773 $$emit$$"jg LARGE\n\t" 10774 $$emit$$"dec rcx\n\t" 10775 $$emit$$"js DONE\t# Zero length\n\t" 10776 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10777 $$emit$$"dec rcx\n\t" 10778 $$emit$$"jge LOOP\n\t" 10779 $$emit$$"jmp DONE\n\t" 10780 $$emit$$"# LARGE:\n\t" 10781 if (UseFastStosb) { 10782 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10783 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10784 } else if (UseXMMForObjInit) { 10785 $$emit$$"movdq $tmp, $val\n\t" 10786 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10787 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10788 $$emit$$"jmpq L_zero_64_bytes\n\t" 10789 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10790 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10791 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10792 $$emit$$"add 0x40,rax\n\t" 10793 $$emit$$"# L_zero_64_bytes:\n\t" 10794 $$emit$$"sub 0x8,rcx\n\t" 10795 $$emit$$"jge L_loop\n\t" 10796 $$emit$$"add 0x4,rcx\n\t" 10797 $$emit$$"jl L_tail\n\t" 10798 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10799 $$emit$$"add 0x20,rax\n\t" 10800 $$emit$$"sub 0x4,rcx\n\t" 10801 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10802 $$emit$$"add 0x4,rcx\n\t" 10803 $$emit$$"jle L_end\n\t" 10804 $$emit$$"dec rcx\n\t" 10805 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10806 $$emit$$"vmovq xmm0,(rax)\n\t" 10807 $$emit$$"add 0x8,rax\n\t" 10808 $$emit$$"dec rcx\n\t" 10809 $$emit$$"jge L_sloop\n\t" 10810 $$emit$$"# L_end:\n\t" 10811 } else { 10812 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10813 } 10814 $$emit$$"# DONE" 10815 %} 10816 ins_encode %{ 10817 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10818 $tmp$$XMMRegister, false, false); 10819 %} 10820 ins_pipe(pipe_slow); 10821 %} 10822 10823 instruct rep_stos_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10824 Universe dummy, rFlagsReg cr) 10825 %{ 10826 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only()); 10827 match(Set dummy (ClearArray (Binary cnt base) val)); 10828 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 10829 10830 format %{ $$template 10831 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10832 $$emit$$"jg LARGE\n\t" 10833 $$emit$$"dec rcx\n\t" 10834 $$emit$$"js DONE\t# Zero length\n\t" 10835 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10836 $$emit$$"dec rcx\n\t" 10837 $$emit$$"jge LOOP\n\t" 10838 $$emit$$"jmp DONE\n\t" 10839 $$emit$$"# LARGE:\n\t" 10840 if (UseXMMForObjInit) { 10841 $$emit$$"movdq $tmp, $val\n\t" 10842 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10843 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10844 $$emit$$"jmpq L_zero_64_bytes\n\t" 10845 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10846 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10847 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10848 $$emit$$"add 0x40,rax\n\t" 10849 $$emit$$"# L_zero_64_bytes:\n\t" 10850 $$emit$$"sub 0x8,rcx\n\t" 10851 $$emit$$"jge L_loop\n\t" 10852 $$emit$$"add 0x4,rcx\n\t" 10853 $$emit$$"jl L_tail\n\t" 10854 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10855 $$emit$$"add 0x20,rax\n\t" 10856 $$emit$$"sub 0x4,rcx\n\t" 10857 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10858 $$emit$$"add 0x4,rcx\n\t" 10859 $$emit$$"jle L_end\n\t" 10860 $$emit$$"dec rcx\n\t" 10861 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10862 $$emit$$"vmovq xmm0,(rax)\n\t" 10863 $$emit$$"add 0x8,rax\n\t" 10864 $$emit$$"dec rcx\n\t" 10865 $$emit$$"jge L_sloop\n\t" 10866 $$emit$$"# L_end:\n\t" 10867 } else { 10868 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10869 } 10870 $$emit$$"# DONE" 10871 %} 10872 ins_encode %{ 10873 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10874 $tmp$$XMMRegister, false, true); 10875 %} 10876 ins_pipe(pipe_slow); 10877 %} 10878 10879 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10880 Universe dummy, rFlagsReg cr) 10881 %{ 10882 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only()); 10883 match(Set dummy (ClearArray (Binary cnt base) val)); 10884 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 10885 10886 format %{ $$template 10887 if (UseFastStosb) { 10888 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10889 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10890 } else if (UseXMMForObjInit) { 10891 $$emit$$"movdq $tmp, $val\n\t" 10892 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10893 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10894 $$emit$$"jmpq L_zero_64_bytes\n\t" 10895 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10896 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10897 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10898 $$emit$$"add 0x40,rax\n\t" 10899 $$emit$$"# L_zero_64_bytes:\n\t" 10900 $$emit$$"sub 0x8,rcx\n\t" 10901 $$emit$$"jge L_loop\n\t" 10902 $$emit$$"add 0x4,rcx\n\t" 10903 $$emit$$"jl L_tail\n\t" 10904 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10905 $$emit$$"add 0x20,rax\n\t" 10906 $$emit$$"sub 0x4,rcx\n\t" 10907 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10908 $$emit$$"add 0x4,rcx\n\t" 10909 $$emit$$"jle L_end\n\t" 10910 $$emit$$"dec rcx\n\t" 10911 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10912 $$emit$$"vmovq xmm0,(rax)\n\t" 10913 $$emit$$"add 0x8,rax\n\t" 10914 $$emit$$"dec rcx\n\t" 10915 $$emit$$"jge L_sloop\n\t" 10916 $$emit$$"# L_end:\n\t" 10917 } else { 10918 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10919 } 10920 %} 10921 ins_encode %{ 10922 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10923 $tmp$$XMMRegister, true, false); 10924 %} 10925 ins_pipe(pipe_slow); 10926 %} 10927 10928 instruct rep_stos_large_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10929 Universe dummy, rFlagsReg cr) 10930 %{ 10931 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only()); 10932 match(Set dummy (ClearArray (Binary cnt base) val)); 10933 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL cr); 10934 10935 format %{ $$template 10936 if (UseXMMForObjInit) { 10937 $$emit$$"movdq $tmp, $val\n\t" 10938 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10939 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10940 $$emit$$"jmpq L_zero_64_bytes\n\t" 10941 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10942 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10943 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10944 $$emit$$"add 0x40,rax\n\t" 10945 $$emit$$"# L_zero_64_bytes:\n\t" 10946 $$emit$$"sub 0x8,rcx\n\t" 10947 $$emit$$"jge L_loop\n\t" 10948 $$emit$$"add 0x4,rcx\n\t" 10949 $$emit$$"jl L_tail\n\t" 10950 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10951 $$emit$$"add 0x20,rax\n\t" 10952 $$emit$$"sub 0x4,rcx\n\t" 10953 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10954 $$emit$$"add 0x4,rcx\n\t" 10955 $$emit$$"jle L_end\n\t" 10956 $$emit$$"dec rcx\n\t" 10957 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10958 $$emit$$"vmovq xmm0,(rax)\n\t" 10959 $$emit$$"add 0x8,rax\n\t" 10960 $$emit$$"dec rcx\n\t" 10961 $$emit$$"jge L_sloop\n\t" 10962 $$emit$$"# L_end:\n\t" 10963 } else { 10964 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10965 } 10966 %} 10967 ins_encode %{ 10968 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10969 $tmp$$XMMRegister, true, true); 10970 %} 10971 ins_pipe(pipe_slow); 10972 %} 10973 10974 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10975 rax_RegI result, regD tmp1, rFlagsReg cr) 10976 %{ 10977 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10978 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10979 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10980 10981 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10982 ins_encode %{ 10983 __ string_compare($str1$$Register, $str2$$Register, 10984 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10985 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 10986 %} 10987 ins_pipe( pipe_slow ); 10988 %} 10989 10990 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10991 rax_RegI result, regD tmp1, rFlagsReg cr) 10992 %{ 10993 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10994 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10995 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10996 10997 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10998 ins_encode %{ 10999 __ string_compare($str1$$Register, $str2$$Register, 11000 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11001 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11002 %} 11003 ins_pipe( pipe_slow ); 11004 %} 11005 11006 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11007 rax_RegI result, regD tmp1, rFlagsReg cr) 11008 %{ 11009 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11010 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11011 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11012 11013 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11014 ins_encode %{ 11015 __ string_compare($str1$$Register, $str2$$Register, 11016 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11017 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11018 %} 11019 ins_pipe( pipe_slow ); 11020 %} 11021 11022 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11023 rax_RegI result, regD tmp1, rFlagsReg cr) 11024 %{ 11025 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11026 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11027 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11028 11029 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11030 ins_encode %{ 11031 __ string_compare($str2$$Register, $str1$$Register, 11032 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11033 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11034 %} 11035 ins_pipe( pipe_slow ); 11036 %} 11037 11038 // fast search of substring with known size. 11039 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11040 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11041 %{ 11042 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11043 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11044 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11045 11046 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11047 ins_encode %{ 11048 int icnt2 = (int)$int_cnt2$$constant; 11049 if (icnt2 >= 16) { 11050 // IndexOf for constant substrings with size >= 16 elements 11051 // which don't need to be loaded through stack. 11052 __ string_indexofC8($str1$$Register, $str2$$Register, 11053 $cnt1$$Register, $cnt2$$Register, 11054 icnt2, $result$$Register, 11055 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11056 } else { 11057 // Small strings are loaded through stack if they cross page boundary. 11058 __ string_indexof($str1$$Register, $str2$$Register, 11059 $cnt1$$Register, $cnt2$$Register, 11060 icnt2, $result$$Register, 11061 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11062 } 11063 %} 11064 ins_pipe( pipe_slow ); 11065 %} 11066 11067 // fast search of substring with known size. 11068 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11069 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11070 %{ 11071 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11072 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11073 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11074 11075 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11076 ins_encode %{ 11077 int icnt2 = (int)$int_cnt2$$constant; 11078 if (icnt2 >= 8) { 11079 // IndexOf for constant substrings with size >= 8 elements 11080 // which don't need to be loaded through stack. 11081 __ string_indexofC8($str1$$Register, $str2$$Register, 11082 $cnt1$$Register, $cnt2$$Register, 11083 icnt2, $result$$Register, 11084 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11085 } else { 11086 // Small strings are loaded through stack if they cross page boundary. 11087 __ string_indexof($str1$$Register, $str2$$Register, 11088 $cnt1$$Register, $cnt2$$Register, 11089 icnt2, $result$$Register, 11090 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11091 } 11092 %} 11093 ins_pipe( pipe_slow ); 11094 %} 11095 11096 // fast search of substring with known size. 11097 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11098 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11099 %{ 11100 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11101 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11102 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11103 11104 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11105 ins_encode %{ 11106 int icnt2 = (int)$int_cnt2$$constant; 11107 if (icnt2 >= 8) { 11108 // IndexOf for constant substrings with size >= 8 elements 11109 // which don't need to be loaded through stack. 11110 __ string_indexofC8($str1$$Register, $str2$$Register, 11111 $cnt1$$Register, $cnt2$$Register, 11112 icnt2, $result$$Register, 11113 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11114 } else { 11115 // Small strings are loaded through stack if they cross page boundary. 11116 __ string_indexof($str1$$Register, $str2$$Register, 11117 $cnt1$$Register, $cnt2$$Register, 11118 icnt2, $result$$Register, 11119 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11120 } 11121 %} 11122 ins_pipe( pipe_slow ); 11123 %} 11124 11125 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11126 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11127 %{ 11128 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11129 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11130 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11131 11132 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11133 ins_encode %{ 11134 __ string_indexof($str1$$Register, $str2$$Register, 11135 $cnt1$$Register, $cnt2$$Register, 11136 (-1), $result$$Register, 11137 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11138 %} 11139 ins_pipe( pipe_slow ); 11140 %} 11141 11142 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11143 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11144 %{ 11145 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11146 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11147 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11148 11149 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11150 ins_encode %{ 11151 __ string_indexof($str1$$Register, $str2$$Register, 11152 $cnt1$$Register, $cnt2$$Register, 11153 (-1), $result$$Register, 11154 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11155 %} 11156 ins_pipe( pipe_slow ); 11157 %} 11158 11159 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11160 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11161 %{ 11162 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11163 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11164 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11165 11166 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11167 ins_encode %{ 11168 __ string_indexof($str1$$Register, $str2$$Register, 11169 $cnt1$$Register, $cnt2$$Register, 11170 (-1), $result$$Register, 11171 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11172 %} 11173 ins_pipe( pipe_slow ); 11174 %} 11175 11176 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11177 rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr) 11178 %{ 11179 predicate(UseSSE42Intrinsics); 11180 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11181 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11182 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11183 ins_encode %{ 11184 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11185 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11186 %} 11187 ins_pipe( pipe_slow ); 11188 %} 11189 11190 // fast string equals 11191 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11192 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11193 %{ 11194 match(Set result (StrEquals (Binary str1 str2) cnt)); 11195 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11196 11197 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11198 ins_encode %{ 11199 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11200 $cnt$$Register, $result$$Register, $tmp3$$Register, 11201 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11202 %} 11203 ins_pipe( pipe_slow ); 11204 %} 11205 11206 // fast array equals 11207 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11208 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11209 %{ 11210 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11211 match(Set result (AryEq ary1 ary2)); 11212 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11213 11214 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11215 ins_encode %{ 11216 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11217 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11218 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11219 %} 11220 ins_pipe( pipe_slow ); 11221 %} 11222 11223 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11224 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11225 %{ 11226 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11227 match(Set result (AryEq ary1 ary2)); 11228 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11229 11230 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11231 ins_encode %{ 11232 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11233 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11234 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11235 %} 11236 ins_pipe( pipe_slow ); 11237 %} 11238 11239 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11240 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11241 %{ 11242 match(Set result (HasNegatives ary1 len)); 11243 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11244 11245 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11246 ins_encode %{ 11247 __ has_negatives($ary1$$Register, $len$$Register, 11248 $result$$Register, $tmp3$$Register, 11249 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11250 %} 11251 ins_pipe( pipe_slow ); 11252 %} 11253 11254 // fast char[] to byte[] compression 11255 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11256 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11257 match(Set result (StrCompressedCopy src (Binary dst len))); 11258 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11259 11260 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11261 ins_encode %{ 11262 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11263 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11264 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11265 %} 11266 ins_pipe( pipe_slow ); 11267 %} 11268 11269 // fast byte[] to char[] inflation 11270 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11271 regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11272 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11273 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11274 11275 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11276 ins_encode %{ 11277 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11278 $tmp1$$XMMRegister, $tmp2$$Register); 11279 %} 11280 ins_pipe( pipe_slow ); 11281 %} 11282 11283 // encode char[] to byte[] in ISO_8859_1 11284 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11285 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11286 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11287 match(Set result (EncodeISOArray src (Binary dst len))); 11288 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11289 11290 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11291 ins_encode %{ 11292 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11293 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11294 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11295 %} 11296 ins_pipe( pipe_slow ); 11297 %} 11298 11299 //----------Overflow Math Instructions----------------------------------------- 11300 11301 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11302 %{ 11303 match(Set cr (OverflowAddI op1 op2)); 11304 effect(DEF cr, USE_KILL op1, USE op2); 11305 11306 format %{ "addl $op1, $op2\t# overflow check int" %} 11307 11308 ins_encode %{ 11309 __ addl($op1$$Register, $op2$$Register); 11310 %} 11311 ins_pipe(ialu_reg_reg); 11312 %} 11313 11314 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11315 %{ 11316 match(Set cr (OverflowAddI op1 op2)); 11317 effect(DEF cr, USE_KILL op1, USE op2); 11318 11319 format %{ "addl $op1, $op2\t# overflow check int" %} 11320 11321 ins_encode %{ 11322 __ addl($op1$$Register, $op2$$constant); 11323 %} 11324 ins_pipe(ialu_reg_reg); 11325 %} 11326 11327 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11328 %{ 11329 match(Set cr (OverflowAddL op1 op2)); 11330 effect(DEF cr, USE_KILL op1, USE op2); 11331 11332 format %{ "addq $op1, $op2\t# overflow check long" %} 11333 ins_encode %{ 11334 __ addq($op1$$Register, $op2$$Register); 11335 %} 11336 ins_pipe(ialu_reg_reg); 11337 %} 11338 11339 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11340 %{ 11341 match(Set cr (OverflowAddL op1 op2)); 11342 effect(DEF cr, USE_KILL op1, USE op2); 11343 11344 format %{ "addq $op1, $op2\t# overflow check long" %} 11345 ins_encode %{ 11346 __ addq($op1$$Register, $op2$$constant); 11347 %} 11348 ins_pipe(ialu_reg_reg); 11349 %} 11350 11351 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11352 %{ 11353 match(Set cr (OverflowSubI op1 op2)); 11354 11355 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11356 ins_encode %{ 11357 __ cmpl($op1$$Register, $op2$$Register); 11358 %} 11359 ins_pipe(ialu_reg_reg); 11360 %} 11361 11362 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11363 %{ 11364 match(Set cr (OverflowSubI op1 op2)); 11365 11366 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11367 ins_encode %{ 11368 __ cmpl($op1$$Register, $op2$$constant); 11369 %} 11370 ins_pipe(ialu_reg_reg); 11371 %} 11372 11373 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11374 %{ 11375 match(Set cr (OverflowSubL op1 op2)); 11376 11377 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11378 ins_encode %{ 11379 __ cmpq($op1$$Register, $op2$$Register); 11380 %} 11381 ins_pipe(ialu_reg_reg); 11382 %} 11383 11384 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11385 %{ 11386 match(Set cr (OverflowSubL op1 op2)); 11387 11388 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11389 ins_encode %{ 11390 __ cmpq($op1$$Register, $op2$$constant); 11391 %} 11392 ins_pipe(ialu_reg_reg); 11393 %} 11394 11395 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11396 %{ 11397 match(Set cr (OverflowSubI zero op2)); 11398 effect(DEF cr, USE_KILL op2); 11399 11400 format %{ "negl $op2\t# overflow check int" %} 11401 ins_encode %{ 11402 __ negl($op2$$Register); 11403 %} 11404 ins_pipe(ialu_reg_reg); 11405 %} 11406 11407 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11408 %{ 11409 match(Set cr (OverflowSubL zero op2)); 11410 effect(DEF cr, USE_KILL op2); 11411 11412 format %{ "negq $op2\t# overflow check long" %} 11413 ins_encode %{ 11414 __ negq($op2$$Register); 11415 %} 11416 ins_pipe(ialu_reg_reg); 11417 %} 11418 11419 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11420 %{ 11421 match(Set cr (OverflowMulI op1 op2)); 11422 effect(DEF cr, USE_KILL op1, USE op2); 11423 11424 format %{ "imull $op1, $op2\t# overflow check int" %} 11425 ins_encode %{ 11426 __ imull($op1$$Register, $op2$$Register); 11427 %} 11428 ins_pipe(ialu_reg_reg_alu0); 11429 %} 11430 11431 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11432 %{ 11433 match(Set cr (OverflowMulI op1 op2)); 11434 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11435 11436 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11437 ins_encode %{ 11438 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11439 %} 11440 ins_pipe(ialu_reg_reg_alu0); 11441 %} 11442 11443 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11444 %{ 11445 match(Set cr (OverflowMulL op1 op2)); 11446 effect(DEF cr, USE_KILL op1, USE op2); 11447 11448 format %{ "imulq $op1, $op2\t# overflow check long" %} 11449 ins_encode %{ 11450 __ imulq($op1$$Register, $op2$$Register); 11451 %} 11452 ins_pipe(ialu_reg_reg_alu0); 11453 %} 11454 11455 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11456 %{ 11457 match(Set cr (OverflowMulL op1 op2)); 11458 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11459 11460 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11461 ins_encode %{ 11462 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11463 %} 11464 ins_pipe(ialu_reg_reg_alu0); 11465 %} 11466 11467 11468 //----------Control Flow Instructions------------------------------------------ 11469 // Signed compare Instructions 11470 11471 // XXX more variants!! 11472 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11473 %{ 11474 match(Set cr (CmpI op1 op2)); 11475 effect(DEF cr, USE op1, USE op2); 11476 11477 format %{ "cmpl $op1, $op2" %} 11478 opcode(0x3B); /* Opcode 3B /r */ 11479 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11480 ins_pipe(ialu_cr_reg_reg); 11481 %} 11482 11483 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11484 %{ 11485 match(Set cr (CmpI op1 op2)); 11486 11487 format %{ "cmpl $op1, $op2" %} 11488 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11489 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11490 ins_pipe(ialu_cr_reg_imm); 11491 %} 11492 11493 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11494 %{ 11495 match(Set cr (CmpI op1 (LoadI op2))); 11496 11497 ins_cost(500); // XXX 11498 format %{ "cmpl $op1, $op2" %} 11499 opcode(0x3B); /* Opcode 3B /r */ 11500 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11501 ins_pipe(ialu_cr_reg_mem); 11502 %} 11503 11504 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11505 %{ 11506 match(Set cr (CmpI src zero)); 11507 11508 format %{ "testl $src, $src" %} 11509 opcode(0x85); 11510 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11511 ins_pipe(ialu_cr_reg_imm); 11512 %} 11513 11514 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11515 %{ 11516 match(Set cr (CmpI (AndI src con) zero)); 11517 11518 format %{ "testl $src, $con" %} 11519 opcode(0xF7, 0x00); 11520 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11521 ins_pipe(ialu_cr_reg_imm); 11522 %} 11523 11524 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11525 %{ 11526 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11527 11528 format %{ "testl $src, $mem" %} 11529 opcode(0x85); 11530 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11531 ins_pipe(ialu_cr_reg_mem); 11532 %} 11533 11534 // Unsigned compare Instructions; really, same as signed except they 11535 // produce an rFlagsRegU instead of rFlagsReg. 11536 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11537 %{ 11538 match(Set cr (CmpU op1 op2)); 11539 11540 format %{ "cmpl $op1, $op2\t# unsigned" %} 11541 opcode(0x3B); /* Opcode 3B /r */ 11542 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11543 ins_pipe(ialu_cr_reg_reg); 11544 %} 11545 11546 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11547 %{ 11548 match(Set cr (CmpU op1 op2)); 11549 11550 format %{ "cmpl $op1, $op2\t# unsigned" %} 11551 opcode(0x81,0x07); /* Opcode 81 /7 */ 11552 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11553 ins_pipe(ialu_cr_reg_imm); 11554 %} 11555 11556 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11557 %{ 11558 match(Set cr (CmpU op1 (LoadI op2))); 11559 11560 ins_cost(500); // XXX 11561 format %{ "cmpl $op1, $op2\t# unsigned" %} 11562 opcode(0x3B); /* Opcode 3B /r */ 11563 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11564 ins_pipe(ialu_cr_reg_mem); 11565 %} 11566 11567 // // // Cisc-spilled version of cmpU_rReg 11568 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11569 // //%{ 11570 // // match(Set cr (CmpU (LoadI op1) op2)); 11571 // // 11572 // // format %{ "CMPu $op1,$op2" %} 11573 // // ins_cost(500); 11574 // // opcode(0x39); /* Opcode 39 /r */ 11575 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11576 // //%} 11577 11578 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11579 %{ 11580 match(Set cr (CmpU src zero)); 11581 11582 format %{ "testl $src, $src\t# unsigned" %} 11583 opcode(0x85); 11584 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11585 ins_pipe(ialu_cr_reg_imm); 11586 %} 11587 11588 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11589 %{ 11590 match(Set cr (CmpP op1 op2)); 11591 11592 format %{ "cmpq $op1, $op2\t# ptr" %} 11593 opcode(0x3B); /* Opcode 3B /r */ 11594 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11595 ins_pipe(ialu_cr_reg_reg); 11596 %} 11597 11598 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11599 %{ 11600 match(Set cr (CmpP op1 (LoadP op2))); 11601 11602 ins_cost(500); // XXX 11603 format %{ "cmpq $op1, $op2\t# ptr" %} 11604 opcode(0x3B); /* Opcode 3B /r */ 11605 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11606 ins_pipe(ialu_cr_reg_mem); 11607 %} 11608 11609 // // // Cisc-spilled version of cmpP_rReg 11610 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11611 // //%{ 11612 // // match(Set cr (CmpP (LoadP op1) op2)); 11613 // // 11614 // // format %{ "CMPu $op1,$op2" %} 11615 // // ins_cost(500); 11616 // // opcode(0x39); /* Opcode 39 /r */ 11617 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11618 // //%} 11619 11620 // XXX this is generalized by compP_rReg_mem??? 11621 // Compare raw pointer (used in out-of-heap check). 11622 // Only works because non-oop pointers must be raw pointers 11623 // and raw pointers have no anti-dependencies. 11624 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11625 %{ 11626 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11627 match(Set cr (CmpP op1 (LoadP op2))); 11628 11629 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11630 opcode(0x3B); /* Opcode 3B /r */ 11631 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11632 ins_pipe(ialu_cr_reg_mem); 11633 %} 11634 11635 // This will generate a signed flags result. This should be OK since 11636 // any compare to a zero should be eq/neq. 11637 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11638 %{ 11639 match(Set cr (CmpP src zero)); 11640 11641 format %{ "testq $src, $src\t# ptr" %} 11642 opcode(0x85); 11643 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11644 ins_pipe(ialu_cr_reg_imm); 11645 %} 11646 11647 // This will generate a signed flags result. This should be OK since 11648 // any compare to a zero should be eq/neq. 11649 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11650 %{ 11651 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11652 match(Set cr (CmpP (LoadP op) zero)); 11653 11654 ins_cost(500); // XXX 11655 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11656 opcode(0xF7); /* Opcode F7 /0 */ 11657 ins_encode(REX_mem_wide(op), 11658 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11659 ins_pipe(ialu_cr_reg_imm); 11660 %} 11661 11662 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11663 %{ 11664 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11665 match(Set cr (CmpP (LoadP mem) zero)); 11666 11667 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11668 ins_encode %{ 11669 __ cmpq(r12, $mem$$Address); 11670 %} 11671 ins_pipe(ialu_cr_reg_mem); 11672 %} 11673 11674 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11675 %{ 11676 match(Set cr (CmpN op1 op2)); 11677 11678 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11679 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11680 ins_pipe(ialu_cr_reg_reg); 11681 %} 11682 11683 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11684 %{ 11685 match(Set cr (CmpN src (LoadN mem))); 11686 11687 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11688 ins_encode %{ 11689 __ cmpl($src$$Register, $mem$$Address); 11690 %} 11691 ins_pipe(ialu_cr_reg_mem); 11692 %} 11693 11694 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11695 match(Set cr (CmpN op1 op2)); 11696 11697 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11698 ins_encode %{ 11699 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11700 %} 11701 ins_pipe(ialu_cr_reg_imm); 11702 %} 11703 11704 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11705 %{ 11706 match(Set cr (CmpN src (LoadN mem))); 11707 11708 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11709 ins_encode %{ 11710 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11711 %} 11712 ins_pipe(ialu_cr_reg_mem); 11713 %} 11714 11715 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11716 match(Set cr (CmpN op1 op2)); 11717 11718 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11719 ins_encode %{ 11720 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11721 %} 11722 ins_pipe(ialu_cr_reg_imm); 11723 %} 11724 11725 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11726 %{ 11727 match(Set cr (CmpN src (LoadNKlass mem))); 11728 11729 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11730 ins_encode %{ 11731 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11732 %} 11733 ins_pipe(ialu_cr_reg_mem); 11734 %} 11735 11736 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11737 match(Set cr (CmpN src zero)); 11738 11739 format %{ "testl $src, $src\t# compressed ptr" %} 11740 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11741 ins_pipe(ialu_cr_reg_imm); 11742 %} 11743 11744 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11745 %{ 11746 predicate(Universe::narrow_oop_base() != NULL); 11747 match(Set cr (CmpN (LoadN mem) zero)); 11748 11749 ins_cost(500); // XXX 11750 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11751 ins_encode %{ 11752 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11753 %} 11754 ins_pipe(ialu_cr_reg_mem); 11755 %} 11756 11757 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11758 %{ 11759 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11760 match(Set cr (CmpN (LoadN mem) zero)); 11761 11762 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11763 ins_encode %{ 11764 __ cmpl(r12, $mem$$Address); 11765 %} 11766 ins_pipe(ialu_cr_reg_mem); 11767 %} 11768 11769 // Yanked all unsigned pointer compare operations. 11770 // Pointer compares are done with CmpP which is already unsigned. 11771 11772 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11773 %{ 11774 match(Set cr (CmpL op1 op2)); 11775 11776 format %{ "cmpq $op1, $op2" %} 11777 opcode(0x3B); /* Opcode 3B /r */ 11778 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11779 ins_pipe(ialu_cr_reg_reg); 11780 %} 11781 11782 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11783 %{ 11784 match(Set cr (CmpL op1 op2)); 11785 11786 format %{ "cmpq $op1, $op2" %} 11787 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11788 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11789 ins_pipe(ialu_cr_reg_imm); 11790 %} 11791 11792 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11793 %{ 11794 match(Set cr (CmpL op1 (LoadL op2))); 11795 11796 format %{ "cmpq $op1, $op2" %} 11797 opcode(0x3B); /* Opcode 3B /r */ 11798 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11799 ins_pipe(ialu_cr_reg_mem); 11800 %} 11801 11802 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11803 %{ 11804 match(Set cr (CmpL src zero)); 11805 11806 format %{ "testq $src, $src" %} 11807 opcode(0x85); 11808 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11809 ins_pipe(ialu_cr_reg_imm); 11810 %} 11811 11812 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11813 %{ 11814 match(Set cr (CmpL (AndL src con) zero)); 11815 11816 format %{ "testq $src, $con\t# long" %} 11817 opcode(0xF7, 0x00); 11818 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11819 ins_pipe(ialu_cr_reg_imm); 11820 %} 11821 11822 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11823 %{ 11824 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11825 11826 format %{ "testq $src, $mem" %} 11827 opcode(0x85); 11828 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11829 ins_pipe(ialu_cr_reg_mem); 11830 %} 11831 11832 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11833 %{ 11834 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11835 11836 format %{ "testq $src, $mem" %} 11837 opcode(0x85); 11838 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11839 ins_pipe(ialu_cr_reg_mem); 11840 %} 11841 11842 // Manifest a CmpL result in an integer register. Very painful. 11843 // This is the test to avoid. 11844 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11845 %{ 11846 match(Set dst (CmpL3 src1 src2)); 11847 effect(KILL flags); 11848 11849 ins_cost(275); // XXX 11850 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11851 "movl $dst, -1\n\t" 11852 "jl,s done\n\t" 11853 "setne $dst\n\t" 11854 "movzbl $dst, $dst\n\t" 11855 "done:" %} 11856 ins_encode(cmpl3_flag(src1, src2, dst)); 11857 ins_pipe(pipe_slow); 11858 %} 11859 11860 // Unsigned long compare Instructions; really, same as signed long except they 11861 // produce an rFlagsRegU instead of rFlagsReg. 11862 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11863 %{ 11864 match(Set cr (CmpUL op1 op2)); 11865 11866 format %{ "cmpq $op1, $op2\t# unsigned" %} 11867 opcode(0x3B); /* Opcode 3B /r */ 11868 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11869 ins_pipe(ialu_cr_reg_reg); 11870 %} 11871 11872 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11873 %{ 11874 match(Set cr (CmpUL op1 op2)); 11875 11876 format %{ "cmpq $op1, $op2\t# unsigned" %} 11877 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11878 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11879 ins_pipe(ialu_cr_reg_imm); 11880 %} 11881 11882 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11883 %{ 11884 match(Set cr (CmpUL op1 (LoadL op2))); 11885 11886 format %{ "cmpq $op1, $op2\t# unsigned" %} 11887 opcode(0x3B); /* Opcode 3B /r */ 11888 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11889 ins_pipe(ialu_cr_reg_mem); 11890 %} 11891 11892 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11893 %{ 11894 match(Set cr (CmpUL src zero)); 11895 11896 format %{ "testq $src, $src\t# unsigned" %} 11897 opcode(0x85); 11898 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11899 ins_pipe(ialu_cr_reg_imm); 11900 %} 11901 11902 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11903 %{ 11904 match(Set cr (CmpI (LoadB mem) imm)); 11905 11906 ins_cost(125); 11907 format %{ "cmpb $mem, $imm" %} 11908 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11909 ins_pipe(ialu_cr_reg_mem); 11910 %} 11911 11912 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 11913 %{ 11914 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11915 11916 ins_cost(125); 11917 format %{ "testb $mem, $imm" %} 11918 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11919 ins_pipe(ialu_cr_reg_mem); 11920 %} 11921 11922 //----------Max and Min-------------------------------------------------------- 11923 // Min Instructions 11924 11925 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11926 %{ 11927 effect(USE_DEF dst, USE src, USE cr); 11928 11929 format %{ "cmovlgt $dst, $src\t# min" %} 11930 opcode(0x0F, 0x4F); 11931 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11932 ins_pipe(pipe_cmov_reg); 11933 %} 11934 11935 11936 instruct minI_rReg(rRegI dst, rRegI src) 11937 %{ 11938 match(Set dst (MinI dst src)); 11939 11940 ins_cost(200); 11941 expand %{ 11942 rFlagsReg cr; 11943 compI_rReg(cr, dst, src); 11944 cmovI_reg_g(dst, src, cr); 11945 %} 11946 %} 11947 11948 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11949 %{ 11950 effect(USE_DEF dst, USE src, USE cr); 11951 11952 format %{ "cmovllt $dst, $src\t# max" %} 11953 opcode(0x0F, 0x4C); 11954 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11955 ins_pipe(pipe_cmov_reg); 11956 %} 11957 11958 11959 instruct maxI_rReg(rRegI dst, rRegI src) 11960 %{ 11961 match(Set dst (MaxI dst src)); 11962 11963 ins_cost(200); 11964 expand %{ 11965 rFlagsReg cr; 11966 compI_rReg(cr, dst, src); 11967 cmovI_reg_l(dst, src, cr); 11968 %} 11969 %} 11970 11971 // ============================================================================ 11972 // Branch Instructions 11973 11974 // Jump Direct - Label defines a relative address from JMP+1 11975 instruct jmpDir(label labl) 11976 %{ 11977 match(Goto); 11978 effect(USE labl); 11979 11980 ins_cost(300); 11981 format %{ "jmp $labl" %} 11982 size(5); 11983 ins_encode %{ 11984 Label* L = $labl$$label; 11985 __ jmp(*L, false); // Always long jump 11986 %} 11987 ins_pipe(pipe_jmp); 11988 %} 11989 11990 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11991 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11992 %{ 11993 match(If cop cr); 11994 effect(USE labl); 11995 11996 ins_cost(300); 11997 format %{ "j$cop $labl" %} 11998 size(6); 11999 ins_encode %{ 12000 Label* L = $labl$$label; 12001 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12002 %} 12003 ins_pipe(pipe_jcc); 12004 %} 12005 12006 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12007 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12008 %{ 12009 predicate(!n->has_vector_mask_set()); 12010 match(CountedLoopEnd cop cr); 12011 effect(USE labl); 12012 12013 ins_cost(300); 12014 format %{ "j$cop $labl\t# loop end" %} 12015 size(6); 12016 ins_encode %{ 12017 Label* L = $labl$$label; 12018 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12019 %} 12020 ins_pipe(pipe_jcc); 12021 %} 12022 12023 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12024 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12025 predicate(!n->has_vector_mask_set()); 12026 match(CountedLoopEnd cop cmp); 12027 effect(USE labl); 12028 12029 ins_cost(300); 12030 format %{ "j$cop,u $labl\t# loop end" %} 12031 size(6); 12032 ins_encode %{ 12033 Label* L = $labl$$label; 12034 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12035 %} 12036 ins_pipe(pipe_jcc); 12037 %} 12038 12039 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12040 predicate(!n->has_vector_mask_set()); 12041 match(CountedLoopEnd cop cmp); 12042 effect(USE labl); 12043 12044 ins_cost(200); 12045 format %{ "j$cop,u $labl\t# loop end" %} 12046 size(6); 12047 ins_encode %{ 12048 Label* L = $labl$$label; 12049 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12050 %} 12051 ins_pipe(pipe_jcc); 12052 %} 12053 12054 // mask version 12055 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12056 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12057 %{ 12058 predicate(n->has_vector_mask_set()); 12059 match(CountedLoopEnd cop cr); 12060 effect(USE labl); 12061 12062 ins_cost(400); 12063 format %{ "j$cop $labl\t# loop end\n\t" 12064 "restorevectmask \t# vector mask restore for loops" %} 12065 size(10); 12066 ins_encode %{ 12067 Label* L = $labl$$label; 12068 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12069 __ restorevectmask(); 12070 %} 12071 ins_pipe(pipe_jcc); 12072 %} 12073 12074 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12075 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12076 predicate(n->has_vector_mask_set()); 12077 match(CountedLoopEnd cop cmp); 12078 effect(USE labl); 12079 12080 ins_cost(400); 12081 format %{ "j$cop,u $labl\t# loop end\n\t" 12082 "restorevectmask \t# vector mask restore for loops" %} 12083 size(10); 12084 ins_encode %{ 12085 Label* L = $labl$$label; 12086 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12087 __ restorevectmask(); 12088 %} 12089 ins_pipe(pipe_jcc); 12090 %} 12091 12092 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12093 predicate(n->has_vector_mask_set()); 12094 match(CountedLoopEnd cop cmp); 12095 effect(USE labl); 12096 12097 ins_cost(300); 12098 format %{ "j$cop,u $labl\t# loop end\n\t" 12099 "restorevectmask \t# vector mask restore for loops" %} 12100 size(10); 12101 ins_encode %{ 12102 Label* L = $labl$$label; 12103 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12104 __ restorevectmask(); 12105 %} 12106 ins_pipe(pipe_jcc); 12107 %} 12108 12109 // Jump Direct Conditional - using unsigned comparison 12110 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12111 match(If cop cmp); 12112 effect(USE labl); 12113 12114 ins_cost(300); 12115 format %{ "j$cop,u $labl" %} 12116 size(6); 12117 ins_encode %{ 12118 Label* L = $labl$$label; 12119 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12120 %} 12121 ins_pipe(pipe_jcc); 12122 %} 12123 12124 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12125 match(If cop cmp); 12126 effect(USE labl); 12127 12128 ins_cost(200); 12129 format %{ "j$cop,u $labl" %} 12130 size(6); 12131 ins_encode %{ 12132 Label* L = $labl$$label; 12133 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12134 %} 12135 ins_pipe(pipe_jcc); 12136 %} 12137 12138 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12139 match(If cop cmp); 12140 effect(USE labl); 12141 12142 ins_cost(200); 12143 format %{ $$template 12144 if ($cop$$cmpcode == Assembler::notEqual) { 12145 $$emit$$"jp,u $labl\n\t" 12146 $$emit$$"j$cop,u $labl" 12147 } else { 12148 $$emit$$"jp,u done\n\t" 12149 $$emit$$"j$cop,u $labl\n\t" 12150 $$emit$$"done:" 12151 } 12152 %} 12153 ins_encode %{ 12154 Label* l = $labl$$label; 12155 if ($cop$$cmpcode == Assembler::notEqual) { 12156 __ jcc(Assembler::parity, *l, false); 12157 __ jcc(Assembler::notEqual, *l, false); 12158 } else if ($cop$$cmpcode == Assembler::equal) { 12159 Label done; 12160 __ jccb(Assembler::parity, done); 12161 __ jcc(Assembler::equal, *l, false); 12162 __ bind(done); 12163 } else { 12164 ShouldNotReachHere(); 12165 } 12166 %} 12167 ins_pipe(pipe_jcc); 12168 %} 12169 12170 // ============================================================================ 12171 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12172 // superklass array for an instance of the superklass. Set a hidden 12173 // internal cache on a hit (cache is checked with exposed code in 12174 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12175 // encoding ALSO sets flags. 12176 12177 instruct partialSubtypeCheck(rdi_RegP result, 12178 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12179 rFlagsReg cr) 12180 %{ 12181 match(Set result (PartialSubtypeCheck sub super)); 12182 effect(KILL rcx, KILL cr); 12183 12184 ins_cost(1100); // slightly larger than the next version 12185 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12186 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12187 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12188 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12189 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12190 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12191 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12192 "miss:\t" %} 12193 12194 opcode(0x1); // Force a XOR of RDI 12195 ins_encode(enc_PartialSubtypeCheck()); 12196 ins_pipe(pipe_slow); 12197 %} 12198 12199 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12200 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12201 immP0 zero, 12202 rdi_RegP result) 12203 %{ 12204 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12205 effect(KILL rcx, KILL result); 12206 12207 ins_cost(1000); 12208 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12209 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12210 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12211 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12212 "jne,s miss\t\t# Missed: flags nz\n\t" 12213 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12214 "miss:\t" %} 12215 12216 opcode(0x0); // No need to XOR RDI 12217 ins_encode(enc_PartialSubtypeCheck()); 12218 ins_pipe(pipe_slow); 12219 %} 12220 12221 // ============================================================================ 12222 // Branch Instructions -- short offset versions 12223 // 12224 // These instructions are used to replace jumps of a long offset (the default 12225 // match) with jumps of a shorter offset. These instructions are all tagged 12226 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12227 // match rules in general matching. Instead, the ADLC generates a conversion 12228 // method in the MachNode which can be used to do in-place replacement of the 12229 // long variant with the shorter variant. The compiler will determine if a 12230 // branch can be taken by the is_short_branch_offset() predicate in the machine 12231 // specific code section of the file. 12232 12233 // Jump Direct - Label defines a relative address from JMP+1 12234 instruct jmpDir_short(label labl) %{ 12235 match(Goto); 12236 effect(USE labl); 12237 12238 ins_cost(300); 12239 format %{ "jmp,s $labl" %} 12240 size(2); 12241 ins_encode %{ 12242 Label* L = $labl$$label; 12243 __ jmpb(*L); 12244 %} 12245 ins_pipe(pipe_jmp); 12246 ins_short_branch(1); 12247 %} 12248 12249 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12250 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12251 match(If cop cr); 12252 effect(USE labl); 12253 12254 ins_cost(300); 12255 format %{ "j$cop,s $labl" %} 12256 size(2); 12257 ins_encode %{ 12258 Label* L = $labl$$label; 12259 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12260 %} 12261 ins_pipe(pipe_jcc); 12262 ins_short_branch(1); 12263 %} 12264 12265 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12266 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12267 match(CountedLoopEnd cop cr); 12268 effect(USE labl); 12269 12270 ins_cost(300); 12271 format %{ "j$cop,s $labl\t# loop end" %} 12272 size(2); 12273 ins_encode %{ 12274 Label* L = $labl$$label; 12275 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12276 %} 12277 ins_pipe(pipe_jcc); 12278 ins_short_branch(1); 12279 %} 12280 12281 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12282 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12283 match(CountedLoopEnd cop cmp); 12284 effect(USE labl); 12285 12286 ins_cost(300); 12287 format %{ "j$cop,us $labl\t# loop end" %} 12288 size(2); 12289 ins_encode %{ 12290 Label* L = $labl$$label; 12291 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12292 %} 12293 ins_pipe(pipe_jcc); 12294 ins_short_branch(1); 12295 %} 12296 12297 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12298 match(CountedLoopEnd cop cmp); 12299 effect(USE labl); 12300 12301 ins_cost(300); 12302 format %{ "j$cop,us $labl\t# loop end" %} 12303 size(2); 12304 ins_encode %{ 12305 Label* L = $labl$$label; 12306 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12307 %} 12308 ins_pipe(pipe_jcc); 12309 ins_short_branch(1); 12310 %} 12311 12312 // Jump Direct Conditional - using unsigned comparison 12313 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12314 match(If cop cmp); 12315 effect(USE labl); 12316 12317 ins_cost(300); 12318 format %{ "j$cop,us $labl" %} 12319 size(2); 12320 ins_encode %{ 12321 Label* L = $labl$$label; 12322 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12323 %} 12324 ins_pipe(pipe_jcc); 12325 ins_short_branch(1); 12326 %} 12327 12328 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12329 match(If cop cmp); 12330 effect(USE labl); 12331 12332 ins_cost(300); 12333 format %{ "j$cop,us $labl" %} 12334 size(2); 12335 ins_encode %{ 12336 Label* L = $labl$$label; 12337 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12338 %} 12339 ins_pipe(pipe_jcc); 12340 ins_short_branch(1); 12341 %} 12342 12343 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12344 match(If cop cmp); 12345 effect(USE labl); 12346 12347 ins_cost(300); 12348 format %{ $$template 12349 if ($cop$$cmpcode == Assembler::notEqual) { 12350 $$emit$$"jp,u,s $labl\n\t" 12351 $$emit$$"j$cop,u,s $labl" 12352 } else { 12353 $$emit$$"jp,u,s done\n\t" 12354 $$emit$$"j$cop,u,s $labl\n\t" 12355 $$emit$$"done:" 12356 } 12357 %} 12358 size(4); 12359 ins_encode %{ 12360 Label* l = $labl$$label; 12361 if ($cop$$cmpcode == Assembler::notEqual) { 12362 __ jccb(Assembler::parity, *l); 12363 __ jccb(Assembler::notEqual, *l); 12364 } else if ($cop$$cmpcode == Assembler::equal) { 12365 Label done; 12366 __ jccb(Assembler::parity, done); 12367 __ jccb(Assembler::equal, *l); 12368 __ bind(done); 12369 } else { 12370 ShouldNotReachHere(); 12371 } 12372 %} 12373 ins_pipe(pipe_jcc); 12374 ins_short_branch(1); 12375 %} 12376 12377 // ============================================================================ 12378 // inlined locking and unlocking 12379 12380 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12381 predicate(Compile::current()->use_rtm()); 12382 match(Set cr (FastLock object box)); 12383 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12384 ins_cost(300); 12385 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12386 ins_encode %{ 12387 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12388 $scr$$Register, $cx1$$Register, $cx2$$Register, 12389 _counters, _rtm_counters, _stack_rtm_counters, 12390 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12391 true, ra_->C->profile_rtm()); 12392 %} 12393 ins_pipe(pipe_slow); 12394 %} 12395 12396 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12397 predicate(!Compile::current()->use_rtm()); 12398 match(Set cr (FastLock object box)); 12399 effect(TEMP tmp, TEMP scr, USE_KILL box); 12400 ins_cost(300); 12401 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12402 ins_encode %{ 12403 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12404 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12405 %} 12406 ins_pipe(pipe_slow); 12407 %} 12408 12409 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12410 match(Set cr (FastUnlock object box)); 12411 effect(TEMP tmp, USE_KILL box); 12412 ins_cost(300); 12413 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12414 ins_encode %{ 12415 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12416 %} 12417 ins_pipe(pipe_slow); 12418 %} 12419 12420 12421 // ============================================================================ 12422 // Safepoint Instructions 12423 instruct safePoint_poll(rFlagsReg cr) 12424 %{ 12425 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12426 match(SafePoint); 12427 effect(KILL cr); 12428 12429 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12430 "# Safepoint: poll for GC" %} 12431 ins_cost(125); 12432 ins_encode %{ 12433 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12434 __ testl(rax, addr); 12435 %} 12436 ins_pipe(ialu_reg_mem); 12437 %} 12438 12439 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12440 %{ 12441 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12442 match(SafePoint poll); 12443 effect(KILL cr, USE poll); 12444 12445 format %{ "testl rax, [$poll]\t" 12446 "# Safepoint: poll for GC" %} 12447 ins_cost(125); 12448 ins_encode %{ 12449 __ relocate(relocInfo::poll_type); 12450 __ testl(rax, Address($poll$$Register, 0)); 12451 %} 12452 ins_pipe(ialu_reg_mem); 12453 %} 12454 12455 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12456 %{ 12457 predicate(SafepointMechanism::uses_thread_local_poll()); 12458 match(SafePoint poll); 12459 effect(KILL cr, USE poll); 12460 12461 format %{ "testl rax, [$poll]\t" 12462 "# Safepoint: poll for GC" %} 12463 ins_cost(125); 12464 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12465 ins_encode %{ 12466 __ relocate(relocInfo::poll_type); 12467 address pre_pc = __ pc(); 12468 __ testl(rax, Address($poll$$Register, 0)); 12469 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12470 %} 12471 ins_pipe(ialu_reg_mem); 12472 %} 12473 12474 // ============================================================================ 12475 // Procedure Call/Return Instructions 12476 // Call Java Static Instruction 12477 // Note: If this code changes, the corresponding ret_addr_offset() and 12478 // compute_padding() functions will have to be adjusted. 12479 instruct CallStaticJavaDirect(method meth) %{ 12480 match(CallStaticJava); 12481 effect(USE meth); 12482 12483 ins_cost(300); 12484 format %{ "call,static " %} 12485 opcode(0xE8); /* E8 cd */ 12486 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12487 ins_pipe(pipe_slow); 12488 ins_alignment(4); 12489 %} 12490 12491 // Call Java Dynamic Instruction 12492 // Note: If this code changes, the corresponding ret_addr_offset() and 12493 // compute_padding() functions will have to be adjusted. 12494 instruct CallDynamicJavaDirect(method meth) 12495 %{ 12496 match(CallDynamicJava); 12497 effect(USE meth); 12498 12499 ins_cost(300); 12500 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12501 "call,dynamic " %} 12502 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12503 ins_pipe(pipe_slow); 12504 ins_alignment(4); 12505 %} 12506 12507 // Call Runtime Instruction 12508 instruct CallRuntimeDirect(method meth) 12509 %{ 12510 match(CallRuntime); 12511 effect(USE meth); 12512 12513 ins_cost(300); 12514 format %{ "call,runtime " %} 12515 ins_encode(clear_avx, Java_To_Runtime(meth)); 12516 ins_pipe(pipe_slow); 12517 %} 12518 12519 // Call runtime without safepoint 12520 instruct CallLeafDirect(method meth) 12521 %{ 12522 match(CallLeaf); 12523 effect(USE meth); 12524 12525 ins_cost(300); 12526 format %{ "call_leaf,runtime " %} 12527 ins_encode(clear_avx, Java_To_Runtime(meth)); 12528 ins_pipe(pipe_slow); 12529 %} 12530 12531 // Call runtime without safepoint 12532 // entry point is null, target holds the address to call 12533 instruct CallLeafNoFPInDirect(rRegP target) 12534 %{ 12535 predicate(n->as_Call()->entry_point() == NULL); 12536 match(CallLeafNoFP target); 12537 12538 ins_cost(300); 12539 format %{ "call_leaf_nofp,runtime indirect " %} 12540 ins_encode %{ 12541 __ call($target$$Register); 12542 %} 12543 12544 ins_pipe(pipe_slow); 12545 %} 12546 12547 instruct CallLeafNoFPDirect(method meth) 12548 %{ 12549 predicate(n->as_Call()->entry_point() != NULL); 12550 match(CallLeafNoFP); 12551 effect(USE meth); 12552 12553 ins_cost(300); 12554 format %{ "call_leaf_nofp,runtime " %} 12555 ins_encode(clear_avx, Java_To_Runtime(meth)); 12556 ins_pipe(pipe_slow); 12557 %} 12558 12559 // Return Instruction 12560 // Remove the return address & jump to it. 12561 // Notice: We always emit a nop after a ret to make sure there is room 12562 // for safepoint patching 12563 instruct Ret() 12564 %{ 12565 match(Return); 12566 12567 format %{ "ret" %} 12568 opcode(0xC3); 12569 ins_encode(OpcP); 12570 ins_pipe(pipe_jmp); 12571 %} 12572 12573 // Tail Call; Jump from runtime stub to Java code. 12574 // Also known as an 'interprocedural jump'. 12575 // Target of jump will eventually return to caller. 12576 // TailJump below removes the return address. 12577 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12578 %{ 12579 match(TailCall jump_target method_oop); 12580 12581 ins_cost(300); 12582 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12583 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12584 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12585 ins_pipe(pipe_jmp); 12586 %} 12587 12588 // Tail Jump; remove the return address; jump to target. 12589 // TailCall above leaves the return address around. 12590 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12591 %{ 12592 match(TailJump jump_target ex_oop); 12593 12594 ins_cost(300); 12595 format %{ "popq rdx\t# pop return address\n\t" 12596 "jmp $jump_target" %} 12597 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12598 ins_encode(Opcode(0x5a), // popq rdx 12599 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12600 ins_pipe(pipe_jmp); 12601 %} 12602 12603 // Create exception oop: created by stack-crawling runtime code. 12604 // Created exception is now available to this handler, and is setup 12605 // just prior to jumping to this handler. No code emitted. 12606 instruct CreateException(rax_RegP ex_oop) 12607 %{ 12608 match(Set ex_oop (CreateEx)); 12609 12610 size(0); 12611 // use the following format syntax 12612 format %{ "# exception oop is in rax; no code emitted" %} 12613 ins_encode(); 12614 ins_pipe(empty); 12615 %} 12616 12617 // Rethrow exception: 12618 // The exception oop will come in the first argument position. 12619 // Then JUMP (not call) to the rethrow stub code. 12620 instruct RethrowException() 12621 %{ 12622 match(Rethrow); 12623 12624 // use the following format syntax 12625 format %{ "jmp rethrow_stub" %} 12626 ins_encode(enc_rethrow); 12627 ins_pipe(pipe_jmp); 12628 %} 12629 12630 // 12631 // Execute ZGC load barrier (strong) slow path 12632 // 12633 12634 // When running without XMM regs 12635 instruct loadBarrierSlowRegNoVec(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_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 loadBarrierSlowRegXmmAndYmm(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 (LoadBarrierSlowReg 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 %{"LoadBarrierSlowRegXmm $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_slow_stub(d))); 12689 #else 12690 ShouldNotReachHere(); 12691 #endif 12692 %} 12693 ins_pipe(pipe_slow); 12694 %} 12695 12696 // For ZMM enabled processors 12697 instruct loadBarrierSlowRegZmm(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 (LoadBarrierSlowReg 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 %{"LoadBarrierSlowRegZmm $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_slow_stub(d))); 12732 #else 12733 ShouldNotReachHere(); 12734 #endif 12735 %} 12736 ins_pipe(pipe_slow); 12737 %} 12738 12739 // 12740 // Execute ZGC load barrier (weak) slow path 12741 // 12742 12743 // When running without XMM regs 12744 instruct loadBarrierWeakSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12745 12746 match(Set dst (LoadBarrierSlowReg mem)); 12747 predicate(MaxVectorSize < 16); 12748 12749 effect(DEF dst, KILL cr); 12750 12751 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12752 ins_encode %{ 12753 #if INCLUDE_ZGC 12754 Register d = $dst$$Register; 12755 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12756 12757 assert(d != r12, "Can't be R12!"); 12758 assert(d != r15, "Can't be R15!"); 12759 assert(d != rsp, "Can't be RSP!"); 12760 12761 __ lea(d, $mem$$Address); 12762 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12763 #else 12764 ShouldNotReachHere(); 12765 #endif 12766 %} 12767 ins_pipe(pipe_slow); 12768 %} 12769 12770 // For XMM and YMM enabled processors 12771 instruct loadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12772 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12773 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12774 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12775 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12776 12777 match(Set dst (LoadBarrierWeakSlowReg mem)); 12778 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12779 12780 effect(DEF dst, KILL cr, 12781 KILL x0, KILL x1, KILL x2, KILL x3, 12782 KILL x4, KILL x5, KILL x6, KILL x7, 12783 KILL x8, KILL x9, KILL x10, KILL x11, 12784 KILL x12, KILL x13, KILL x14, KILL x15); 12785 12786 format %{"LoadBarrierWeakSlowRegXmm $dst, $mem" %} 12787 ins_encode %{ 12788 #if INCLUDE_ZGC 12789 Register d = $dst$$Register; 12790 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12791 12792 assert(d != r12, "Can't be R12!"); 12793 assert(d != r15, "Can't be R15!"); 12794 assert(d != rsp, "Can't be RSP!"); 12795 12796 __ lea(d,$mem$$Address); 12797 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12798 #else 12799 ShouldNotReachHere(); 12800 #endif 12801 %} 12802 ins_pipe(pipe_slow); 12803 %} 12804 12805 // For ZMM enabled processors 12806 instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12807 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12808 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12809 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12810 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12811 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12812 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12813 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12814 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12815 12816 match(Set dst (LoadBarrierWeakSlowReg mem)); 12817 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12818 12819 effect(DEF dst, KILL cr, 12820 KILL x0, KILL x1, KILL x2, KILL x3, 12821 KILL x4, KILL x5, KILL x6, KILL x7, 12822 KILL x8, KILL x9, KILL x10, KILL x11, 12823 KILL x12, KILL x13, KILL x14, KILL x15, 12824 KILL x16, KILL x17, KILL x18, KILL x19, 12825 KILL x20, KILL x21, KILL x22, KILL x23, 12826 KILL x24, KILL x25, KILL x26, KILL x27, 12827 KILL x28, KILL x29, KILL x30, KILL x31); 12828 12829 format %{"LoadBarrierWeakSlowRegZmm $dst, $mem" %} 12830 ins_encode %{ 12831 #if INCLUDE_ZGC 12832 Register d = $dst$$Register; 12833 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12834 12835 assert(d != r12, "Can't be R12!"); 12836 assert(d != r15, "Can't be R15!"); 12837 assert(d != rsp, "Can't be RSP!"); 12838 12839 __ lea(d,$mem$$Address); 12840 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12841 #else 12842 ShouldNotReachHere(); 12843 #endif 12844 %} 12845 ins_pipe(pipe_slow); 12846 %} 12847 12848 // ============================================================================ 12849 // This name is KNOWN by the ADLC and cannot be changed. 12850 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12851 // for this guy. 12852 instruct tlsLoadP(r15_RegP dst) %{ 12853 match(Set dst (ThreadLocal)); 12854 effect(DEF dst); 12855 12856 size(0); 12857 format %{ "# TLS is in R15" %} 12858 ins_encode( /*empty encoding*/ ); 12859 ins_pipe(ialu_reg_reg); 12860 %} 12861 12862 12863 //----------PEEPHOLE RULES----------------------------------------------------- 12864 // These must follow all instruction definitions as they use the names 12865 // defined in the instructions definitions. 12866 // 12867 // peepmatch ( root_instr_name [preceding_instruction]* ); 12868 // 12869 // peepconstraint %{ 12870 // (instruction_number.operand_name relational_op instruction_number.operand_name 12871 // [, ...] ); 12872 // // instruction numbers are zero-based using left to right order in peepmatch 12873 // 12874 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12875 // // provide an instruction_number.operand_name for each operand that appears 12876 // // in the replacement instruction's match rule 12877 // 12878 // ---------VM FLAGS--------------------------------------------------------- 12879 // 12880 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12881 // 12882 // Each peephole rule is given an identifying number starting with zero and 12883 // increasing by one in the order seen by the parser. An individual peephole 12884 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12885 // on the command-line. 12886 // 12887 // ---------CURRENT LIMITATIONS---------------------------------------------- 12888 // 12889 // Only match adjacent instructions in same basic block 12890 // Only equality constraints 12891 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12892 // Only one replacement instruction 12893 // 12894 // ---------EXAMPLE---------------------------------------------------------- 12895 // 12896 // // pertinent parts of existing instructions in architecture description 12897 // instruct movI(rRegI dst, rRegI src) 12898 // %{ 12899 // match(Set dst (CopyI src)); 12900 // %} 12901 // 12902 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12903 // %{ 12904 // match(Set dst (AddI dst src)); 12905 // effect(KILL cr); 12906 // %} 12907 // 12908 // // Change (inc mov) to lea 12909 // peephole %{ 12910 // // increment preceeded by register-register move 12911 // peepmatch ( incI_rReg movI ); 12912 // // require that the destination register of the increment 12913 // // match the destination register of the move 12914 // peepconstraint ( 0.dst == 1.dst ); 12915 // // construct a replacement instruction that sets 12916 // // the destination to ( move's source register + one ) 12917 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12918 // %} 12919 // 12920 12921 // Implementation no longer uses movX instructions since 12922 // machine-independent system no longer uses CopyX nodes. 12923 // 12924 // peephole 12925 // %{ 12926 // peepmatch (incI_rReg movI); 12927 // peepconstraint (0.dst == 1.dst); 12928 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12929 // %} 12930 12931 // peephole 12932 // %{ 12933 // peepmatch (decI_rReg movI); 12934 // peepconstraint (0.dst == 1.dst); 12935 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12936 // %} 12937 12938 // peephole 12939 // %{ 12940 // peepmatch (addI_rReg_imm movI); 12941 // peepconstraint (0.dst == 1.dst); 12942 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12943 // %} 12944 12945 // peephole 12946 // %{ 12947 // peepmatch (incL_rReg movL); 12948 // peepconstraint (0.dst == 1.dst); 12949 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12950 // %} 12951 12952 // peephole 12953 // %{ 12954 // peepmatch (decL_rReg movL); 12955 // peepconstraint (0.dst == 1.dst); 12956 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12957 // %} 12958 12959 // peephole 12960 // %{ 12961 // peepmatch (addL_rReg_imm movL); 12962 // peepconstraint (0.dst == 1.dst); 12963 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12964 // %} 12965 12966 // peephole 12967 // %{ 12968 // peepmatch (addP_rReg_imm movP); 12969 // peepconstraint (0.dst == 1.dst); 12970 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12971 // %} 12972 12973 // // Change load of spilled value to only a spill 12974 // instruct storeI(memory mem, rRegI src) 12975 // %{ 12976 // match(Set mem (StoreI mem src)); 12977 // %} 12978 // 12979 // instruct loadI(rRegI dst, memory mem) 12980 // %{ 12981 // match(Set dst (LoadI mem)); 12982 // %} 12983 // 12984 12985 peephole 12986 %{ 12987 peepmatch (loadI storeI); 12988 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12989 peepreplace (storeI(1.mem 1.mem 1.src)); 12990 %} 12991 12992 peephole 12993 %{ 12994 peepmatch (loadL storeL); 12995 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12996 peepreplace (storeL(1.mem 1.mem 1.src)); 12997 %} 12998 12999 //----------SMARTSPILL RULES--------------------------------------------------- 13000 // These must follow all instruction definitions as they use the names 13001 // defined in the instructions definitions.