1 // 2 // Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // Specify priority of register selection within phases of register 135 // allocation. Highest priority is first. A useful heuristic is to 136 // give registers a low priority when they are required by machine 137 // instructions, like EAX and EDX on I486, and choose no-save registers 138 // before save-on-call, & save-on-call before save-on-entry. Registers 139 // which participate in fixed calling sequences should come last. 140 // Registers which are used as pairs must fall on an even boundary. 141 142 alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160 //----------Architecture Description Register Classes-------------------------- 161 // Several register classes are automatically defined based upon information in 162 // this architecture description. 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167 // 168 169 // Empty register class. 170 reg_class no_reg(); 171 172 // Class for all pointer registers (including RSP and RBP) 173 reg_class any_reg_with_rbp(RAX, RAX_H, 174 RDX, RDX_H, 175 RBP, RBP_H, 176 RDI, RDI_H, 177 RSI, RSI_H, 178 RCX, RCX_H, 179 RBX, RBX_H, 180 RSP, RSP_H, 181 R8, R8_H, 182 R9, R9_H, 183 R10, R10_H, 184 R11, R11_H, 185 R12, R12_H, 186 R13, R13_H, 187 R14, R14_H, 188 R15, R15_H); 189 190 // Class for all pointer registers (including RSP, but excluding RBP) 191 reg_class any_reg_no_rbp(RAX, RAX_H, 192 RDX, RDX_H, 193 RDI, RDI_H, 194 RSI, RSI_H, 195 RCX, RCX_H, 196 RBX, RBX_H, 197 RSP, RSP_H, 198 R8, R8_H, 199 R9, R9_H, 200 R10, R10_H, 201 R11, R11_H, 202 R12, R12_H, 203 R13, R13_H, 204 R14, R14_H, 205 R15, R15_H); 206 207 // Dynamic register class that selects at runtime between register classes 208 // any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer). 209 // Equivalent to: return PreserveFramePointer ? any_reg_no_rbp : any_reg_with_rbp; 210 reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %}); 211 212 // Class for all pointer registers (excluding RSP) 213 reg_class ptr_reg_with_rbp(RAX, RAX_H, 214 RDX, RDX_H, 215 RBP, RBP_H, 216 RDI, RDI_H, 217 RSI, RSI_H, 218 RCX, RCX_H, 219 RBX, RBX_H, 220 R8, R8_H, 221 R9, R9_H, 222 R10, R10_H, 223 R11, R11_H, 224 R13, R13_H, 225 R14, R14_H); 226 227 // Class for all pointer registers (excluding RSP and RBP) 228 reg_class ptr_reg_no_rbp(RAX, RAX_H, 229 RDX, RDX_H, 230 RDI, RDI_H, 231 RSI, RSI_H, 232 RCX, RCX_H, 233 RBX, RBX_H, 234 R8, R8_H, 235 R9, R9_H, 236 R10, R10_H, 237 R11, R11_H, 238 R13, R13_H, 239 R14, R14_H); 240 241 // Dynamic register class that selects between ptr_reg_no_rbp and ptr_reg_with_rbp. 242 reg_class_dynamic ptr_reg(ptr_reg_no_rbp, ptr_reg_with_rbp, %{ PreserveFramePointer %}); 243 244 // Class for all pointer registers (excluding RAX and RSP) 245 reg_class ptr_no_rax_reg_with_rbp(RDX, RDX_H, 246 RBP, RBP_H, 247 RDI, RDI_H, 248 RSI, RSI_H, 249 RCX, RCX_H, 250 RBX, RBX_H, 251 R8, R8_H, 252 R9, R9_H, 253 R10, R10_H, 254 R11, R11_H, 255 R13, R13_H, 256 R14, R14_H); 257 258 // Class for all pointer registers (excluding RAX, RSP, and RBP) 259 reg_class ptr_no_rax_reg_no_rbp(RDX, RDX_H, 260 RDI, RDI_H, 261 RSI, RSI_H, 262 RCX, RCX_H, 263 RBX, RBX_H, 264 R8, R8_H, 265 R9, R9_H, 266 R10, R10_H, 267 R11, R11_H, 268 R13, R13_H, 269 R14, R14_H); 270 271 // Dynamic register class that selects between ptr_no_rax_reg_no_rbp and ptr_no_rax_reg_with_rbp. 272 reg_class_dynamic ptr_no_rax_reg(ptr_no_rax_reg_no_rbp, ptr_no_rax_reg_with_rbp, %{ PreserveFramePointer %}); 273 274 // Class for all pointer registers (excluding RAX, RBX, and RSP) 275 reg_class ptr_no_rax_rbx_reg_with_rbp(RDX, RDX_H, 276 RBP, RBP_H, 277 RDI, RDI_H, 278 RSI, RSI_H, 279 RCX, RCX_H, 280 R8, R8_H, 281 R9, R9_H, 282 R10, R10_H, 283 R11, R11_H, 284 R13, R13_H, 285 R14, R14_H); 286 287 // Class for all pointer registers (excluding RAX, RBX, RSP, and RBP) 288 reg_class ptr_no_rax_rbx_reg_no_rbp(RDX, RDX_H, 289 RDI, RDI_H, 290 RSI, RSI_H, 291 RCX, RCX_H, 292 R8, R8_H, 293 R9, R9_H, 294 R10, R10_H, 295 R11, R11_H, 296 R13, R13_H, 297 R14, R14_H); 298 299 // Dynamic register class that selects between ptr_no_rax_rbx_reg_no_rbp and ptr_no_rax_rbx_reg_with_rbp. 300 reg_class_dynamic ptr_no_rax_rbx_reg(ptr_no_rax_rbx_reg_no_rbp, ptr_no_rax_rbx_reg_with_rbp, %{ PreserveFramePointer %}); 301 302 // Singleton class for RAX pointer register 303 reg_class ptr_rax_reg(RAX, RAX_H); 304 305 // Singleton class for RBX pointer register 306 reg_class ptr_rbx_reg(RBX, RBX_H); 307 308 // Singleton class for RSI pointer register 309 reg_class ptr_rsi_reg(RSI, RSI_H); 310 311 // Singleton class for RDI pointer register 312 reg_class ptr_rdi_reg(RDI, RDI_H); 313 314 // Singleton class for stack pointer 315 reg_class ptr_rsp_reg(RSP, RSP_H); 316 317 // Singleton class for TLS pointer 318 reg_class ptr_r15_reg(R15, R15_H); 319 320 // Class for all long registers (excluding RSP) 321 reg_class long_reg_with_rbp(RAX, RAX_H, 322 RDX, RDX_H, 323 RBP, RBP_H, 324 RDI, RDI_H, 325 RSI, RSI_H, 326 RCX, RCX_H, 327 RBX, RBX_H, 328 R8, R8_H, 329 R9, R9_H, 330 R10, R10_H, 331 R11, R11_H, 332 R13, R13_H, 333 R14, R14_H); 334 335 // Class for all long registers (excluding RSP and RBP) 336 reg_class long_reg_no_rbp(RAX, RAX_H, 337 RDX, RDX_H, 338 RDI, RDI_H, 339 RSI, RSI_H, 340 RCX, RCX_H, 341 RBX, RBX_H, 342 R8, R8_H, 343 R9, R9_H, 344 R10, R10_H, 345 R11, R11_H, 346 R13, R13_H, 347 R14, R14_H); 348 349 // Dynamic register class that selects between long_reg_no_rbp and long_reg_with_rbp. 350 reg_class_dynamic long_reg(long_reg_no_rbp, long_reg_with_rbp, %{ PreserveFramePointer %}); 351 352 // Class for all long registers (excluding RAX, RDX and RSP) 353 reg_class long_no_rax_rdx_reg_with_rbp(RBP, RBP_H, 354 RDI, RDI_H, 355 RSI, RSI_H, 356 RCX, RCX_H, 357 RBX, RBX_H, 358 R8, R8_H, 359 R9, R9_H, 360 R10, R10_H, 361 R11, R11_H, 362 R13, R13_H, 363 R14, R14_H); 364 365 // Class for all long registers (excluding RAX, RDX, RSP, and RBP) 366 reg_class long_no_rax_rdx_reg_no_rbp(RDI, RDI_H, 367 RSI, RSI_H, 368 RCX, RCX_H, 369 RBX, RBX_H, 370 R8, R8_H, 371 R9, R9_H, 372 R10, R10_H, 373 R11, R11_H, 374 R13, R13_H, 375 R14, R14_H); 376 377 // Dynamic register class that selects between long_no_rax_rdx_reg_no_rbp and long_no_rax_rdx_reg_with_rbp. 378 reg_class_dynamic long_no_rax_rdx_reg(long_no_rax_rdx_reg_no_rbp, long_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 379 380 // Class for all long registers (excluding RCX and RSP) 381 reg_class long_no_rcx_reg_with_rbp(RBP, RBP_H, 382 RDI, RDI_H, 383 RSI, RSI_H, 384 RAX, RAX_H, 385 RDX, RDX_H, 386 RBX, RBX_H, 387 R8, R8_H, 388 R9, R9_H, 389 R10, R10_H, 390 R11, R11_H, 391 R13, R13_H, 392 R14, R14_H); 393 394 // Class for all long registers (excluding RCX, RSP, and RBP) 395 reg_class long_no_rcx_reg_no_rbp(RDI, RDI_H, 396 RSI, RSI_H, 397 RAX, RAX_H, 398 RDX, RDX_H, 399 RBX, RBX_H, 400 R8, R8_H, 401 R9, R9_H, 402 R10, R10_H, 403 R11, R11_H, 404 R13, R13_H, 405 R14, R14_H); 406 407 // Dynamic register class that selects between long_no_rcx_reg_no_rbp and long_no_rcx_reg_with_rbp. 408 reg_class_dynamic long_no_rcx_reg(long_no_rcx_reg_no_rbp, long_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 409 410 // Singleton class for RAX long register 411 reg_class long_rax_reg(RAX, RAX_H); 412 413 // Singleton class for RCX long register 414 reg_class long_rcx_reg(RCX, RCX_H); 415 416 // Singleton class for RDX long register 417 reg_class long_rdx_reg(RDX, RDX_H); 418 419 // Class for all int registers (excluding RSP) 420 reg_class int_reg_with_rbp(RAX, 421 RDX, 422 RBP, 423 RDI, 424 RSI, 425 RCX, 426 RBX, 427 R8, 428 R9, 429 R10, 430 R11, 431 R13, 432 R14); 433 434 // Class for all int registers (excluding RSP and RBP) 435 reg_class int_reg_no_rbp(RAX, 436 RDX, 437 RDI, 438 RSI, 439 RCX, 440 RBX, 441 R8, 442 R9, 443 R10, 444 R11, 445 R13, 446 R14); 447 448 // Dynamic register class that selects between int_reg_no_rbp and int_reg_with_rbp. 449 reg_class_dynamic int_reg(int_reg_no_rbp, int_reg_with_rbp, %{ PreserveFramePointer %}); 450 451 // Class for all int registers (excluding RCX and RSP) 452 reg_class int_no_rcx_reg_with_rbp(RAX, 453 RDX, 454 RBP, 455 RDI, 456 RSI, 457 RBX, 458 R8, 459 R9, 460 R10, 461 R11, 462 R13, 463 R14); 464 465 // Class for all int registers (excluding RCX, RSP, and RBP) 466 reg_class int_no_rcx_reg_no_rbp(RAX, 467 RDX, 468 RDI, 469 RSI, 470 RBX, 471 R8, 472 R9, 473 R10, 474 R11, 475 R13, 476 R14); 477 478 // Dynamic register class that selects between int_no_rcx_reg_no_rbp and int_no_rcx_reg_with_rbp. 479 reg_class_dynamic int_no_rcx_reg(int_no_rcx_reg_no_rbp, int_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 480 481 // Class for all int registers (excluding RAX, RDX, and RSP) 482 reg_class int_no_rax_rdx_reg_with_rbp(RBP, 483 RDI, 484 RSI, 485 RCX, 486 RBX, 487 R8, 488 R9, 489 R10, 490 R11, 491 R13, 492 R14); 493 494 // Class for all int registers (excluding RAX, RDX, RSP, and RBP) 495 reg_class int_no_rax_rdx_reg_no_rbp(RDI, 496 RSI, 497 RCX, 498 RBX, 499 R8, 500 R9, 501 R10, 502 R11, 503 R13, 504 R14); 505 506 // Dynamic register class that selects between int_no_rax_rdx_reg_no_rbp and int_no_rax_rdx_reg_with_rbp. 507 reg_class_dynamic int_no_rax_rdx_reg(int_no_rax_rdx_reg_no_rbp, int_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 508 509 // Singleton class for RAX int register 510 reg_class int_rax_reg(RAX); 511 512 // Singleton class for RBX int register 513 reg_class int_rbx_reg(RBX); 514 515 // Singleton class for RCX int register 516 reg_class int_rcx_reg(RCX); 517 518 // Singleton class for RCX int register 519 reg_class int_rdx_reg(RDX); 520 521 // Singleton class for RCX int register 522 reg_class int_rdi_reg(RDI); 523 524 // Singleton class for instruction pointer 525 // reg_class ip_reg(RIP); 526 527 %} 528 529 source_hpp %{ 530 #if INCLUDE_ZGC 531 #include "gc/z/zBarrierSetAssembler.hpp" 532 #endif 533 %} 534 535 //----------SOURCE BLOCK------------------------------------------------------- 536 // This is a block of C++ code which provides values, functions, and 537 // definitions necessary in the rest of the architecture description 538 source %{ 539 #define RELOC_IMM64 Assembler::imm_operand 540 #define RELOC_DISP32 Assembler::disp32_operand 541 542 #define __ _masm. 543 544 static bool generate_vzeroupper(Compile* C) { 545 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 546 } 547 548 static int clear_avx_size() { 549 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 550 } 551 552 // !!!!! Special hack to get all types of calls to specify the byte offset 553 // from the start of the call to the point where the return address 554 // will point. 555 int MachCallStaticJavaNode::ret_addr_offset() 556 { 557 int offset = 5; // 5 bytes from start of call to where return address points 558 offset += clear_avx_size(); 559 return offset; 560 } 561 562 int MachCallDynamicJavaNode::ret_addr_offset() 563 { 564 int offset = 15; // 15 bytes from start of call to where return address points 565 offset += clear_avx_size(); 566 return offset; 567 } 568 569 int MachCallRuntimeNode::ret_addr_offset() { 570 int offset = 13; // movq r10,#addr; callq (r10) 571 offset += clear_avx_size(); 572 return offset; 573 } 574 575 // Indicate if the safepoint node needs the polling page as an input, 576 // it does if the polling page is more than disp32 away. 577 bool SafePointNode::needs_polling_address_input() 578 { 579 return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far(); 580 } 581 582 // 583 // Compute padding required for nodes which need alignment 584 // 585 586 // The address of the call instruction needs to be 4-byte aligned to 587 // ensure that it does not span a cache line so that it can be patched. 588 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 589 { 590 current_offset += clear_avx_size(); // skip vzeroupper 591 current_offset += 1; // skip call opcode byte 592 return align_up(current_offset, alignment_required()) - current_offset; 593 } 594 595 // The address of the call instruction needs to be 4-byte aligned to 596 // ensure that it does not span a cache line so that it can be patched. 597 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 598 { 599 current_offset += clear_avx_size(); // skip vzeroupper 600 current_offset += 11; // skip movq instruction + call opcode byte 601 return align_up(current_offset, alignment_required()) - current_offset; 602 } 603 604 // EMIT_RM() 605 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 606 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 607 cbuf.insts()->emit_int8(c); 608 } 609 610 // EMIT_CC() 611 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 612 unsigned char c = (unsigned char) (f1 | f2); 613 cbuf.insts()->emit_int8(c); 614 } 615 616 // EMIT_OPCODE() 617 void emit_opcode(CodeBuffer &cbuf, int code) { 618 cbuf.insts()->emit_int8((unsigned char) code); 619 } 620 621 // EMIT_OPCODE() w/ relocation information 622 void emit_opcode(CodeBuffer &cbuf, 623 int code, relocInfo::relocType reloc, int offset, int format) 624 { 625 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 626 emit_opcode(cbuf, code); 627 } 628 629 // EMIT_D8() 630 void emit_d8(CodeBuffer &cbuf, int d8) { 631 cbuf.insts()->emit_int8((unsigned char) d8); 632 } 633 634 // EMIT_D16() 635 void emit_d16(CodeBuffer &cbuf, int d16) { 636 cbuf.insts()->emit_int16(d16); 637 } 638 639 // EMIT_D32() 640 void emit_d32(CodeBuffer &cbuf, int d32) { 641 cbuf.insts()->emit_int32(d32); 642 } 643 644 // EMIT_D64() 645 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 646 cbuf.insts()->emit_int64(d64); 647 } 648 649 // emit 32 bit value and construct relocation entry from relocInfo::relocType 650 void emit_d32_reloc(CodeBuffer& cbuf, 651 int d32, 652 relocInfo::relocType reloc, 653 int format) 654 { 655 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 656 cbuf.relocate(cbuf.insts_mark(), reloc, format); 657 cbuf.insts()->emit_int32(d32); 658 } 659 660 // emit 32 bit value and construct relocation entry from RelocationHolder 661 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 662 #ifdef ASSERT 663 if (rspec.reloc()->type() == relocInfo::oop_type && 664 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 665 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 666 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop((intptr_t)d32))), "cannot embed scavengable oops in code"); 667 } 668 #endif 669 cbuf.relocate(cbuf.insts_mark(), rspec, format); 670 cbuf.insts()->emit_int32(d32); 671 } 672 673 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 674 address next_ip = cbuf.insts_end() + 4; 675 emit_d32_reloc(cbuf, (int) (addr - next_ip), 676 external_word_Relocation::spec(addr), 677 RELOC_DISP32); 678 } 679 680 681 // emit 64 bit value and construct relocation entry from relocInfo::relocType 682 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 683 cbuf.relocate(cbuf.insts_mark(), reloc, format); 684 cbuf.insts()->emit_int64(d64); 685 } 686 687 // emit 64 bit value and construct relocation entry from RelocationHolder 688 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 689 #ifdef ASSERT 690 if (rspec.reloc()->type() == relocInfo::oop_type && 691 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 692 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 693 assert(oopDesc::is_oop(cast_to_oop(d64)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop(d64))), 694 "cannot embed scavengable oops in code"); 695 } 696 #endif 697 cbuf.relocate(cbuf.insts_mark(), rspec, format); 698 cbuf.insts()->emit_int64(d64); 699 } 700 701 // Access stack slot for load or store 702 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 703 { 704 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 705 if (-0x80 <= disp && disp < 0x80) { 706 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 707 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 708 emit_d8(cbuf, disp); // Displacement // R/M byte 709 } else { 710 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 711 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 712 emit_d32(cbuf, disp); // Displacement // R/M byte 713 } 714 } 715 716 // rRegI ereg, memory mem) %{ // emit_reg_mem 717 void encode_RegMem(CodeBuffer &cbuf, 718 int reg, 719 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 720 { 721 assert(disp_reloc == relocInfo::none, "cannot have disp"); 722 int regenc = reg & 7; 723 int baseenc = base & 7; 724 int indexenc = index & 7; 725 726 // There is no index & no scale, use form without SIB byte 727 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 728 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 729 if (disp == 0 && base != RBP_enc && base != R13_enc) { 730 emit_rm(cbuf, 0x0, regenc, baseenc); // * 731 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 732 // If 8-bit displacement, mode 0x1 733 emit_rm(cbuf, 0x1, regenc, baseenc); // * 734 emit_d8(cbuf, disp); 735 } else { 736 // If 32-bit displacement 737 if (base == -1) { // Special flag for absolute address 738 emit_rm(cbuf, 0x0, regenc, 0x5); // * 739 if (disp_reloc != relocInfo::none) { 740 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 741 } else { 742 emit_d32(cbuf, disp); 743 } 744 } else { 745 // Normal base + offset 746 emit_rm(cbuf, 0x2, regenc, baseenc); // * 747 if (disp_reloc != relocInfo::none) { 748 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 749 } else { 750 emit_d32(cbuf, disp); 751 } 752 } 753 } 754 } else { 755 // Else, encode with the SIB byte 756 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 757 if (disp == 0 && base != RBP_enc && base != R13_enc) { 758 // If no displacement 759 emit_rm(cbuf, 0x0, regenc, 0x4); // * 760 emit_rm(cbuf, scale, indexenc, baseenc); 761 } else { 762 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 763 // If 8-bit displacement, mode 0x1 764 emit_rm(cbuf, 0x1, regenc, 0x4); // * 765 emit_rm(cbuf, scale, indexenc, baseenc); 766 emit_d8(cbuf, disp); 767 } else { 768 // If 32-bit displacement 769 if (base == 0x04 ) { 770 emit_rm(cbuf, 0x2, regenc, 0x4); 771 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 772 } else { 773 emit_rm(cbuf, 0x2, regenc, 0x4); 774 emit_rm(cbuf, scale, indexenc, baseenc); // * 775 } 776 if (disp_reloc != relocInfo::none) { 777 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 778 } else { 779 emit_d32(cbuf, disp); 780 } 781 } 782 } 783 } 784 } 785 786 // This could be in MacroAssembler but it's fairly C2 specific 787 void emit_cmpfp_fixup(MacroAssembler& _masm) { 788 Label exit; 789 __ jccb(Assembler::noParity, exit); 790 __ pushf(); 791 // 792 // comiss/ucomiss instructions set ZF,PF,CF flags and 793 // zero OF,AF,SF for NaN values. 794 // Fixup flags by zeroing ZF,PF so that compare of NaN 795 // values returns 'less than' result (CF is set). 796 // Leave the rest of flags unchanged. 797 // 798 // 7 6 5 4 3 2 1 0 799 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 800 // 0 0 1 0 1 0 1 1 (0x2B) 801 // 802 __ andq(Address(rsp, 0), 0xffffff2b); 803 __ popf(); 804 __ bind(exit); 805 } 806 807 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 808 Label done; 809 __ movl(dst, -1); 810 __ jcc(Assembler::parity, done); 811 __ jcc(Assembler::below, done); 812 __ setb(Assembler::notEqual, dst); 813 __ movzbl(dst, dst); 814 __ bind(done); 815 } 816 817 818 //============================================================================= 819 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 820 821 int Compile::ConstantTable::calculate_table_base_offset() const { 822 return 0; // absolute addressing, no offset 823 } 824 825 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 826 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 827 ShouldNotReachHere(); 828 } 829 830 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 831 // Empty encoding 832 } 833 834 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 835 return 0; 836 } 837 838 #ifndef PRODUCT 839 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 840 st->print("# MachConstantBaseNode (empty encoding)"); 841 } 842 #endif 843 844 845 //============================================================================= 846 #ifndef PRODUCT 847 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 848 Compile* C = ra_->C; 849 850 int framesize = C->frame_size_in_bytes(); 851 int bangsize = C->bang_size_in_bytes(); 852 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 853 // Remove wordSize for return addr which is already pushed. 854 framesize -= wordSize; 855 856 if (C->need_stack_bang(bangsize)) { 857 framesize -= wordSize; 858 st->print("# stack bang (%d bytes)", bangsize); 859 st->print("\n\t"); 860 st->print("pushq rbp\t# Save rbp"); 861 if (PreserveFramePointer) { 862 st->print("\n\t"); 863 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 864 } 865 if (framesize) { 866 st->print("\n\t"); 867 st->print("subq rsp, #%d\t# Create frame",framesize); 868 } 869 } else { 870 st->print("subq rsp, #%d\t# Create frame",framesize); 871 st->print("\n\t"); 872 framesize -= wordSize; 873 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 874 if (PreserveFramePointer) { 875 st->print("\n\t"); 876 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 877 if (framesize > 0) { 878 st->print("\n\t"); 879 st->print("addq rbp, #%d", framesize); 880 } 881 } 882 } 883 884 if (VerifyStackAtCalls) { 885 st->print("\n\t"); 886 framesize -= wordSize; 887 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 888 #ifdef ASSERT 889 st->print("\n\t"); 890 st->print("# stack alignment check"); 891 #endif 892 } 893 if (C->stub_function() != NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 894 st->print("\n\t"); 895 st->print("cmpl [r15_thread + #disarmed_offset], #disarmed_value\t"); 896 st->print("\n\t"); 897 st->print("je fast_entry\t"); 898 st->print("\n\t"); 899 st->print("call #nmethod_entry_barrier_stub\t"); 900 st->print("\n\tfast_entry:"); 901 } 902 st->cr(); 903 } 904 #endif 905 906 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 907 Compile* C = ra_->C; 908 MacroAssembler _masm(&cbuf); 909 910 int framesize = C->frame_size_in_bytes(); 911 int bangsize = C->bang_size_in_bytes(); 912 913 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != NULL); 914 915 C->set_frame_complete(cbuf.insts_size()); 916 917 if (C->has_mach_constant_base_node()) { 918 // NOTE: We set the table base offset here because users might be 919 // emitted before MachConstantBaseNode. 920 Compile::ConstantTable& constant_table = C->constant_table(); 921 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 922 } 923 } 924 925 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 926 { 927 return MachNode::size(ra_); // too many variables; just compute it 928 // the hard way 929 } 930 931 int MachPrologNode::reloc() const 932 { 933 return 0; // a large enough number 934 } 935 936 //============================================================================= 937 #ifndef PRODUCT 938 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 939 { 940 Compile* C = ra_->C; 941 if (generate_vzeroupper(C)) { 942 st->print("vzeroupper"); 943 st->cr(); st->print("\t"); 944 } 945 946 int framesize = C->frame_size_in_bytes(); 947 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 948 // Remove word for return adr already pushed 949 // and RBP 950 framesize -= 2*wordSize; 951 952 if (framesize) { 953 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 954 st->print("\t"); 955 } 956 957 st->print_cr("popq rbp"); 958 if (do_polling() && C->is_method_compilation()) { 959 st->print("\t"); 960 if (SafepointMechanism::uses_thread_local_poll()) { 961 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 962 "testl rax, [rscratch1]\t" 963 "# Safepoint: poll for GC"); 964 } else if (Assembler::is_polling_page_far()) { 965 st->print_cr("movq rscratch1, #polling_page_address\n\t" 966 "testl rax, [rscratch1]\t" 967 "# Safepoint: poll for GC"); 968 } else { 969 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 970 "# Safepoint: poll for GC"); 971 } 972 } 973 } 974 #endif 975 976 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 977 { 978 Compile* C = ra_->C; 979 MacroAssembler _masm(&cbuf); 980 981 if (generate_vzeroupper(C)) { 982 // Clear upper bits of YMM registers when current compiled code uses 983 // wide vectors to avoid AVX <-> SSE transition penalty during call. 984 __ vzeroupper(); 985 } 986 987 int framesize = C->frame_size_in_bytes(); 988 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 989 // Remove word for return adr already pushed 990 // and RBP 991 framesize -= 2*wordSize; 992 993 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 994 995 if (framesize) { 996 emit_opcode(cbuf, Assembler::REX_W); 997 if (framesize < 0x80) { 998 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 999 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1000 emit_d8(cbuf, framesize); 1001 } else { 1002 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 1003 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1004 emit_d32(cbuf, framesize); 1005 } 1006 } 1007 1008 // popq rbp 1009 emit_opcode(cbuf, 0x58 | RBP_enc); 1010 1011 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1012 __ reserved_stack_check(); 1013 } 1014 1015 if (do_polling() && C->is_method_compilation()) { 1016 MacroAssembler _masm(&cbuf); 1017 if (SafepointMechanism::uses_thread_local_poll()) { 1018 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 1019 __ relocate(relocInfo::poll_return_type); 1020 __ testl(rax, Address(rscratch1, 0)); 1021 } else { 1022 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1023 if (Assembler::is_polling_page_far()) { 1024 __ lea(rscratch1, polling_page); 1025 __ relocate(relocInfo::poll_return_type); 1026 __ testl(rax, Address(rscratch1, 0)); 1027 } else { 1028 __ testl(rax, polling_page); 1029 } 1030 } 1031 } 1032 } 1033 1034 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1035 { 1036 return MachNode::size(ra_); // too many variables; just compute it 1037 // the hard way 1038 } 1039 1040 int MachEpilogNode::reloc() const 1041 { 1042 return 2; // a large enough number 1043 } 1044 1045 const Pipeline* MachEpilogNode::pipeline() const 1046 { 1047 return MachNode::pipeline_class(); 1048 } 1049 1050 int MachEpilogNode::safepoint_offset() const 1051 { 1052 return 0; 1053 } 1054 1055 //============================================================================= 1056 1057 enum RC { 1058 rc_bad, 1059 rc_int, 1060 rc_float, 1061 rc_stack 1062 }; 1063 1064 static enum RC rc_class(OptoReg::Name reg) 1065 { 1066 if( !OptoReg::is_valid(reg) ) return rc_bad; 1067 1068 if (OptoReg::is_stack(reg)) return rc_stack; 1069 1070 VMReg r = OptoReg::as_VMReg(reg); 1071 1072 if (r->is_Register()) return rc_int; 1073 1074 assert(r->is_XMMRegister(), "must be"); 1075 return rc_float; 1076 } 1077 1078 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1079 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1080 int src_hi, int dst_hi, uint ireg, outputStream* st); 1081 1082 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1083 int stack_offset, int reg, uint ireg, outputStream* st); 1084 1085 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1086 int dst_offset, uint ireg, outputStream* st) { 1087 if (cbuf) { 1088 MacroAssembler _masm(cbuf); 1089 switch (ireg) { 1090 case Op_VecS: 1091 __ movq(Address(rsp, -8), rax); 1092 __ movl(rax, Address(rsp, src_offset)); 1093 __ movl(Address(rsp, dst_offset), rax); 1094 __ movq(rax, Address(rsp, -8)); 1095 break; 1096 case Op_VecD: 1097 __ pushq(Address(rsp, src_offset)); 1098 __ popq (Address(rsp, dst_offset)); 1099 break; 1100 case Op_VecX: 1101 __ pushq(Address(rsp, src_offset)); 1102 __ popq (Address(rsp, dst_offset)); 1103 __ pushq(Address(rsp, src_offset+8)); 1104 __ popq (Address(rsp, dst_offset+8)); 1105 break; 1106 case Op_VecY: 1107 __ vmovdqu(Address(rsp, -32), xmm0); 1108 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1109 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1110 __ vmovdqu(xmm0, Address(rsp, -32)); 1111 break; 1112 case Op_VecZ: 1113 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1114 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1115 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1116 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1117 break; 1118 default: 1119 ShouldNotReachHere(); 1120 } 1121 #ifndef PRODUCT 1122 } else { 1123 switch (ireg) { 1124 case Op_VecS: 1125 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1126 "movl rax, [rsp + #%d]\n\t" 1127 "movl [rsp + #%d], rax\n\t" 1128 "movq rax, [rsp - #8]", 1129 src_offset, dst_offset); 1130 break; 1131 case Op_VecD: 1132 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1133 "popq [rsp + #%d]", 1134 src_offset, dst_offset); 1135 break; 1136 case Op_VecX: 1137 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1138 "popq [rsp + #%d]\n\t" 1139 "pushq [rsp + #%d]\n\t" 1140 "popq [rsp + #%d]", 1141 src_offset, dst_offset, src_offset+8, dst_offset+8); 1142 break; 1143 case Op_VecY: 1144 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1145 "vmovdqu xmm0, [rsp + #%d]\n\t" 1146 "vmovdqu [rsp + #%d], xmm0\n\t" 1147 "vmovdqu xmm0, [rsp - #32]", 1148 src_offset, dst_offset); 1149 break; 1150 case Op_VecZ: 1151 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1152 "vmovdqu xmm0, [rsp + #%d]\n\t" 1153 "vmovdqu [rsp + #%d], xmm0\n\t" 1154 "vmovdqu xmm0, [rsp - #64]", 1155 src_offset, dst_offset); 1156 break; 1157 default: 1158 ShouldNotReachHere(); 1159 } 1160 #endif 1161 } 1162 } 1163 1164 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1165 PhaseRegAlloc* ra_, 1166 bool do_size, 1167 outputStream* st) const { 1168 assert(cbuf != NULL || st != NULL, "sanity"); 1169 // Get registers to move 1170 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1171 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1172 OptoReg::Name dst_second = ra_->get_reg_second(this); 1173 OptoReg::Name dst_first = ra_->get_reg_first(this); 1174 1175 enum RC src_second_rc = rc_class(src_second); 1176 enum RC src_first_rc = rc_class(src_first); 1177 enum RC dst_second_rc = rc_class(dst_second); 1178 enum RC dst_first_rc = rc_class(dst_first); 1179 1180 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1181 "must move at least 1 register" ); 1182 1183 if (src_first == dst_first && src_second == dst_second) { 1184 // Self copy, no move 1185 return 0; 1186 } 1187 if (bottom_type()->isa_vect() != NULL) { 1188 uint ireg = ideal_reg(); 1189 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1190 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1191 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1192 // mem -> mem 1193 int src_offset = ra_->reg2offset(src_first); 1194 int dst_offset = ra_->reg2offset(dst_first); 1195 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1196 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1197 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1198 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1199 int stack_offset = ra_->reg2offset(dst_first); 1200 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1201 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1202 int stack_offset = ra_->reg2offset(src_first); 1203 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1204 } else { 1205 ShouldNotReachHere(); 1206 } 1207 return 0; 1208 } 1209 if (src_first_rc == rc_stack) { 1210 // mem -> 1211 if (dst_first_rc == rc_stack) { 1212 // mem -> mem 1213 assert(src_second != dst_first, "overlap"); 1214 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1215 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1216 // 64-bit 1217 int src_offset = ra_->reg2offset(src_first); 1218 int dst_offset = ra_->reg2offset(dst_first); 1219 if (cbuf) { 1220 MacroAssembler _masm(cbuf); 1221 __ pushq(Address(rsp, src_offset)); 1222 __ popq (Address(rsp, dst_offset)); 1223 #ifndef PRODUCT 1224 } else { 1225 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1226 "popq [rsp + #%d]", 1227 src_offset, dst_offset); 1228 #endif 1229 } 1230 } else { 1231 // 32-bit 1232 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1233 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1234 // No pushl/popl, so: 1235 int src_offset = ra_->reg2offset(src_first); 1236 int dst_offset = ra_->reg2offset(dst_first); 1237 if (cbuf) { 1238 MacroAssembler _masm(cbuf); 1239 __ movq(Address(rsp, -8), rax); 1240 __ movl(rax, Address(rsp, src_offset)); 1241 __ movl(Address(rsp, dst_offset), rax); 1242 __ movq(rax, Address(rsp, -8)); 1243 #ifndef PRODUCT 1244 } else { 1245 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1246 "movl rax, [rsp + #%d]\n\t" 1247 "movl [rsp + #%d], rax\n\t" 1248 "movq rax, [rsp - #8]", 1249 src_offset, dst_offset); 1250 #endif 1251 } 1252 } 1253 return 0; 1254 } else if (dst_first_rc == rc_int) { 1255 // mem -> gpr 1256 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1257 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1258 // 64-bit 1259 int offset = ra_->reg2offset(src_first); 1260 if (cbuf) { 1261 MacroAssembler _masm(cbuf); 1262 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1263 #ifndef PRODUCT 1264 } else { 1265 st->print("movq %s, [rsp + #%d]\t# spill", 1266 Matcher::regName[dst_first], 1267 offset); 1268 #endif 1269 } 1270 } else { 1271 // 32-bit 1272 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1273 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1274 int offset = ra_->reg2offset(src_first); 1275 if (cbuf) { 1276 MacroAssembler _masm(cbuf); 1277 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1278 #ifndef PRODUCT 1279 } else { 1280 st->print("movl %s, [rsp + #%d]\t# spill", 1281 Matcher::regName[dst_first], 1282 offset); 1283 #endif 1284 } 1285 } 1286 return 0; 1287 } else if (dst_first_rc == rc_float) { 1288 // mem-> xmm 1289 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1290 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1291 // 64-bit 1292 int offset = ra_->reg2offset(src_first); 1293 if (cbuf) { 1294 MacroAssembler _masm(cbuf); 1295 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1296 #ifndef PRODUCT 1297 } else { 1298 st->print("%s %s, [rsp + #%d]\t# spill", 1299 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1300 Matcher::regName[dst_first], 1301 offset); 1302 #endif 1303 } 1304 } else { 1305 // 32-bit 1306 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1307 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1308 int offset = ra_->reg2offset(src_first); 1309 if (cbuf) { 1310 MacroAssembler _masm(cbuf); 1311 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1312 #ifndef PRODUCT 1313 } else { 1314 st->print("movss %s, [rsp + #%d]\t# spill", 1315 Matcher::regName[dst_first], 1316 offset); 1317 #endif 1318 } 1319 } 1320 return 0; 1321 } 1322 } else if (src_first_rc == rc_int) { 1323 // gpr -> 1324 if (dst_first_rc == rc_stack) { 1325 // gpr -> mem 1326 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1327 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1328 // 64-bit 1329 int offset = ra_->reg2offset(dst_first); 1330 if (cbuf) { 1331 MacroAssembler _masm(cbuf); 1332 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1333 #ifndef PRODUCT 1334 } else { 1335 st->print("movq [rsp + #%d], %s\t# spill", 1336 offset, 1337 Matcher::regName[src_first]); 1338 #endif 1339 } 1340 } else { 1341 // 32-bit 1342 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1343 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1344 int offset = ra_->reg2offset(dst_first); 1345 if (cbuf) { 1346 MacroAssembler _masm(cbuf); 1347 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1348 #ifndef PRODUCT 1349 } else { 1350 st->print("movl [rsp + #%d], %s\t# spill", 1351 offset, 1352 Matcher::regName[src_first]); 1353 #endif 1354 } 1355 } 1356 return 0; 1357 } else if (dst_first_rc == rc_int) { 1358 // gpr -> gpr 1359 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1360 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1361 // 64-bit 1362 if (cbuf) { 1363 MacroAssembler _masm(cbuf); 1364 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1365 as_Register(Matcher::_regEncode[src_first])); 1366 #ifndef PRODUCT 1367 } else { 1368 st->print("movq %s, %s\t# spill", 1369 Matcher::regName[dst_first], 1370 Matcher::regName[src_first]); 1371 #endif 1372 } 1373 return 0; 1374 } else { 1375 // 32-bit 1376 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1377 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1378 if (cbuf) { 1379 MacroAssembler _masm(cbuf); 1380 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1381 as_Register(Matcher::_regEncode[src_first])); 1382 #ifndef PRODUCT 1383 } else { 1384 st->print("movl %s, %s\t# spill", 1385 Matcher::regName[dst_first], 1386 Matcher::regName[src_first]); 1387 #endif 1388 } 1389 return 0; 1390 } 1391 } else if (dst_first_rc == rc_float) { 1392 // gpr -> xmm 1393 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1394 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1395 // 64-bit 1396 if (cbuf) { 1397 MacroAssembler _masm(cbuf); 1398 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1399 #ifndef PRODUCT 1400 } else { 1401 st->print("movdq %s, %s\t# spill", 1402 Matcher::regName[dst_first], 1403 Matcher::regName[src_first]); 1404 #endif 1405 } 1406 } else { 1407 // 32-bit 1408 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1409 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1410 if (cbuf) { 1411 MacroAssembler _masm(cbuf); 1412 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1413 #ifndef PRODUCT 1414 } else { 1415 st->print("movdl %s, %s\t# spill", 1416 Matcher::regName[dst_first], 1417 Matcher::regName[src_first]); 1418 #endif 1419 } 1420 } 1421 return 0; 1422 } 1423 } else if (src_first_rc == rc_float) { 1424 // xmm -> 1425 if (dst_first_rc == rc_stack) { 1426 // xmm -> mem 1427 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1428 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1429 // 64-bit 1430 int offset = ra_->reg2offset(dst_first); 1431 if (cbuf) { 1432 MacroAssembler _masm(cbuf); 1433 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1434 #ifndef PRODUCT 1435 } else { 1436 st->print("movsd [rsp + #%d], %s\t# spill", 1437 offset, 1438 Matcher::regName[src_first]); 1439 #endif 1440 } 1441 } else { 1442 // 32-bit 1443 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1444 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1445 int offset = ra_->reg2offset(dst_first); 1446 if (cbuf) { 1447 MacroAssembler _masm(cbuf); 1448 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1449 #ifndef PRODUCT 1450 } else { 1451 st->print("movss [rsp + #%d], %s\t# spill", 1452 offset, 1453 Matcher::regName[src_first]); 1454 #endif 1455 } 1456 } 1457 return 0; 1458 } else if (dst_first_rc == rc_int) { 1459 // xmm -> gpr 1460 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1461 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1462 // 64-bit 1463 if (cbuf) { 1464 MacroAssembler _masm(cbuf); 1465 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1466 #ifndef PRODUCT 1467 } else { 1468 st->print("movdq %s, %s\t# spill", 1469 Matcher::regName[dst_first], 1470 Matcher::regName[src_first]); 1471 #endif 1472 } 1473 } else { 1474 // 32-bit 1475 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1476 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1477 if (cbuf) { 1478 MacroAssembler _masm(cbuf); 1479 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1480 #ifndef PRODUCT 1481 } else { 1482 st->print("movdl %s, %s\t# spill", 1483 Matcher::regName[dst_first], 1484 Matcher::regName[src_first]); 1485 #endif 1486 } 1487 } 1488 return 0; 1489 } else if (dst_first_rc == rc_float) { 1490 // xmm -> xmm 1491 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1492 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1493 // 64-bit 1494 if (cbuf) { 1495 MacroAssembler _masm(cbuf); 1496 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1497 #ifndef PRODUCT 1498 } else { 1499 st->print("%s %s, %s\t# spill", 1500 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1501 Matcher::regName[dst_first], 1502 Matcher::regName[src_first]); 1503 #endif 1504 } 1505 } else { 1506 // 32-bit 1507 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1508 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1509 if (cbuf) { 1510 MacroAssembler _masm(cbuf); 1511 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1512 #ifndef PRODUCT 1513 } else { 1514 st->print("%s %s, %s\t# spill", 1515 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1516 Matcher::regName[dst_first], 1517 Matcher::regName[src_first]); 1518 #endif 1519 } 1520 } 1521 return 0; 1522 } 1523 } 1524 1525 assert(0," foo "); 1526 Unimplemented(); 1527 return 0; 1528 } 1529 1530 #ifndef PRODUCT 1531 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1532 implementation(NULL, ra_, false, st); 1533 } 1534 #endif 1535 1536 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1537 implementation(&cbuf, ra_, false, NULL); 1538 } 1539 1540 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1541 return MachNode::size(ra_); 1542 } 1543 1544 //============================================================================= 1545 #ifndef PRODUCT 1546 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1547 { 1548 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1549 int reg = ra_->get_reg_first(this); 1550 st->print("leaq %s, [rsp + #%d]\t# box lock", 1551 Matcher::regName[reg], offset); 1552 } 1553 #endif 1554 1555 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1556 { 1557 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1558 int reg = ra_->get_encode(this); 1559 if (offset >= 0x80) { 1560 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1561 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1562 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1563 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1564 emit_d32(cbuf, offset); 1565 } else { 1566 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1567 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1568 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1569 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1570 emit_d8(cbuf, offset); 1571 } 1572 } 1573 1574 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1575 { 1576 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1577 return (offset < 0x80) ? 5 : 8; // REX 1578 } 1579 1580 //============================================================================= 1581 #ifndef PRODUCT 1582 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1583 { 1584 if (UseCompressedClassPointers) { 1585 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1586 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1587 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1588 } else { 1589 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1590 "# Inline cache check"); 1591 } 1592 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1593 st->print_cr("\tnop\t# nops to align entry point"); 1594 } 1595 #endif 1596 1597 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1598 { 1599 MacroAssembler masm(&cbuf); 1600 uint insts_size = cbuf.insts_size(); 1601 if (UseCompressedClassPointers) { 1602 masm.load_klass(rscratch1, j_rarg0); 1603 masm.cmpptr(rax, rscratch1); 1604 } else { 1605 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1606 } 1607 1608 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1609 1610 /* WARNING these NOPs are critical so that verified entry point is properly 1611 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1612 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1613 if (OptoBreakpoint) { 1614 // Leave space for int3 1615 nops_cnt -= 1; 1616 } 1617 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1618 if (nops_cnt > 0) 1619 masm.nop(nops_cnt); 1620 } 1621 1622 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1623 { 1624 return MachNode::size(ra_); // too many variables; just compute it 1625 // the hard way 1626 } 1627 1628 1629 //============================================================================= 1630 1631 int Matcher::regnum_to_fpu_offset(int regnum) 1632 { 1633 return regnum - 32; // The FP registers are in the second chunk 1634 } 1635 1636 // This is UltraSparc specific, true just means we have fast l2f conversion 1637 const bool Matcher::convL2FSupported(void) { 1638 return true; 1639 } 1640 1641 // Is this branch offset short enough that a short branch can be used? 1642 // 1643 // NOTE: If the platform does not provide any short branch variants, then 1644 // this method should return false for offset 0. 1645 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1646 // The passed offset is relative to address of the branch. 1647 // On 86 a branch displacement is calculated relative to address 1648 // of a next instruction. 1649 offset -= br_size; 1650 1651 // the short version of jmpConUCF2 contains multiple branches, 1652 // making the reach slightly less 1653 if (rule == jmpConUCF2_rule) 1654 return (-126 <= offset && offset <= 125); 1655 return (-128 <= offset && offset <= 127); 1656 } 1657 1658 const bool Matcher::isSimpleConstant64(jlong value) { 1659 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1660 //return value == (int) value; // Cf. storeImmL and immL32. 1661 1662 // Probably always true, even if a temp register is required. 1663 return true; 1664 } 1665 1666 // The ecx parameter to rep stosq for the ClearArray node is in words. 1667 const bool Matcher::init_array_count_is_in_bytes = false; 1668 1669 // No additional cost for CMOVL. 1670 const int Matcher::long_cmove_cost() { return 0; } 1671 1672 // No CMOVF/CMOVD with SSE2 1673 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1674 1675 // Does the CPU require late expand (see block.cpp for description of late expand)? 1676 const bool Matcher::require_postalloc_expand = false; 1677 1678 // Do we need to mask the count passed to shift instructions or does 1679 // the cpu only look at the lower 5/6 bits anyway? 1680 const bool Matcher::need_masked_shift_count = false; 1681 1682 bool Matcher::narrow_oop_use_complex_address() { 1683 assert(UseCompressedOops, "only for compressed oops code"); 1684 return (LogMinObjAlignmentInBytes <= 3); 1685 } 1686 1687 bool Matcher::narrow_klass_use_complex_address() { 1688 assert(UseCompressedClassPointers, "only for compressed klass code"); 1689 return (LogKlassAlignmentInBytes <= 3); 1690 } 1691 1692 bool Matcher::const_oop_prefer_decode() { 1693 // Prefer ConN+DecodeN over ConP. 1694 return true; 1695 } 1696 1697 bool Matcher::const_klass_prefer_decode() { 1698 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1699 // or condisider the following: 1700 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1701 //return Universe::narrow_klass_base() == NULL; 1702 return true; 1703 } 1704 1705 // Is it better to copy float constants, or load them directly from 1706 // memory? Intel can load a float constant from a direct address, 1707 // requiring no extra registers. Most RISCs will have to materialize 1708 // an address into a register first, so they would do better to copy 1709 // the constant from stack. 1710 const bool Matcher::rematerialize_float_constants = true; // XXX 1711 1712 // If CPU can load and store mis-aligned doubles directly then no 1713 // fixup is needed. Else we split the double into 2 integer pieces 1714 // and move it piece-by-piece. Only happens when passing doubles into 1715 // C code as the Java calling convention forces doubles to be aligned. 1716 const bool Matcher::misaligned_doubles_ok = true; 1717 1718 // No-op on amd64 1719 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1720 1721 // Advertise here if the CPU requires explicit rounding operations to 1722 // implement the UseStrictFP mode. 1723 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1724 1725 // Are floats conerted to double when stored to stack during deoptimization? 1726 // On x64 it is stored without convertion so we can use normal access. 1727 bool Matcher::float_in_double() { return false; } 1728 1729 // Do ints take an entire long register or just half? 1730 const bool Matcher::int_in_long = true; 1731 1732 // Return whether or not this register is ever used as an argument. 1733 // This function is used on startup to build the trampoline stubs in 1734 // generateOptoStub. Registers not mentioned will be killed by the VM 1735 // call in the trampoline, and arguments in those registers not be 1736 // available to the callee. 1737 bool Matcher::can_be_java_arg(int reg) 1738 { 1739 return 1740 reg == RDI_num || reg == RDI_H_num || 1741 reg == RSI_num || reg == RSI_H_num || 1742 reg == RDX_num || reg == RDX_H_num || 1743 reg == RCX_num || reg == RCX_H_num || 1744 reg == R8_num || reg == R8_H_num || 1745 reg == R9_num || reg == R9_H_num || 1746 reg == R12_num || reg == R12_H_num || 1747 reg == XMM0_num || reg == XMM0b_num || 1748 reg == XMM1_num || reg == XMM1b_num || 1749 reg == XMM2_num || reg == XMM2b_num || 1750 reg == XMM3_num || reg == XMM3b_num || 1751 reg == XMM4_num || reg == XMM4b_num || 1752 reg == XMM5_num || reg == XMM5b_num || 1753 reg == XMM6_num || reg == XMM6b_num || 1754 reg == XMM7_num || reg == XMM7b_num; 1755 } 1756 1757 bool Matcher::is_spillable_arg(int reg) 1758 { 1759 return can_be_java_arg(reg); 1760 } 1761 1762 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1763 // In 64 bit mode a code which use multiply when 1764 // devisor is constant is faster than hardware 1765 // DIV instruction (it uses MulHiL). 1766 return false; 1767 } 1768 1769 // Register for DIVI projection of divmodI 1770 RegMask Matcher::divI_proj_mask() { 1771 return INT_RAX_REG_mask(); 1772 } 1773 1774 // Register for MODI projection of divmodI 1775 RegMask Matcher::modI_proj_mask() { 1776 return INT_RDX_REG_mask(); 1777 } 1778 1779 // Register for DIVL projection of divmodL 1780 RegMask Matcher::divL_proj_mask() { 1781 return LONG_RAX_REG_mask(); 1782 } 1783 1784 // Register for MODL projection of divmodL 1785 RegMask Matcher::modL_proj_mask() { 1786 return LONG_RDX_REG_mask(); 1787 } 1788 1789 // Register for saving SP into on method handle invokes. Not used on x86_64. 1790 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1791 return NO_REG_mask(); 1792 } 1793 1794 %} 1795 1796 //----------ENCODING BLOCK----------------------------------------------------- 1797 // This block specifies the encoding classes used by the compiler to 1798 // output byte streams. Encoding classes are parameterized macros 1799 // used by Machine Instruction Nodes in order to generate the bit 1800 // encoding of the instruction. Operands specify their base encoding 1801 // interface with the interface keyword. There are currently 1802 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1803 // COND_INTER. REG_INTER causes an operand to generate a function 1804 // which returns its register number when queried. CONST_INTER causes 1805 // an operand to generate a function which returns the value of the 1806 // constant when queried. MEMORY_INTER causes an operand to generate 1807 // four functions which return the Base Register, the Index Register, 1808 // the Scale Value, and the Offset Value of the operand when queried. 1809 // COND_INTER causes an operand to generate six functions which return 1810 // the encoding code (ie - encoding bits for the instruction) 1811 // associated with each basic boolean condition for a conditional 1812 // instruction. 1813 // 1814 // Instructions specify two basic values for encoding. Again, a 1815 // function is available to check if the constant displacement is an 1816 // oop. They use the ins_encode keyword to specify their encoding 1817 // classes (which must be a sequence of enc_class names, and their 1818 // parameters, specified in the encoding block), and they use the 1819 // opcode keyword to specify, in order, their primary, secondary, and 1820 // tertiary opcode. Only the opcode sections which a particular 1821 // instruction needs for encoding need to be specified. 1822 encode %{ 1823 // Build emit functions for each basic byte or larger field in the 1824 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1825 // from C++ code in the enc_class source block. Emit functions will 1826 // live in the main source block for now. In future, we can 1827 // generalize this by adding a syntax that specifies the sizes of 1828 // fields in an order, so that the adlc can build the emit functions 1829 // automagically 1830 1831 // Emit primary opcode 1832 enc_class OpcP 1833 %{ 1834 emit_opcode(cbuf, $primary); 1835 %} 1836 1837 // Emit secondary opcode 1838 enc_class OpcS 1839 %{ 1840 emit_opcode(cbuf, $secondary); 1841 %} 1842 1843 // Emit tertiary opcode 1844 enc_class OpcT 1845 %{ 1846 emit_opcode(cbuf, $tertiary); 1847 %} 1848 1849 // Emit opcode directly 1850 enc_class Opcode(immI d8) 1851 %{ 1852 emit_opcode(cbuf, $d8$$constant); 1853 %} 1854 1855 // Emit size prefix 1856 enc_class SizePrefix 1857 %{ 1858 emit_opcode(cbuf, 0x66); 1859 %} 1860 1861 enc_class reg(rRegI reg) 1862 %{ 1863 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1864 %} 1865 1866 enc_class reg_reg(rRegI dst, rRegI src) 1867 %{ 1868 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1869 %} 1870 1871 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1872 %{ 1873 emit_opcode(cbuf, $opcode$$constant); 1874 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1875 %} 1876 1877 enc_class cdql_enc(no_rax_rdx_RegI div) 1878 %{ 1879 // Full implementation of Java idiv and irem; checks for 1880 // special case as described in JVM spec., p.243 & p.271. 1881 // 1882 // normal case special case 1883 // 1884 // input : rax: dividend min_int 1885 // reg: divisor -1 1886 // 1887 // output: rax: quotient (= rax idiv reg) min_int 1888 // rdx: remainder (= rax irem reg) 0 1889 // 1890 // Code sequnce: 1891 // 1892 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1893 // 5: 75 07/08 jne e <normal> 1894 // 7: 33 d2 xor %edx,%edx 1895 // [div >= 8 -> offset + 1] 1896 // [REX_B] 1897 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1898 // c: 74 03/04 je 11 <done> 1899 // 000000000000000e <normal>: 1900 // e: 99 cltd 1901 // [div >= 8 -> offset + 1] 1902 // [REX_B] 1903 // f: f7 f9 idiv $div 1904 // 0000000000000011 <done>: 1905 1906 // cmp $0x80000000,%eax 1907 emit_opcode(cbuf, 0x3d); 1908 emit_d8(cbuf, 0x00); 1909 emit_d8(cbuf, 0x00); 1910 emit_d8(cbuf, 0x00); 1911 emit_d8(cbuf, 0x80); 1912 1913 // jne e <normal> 1914 emit_opcode(cbuf, 0x75); 1915 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1916 1917 // xor %edx,%edx 1918 emit_opcode(cbuf, 0x33); 1919 emit_d8(cbuf, 0xD2); 1920 1921 // cmp $0xffffffffffffffff,%ecx 1922 if ($div$$reg >= 8) { 1923 emit_opcode(cbuf, Assembler::REX_B); 1924 } 1925 emit_opcode(cbuf, 0x83); 1926 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1927 emit_d8(cbuf, 0xFF); 1928 1929 // je 11 <done> 1930 emit_opcode(cbuf, 0x74); 1931 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1932 1933 // <normal> 1934 // cltd 1935 emit_opcode(cbuf, 0x99); 1936 1937 // idivl (note: must be emitted by the user of this rule) 1938 // <done> 1939 %} 1940 1941 enc_class cdqq_enc(no_rax_rdx_RegL div) 1942 %{ 1943 // Full implementation of Java ldiv and lrem; checks for 1944 // special case as described in JVM spec., p.243 & p.271. 1945 // 1946 // normal case special case 1947 // 1948 // input : rax: dividend min_long 1949 // reg: divisor -1 1950 // 1951 // output: rax: quotient (= rax idiv reg) min_long 1952 // rdx: remainder (= rax irem reg) 0 1953 // 1954 // Code sequnce: 1955 // 1956 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1957 // 7: 00 00 80 1958 // a: 48 39 d0 cmp %rdx,%rax 1959 // d: 75 08 jne 17 <normal> 1960 // f: 33 d2 xor %edx,%edx 1961 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1962 // 15: 74 05 je 1c <done> 1963 // 0000000000000017 <normal>: 1964 // 17: 48 99 cqto 1965 // 19: 48 f7 f9 idiv $div 1966 // 000000000000001c <done>: 1967 1968 // mov $0x8000000000000000,%rdx 1969 emit_opcode(cbuf, Assembler::REX_W); 1970 emit_opcode(cbuf, 0xBA); 1971 emit_d8(cbuf, 0x00); 1972 emit_d8(cbuf, 0x00); 1973 emit_d8(cbuf, 0x00); 1974 emit_d8(cbuf, 0x00); 1975 emit_d8(cbuf, 0x00); 1976 emit_d8(cbuf, 0x00); 1977 emit_d8(cbuf, 0x00); 1978 emit_d8(cbuf, 0x80); 1979 1980 // cmp %rdx,%rax 1981 emit_opcode(cbuf, Assembler::REX_W); 1982 emit_opcode(cbuf, 0x39); 1983 emit_d8(cbuf, 0xD0); 1984 1985 // jne 17 <normal> 1986 emit_opcode(cbuf, 0x75); 1987 emit_d8(cbuf, 0x08); 1988 1989 // xor %edx,%edx 1990 emit_opcode(cbuf, 0x33); 1991 emit_d8(cbuf, 0xD2); 1992 1993 // cmp $0xffffffffffffffff,$div 1994 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1995 emit_opcode(cbuf, 0x83); 1996 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1997 emit_d8(cbuf, 0xFF); 1998 1999 // je 1e <done> 2000 emit_opcode(cbuf, 0x74); 2001 emit_d8(cbuf, 0x05); 2002 2003 // <normal> 2004 // cqto 2005 emit_opcode(cbuf, Assembler::REX_W); 2006 emit_opcode(cbuf, 0x99); 2007 2008 // idivq (note: must be emitted by the user of this rule) 2009 // <done> 2010 %} 2011 2012 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2013 enc_class OpcSE(immI imm) 2014 %{ 2015 // Emit primary opcode and set sign-extend bit 2016 // Check for 8-bit immediate, and set sign extend bit in opcode 2017 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2018 emit_opcode(cbuf, $primary | 0x02); 2019 } else { 2020 // 32-bit immediate 2021 emit_opcode(cbuf, $primary); 2022 } 2023 %} 2024 2025 enc_class OpcSErm(rRegI dst, immI imm) 2026 %{ 2027 // OpcSEr/m 2028 int dstenc = $dst$$reg; 2029 if (dstenc >= 8) { 2030 emit_opcode(cbuf, Assembler::REX_B); 2031 dstenc -= 8; 2032 } 2033 // Emit primary opcode and set sign-extend bit 2034 // Check for 8-bit immediate, and set sign extend bit in opcode 2035 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2036 emit_opcode(cbuf, $primary | 0x02); 2037 } else { 2038 // 32-bit immediate 2039 emit_opcode(cbuf, $primary); 2040 } 2041 // Emit r/m byte with secondary opcode, after primary opcode. 2042 emit_rm(cbuf, 0x3, $secondary, dstenc); 2043 %} 2044 2045 enc_class OpcSErm_wide(rRegL dst, immI imm) 2046 %{ 2047 // OpcSEr/m 2048 int dstenc = $dst$$reg; 2049 if (dstenc < 8) { 2050 emit_opcode(cbuf, Assembler::REX_W); 2051 } else { 2052 emit_opcode(cbuf, Assembler::REX_WB); 2053 dstenc -= 8; 2054 } 2055 // Emit primary opcode and set sign-extend bit 2056 // Check for 8-bit immediate, and set sign extend bit in opcode 2057 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2058 emit_opcode(cbuf, $primary | 0x02); 2059 } else { 2060 // 32-bit immediate 2061 emit_opcode(cbuf, $primary); 2062 } 2063 // Emit r/m byte with secondary opcode, after primary opcode. 2064 emit_rm(cbuf, 0x3, $secondary, dstenc); 2065 %} 2066 2067 enc_class Con8or32(immI imm) 2068 %{ 2069 // Check for 8-bit immediate, and set sign extend bit in opcode 2070 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2071 $$$emit8$imm$$constant; 2072 } else { 2073 // 32-bit immediate 2074 $$$emit32$imm$$constant; 2075 } 2076 %} 2077 2078 enc_class opc2_reg(rRegI dst) 2079 %{ 2080 // BSWAP 2081 emit_cc(cbuf, $secondary, $dst$$reg); 2082 %} 2083 2084 enc_class opc3_reg(rRegI dst) 2085 %{ 2086 // BSWAP 2087 emit_cc(cbuf, $tertiary, $dst$$reg); 2088 %} 2089 2090 enc_class reg_opc(rRegI div) 2091 %{ 2092 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2093 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2094 %} 2095 2096 enc_class enc_cmov(cmpOp cop) 2097 %{ 2098 // CMOV 2099 $$$emit8$primary; 2100 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2101 %} 2102 2103 enc_class enc_PartialSubtypeCheck() 2104 %{ 2105 Register Rrdi = as_Register(RDI_enc); // result register 2106 Register Rrax = as_Register(RAX_enc); // super class 2107 Register Rrcx = as_Register(RCX_enc); // killed 2108 Register Rrsi = as_Register(RSI_enc); // sub class 2109 Label miss; 2110 const bool set_cond_codes = true; 2111 2112 MacroAssembler _masm(&cbuf); 2113 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2114 NULL, &miss, 2115 /*set_cond_codes:*/ true); 2116 if ($primary) { 2117 __ xorptr(Rrdi, Rrdi); 2118 } 2119 __ bind(miss); 2120 %} 2121 2122 enc_class clear_avx %{ 2123 debug_only(int off0 = cbuf.insts_size()); 2124 if (generate_vzeroupper(Compile::current())) { 2125 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2126 // Clear upper bits of YMM registers when current compiled code uses 2127 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2128 MacroAssembler _masm(&cbuf); 2129 __ vzeroupper(); 2130 } 2131 debug_only(int off1 = cbuf.insts_size()); 2132 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2133 %} 2134 2135 enc_class Java_To_Runtime(method meth) %{ 2136 // No relocation needed 2137 MacroAssembler _masm(&cbuf); 2138 __ mov64(r10, (int64_t) $meth$$method); 2139 __ call(r10); 2140 %} 2141 2142 enc_class Java_To_Interpreter(method meth) 2143 %{ 2144 // CALL Java_To_Interpreter 2145 // This is the instruction starting address for relocation info. 2146 cbuf.set_insts_mark(); 2147 $$$emit8$primary; 2148 // CALL directly to the runtime 2149 emit_d32_reloc(cbuf, 2150 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2151 runtime_call_Relocation::spec(), 2152 RELOC_DISP32); 2153 %} 2154 2155 enc_class Java_Static_Call(method meth) 2156 %{ 2157 // JAVA STATIC CALL 2158 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2159 // determine who we intended to call. 2160 cbuf.set_insts_mark(); 2161 $$$emit8$primary; 2162 2163 if (!_method) { 2164 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2165 runtime_call_Relocation::spec(), 2166 RELOC_DISP32); 2167 } else { 2168 int method_index = resolved_method_index(cbuf); 2169 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2170 : static_call_Relocation::spec(method_index); 2171 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2172 rspec, RELOC_DISP32); 2173 // Emit stubs for static call. 2174 address mark = cbuf.insts_mark(); 2175 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2176 if (stub == NULL) { 2177 ciEnv::current()->record_failure("CodeCache is full"); 2178 return; 2179 } 2180 #if INCLUDE_AOT 2181 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2182 #endif 2183 } 2184 %} 2185 2186 enc_class Java_Dynamic_Call(method meth) %{ 2187 MacroAssembler _masm(&cbuf); 2188 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2189 %} 2190 2191 enc_class Java_Compiled_Call(method meth) 2192 %{ 2193 // JAVA COMPILED CALL 2194 int disp = in_bytes(Method:: from_compiled_offset()); 2195 2196 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2197 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2198 2199 // callq *disp(%rax) 2200 cbuf.set_insts_mark(); 2201 $$$emit8$primary; 2202 if (disp < 0x80) { 2203 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2204 emit_d8(cbuf, disp); // Displacement 2205 } else { 2206 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2207 emit_d32(cbuf, disp); // Displacement 2208 } 2209 %} 2210 2211 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2212 %{ 2213 // SAL, SAR, SHR 2214 int dstenc = $dst$$reg; 2215 if (dstenc >= 8) { 2216 emit_opcode(cbuf, Assembler::REX_B); 2217 dstenc -= 8; 2218 } 2219 $$$emit8$primary; 2220 emit_rm(cbuf, 0x3, $secondary, dstenc); 2221 $$$emit8$shift$$constant; 2222 %} 2223 2224 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2225 %{ 2226 // SAL, SAR, SHR 2227 int dstenc = $dst$$reg; 2228 if (dstenc < 8) { 2229 emit_opcode(cbuf, Assembler::REX_W); 2230 } else { 2231 emit_opcode(cbuf, Assembler::REX_WB); 2232 dstenc -= 8; 2233 } 2234 $$$emit8$primary; 2235 emit_rm(cbuf, 0x3, $secondary, dstenc); 2236 $$$emit8$shift$$constant; 2237 %} 2238 2239 enc_class load_immI(rRegI dst, immI src) 2240 %{ 2241 int dstenc = $dst$$reg; 2242 if (dstenc >= 8) { 2243 emit_opcode(cbuf, Assembler::REX_B); 2244 dstenc -= 8; 2245 } 2246 emit_opcode(cbuf, 0xB8 | dstenc); 2247 $$$emit32$src$$constant; 2248 %} 2249 2250 enc_class load_immL(rRegL dst, immL src) 2251 %{ 2252 int dstenc = $dst$$reg; 2253 if (dstenc < 8) { 2254 emit_opcode(cbuf, Assembler::REX_W); 2255 } else { 2256 emit_opcode(cbuf, Assembler::REX_WB); 2257 dstenc -= 8; 2258 } 2259 emit_opcode(cbuf, 0xB8 | dstenc); 2260 emit_d64(cbuf, $src$$constant); 2261 %} 2262 2263 enc_class load_immUL32(rRegL dst, immUL32 src) 2264 %{ 2265 // same as load_immI, but this time we care about zeroes in the high word 2266 int dstenc = $dst$$reg; 2267 if (dstenc >= 8) { 2268 emit_opcode(cbuf, Assembler::REX_B); 2269 dstenc -= 8; 2270 } 2271 emit_opcode(cbuf, 0xB8 | dstenc); 2272 $$$emit32$src$$constant; 2273 %} 2274 2275 enc_class load_immL32(rRegL dst, immL32 src) 2276 %{ 2277 int dstenc = $dst$$reg; 2278 if (dstenc < 8) { 2279 emit_opcode(cbuf, Assembler::REX_W); 2280 } else { 2281 emit_opcode(cbuf, Assembler::REX_WB); 2282 dstenc -= 8; 2283 } 2284 emit_opcode(cbuf, 0xC7); 2285 emit_rm(cbuf, 0x03, 0x00, dstenc); 2286 $$$emit32$src$$constant; 2287 %} 2288 2289 enc_class load_immP31(rRegP dst, immP32 src) 2290 %{ 2291 // same as load_immI, but this time we care about zeroes in the high word 2292 int dstenc = $dst$$reg; 2293 if (dstenc >= 8) { 2294 emit_opcode(cbuf, Assembler::REX_B); 2295 dstenc -= 8; 2296 } 2297 emit_opcode(cbuf, 0xB8 | dstenc); 2298 $$$emit32$src$$constant; 2299 %} 2300 2301 enc_class load_immP(rRegP dst, immP src) 2302 %{ 2303 int dstenc = $dst$$reg; 2304 if (dstenc < 8) { 2305 emit_opcode(cbuf, Assembler::REX_W); 2306 } else { 2307 emit_opcode(cbuf, Assembler::REX_WB); 2308 dstenc -= 8; 2309 } 2310 emit_opcode(cbuf, 0xB8 | dstenc); 2311 // This next line should be generated from ADLC 2312 if ($src->constant_reloc() != relocInfo::none) { 2313 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2314 } else { 2315 emit_d64(cbuf, $src$$constant); 2316 } 2317 %} 2318 2319 enc_class Con32(immI src) 2320 %{ 2321 // Output immediate 2322 $$$emit32$src$$constant; 2323 %} 2324 2325 enc_class Con32F_as_bits(immF src) 2326 %{ 2327 // Output Float immediate bits 2328 jfloat jf = $src$$constant; 2329 jint jf_as_bits = jint_cast(jf); 2330 emit_d32(cbuf, jf_as_bits); 2331 %} 2332 2333 enc_class Con16(immI src) 2334 %{ 2335 // Output immediate 2336 $$$emit16$src$$constant; 2337 %} 2338 2339 // How is this different from Con32??? XXX 2340 enc_class Con_d32(immI src) 2341 %{ 2342 emit_d32(cbuf,$src$$constant); 2343 %} 2344 2345 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2346 // Output immediate memory reference 2347 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2348 emit_d32(cbuf, 0x00); 2349 %} 2350 2351 enc_class lock_prefix() 2352 %{ 2353 emit_opcode(cbuf, 0xF0); // lock 2354 %} 2355 2356 enc_class REX_mem(memory mem) 2357 %{ 2358 if ($mem$$base >= 8) { 2359 if ($mem$$index < 8) { 2360 emit_opcode(cbuf, Assembler::REX_B); 2361 } else { 2362 emit_opcode(cbuf, Assembler::REX_XB); 2363 } 2364 } else { 2365 if ($mem$$index >= 8) { 2366 emit_opcode(cbuf, Assembler::REX_X); 2367 } 2368 } 2369 %} 2370 2371 enc_class REX_mem_wide(memory mem) 2372 %{ 2373 if ($mem$$base >= 8) { 2374 if ($mem$$index < 8) { 2375 emit_opcode(cbuf, Assembler::REX_WB); 2376 } else { 2377 emit_opcode(cbuf, Assembler::REX_WXB); 2378 } 2379 } else { 2380 if ($mem$$index < 8) { 2381 emit_opcode(cbuf, Assembler::REX_W); 2382 } else { 2383 emit_opcode(cbuf, Assembler::REX_WX); 2384 } 2385 } 2386 %} 2387 2388 // for byte regs 2389 enc_class REX_breg(rRegI reg) 2390 %{ 2391 if ($reg$$reg >= 4) { 2392 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2393 } 2394 %} 2395 2396 // for byte regs 2397 enc_class REX_reg_breg(rRegI dst, rRegI src) 2398 %{ 2399 if ($dst$$reg < 8) { 2400 if ($src$$reg >= 4) { 2401 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2402 } 2403 } else { 2404 if ($src$$reg < 8) { 2405 emit_opcode(cbuf, Assembler::REX_R); 2406 } else { 2407 emit_opcode(cbuf, Assembler::REX_RB); 2408 } 2409 } 2410 %} 2411 2412 // for byte regs 2413 enc_class REX_breg_mem(rRegI reg, memory mem) 2414 %{ 2415 if ($reg$$reg < 8) { 2416 if ($mem$$base < 8) { 2417 if ($mem$$index >= 8) { 2418 emit_opcode(cbuf, Assembler::REX_X); 2419 } else if ($reg$$reg >= 4) { 2420 emit_opcode(cbuf, Assembler::REX); 2421 } 2422 } else { 2423 if ($mem$$index < 8) { 2424 emit_opcode(cbuf, Assembler::REX_B); 2425 } else { 2426 emit_opcode(cbuf, Assembler::REX_XB); 2427 } 2428 } 2429 } else { 2430 if ($mem$$base < 8) { 2431 if ($mem$$index < 8) { 2432 emit_opcode(cbuf, Assembler::REX_R); 2433 } else { 2434 emit_opcode(cbuf, Assembler::REX_RX); 2435 } 2436 } else { 2437 if ($mem$$index < 8) { 2438 emit_opcode(cbuf, Assembler::REX_RB); 2439 } else { 2440 emit_opcode(cbuf, Assembler::REX_RXB); 2441 } 2442 } 2443 } 2444 %} 2445 2446 enc_class REX_reg(rRegI reg) 2447 %{ 2448 if ($reg$$reg >= 8) { 2449 emit_opcode(cbuf, Assembler::REX_B); 2450 } 2451 %} 2452 2453 enc_class REX_reg_wide(rRegI reg) 2454 %{ 2455 if ($reg$$reg < 8) { 2456 emit_opcode(cbuf, Assembler::REX_W); 2457 } else { 2458 emit_opcode(cbuf, Assembler::REX_WB); 2459 } 2460 %} 2461 2462 enc_class REX_reg_reg(rRegI dst, rRegI src) 2463 %{ 2464 if ($dst$$reg < 8) { 2465 if ($src$$reg >= 8) { 2466 emit_opcode(cbuf, Assembler::REX_B); 2467 } 2468 } else { 2469 if ($src$$reg < 8) { 2470 emit_opcode(cbuf, Assembler::REX_R); 2471 } else { 2472 emit_opcode(cbuf, Assembler::REX_RB); 2473 } 2474 } 2475 %} 2476 2477 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2478 %{ 2479 if ($dst$$reg < 8) { 2480 if ($src$$reg < 8) { 2481 emit_opcode(cbuf, Assembler::REX_W); 2482 } else { 2483 emit_opcode(cbuf, Assembler::REX_WB); 2484 } 2485 } else { 2486 if ($src$$reg < 8) { 2487 emit_opcode(cbuf, Assembler::REX_WR); 2488 } else { 2489 emit_opcode(cbuf, Assembler::REX_WRB); 2490 } 2491 } 2492 %} 2493 2494 enc_class REX_reg_mem(rRegI reg, memory mem) 2495 %{ 2496 if ($reg$$reg < 8) { 2497 if ($mem$$base < 8) { 2498 if ($mem$$index >= 8) { 2499 emit_opcode(cbuf, Assembler::REX_X); 2500 } 2501 } else { 2502 if ($mem$$index < 8) { 2503 emit_opcode(cbuf, Assembler::REX_B); 2504 } else { 2505 emit_opcode(cbuf, Assembler::REX_XB); 2506 } 2507 } 2508 } else { 2509 if ($mem$$base < 8) { 2510 if ($mem$$index < 8) { 2511 emit_opcode(cbuf, Assembler::REX_R); 2512 } else { 2513 emit_opcode(cbuf, Assembler::REX_RX); 2514 } 2515 } else { 2516 if ($mem$$index < 8) { 2517 emit_opcode(cbuf, Assembler::REX_RB); 2518 } else { 2519 emit_opcode(cbuf, Assembler::REX_RXB); 2520 } 2521 } 2522 } 2523 %} 2524 2525 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2526 %{ 2527 if ($reg$$reg < 8) { 2528 if ($mem$$base < 8) { 2529 if ($mem$$index < 8) { 2530 emit_opcode(cbuf, Assembler::REX_W); 2531 } else { 2532 emit_opcode(cbuf, Assembler::REX_WX); 2533 } 2534 } else { 2535 if ($mem$$index < 8) { 2536 emit_opcode(cbuf, Assembler::REX_WB); 2537 } else { 2538 emit_opcode(cbuf, Assembler::REX_WXB); 2539 } 2540 } 2541 } else { 2542 if ($mem$$base < 8) { 2543 if ($mem$$index < 8) { 2544 emit_opcode(cbuf, Assembler::REX_WR); 2545 } else { 2546 emit_opcode(cbuf, Assembler::REX_WRX); 2547 } 2548 } else { 2549 if ($mem$$index < 8) { 2550 emit_opcode(cbuf, Assembler::REX_WRB); 2551 } else { 2552 emit_opcode(cbuf, Assembler::REX_WRXB); 2553 } 2554 } 2555 } 2556 %} 2557 2558 enc_class reg_mem(rRegI ereg, memory mem) 2559 %{ 2560 // High registers handle in encode_RegMem 2561 int reg = $ereg$$reg; 2562 int base = $mem$$base; 2563 int index = $mem$$index; 2564 int scale = $mem$$scale; 2565 int disp = $mem$$disp; 2566 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2567 2568 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2569 %} 2570 2571 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2572 %{ 2573 int rm_byte_opcode = $rm_opcode$$constant; 2574 2575 // High registers handle in encode_RegMem 2576 int base = $mem$$base; 2577 int index = $mem$$index; 2578 int scale = $mem$$scale; 2579 int displace = $mem$$disp; 2580 2581 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2582 // working with static 2583 // globals 2584 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2585 disp_reloc); 2586 %} 2587 2588 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2589 %{ 2590 int reg_encoding = $dst$$reg; 2591 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2592 int index = 0x04; // 0x04 indicates no index 2593 int scale = 0x00; // 0x00 indicates no scale 2594 int displace = $src1$$constant; // 0x00 indicates no displacement 2595 relocInfo::relocType disp_reloc = relocInfo::none; 2596 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2597 disp_reloc); 2598 %} 2599 2600 enc_class neg_reg(rRegI dst) 2601 %{ 2602 int dstenc = $dst$$reg; 2603 if (dstenc >= 8) { 2604 emit_opcode(cbuf, Assembler::REX_B); 2605 dstenc -= 8; 2606 } 2607 // NEG $dst 2608 emit_opcode(cbuf, 0xF7); 2609 emit_rm(cbuf, 0x3, 0x03, dstenc); 2610 %} 2611 2612 enc_class neg_reg_wide(rRegI dst) 2613 %{ 2614 int dstenc = $dst$$reg; 2615 if (dstenc < 8) { 2616 emit_opcode(cbuf, Assembler::REX_W); 2617 } else { 2618 emit_opcode(cbuf, Assembler::REX_WB); 2619 dstenc -= 8; 2620 } 2621 // NEG $dst 2622 emit_opcode(cbuf, 0xF7); 2623 emit_rm(cbuf, 0x3, 0x03, dstenc); 2624 %} 2625 2626 enc_class setLT_reg(rRegI dst) 2627 %{ 2628 int dstenc = $dst$$reg; 2629 if (dstenc >= 8) { 2630 emit_opcode(cbuf, Assembler::REX_B); 2631 dstenc -= 8; 2632 } else if (dstenc >= 4) { 2633 emit_opcode(cbuf, Assembler::REX); 2634 } 2635 // SETLT $dst 2636 emit_opcode(cbuf, 0x0F); 2637 emit_opcode(cbuf, 0x9C); 2638 emit_rm(cbuf, 0x3, 0x0, dstenc); 2639 %} 2640 2641 enc_class setNZ_reg(rRegI dst) 2642 %{ 2643 int dstenc = $dst$$reg; 2644 if (dstenc >= 8) { 2645 emit_opcode(cbuf, Assembler::REX_B); 2646 dstenc -= 8; 2647 } else if (dstenc >= 4) { 2648 emit_opcode(cbuf, Assembler::REX); 2649 } 2650 // SETNZ $dst 2651 emit_opcode(cbuf, 0x0F); 2652 emit_opcode(cbuf, 0x95); 2653 emit_rm(cbuf, 0x3, 0x0, dstenc); 2654 %} 2655 2656 2657 // Compare the lonogs and set -1, 0, or 1 into dst 2658 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2659 %{ 2660 int src1enc = $src1$$reg; 2661 int src2enc = $src2$$reg; 2662 int dstenc = $dst$$reg; 2663 2664 // cmpq $src1, $src2 2665 if (src1enc < 8) { 2666 if (src2enc < 8) { 2667 emit_opcode(cbuf, Assembler::REX_W); 2668 } else { 2669 emit_opcode(cbuf, Assembler::REX_WB); 2670 } 2671 } else { 2672 if (src2enc < 8) { 2673 emit_opcode(cbuf, Assembler::REX_WR); 2674 } else { 2675 emit_opcode(cbuf, Assembler::REX_WRB); 2676 } 2677 } 2678 emit_opcode(cbuf, 0x3B); 2679 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2680 2681 // movl $dst, -1 2682 if (dstenc >= 8) { 2683 emit_opcode(cbuf, Assembler::REX_B); 2684 } 2685 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2686 emit_d32(cbuf, -1); 2687 2688 // jl,s done 2689 emit_opcode(cbuf, 0x7C); 2690 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2691 2692 // setne $dst 2693 if (dstenc >= 4) { 2694 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2695 } 2696 emit_opcode(cbuf, 0x0F); 2697 emit_opcode(cbuf, 0x95); 2698 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2699 2700 // movzbl $dst, $dst 2701 if (dstenc >= 4) { 2702 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2703 } 2704 emit_opcode(cbuf, 0x0F); 2705 emit_opcode(cbuf, 0xB6); 2706 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2707 %} 2708 2709 enc_class Push_ResultXD(regD dst) %{ 2710 MacroAssembler _masm(&cbuf); 2711 __ fstp_d(Address(rsp, 0)); 2712 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2713 __ addptr(rsp, 8); 2714 %} 2715 2716 enc_class Push_SrcXD(regD src) %{ 2717 MacroAssembler _masm(&cbuf); 2718 __ subptr(rsp, 8); 2719 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2720 __ fld_d(Address(rsp, 0)); 2721 %} 2722 2723 2724 enc_class enc_rethrow() 2725 %{ 2726 cbuf.set_insts_mark(); 2727 emit_opcode(cbuf, 0xE9); // jmp entry 2728 emit_d32_reloc(cbuf, 2729 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2730 runtime_call_Relocation::spec(), 2731 RELOC_DISP32); 2732 %} 2733 2734 %} 2735 2736 2737 2738 //----------FRAME-------------------------------------------------------------- 2739 // Definition of frame structure and management information. 2740 // 2741 // S T A C K L A Y O U T Allocators stack-slot number 2742 // | (to get allocators register number 2743 // G Owned by | | v add OptoReg::stack0()) 2744 // r CALLER | | 2745 // o | +--------+ pad to even-align allocators stack-slot 2746 // w V | pad0 | numbers; owned by CALLER 2747 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2748 // h ^ | in | 5 2749 // | | args | 4 Holes in incoming args owned by SELF 2750 // | | | | 3 2751 // | | +--------+ 2752 // V | | old out| Empty on Intel, window on Sparc 2753 // | old |preserve| Must be even aligned. 2754 // | SP-+--------+----> Matcher::_old_SP, even aligned 2755 // | | in | 3 area for Intel ret address 2756 // Owned by |preserve| Empty on Sparc. 2757 // SELF +--------+ 2758 // | | pad2 | 2 pad to align old SP 2759 // | +--------+ 1 2760 // | | locks | 0 2761 // | +--------+----> OptoReg::stack0(), even aligned 2762 // | | pad1 | 11 pad to align new SP 2763 // | +--------+ 2764 // | | | 10 2765 // | | spills | 9 spills 2766 // V | | 8 (pad0 slot for callee) 2767 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2768 // ^ | out | 7 2769 // | | args | 6 Holes in outgoing args owned by CALLEE 2770 // Owned by +--------+ 2771 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2772 // | new |preserve| Must be even-aligned. 2773 // | SP-+--------+----> Matcher::_new_SP, even aligned 2774 // | | | 2775 // 2776 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2777 // known from SELF's arguments and the Java calling convention. 2778 // Region 6-7 is determined per call site. 2779 // Note 2: If the calling convention leaves holes in the incoming argument 2780 // area, those holes are owned by SELF. Holes in the outgoing area 2781 // are owned by the CALLEE. Holes should not be nessecary in the 2782 // incoming area, as the Java calling convention is completely under 2783 // the control of the AD file. Doubles can be sorted and packed to 2784 // avoid holes. Holes in the outgoing arguments may be nessecary for 2785 // varargs C calling conventions. 2786 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2787 // even aligned with pad0 as needed. 2788 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2789 // region 6-11 is even aligned; it may be padded out more so that 2790 // the region from SP to FP meets the minimum stack alignment. 2791 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2792 // alignment. Region 11, pad1, may be dynamically extended so that 2793 // SP meets the minimum alignment. 2794 2795 frame 2796 %{ 2797 // What direction does stack grow in (assumed to be same for C & Java) 2798 stack_direction(TOWARDS_LOW); 2799 2800 // These three registers define part of the calling convention 2801 // between compiled code and the interpreter. 2802 inline_cache_reg(RAX); // Inline Cache Register 2803 interpreter_method_oop_reg(RBX); // Method Oop Register when 2804 // calling interpreter 2805 2806 // Optional: name the operand used by cisc-spilling to access 2807 // [stack_pointer + offset] 2808 cisc_spilling_operand_name(indOffset32); 2809 2810 // Number of stack slots consumed by locking an object 2811 sync_stack_slots(2); 2812 2813 // Compiled code's Frame Pointer 2814 frame_pointer(RSP); 2815 2816 // Interpreter stores its frame pointer in a register which is 2817 // stored to the stack by I2CAdaptors. 2818 // I2CAdaptors convert from interpreted java to compiled java. 2819 interpreter_frame_pointer(RBP); 2820 2821 // Stack alignment requirement 2822 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2823 2824 // Number of stack slots between incoming argument block and the start of 2825 // a new frame. The PROLOG must add this many slots to the stack. The 2826 // EPILOG must remove this many slots. amd64 needs two slots for 2827 // return address. 2828 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2829 2830 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2831 // for calls to C. Supports the var-args backing area for register parms. 2832 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2833 2834 // The after-PROLOG location of the return address. Location of 2835 // return address specifies a type (REG or STACK) and a number 2836 // representing the register number (i.e. - use a register name) or 2837 // stack slot. 2838 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2839 // Otherwise, it is above the locks and verification slot and alignment word 2840 return_addr(STACK - 2 + 2841 align_up((Compile::current()->in_preserve_stack_slots() + 2842 Compile::current()->fixed_slots()), 2843 stack_alignment_in_slots())); 2844 2845 // Body of function which returns an integer array locating 2846 // arguments either in registers or in stack slots. Passed an array 2847 // of ideal registers called "sig" and a "length" count. Stack-slot 2848 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2849 // arguments for a CALLEE. Incoming stack arguments are 2850 // automatically biased by the preserve_stack_slots field above. 2851 2852 calling_convention 2853 %{ 2854 // No difference between ingoing/outgoing just pass false 2855 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2856 %} 2857 2858 c_calling_convention 2859 %{ 2860 // This is obviously always outgoing 2861 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2862 %} 2863 2864 // Location of compiled Java return values. Same as C for now. 2865 return_value 2866 %{ 2867 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2868 "only return normal values"); 2869 2870 static const int lo[Op_RegL + 1] = { 2871 0, 2872 0, 2873 RAX_num, // Op_RegN 2874 RAX_num, // Op_RegI 2875 RAX_num, // Op_RegP 2876 XMM0_num, // Op_RegF 2877 XMM0_num, // Op_RegD 2878 RAX_num // Op_RegL 2879 }; 2880 static const int hi[Op_RegL + 1] = { 2881 0, 2882 0, 2883 OptoReg::Bad, // Op_RegN 2884 OptoReg::Bad, // Op_RegI 2885 RAX_H_num, // Op_RegP 2886 OptoReg::Bad, // Op_RegF 2887 XMM0b_num, // Op_RegD 2888 RAX_H_num // Op_RegL 2889 }; 2890 // Excluded flags and vector registers. 2891 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2892 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2893 %} 2894 %} 2895 2896 //----------ATTRIBUTES--------------------------------------------------------- 2897 //----------Operand Attributes------------------------------------------------- 2898 op_attrib op_cost(0); // Required cost attribute 2899 2900 //----------Instruction Attributes--------------------------------------------- 2901 ins_attrib ins_cost(100); // Required cost attribute 2902 ins_attrib ins_size(8); // Required size attribute (in bits) 2903 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2904 // a non-matching short branch variant 2905 // of some long branch? 2906 ins_attrib ins_alignment(1); // Required alignment attribute (must 2907 // be a power of 2) specifies the 2908 // alignment that some part of the 2909 // instruction (not necessarily the 2910 // start) requires. If > 1, a 2911 // compute_padding() function must be 2912 // provided for the instruction 2913 2914 //----------OPERANDS----------------------------------------------------------- 2915 // Operand definitions must precede instruction definitions for correct parsing 2916 // in the ADLC because operands constitute user defined types which are used in 2917 // instruction definitions. 2918 2919 //----------Simple Operands---------------------------------------------------- 2920 // Immediate Operands 2921 // Integer Immediate 2922 operand immI() 2923 %{ 2924 match(ConI); 2925 2926 op_cost(10); 2927 format %{ %} 2928 interface(CONST_INTER); 2929 %} 2930 2931 // Constant for test vs zero 2932 operand immI0() 2933 %{ 2934 predicate(n->get_int() == 0); 2935 match(ConI); 2936 2937 op_cost(0); 2938 format %{ %} 2939 interface(CONST_INTER); 2940 %} 2941 2942 // Constant for increment 2943 operand immI1() 2944 %{ 2945 predicate(n->get_int() == 1); 2946 match(ConI); 2947 2948 op_cost(0); 2949 format %{ %} 2950 interface(CONST_INTER); 2951 %} 2952 2953 // Constant for decrement 2954 operand immI_M1() 2955 %{ 2956 predicate(n->get_int() == -1); 2957 match(ConI); 2958 2959 op_cost(0); 2960 format %{ %} 2961 interface(CONST_INTER); 2962 %} 2963 2964 // Valid scale values for addressing modes 2965 operand immI2() 2966 %{ 2967 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2968 match(ConI); 2969 2970 format %{ %} 2971 interface(CONST_INTER); 2972 %} 2973 2974 operand immI8() 2975 %{ 2976 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2977 match(ConI); 2978 2979 op_cost(5); 2980 format %{ %} 2981 interface(CONST_INTER); 2982 %} 2983 2984 operand immU8() 2985 %{ 2986 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2987 match(ConI); 2988 2989 op_cost(5); 2990 format %{ %} 2991 interface(CONST_INTER); 2992 %} 2993 2994 operand immI16() 2995 %{ 2996 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2997 match(ConI); 2998 2999 op_cost(10); 3000 format %{ %} 3001 interface(CONST_INTER); 3002 %} 3003 3004 // Int Immediate non-negative 3005 operand immU31() 3006 %{ 3007 predicate(n->get_int() >= 0); 3008 match(ConI); 3009 3010 op_cost(0); 3011 format %{ %} 3012 interface(CONST_INTER); 3013 %} 3014 3015 // Constant for long shifts 3016 operand immI_32() 3017 %{ 3018 predicate( n->get_int() == 32 ); 3019 match(ConI); 3020 3021 op_cost(0); 3022 format %{ %} 3023 interface(CONST_INTER); 3024 %} 3025 3026 // Constant for long shifts 3027 operand immI_64() 3028 %{ 3029 predicate( n->get_int() == 64 ); 3030 match(ConI); 3031 3032 op_cost(0); 3033 format %{ %} 3034 interface(CONST_INTER); 3035 %} 3036 3037 // Pointer Immediate 3038 operand immP() 3039 %{ 3040 match(ConP); 3041 3042 op_cost(10); 3043 format %{ %} 3044 interface(CONST_INTER); 3045 %} 3046 3047 // NULL Pointer Immediate 3048 operand immP0() 3049 %{ 3050 predicate(n->get_ptr() == 0); 3051 match(ConP); 3052 3053 op_cost(5); 3054 format %{ %} 3055 interface(CONST_INTER); 3056 %} 3057 3058 // Pointer Immediate 3059 operand immN() %{ 3060 match(ConN); 3061 3062 op_cost(10); 3063 format %{ %} 3064 interface(CONST_INTER); 3065 %} 3066 3067 operand immNKlass() %{ 3068 match(ConNKlass); 3069 3070 op_cost(10); 3071 format %{ %} 3072 interface(CONST_INTER); 3073 %} 3074 3075 // NULL Pointer Immediate 3076 operand immN0() %{ 3077 predicate(n->get_narrowcon() == 0); 3078 match(ConN); 3079 3080 op_cost(5); 3081 format %{ %} 3082 interface(CONST_INTER); 3083 %} 3084 3085 operand immP31() 3086 %{ 3087 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3088 && (n->get_ptr() >> 31) == 0); 3089 match(ConP); 3090 3091 op_cost(5); 3092 format %{ %} 3093 interface(CONST_INTER); 3094 %} 3095 3096 3097 // Long Immediate 3098 operand immL() 3099 %{ 3100 match(ConL); 3101 3102 op_cost(20); 3103 format %{ %} 3104 interface(CONST_INTER); 3105 %} 3106 3107 // Long Immediate 8-bit 3108 operand immL8() 3109 %{ 3110 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3111 match(ConL); 3112 3113 op_cost(5); 3114 format %{ %} 3115 interface(CONST_INTER); 3116 %} 3117 3118 // Long Immediate 32-bit unsigned 3119 operand immUL32() 3120 %{ 3121 predicate(n->get_long() == (unsigned int) (n->get_long())); 3122 match(ConL); 3123 3124 op_cost(10); 3125 format %{ %} 3126 interface(CONST_INTER); 3127 %} 3128 3129 // Long Immediate 32-bit signed 3130 operand immL32() 3131 %{ 3132 predicate(n->get_long() == (int) (n->get_long())); 3133 match(ConL); 3134 3135 op_cost(15); 3136 format %{ %} 3137 interface(CONST_INTER); 3138 %} 3139 3140 // Long Immediate zero 3141 operand immL0() 3142 %{ 3143 predicate(n->get_long() == 0L); 3144 match(ConL); 3145 3146 op_cost(10); 3147 format %{ %} 3148 interface(CONST_INTER); 3149 %} 3150 3151 // Constant for increment 3152 operand immL1() 3153 %{ 3154 predicate(n->get_long() == 1); 3155 match(ConL); 3156 3157 format %{ %} 3158 interface(CONST_INTER); 3159 %} 3160 3161 // Constant for decrement 3162 operand immL_M1() 3163 %{ 3164 predicate(n->get_long() == -1); 3165 match(ConL); 3166 3167 format %{ %} 3168 interface(CONST_INTER); 3169 %} 3170 3171 // Long Immediate: the value 10 3172 operand immL10() 3173 %{ 3174 predicate(n->get_long() == 10); 3175 match(ConL); 3176 3177 format %{ %} 3178 interface(CONST_INTER); 3179 %} 3180 3181 // Long immediate from 0 to 127. 3182 // Used for a shorter form of long mul by 10. 3183 operand immL_127() 3184 %{ 3185 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3186 match(ConL); 3187 3188 op_cost(10); 3189 format %{ %} 3190 interface(CONST_INTER); 3191 %} 3192 3193 // Long Immediate: low 32-bit mask 3194 operand immL_32bits() 3195 %{ 3196 predicate(n->get_long() == 0xFFFFFFFFL); 3197 match(ConL); 3198 op_cost(20); 3199 3200 format %{ %} 3201 interface(CONST_INTER); 3202 %} 3203 3204 // Float Immediate zero 3205 operand immF0() 3206 %{ 3207 predicate(jint_cast(n->getf()) == 0); 3208 match(ConF); 3209 3210 op_cost(5); 3211 format %{ %} 3212 interface(CONST_INTER); 3213 %} 3214 3215 // Float Immediate 3216 operand immF() 3217 %{ 3218 match(ConF); 3219 3220 op_cost(15); 3221 format %{ %} 3222 interface(CONST_INTER); 3223 %} 3224 3225 // Double Immediate zero 3226 operand immD0() 3227 %{ 3228 predicate(jlong_cast(n->getd()) == 0); 3229 match(ConD); 3230 3231 op_cost(5); 3232 format %{ %} 3233 interface(CONST_INTER); 3234 %} 3235 3236 // Double Immediate 3237 operand immD() 3238 %{ 3239 match(ConD); 3240 3241 op_cost(15); 3242 format %{ %} 3243 interface(CONST_INTER); 3244 %} 3245 3246 // Immediates for special shifts (sign extend) 3247 3248 // Constants for increment 3249 operand immI_16() 3250 %{ 3251 predicate(n->get_int() == 16); 3252 match(ConI); 3253 3254 format %{ %} 3255 interface(CONST_INTER); 3256 %} 3257 3258 operand immI_24() 3259 %{ 3260 predicate(n->get_int() == 24); 3261 match(ConI); 3262 3263 format %{ %} 3264 interface(CONST_INTER); 3265 %} 3266 3267 // Constant for byte-wide masking 3268 operand immI_255() 3269 %{ 3270 predicate(n->get_int() == 255); 3271 match(ConI); 3272 3273 format %{ %} 3274 interface(CONST_INTER); 3275 %} 3276 3277 // Constant for short-wide masking 3278 operand immI_65535() 3279 %{ 3280 predicate(n->get_int() == 65535); 3281 match(ConI); 3282 3283 format %{ %} 3284 interface(CONST_INTER); 3285 %} 3286 3287 // Constant for byte-wide masking 3288 operand immL_255() 3289 %{ 3290 predicate(n->get_long() == 255); 3291 match(ConL); 3292 3293 format %{ %} 3294 interface(CONST_INTER); 3295 %} 3296 3297 // Constant for short-wide masking 3298 operand immL_65535() 3299 %{ 3300 predicate(n->get_long() == 65535); 3301 match(ConL); 3302 3303 format %{ %} 3304 interface(CONST_INTER); 3305 %} 3306 3307 // Register Operands 3308 // Integer Register 3309 operand rRegI() 3310 %{ 3311 constraint(ALLOC_IN_RC(int_reg)); 3312 match(RegI); 3313 3314 match(rax_RegI); 3315 match(rbx_RegI); 3316 match(rcx_RegI); 3317 match(rdx_RegI); 3318 match(rdi_RegI); 3319 3320 format %{ %} 3321 interface(REG_INTER); 3322 %} 3323 3324 // Special Registers 3325 operand rax_RegI() 3326 %{ 3327 constraint(ALLOC_IN_RC(int_rax_reg)); 3328 match(RegI); 3329 match(rRegI); 3330 3331 format %{ "RAX" %} 3332 interface(REG_INTER); 3333 %} 3334 3335 // Special Registers 3336 operand rbx_RegI() 3337 %{ 3338 constraint(ALLOC_IN_RC(int_rbx_reg)); 3339 match(RegI); 3340 match(rRegI); 3341 3342 format %{ "RBX" %} 3343 interface(REG_INTER); 3344 %} 3345 3346 operand rcx_RegI() 3347 %{ 3348 constraint(ALLOC_IN_RC(int_rcx_reg)); 3349 match(RegI); 3350 match(rRegI); 3351 3352 format %{ "RCX" %} 3353 interface(REG_INTER); 3354 %} 3355 3356 operand rdx_RegI() 3357 %{ 3358 constraint(ALLOC_IN_RC(int_rdx_reg)); 3359 match(RegI); 3360 match(rRegI); 3361 3362 format %{ "RDX" %} 3363 interface(REG_INTER); 3364 %} 3365 3366 operand rdi_RegI() 3367 %{ 3368 constraint(ALLOC_IN_RC(int_rdi_reg)); 3369 match(RegI); 3370 match(rRegI); 3371 3372 format %{ "RDI" %} 3373 interface(REG_INTER); 3374 %} 3375 3376 operand no_rcx_RegI() 3377 %{ 3378 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3379 match(RegI); 3380 match(rax_RegI); 3381 match(rbx_RegI); 3382 match(rdx_RegI); 3383 match(rdi_RegI); 3384 3385 format %{ %} 3386 interface(REG_INTER); 3387 %} 3388 3389 operand no_rax_rdx_RegI() 3390 %{ 3391 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3392 match(RegI); 3393 match(rbx_RegI); 3394 match(rcx_RegI); 3395 match(rdi_RegI); 3396 3397 format %{ %} 3398 interface(REG_INTER); 3399 %} 3400 3401 // Pointer Register 3402 operand any_RegP() 3403 %{ 3404 constraint(ALLOC_IN_RC(any_reg)); 3405 match(RegP); 3406 match(rax_RegP); 3407 match(rbx_RegP); 3408 match(rdi_RegP); 3409 match(rsi_RegP); 3410 match(rbp_RegP); 3411 match(r15_RegP); 3412 match(rRegP); 3413 3414 format %{ %} 3415 interface(REG_INTER); 3416 %} 3417 3418 operand rRegP() 3419 %{ 3420 constraint(ALLOC_IN_RC(ptr_reg)); 3421 match(RegP); 3422 match(rax_RegP); 3423 match(rbx_RegP); 3424 match(rdi_RegP); 3425 match(rsi_RegP); 3426 match(rbp_RegP); // See Q&A below about 3427 match(r15_RegP); // r15_RegP and rbp_RegP. 3428 3429 format %{ %} 3430 interface(REG_INTER); 3431 %} 3432 3433 operand rRegN() %{ 3434 constraint(ALLOC_IN_RC(int_reg)); 3435 match(RegN); 3436 3437 format %{ %} 3438 interface(REG_INTER); 3439 %} 3440 3441 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3442 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3443 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3444 // The output of an instruction is controlled by the allocator, which respects 3445 // register class masks, not match rules. Unless an instruction mentions 3446 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3447 // by the allocator as an input. 3448 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3449 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3450 // result, RBP is not included in the output of the instruction either. 3451 3452 operand no_rax_RegP() 3453 %{ 3454 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3455 match(RegP); 3456 match(rbx_RegP); 3457 match(rsi_RegP); 3458 match(rdi_RegP); 3459 3460 format %{ %} 3461 interface(REG_INTER); 3462 %} 3463 3464 // This operand is not allowed to use RBP even if 3465 // RBP is not used to hold the frame pointer. 3466 operand no_rbp_RegP() 3467 %{ 3468 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3469 match(RegP); 3470 match(rbx_RegP); 3471 match(rsi_RegP); 3472 match(rdi_RegP); 3473 3474 format %{ %} 3475 interface(REG_INTER); 3476 %} 3477 3478 operand no_rax_rbx_RegP() 3479 %{ 3480 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3481 match(RegP); 3482 match(rsi_RegP); 3483 match(rdi_RegP); 3484 3485 format %{ %} 3486 interface(REG_INTER); 3487 %} 3488 3489 // Special Registers 3490 // Return a pointer value 3491 operand rax_RegP() 3492 %{ 3493 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3494 match(RegP); 3495 match(rRegP); 3496 3497 format %{ %} 3498 interface(REG_INTER); 3499 %} 3500 3501 // Special Registers 3502 // Return a compressed pointer value 3503 operand rax_RegN() 3504 %{ 3505 constraint(ALLOC_IN_RC(int_rax_reg)); 3506 match(RegN); 3507 match(rRegN); 3508 3509 format %{ %} 3510 interface(REG_INTER); 3511 %} 3512 3513 // Used in AtomicAdd 3514 operand rbx_RegP() 3515 %{ 3516 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3517 match(RegP); 3518 match(rRegP); 3519 3520 format %{ %} 3521 interface(REG_INTER); 3522 %} 3523 3524 operand rsi_RegP() 3525 %{ 3526 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3527 match(RegP); 3528 match(rRegP); 3529 3530 format %{ %} 3531 interface(REG_INTER); 3532 %} 3533 3534 // Used in rep stosq 3535 operand rdi_RegP() 3536 %{ 3537 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3538 match(RegP); 3539 match(rRegP); 3540 3541 format %{ %} 3542 interface(REG_INTER); 3543 %} 3544 3545 operand r15_RegP() 3546 %{ 3547 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3548 match(RegP); 3549 match(rRegP); 3550 3551 format %{ %} 3552 interface(REG_INTER); 3553 %} 3554 3555 operand rRegL() 3556 %{ 3557 constraint(ALLOC_IN_RC(long_reg)); 3558 match(RegL); 3559 match(rax_RegL); 3560 match(rdx_RegL); 3561 3562 format %{ %} 3563 interface(REG_INTER); 3564 %} 3565 3566 // Special Registers 3567 operand no_rax_rdx_RegL() 3568 %{ 3569 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3570 match(RegL); 3571 match(rRegL); 3572 3573 format %{ %} 3574 interface(REG_INTER); 3575 %} 3576 3577 operand no_rax_RegL() 3578 %{ 3579 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3580 match(RegL); 3581 match(rRegL); 3582 match(rdx_RegL); 3583 3584 format %{ %} 3585 interface(REG_INTER); 3586 %} 3587 3588 operand no_rcx_RegL() 3589 %{ 3590 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3591 match(RegL); 3592 match(rRegL); 3593 3594 format %{ %} 3595 interface(REG_INTER); 3596 %} 3597 3598 operand rax_RegL() 3599 %{ 3600 constraint(ALLOC_IN_RC(long_rax_reg)); 3601 match(RegL); 3602 match(rRegL); 3603 3604 format %{ "RAX" %} 3605 interface(REG_INTER); 3606 %} 3607 3608 operand rcx_RegL() 3609 %{ 3610 constraint(ALLOC_IN_RC(long_rcx_reg)); 3611 match(RegL); 3612 match(rRegL); 3613 3614 format %{ %} 3615 interface(REG_INTER); 3616 %} 3617 3618 operand rdx_RegL() 3619 %{ 3620 constraint(ALLOC_IN_RC(long_rdx_reg)); 3621 match(RegL); 3622 match(rRegL); 3623 3624 format %{ %} 3625 interface(REG_INTER); 3626 %} 3627 3628 // Flags register, used as output of compare instructions 3629 operand rFlagsReg() 3630 %{ 3631 constraint(ALLOC_IN_RC(int_flags)); 3632 match(RegFlags); 3633 3634 format %{ "RFLAGS" %} 3635 interface(REG_INTER); 3636 %} 3637 3638 // Flags register, used as output of FLOATING POINT compare instructions 3639 operand rFlagsRegU() 3640 %{ 3641 constraint(ALLOC_IN_RC(int_flags)); 3642 match(RegFlags); 3643 3644 format %{ "RFLAGS_U" %} 3645 interface(REG_INTER); 3646 %} 3647 3648 operand rFlagsRegUCF() %{ 3649 constraint(ALLOC_IN_RC(int_flags)); 3650 match(RegFlags); 3651 predicate(false); 3652 3653 format %{ "RFLAGS_U_CF" %} 3654 interface(REG_INTER); 3655 %} 3656 3657 // Float register operands 3658 operand regF() %{ 3659 constraint(ALLOC_IN_RC(float_reg)); 3660 match(RegF); 3661 3662 format %{ %} 3663 interface(REG_INTER); 3664 %} 3665 3666 3667 // Float register operands 3668 operand legRegF() %{ 3669 constraint(ALLOC_IN_RC(float_reg_legacy)); 3670 match(RegF); 3671 3672 format %{ %} 3673 interface(REG_INTER); 3674 %} 3675 3676 // Float register operands 3677 operand vlRegF() %{ 3678 constraint(ALLOC_IN_RC(float_reg_vl)); 3679 match(RegF); 3680 3681 format %{ %} 3682 interface(REG_INTER); 3683 %} 3684 3685 // Double register operands 3686 operand regD() %{ 3687 constraint(ALLOC_IN_RC(double_reg)); 3688 match(RegD); 3689 3690 format %{ %} 3691 interface(REG_INTER); 3692 %} 3693 3694 // Double register operands 3695 operand legRegD() %{ 3696 constraint(ALLOC_IN_RC(double_reg_legacy)); 3697 match(RegD); 3698 3699 format %{ %} 3700 interface(REG_INTER); 3701 %} 3702 3703 // Double register operands 3704 operand vlRegD() %{ 3705 constraint(ALLOC_IN_RC(double_reg_vl)); 3706 match(RegD); 3707 3708 format %{ %} 3709 interface(REG_INTER); 3710 %} 3711 3712 // Vectors 3713 operand vecS() %{ 3714 constraint(ALLOC_IN_RC(vectors_reg_vlbwdq)); 3715 match(VecS); 3716 3717 format %{ %} 3718 interface(REG_INTER); 3719 %} 3720 3721 // Vectors 3722 operand legVecS() %{ 3723 constraint(ALLOC_IN_RC(vectors_reg_legacy)); 3724 match(VecS); 3725 3726 format %{ %} 3727 interface(REG_INTER); 3728 %} 3729 3730 operand vecD() %{ 3731 constraint(ALLOC_IN_RC(vectord_reg_vlbwdq)); 3732 match(VecD); 3733 3734 format %{ %} 3735 interface(REG_INTER); 3736 %} 3737 3738 operand legVecD() %{ 3739 constraint(ALLOC_IN_RC(vectord_reg_legacy)); 3740 match(VecD); 3741 3742 format %{ %} 3743 interface(REG_INTER); 3744 %} 3745 3746 operand vecX() %{ 3747 constraint(ALLOC_IN_RC(vectorx_reg_vlbwdq)); 3748 match(VecX); 3749 3750 format %{ %} 3751 interface(REG_INTER); 3752 %} 3753 3754 operand legVecX() %{ 3755 constraint(ALLOC_IN_RC(vectorx_reg_legacy)); 3756 match(VecX); 3757 3758 format %{ %} 3759 interface(REG_INTER); 3760 %} 3761 3762 operand vecY() %{ 3763 constraint(ALLOC_IN_RC(vectory_reg_vlbwdq)); 3764 match(VecY); 3765 3766 format %{ %} 3767 interface(REG_INTER); 3768 %} 3769 3770 operand legVecY() %{ 3771 constraint(ALLOC_IN_RC(vectory_reg_legacy)); 3772 match(VecY); 3773 3774 format %{ %} 3775 interface(REG_INTER); 3776 %} 3777 3778 //----------Memory Operands---------------------------------------------------- 3779 // Direct Memory Operand 3780 // operand direct(immP addr) 3781 // %{ 3782 // match(addr); 3783 3784 // format %{ "[$addr]" %} 3785 // interface(MEMORY_INTER) %{ 3786 // base(0xFFFFFFFF); 3787 // index(0x4); 3788 // scale(0x0); 3789 // disp($addr); 3790 // %} 3791 // %} 3792 3793 // Indirect Memory Operand 3794 operand indirect(any_RegP reg) 3795 %{ 3796 constraint(ALLOC_IN_RC(ptr_reg)); 3797 match(reg); 3798 3799 format %{ "[$reg]" %} 3800 interface(MEMORY_INTER) %{ 3801 base($reg); 3802 index(0x4); 3803 scale(0x0); 3804 disp(0x0); 3805 %} 3806 %} 3807 3808 // Indirect Memory Plus Short Offset Operand 3809 operand indOffset8(any_RegP reg, immL8 off) 3810 %{ 3811 constraint(ALLOC_IN_RC(ptr_reg)); 3812 match(AddP reg off); 3813 3814 format %{ "[$reg + $off (8-bit)]" %} 3815 interface(MEMORY_INTER) %{ 3816 base($reg); 3817 index(0x4); 3818 scale(0x0); 3819 disp($off); 3820 %} 3821 %} 3822 3823 // Indirect Memory Plus Long Offset Operand 3824 operand indOffset32(any_RegP reg, immL32 off) 3825 %{ 3826 constraint(ALLOC_IN_RC(ptr_reg)); 3827 match(AddP reg off); 3828 3829 format %{ "[$reg + $off (32-bit)]" %} 3830 interface(MEMORY_INTER) %{ 3831 base($reg); 3832 index(0x4); 3833 scale(0x0); 3834 disp($off); 3835 %} 3836 %} 3837 3838 // Indirect Memory Plus Index Register Plus Offset Operand 3839 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3840 %{ 3841 constraint(ALLOC_IN_RC(ptr_reg)); 3842 match(AddP (AddP reg lreg) off); 3843 3844 op_cost(10); 3845 format %{"[$reg + $off + $lreg]" %} 3846 interface(MEMORY_INTER) %{ 3847 base($reg); 3848 index($lreg); 3849 scale(0x0); 3850 disp($off); 3851 %} 3852 %} 3853 3854 // Indirect Memory Plus Index Register Plus Offset Operand 3855 operand indIndex(any_RegP reg, rRegL lreg) 3856 %{ 3857 constraint(ALLOC_IN_RC(ptr_reg)); 3858 match(AddP reg lreg); 3859 3860 op_cost(10); 3861 format %{"[$reg + $lreg]" %} 3862 interface(MEMORY_INTER) %{ 3863 base($reg); 3864 index($lreg); 3865 scale(0x0); 3866 disp(0x0); 3867 %} 3868 %} 3869 3870 // Indirect Memory Times Scale Plus Index Register 3871 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3872 %{ 3873 constraint(ALLOC_IN_RC(ptr_reg)); 3874 match(AddP reg (LShiftL lreg scale)); 3875 3876 op_cost(10); 3877 format %{"[$reg + $lreg << $scale]" %} 3878 interface(MEMORY_INTER) %{ 3879 base($reg); 3880 index($lreg); 3881 scale($scale); 3882 disp(0x0); 3883 %} 3884 %} 3885 3886 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3887 %{ 3888 constraint(ALLOC_IN_RC(ptr_reg)); 3889 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3890 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3891 3892 op_cost(10); 3893 format %{"[$reg + pos $idx << $scale]" %} 3894 interface(MEMORY_INTER) %{ 3895 base($reg); 3896 index($idx); 3897 scale($scale); 3898 disp(0x0); 3899 %} 3900 %} 3901 3902 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3903 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3904 %{ 3905 constraint(ALLOC_IN_RC(ptr_reg)); 3906 match(AddP (AddP reg (LShiftL lreg scale)) off); 3907 3908 op_cost(10); 3909 format %{"[$reg + $off + $lreg << $scale]" %} 3910 interface(MEMORY_INTER) %{ 3911 base($reg); 3912 index($lreg); 3913 scale($scale); 3914 disp($off); 3915 %} 3916 %} 3917 3918 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3919 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3920 %{ 3921 constraint(ALLOC_IN_RC(ptr_reg)); 3922 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3923 match(AddP (AddP reg (ConvI2L idx)) off); 3924 3925 op_cost(10); 3926 format %{"[$reg + $off + $idx]" %} 3927 interface(MEMORY_INTER) %{ 3928 base($reg); 3929 index($idx); 3930 scale(0x0); 3931 disp($off); 3932 %} 3933 %} 3934 3935 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3936 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3937 %{ 3938 constraint(ALLOC_IN_RC(ptr_reg)); 3939 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3940 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3941 3942 op_cost(10); 3943 format %{"[$reg + $off + $idx << $scale]" %} 3944 interface(MEMORY_INTER) %{ 3945 base($reg); 3946 index($idx); 3947 scale($scale); 3948 disp($off); 3949 %} 3950 %} 3951 3952 // Indirect Narrow Oop Plus Offset Operand 3953 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3954 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3955 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3956 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3957 constraint(ALLOC_IN_RC(ptr_reg)); 3958 match(AddP (DecodeN reg) off); 3959 3960 op_cost(10); 3961 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3962 interface(MEMORY_INTER) %{ 3963 base(0xc); // R12 3964 index($reg); 3965 scale(0x3); 3966 disp($off); 3967 %} 3968 %} 3969 3970 // Indirect Memory Operand 3971 operand indirectNarrow(rRegN reg) 3972 %{ 3973 predicate(Universe::narrow_oop_shift() == 0); 3974 constraint(ALLOC_IN_RC(ptr_reg)); 3975 match(DecodeN reg); 3976 3977 format %{ "[$reg]" %} 3978 interface(MEMORY_INTER) %{ 3979 base($reg); 3980 index(0x4); 3981 scale(0x0); 3982 disp(0x0); 3983 %} 3984 %} 3985 3986 // Indirect Memory Plus Short Offset Operand 3987 operand indOffset8Narrow(rRegN reg, immL8 off) 3988 %{ 3989 predicate(Universe::narrow_oop_shift() == 0); 3990 constraint(ALLOC_IN_RC(ptr_reg)); 3991 match(AddP (DecodeN reg) off); 3992 3993 format %{ "[$reg + $off (8-bit)]" %} 3994 interface(MEMORY_INTER) %{ 3995 base($reg); 3996 index(0x4); 3997 scale(0x0); 3998 disp($off); 3999 %} 4000 %} 4001 4002 // Indirect Memory Plus Long Offset Operand 4003 operand indOffset32Narrow(rRegN reg, immL32 off) 4004 %{ 4005 predicate(Universe::narrow_oop_shift() == 0); 4006 constraint(ALLOC_IN_RC(ptr_reg)); 4007 match(AddP (DecodeN reg) off); 4008 4009 format %{ "[$reg + $off (32-bit)]" %} 4010 interface(MEMORY_INTER) %{ 4011 base($reg); 4012 index(0x4); 4013 scale(0x0); 4014 disp($off); 4015 %} 4016 %} 4017 4018 // Indirect Memory Plus Index Register Plus Offset Operand 4019 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 4020 %{ 4021 predicate(Universe::narrow_oop_shift() == 0); 4022 constraint(ALLOC_IN_RC(ptr_reg)); 4023 match(AddP (AddP (DecodeN reg) lreg) off); 4024 4025 op_cost(10); 4026 format %{"[$reg + $off + $lreg]" %} 4027 interface(MEMORY_INTER) %{ 4028 base($reg); 4029 index($lreg); 4030 scale(0x0); 4031 disp($off); 4032 %} 4033 %} 4034 4035 // Indirect Memory Plus Index Register Plus Offset Operand 4036 operand indIndexNarrow(rRegN reg, rRegL lreg) 4037 %{ 4038 predicate(Universe::narrow_oop_shift() == 0); 4039 constraint(ALLOC_IN_RC(ptr_reg)); 4040 match(AddP (DecodeN reg) lreg); 4041 4042 op_cost(10); 4043 format %{"[$reg + $lreg]" %} 4044 interface(MEMORY_INTER) %{ 4045 base($reg); 4046 index($lreg); 4047 scale(0x0); 4048 disp(0x0); 4049 %} 4050 %} 4051 4052 // Indirect Memory Times Scale Plus Index Register 4053 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4054 %{ 4055 predicate(Universe::narrow_oop_shift() == 0); 4056 constraint(ALLOC_IN_RC(ptr_reg)); 4057 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4058 4059 op_cost(10); 4060 format %{"[$reg + $lreg << $scale]" %} 4061 interface(MEMORY_INTER) %{ 4062 base($reg); 4063 index($lreg); 4064 scale($scale); 4065 disp(0x0); 4066 %} 4067 %} 4068 4069 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4070 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4071 %{ 4072 predicate(Universe::narrow_oop_shift() == 0); 4073 constraint(ALLOC_IN_RC(ptr_reg)); 4074 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4075 4076 op_cost(10); 4077 format %{"[$reg + $off + $lreg << $scale]" %} 4078 interface(MEMORY_INTER) %{ 4079 base($reg); 4080 index($lreg); 4081 scale($scale); 4082 disp($off); 4083 %} 4084 %} 4085 4086 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4087 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4088 %{ 4089 constraint(ALLOC_IN_RC(ptr_reg)); 4090 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4091 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4092 4093 op_cost(10); 4094 format %{"[$reg + $off + $idx]" %} 4095 interface(MEMORY_INTER) %{ 4096 base($reg); 4097 index($idx); 4098 scale(0x0); 4099 disp($off); 4100 %} 4101 %} 4102 4103 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4104 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4105 %{ 4106 constraint(ALLOC_IN_RC(ptr_reg)); 4107 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4108 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4109 4110 op_cost(10); 4111 format %{"[$reg + $off + $idx << $scale]" %} 4112 interface(MEMORY_INTER) %{ 4113 base($reg); 4114 index($idx); 4115 scale($scale); 4116 disp($off); 4117 %} 4118 %} 4119 4120 //----------Special Memory Operands-------------------------------------------- 4121 // Stack Slot Operand - This operand is used for loading and storing temporary 4122 // values on the stack where a match requires a value to 4123 // flow through memory. 4124 operand stackSlotP(sRegP reg) 4125 %{ 4126 constraint(ALLOC_IN_RC(stack_slots)); 4127 // No match rule because this operand is only generated in matching 4128 4129 format %{ "[$reg]" %} 4130 interface(MEMORY_INTER) %{ 4131 base(0x4); // RSP 4132 index(0x4); // No Index 4133 scale(0x0); // No Scale 4134 disp($reg); // Stack Offset 4135 %} 4136 %} 4137 4138 operand stackSlotI(sRegI reg) 4139 %{ 4140 constraint(ALLOC_IN_RC(stack_slots)); 4141 // No match rule because this operand is only generated in matching 4142 4143 format %{ "[$reg]" %} 4144 interface(MEMORY_INTER) %{ 4145 base(0x4); // RSP 4146 index(0x4); // No Index 4147 scale(0x0); // No Scale 4148 disp($reg); // Stack Offset 4149 %} 4150 %} 4151 4152 operand stackSlotF(sRegF reg) 4153 %{ 4154 constraint(ALLOC_IN_RC(stack_slots)); 4155 // No match rule because this operand is only generated in matching 4156 4157 format %{ "[$reg]" %} 4158 interface(MEMORY_INTER) %{ 4159 base(0x4); // RSP 4160 index(0x4); // No Index 4161 scale(0x0); // No Scale 4162 disp($reg); // Stack Offset 4163 %} 4164 %} 4165 4166 operand stackSlotD(sRegD reg) 4167 %{ 4168 constraint(ALLOC_IN_RC(stack_slots)); 4169 // No match rule because this operand is only generated in matching 4170 4171 format %{ "[$reg]" %} 4172 interface(MEMORY_INTER) %{ 4173 base(0x4); // RSP 4174 index(0x4); // No Index 4175 scale(0x0); // No Scale 4176 disp($reg); // Stack Offset 4177 %} 4178 %} 4179 operand stackSlotL(sRegL reg) 4180 %{ 4181 constraint(ALLOC_IN_RC(stack_slots)); 4182 // No match rule because this operand is only generated in matching 4183 4184 format %{ "[$reg]" %} 4185 interface(MEMORY_INTER) %{ 4186 base(0x4); // RSP 4187 index(0x4); // No Index 4188 scale(0x0); // No Scale 4189 disp($reg); // Stack Offset 4190 %} 4191 %} 4192 4193 //----------Conditional Branch Operands---------------------------------------- 4194 // Comparison Op - This is the operation of the comparison, and is limited to 4195 // the following set of codes: 4196 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4197 // 4198 // Other attributes of the comparison, such as unsignedness, are specified 4199 // by the comparison instruction that sets a condition code flags register. 4200 // That result is represented by a flags operand whose subtype is appropriate 4201 // to the unsignedness (etc.) of the comparison. 4202 // 4203 // Later, the instruction which matches both the Comparison Op (a Bool) and 4204 // the flags (produced by the Cmp) specifies the coding of the comparison op 4205 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4206 4207 // Comparision Code 4208 operand cmpOp() 4209 %{ 4210 match(Bool); 4211 4212 format %{ "" %} 4213 interface(COND_INTER) %{ 4214 equal(0x4, "e"); 4215 not_equal(0x5, "ne"); 4216 less(0xC, "l"); 4217 greater_equal(0xD, "ge"); 4218 less_equal(0xE, "le"); 4219 greater(0xF, "g"); 4220 overflow(0x0, "o"); 4221 no_overflow(0x1, "no"); 4222 %} 4223 %} 4224 4225 // Comparison Code, unsigned compare. Used by FP also, with 4226 // C2 (unordered) turned into GT or LT already. The other bits 4227 // C0 and C3 are turned into Carry & Zero flags. 4228 operand cmpOpU() 4229 %{ 4230 match(Bool); 4231 4232 format %{ "" %} 4233 interface(COND_INTER) %{ 4234 equal(0x4, "e"); 4235 not_equal(0x5, "ne"); 4236 less(0x2, "b"); 4237 greater_equal(0x3, "nb"); 4238 less_equal(0x6, "be"); 4239 greater(0x7, "nbe"); 4240 overflow(0x0, "o"); 4241 no_overflow(0x1, "no"); 4242 %} 4243 %} 4244 4245 4246 // Floating comparisons that don't require any fixup for the unordered case 4247 operand cmpOpUCF() %{ 4248 match(Bool); 4249 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4250 n->as_Bool()->_test._test == BoolTest::ge || 4251 n->as_Bool()->_test._test == BoolTest::le || 4252 n->as_Bool()->_test._test == BoolTest::gt); 4253 format %{ "" %} 4254 interface(COND_INTER) %{ 4255 equal(0x4, "e"); 4256 not_equal(0x5, "ne"); 4257 less(0x2, "b"); 4258 greater_equal(0x3, "nb"); 4259 less_equal(0x6, "be"); 4260 greater(0x7, "nbe"); 4261 overflow(0x0, "o"); 4262 no_overflow(0x1, "no"); 4263 %} 4264 %} 4265 4266 4267 // Floating comparisons that can be fixed up with extra conditional jumps 4268 operand cmpOpUCF2() %{ 4269 match(Bool); 4270 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4271 n->as_Bool()->_test._test == BoolTest::eq); 4272 format %{ "" %} 4273 interface(COND_INTER) %{ 4274 equal(0x4, "e"); 4275 not_equal(0x5, "ne"); 4276 less(0x2, "b"); 4277 greater_equal(0x3, "nb"); 4278 less_equal(0x6, "be"); 4279 greater(0x7, "nbe"); 4280 overflow(0x0, "o"); 4281 no_overflow(0x1, "no"); 4282 %} 4283 %} 4284 4285 // Operands for bound floating pointer register arguments 4286 operand rxmm0() %{ 4287 constraint(ALLOC_IN_RC(xmm0_reg)); 4288 match(VecX); 4289 format%{%} 4290 interface(REG_INTER); 4291 %} 4292 operand rxmm1() %{ 4293 constraint(ALLOC_IN_RC(xmm1_reg)); 4294 match(VecX); 4295 format%{%} 4296 interface(REG_INTER); 4297 %} 4298 operand rxmm2() %{ 4299 constraint(ALLOC_IN_RC(xmm2_reg)); 4300 match(VecX); 4301 format%{%} 4302 interface(REG_INTER); 4303 %} 4304 operand rxmm3() %{ 4305 constraint(ALLOC_IN_RC(xmm3_reg)); 4306 match(VecX); 4307 format%{%} 4308 interface(REG_INTER); 4309 %} 4310 operand rxmm4() %{ 4311 constraint(ALLOC_IN_RC(xmm4_reg)); 4312 match(VecX); 4313 format%{%} 4314 interface(REG_INTER); 4315 %} 4316 operand rxmm5() %{ 4317 constraint(ALLOC_IN_RC(xmm5_reg)); 4318 match(VecX); 4319 format%{%} 4320 interface(REG_INTER); 4321 %} 4322 operand rxmm6() %{ 4323 constraint(ALLOC_IN_RC(xmm6_reg)); 4324 match(VecX); 4325 format%{%} 4326 interface(REG_INTER); 4327 %} 4328 operand rxmm7() %{ 4329 constraint(ALLOC_IN_RC(xmm7_reg)); 4330 match(VecX); 4331 format%{%} 4332 interface(REG_INTER); 4333 %} 4334 operand rxmm8() %{ 4335 constraint(ALLOC_IN_RC(xmm8_reg)); 4336 match(VecX); 4337 format%{%} 4338 interface(REG_INTER); 4339 %} 4340 operand rxmm9() %{ 4341 constraint(ALLOC_IN_RC(xmm9_reg)); 4342 match(VecX); 4343 format%{%} 4344 interface(REG_INTER); 4345 %} 4346 operand rxmm10() %{ 4347 constraint(ALLOC_IN_RC(xmm10_reg)); 4348 match(VecX); 4349 format%{%} 4350 interface(REG_INTER); 4351 %} 4352 operand rxmm11() %{ 4353 constraint(ALLOC_IN_RC(xmm11_reg)); 4354 match(VecX); 4355 format%{%} 4356 interface(REG_INTER); 4357 %} 4358 operand rxmm12() %{ 4359 constraint(ALLOC_IN_RC(xmm12_reg)); 4360 match(VecX); 4361 format%{%} 4362 interface(REG_INTER); 4363 %} 4364 operand rxmm13() %{ 4365 constraint(ALLOC_IN_RC(xmm13_reg)); 4366 match(VecX); 4367 format%{%} 4368 interface(REG_INTER); 4369 %} 4370 operand rxmm14() %{ 4371 constraint(ALLOC_IN_RC(xmm14_reg)); 4372 match(VecX); 4373 format%{%} 4374 interface(REG_INTER); 4375 %} 4376 operand rxmm15() %{ 4377 constraint(ALLOC_IN_RC(xmm15_reg)); 4378 match(VecX); 4379 format%{%} 4380 interface(REG_INTER); 4381 %} 4382 operand rxmm16() %{ 4383 constraint(ALLOC_IN_RC(xmm16_reg)); 4384 match(VecX); 4385 format%{%} 4386 interface(REG_INTER); 4387 %} 4388 operand rxmm17() %{ 4389 constraint(ALLOC_IN_RC(xmm17_reg)); 4390 match(VecX); 4391 format%{%} 4392 interface(REG_INTER); 4393 %} 4394 operand rxmm18() %{ 4395 constraint(ALLOC_IN_RC(xmm18_reg)); 4396 match(VecX); 4397 format%{%} 4398 interface(REG_INTER); 4399 %} 4400 operand rxmm19() %{ 4401 constraint(ALLOC_IN_RC(xmm19_reg)); 4402 match(VecX); 4403 format%{%} 4404 interface(REG_INTER); 4405 %} 4406 operand rxmm20() %{ 4407 constraint(ALLOC_IN_RC(xmm20_reg)); 4408 match(VecX); 4409 format%{%} 4410 interface(REG_INTER); 4411 %} 4412 operand rxmm21() %{ 4413 constraint(ALLOC_IN_RC(xmm21_reg)); 4414 match(VecX); 4415 format%{%} 4416 interface(REG_INTER); 4417 %} 4418 operand rxmm22() %{ 4419 constraint(ALLOC_IN_RC(xmm22_reg)); 4420 match(VecX); 4421 format%{%} 4422 interface(REG_INTER); 4423 %} 4424 operand rxmm23() %{ 4425 constraint(ALLOC_IN_RC(xmm23_reg)); 4426 match(VecX); 4427 format%{%} 4428 interface(REG_INTER); 4429 %} 4430 operand rxmm24() %{ 4431 constraint(ALLOC_IN_RC(xmm24_reg)); 4432 match(VecX); 4433 format%{%} 4434 interface(REG_INTER); 4435 %} 4436 operand rxmm25() %{ 4437 constraint(ALLOC_IN_RC(xmm25_reg)); 4438 match(VecX); 4439 format%{%} 4440 interface(REG_INTER); 4441 %} 4442 operand rxmm26() %{ 4443 constraint(ALLOC_IN_RC(xmm26_reg)); 4444 match(VecX); 4445 format%{%} 4446 interface(REG_INTER); 4447 %} 4448 operand rxmm27() %{ 4449 constraint(ALLOC_IN_RC(xmm27_reg)); 4450 match(VecX); 4451 format%{%} 4452 interface(REG_INTER); 4453 %} 4454 operand rxmm28() %{ 4455 constraint(ALLOC_IN_RC(xmm28_reg)); 4456 match(VecX); 4457 format%{%} 4458 interface(REG_INTER); 4459 %} 4460 operand rxmm29() %{ 4461 constraint(ALLOC_IN_RC(xmm29_reg)); 4462 match(VecX); 4463 format%{%} 4464 interface(REG_INTER); 4465 %} 4466 operand rxmm30() %{ 4467 constraint(ALLOC_IN_RC(xmm30_reg)); 4468 match(VecX); 4469 format%{%} 4470 interface(REG_INTER); 4471 %} 4472 operand rxmm31() %{ 4473 constraint(ALLOC_IN_RC(xmm31_reg)); 4474 match(VecX); 4475 format%{%} 4476 interface(REG_INTER); 4477 %} 4478 4479 //----------OPERAND CLASSES---------------------------------------------------- 4480 // Operand Classes are groups of operands that are used as to simplify 4481 // instruction definitions by not requiring the AD writer to specify separate 4482 // instructions for every form of operand when the instruction accepts 4483 // multiple operand types with the same basic encoding and format. The classic 4484 // case of this is memory operands. 4485 4486 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4487 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4488 indCompressedOopOffset, 4489 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4490 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4491 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4492 4493 //----------PIPELINE----------------------------------------------------------- 4494 // Rules which define the behavior of the target architectures pipeline. 4495 pipeline %{ 4496 4497 //----------ATTRIBUTES--------------------------------------------------------- 4498 attributes %{ 4499 variable_size_instructions; // Fixed size instructions 4500 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4501 instruction_unit_size = 1; // An instruction is 1 bytes long 4502 instruction_fetch_unit_size = 16; // The processor fetches one line 4503 instruction_fetch_units = 1; // of 16 bytes 4504 4505 // List of nop instructions 4506 nops( MachNop ); 4507 %} 4508 4509 //----------RESOURCES---------------------------------------------------------- 4510 // Resources are the functional units available to the machine 4511 4512 // Generic P2/P3 pipeline 4513 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4514 // 3 instructions decoded per cycle. 4515 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4516 // 3 ALU op, only ALU0 handles mul instructions. 4517 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4518 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4519 BR, FPU, 4520 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4521 4522 //----------PIPELINE DESCRIPTION----------------------------------------------- 4523 // Pipeline Description specifies the stages in the machine's pipeline 4524 4525 // Generic P2/P3 pipeline 4526 pipe_desc(S0, S1, S2, S3, S4, S5); 4527 4528 //----------PIPELINE CLASSES--------------------------------------------------- 4529 // Pipeline Classes describe the stages in which input and output are 4530 // referenced by the hardware pipeline. 4531 4532 // Naming convention: ialu or fpu 4533 // Then: _reg 4534 // Then: _reg if there is a 2nd register 4535 // Then: _long if it's a pair of instructions implementing a long 4536 // Then: _fat if it requires the big decoder 4537 // Or: _mem if it requires the big decoder and a memory unit. 4538 4539 // Integer ALU reg operation 4540 pipe_class ialu_reg(rRegI dst) 4541 %{ 4542 single_instruction; 4543 dst : S4(write); 4544 dst : S3(read); 4545 DECODE : S0; // any decoder 4546 ALU : S3; // any alu 4547 %} 4548 4549 // Long ALU reg operation 4550 pipe_class ialu_reg_long(rRegL dst) 4551 %{ 4552 instruction_count(2); 4553 dst : S4(write); 4554 dst : S3(read); 4555 DECODE : S0(2); // any 2 decoders 4556 ALU : S3(2); // both alus 4557 %} 4558 4559 // Integer ALU reg operation using big decoder 4560 pipe_class ialu_reg_fat(rRegI dst) 4561 %{ 4562 single_instruction; 4563 dst : S4(write); 4564 dst : S3(read); 4565 D0 : S0; // big decoder only 4566 ALU : S3; // any alu 4567 %} 4568 4569 // Long ALU reg operation using big decoder 4570 pipe_class ialu_reg_long_fat(rRegL dst) 4571 %{ 4572 instruction_count(2); 4573 dst : S4(write); 4574 dst : S3(read); 4575 D0 : S0(2); // big decoder only; twice 4576 ALU : S3(2); // any 2 alus 4577 %} 4578 4579 // Integer ALU reg-reg operation 4580 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4581 %{ 4582 single_instruction; 4583 dst : S4(write); 4584 src : S3(read); 4585 DECODE : S0; // any decoder 4586 ALU : S3; // any alu 4587 %} 4588 4589 // Long ALU reg-reg operation 4590 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4591 %{ 4592 instruction_count(2); 4593 dst : S4(write); 4594 src : S3(read); 4595 DECODE : S0(2); // any 2 decoders 4596 ALU : S3(2); // both alus 4597 %} 4598 4599 // Integer ALU reg-reg operation 4600 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4601 %{ 4602 single_instruction; 4603 dst : S4(write); 4604 src : S3(read); 4605 D0 : S0; // big decoder only 4606 ALU : S3; // any alu 4607 %} 4608 4609 // Long ALU reg-reg operation 4610 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4611 %{ 4612 instruction_count(2); 4613 dst : S4(write); 4614 src : S3(read); 4615 D0 : S0(2); // big decoder only; twice 4616 ALU : S3(2); // both alus 4617 %} 4618 4619 // Integer ALU reg-mem operation 4620 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4621 %{ 4622 single_instruction; 4623 dst : S5(write); 4624 mem : S3(read); 4625 D0 : S0; // big decoder only 4626 ALU : S4; // any alu 4627 MEM : S3; // any mem 4628 %} 4629 4630 // Integer mem operation (prefetch) 4631 pipe_class ialu_mem(memory mem) 4632 %{ 4633 single_instruction; 4634 mem : S3(read); 4635 D0 : S0; // big decoder only 4636 MEM : S3; // any mem 4637 %} 4638 4639 // Integer Store to Memory 4640 pipe_class ialu_mem_reg(memory mem, rRegI src) 4641 %{ 4642 single_instruction; 4643 mem : S3(read); 4644 src : S5(read); 4645 D0 : S0; // big decoder only 4646 ALU : S4; // any alu 4647 MEM : S3; 4648 %} 4649 4650 // // Long Store to Memory 4651 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4652 // %{ 4653 // instruction_count(2); 4654 // mem : S3(read); 4655 // src : S5(read); 4656 // D0 : S0(2); // big decoder only; twice 4657 // ALU : S4(2); // any 2 alus 4658 // MEM : S3(2); // Both mems 4659 // %} 4660 4661 // Integer Store to Memory 4662 pipe_class ialu_mem_imm(memory mem) 4663 %{ 4664 single_instruction; 4665 mem : S3(read); 4666 D0 : S0; // big decoder only 4667 ALU : S4; // any alu 4668 MEM : S3; 4669 %} 4670 4671 // Integer ALU0 reg-reg operation 4672 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4673 %{ 4674 single_instruction; 4675 dst : S4(write); 4676 src : S3(read); 4677 D0 : S0; // Big decoder only 4678 ALU0 : S3; // only alu0 4679 %} 4680 4681 // Integer ALU0 reg-mem operation 4682 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4683 %{ 4684 single_instruction; 4685 dst : S5(write); 4686 mem : S3(read); 4687 D0 : S0; // big decoder only 4688 ALU0 : S4; // ALU0 only 4689 MEM : S3; // any mem 4690 %} 4691 4692 // Integer ALU reg-reg operation 4693 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4694 %{ 4695 single_instruction; 4696 cr : S4(write); 4697 src1 : S3(read); 4698 src2 : S3(read); 4699 DECODE : S0; // any decoder 4700 ALU : S3; // any alu 4701 %} 4702 4703 // Integer ALU reg-imm operation 4704 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4705 %{ 4706 single_instruction; 4707 cr : S4(write); 4708 src1 : S3(read); 4709 DECODE : S0; // any decoder 4710 ALU : S3; // any alu 4711 %} 4712 4713 // Integer ALU reg-mem operation 4714 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4715 %{ 4716 single_instruction; 4717 cr : S4(write); 4718 src1 : S3(read); 4719 src2 : S3(read); 4720 D0 : S0; // big decoder only 4721 ALU : S4; // any alu 4722 MEM : S3; 4723 %} 4724 4725 // Conditional move reg-reg 4726 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4727 %{ 4728 instruction_count(4); 4729 y : S4(read); 4730 q : S3(read); 4731 p : S3(read); 4732 DECODE : S0(4); // any decoder 4733 %} 4734 4735 // Conditional move reg-reg 4736 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4737 %{ 4738 single_instruction; 4739 dst : S4(write); 4740 src : S3(read); 4741 cr : S3(read); 4742 DECODE : S0; // any decoder 4743 %} 4744 4745 // Conditional move reg-mem 4746 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4747 %{ 4748 single_instruction; 4749 dst : S4(write); 4750 src : S3(read); 4751 cr : S3(read); 4752 DECODE : S0; // any decoder 4753 MEM : S3; 4754 %} 4755 4756 // Conditional move reg-reg long 4757 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4758 %{ 4759 single_instruction; 4760 dst : S4(write); 4761 src : S3(read); 4762 cr : S3(read); 4763 DECODE : S0(2); // any 2 decoders 4764 %} 4765 4766 // XXX 4767 // // Conditional move double reg-reg 4768 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4769 // %{ 4770 // single_instruction; 4771 // dst : S4(write); 4772 // src : S3(read); 4773 // cr : S3(read); 4774 // DECODE : S0; // any decoder 4775 // %} 4776 4777 // Float reg-reg operation 4778 pipe_class fpu_reg(regD dst) 4779 %{ 4780 instruction_count(2); 4781 dst : S3(read); 4782 DECODE : S0(2); // any 2 decoders 4783 FPU : S3; 4784 %} 4785 4786 // Float reg-reg operation 4787 pipe_class fpu_reg_reg(regD dst, regD src) 4788 %{ 4789 instruction_count(2); 4790 dst : S4(write); 4791 src : S3(read); 4792 DECODE : S0(2); // any 2 decoders 4793 FPU : S3; 4794 %} 4795 4796 // Float reg-reg operation 4797 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4798 %{ 4799 instruction_count(3); 4800 dst : S4(write); 4801 src1 : S3(read); 4802 src2 : S3(read); 4803 DECODE : S0(3); // any 3 decoders 4804 FPU : S3(2); 4805 %} 4806 4807 // Float reg-reg operation 4808 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4809 %{ 4810 instruction_count(4); 4811 dst : S4(write); 4812 src1 : S3(read); 4813 src2 : S3(read); 4814 src3 : S3(read); 4815 DECODE : S0(4); // any 3 decoders 4816 FPU : S3(2); 4817 %} 4818 4819 // Float reg-reg operation 4820 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4821 %{ 4822 instruction_count(4); 4823 dst : S4(write); 4824 src1 : S3(read); 4825 src2 : S3(read); 4826 src3 : S3(read); 4827 DECODE : S1(3); // any 3 decoders 4828 D0 : S0; // Big decoder only 4829 FPU : S3(2); 4830 MEM : S3; 4831 %} 4832 4833 // Float reg-mem operation 4834 pipe_class fpu_reg_mem(regD dst, memory mem) 4835 %{ 4836 instruction_count(2); 4837 dst : S5(write); 4838 mem : S3(read); 4839 D0 : S0; // big decoder only 4840 DECODE : S1; // any decoder for FPU POP 4841 FPU : S4; 4842 MEM : S3; // any mem 4843 %} 4844 4845 // Float reg-mem operation 4846 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4847 %{ 4848 instruction_count(3); 4849 dst : S5(write); 4850 src1 : S3(read); 4851 mem : S3(read); 4852 D0 : S0; // big decoder only 4853 DECODE : S1(2); // any decoder for FPU POP 4854 FPU : S4; 4855 MEM : S3; // any mem 4856 %} 4857 4858 // Float mem-reg operation 4859 pipe_class fpu_mem_reg(memory mem, regD src) 4860 %{ 4861 instruction_count(2); 4862 src : S5(read); 4863 mem : S3(read); 4864 DECODE : S0; // any decoder for FPU PUSH 4865 D0 : S1; // big decoder only 4866 FPU : S4; 4867 MEM : S3; // any mem 4868 %} 4869 4870 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4871 %{ 4872 instruction_count(3); 4873 src1 : S3(read); 4874 src2 : S3(read); 4875 mem : S3(read); 4876 DECODE : S0(2); // any decoder for FPU PUSH 4877 D0 : S1; // big decoder only 4878 FPU : S4; 4879 MEM : S3; // any mem 4880 %} 4881 4882 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4883 %{ 4884 instruction_count(3); 4885 src1 : S3(read); 4886 src2 : S3(read); 4887 mem : S4(read); 4888 DECODE : S0; // any decoder for FPU PUSH 4889 D0 : S0(2); // big decoder only 4890 FPU : S4; 4891 MEM : S3(2); // any mem 4892 %} 4893 4894 pipe_class fpu_mem_mem(memory dst, memory src1) 4895 %{ 4896 instruction_count(2); 4897 src1 : S3(read); 4898 dst : S4(read); 4899 D0 : S0(2); // big decoder only 4900 MEM : S3(2); // any mem 4901 %} 4902 4903 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4904 %{ 4905 instruction_count(3); 4906 src1 : S3(read); 4907 src2 : S3(read); 4908 dst : S4(read); 4909 D0 : S0(3); // big decoder only 4910 FPU : S4; 4911 MEM : S3(3); // any mem 4912 %} 4913 4914 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4915 %{ 4916 instruction_count(3); 4917 src1 : S4(read); 4918 mem : S4(read); 4919 DECODE : S0; // any decoder for FPU PUSH 4920 D0 : S0(2); // big decoder only 4921 FPU : S4; 4922 MEM : S3(2); // any mem 4923 %} 4924 4925 // Float load constant 4926 pipe_class fpu_reg_con(regD dst) 4927 %{ 4928 instruction_count(2); 4929 dst : S5(write); 4930 D0 : S0; // big decoder only for the load 4931 DECODE : S1; // any decoder for FPU POP 4932 FPU : S4; 4933 MEM : S3; // any mem 4934 %} 4935 4936 // Float load constant 4937 pipe_class fpu_reg_reg_con(regD dst, regD src) 4938 %{ 4939 instruction_count(3); 4940 dst : S5(write); 4941 src : S3(read); 4942 D0 : S0; // big decoder only for the load 4943 DECODE : S1(2); // any decoder for FPU POP 4944 FPU : S4; 4945 MEM : S3; // any mem 4946 %} 4947 4948 // UnConditional branch 4949 pipe_class pipe_jmp(label labl) 4950 %{ 4951 single_instruction; 4952 BR : S3; 4953 %} 4954 4955 // Conditional branch 4956 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4957 %{ 4958 single_instruction; 4959 cr : S1(read); 4960 BR : S3; 4961 %} 4962 4963 // Allocation idiom 4964 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4965 %{ 4966 instruction_count(1); force_serialization; 4967 fixed_latency(6); 4968 heap_ptr : S3(read); 4969 DECODE : S0(3); 4970 D0 : S2; 4971 MEM : S3; 4972 ALU : S3(2); 4973 dst : S5(write); 4974 BR : S5; 4975 %} 4976 4977 // Generic big/slow expanded idiom 4978 pipe_class pipe_slow() 4979 %{ 4980 instruction_count(10); multiple_bundles; force_serialization; 4981 fixed_latency(100); 4982 D0 : S0(2); 4983 MEM : S3(2); 4984 %} 4985 4986 // The real do-nothing guy 4987 pipe_class empty() 4988 %{ 4989 instruction_count(0); 4990 %} 4991 4992 // Define the class for the Nop node 4993 define 4994 %{ 4995 MachNop = empty; 4996 %} 4997 4998 %} 4999 5000 //----------INSTRUCTIONS------------------------------------------------------- 5001 // 5002 // match -- States which machine-independent subtree may be replaced 5003 // by this instruction. 5004 // ins_cost -- The estimated cost of this instruction is used by instruction 5005 // selection to identify a minimum cost tree of machine 5006 // instructions that matches a tree of machine-independent 5007 // instructions. 5008 // format -- A string providing the disassembly for this instruction. 5009 // The value of an instruction's operand may be inserted 5010 // by referring to it with a '$' prefix. 5011 // opcode -- Three instruction opcodes may be provided. These are referred 5012 // to within an encode class as $primary, $secondary, and $tertiary 5013 // rrspectively. The primary opcode is commonly used to 5014 // indicate the type of machine instruction, while secondary 5015 // and tertiary are often used for prefix options or addressing 5016 // modes. 5017 // ins_encode -- A list of encode classes with parameters. The encode class 5018 // name must have been defined in an 'enc_class' specification 5019 // in the encode section of the architecture description. 5020 5021 5022 //----------Load/Store/Move Instructions--------------------------------------- 5023 //----------Load Instructions-------------------------------------------------- 5024 5025 // Load Byte (8 bit signed) 5026 instruct loadB(rRegI dst, memory mem) 5027 %{ 5028 match(Set dst (LoadB mem)); 5029 5030 ins_cost(125); 5031 format %{ "movsbl $dst, $mem\t# byte" %} 5032 5033 ins_encode %{ 5034 __ movsbl($dst$$Register, $mem$$Address); 5035 %} 5036 5037 ins_pipe(ialu_reg_mem); 5038 %} 5039 5040 // Load Byte (8 bit signed) into Long Register 5041 instruct loadB2L(rRegL dst, memory mem) 5042 %{ 5043 match(Set dst (ConvI2L (LoadB mem))); 5044 5045 ins_cost(125); 5046 format %{ "movsbq $dst, $mem\t# byte -> long" %} 5047 5048 ins_encode %{ 5049 __ movsbq($dst$$Register, $mem$$Address); 5050 %} 5051 5052 ins_pipe(ialu_reg_mem); 5053 %} 5054 5055 // Load Unsigned Byte (8 bit UNsigned) 5056 instruct loadUB(rRegI dst, memory mem) 5057 %{ 5058 match(Set dst (LoadUB mem)); 5059 5060 ins_cost(125); 5061 format %{ "movzbl $dst, $mem\t# ubyte" %} 5062 5063 ins_encode %{ 5064 __ movzbl($dst$$Register, $mem$$Address); 5065 %} 5066 5067 ins_pipe(ialu_reg_mem); 5068 %} 5069 5070 // Load Unsigned Byte (8 bit UNsigned) into Long Register 5071 instruct loadUB2L(rRegL dst, memory mem) 5072 %{ 5073 match(Set dst (ConvI2L (LoadUB mem))); 5074 5075 ins_cost(125); 5076 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 5077 5078 ins_encode %{ 5079 __ movzbq($dst$$Register, $mem$$Address); 5080 %} 5081 5082 ins_pipe(ialu_reg_mem); 5083 %} 5084 5085 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 5086 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5087 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5088 effect(KILL cr); 5089 5090 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 5091 "andl $dst, right_n_bits($mask, 8)" %} 5092 ins_encode %{ 5093 Register Rdst = $dst$$Register; 5094 __ movzbq(Rdst, $mem$$Address); 5095 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 5096 %} 5097 ins_pipe(ialu_reg_mem); 5098 %} 5099 5100 // Load Short (16 bit signed) 5101 instruct loadS(rRegI dst, memory mem) 5102 %{ 5103 match(Set dst (LoadS mem)); 5104 5105 ins_cost(125); 5106 format %{ "movswl $dst, $mem\t# short" %} 5107 5108 ins_encode %{ 5109 __ movswl($dst$$Register, $mem$$Address); 5110 %} 5111 5112 ins_pipe(ialu_reg_mem); 5113 %} 5114 5115 // Load Short (16 bit signed) to Byte (8 bit signed) 5116 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5117 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5118 5119 ins_cost(125); 5120 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5121 ins_encode %{ 5122 __ movsbl($dst$$Register, $mem$$Address); 5123 %} 5124 ins_pipe(ialu_reg_mem); 5125 %} 5126 5127 // Load Short (16 bit signed) into Long Register 5128 instruct loadS2L(rRegL dst, memory mem) 5129 %{ 5130 match(Set dst (ConvI2L (LoadS mem))); 5131 5132 ins_cost(125); 5133 format %{ "movswq $dst, $mem\t# short -> long" %} 5134 5135 ins_encode %{ 5136 __ movswq($dst$$Register, $mem$$Address); 5137 %} 5138 5139 ins_pipe(ialu_reg_mem); 5140 %} 5141 5142 // Load Unsigned Short/Char (16 bit UNsigned) 5143 instruct loadUS(rRegI dst, memory mem) 5144 %{ 5145 match(Set dst (LoadUS mem)); 5146 5147 ins_cost(125); 5148 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5149 5150 ins_encode %{ 5151 __ movzwl($dst$$Register, $mem$$Address); 5152 %} 5153 5154 ins_pipe(ialu_reg_mem); 5155 %} 5156 5157 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5158 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5159 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5160 5161 ins_cost(125); 5162 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5163 ins_encode %{ 5164 __ movsbl($dst$$Register, $mem$$Address); 5165 %} 5166 ins_pipe(ialu_reg_mem); 5167 %} 5168 5169 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5170 instruct loadUS2L(rRegL dst, memory mem) 5171 %{ 5172 match(Set dst (ConvI2L (LoadUS mem))); 5173 5174 ins_cost(125); 5175 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5176 5177 ins_encode %{ 5178 __ movzwq($dst$$Register, $mem$$Address); 5179 %} 5180 5181 ins_pipe(ialu_reg_mem); 5182 %} 5183 5184 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5185 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5186 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5187 5188 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5189 ins_encode %{ 5190 __ movzbq($dst$$Register, $mem$$Address); 5191 %} 5192 ins_pipe(ialu_reg_mem); 5193 %} 5194 5195 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 5196 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5197 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5198 effect(KILL cr); 5199 5200 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 5201 "andl $dst, right_n_bits($mask, 16)" %} 5202 ins_encode %{ 5203 Register Rdst = $dst$$Register; 5204 __ movzwq(Rdst, $mem$$Address); 5205 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 5206 %} 5207 ins_pipe(ialu_reg_mem); 5208 %} 5209 5210 // Load Integer 5211 instruct loadI(rRegI dst, memory mem) 5212 %{ 5213 match(Set dst (LoadI mem)); 5214 5215 ins_cost(125); 5216 format %{ "movl $dst, $mem\t# int" %} 5217 5218 ins_encode %{ 5219 __ movl($dst$$Register, $mem$$Address); 5220 %} 5221 5222 ins_pipe(ialu_reg_mem); 5223 %} 5224 5225 // Load Integer (32 bit signed) to Byte (8 bit signed) 5226 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5227 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5228 5229 ins_cost(125); 5230 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5231 ins_encode %{ 5232 __ movsbl($dst$$Register, $mem$$Address); 5233 %} 5234 ins_pipe(ialu_reg_mem); 5235 %} 5236 5237 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5238 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5239 match(Set dst (AndI (LoadI mem) mask)); 5240 5241 ins_cost(125); 5242 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5243 ins_encode %{ 5244 __ movzbl($dst$$Register, $mem$$Address); 5245 %} 5246 ins_pipe(ialu_reg_mem); 5247 %} 5248 5249 // Load Integer (32 bit signed) to Short (16 bit signed) 5250 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5251 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5252 5253 ins_cost(125); 5254 format %{ "movswl $dst, $mem\t# int -> short" %} 5255 ins_encode %{ 5256 __ movswl($dst$$Register, $mem$$Address); 5257 %} 5258 ins_pipe(ialu_reg_mem); 5259 %} 5260 5261 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5262 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5263 match(Set dst (AndI (LoadI mem) mask)); 5264 5265 ins_cost(125); 5266 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5267 ins_encode %{ 5268 __ movzwl($dst$$Register, $mem$$Address); 5269 %} 5270 ins_pipe(ialu_reg_mem); 5271 %} 5272 5273 // Load Integer into Long Register 5274 instruct loadI2L(rRegL dst, memory mem) 5275 %{ 5276 match(Set dst (ConvI2L (LoadI mem))); 5277 5278 ins_cost(125); 5279 format %{ "movslq $dst, $mem\t# int -> long" %} 5280 5281 ins_encode %{ 5282 __ movslq($dst$$Register, $mem$$Address); 5283 %} 5284 5285 ins_pipe(ialu_reg_mem); 5286 %} 5287 5288 // Load Integer with mask 0xFF into Long Register 5289 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5290 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5291 5292 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5293 ins_encode %{ 5294 __ movzbq($dst$$Register, $mem$$Address); 5295 %} 5296 ins_pipe(ialu_reg_mem); 5297 %} 5298 5299 // Load Integer with mask 0xFFFF into Long Register 5300 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5301 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5302 5303 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5304 ins_encode %{ 5305 __ movzwq($dst$$Register, $mem$$Address); 5306 %} 5307 ins_pipe(ialu_reg_mem); 5308 %} 5309 5310 // Load Integer with a 31-bit mask into Long Register 5311 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5312 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5313 effect(KILL cr); 5314 5315 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5316 "andl $dst, $mask" %} 5317 ins_encode %{ 5318 Register Rdst = $dst$$Register; 5319 __ movl(Rdst, $mem$$Address); 5320 __ andl(Rdst, $mask$$constant); 5321 %} 5322 ins_pipe(ialu_reg_mem); 5323 %} 5324 5325 // Load Unsigned Integer into Long Register 5326 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5327 %{ 5328 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5329 5330 ins_cost(125); 5331 format %{ "movl $dst, $mem\t# uint -> long" %} 5332 5333 ins_encode %{ 5334 __ movl($dst$$Register, $mem$$Address); 5335 %} 5336 5337 ins_pipe(ialu_reg_mem); 5338 %} 5339 5340 // Load Long 5341 instruct loadL(rRegL dst, memory mem) 5342 %{ 5343 match(Set dst (LoadL mem)); 5344 5345 ins_cost(125); 5346 format %{ "movq $dst, $mem\t# long" %} 5347 5348 ins_encode %{ 5349 __ movq($dst$$Register, $mem$$Address); 5350 %} 5351 5352 ins_pipe(ialu_reg_mem); // XXX 5353 %} 5354 5355 // Load Range 5356 instruct loadRange(rRegI dst, memory mem) 5357 %{ 5358 match(Set dst (LoadRange mem)); 5359 5360 ins_cost(125); // XXX 5361 format %{ "movl $dst, $mem\t# range" %} 5362 opcode(0x8B); 5363 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5364 ins_pipe(ialu_reg_mem); 5365 %} 5366 5367 // Load Pointer 5368 instruct loadP(rRegP dst, memory mem) 5369 %{ 5370 match(Set dst (LoadP mem)); 5371 5372 ins_cost(125); // XXX 5373 format %{ "movq $dst, $mem\t# ptr" %} 5374 opcode(0x8B); 5375 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5376 ins_pipe(ialu_reg_mem); // XXX 5377 %} 5378 5379 // Load Compressed Pointer 5380 instruct loadN(rRegN dst, memory mem) 5381 %{ 5382 match(Set dst (LoadN mem)); 5383 5384 ins_cost(125); // XXX 5385 format %{ "movl $dst, $mem\t# compressed ptr" %} 5386 ins_encode %{ 5387 __ movl($dst$$Register, $mem$$Address); 5388 %} 5389 ins_pipe(ialu_reg_mem); // XXX 5390 %} 5391 5392 5393 // Load Klass Pointer 5394 instruct loadKlass(rRegP dst, memory mem) 5395 %{ 5396 match(Set dst (LoadKlass mem)); 5397 5398 ins_cost(125); // XXX 5399 format %{ "movq $dst, $mem\t# class" %} 5400 opcode(0x8B); 5401 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5402 ins_pipe(ialu_reg_mem); // XXX 5403 %} 5404 5405 // Load narrow Klass Pointer 5406 instruct loadNKlass(rRegN dst, memory mem) 5407 %{ 5408 match(Set dst (LoadNKlass mem)); 5409 5410 ins_cost(125); // XXX 5411 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5412 ins_encode %{ 5413 __ movl($dst$$Register, $mem$$Address); 5414 %} 5415 ins_pipe(ialu_reg_mem); // XXX 5416 %} 5417 5418 // Load Float 5419 instruct loadF(regF dst, memory mem) 5420 %{ 5421 match(Set dst (LoadF mem)); 5422 5423 ins_cost(145); // XXX 5424 format %{ "movss $dst, $mem\t# float" %} 5425 ins_encode %{ 5426 __ movflt($dst$$XMMRegister, $mem$$Address); 5427 %} 5428 ins_pipe(pipe_slow); // XXX 5429 %} 5430 5431 5432 // Load Float 5433 instruct MoveF2VL(vlRegF dst, regF src) %{ 5434 match(Set dst src); 5435 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5436 ins_encode %{ 5437 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5438 %} 5439 ins_pipe( fpu_reg_reg ); 5440 %} 5441 5442 // Load Float 5443 instruct MoveF2LEG(legRegF dst, regF src) %{ 5444 match(Set dst src); 5445 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5446 ins_encode %{ 5447 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5448 %} 5449 ins_pipe( fpu_reg_reg ); 5450 %} 5451 5452 // Load Float 5453 instruct MoveVL2F(regF dst, vlRegF src) %{ 5454 match(Set dst src); 5455 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5456 ins_encode %{ 5457 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5458 %} 5459 ins_pipe( fpu_reg_reg ); 5460 %} 5461 5462 // Load Float 5463 instruct MoveLEG2F(regF dst, legRegF src) %{ 5464 match(Set dst src); 5465 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5466 ins_encode %{ 5467 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5468 %} 5469 ins_pipe( fpu_reg_reg ); 5470 %} 5471 5472 // Load Double 5473 instruct loadD_partial(regD dst, memory mem) 5474 %{ 5475 predicate(!UseXmmLoadAndClearUpper); 5476 match(Set dst (LoadD mem)); 5477 5478 ins_cost(145); // XXX 5479 format %{ "movlpd $dst, $mem\t# double" %} 5480 ins_encode %{ 5481 __ movdbl($dst$$XMMRegister, $mem$$Address); 5482 %} 5483 ins_pipe(pipe_slow); // XXX 5484 %} 5485 5486 5487 instruct loadD(regD dst, memory mem) 5488 %{ 5489 predicate(UseXmmLoadAndClearUpper); 5490 match(Set dst (LoadD mem)); 5491 5492 ins_cost(145); // XXX 5493 format %{ "movsd $dst, $mem\t# double" %} 5494 ins_encode %{ 5495 __ movdbl($dst$$XMMRegister, $mem$$Address); 5496 %} 5497 ins_pipe(pipe_slow); // XXX 5498 %} 5499 5500 // Load Double 5501 instruct MoveD2VL(vlRegD dst, regD src) %{ 5502 match(Set dst src); 5503 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5504 ins_encode %{ 5505 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5506 %} 5507 ins_pipe( fpu_reg_reg ); 5508 %} 5509 5510 // Load Double 5511 instruct MoveD2LEG(legRegD dst, regD src) %{ 5512 match(Set dst src); 5513 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5514 ins_encode %{ 5515 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5516 %} 5517 ins_pipe( fpu_reg_reg ); 5518 %} 5519 5520 // Load Double 5521 instruct MoveVL2D(regD dst, vlRegD src) %{ 5522 match(Set dst src); 5523 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5524 ins_encode %{ 5525 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5526 %} 5527 ins_pipe( fpu_reg_reg ); 5528 %} 5529 5530 // Load Double 5531 instruct MoveLEG2D(regD dst, legRegD src) %{ 5532 match(Set dst src); 5533 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5534 ins_encode %{ 5535 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5536 %} 5537 ins_pipe( fpu_reg_reg ); 5538 %} 5539 5540 // Load Effective Address 5541 instruct leaP8(rRegP dst, indOffset8 mem) 5542 %{ 5543 match(Set dst mem); 5544 5545 ins_cost(110); // XXX 5546 format %{ "leaq $dst, $mem\t# ptr 8" %} 5547 opcode(0x8D); 5548 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5549 ins_pipe(ialu_reg_reg_fat); 5550 %} 5551 5552 instruct leaP32(rRegP dst, indOffset32 mem) 5553 %{ 5554 match(Set dst mem); 5555 5556 ins_cost(110); 5557 format %{ "leaq $dst, $mem\t# ptr 32" %} 5558 opcode(0x8D); 5559 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5560 ins_pipe(ialu_reg_reg_fat); 5561 %} 5562 5563 // instruct leaPIdx(rRegP dst, indIndex mem) 5564 // %{ 5565 // match(Set dst mem); 5566 5567 // ins_cost(110); 5568 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5569 // opcode(0x8D); 5570 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5571 // ins_pipe(ialu_reg_reg_fat); 5572 // %} 5573 5574 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5575 %{ 5576 match(Set dst mem); 5577 5578 ins_cost(110); 5579 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5580 opcode(0x8D); 5581 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5582 ins_pipe(ialu_reg_reg_fat); 5583 %} 5584 5585 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5586 %{ 5587 match(Set dst mem); 5588 5589 ins_cost(110); 5590 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5591 opcode(0x8D); 5592 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5593 ins_pipe(ialu_reg_reg_fat); 5594 %} 5595 5596 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5597 %{ 5598 match(Set dst mem); 5599 5600 ins_cost(110); 5601 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5602 opcode(0x8D); 5603 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5604 ins_pipe(ialu_reg_reg_fat); 5605 %} 5606 5607 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5608 %{ 5609 match(Set dst mem); 5610 5611 ins_cost(110); 5612 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5613 opcode(0x8D); 5614 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5615 ins_pipe(ialu_reg_reg_fat); 5616 %} 5617 5618 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5619 %{ 5620 match(Set dst mem); 5621 5622 ins_cost(110); 5623 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5624 opcode(0x8D); 5625 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5626 ins_pipe(ialu_reg_reg_fat); 5627 %} 5628 5629 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5630 %{ 5631 match(Set dst mem); 5632 5633 ins_cost(110); 5634 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5635 opcode(0x8D); 5636 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5637 ins_pipe(ialu_reg_reg_fat); 5638 %} 5639 5640 // Load Effective Address which uses Narrow (32-bits) oop 5641 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5642 %{ 5643 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5644 match(Set dst mem); 5645 5646 ins_cost(110); 5647 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5648 opcode(0x8D); 5649 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5650 ins_pipe(ialu_reg_reg_fat); 5651 %} 5652 5653 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5654 %{ 5655 predicate(Universe::narrow_oop_shift() == 0); 5656 match(Set dst mem); 5657 5658 ins_cost(110); // XXX 5659 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5660 opcode(0x8D); 5661 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5662 ins_pipe(ialu_reg_reg_fat); 5663 %} 5664 5665 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5666 %{ 5667 predicate(Universe::narrow_oop_shift() == 0); 5668 match(Set dst mem); 5669 5670 ins_cost(110); 5671 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5672 opcode(0x8D); 5673 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5674 ins_pipe(ialu_reg_reg_fat); 5675 %} 5676 5677 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5678 %{ 5679 predicate(Universe::narrow_oop_shift() == 0); 5680 match(Set dst mem); 5681 5682 ins_cost(110); 5683 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5684 opcode(0x8D); 5685 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5686 ins_pipe(ialu_reg_reg_fat); 5687 %} 5688 5689 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5690 %{ 5691 predicate(Universe::narrow_oop_shift() == 0); 5692 match(Set dst mem); 5693 5694 ins_cost(110); 5695 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5696 opcode(0x8D); 5697 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5698 ins_pipe(ialu_reg_reg_fat); 5699 %} 5700 5701 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5702 %{ 5703 predicate(Universe::narrow_oop_shift() == 0); 5704 match(Set dst mem); 5705 5706 ins_cost(110); 5707 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5708 opcode(0x8D); 5709 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5710 ins_pipe(ialu_reg_reg_fat); 5711 %} 5712 5713 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5714 %{ 5715 predicate(Universe::narrow_oop_shift() == 0); 5716 match(Set dst mem); 5717 5718 ins_cost(110); 5719 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5720 opcode(0x8D); 5721 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5722 ins_pipe(ialu_reg_reg_fat); 5723 %} 5724 5725 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5726 %{ 5727 predicate(Universe::narrow_oop_shift() == 0); 5728 match(Set dst mem); 5729 5730 ins_cost(110); 5731 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5732 opcode(0x8D); 5733 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5734 ins_pipe(ialu_reg_reg_fat); 5735 %} 5736 5737 instruct loadConI(rRegI dst, immI src) 5738 %{ 5739 match(Set dst src); 5740 5741 format %{ "movl $dst, $src\t# int" %} 5742 ins_encode(load_immI(dst, src)); 5743 ins_pipe(ialu_reg_fat); // XXX 5744 %} 5745 5746 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5747 %{ 5748 match(Set dst src); 5749 effect(KILL cr); 5750 5751 ins_cost(50); 5752 format %{ "xorl $dst, $dst\t# int" %} 5753 opcode(0x33); /* + rd */ 5754 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5755 ins_pipe(ialu_reg); 5756 %} 5757 5758 instruct loadConL(rRegL dst, immL src) 5759 %{ 5760 match(Set dst src); 5761 5762 ins_cost(150); 5763 format %{ "movq $dst, $src\t# long" %} 5764 ins_encode(load_immL(dst, src)); 5765 ins_pipe(ialu_reg); 5766 %} 5767 5768 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5769 %{ 5770 match(Set dst src); 5771 effect(KILL cr); 5772 5773 ins_cost(50); 5774 format %{ "xorl $dst, $dst\t# long" %} 5775 opcode(0x33); /* + rd */ 5776 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5777 ins_pipe(ialu_reg); // XXX 5778 %} 5779 5780 instruct loadConUL32(rRegL dst, immUL32 src) 5781 %{ 5782 match(Set dst src); 5783 5784 ins_cost(60); 5785 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5786 ins_encode(load_immUL32(dst, src)); 5787 ins_pipe(ialu_reg); 5788 %} 5789 5790 instruct loadConL32(rRegL dst, immL32 src) 5791 %{ 5792 match(Set dst src); 5793 5794 ins_cost(70); 5795 format %{ "movq $dst, $src\t# long (32-bit)" %} 5796 ins_encode(load_immL32(dst, src)); 5797 ins_pipe(ialu_reg); 5798 %} 5799 5800 instruct loadConP(rRegP dst, immP con) %{ 5801 match(Set dst con); 5802 5803 format %{ "movq $dst, $con\t# ptr" %} 5804 ins_encode(load_immP(dst, con)); 5805 ins_pipe(ialu_reg_fat); // XXX 5806 %} 5807 5808 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5809 %{ 5810 match(Set dst src); 5811 effect(KILL cr); 5812 5813 ins_cost(50); 5814 format %{ "xorl $dst, $dst\t# ptr" %} 5815 opcode(0x33); /* + rd */ 5816 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5817 ins_pipe(ialu_reg); 5818 %} 5819 5820 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5821 %{ 5822 match(Set dst src); 5823 effect(KILL cr); 5824 5825 ins_cost(60); 5826 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5827 ins_encode(load_immP31(dst, src)); 5828 ins_pipe(ialu_reg); 5829 %} 5830 5831 instruct loadConF(regF dst, immF con) %{ 5832 match(Set dst con); 5833 ins_cost(125); 5834 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5835 ins_encode %{ 5836 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5837 %} 5838 ins_pipe(pipe_slow); 5839 %} 5840 5841 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5842 match(Set dst src); 5843 effect(KILL cr); 5844 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5845 ins_encode %{ 5846 __ xorq($dst$$Register, $dst$$Register); 5847 %} 5848 ins_pipe(ialu_reg); 5849 %} 5850 5851 instruct loadConN(rRegN dst, immN src) %{ 5852 match(Set dst src); 5853 5854 ins_cost(125); 5855 format %{ "movl $dst, $src\t# compressed ptr" %} 5856 ins_encode %{ 5857 address con = (address)$src$$constant; 5858 if (con == NULL) { 5859 ShouldNotReachHere(); 5860 } else { 5861 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5862 } 5863 %} 5864 ins_pipe(ialu_reg_fat); // XXX 5865 %} 5866 5867 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5868 match(Set dst src); 5869 5870 ins_cost(125); 5871 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5872 ins_encode %{ 5873 address con = (address)$src$$constant; 5874 if (con == NULL) { 5875 ShouldNotReachHere(); 5876 } else { 5877 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5878 } 5879 %} 5880 ins_pipe(ialu_reg_fat); // XXX 5881 %} 5882 5883 instruct loadConF0(regF dst, immF0 src) 5884 %{ 5885 match(Set dst src); 5886 ins_cost(100); 5887 5888 format %{ "xorps $dst, $dst\t# float 0.0" %} 5889 ins_encode %{ 5890 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5891 %} 5892 ins_pipe(pipe_slow); 5893 %} 5894 5895 // Use the same format since predicate() can not be used here. 5896 instruct loadConD(regD dst, immD con) %{ 5897 match(Set dst con); 5898 ins_cost(125); 5899 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5900 ins_encode %{ 5901 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5902 %} 5903 ins_pipe(pipe_slow); 5904 %} 5905 5906 instruct loadConD0(regD dst, immD0 src) 5907 %{ 5908 match(Set dst src); 5909 ins_cost(100); 5910 5911 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5912 ins_encode %{ 5913 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5914 %} 5915 ins_pipe(pipe_slow); 5916 %} 5917 5918 instruct loadSSI(rRegI dst, stackSlotI src) 5919 %{ 5920 match(Set dst src); 5921 5922 ins_cost(125); 5923 format %{ "movl $dst, $src\t# int stk" %} 5924 opcode(0x8B); 5925 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5926 ins_pipe(ialu_reg_mem); 5927 %} 5928 5929 instruct loadSSL(rRegL dst, stackSlotL src) 5930 %{ 5931 match(Set dst src); 5932 5933 ins_cost(125); 5934 format %{ "movq $dst, $src\t# long stk" %} 5935 opcode(0x8B); 5936 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5937 ins_pipe(ialu_reg_mem); 5938 %} 5939 5940 instruct loadSSP(rRegP dst, stackSlotP src) 5941 %{ 5942 match(Set dst src); 5943 5944 ins_cost(125); 5945 format %{ "movq $dst, $src\t# ptr stk" %} 5946 opcode(0x8B); 5947 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5948 ins_pipe(ialu_reg_mem); 5949 %} 5950 5951 instruct loadSSF(regF dst, stackSlotF src) 5952 %{ 5953 match(Set dst src); 5954 5955 ins_cost(125); 5956 format %{ "movss $dst, $src\t# float stk" %} 5957 ins_encode %{ 5958 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5959 %} 5960 ins_pipe(pipe_slow); // XXX 5961 %} 5962 5963 // Use the same format since predicate() can not be used here. 5964 instruct loadSSD(regD dst, stackSlotD src) 5965 %{ 5966 match(Set dst src); 5967 5968 ins_cost(125); 5969 format %{ "movsd $dst, $src\t# double stk" %} 5970 ins_encode %{ 5971 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5972 %} 5973 ins_pipe(pipe_slow); // XXX 5974 %} 5975 5976 // Prefetch instructions for allocation. 5977 // Must be safe to execute with invalid address (cannot fault). 5978 5979 instruct prefetchAlloc( memory mem ) %{ 5980 predicate(AllocatePrefetchInstr==3); 5981 match(PrefetchAllocation mem); 5982 ins_cost(125); 5983 5984 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5985 ins_encode %{ 5986 __ prefetchw($mem$$Address); 5987 %} 5988 ins_pipe(ialu_mem); 5989 %} 5990 5991 instruct prefetchAllocNTA( memory mem ) %{ 5992 predicate(AllocatePrefetchInstr==0); 5993 match(PrefetchAllocation mem); 5994 ins_cost(125); 5995 5996 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5997 ins_encode %{ 5998 __ prefetchnta($mem$$Address); 5999 %} 6000 ins_pipe(ialu_mem); 6001 %} 6002 6003 instruct prefetchAllocT0( memory mem ) %{ 6004 predicate(AllocatePrefetchInstr==1); 6005 match(PrefetchAllocation mem); 6006 ins_cost(125); 6007 6008 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 6009 ins_encode %{ 6010 __ prefetcht0($mem$$Address); 6011 %} 6012 ins_pipe(ialu_mem); 6013 %} 6014 6015 instruct prefetchAllocT2( memory mem ) %{ 6016 predicate(AllocatePrefetchInstr==2); 6017 match(PrefetchAllocation mem); 6018 ins_cost(125); 6019 6020 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 6021 ins_encode %{ 6022 __ prefetcht2($mem$$Address); 6023 %} 6024 ins_pipe(ialu_mem); 6025 %} 6026 6027 //----------Store Instructions------------------------------------------------- 6028 6029 // Store Byte 6030 instruct storeB(memory mem, rRegI src) 6031 %{ 6032 match(Set mem (StoreB mem src)); 6033 6034 ins_cost(125); // XXX 6035 format %{ "movb $mem, $src\t# byte" %} 6036 opcode(0x88); 6037 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 6038 ins_pipe(ialu_mem_reg); 6039 %} 6040 6041 // Store Char/Short 6042 instruct storeC(memory mem, rRegI src) 6043 %{ 6044 match(Set mem (StoreC mem src)); 6045 6046 ins_cost(125); // XXX 6047 format %{ "movw $mem, $src\t# char/short" %} 6048 opcode(0x89); 6049 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6050 ins_pipe(ialu_mem_reg); 6051 %} 6052 6053 // Store Integer 6054 instruct storeI(memory mem, rRegI src) 6055 %{ 6056 match(Set mem (StoreI mem src)); 6057 6058 ins_cost(125); // XXX 6059 format %{ "movl $mem, $src\t# int" %} 6060 opcode(0x89); 6061 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6062 ins_pipe(ialu_mem_reg); 6063 %} 6064 6065 // Store Long 6066 instruct storeL(memory mem, rRegL src) 6067 %{ 6068 match(Set mem (StoreL mem src)); 6069 6070 ins_cost(125); // XXX 6071 format %{ "movq $mem, $src\t# long" %} 6072 opcode(0x89); 6073 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6074 ins_pipe(ialu_mem_reg); // XXX 6075 %} 6076 6077 // Store Pointer 6078 instruct storeP(memory mem, any_RegP src) 6079 %{ 6080 match(Set mem (StoreP mem src)); 6081 6082 ins_cost(125); // XXX 6083 format %{ "movq $mem, $src\t# ptr" %} 6084 opcode(0x89); 6085 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6086 ins_pipe(ialu_mem_reg); 6087 %} 6088 6089 instruct storeImmP0(memory mem, immP0 zero) 6090 %{ 6091 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6092 match(Set mem (StoreP mem zero)); 6093 6094 ins_cost(125); // XXX 6095 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 6096 ins_encode %{ 6097 __ movq($mem$$Address, r12); 6098 %} 6099 ins_pipe(ialu_mem_reg); 6100 %} 6101 6102 // Store NULL Pointer, mark word, or other simple pointer constant. 6103 instruct storeImmP(memory mem, immP31 src) 6104 %{ 6105 match(Set mem (StoreP mem src)); 6106 6107 ins_cost(150); // XXX 6108 format %{ "movq $mem, $src\t# ptr" %} 6109 opcode(0xC7); /* C7 /0 */ 6110 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6111 ins_pipe(ialu_mem_imm); 6112 %} 6113 6114 // Store Compressed Pointer 6115 instruct storeN(memory mem, rRegN src) 6116 %{ 6117 match(Set mem (StoreN mem src)); 6118 6119 ins_cost(125); // XXX 6120 format %{ "movl $mem, $src\t# compressed ptr" %} 6121 ins_encode %{ 6122 __ movl($mem$$Address, $src$$Register); 6123 %} 6124 ins_pipe(ialu_mem_reg); 6125 %} 6126 6127 instruct storeNKlass(memory mem, rRegN src) 6128 %{ 6129 match(Set mem (StoreNKlass mem src)); 6130 6131 ins_cost(125); // XXX 6132 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6133 ins_encode %{ 6134 __ movl($mem$$Address, $src$$Register); 6135 %} 6136 ins_pipe(ialu_mem_reg); 6137 %} 6138 6139 instruct storeImmN0(memory mem, immN0 zero) 6140 %{ 6141 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 6142 match(Set mem (StoreN mem zero)); 6143 6144 ins_cost(125); // XXX 6145 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6146 ins_encode %{ 6147 __ movl($mem$$Address, r12); 6148 %} 6149 ins_pipe(ialu_mem_reg); 6150 %} 6151 6152 instruct storeImmN(memory mem, immN src) 6153 %{ 6154 match(Set mem (StoreN mem src)); 6155 6156 ins_cost(150); // XXX 6157 format %{ "movl $mem, $src\t# compressed ptr" %} 6158 ins_encode %{ 6159 address con = (address)$src$$constant; 6160 if (con == NULL) { 6161 __ movl($mem$$Address, (int32_t)0); 6162 } else { 6163 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6164 } 6165 %} 6166 ins_pipe(ialu_mem_imm); 6167 %} 6168 6169 instruct storeImmNKlass(memory mem, immNKlass src) 6170 %{ 6171 match(Set mem (StoreNKlass mem src)); 6172 6173 ins_cost(150); // XXX 6174 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6175 ins_encode %{ 6176 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 6177 %} 6178 ins_pipe(ialu_mem_imm); 6179 %} 6180 6181 // Store Integer Immediate 6182 instruct storeImmI0(memory mem, immI0 zero) 6183 %{ 6184 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6185 match(Set mem (StoreI mem zero)); 6186 6187 ins_cost(125); // XXX 6188 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6189 ins_encode %{ 6190 __ movl($mem$$Address, r12); 6191 %} 6192 ins_pipe(ialu_mem_reg); 6193 %} 6194 6195 instruct storeImmI(memory mem, immI src) 6196 %{ 6197 match(Set mem (StoreI mem src)); 6198 6199 ins_cost(150); 6200 format %{ "movl $mem, $src\t# int" %} 6201 opcode(0xC7); /* C7 /0 */ 6202 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6203 ins_pipe(ialu_mem_imm); 6204 %} 6205 6206 // Store Long Immediate 6207 instruct storeImmL0(memory mem, immL0 zero) 6208 %{ 6209 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6210 match(Set mem (StoreL mem zero)); 6211 6212 ins_cost(125); // XXX 6213 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6214 ins_encode %{ 6215 __ movq($mem$$Address, r12); 6216 %} 6217 ins_pipe(ialu_mem_reg); 6218 %} 6219 6220 instruct storeImmL(memory mem, immL32 src) 6221 %{ 6222 match(Set mem (StoreL mem src)); 6223 6224 ins_cost(150); 6225 format %{ "movq $mem, $src\t# long" %} 6226 opcode(0xC7); /* C7 /0 */ 6227 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6228 ins_pipe(ialu_mem_imm); 6229 %} 6230 6231 // Store Short/Char Immediate 6232 instruct storeImmC0(memory mem, immI0 zero) 6233 %{ 6234 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6235 match(Set mem (StoreC mem zero)); 6236 6237 ins_cost(125); // XXX 6238 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6239 ins_encode %{ 6240 __ movw($mem$$Address, r12); 6241 %} 6242 ins_pipe(ialu_mem_reg); 6243 %} 6244 6245 instruct storeImmI16(memory mem, immI16 src) 6246 %{ 6247 predicate(UseStoreImmI16); 6248 match(Set mem (StoreC mem src)); 6249 6250 ins_cost(150); 6251 format %{ "movw $mem, $src\t# short/char" %} 6252 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6253 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6254 ins_pipe(ialu_mem_imm); 6255 %} 6256 6257 // Store Byte Immediate 6258 instruct storeImmB0(memory mem, immI0 zero) 6259 %{ 6260 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6261 match(Set mem (StoreB mem zero)); 6262 6263 ins_cost(125); // XXX 6264 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6265 ins_encode %{ 6266 __ movb($mem$$Address, r12); 6267 %} 6268 ins_pipe(ialu_mem_reg); 6269 %} 6270 6271 instruct storeImmB(memory mem, immI8 src) 6272 %{ 6273 match(Set mem (StoreB mem src)); 6274 6275 ins_cost(150); // XXX 6276 format %{ "movb $mem, $src\t# byte" %} 6277 opcode(0xC6); /* C6 /0 */ 6278 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6279 ins_pipe(ialu_mem_imm); 6280 %} 6281 6282 // Store CMS card-mark Immediate 6283 instruct storeImmCM0_reg(memory mem, immI0 zero) 6284 %{ 6285 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6286 match(Set mem (StoreCM mem zero)); 6287 6288 ins_cost(125); // XXX 6289 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6290 ins_encode %{ 6291 __ movb($mem$$Address, r12); 6292 %} 6293 ins_pipe(ialu_mem_reg); 6294 %} 6295 6296 instruct storeImmCM0(memory mem, immI0 src) 6297 %{ 6298 match(Set mem (StoreCM mem src)); 6299 6300 ins_cost(150); // XXX 6301 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6302 opcode(0xC6); /* C6 /0 */ 6303 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6304 ins_pipe(ialu_mem_imm); 6305 %} 6306 6307 // Store Float 6308 instruct storeF(memory mem, regF src) 6309 %{ 6310 match(Set mem (StoreF mem src)); 6311 6312 ins_cost(95); // XXX 6313 format %{ "movss $mem, $src\t# float" %} 6314 ins_encode %{ 6315 __ movflt($mem$$Address, $src$$XMMRegister); 6316 %} 6317 ins_pipe(pipe_slow); // XXX 6318 %} 6319 6320 // Store immediate Float value (it is faster than store from XMM register) 6321 instruct storeF0(memory mem, immF0 zero) 6322 %{ 6323 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6324 match(Set mem (StoreF mem zero)); 6325 6326 ins_cost(25); // XXX 6327 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6328 ins_encode %{ 6329 __ movl($mem$$Address, r12); 6330 %} 6331 ins_pipe(ialu_mem_reg); 6332 %} 6333 6334 instruct storeF_imm(memory mem, immF src) 6335 %{ 6336 match(Set mem (StoreF mem src)); 6337 6338 ins_cost(50); 6339 format %{ "movl $mem, $src\t# float" %} 6340 opcode(0xC7); /* C7 /0 */ 6341 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6342 ins_pipe(ialu_mem_imm); 6343 %} 6344 6345 // Store Double 6346 instruct storeD(memory mem, regD src) 6347 %{ 6348 match(Set mem (StoreD mem src)); 6349 6350 ins_cost(95); // XXX 6351 format %{ "movsd $mem, $src\t# double" %} 6352 ins_encode %{ 6353 __ movdbl($mem$$Address, $src$$XMMRegister); 6354 %} 6355 ins_pipe(pipe_slow); // XXX 6356 %} 6357 6358 // Store immediate double 0.0 (it is faster than store from XMM register) 6359 instruct storeD0_imm(memory mem, immD0 src) 6360 %{ 6361 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6362 match(Set mem (StoreD mem src)); 6363 6364 ins_cost(50); 6365 format %{ "movq $mem, $src\t# double 0." %} 6366 opcode(0xC7); /* C7 /0 */ 6367 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6368 ins_pipe(ialu_mem_imm); 6369 %} 6370 6371 instruct storeD0(memory mem, immD0 zero) 6372 %{ 6373 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6374 match(Set mem (StoreD mem zero)); 6375 6376 ins_cost(25); // XXX 6377 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6378 ins_encode %{ 6379 __ movq($mem$$Address, r12); 6380 %} 6381 ins_pipe(ialu_mem_reg); 6382 %} 6383 6384 instruct storeSSI(stackSlotI dst, rRegI src) 6385 %{ 6386 match(Set dst src); 6387 6388 ins_cost(100); 6389 format %{ "movl $dst, $src\t# int stk" %} 6390 opcode(0x89); 6391 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6392 ins_pipe( ialu_mem_reg ); 6393 %} 6394 6395 instruct storeSSL(stackSlotL dst, rRegL src) 6396 %{ 6397 match(Set dst src); 6398 6399 ins_cost(100); 6400 format %{ "movq $dst, $src\t# long stk" %} 6401 opcode(0x89); 6402 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6403 ins_pipe(ialu_mem_reg); 6404 %} 6405 6406 instruct storeSSP(stackSlotP dst, rRegP src) 6407 %{ 6408 match(Set dst src); 6409 6410 ins_cost(100); 6411 format %{ "movq $dst, $src\t# ptr stk" %} 6412 opcode(0x89); 6413 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6414 ins_pipe(ialu_mem_reg); 6415 %} 6416 6417 instruct storeSSF(stackSlotF dst, regF src) 6418 %{ 6419 match(Set dst src); 6420 6421 ins_cost(95); // XXX 6422 format %{ "movss $dst, $src\t# float stk" %} 6423 ins_encode %{ 6424 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6425 %} 6426 ins_pipe(pipe_slow); // XXX 6427 %} 6428 6429 instruct storeSSD(stackSlotD dst, regD src) 6430 %{ 6431 match(Set dst src); 6432 6433 ins_cost(95); // XXX 6434 format %{ "movsd $dst, $src\t# double stk" %} 6435 ins_encode %{ 6436 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6437 %} 6438 ins_pipe(pipe_slow); // XXX 6439 %} 6440 6441 //----------BSWAP Instructions------------------------------------------------- 6442 instruct bytes_reverse_int(rRegI dst) %{ 6443 match(Set dst (ReverseBytesI dst)); 6444 6445 format %{ "bswapl $dst" %} 6446 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6447 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6448 ins_pipe( ialu_reg ); 6449 %} 6450 6451 instruct bytes_reverse_long(rRegL dst) %{ 6452 match(Set dst (ReverseBytesL dst)); 6453 6454 format %{ "bswapq $dst" %} 6455 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6456 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6457 ins_pipe( ialu_reg); 6458 %} 6459 6460 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6461 match(Set dst (ReverseBytesUS dst)); 6462 effect(KILL cr); 6463 6464 format %{ "bswapl $dst\n\t" 6465 "shrl $dst,16\n\t" %} 6466 ins_encode %{ 6467 __ bswapl($dst$$Register); 6468 __ shrl($dst$$Register, 16); 6469 %} 6470 ins_pipe( ialu_reg ); 6471 %} 6472 6473 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6474 match(Set dst (ReverseBytesS dst)); 6475 effect(KILL cr); 6476 6477 format %{ "bswapl $dst\n\t" 6478 "sar $dst,16\n\t" %} 6479 ins_encode %{ 6480 __ bswapl($dst$$Register); 6481 __ sarl($dst$$Register, 16); 6482 %} 6483 ins_pipe( ialu_reg ); 6484 %} 6485 6486 //---------- Zeros Count Instructions ------------------------------------------ 6487 6488 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6489 predicate(UseCountLeadingZerosInstruction); 6490 match(Set dst (CountLeadingZerosI src)); 6491 effect(KILL cr); 6492 6493 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6494 ins_encode %{ 6495 __ lzcntl($dst$$Register, $src$$Register); 6496 %} 6497 ins_pipe(ialu_reg); 6498 %} 6499 6500 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6501 predicate(!UseCountLeadingZerosInstruction); 6502 match(Set dst (CountLeadingZerosI src)); 6503 effect(KILL cr); 6504 6505 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6506 "jnz skip\n\t" 6507 "movl $dst, -1\n" 6508 "skip:\n\t" 6509 "negl $dst\n\t" 6510 "addl $dst, 31" %} 6511 ins_encode %{ 6512 Register Rdst = $dst$$Register; 6513 Register Rsrc = $src$$Register; 6514 Label skip; 6515 __ bsrl(Rdst, Rsrc); 6516 __ jccb(Assembler::notZero, skip); 6517 __ movl(Rdst, -1); 6518 __ bind(skip); 6519 __ negl(Rdst); 6520 __ addl(Rdst, BitsPerInt - 1); 6521 %} 6522 ins_pipe(ialu_reg); 6523 %} 6524 6525 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6526 predicate(UseCountLeadingZerosInstruction); 6527 match(Set dst (CountLeadingZerosL src)); 6528 effect(KILL cr); 6529 6530 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6531 ins_encode %{ 6532 __ lzcntq($dst$$Register, $src$$Register); 6533 %} 6534 ins_pipe(ialu_reg); 6535 %} 6536 6537 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6538 predicate(!UseCountLeadingZerosInstruction); 6539 match(Set dst (CountLeadingZerosL src)); 6540 effect(KILL cr); 6541 6542 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6543 "jnz skip\n\t" 6544 "movl $dst, -1\n" 6545 "skip:\n\t" 6546 "negl $dst\n\t" 6547 "addl $dst, 63" %} 6548 ins_encode %{ 6549 Register Rdst = $dst$$Register; 6550 Register Rsrc = $src$$Register; 6551 Label skip; 6552 __ bsrq(Rdst, Rsrc); 6553 __ jccb(Assembler::notZero, skip); 6554 __ movl(Rdst, -1); 6555 __ bind(skip); 6556 __ negl(Rdst); 6557 __ addl(Rdst, BitsPerLong - 1); 6558 %} 6559 ins_pipe(ialu_reg); 6560 %} 6561 6562 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6563 predicate(UseCountTrailingZerosInstruction); 6564 match(Set dst (CountTrailingZerosI src)); 6565 effect(KILL cr); 6566 6567 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6568 ins_encode %{ 6569 __ tzcntl($dst$$Register, $src$$Register); 6570 %} 6571 ins_pipe(ialu_reg); 6572 %} 6573 6574 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6575 predicate(!UseCountTrailingZerosInstruction); 6576 match(Set dst (CountTrailingZerosI src)); 6577 effect(KILL cr); 6578 6579 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6580 "jnz done\n\t" 6581 "movl $dst, 32\n" 6582 "done:" %} 6583 ins_encode %{ 6584 Register Rdst = $dst$$Register; 6585 Label done; 6586 __ bsfl(Rdst, $src$$Register); 6587 __ jccb(Assembler::notZero, done); 6588 __ movl(Rdst, BitsPerInt); 6589 __ bind(done); 6590 %} 6591 ins_pipe(ialu_reg); 6592 %} 6593 6594 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6595 predicate(UseCountTrailingZerosInstruction); 6596 match(Set dst (CountTrailingZerosL src)); 6597 effect(KILL cr); 6598 6599 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6600 ins_encode %{ 6601 __ tzcntq($dst$$Register, $src$$Register); 6602 %} 6603 ins_pipe(ialu_reg); 6604 %} 6605 6606 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6607 predicate(!UseCountTrailingZerosInstruction); 6608 match(Set dst (CountTrailingZerosL src)); 6609 effect(KILL cr); 6610 6611 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6612 "jnz done\n\t" 6613 "movl $dst, 64\n" 6614 "done:" %} 6615 ins_encode %{ 6616 Register Rdst = $dst$$Register; 6617 Label done; 6618 __ bsfq(Rdst, $src$$Register); 6619 __ jccb(Assembler::notZero, done); 6620 __ movl(Rdst, BitsPerLong); 6621 __ bind(done); 6622 %} 6623 ins_pipe(ialu_reg); 6624 %} 6625 6626 6627 //---------- Population Count Instructions ------------------------------------- 6628 6629 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6630 predicate(UsePopCountInstruction); 6631 match(Set dst (PopCountI src)); 6632 effect(KILL cr); 6633 6634 format %{ "popcnt $dst, $src" %} 6635 ins_encode %{ 6636 __ popcntl($dst$$Register, $src$$Register); 6637 %} 6638 ins_pipe(ialu_reg); 6639 %} 6640 6641 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6642 predicate(UsePopCountInstruction); 6643 match(Set dst (PopCountI (LoadI mem))); 6644 effect(KILL cr); 6645 6646 format %{ "popcnt $dst, $mem" %} 6647 ins_encode %{ 6648 __ popcntl($dst$$Register, $mem$$Address); 6649 %} 6650 ins_pipe(ialu_reg); 6651 %} 6652 6653 // Note: Long.bitCount(long) returns an int. 6654 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6655 predicate(UsePopCountInstruction); 6656 match(Set dst (PopCountL src)); 6657 effect(KILL cr); 6658 6659 format %{ "popcnt $dst, $src" %} 6660 ins_encode %{ 6661 __ popcntq($dst$$Register, $src$$Register); 6662 %} 6663 ins_pipe(ialu_reg); 6664 %} 6665 6666 // Note: Long.bitCount(long) returns an int. 6667 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6668 predicate(UsePopCountInstruction); 6669 match(Set dst (PopCountL (LoadL mem))); 6670 effect(KILL cr); 6671 6672 format %{ "popcnt $dst, $mem" %} 6673 ins_encode %{ 6674 __ popcntq($dst$$Register, $mem$$Address); 6675 %} 6676 ins_pipe(ialu_reg); 6677 %} 6678 6679 6680 //----------MemBar Instructions----------------------------------------------- 6681 // Memory barrier flavors 6682 6683 instruct membar_acquire() 6684 %{ 6685 match(MemBarAcquire); 6686 match(LoadFence); 6687 ins_cost(0); 6688 6689 size(0); 6690 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6691 ins_encode(); 6692 ins_pipe(empty); 6693 %} 6694 6695 instruct membar_acquire_lock() 6696 %{ 6697 match(MemBarAcquireLock); 6698 ins_cost(0); 6699 6700 size(0); 6701 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6702 ins_encode(); 6703 ins_pipe(empty); 6704 %} 6705 6706 instruct membar_release() 6707 %{ 6708 match(MemBarRelease); 6709 match(StoreFence); 6710 ins_cost(0); 6711 6712 size(0); 6713 format %{ "MEMBAR-release ! (empty encoding)" %} 6714 ins_encode(); 6715 ins_pipe(empty); 6716 %} 6717 6718 instruct membar_release_lock() 6719 %{ 6720 match(MemBarReleaseLock); 6721 ins_cost(0); 6722 6723 size(0); 6724 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6725 ins_encode(); 6726 ins_pipe(empty); 6727 %} 6728 6729 instruct membar_volatile(rFlagsReg cr) %{ 6730 match(MemBarVolatile); 6731 effect(KILL cr); 6732 ins_cost(400); 6733 6734 format %{ 6735 $$template 6736 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6737 %} 6738 ins_encode %{ 6739 __ membar(Assembler::StoreLoad); 6740 %} 6741 ins_pipe(pipe_slow); 6742 %} 6743 6744 instruct unnecessary_membar_volatile() 6745 %{ 6746 match(MemBarVolatile); 6747 predicate(Matcher::post_store_load_barrier(n)); 6748 ins_cost(0); 6749 6750 size(0); 6751 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6752 ins_encode(); 6753 ins_pipe(empty); 6754 %} 6755 6756 instruct membar_storestore() %{ 6757 match(MemBarStoreStore); 6758 ins_cost(0); 6759 6760 size(0); 6761 format %{ "MEMBAR-storestore (empty encoding)" %} 6762 ins_encode( ); 6763 ins_pipe(empty); 6764 %} 6765 6766 //----------Move Instructions-------------------------------------------------- 6767 6768 instruct castX2P(rRegP dst, rRegL src) 6769 %{ 6770 match(Set dst (CastX2P src)); 6771 6772 format %{ "movq $dst, $src\t# long->ptr" %} 6773 ins_encode %{ 6774 if ($dst$$reg != $src$$reg) { 6775 __ movptr($dst$$Register, $src$$Register); 6776 } 6777 %} 6778 ins_pipe(ialu_reg_reg); // XXX 6779 %} 6780 6781 instruct castP2X(rRegL dst, rRegP src) 6782 %{ 6783 match(Set dst (CastP2X src)); 6784 6785 format %{ "movq $dst, $src\t# ptr -> long" %} 6786 ins_encode %{ 6787 if ($dst$$reg != $src$$reg) { 6788 __ movptr($dst$$Register, $src$$Register); 6789 } 6790 %} 6791 ins_pipe(ialu_reg_reg); // XXX 6792 %} 6793 6794 // Convert oop into int for vectors alignment masking 6795 instruct convP2I(rRegI dst, rRegP src) 6796 %{ 6797 match(Set dst (ConvL2I (CastP2X src))); 6798 6799 format %{ "movl $dst, $src\t# ptr -> int" %} 6800 ins_encode %{ 6801 __ movl($dst$$Register, $src$$Register); 6802 %} 6803 ins_pipe(ialu_reg_reg); // XXX 6804 %} 6805 6806 // Convert compressed oop into int for vectors alignment masking 6807 // in case of 32bit oops (heap < 4Gb). 6808 instruct convN2I(rRegI dst, rRegN src) 6809 %{ 6810 predicate(Universe::narrow_oop_shift() == 0); 6811 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6812 6813 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6814 ins_encode %{ 6815 __ movl($dst$$Register, $src$$Register); 6816 %} 6817 ins_pipe(ialu_reg_reg); // XXX 6818 %} 6819 6820 // Convert oop pointer into compressed form 6821 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6822 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6823 match(Set dst (EncodeP src)); 6824 effect(KILL cr); 6825 format %{ "encode_heap_oop $dst,$src" %} 6826 ins_encode %{ 6827 Register s = $src$$Register; 6828 Register d = $dst$$Register; 6829 if (s != d) { 6830 __ movq(d, s); 6831 } 6832 __ encode_heap_oop(d); 6833 %} 6834 ins_pipe(ialu_reg_long); 6835 %} 6836 6837 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6838 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6839 match(Set dst (EncodeP src)); 6840 effect(KILL cr); 6841 format %{ "encode_heap_oop_not_null $dst,$src" %} 6842 ins_encode %{ 6843 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6844 %} 6845 ins_pipe(ialu_reg_long); 6846 %} 6847 6848 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6849 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6850 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6851 match(Set dst (DecodeN src)); 6852 effect(KILL cr); 6853 format %{ "decode_heap_oop $dst,$src" %} 6854 ins_encode %{ 6855 Register s = $src$$Register; 6856 Register d = $dst$$Register; 6857 if (s != d) { 6858 __ movq(d, s); 6859 } 6860 __ decode_heap_oop(d); 6861 %} 6862 ins_pipe(ialu_reg_long); 6863 %} 6864 6865 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6866 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6867 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6868 match(Set dst (DecodeN src)); 6869 effect(KILL cr); 6870 format %{ "decode_heap_oop_not_null $dst,$src" %} 6871 ins_encode %{ 6872 Register s = $src$$Register; 6873 Register d = $dst$$Register; 6874 if (s != d) { 6875 __ decode_heap_oop_not_null(d, s); 6876 } else { 6877 __ decode_heap_oop_not_null(d); 6878 } 6879 %} 6880 ins_pipe(ialu_reg_long); 6881 %} 6882 6883 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6884 match(Set dst (EncodePKlass src)); 6885 effect(KILL cr); 6886 format %{ "encode_klass_not_null $dst,$src" %} 6887 ins_encode %{ 6888 __ encode_klass_not_null($dst$$Register, $src$$Register); 6889 %} 6890 ins_pipe(ialu_reg_long); 6891 %} 6892 6893 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6894 match(Set dst (DecodeNKlass src)); 6895 effect(KILL cr); 6896 format %{ "decode_klass_not_null $dst,$src" %} 6897 ins_encode %{ 6898 Register s = $src$$Register; 6899 Register d = $dst$$Register; 6900 if (s != d) { 6901 __ decode_klass_not_null(d, s); 6902 } else { 6903 __ decode_klass_not_null(d); 6904 } 6905 %} 6906 ins_pipe(ialu_reg_long); 6907 %} 6908 6909 6910 //----------Conditional Move--------------------------------------------------- 6911 // Jump 6912 // dummy instruction for generating temp registers 6913 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6914 match(Jump (LShiftL switch_val shift)); 6915 ins_cost(350); 6916 predicate(false); 6917 effect(TEMP dest); 6918 6919 format %{ "leaq $dest, [$constantaddress]\n\t" 6920 "jmp [$dest + $switch_val << $shift]\n\t" %} 6921 ins_encode %{ 6922 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6923 // to do that and the compiler is using that register as one it can allocate. 6924 // So we build it all by hand. 6925 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6926 // ArrayAddress dispatch(table, index); 6927 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6928 __ lea($dest$$Register, $constantaddress); 6929 __ jmp(dispatch); 6930 %} 6931 ins_pipe(pipe_jmp); 6932 %} 6933 6934 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6935 match(Jump (AddL (LShiftL switch_val shift) offset)); 6936 ins_cost(350); 6937 effect(TEMP dest); 6938 6939 format %{ "leaq $dest, [$constantaddress]\n\t" 6940 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6941 ins_encode %{ 6942 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6943 // to do that and the compiler is using that register as one it can allocate. 6944 // So we build it all by hand. 6945 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6946 // ArrayAddress dispatch(table, index); 6947 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6948 __ lea($dest$$Register, $constantaddress); 6949 __ jmp(dispatch); 6950 %} 6951 ins_pipe(pipe_jmp); 6952 %} 6953 6954 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6955 match(Jump switch_val); 6956 ins_cost(350); 6957 effect(TEMP dest); 6958 6959 format %{ "leaq $dest, [$constantaddress]\n\t" 6960 "jmp [$dest + $switch_val]\n\t" %} 6961 ins_encode %{ 6962 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6963 // to do that and the compiler is using that register as one it can allocate. 6964 // So we build it all by hand. 6965 // Address index(noreg, switch_reg, Address::times_1); 6966 // ArrayAddress dispatch(table, index); 6967 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6968 __ lea($dest$$Register, $constantaddress); 6969 __ jmp(dispatch); 6970 %} 6971 ins_pipe(pipe_jmp); 6972 %} 6973 6974 // Conditional move 6975 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6976 %{ 6977 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6978 6979 ins_cost(200); // XXX 6980 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6981 opcode(0x0F, 0x40); 6982 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6983 ins_pipe(pipe_cmov_reg); 6984 %} 6985 6986 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6987 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6988 6989 ins_cost(200); // XXX 6990 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6991 opcode(0x0F, 0x40); 6992 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6993 ins_pipe(pipe_cmov_reg); 6994 %} 6995 6996 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6997 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6998 ins_cost(200); 6999 expand %{ 7000 cmovI_regU(cop, cr, dst, src); 7001 %} 7002 %} 7003 7004 // Conditional move 7005 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 7006 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7007 7008 ins_cost(250); // XXX 7009 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7010 opcode(0x0F, 0x40); 7011 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7012 ins_pipe(pipe_cmov_mem); 7013 %} 7014 7015 // Conditional move 7016 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 7017 %{ 7018 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7019 7020 ins_cost(250); // XXX 7021 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7022 opcode(0x0F, 0x40); 7023 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7024 ins_pipe(pipe_cmov_mem); 7025 %} 7026 7027 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 7028 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7029 ins_cost(250); 7030 expand %{ 7031 cmovI_memU(cop, cr, dst, src); 7032 %} 7033 %} 7034 7035 // Conditional move 7036 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 7037 %{ 7038 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7039 7040 ins_cost(200); // XXX 7041 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 7042 opcode(0x0F, 0x40); 7043 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7044 ins_pipe(pipe_cmov_reg); 7045 %} 7046 7047 // Conditional move 7048 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 7049 %{ 7050 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7051 7052 ins_cost(200); // XXX 7053 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 7054 opcode(0x0F, 0x40); 7055 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7056 ins_pipe(pipe_cmov_reg); 7057 %} 7058 7059 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 7060 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7061 ins_cost(200); 7062 expand %{ 7063 cmovN_regU(cop, cr, dst, src); 7064 %} 7065 %} 7066 7067 // Conditional move 7068 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7069 %{ 7070 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7071 7072 ins_cost(200); // XXX 7073 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 7074 opcode(0x0F, 0x40); 7075 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7076 ins_pipe(pipe_cmov_reg); // XXX 7077 %} 7078 7079 // Conditional move 7080 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 7081 %{ 7082 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7083 7084 ins_cost(200); // XXX 7085 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7086 opcode(0x0F, 0x40); 7087 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7088 ins_pipe(pipe_cmov_reg); // XXX 7089 %} 7090 7091 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 7092 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7093 ins_cost(200); 7094 expand %{ 7095 cmovP_regU(cop, cr, dst, src); 7096 %} 7097 %} 7098 7099 // DISABLED: Requires the ADLC to emit a bottom_type call that 7100 // correctly meets the two pointer arguments; one is an incoming 7101 // register but the other is a memory operand. ALSO appears to 7102 // be buggy with implicit null checks. 7103 // 7104 //// Conditional move 7105 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7106 //%{ 7107 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7108 // ins_cost(250); 7109 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7110 // opcode(0x0F,0x40); 7111 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7112 // ins_pipe( pipe_cmov_mem ); 7113 //%} 7114 // 7115 //// Conditional move 7116 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7117 //%{ 7118 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7119 // ins_cost(250); 7120 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7121 // opcode(0x0F,0x40); 7122 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7123 // ins_pipe( pipe_cmov_mem ); 7124 //%} 7125 7126 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7127 %{ 7128 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7129 7130 ins_cost(200); // XXX 7131 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7132 opcode(0x0F, 0x40); 7133 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7134 ins_pipe(pipe_cmov_reg); // XXX 7135 %} 7136 7137 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7138 %{ 7139 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7140 7141 ins_cost(200); // XXX 7142 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7143 opcode(0x0F, 0x40); 7144 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7145 ins_pipe(pipe_cmov_mem); // XXX 7146 %} 7147 7148 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7149 %{ 7150 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7151 7152 ins_cost(200); // XXX 7153 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7154 opcode(0x0F, 0x40); 7155 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7156 ins_pipe(pipe_cmov_reg); // XXX 7157 %} 7158 7159 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7160 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7161 ins_cost(200); 7162 expand %{ 7163 cmovL_regU(cop, cr, dst, src); 7164 %} 7165 %} 7166 7167 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7168 %{ 7169 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7170 7171 ins_cost(200); // XXX 7172 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7173 opcode(0x0F, 0x40); 7174 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7175 ins_pipe(pipe_cmov_mem); // XXX 7176 %} 7177 7178 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7179 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7180 ins_cost(200); 7181 expand %{ 7182 cmovL_memU(cop, cr, dst, src); 7183 %} 7184 %} 7185 7186 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7187 %{ 7188 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7189 7190 ins_cost(200); // XXX 7191 format %{ "jn$cop skip\t# signed cmove float\n\t" 7192 "movss $dst, $src\n" 7193 "skip:" %} 7194 ins_encode %{ 7195 Label Lskip; 7196 // Invert sense of branch from sense of CMOV 7197 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7198 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7199 __ bind(Lskip); 7200 %} 7201 ins_pipe(pipe_slow); 7202 %} 7203 7204 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7205 // %{ 7206 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7207 7208 // ins_cost(200); // XXX 7209 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7210 // "movss $dst, $src\n" 7211 // "skip:" %} 7212 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7213 // ins_pipe(pipe_slow); 7214 // %} 7215 7216 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7217 %{ 7218 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7219 7220 ins_cost(200); // XXX 7221 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7222 "movss $dst, $src\n" 7223 "skip:" %} 7224 ins_encode %{ 7225 Label Lskip; 7226 // Invert sense of branch from sense of CMOV 7227 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7228 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7229 __ bind(Lskip); 7230 %} 7231 ins_pipe(pipe_slow); 7232 %} 7233 7234 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7235 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7236 ins_cost(200); 7237 expand %{ 7238 cmovF_regU(cop, cr, dst, src); 7239 %} 7240 %} 7241 7242 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7243 %{ 7244 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7245 7246 ins_cost(200); // XXX 7247 format %{ "jn$cop skip\t# signed cmove double\n\t" 7248 "movsd $dst, $src\n" 7249 "skip:" %} 7250 ins_encode %{ 7251 Label Lskip; 7252 // Invert sense of branch from sense of CMOV 7253 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7254 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7255 __ bind(Lskip); 7256 %} 7257 ins_pipe(pipe_slow); 7258 %} 7259 7260 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7261 %{ 7262 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7263 7264 ins_cost(200); // XXX 7265 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7266 "movsd $dst, $src\n" 7267 "skip:" %} 7268 ins_encode %{ 7269 Label Lskip; 7270 // Invert sense of branch from sense of CMOV 7271 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7272 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7273 __ bind(Lskip); 7274 %} 7275 ins_pipe(pipe_slow); 7276 %} 7277 7278 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7279 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7280 ins_cost(200); 7281 expand %{ 7282 cmovD_regU(cop, cr, dst, src); 7283 %} 7284 %} 7285 7286 //----------Arithmetic Instructions-------------------------------------------- 7287 //----------Addition Instructions---------------------------------------------- 7288 7289 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7290 %{ 7291 match(Set dst (AddI dst src)); 7292 effect(KILL cr); 7293 7294 format %{ "addl $dst, $src\t# int" %} 7295 opcode(0x03); 7296 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7297 ins_pipe(ialu_reg_reg); 7298 %} 7299 7300 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7301 %{ 7302 match(Set dst (AddI dst src)); 7303 effect(KILL cr); 7304 7305 format %{ "addl $dst, $src\t# int" %} 7306 opcode(0x81, 0x00); /* /0 id */ 7307 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7308 ins_pipe( ialu_reg ); 7309 %} 7310 7311 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7312 %{ 7313 match(Set dst (AddI dst (LoadI src))); 7314 effect(KILL cr); 7315 7316 ins_cost(125); // XXX 7317 format %{ "addl $dst, $src\t# int" %} 7318 opcode(0x03); 7319 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7320 ins_pipe(ialu_reg_mem); 7321 %} 7322 7323 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7324 %{ 7325 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7326 effect(KILL cr); 7327 7328 ins_cost(150); // XXX 7329 format %{ "addl $dst, $src\t# int" %} 7330 opcode(0x01); /* Opcode 01 /r */ 7331 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7332 ins_pipe(ialu_mem_reg); 7333 %} 7334 7335 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7336 %{ 7337 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7338 effect(KILL cr); 7339 7340 ins_cost(125); // XXX 7341 format %{ "addl $dst, $src\t# int" %} 7342 opcode(0x81); /* Opcode 81 /0 id */ 7343 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7344 ins_pipe(ialu_mem_imm); 7345 %} 7346 7347 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7348 %{ 7349 predicate(UseIncDec); 7350 match(Set dst (AddI dst src)); 7351 effect(KILL cr); 7352 7353 format %{ "incl $dst\t# int" %} 7354 opcode(0xFF, 0x00); // FF /0 7355 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7356 ins_pipe(ialu_reg); 7357 %} 7358 7359 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7360 %{ 7361 predicate(UseIncDec); 7362 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7363 effect(KILL cr); 7364 7365 ins_cost(125); // XXX 7366 format %{ "incl $dst\t# int" %} 7367 opcode(0xFF); /* Opcode FF /0 */ 7368 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7369 ins_pipe(ialu_mem_imm); 7370 %} 7371 7372 // XXX why does that use AddI 7373 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7374 %{ 7375 predicate(UseIncDec); 7376 match(Set dst (AddI dst src)); 7377 effect(KILL cr); 7378 7379 format %{ "decl $dst\t# int" %} 7380 opcode(0xFF, 0x01); // FF /1 7381 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7382 ins_pipe(ialu_reg); 7383 %} 7384 7385 // XXX why does that use AddI 7386 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7387 %{ 7388 predicate(UseIncDec); 7389 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7390 effect(KILL cr); 7391 7392 ins_cost(125); // XXX 7393 format %{ "decl $dst\t# int" %} 7394 opcode(0xFF); /* Opcode FF /1 */ 7395 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7396 ins_pipe(ialu_mem_imm); 7397 %} 7398 7399 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7400 %{ 7401 match(Set dst (AddI src0 src1)); 7402 7403 ins_cost(110); 7404 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7405 opcode(0x8D); /* 0x8D /r */ 7406 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7407 ins_pipe(ialu_reg_reg); 7408 %} 7409 7410 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7411 %{ 7412 match(Set dst (AddL dst src)); 7413 effect(KILL cr); 7414 7415 format %{ "addq $dst, $src\t# long" %} 7416 opcode(0x03); 7417 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7418 ins_pipe(ialu_reg_reg); 7419 %} 7420 7421 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7422 %{ 7423 match(Set dst (AddL dst src)); 7424 effect(KILL cr); 7425 7426 format %{ "addq $dst, $src\t# long" %} 7427 opcode(0x81, 0x00); /* /0 id */ 7428 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7429 ins_pipe( ialu_reg ); 7430 %} 7431 7432 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7433 %{ 7434 match(Set dst (AddL dst (LoadL src))); 7435 effect(KILL cr); 7436 7437 ins_cost(125); // XXX 7438 format %{ "addq $dst, $src\t# long" %} 7439 opcode(0x03); 7440 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7441 ins_pipe(ialu_reg_mem); 7442 %} 7443 7444 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7445 %{ 7446 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7447 effect(KILL cr); 7448 7449 ins_cost(150); // XXX 7450 format %{ "addq $dst, $src\t# long" %} 7451 opcode(0x01); /* Opcode 01 /r */ 7452 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7453 ins_pipe(ialu_mem_reg); 7454 %} 7455 7456 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7457 %{ 7458 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7459 effect(KILL cr); 7460 7461 ins_cost(125); // XXX 7462 format %{ "addq $dst, $src\t# long" %} 7463 opcode(0x81); /* Opcode 81 /0 id */ 7464 ins_encode(REX_mem_wide(dst), 7465 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7466 ins_pipe(ialu_mem_imm); 7467 %} 7468 7469 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7470 %{ 7471 predicate(UseIncDec); 7472 match(Set dst (AddL dst src)); 7473 effect(KILL cr); 7474 7475 format %{ "incq $dst\t# long" %} 7476 opcode(0xFF, 0x00); // FF /0 7477 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7478 ins_pipe(ialu_reg); 7479 %} 7480 7481 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7482 %{ 7483 predicate(UseIncDec); 7484 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7485 effect(KILL cr); 7486 7487 ins_cost(125); // XXX 7488 format %{ "incq $dst\t# long" %} 7489 opcode(0xFF); /* Opcode FF /0 */ 7490 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7491 ins_pipe(ialu_mem_imm); 7492 %} 7493 7494 // XXX why does that use AddL 7495 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7496 %{ 7497 predicate(UseIncDec); 7498 match(Set dst (AddL dst src)); 7499 effect(KILL cr); 7500 7501 format %{ "decq $dst\t# long" %} 7502 opcode(0xFF, 0x01); // FF /1 7503 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7504 ins_pipe(ialu_reg); 7505 %} 7506 7507 // XXX why does that use AddL 7508 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7509 %{ 7510 predicate(UseIncDec); 7511 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7512 effect(KILL cr); 7513 7514 ins_cost(125); // XXX 7515 format %{ "decq $dst\t# long" %} 7516 opcode(0xFF); /* Opcode FF /1 */ 7517 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7518 ins_pipe(ialu_mem_imm); 7519 %} 7520 7521 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7522 %{ 7523 match(Set dst (AddL src0 src1)); 7524 7525 ins_cost(110); 7526 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7527 opcode(0x8D); /* 0x8D /r */ 7528 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7529 ins_pipe(ialu_reg_reg); 7530 %} 7531 7532 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7533 %{ 7534 match(Set dst (AddP dst src)); 7535 effect(KILL cr); 7536 7537 format %{ "addq $dst, $src\t# ptr" %} 7538 opcode(0x03); 7539 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7540 ins_pipe(ialu_reg_reg); 7541 %} 7542 7543 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7544 %{ 7545 match(Set dst (AddP dst src)); 7546 effect(KILL cr); 7547 7548 format %{ "addq $dst, $src\t# ptr" %} 7549 opcode(0x81, 0x00); /* /0 id */ 7550 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7551 ins_pipe( ialu_reg ); 7552 %} 7553 7554 // XXX addP mem ops ???? 7555 7556 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7557 %{ 7558 match(Set dst (AddP src0 src1)); 7559 7560 ins_cost(110); 7561 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7562 opcode(0x8D); /* 0x8D /r */ 7563 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7564 ins_pipe(ialu_reg_reg); 7565 %} 7566 7567 instruct checkCastPP(rRegP dst) 7568 %{ 7569 match(Set dst (CheckCastPP dst)); 7570 7571 size(0); 7572 format %{ "# checkcastPP of $dst" %} 7573 ins_encode(/* empty encoding */); 7574 ins_pipe(empty); 7575 %} 7576 7577 instruct castPP(rRegP dst) 7578 %{ 7579 match(Set dst (CastPP dst)); 7580 7581 size(0); 7582 format %{ "# castPP of $dst" %} 7583 ins_encode(/* empty encoding */); 7584 ins_pipe(empty); 7585 %} 7586 7587 instruct castII(rRegI dst) 7588 %{ 7589 match(Set dst (CastII dst)); 7590 7591 size(0); 7592 format %{ "# castII of $dst" %} 7593 ins_encode(/* empty encoding */); 7594 ins_cost(0); 7595 ins_pipe(empty); 7596 %} 7597 7598 // LoadP-locked same as a regular LoadP when used with compare-swap 7599 instruct loadPLocked(rRegP dst, memory mem) 7600 %{ 7601 match(Set dst (LoadPLocked mem)); 7602 7603 ins_cost(125); // XXX 7604 format %{ "movq $dst, $mem\t# ptr locked" %} 7605 opcode(0x8B); 7606 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7607 ins_pipe(ialu_reg_mem); // XXX 7608 %} 7609 7610 // Conditional-store of the updated heap-top. 7611 // Used during allocation of the shared heap. 7612 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7613 7614 instruct storePConditional(memory heap_top_ptr, 7615 rax_RegP oldval, rRegP newval, 7616 rFlagsReg cr) 7617 %{ 7618 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7619 7620 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7621 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7622 opcode(0x0F, 0xB1); 7623 ins_encode(lock_prefix, 7624 REX_reg_mem_wide(newval, heap_top_ptr), 7625 OpcP, OpcS, 7626 reg_mem(newval, heap_top_ptr)); 7627 ins_pipe(pipe_cmpxchg); 7628 %} 7629 7630 // Conditional-store of an int value. 7631 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7632 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7633 %{ 7634 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7635 effect(KILL oldval); 7636 7637 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7638 opcode(0x0F, 0xB1); 7639 ins_encode(lock_prefix, 7640 REX_reg_mem(newval, mem), 7641 OpcP, OpcS, 7642 reg_mem(newval, mem)); 7643 ins_pipe(pipe_cmpxchg); 7644 %} 7645 7646 // Conditional-store of a long value. 7647 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7648 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7649 %{ 7650 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7651 effect(KILL oldval); 7652 7653 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7654 opcode(0x0F, 0xB1); 7655 ins_encode(lock_prefix, 7656 REX_reg_mem_wide(newval, mem), 7657 OpcP, OpcS, 7658 reg_mem(newval, mem)); 7659 ins_pipe(pipe_cmpxchg); 7660 %} 7661 7662 7663 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7664 instruct compareAndSwapP(rRegI res, 7665 memory mem_ptr, 7666 rax_RegP oldval, rRegP newval, 7667 rFlagsReg cr) 7668 %{ 7669 predicate(VM_Version::supports_cx8()); 7670 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7671 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7672 effect(KILL cr, KILL oldval); 7673 7674 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7675 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7676 "sete $res\n\t" 7677 "movzbl $res, $res" %} 7678 opcode(0x0F, 0xB1); 7679 ins_encode(lock_prefix, 7680 REX_reg_mem_wide(newval, mem_ptr), 7681 OpcP, OpcS, 7682 reg_mem(newval, mem_ptr), 7683 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7684 REX_reg_breg(res, res), // movzbl 7685 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7686 ins_pipe( pipe_cmpxchg ); 7687 %} 7688 7689 instruct compareAndSwapL(rRegI res, 7690 memory mem_ptr, 7691 rax_RegL oldval, rRegL newval, 7692 rFlagsReg cr) 7693 %{ 7694 predicate(VM_Version::supports_cx8()); 7695 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7696 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7697 effect(KILL cr, KILL oldval); 7698 7699 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7700 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7701 "sete $res\n\t" 7702 "movzbl $res, $res" %} 7703 opcode(0x0F, 0xB1); 7704 ins_encode(lock_prefix, 7705 REX_reg_mem_wide(newval, mem_ptr), 7706 OpcP, OpcS, 7707 reg_mem(newval, mem_ptr), 7708 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7709 REX_reg_breg(res, res), // movzbl 7710 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7711 ins_pipe( pipe_cmpxchg ); 7712 %} 7713 7714 instruct compareAndSwapI(rRegI res, 7715 memory mem_ptr, 7716 rax_RegI oldval, rRegI newval, 7717 rFlagsReg cr) 7718 %{ 7719 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7720 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7721 effect(KILL cr, KILL oldval); 7722 7723 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7724 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7725 "sete $res\n\t" 7726 "movzbl $res, $res" %} 7727 opcode(0x0F, 0xB1); 7728 ins_encode(lock_prefix, 7729 REX_reg_mem(newval, mem_ptr), 7730 OpcP, OpcS, 7731 reg_mem(newval, mem_ptr), 7732 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7733 REX_reg_breg(res, res), // movzbl 7734 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7735 ins_pipe( pipe_cmpxchg ); 7736 %} 7737 7738 instruct compareAndSwapB(rRegI res, 7739 memory mem_ptr, 7740 rax_RegI oldval, rRegI newval, 7741 rFlagsReg cr) 7742 %{ 7743 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7744 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7745 effect(KILL cr, KILL oldval); 7746 7747 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7748 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7749 "sete $res\n\t" 7750 "movzbl $res, $res" %} 7751 opcode(0x0F, 0xB0); 7752 ins_encode(lock_prefix, 7753 REX_breg_mem(newval, mem_ptr), 7754 OpcP, OpcS, 7755 reg_mem(newval, mem_ptr), 7756 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7757 REX_reg_breg(res, res), // movzbl 7758 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7759 ins_pipe( pipe_cmpxchg ); 7760 %} 7761 7762 instruct compareAndSwapS(rRegI res, 7763 memory mem_ptr, 7764 rax_RegI oldval, rRegI newval, 7765 rFlagsReg cr) 7766 %{ 7767 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7768 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7769 effect(KILL cr, KILL oldval); 7770 7771 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7772 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7773 "sete $res\n\t" 7774 "movzbl $res, $res" %} 7775 opcode(0x0F, 0xB1); 7776 ins_encode(lock_prefix, 7777 SizePrefix, 7778 REX_reg_mem(newval, mem_ptr), 7779 OpcP, OpcS, 7780 reg_mem(newval, mem_ptr), 7781 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7782 REX_reg_breg(res, res), // movzbl 7783 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7784 ins_pipe( pipe_cmpxchg ); 7785 %} 7786 7787 instruct compareAndSwapN(rRegI res, 7788 memory mem_ptr, 7789 rax_RegN oldval, rRegN newval, 7790 rFlagsReg cr) %{ 7791 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7792 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7793 effect(KILL cr, KILL oldval); 7794 7795 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7796 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7797 "sete $res\n\t" 7798 "movzbl $res, $res" %} 7799 opcode(0x0F, 0xB1); 7800 ins_encode(lock_prefix, 7801 REX_reg_mem(newval, mem_ptr), 7802 OpcP, OpcS, 7803 reg_mem(newval, mem_ptr), 7804 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7805 REX_reg_breg(res, res), // movzbl 7806 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7807 ins_pipe( pipe_cmpxchg ); 7808 %} 7809 7810 instruct compareAndExchangeB( 7811 memory mem_ptr, 7812 rax_RegI oldval, rRegI newval, 7813 rFlagsReg cr) 7814 %{ 7815 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7816 effect(KILL cr); 7817 7818 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7819 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7820 opcode(0x0F, 0xB0); 7821 ins_encode(lock_prefix, 7822 REX_breg_mem(newval, mem_ptr), 7823 OpcP, OpcS, 7824 reg_mem(newval, mem_ptr) // lock cmpxchg 7825 ); 7826 ins_pipe( pipe_cmpxchg ); 7827 %} 7828 7829 instruct compareAndExchangeS( 7830 memory mem_ptr, 7831 rax_RegI oldval, rRegI newval, 7832 rFlagsReg cr) 7833 %{ 7834 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7835 effect(KILL cr); 7836 7837 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7838 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7839 opcode(0x0F, 0xB1); 7840 ins_encode(lock_prefix, 7841 SizePrefix, 7842 REX_reg_mem(newval, mem_ptr), 7843 OpcP, OpcS, 7844 reg_mem(newval, mem_ptr) // lock cmpxchg 7845 ); 7846 ins_pipe( pipe_cmpxchg ); 7847 %} 7848 7849 instruct compareAndExchangeI( 7850 memory mem_ptr, 7851 rax_RegI oldval, rRegI newval, 7852 rFlagsReg cr) 7853 %{ 7854 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7855 effect(KILL cr); 7856 7857 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7858 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7859 opcode(0x0F, 0xB1); 7860 ins_encode(lock_prefix, 7861 REX_reg_mem(newval, mem_ptr), 7862 OpcP, OpcS, 7863 reg_mem(newval, mem_ptr) // lock cmpxchg 7864 ); 7865 ins_pipe( pipe_cmpxchg ); 7866 %} 7867 7868 instruct compareAndExchangeL( 7869 memory mem_ptr, 7870 rax_RegL oldval, rRegL newval, 7871 rFlagsReg cr) 7872 %{ 7873 predicate(VM_Version::supports_cx8()); 7874 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7875 effect(KILL cr); 7876 7877 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7878 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7879 opcode(0x0F, 0xB1); 7880 ins_encode(lock_prefix, 7881 REX_reg_mem_wide(newval, mem_ptr), 7882 OpcP, OpcS, 7883 reg_mem(newval, mem_ptr) // lock cmpxchg 7884 ); 7885 ins_pipe( pipe_cmpxchg ); 7886 %} 7887 7888 instruct compareAndExchangeN( 7889 memory mem_ptr, 7890 rax_RegN oldval, rRegN newval, 7891 rFlagsReg cr) %{ 7892 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7893 effect(KILL cr); 7894 7895 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7896 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7897 opcode(0x0F, 0xB1); 7898 ins_encode(lock_prefix, 7899 REX_reg_mem(newval, mem_ptr), 7900 OpcP, OpcS, 7901 reg_mem(newval, mem_ptr) // lock cmpxchg 7902 ); 7903 ins_pipe( pipe_cmpxchg ); 7904 %} 7905 7906 instruct compareAndExchangeP( 7907 memory mem_ptr, 7908 rax_RegP oldval, rRegP newval, 7909 rFlagsReg cr) 7910 %{ 7911 predicate(VM_Version::supports_cx8()); 7912 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7913 effect(KILL cr); 7914 7915 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7916 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7917 opcode(0x0F, 0xB1); 7918 ins_encode(lock_prefix, 7919 REX_reg_mem_wide(newval, mem_ptr), 7920 OpcP, OpcS, 7921 reg_mem(newval, mem_ptr) // lock cmpxchg 7922 ); 7923 ins_pipe( pipe_cmpxchg ); 7924 %} 7925 7926 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7927 predicate(n->as_LoadStore()->result_not_used()); 7928 match(Set dummy (GetAndAddB mem add)); 7929 effect(KILL cr); 7930 format %{ "ADDB [$mem],$add" %} 7931 ins_encode %{ 7932 __ lock(); 7933 __ addb($mem$$Address, $add$$constant); 7934 %} 7935 ins_pipe( pipe_cmpxchg ); 7936 %} 7937 7938 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7939 match(Set newval (GetAndAddB mem newval)); 7940 effect(KILL cr); 7941 format %{ "XADDB [$mem],$newval" %} 7942 ins_encode %{ 7943 __ lock(); 7944 __ xaddb($mem$$Address, $newval$$Register); 7945 %} 7946 ins_pipe( pipe_cmpxchg ); 7947 %} 7948 7949 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7950 predicate(n->as_LoadStore()->result_not_used()); 7951 match(Set dummy (GetAndAddS mem add)); 7952 effect(KILL cr); 7953 format %{ "ADDW [$mem],$add" %} 7954 ins_encode %{ 7955 __ lock(); 7956 __ addw($mem$$Address, $add$$constant); 7957 %} 7958 ins_pipe( pipe_cmpxchg ); 7959 %} 7960 7961 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7962 match(Set newval (GetAndAddS mem newval)); 7963 effect(KILL cr); 7964 format %{ "XADDW [$mem],$newval" %} 7965 ins_encode %{ 7966 __ lock(); 7967 __ xaddw($mem$$Address, $newval$$Register); 7968 %} 7969 ins_pipe( pipe_cmpxchg ); 7970 %} 7971 7972 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7973 predicate(n->as_LoadStore()->result_not_used()); 7974 match(Set dummy (GetAndAddI mem add)); 7975 effect(KILL cr); 7976 format %{ "ADDL [$mem],$add" %} 7977 ins_encode %{ 7978 __ lock(); 7979 __ addl($mem$$Address, $add$$constant); 7980 %} 7981 ins_pipe( pipe_cmpxchg ); 7982 %} 7983 7984 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7985 match(Set newval (GetAndAddI mem newval)); 7986 effect(KILL cr); 7987 format %{ "XADDL [$mem],$newval" %} 7988 ins_encode %{ 7989 __ lock(); 7990 __ xaddl($mem$$Address, $newval$$Register); 7991 %} 7992 ins_pipe( pipe_cmpxchg ); 7993 %} 7994 7995 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7996 predicate(n->as_LoadStore()->result_not_used()); 7997 match(Set dummy (GetAndAddL mem add)); 7998 effect(KILL cr); 7999 format %{ "ADDQ [$mem],$add" %} 8000 ins_encode %{ 8001 __ lock(); 8002 __ addq($mem$$Address, $add$$constant); 8003 %} 8004 ins_pipe( pipe_cmpxchg ); 8005 %} 8006 8007 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 8008 match(Set newval (GetAndAddL mem newval)); 8009 effect(KILL cr); 8010 format %{ "XADDQ [$mem],$newval" %} 8011 ins_encode %{ 8012 __ lock(); 8013 __ xaddq($mem$$Address, $newval$$Register); 8014 %} 8015 ins_pipe( pipe_cmpxchg ); 8016 %} 8017 8018 instruct xchgB( memory mem, rRegI newval) %{ 8019 match(Set newval (GetAndSetB mem newval)); 8020 format %{ "XCHGB $newval,[$mem]" %} 8021 ins_encode %{ 8022 __ xchgb($newval$$Register, $mem$$Address); 8023 %} 8024 ins_pipe( pipe_cmpxchg ); 8025 %} 8026 8027 instruct xchgS( memory mem, rRegI newval) %{ 8028 match(Set newval (GetAndSetS mem newval)); 8029 format %{ "XCHGW $newval,[$mem]" %} 8030 ins_encode %{ 8031 __ xchgw($newval$$Register, $mem$$Address); 8032 %} 8033 ins_pipe( pipe_cmpxchg ); 8034 %} 8035 8036 instruct xchgI( memory mem, rRegI newval) %{ 8037 match(Set newval (GetAndSetI mem newval)); 8038 format %{ "XCHGL $newval,[$mem]" %} 8039 ins_encode %{ 8040 __ xchgl($newval$$Register, $mem$$Address); 8041 %} 8042 ins_pipe( pipe_cmpxchg ); 8043 %} 8044 8045 instruct xchgL( memory mem, rRegL newval) %{ 8046 match(Set newval (GetAndSetL mem newval)); 8047 format %{ "XCHGL $newval,[$mem]" %} 8048 ins_encode %{ 8049 __ xchgq($newval$$Register, $mem$$Address); 8050 %} 8051 ins_pipe( pipe_cmpxchg ); 8052 %} 8053 8054 instruct xchgP( memory mem, rRegP newval) %{ 8055 match(Set newval (GetAndSetP mem newval)); 8056 format %{ "XCHGQ $newval,[$mem]" %} 8057 ins_encode %{ 8058 __ xchgq($newval$$Register, $mem$$Address); 8059 %} 8060 ins_pipe( pipe_cmpxchg ); 8061 %} 8062 8063 instruct xchgN( memory mem, rRegN newval) %{ 8064 match(Set newval (GetAndSetN mem newval)); 8065 format %{ "XCHGL $newval,$mem]" %} 8066 ins_encode %{ 8067 __ xchgl($newval$$Register, $mem$$Address); 8068 %} 8069 ins_pipe( pipe_cmpxchg ); 8070 %} 8071 8072 //----------Subtraction Instructions------------------------------------------- 8073 8074 // Integer Subtraction Instructions 8075 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8076 %{ 8077 match(Set dst (SubI dst src)); 8078 effect(KILL cr); 8079 8080 format %{ "subl $dst, $src\t# int" %} 8081 opcode(0x2B); 8082 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8083 ins_pipe(ialu_reg_reg); 8084 %} 8085 8086 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8087 %{ 8088 match(Set dst (SubI dst src)); 8089 effect(KILL cr); 8090 8091 format %{ "subl $dst, $src\t# int" %} 8092 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8093 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8094 ins_pipe(ialu_reg); 8095 %} 8096 8097 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8098 %{ 8099 match(Set dst (SubI dst (LoadI src))); 8100 effect(KILL cr); 8101 8102 ins_cost(125); 8103 format %{ "subl $dst, $src\t# int" %} 8104 opcode(0x2B); 8105 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8106 ins_pipe(ialu_reg_mem); 8107 %} 8108 8109 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8110 %{ 8111 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8112 effect(KILL cr); 8113 8114 ins_cost(150); 8115 format %{ "subl $dst, $src\t# int" %} 8116 opcode(0x29); /* Opcode 29 /r */ 8117 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8118 ins_pipe(ialu_mem_reg); 8119 %} 8120 8121 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8122 %{ 8123 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8124 effect(KILL cr); 8125 8126 ins_cost(125); // XXX 8127 format %{ "subl $dst, $src\t# int" %} 8128 opcode(0x81); /* Opcode 81 /5 id */ 8129 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8130 ins_pipe(ialu_mem_imm); 8131 %} 8132 8133 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8134 %{ 8135 match(Set dst (SubL dst src)); 8136 effect(KILL cr); 8137 8138 format %{ "subq $dst, $src\t# long" %} 8139 opcode(0x2B); 8140 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8141 ins_pipe(ialu_reg_reg); 8142 %} 8143 8144 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8145 %{ 8146 match(Set dst (SubL dst src)); 8147 effect(KILL cr); 8148 8149 format %{ "subq $dst, $src\t# long" %} 8150 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8151 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8152 ins_pipe(ialu_reg); 8153 %} 8154 8155 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8156 %{ 8157 match(Set dst (SubL dst (LoadL src))); 8158 effect(KILL cr); 8159 8160 ins_cost(125); 8161 format %{ "subq $dst, $src\t# long" %} 8162 opcode(0x2B); 8163 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8164 ins_pipe(ialu_reg_mem); 8165 %} 8166 8167 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8168 %{ 8169 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8170 effect(KILL cr); 8171 8172 ins_cost(150); 8173 format %{ "subq $dst, $src\t# long" %} 8174 opcode(0x29); /* Opcode 29 /r */ 8175 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8176 ins_pipe(ialu_mem_reg); 8177 %} 8178 8179 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8180 %{ 8181 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8182 effect(KILL cr); 8183 8184 ins_cost(125); // XXX 8185 format %{ "subq $dst, $src\t# long" %} 8186 opcode(0x81); /* Opcode 81 /5 id */ 8187 ins_encode(REX_mem_wide(dst), 8188 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8189 ins_pipe(ialu_mem_imm); 8190 %} 8191 8192 // Subtract from a pointer 8193 // XXX hmpf??? 8194 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8195 %{ 8196 match(Set dst (AddP dst (SubI zero src))); 8197 effect(KILL cr); 8198 8199 format %{ "subq $dst, $src\t# ptr - int" %} 8200 opcode(0x2B); 8201 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8202 ins_pipe(ialu_reg_reg); 8203 %} 8204 8205 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8206 %{ 8207 match(Set dst (SubI zero dst)); 8208 effect(KILL cr); 8209 8210 format %{ "negl $dst\t# int" %} 8211 opcode(0xF7, 0x03); // Opcode F7 /3 8212 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8213 ins_pipe(ialu_reg); 8214 %} 8215 8216 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8217 %{ 8218 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8219 effect(KILL cr); 8220 8221 format %{ "negl $dst\t# int" %} 8222 opcode(0xF7, 0x03); // Opcode F7 /3 8223 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8224 ins_pipe(ialu_reg); 8225 %} 8226 8227 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8228 %{ 8229 match(Set dst (SubL zero dst)); 8230 effect(KILL cr); 8231 8232 format %{ "negq $dst\t# long" %} 8233 opcode(0xF7, 0x03); // Opcode F7 /3 8234 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8235 ins_pipe(ialu_reg); 8236 %} 8237 8238 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8239 %{ 8240 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8241 effect(KILL cr); 8242 8243 format %{ "negq $dst\t# long" %} 8244 opcode(0xF7, 0x03); // Opcode F7 /3 8245 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8246 ins_pipe(ialu_reg); 8247 %} 8248 8249 //----------Multiplication/Division Instructions------------------------------- 8250 // Integer Multiplication Instructions 8251 // Multiply Register 8252 8253 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8254 %{ 8255 match(Set dst (MulI dst src)); 8256 effect(KILL cr); 8257 8258 ins_cost(300); 8259 format %{ "imull $dst, $src\t# int" %} 8260 opcode(0x0F, 0xAF); 8261 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8262 ins_pipe(ialu_reg_reg_alu0); 8263 %} 8264 8265 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8266 %{ 8267 match(Set dst (MulI src imm)); 8268 effect(KILL cr); 8269 8270 ins_cost(300); 8271 format %{ "imull $dst, $src, $imm\t# int" %} 8272 opcode(0x69); /* 69 /r id */ 8273 ins_encode(REX_reg_reg(dst, src), 8274 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8275 ins_pipe(ialu_reg_reg_alu0); 8276 %} 8277 8278 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8279 %{ 8280 match(Set dst (MulI dst (LoadI src))); 8281 effect(KILL cr); 8282 8283 ins_cost(350); 8284 format %{ "imull $dst, $src\t# int" %} 8285 opcode(0x0F, 0xAF); 8286 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8287 ins_pipe(ialu_reg_mem_alu0); 8288 %} 8289 8290 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8291 %{ 8292 match(Set dst (MulI (LoadI src) imm)); 8293 effect(KILL cr); 8294 8295 ins_cost(300); 8296 format %{ "imull $dst, $src, $imm\t# int" %} 8297 opcode(0x69); /* 69 /r id */ 8298 ins_encode(REX_reg_mem(dst, src), 8299 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8300 ins_pipe(ialu_reg_mem_alu0); 8301 %} 8302 8303 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8304 %{ 8305 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8306 effect(KILL cr, KILL src2); 8307 8308 expand %{ mulI_rReg(dst, src1, cr); 8309 mulI_rReg(src2, src3, cr); 8310 addI_rReg(dst, src2, cr); %} 8311 %} 8312 8313 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8314 %{ 8315 match(Set dst (MulL dst src)); 8316 effect(KILL cr); 8317 8318 ins_cost(300); 8319 format %{ "imulq $dst, $src\t# long" %} 8320 opcode(0x0F, 0xAF); 8321 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8322 ins_pipe(ialu_reg_reg_alu0); 8323 %} 8324 8325 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8326 %{ 8327 match(Set dst (MulL src imm)); 8328 effect(KILL cr); 8329 8330 ins_cost(300); 8331 format %{ "imulq $dst, $src, $imm\t# long" %} 8332 opcode(0x69); /* 69 /r id */ 8333 ins_encode(REX_reg_reg_wide(dst, src), 8334 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8335 ins_pipe(ialu_reg_reg_alu0); 8336 %} 8337 8338 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8339 %{ 8340 match(Set dst (MulL dst (LoadL src))); 8341 effect(KILL cr); 8342 8343 ins_cost(350); 8344 format %{ "imulq $dst, $src\t# long" %} 8345 opcode(0x0F, 0xAF); 8346 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8347 ins_pipe(ialu_reg_mem_alu0); 8348 %} 8349 8350 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8351 %{ 8352 match(Set dst (MulL (LoadL src) imm)); 8353 effect(KILL cr); 8354 8355 ins_cost(300); 8356 format %{ "imulq $dst, $src, $imm\t# long" %} 8357 opcode(0x69); /* 69 /r id */ 8358 ins_encode(REX_reg_mem_wide(dst, src), 8359 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8360 ins_pipe(ialu_reg_mem_alu0); 8361 %} 8362 8363 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8364 %{ 8365 match(Set dst (MulHiL src rax)); 8366 effect(USE_KILL rax, KILL cr); 8367 8368 ins_cost(300); 8369 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8370 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8371 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8372 ins_pipe(ialu_reg_reg_alu0); 8373 %} 8374 8375 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8376 rFlagsReg cr) 8377 %{ 8378 match(Set rax (DivI rax div)); 8379 effect(KILL rdx, KILL cr); 8380 8381 ins_cost(30*100+10*100); // XXX 8382 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8383 "jne,s normal\n\t" 8384 "xorl rdx, rdx\n\t" 8385 "cmpl $div, -1\n\t" 8386 "je,s done\n" 8387 "normal: cdql\n\t" 8388 "idivl $div\n" 8389 "done:" %} 8390 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8391 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8392 ins_pipe(ialu_reg_reg_alu0); 8393 %} 8394 8395 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8396 rFlagsReg cr) 8397 %{ 8398 match(Set rax (DivL rax div)); 8399 effect(KILL rdx, KILL cr); 8400 8401 ins_cost(30*100+10*100); // XXX 8402 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8403 "cmpq rax, rdx\n\t" 8404 "jne,s normal\n\t" 8405 "xorl rdx, rdx\n\t" 8406 "cmpq $div, -1\n\t" 8407 "je,s done\n" 8408 "normal: cdqq\n\t" 8409 "idivq $div\n" 8410 "done:" %} 8411 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8412 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8413 ins_pipe(ialu_reg_reg_alu0); 8414 %} 8415 8416 // Integer DIVMOD with Register, both quotient and mod results 8417 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8418 rFlagsReg cr) 8419 %{ 8420 match(DivModI rax div); 8421 effect(KILL cr); 8422 8423 ins_cost(30*100+10*100); // XXX 8424 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8425 "jne,s normal\n\t" 8426 "xorl rdx, rdx\n\t" 8427 "cmpl $div, -1\n\t" 8428 "je,s done\n" 8429 "normal: cdql\n\t" 8430 "idivl $div\n" 8431 "done:" %} 8432 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8433 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8434 ins_pipe(pipe_slow); 8435 %} 8436 8437 // Long DIVMOD with Register, both quotient and mod results 8438 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8439 rFlagsReg cr) 8440 %{ 8441 match(DivModL rax div); 8442 effect(KILL cr); 8443 8444 ins_cost(30*100+10*100); // XXX 8445 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8446 "cmpq rax, rdx\n\t" 8447 "jne,s normal\n\t" 8448 "xorl rdx, rdx\n\t" 8449 "cmpq $div, -1\n\t" 8450 "je,s done\n" 8451 "normal: cdqq\n\t" 8452 "idivq $div\n" 8453 "done:" %} 8454 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8455 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8456 ins_pipe(pipe_slow); 8457 %} 8458 8459 //----------- DivL-By-Constant-Expansions-------------------------------------- 8460 // DivI cases are handled by the compiler 8461 8462 // Magic constant, reciprocal of 10 8463 instruct loadConL_0x6666666666666667(rRegL dst) 8464 %{ 8465 effect(DEF dst); 8466 8467 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8468 ins_encode(load_immL(dst, 0x6666666666666667)); 8469 ins_pipe(ialu_reg); 8470 %} 8471 8472 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8473 %{ 8474 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8475 8476 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8477 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8478 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8479 ins_pipe(ialu_reg_reg_alu0); 8480 %} 8481 8482 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8483 %{ 8484 effect(USE_DEF dst, KILL cr); 8485 8486 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8487 opcode(0xC1, 0x7); /* C1 /7 ib */ 8488 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8489 ins_pipe(ialu_reg); 8490 %} 8491 8492 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8493 %{ 8494 effect(USE_DEF dst, KILL cr); 8495 8496 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8497 opcode(0xC1, 0x7); /* C1 /7 ib */ 8498 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8499 ins_pipe(ialu_reg); 8500 %} 8501 8502 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8503 %{ 8504 match(Set dst (DivL src div)); 8505 8506 ins_cost((5+8)*100); 8507 expand %{ 8508 rax_RegL rax; // Killed temp 8509 rFlagsReg cr; // Killed 8510 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8511 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8512 sarL_rReg_63(src, cr); // sarq src, 63 8513 sarL_rReg_2(dst, cr); // sarq rdx, 2 8514 subL_rReg(dst, src, cr); // subl rdx, src 8515 %} 8516 %} 8517 8518 //----------------------------------------------------------------------------- 8519 8520 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8521 rFlagsReg cr) 8522 %{ 8523 match(Set rdx (ModI rax div)); 8524 effect(KILL rax, KILL cr); 8525 8526 ins_cost(300); // XXX 8527 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8528 "jne,s normal\n\t" 8529 "xorl rdx, rdx\n\t" 8530 "cmpl $div, -1\n\t" 8531 "je,s done\n" 8532 "normal: cdql\n\t" 8533 "idivl $div\n" 8534 "done:" %} 8535 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8536 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8537 ins_pipe(ialu_reg_reg_alu0); 8538 %} 8539 8540 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8541 rFlagsReg cr) 8542 %{ 8543 match(Set rdx (ModL rax div)); 8544 effect(KILL rax, KILL cr); 8545 8546 ins_cost(300); // XXX 8547 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8548 "cmpq rax, rdx\n\t" 8549 "jne,s normal\n\t" 8550 "xorl rdx, rdx\n\t" 8551 "cmpq $div, -1\n\t" 8552 "je,s done\n" 8553 "normal: cdqq\n\t" 8554 "idivq $div\n" 8555 "done:" %} 8556 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8557 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8558 ins_pipe(ialu_reg_reg_alu0); 8559 %} 8560 8561 // Integer Shift Instructions 8562 // Shift Left by one 8563 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8564 %{ 8565 match(Set dst (LShiftI dst shift)); 8566 effect(KILL cr); 8567 8568 format %{ "sall $dst, $shift" %} 8569 opcode(0xD1, 0x4); /* D1 /4 */ 8570 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8571 ins_pipe(ialu_reg); 8572 %} 8573 8574 // Shift Left by one 8575 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8576 %{ 8577 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8578 effect(KILL cr); 8579 8580 format %{ "sall $dst, $shift\t" %} 8581 opcode(0xD1, 0x4); /* D1 /4 */ 8582 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8583 ins_pipe(ialu_mem_imm); 8584 %} 8585 8586 // Shift Left by 8-bit immediate 8587 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8588 %{ 8589 match(Set dst (LShiftI dst shift)); 8590 effect(KILL cr); 8591 8592 format %{ "sall $dst, $shift" %} 8593 opcode(0xC1, 0x4); /* C1 /4 ib */ 8594 ins_encode(reg_opc_imm(dst, shift)); 8595 ins_pipe(ialu_reg); 8596 %} 8597 8598 // Shift Left by 8-bit immediate 8599 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8600 %{ 8601 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8602 effect(KILL cr); 8603 8604 format %{ "sall $dst, $shift" %} 8605 opcode(0xC1, 0x4); /* C1 /4 ib */ 8606 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8607 ins_pipe(ialu_mem_imm); 8608 %} 8609 8610 // Shift Left by variable 8611 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8612 %{ 8613 match(Set dst (LShiftI dst shift)); 8614 effect(KILL cr); 8615 8616 format %{ "sall $dst, $shift" %} 8617 opcode(0xD3, 0x4); /* D3 /4 */ 8618 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8619 ins_pipe(ialu_reg_reg); 8620 %} 8621 8622 // Shift Left by variable 8623 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8624 %{ 8625 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8626 effect(KILL cr); 8627 8628 format %{ "sall $dst, $shift" %} 8629 opcode(0xD3, 0x4); /* D3 /4 */ 8630 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8631 ins_pipe(ialu_mem_reg); 8632 %} 8633 8634 // Arithmetic shift right by one 8635 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8636 %{ 8637 match(Set dst (RShiftI dst shift)); 8638 effect(KILL cr); 8639 8640 format %{ "sarl $dst, $shift" %} 8641 opcode(0xD1, 0x7); /* D1 /7 */ 8642 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8643 ins_pipe(ialu_reg); 8644 %} 8645 8646 // Arithmetic shift right by one 8647 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8648 %{ 8649 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8650 effect(KILL cr); 8651 8652 format %{ "sarl $dst, $shift" %} 8653 opcode(0xD1, 0x7); /* D1 /7 */ 8654 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8655 ins_pipe(ialu_mem_imm); 8656 %} 8657 8658 // Arithmetic Shift Right by 8-bit immediate 8659 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8660 %{ 8661 match(Set dst (RShiftI dst shift)); 8662 effect(KILL cr); 8663 8664 format %{ "sarl $dst, $shift" %} 8665 opcode(0xC1, 0x7); /* C1 /7 ib */ 8666 ins_encode(reg_opc_imm(dst, shift)); 8667 ins_pipe(ialu_mem_imm); 8668 %} 8669 8670 // Arithmetic Shift Right by 8-bit immediate 8671 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8672 %{ 8673 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8674 effect(KILL cr); 8675 8676 format %{ "sarl $dst, $shift" %} 8677 opcode(0xC1, 0x7); /* C1 /7 ib */ 8678 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8679 ins_pipe(ialu_mem_imm); 8680 %} 8681 8682 // Arithmetic Shift Right by variable 8683 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8684 %{ 8685 match(Set dst (RShiftI dst shift)); 8686 effect(KILL cr); 8687 8688 format %{ "sarl $dst, $shift" %} 8689 opcode(0xD3, 0x7); /* D3 /7 */ 8690 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8691 ins_pipe(ialu_reg_reg); 8692 %} 8693 8694 // Arithmetic Shift Right by variable 8695 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8696 %{ 8697 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8698 effect(KILL cr); 8699 8700 format %{ "sarl $dst, $shift" %} 8701 opcode(0xD3, 0x7); /* D3 /7 */ 8702 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8703 ins_pipe(ialu_mem_reg); 8704 %} 8705 8706 // Logical shift right by one 8707 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8708 %{ 8709 match(Set dst (URShiftI dst shift)); 8710 effect(KILL cr); 8711 8712 format %{ "shrl $dst, $shift" %} 8713 opcode(0xD1, 0x5); /* D1 /5 */ 8714 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8715 ins_pipe(ialu_reg); 8716 %} 8717 8718 // Logical shift right by one 8719 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8720 %{ 8721 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8722 effect(KILL cr); 8723 8724 format %{ "shrl $dst, $shift" %} 8725 opcode(0xD1, 0x5); /* D1 /5 */ 8726 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8727 ins_pipe(ialu_mem_imm); 8728 %} 8729 8730 // Logical Shift Right by 8-bit immediate 8731 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8732 %{ 8733 match(Set dst (URShiftI dst shift)); 8734 effect(KILL cr); 8735 8736 format %{ "shrl $dst, $shift" %} 8737 opcode(0xC1, 0x5); /* C1 /5 ib */ 8738 ins_encode(reg_opc_imm(dst, shift)); 8739 ins_pipe(ialu_reg); 8740 %} 8741 8742 // Logical Shift Right by 8-bit immediate 8743 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8744 %{ 8745 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8746 effect(KILL cr); 8747 8748 format %{ "shrl $dst, $shift" %} 8749 opcode(0xC1, 0x5); /* C1 /5 ib */ 8750 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8751 ins_pipe(ialu_mem_imm); 8752 %} 8753 8754 // Logical Shift Right by variable 8755 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8756 %{ 8757 match(Set dst (URShiftI dst shift)); 8758 effect(KILL cr); 8759 8760 format %{ "shrl $dst, $shift" %} 8761 opcode(0xD3, 0x5); /* D3 /5 */ 8762 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8763 ins_pipe(ialu_reg_reg); 8764 %} 8765 8766 // Logical Shift Right by variable 8767 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8768 %{ 8769 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8770 effect(KILL cr); 8771 8772 format %{ "shrl $dst, $shift" %} 8773 opcode(0xD3, 0x5); /* D3 /5 */ 8774 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8775 ins_pipe(ialu_mem_reg); 8776 %} 8777 8778 // Long Shift Instructions 8779 // Shift Left by one 8780 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8781 %{ 8782 match(Set dst (LShiftL dst shift)); 8783 effect(KILL cr); 8784 8785 format %{ "salq $dst, $shift" %} 8786 opcode(0xD1, 0x4); /* D1 /4 */ 8787 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8788 ins_pipe(ialu_reg); 8789 %} 8790 8791 // Shift Left by one 8792 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8793 %{ 8794 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8795 effect(KILL cr); 8796 8797 format %{ "salq $dst, $shift" %} 8798 opcode(0xD1, 0x4); /* D1 /4 */ 8799 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8800 ins_pipe(ialu_mem_imm); 8801 %} 8802 8803 // Shift Left by 8-bit immediate 8804 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8805 %{ 8806 match(Set dst (LShiftL dst shift)); 8807 effect(KILL cr); 8808 8809 format %{ "salq $dst, $shift" %} 8810 opcode(0xC1, 0x4); /* C1 /4 ib */ 8811 ins_encode(reg_opc_imm_wide(dst, shift)); 8812 ins_pipe(ialu_reg); 8813 %} 8814 8815 // Shift Left by 8-bit immediate 8816 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8817 %{ 8818 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8819 effect(KILL cr); 8820 8821 format %{ "salq $dst, $shift" %} 8822 opcode(0xC1, 0x4); /* C1 /4 ib */ 8823 ins_encode(REX_mem_wide(dst), OpcP, 8824 RM_opc_mem(secondary, dst), Con8or32(shift)); 8825 ins_pipe(ialu_mem_imm); 8826 %} 8827 8828 // Shift Left by variable 8829 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8830 %{ 8831 match(Set dst (LShiftL dst shift)); 8832 effect(KILL cr); 8833 8834 format %{ "salq $dst, $shift" %} 8835 opcode(0xD3, 0x4); /* D3 /4 */ 8836 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8837 ins_pipe(ialu_reg_reg); 8838 %} 8839 8840 // Shift Left by variable 8841 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8842 %{ 8843 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8844 effect(KILL cr); 8845 8846 format %{ "salq $dst, $shift" %} 8847 opcode(0xD3, 0x4); /* D3 /4 */ 8848 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8849 ins_pipe(ialu_mem_reg); 8850 %} 8851 8852 // Arithmetic shift right by one 8853 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8854 %{ 8855 match(Set dst (RShiftL dst shift)); 8856 effect(KILL cr); 8857 8858 format %{ "sarq $dst, $shift" %} 8859 opcode(0xD1, 0x7); /* D1 /7 */ 8860 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8861 ins_pipe(ialu_reg); 8862 %} 8863 8864 // Arithmetic shift right by one 8865 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8866 %{ 8867 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8868 effect(KILL cr); 8869 8870 format %{ "sarq $dst, $shift" %} 8871 opcode(0xD1, 0x7); /* D1 /7 */ 8872 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8873 ins_pipe(ialu_mem_imm); 8874 %} 8875 8876 // Arithmetic Shift Right by 8-bit immediate 8877 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8878 %{ 8879 match(Set dst (RShiftL dst shift)); 8880 effect(KILL cr); 8881 8882 format %{ "sarq $dst, $shift" %} 8883 opcode(0xC1, 0x7); /* C1 /7 ib */ 8884 ins_encode(reg_opc_imm_wide(dst, shift)); 8885 ins_pipe(ialu_mem_imm); 8886 %} 8887 8888 // Arithmetic Shift Right by 8-bit immediate 8889 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8890 %{ 8891 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8892 effect(KILL cr); 8893 8894 format %{ "sarq $dst, $shift" %} 8895 opcode(0xC1, 0x7); /* C1 /7 ib */ 8896 ins_encode(REX_mem_wide(dst), OpcP, 8897 RM_opc_mem(secondary, dst), Con8or32(shift)); 8898 ins_pipe(ialu_mem_imm); 8899 %} 8900 8901 // Arithmetic Shift Right by variable 8902 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8903 %{ 8904 match(Set dst (RShiftL dst shift)); 8905 effect(KILL cr); 8906 8907 format %{ "sarq $dst, $shift" %} 8908 opcode(0xD3, 0x7); /* D3 /7 */ 8909 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8910 ins_pipe(ialu_reg_reg); 8911 %} 8912 8913 // Arithmetic Shift Right by variable 8914 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8915 %{ 8916 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8917 effect(KILL cr); 8918 8919 format %{ "sarq $dst, $shift" %} 8920 opcode(0xD3, 0x7); /* D3 /7 */ 8921 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8922 ins_pipe(ialu_mem_reg); 8923 %} 8924 8925 // Logical shift right by one 8926 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8927 %{ 8928 match(Set dst (URShiftL dst shift)); 8929 effect(KILL cr); 8930 8931 format %{ "shrq $dst, $shift" %} 8932 opcode(0xD1, 0x5); /* D1 /5 */ 8933 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8934 ins_pipe(ialu_reg); 8935 %} 8936 8937 // Logical shift right by one 8938 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8939 %{ 8940 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8941 effect(KILL cr); 8942 8943 format %{ "shrq $dst, $shift" %} 8944 opcode(0xD1, 0x5); /* D1 /5 */ 8945 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8946 ins_pipe(ialu_mem_imm); 8947 %} 8948 8949 // Logical Shift Right by 8-bit immediate 8950 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8951 %{ 8952 match(Set dst (URShiftL dst shift)); 8953 effect(KILL cr); 8954 8955 format %{ "shrq $dst, $shift" %} 8956 opcode(0xC1, 0x5); /* C1 /5 ib */ 8957 ins_encode(reg_opc_imm_wide(dst, shift)); 8958 ins_pipe(ialu_reg); 8959 %} 8960 8961 8962 // Logical Shift Right by 8-bit immediate 8963 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8964 %{ 8965 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8966 effect(KILL cr); 8967 8968 format %{ "shrq $dst, $shift" %} 8969 opcode(0xC1, 0x5); /* C1 /5 ib */ 8970 ins_encode(REX_mem_wide(dst), OpcP, 8971 RM_opc_mem(secondary, dst), Con8or32(shift)); 8972 ins_pipe(ialu_mem_imm); 8973 %} 8974 8975 // Logical Shift Right by variable 8976 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8977 %{ 8978 match(Set dst (URShiftL dst shift)); 8979 effect(KILL cr); 8980 8981 format %{ "shrq $dst, $shift" %} 8982 opcode(0xD3, 0x5); /* D3 /5 */ 8983 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8984 ins_pipe(ialu_reg_reg); 8985 %} 8986 8987 // Logical Shift Right by variable 8988 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8989 %{ 8990 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8991 effect(KILL cr); 8992 8993 format %{ "shrq $dst, $shift" %} 8994 opcode(0xD3, 0x5); /* D3 /5 */ 8995 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8996 ins_pipe(ialu_mem_reg); 8997 %} 8998 8999 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9000 // This idiom is used by the compiler for the i2b bytecode. 9001 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9002 %{ 9003 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9004 9005 format %{ "movsbl $dst, $src\t# i2b" %} 9006 opcode(0x0F, 0xBE); 9007 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9008 ins_pipe(ialu_reg_reg); 9009 %} 9010 9011 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9012 // This idiom is used by the compiler the i2s bytecode. 9013 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9014 %{ 9015 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9016 9017 format %{ "movswl $dst, $src\t# i2s" %} 9018 opcode(0x0F, 0xBF); 9019 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9020 ins_pipe(ialu_reg_reg); 9021 %} 9022 9023 // ROL/ROR instructions 9024 9025 // ROL expand 9026 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 9027 effect(KILL cr, USE_DEF dst); 9028 9029 format %{ "roll $dst" %} 9030 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9031 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9032 ins_pipe(ialu_reg); 9033 %} 9034 9035 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 9036 effect(USE_DEF dst, USE shift, KILL cr); 9037 9038 format %{ "roll $dst, $shift" %} 9039 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9040 ins_encode( reg_opc_imm(dst, shift) ); 9041 ins_pipe(ialu_reg); 9042 %} 9043 9044 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9045 %{ 9046 effect(USE_DEF dst, USE shift, KILL cr); 9047 9048 format %{ "roll $dst, $shift" %} 9049 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9050 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9051 ins_pipe(ialu_reg_reg); 9052 %} 9053 // end of ROL expand 9054 9055 // Rotate Left by one 9056 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9057 %{ 9058 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9059 9060 expand %{ 9061 rolI_rReg_imm1(dst, cr); 9062 %} 9063 %} 9064 9065 // Rotate Left by 8-bit immediate 9066 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9067 %{ 9068 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9069 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9070 9071 expand %{ 9072 rolI_rReg_imm8(dst, lshift, cr); 9073 %} 9074 %} 9075 9076 // Rotate Left by variable 9077 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9078 %{ 9079 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9080 9081 expand %{ 9082 rolI_rReg_CL(dst, shift, cr); 9083 %} 9084 %} 9085 9086 // Rotate Left by variable 9087 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9088 %{ 9089 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9090 9091 expand %{ 9092 rolI_rReg_CL(dst, shift, cr); 9093 %} 9094 %} 9095 9096 // ROR expand 9097 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9098 %{ 9099 effect(USE_DEF dst, KILL cr); 9100 9101 format %{ "rorl $dst" %} 9102 opcode(0xD1, 0x1); /* D1 /1 */ 9103 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9104 ins_pipe(ialu_reg); 9105 %} 9106 9107 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9108 %{ 9109 effect(USE_DEF dst, USE shift, KILL cr); 9110 9111 format %{ "rorl $dst, $shift" %} 9112 opcode(0xC1, 0x1); /* C1 /1 ib */ 9113 ins_encode(reg_opc_imm(dst, shift)); 9114 ins_pipe(ialu_reg); 9115 %} 9116 9117 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9118 %{ 9119 effect(USE_DEF dst, USE shift, KILL cr); 9120 9121 format %{ "rorl $dst, $shift" %} 9122 opcode(0xD3, 0x1); /* D3 /1 */ 9123 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9124 ins_pipe(ialu_reg_reg); 9125 %} 9126 // end of ROR expand 9127 9128 // Rotate Right by one 9129 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9130 %{ 9131 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9132 9133 expand %{ 9134 rorI_rReg_imm1(dst, cr); 9135 %} 9136 %} 9137 9138 // Rotate Right by 8-bit immediate 9139 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9140 %{ 9141 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9142 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9143 9144 expand %{ 9145 rorI_rReg_imm8(dst, rshift, cr); 9146 %} 9147 %} 9148 9149 // Rotate Right by variable 9150 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9151 %{ 9152 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9153 9154 expand %{ 9155 rorI_rReg_CL(dst, shift, cr); 9156 %} 9157 %} 9158 9159 // Rotate Right by variable 9160 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9161 %{ 9162 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9163 9164 expand %{ 9165 rorI_rReg_CL(dst, shift, cr); 9166 %} 9167 %} 9168 9169 // for long rotate 9170 // ROL expand 9171 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9172 effect(USE_DEF dst, KILL cr); 9173 9174 format %{ "rolq $dst" %} 9175 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9176 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9177 ins_pipe(ialu_reg); 9178 %} 9179 9180 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9181 effect(USE_DEF dst, USE shift, KILL cr); 9182 9183 format %{ "rolq $dst, $shift" %} 9184 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9185 ins_encode( reg_opc_imm_wide(dst, shift) ); 9186 ins_pipe(ialu_reg); 9187 %} 9188 9189 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9190 %{ 9191 effect(USE_DEF dst, USE shift, KILL cr); 9192 9193 format %{ "rolq $dst, $shift" %} 9194 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9195 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9196 ins_pipe(ialu_reg_reg); 9197 %} 9198 // end of ROL expand 9199 9200 // Rotate Left by one 9201 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9202 %{ 9203 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9204 9205 expand %{ 9206 rolL_rReg_imm1(dst, cr); 9207 %} 9208 %} 9209 9210 // Rotate Left by 8-bit immediate 9211 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9212 %{ 9213 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9214 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9215 9216 expand %{ 9217 rolL_rReg_imm8(dst, lshift, cr); 9218 %} 9219 %} 9220 9221 // Rotate Left by variable 9222 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9223 %{ 9224 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9225 9226 expand %{ 9227 rolL_rReg_CL(dst, shift, cr); 9228 %} 9229 %} 9230 9231 // Rotate Left by variable 9232 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9233 %{ 9234 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9235 9236 expand %{ 9237 rolL_rReg_CL(dst, shift, cr); 9238 %} 9239 %} 9240 9241 // ROR expand 9242 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9243 %{ 9244 effect(USE_DEF dst, KILL cr); 9245 9246 format %{ "rorq $dst" %} 9247 opcode(0xD1, 0x1); /* D1 /1 */ 9248 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9249 ins_pipe(ialu_reg); 9250 %} 9251 9252 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9253 %{ 9254 effect(USE_DEF dst, USE shift, KILL cr); 9255 9256 format %{ "rorq $dst, $shift" %} 9257 opcode(0xC1, 0x1); /* C1 /1 ib */ 9258 ins_encode(reg_opc_imm_wide(dst, shift)); 9259 ins_pipe(ialu_reg); 9260 %} 9261 9262 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9263 %{ 9264 effect(USE_DEF dst, USE shift, KILL cr); 9265 9266 format %{ "rorq $dst, $shift" %} 9267 opcode(0xD3, 0x1); /* D3 /1 */ 9268 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9269 ins_pipe(ialu_reg_reg); 9270 %} 9271 // end of ROR expand 9272 9273 // Rotate Right by one 9274 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9275 %{ 9276 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9277 9278 expand %{ 9279 rorL_rReg_imm1(dst, cr); 9280 %} 9281 %} 9282 9283 // Rotate Right by 8-bit immediate 9284 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9285 %{ 9286 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9287 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9288 9289 expand %{ 9290 rorL_rReg_imm8(dst, rshift, cr); 9291 %} 9292 %} 9293 9294 // Rotate Right by variable 9295 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9296 %{ 9297 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9298 9299 expand %{ 9300 rorL_rReg_CL(dst, shift, cr); 9301 %} 9302 %} 9303 9304 // Rotate Right by variable 9305 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9306 %{ 9307 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9308 9309 expand %{ 9310 rorL_rReg_CL(dst, shift, cr); 9311 %} 9312 %} 9313 9314 // Logical Instructions 9315 9316 // Integer Logical Instructions 9317 9318 // And Instructions 9319 // And Register with Register 9320 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9321 %{ 9322 match(Set dst (AndI dst src)); 9323 effect(KILL cr); 9324 9325 format %{ "andl $dst, $src\t# int" %} 9326 opcode(0x23); 9327 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9328 ins_pipe(ialu_reg_reg); 9329 %} 9330 9331 // And Register with Immediate 255 9332 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9333 %{ 9334 match(Set dst (AndI dst src)); 9335 9336 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9337 opcode(0x0F, 0xB6); 9338 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9339 ins_pipe(ialu_reg); 9340 %} 9341 9342 // And Register with Immediate 255 and promote to long 9343 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9344 %{ 9345 match(Set dst (ConvI2L (AndI src mask))); 9346 9347 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9348 opcode(0x0F, 0xB6); 9349 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9350 ins_pipe(ialu_reg); 9351 %} 9352 9353 // And Register with Immediate 65535 9354 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9355 %{ 9356 match(Set dst (AndI dst src)); 9357 9358 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9359 opcode(0x0F, 0xB7); 9360 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9361 ins_pipe(ialu_reg); 9362 %} 9363 9364 // And Register with Immediate 65535 and promote to long 9365 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9366 %{ 9367 match(Set dst (ConvI2L (AndI src mask))); 9368 9369 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9370 opcode(0x0F, 0xB7); 9371 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9372 ins_pipe(ialu_reg); 9373 %} 9374 9375 // And Register with Immediate 9376 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9377 %{ 9378 match(Set dst (AndI dst src)); 9379 effect(KILL cr); 9380 9381 format %{ "andl $dst, $src\t# int" %} 9382 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9383 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9384 ins_pipe(ialu_reg); 9385 %} 9386 9387 // And Register with Memory 9388 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9389 %{ 9390 match(Set dst (AndI dst (LoadI src))); 9391 effect(KILL cr); 9392 9393 ins_cost(125); 9394 format %{ "andl $dst, $src\t# int" %} 9395 opcode(0x23); 9396 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9397 ins_pipe(ialu_reg_mem); 9398 %} 9399 9400 // And Memory with Register 9401 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9402 %{ 9403 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 9404 effect(KILL cr); 9405 9406 ins_cost(150); 9407 format %{ "andb $dst, $src\t# byte" %} 9408 opcode(0x20); 9409 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9410 ins_pipe(ialu_mem_reg); 9411 %} 9412 9413 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9414 %{ 9415 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9416 effect(KILL cr); 9417 9418 ins_cost(150); 9419 format %{ "andl $dst, $src\t# int" %} 9420 opcode(0x21); /* Opcode 21 /r */ 9421 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9422 ins_pipe(ialu_mem_reg); 9423 %} 9424 9425 // And Memory with Immediate 9426 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9427 %{ 9428 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9429 effect(KILL cr); 9430 9431 ins_cost(125); 9432 format %{ "andl $dst, $src\t# int" %} 9433 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9434 ins_encode(REX_mem(dst), OpcSE(src), 9435 RM_opc_mem(secondary, dst), Con8or32(src)); 9436 ins_pipe(ialu_mem_imm); 9437 %} 9438 9439 // BMI1 instructions 9440 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9441 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9442 predicate(UseBMI1Instructions); 9443 effect(KILL cr); 9444 9445 ins_cost(125); 9446 format %{ "andnl $dst, $src1, $src2" %} 9447 9448 ins_encode %{ 9449 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9450 %} 9451 ins_pipe(ialu_reg_mem); 9452 %} 9453 9454 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9455 match(Set dst (AndI (XorI src1 minus_1) src2)); 9456 predicate(UseBMI1Instructions); 9457 effect(KILL cr); 9458 9459 format %{ "andnl $dst, $src1, $src2" %} 9460 9461 ins_encode %{ 9462 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9463 %} 9464 ins_pipe(ialu_reg); 9465 %} 9466 9467 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9468 match(Set dst (AndI (SubI imm_zero src) src)); 9469 predicate(UseBMI1Instructions); 9470 effect(KILL cr); 9471 9472 format %{ "blsil $dst, $src" %} 9473 9474 ins_encode %{ 9475 __ blsil($dst$$Register, $src$$Register); 9476 %} 9477 ins_pipe(ialu_reg); 9478 %} 9479 9480 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9481 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9482 predicate(UseBMI1Instructions); 9483 effect(KILL cr); 9484 9485 ins_cost(125); 9486 format %{ "blsil $dst, $src" %} 9487 9488 ins_encode %{ 9489 __ blsil($dst$$Register, $src$$Address); 9490 %} 9491 ins_pipe(ialu_reg_mem); 9492 %} 9493 9494 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9495 %{ 9496 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9497 predicate(UseBMI1Instructions); 9498 effect(KILL cr); 9499 9500 ins_cost(125); 9501 format %{ "blsmskl $dst, $src" %} 9502 9503 ins_encode %{ 9504 __ blsmskl($dst$$Register, $src$$Address); 9505 %} 9506 ins_pipe(ialu_reg_mem); 9507 %} 9508 9509 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9510 %{ 9511 match(Set dst (XorI (AddI src minus_1) src)); 9512 predicate(UseBMI1Instructions); 9513 effect(KILL cr); 9514 9515 format %{ "blsmskl $dst, $src" %} 9516 9517 ins_encode %{ 9518 __ blsmskl($dst$$Register, $src$$Register); 9519 %} 9520 9521 ins_pipe(ialu_reg); 9522 %} 9523 9524 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9525 %{ 9526 match(Set dst (AndI (AddI src minus_1) src) ); 9527 predicate(UseBMI1Instructions); 9528 effect(KILL cr); 9529 9530 format %{ "blsrl $dst, $src" %} 9531 9532 ins_encode %{ 9533 __ blsrl($dst$$Register, $src$$Register); 9534 %} 9535 9536 ins_pipe(ialu_reg_mem); 9537 %} 9538 9539 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9540 %{ 9541 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9542 predicate(UseBMI1Instructions); 9543 effect(KILL cr); 9544 9545 ins_cost(125); 9546 format %{ "blsrl $dst, $src" %} 9547 9548 ins_encode %{ 9549 __ blsrl($dst$$Register, $src$$Address); 9550 %} 9551 9552 ins_pipe(ialu_reg); 9553 %} 9554 9555 // Or Instructions 9556 // Or Register with Register 9557 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9558 %{ 9559 match(Set dst (OrI dst src)); 9560 effect(KILL cr); 9561 9562 format %{ "orl $dst, $src\t# int" %} 9563 opcode(0x0B); 9564 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9565 ins_pipe(ialu_reg_reg); 9566 %} 9567 9568 // Or Register with Immediate 9569 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9570 %{ 9571 match(Set dst (OrI dst src)); 9572 effect(KILL cr); 9573 9574 format %{ "orl $dst, $src\t# int" %} 9575 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9576 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9577 ins_pipe(ialu_reg); 9578 %} 9579 9580 // Or Register with Memory 9581 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9582 %{ 9583 match(Set dst (OrI dst (LoadI src))); 9584 effect(KILL cr); 9585 9586 ins_cost(125); 9587 format %{ "orl $dst, $src\t# int" %} 9588 opcode(0x0B); 9589 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9590 ins_pipe(ialu_reg_mem); 9591 %} 9592 9593 // Or Memory with Register 9594 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9595 %{ 9596 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9597 effect(KILL cr); 9598 9599 ins_cost(150); 9600 format %{ "orb $dst, $src\t# byte" %} 9601 opcode(0x08); 9602 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9603 ins_pipe(ialu_mem_reg); 9604 %} 9605 9606 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9607 %{ 9608 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9609 effect(KILL cr); 9610 9611 ins_cost(150); 9612 format %{ "orl $dst, $src\t# int" %} 9613 opcode(0x09); /* Opcode 09 /r */ 9614 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9615 ins_pipe(ialu_mem_reg); 9616 %} 9617 9618 // Or Memory with Immediate 9619 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9620 %{ 9621 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9622 effect(KILL cr); 9623 9624 ins_cost(125); 9625 format %{ "orl $dst, $src\t# int" %} 9626 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9627 ins_encode(REX_mem(dst), OpcSE(src), 9628 RM_opc_mem(secondary, dst), Con8or32(src)); 9629 ins_pipe(ialu_mem_imm); 9630 %} 9631 9632 // Xor Instructions 9633 // Xor Register with Register 9634 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9635 %{ 9636 match(Set dst (XorI dst src)); 9637 effect(KILL cr); 9638 9639 format %{ "xorl $dst, $src\t# int" %} 9640 opcode(0x33); 9641 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9642 ins_pipe(ialu_reg_reg); 9643 %} 9644 9645 // Xor Register with Immediate -1 9646 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9647 match(Set dst (XorI dst imm)); 9648 9649 format %{ "not $dst" %} 9650 ins_encode %{ 9651 __ notl($dst$$Register); 9652 %} 9653 ins_pipe(ialu_reg); 9654 %} 9655 9656 // Xor Register with Immediate 9657 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9658 %{ 9659 match(Set dst (XorI dst src)); 9660 effect(KILL cr); 9661 9662 format %{ "xorl $dst, $src\t# int" %} 9663 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9664 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9665 ins_pipe(ialu_reg); 9666 %} 9667 9668 // Xor Register with Memory 9669 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9670 %{ 9671 match(Set dst (XorI dst (LoadI src))); 9672 effect(KILL cr); 9673 9674 ins_cost(125); 9675 format %{ "xorl $dst, $src\t# int" %} 9676 opcode(0x33); 9677 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9678 ins_pipe(ialu_reg_mem); 9679 %} 9680 9681 // Xor Memory with Register 9682 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9683 %{ 9684 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9685 effect(KILL cr); 9686 9687 ins_cost(150); 9688 format %{ "xorb $dst, $src\t# byte" %} 9689 opcode(0x30); 9690 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9691 ins_pipe(ialu_mem_reg); 9692 %} 9693 9694 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9695 %{ 9696 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9697 effect(KILL cr); 9698 9699 ins_cost(150); 9700 format %{ "xorl $dst, $src\t# int" %} 9701 opcode(0x31); /* Opcode 31 /r */ 9702 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9703 ins_pipe(ialu_mem_reg); 9704 %} 9705 9706 // Xor Memory with Immediate 9707 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9708 %{ 9709 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9710 effect(KILL cr); 9711 9712 ins_cost(125); 9713 format %{ "xorl $dst, $src\t# int" %} 9714 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9715 ins_encode(REX_mem(dst), OpcSE(src), 9716 RM_opc_mem(secondary, dst), Con8or32(src)); 9717 ins_pipe(ialu_mem_imm); 9718 %} 9719 9720 9721 // Long Logical Instructions 9722 9723 // And Instructions 9724 // And Register with Register 9725 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9726 %{ 9727 match(Set dst (AndL dst src)); 9728 effect(KILL cr); 9729 9730 format %{ "andq $dst, $src\t# long" %} 9731 opcode(0x23); 9732 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9733 ins_pipe(ialu_reg_reg); 9734 %} 9735 9736 // And Register with Immediate 255 9737 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9738 %{ 9739 match(Set dst (AndL dst src)); 9740 9741 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9742 opcode(0x0F, 0xB6); 9743 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9744 ins_pipe(ialu_reg); 9745 %} 9746 9747 // And Register with Immediate 65535 9748 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9749 %{ 9750 match(Set dst (AndL dst src)); 9751 9752 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9753 opcode(0x0F, 0xB7); 9754 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9755 ins_pipe(ialu_reg); 9756 %} 9757 9758 // And Register with Immediate 9759 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9760 %{ 9761 match(Set dst (AndL dst src)); 9762 effect(KILL cr); 9763 9764 format %{ "andq $dst, $src\t# long" %} 9765 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9766 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9767 ins_pipe(ialu_reg); 9768 %} 9769 9770 // And Register with Memory 9771 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9772 %{ 9773 match(Set dst (AndL dst (LoadL src))); 9774 effect(KILL cr); 9775 9776 ins_cost(125); 9777 format %{ "andq $dst, $src\t# long" %} 9778 opcode(0x23); 9779 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9780 ins_pipe(ialu_reg_mem); 9781 %} 9782 9783 // And Memory with Register 9784 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9785 %{ 9786 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9787 effect(KILL cr); 9788 9789 ins_cost(150); 9790 format %{ "andq $dst, $src\t# long" %} 9791 opcode(0x21); /* Opcode 21 /r */ 9792 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9793 ins_pipe(ialu_mem_reg); 9794 %} 9795 9796 // And Memory with Immediate 9797 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9798 %{ 9799 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9800 effect(KILL cr); 9801 9802 ins_cost(125); 9803 format %{ "andq $dst, $src\t# long" %} 9804 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9805 ins_encode(REX_mem_wide(dst), OpcSE(src), 9806 RM_opc_mem(secondary, dst), Con8or32(src)); 9807 ins_pipe(ialu_mem_imm); 9808 %} 9809 9810 // BMI1 instructions 9811 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9812 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9813 predicate(UseBMI1Instructions); 9814 effect(KILL cr); 9815 9816 ins_cost(125); 9817 format %{ "andnq $dst, $src1, $src2" %} 9818 9819 ins_encode %{ 9820 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9821 %} 9822 ins_pipe(ialu_reg_mem); 9823 %} 9824 9825 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9826 match(Set dst (AndL (XorL src1 minus_1) src2)); 9827 predicate(UseBMI1Instructions); 9828 effect(KILL cr); 9829 9830 format %{ "andnq $dst, $src1, $src2" %} 9831 9832 ins_encode %{ 9833 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9834 %} 9835 ins_pipe(ialu_reg_mem); 9836 %} 9837 9838 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9839 match(Set dst (AndL (SubL imm_zero src) src)); 9840 predicate(UseBMI1Instructions); 9841 effect(KILL cr); 9842 9843 format %{ "blsiq $dst, $src" %} 9844 9845 ins_encode %{ 9846 __ blsiq($dst$$Register, $src$$Register); 9847 %} 9848 ins_pipe(ialu_reg); 9849 %} 9850 9851 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9852 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9853 predicate(UseBMI1Instructions); 9854 effect(KILL cr); 9855 9856 ins_cost(125); 9857 format %{ "blsiq $dst, $src" %} 9858 9859 ins_encode %{ 9860 __ blsiq($dst$$Register, $src$$Address); 9861 %} 9862 ins_pipe(ialu_reg_mem); 9863 %} 9864 9865 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9866 %{ 9867 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9868 predicate(UseBMI1Instructions); 9869 effect(KILL cr); 9870 9871 ins_cost(125); 9872 format %{ "blsmskq $dst, $src" %} 9873 9874 ins_encode %{ 9875 __ blsmskq($dst$$Register, $src$$Address); 9876 %} 9877 ins_pipe(ialu_reg_mem); 9878 %} 9879 9880 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9881 %{ 9882 match(Set dst (XorL (AddL src minus_1) src)); 9883 predicate(UseBMI1Instructions); 9884 effect(KILL cr); 9885 9886 format %{ "blsmskq $dst, $src" %} 9887 9888 ins_encode %{ 9889 __ blsmskq($dst$$Register, $src$$Register); 9890 %} 9891 9892 ins_pipe(ialu_reg); 9893 %} 9894 9895 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9896 %{ 9897 match(Set dst (AndL (AddL src minus_1) src) ); 9898 predicate(UseBMI1Instructions); 9899 effect(KILL cr); 9900 9901 format %{ "blsrq $dst, $src" %} 9902 9903 ins_encode %{ 9904 __ blsrq($dst$$Register, $src$$Register); 9905 %} 9906 9907 ins_pipe(ialu_reg); 9908 %} 9909 9910 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9911 %{ 9912 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9913 predicate(UseBMI1Instructions); 9914 effect(KILL cr); 9915 9916 ins_cost(125); 9917 format %{ "blsrq $dst, $src" %} 9918 9919 ins_encode %{ 9920 __ blsrq($dst$$Register, $src$$Address); 9921 %} 9922 9923 ins_pipe(ialu_reg); 9924 %} 9925 9926 // Or Instructions 9927 // Or Register with Register 9928 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9929 %{ 9930 match(Set dst (OrL dst src)); 9931 effect(KILL cr); 9932 9933 format %{ "orq $dst, $src\t# long" %} 9934 opcode(0x0B); 9935 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9936 ins_pipe(ialu_reg_reg); 9937 %} 9938 9939 // Use any_RegP to match R15 (TLS register) without spilling. 9940 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9941 match(Set dst (OrL dst (CastP2X src))); 9942 effect(KILL cr); 9943 9944 format %{ "orq $dst, $src\t# long" %} 9945 opcode(0x0B); 9946 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9947 ins_pipe(ialu_reg_reg); 9948 %} 9949 9950 9951 // Or Register with Immediate 9952 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9953 %{ 9954 match(Set dst (OrL dst src)); 9955 effect(KILL cr); 9956 9957 format %{ "orq $dst, $src\t# long" %} 9958 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9959 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9960 ins_pipe(ialu_reg); 9961 %} 9962 9963 // Or Register with Memory 9964 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9965 %{ 9966 match(Set dst (OrL dst (LoadL src))); 9967 effect(KILL cr); 9968 9969 ins_cost(125); 9970 format %{ "orq $dst, $src\t# long" %} 9971 opcode(0x0B); 9972 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9973 ins_pipe(ialu_reg_mem); 9974 %} 9975 9976 // Or Memory with Register 9977 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9978 %{ 9979 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9980 effect(KILL cr); 9981 9982 ins_cost(150); 9983 format %{ "orq $dst, $src\t# long" %} 9984 opcode(0x09); /* Opcode 09 /r */ 9985 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9986 ins_pipe(ialu_mem_reg); 9987 %} 9988 9989 // Or Memory with Immediate 9990 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9991 %{ 9992 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9993 effect(KILL cr); 9994 9995 ins_cost(125); 9996 format %{ "orq $dst, $src\t# long" %} 9997 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9998 ins_encode(REX_mem_wide(dst), OpcSE(src), 9999 RM_opc_mem(secondary, dst), Con8or32(src)); 10000 ins_pipe(ialu_mem_imm); 10001 %} 10002 10003 // Xor Instructions 10004 // Xor Register with Register 10005 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10006 %{ 10007 match(Set dst (XorL dst src)); 10008 effect(KILL cr); 10009 10010 format %{ "xorq $dst, $src\t# long" %} 10011 opcode(0x33); 10012 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10013 ins_pipe(ialu_reg_reg); 10014 %} 10015 10016 // Xor Register with Immediate -1 10017 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 10018 match(Set dst (XorL dst imm)); 10019 10020 format %{ "notq $dst" %} 10021 ins_encode %{ 10022 __ notq($dst$$Register); 10023 %} 10024 ins_pipe(ialu_reg); 10025 %} 10026 10027 // Xor Register with Immediate 10028 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10029 %{ 10030 match(Set dst (XorL dst src)); 10031 effect(KILL cr); 10032 10033 format %{ "xorq $dst, $src\t# long" %} 10034 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 10035 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10036 ins_pipe(ialu_reg); 10037 %} 10038 10039 // Xor Register with Memory 10040 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10041 %{ 10042 match(Set dst (XorL dst (LoadL src))); 10043 effect(KILL cr); 10044 10045 ins_cost(125); 10046 format %{ "xorq $dst, $src\t# long" %} 10047 opcode(0x33); 10048 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10049 ins_pipe(ialu_reg_mem); 10050 %} 10051 10052 // Xor Memory with Register 10053 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10054 %{ 10055 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10056 effect(KILL cr); 10057 10058 ins_cost(150); 10059 format %{ "xorq $dst, $src\t# long" %} 10060 opcode(0x31); /* Opcode 31 /r */ 10061 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10062 ins_pipe(ialu_mem_reg); 10063 %} 10064 10065 // Xor Memory with Immediate 10066 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10067 %{ 10068 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10069 effect(KILL cr); 10070 10071 ins_cost(125); 10072 format %{ "xorq $dst, $src\t# long" %} 10073 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 10074 ins_encode(REX_mem_wide(dst), OpcSE(src), 10075 RM_opc_mem(secondary, dst), Con8or32(src)); 10076 ins_pipe(ialu_mem_imm); 10077 %} 10078 10079 // Convert Int to Boolean 10080 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 10081 %{ 10082 match(Set dst (Conv2B src)); 10083 effect(KILL cr); 10084 10085 format %{ "testl $src, $src\t# ci2b\n\t" 10086 "setnz $dst\n\t" 10087 "movzbl $dst, $dst" %} 10088 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10089 setNZ_reg(dst), 10090 REX_reg_breg(dst, dst), // movzbl 10091 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10092 ins_pipe(pipe_slow); // XXX 10093 %} 10094 10095 // Convert Pointer to Boolean 10096 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10097 %{ 10098 match(Set dst (Conv2B src)); 10099 effect(KILL cr); 10100 10101 format %{ "testq $src, $src\t# cp2b\n\t" 10102 "setnz $dst\n\t" 10103 "movzbl $dst, $dst" %} 10104 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10105 setNZ_reg(dst), 10106 REX_reg_breg(dst, dst), // movzbl 10107 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10108 ins_pipe(pipe_slow); // XXX 10109 %} 10110 10111 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10112 %{ 10113 match(Set dst (CmpLTMask p q)); 10114 effect(KILL cr); 10115 10116 ins_cost(400); 10117 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10118 "setlt $dst\n\t" 10119 "movzbl $dst, $dst\n\t" 10120 "negl $dst" %} 10121 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10122 setLT_reg(dst), 10123 REX_reg_breg(dst, dst), // movzbl 10124 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10125 neg_reg(dst)); 10126 ins_pipe(pipe_slow); 10127 %} 10128 10129 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10130 %{ 10131 match(Set dst (CmpLTMask dst zero)); 10132 effect(KILL cr); 10133 10134 ins_cost(100); 10135 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10136 ins_encode %{ 10137 __ sarl($dst$$Register, 31); 10138 %} 10139 ins_pipe(ialu_reg); 10140 %} 10141 10142 /* Better to save a register than avoid a branch */ 10143 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10144 %{ 10145 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10146 effect(KILL cr); 10147 ins_cost(300); 10148 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10149 "jge done\n\t" 10150 "addl $p,$y\n" 10151 "done: " %} 10152 ins_encode %{ 10153 Register Rp = $p$$Register; 10154 Register Rq = $q$$Register; 10155 Register Ry = $y$$Register; 10156 Label done; 10157 __ subl(Rp, Rq); 10158 __ jccb(Assembler::greaterEqual, done); 10159 __ addl(Rp, Ry); 10160 __ bind(done); 10161 %} 10162 ins_pipe(pipe_cmplt); 10163 %} 10164 10165 /* Better to save a register than avoid a branch */ 10166 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10167 %{ 10168 match(Set y (AndI (CmpLTMask p q) y)); 10169 effect(KILL cr); 10170 10171 ins_cost(300); 10172 10173 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10174 "jlt done\n\t" 10175 "xorl $y, $y\n" 10176 "done: " %} 10177 ins_encode %{ 10178 Register Rp = $p$$Register; 10179 Register Rq = $q$$Register; 10180 Register Ry = $y$$Register; 10181 Label done; 10182 __ cmpl(Rp, Rq); 10183 __ jccb(Assembler::less, done); 10184 __ xorl(Ry, Ry); 10185 __ bind(done); 10186 %} 10187 ins_pipe(pipe_cmplt); 10188 %} 10189 10190 10191 //---------- FP Instructions------------------------------------------------ 10192 10193 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10194 %{ 10195 match(Set cr (CmpF src1 src2)); 10196 10197 ins_cost(145); 10198 format %{ "ucomiss $src1, $src2\n\t" 10199 "jnp,s exit\n\t" 10200 "pushfq\t# saw NaN, set CF\n\t" 10201 "andq [rsp], #0xffffff2b\n\t" 10202 "popfq\n" 10203 "exit:" %} 10204 ins_encode %{ 10205 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10206 emit_cmpfp_fixup(_masm); 10207 %} 10208 ins_pipe(pipe_slow); 10209 %} 10210 10211 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10212 match(Set cr (CmpF src1 src2)); 10213 10214 ins_cost(100); 10215 format %{ "ucomiss $src1, $src2" %} 10216 ins_encode %{ 10217 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10218 %} 10219 ins_pipe(pipe_slow); 10220 %} 10221 10222 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10223 %{ 10224 match(Set cr (CmpF src1 (LoadF src2))); 10225 10226 ins_cost(145); 10227 format %{ "ucomiss $src1, $src2\n\t" 10228 "jnp,s exit\n\t" 10229 "pushfq\t# saw NaN, set CF\n\t" 10230 "andq [rsp], #0xffffff2b\n\t" 10231 "popfq\n" 10232 "exit:" %} 10233 ins_encode %{ 10234 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10235 emit_cmpfp_fixup(_masm); 10236 %} 10237 ins_pipe(pipe_slow); 10238 %} 10239 10240 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10241 match(Set cr (CmpF src1 (LoadF src2))); 10242 10243 ins_cost(100); 10244 format %{ "ucomiss $src1, $src2" %} 10245 ins_encode %{ 10246 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10247 %} 10248 ins_pipe(pipe_slow); 10249 %} 10250 10251 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10252 match(Set cr (CmpF src con)); 10253 10254 ins_cost(145); 10255 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10256 "jnp,s exit\n\t" 10257 "pushfq\t# saw NaN, set CF\n\t" 10258 "andq [rsp], #0xffffff2b\n\t" 10259 "popfq\n" 10260 "exit:" %} 10261 ins_encode %{ 10262 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10263 emit_cmpfp_fixup(_masm); 10264 %} 10265 ins_pipe(pipe_slow); 10266 %} 10267 10268 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10269 match(Set cr (CmpF src con)); 10270 ins_cost(100); 10271 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10272 ins_encode %{ 10273 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10274 %} 10275 ins_pipe(pipe_slow); 10276 %} 10277 10278 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10279 %{ 10280 match(Set cr (CmpD src1 src2)); 10281 10282 ins_cost(145); 10283 format %{ "ucomisd $src1, $src2\n\t" 10284 "jnp,s exit\n\t" 10285 "pushfq\t# saw NaN, set CF\n\t" 10286 "andq [rsp], #0xffffff2b\n\t" 10287 "popfq\n" 10288 "exit:" %} 10289 ins_encode %{ 10290 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10291 emit_cmpfp_fixup(_masm); 10292 %} 10293 ins_pipe(pipe_slow); 10294 %} 10295 10296 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10297 match(Set cr (CmpD src1 src2)); 10298 10299 ins_cost(100); 10300 format %{ "ucomisd $src1, $src2 test" %} 10301 ins_encode %{ 10302 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10303 %} 10304 ins_pipe(pipe_slow); 10305 %} 10306 10307 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10308 %{ 10309 match(Set cr (CmpD src1 (LoadD src2))); 10310 10311 ins_cost(145); 10312 format %{ "ucomisd $src1, $src2\n\t" 10313 "jnp,s exit\n\t" 10314 "pushfq\t# saw NaN, set CF\n\t" 10315 "andq [rsp], #0xffffff2b\n\t" 10316 "popfq\n" 10317 "exit:" %} 10318 ins_encode %{ 10319 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10320 emit_cmpfp_fixup(_masm); 10321 %} 10322 ins_pipe(pipe_slow); 10323 %} 10324 10325 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10326 match(Set cr (CmpD src1 (LoadD src2))); 10327 10328 ins_cost(100); 10329 format %{ "ucomisd $src1, $src2" %} 10330 ins_encode %{ 10331 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10332 %} 10333 ins_pipe(pipe_slow); 10334 %} 10335 10336 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10337 match(Set cr (CmpD src con)); 10338 10339 ins_cost(145); 10340 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10341 "jnp,s exit\n\t" 10342 "pushfq\t# saw NaN, set CF\n\t" 10343 "andq [rsp], #0xffffff2b\n\t" 10344 "popfq\n" 10345 "exit:" %} 10346 ins_encode %{ 10347 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10348 emit_cmpfp_fixup(_masm); 10349 %} 10350 ins_pipe(pipe_slow); 10351 %} 10352 10353 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10354 match(Set cr (CmpD src con)); 10355 ins_cost(100); 10356 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10357 ins_encode %{ 10358 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10359 %} 10360 ins_pipe(pipe_slow); 10361 %} 10362 10363 // Compare into -1,0,1 10364 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10365 %{ 10366 match(Set dst (CmpF3 src1 src2)); 10367 effect(KILL cr); 10368 10369 ins_cost(275); 10370 format %{ "ucomiss $src1, $src2\n\t" 10371 "movl $dst, #-1\n\t" 10372 "jp,s done\n\t" 10373 "jb,s done\n\t" 10374 "setne $dst\n\t" 10375 "movzbl $dst, $dst\n" 10376 "done:" %} 10377 ins_encode %{ 10378 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10379 emit_cmpfp3(_masm, $dst$$Register); 10380 %} 10381 ins_pipe(pipe_slow); 10382 %} 10383 10384 // Compare into -1,0,1 10385 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10386 %{ 10387 match(Set dst (CmpF3 src1 (LoadF src2))); 10388 effect(KILL cr); 10389 10390 ins_cost(275); 10391 format %{ "ucomiss $src1, $src2\n\t" 10392 "movl $dst, #-1\n\t" 10393 "jp,s done\n\t" 10394 "jb,s done\n\t" 10395 "setne $dst\n\t" 10396 "movzbl $dst, $dst\n" 10397 "done:" %} 10398 ins_encode %{ 10399 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10400 emit_cmpfp3(_masm, $dst$$Register); 10401 %} 10402 ins_pipe(pipe_slow); 10403 %} 10404 10405 // Compare into -1,0,1 10406 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10407 match(Set dst (CmpF3 src con)); 10408 effect(KILL cr); 10409 10410 ins_cost(275); 10411 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10412 "movl $dst, #-1\n\t" 10413 "jp,s done\n\t" 10414 "jb,s done\n\t" 10415 "setne $dst\n\t" 10416 "movzbl $dst, $dst\n" 10417 "done:" %} 10418 ins_encode %{ 10419 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10420 emit_cmpfp3(_masm, $dst$$Register); 10421 %} 10422 ins_pipe(pipe_slow); 10423 %} 10424 10425 // Compare into -1,0,1 10426 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10427 %{ 10428 match(Set dst (CmpD3 src1 src2)); 10429 effect(KILL cr); 10430 10431 ins_cost(275); 10432 format %{ "ucomisd $src1, $src2\n\t" 10433 "movl $dst, #-1\n\t" 10434 "jp,s done\n\t" 10435 "jb,s done\n\t" 10436 "setne $dst\n\t" 10437 "movzbl $dst, $dst\n" 10438 "done:" %} 10439 ins_encode %{ 10440 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10441 emit_cmpfp3(_masm, $dst$$Register); 10442 %} 10443 ins_pipe(pipe_slow); 10444 %} 10445 10446 // Compare into -1,0,1 10447 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10448 %{ 10449 match(Set dst (CmpD3 src1 (LoadD src2))); 10450 effect(KILL cr); 10451 10452 ins_cost(275); 10453 format %{ "ucomisd $src1, $src2\n\t" 10454 "movl $dst, #-1\n\t" 10455 "jp,s done\n\t" 10456 "jb,s done\n\t" 10457 "setne $dst\n\t" 10458 "movzbl $dst, $dst\n" 10459 "done:" %} 10460 ins_encode %{ 10461 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10462 emit_cmpfp3(_masm, $dst$$Register); 10463 %} 10464 ins_pipe(pipe_slow); 10465 %} 10466 10467 // Compare into -1,0,1 10468 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10469 match(Set dst (CmpD3 src con)); 10470 effect(KILL cr); 10471 10472 ins_cost(275); 10473 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10474 "movl $dst, #-1\n\t" 10475 "jp,s done\n\t" 10476 "jb,s done\n\t" 10477 "setne $dst\n\t" 10478 "movzbl $dst, $dst\n" 10479 "done:" %} 10480 ins_encode %{ 10481 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10482 emit_cmpfp3(_masm, $dst$$Register); 10483 %} 10484 ins_pipe(pipe_slow); 10485 %} 10486 10487 //----------Arithmetic Conversion Instructions--------------------------------- 10488 10489 instruct roundFloat_nop(regF dst) 10490 %{ 10491 match(Set dst (RoundFloat dst)); 10492 10493 ins_cost(0); 10494 ins_encode(); 10495 ins_pipe(empty); 10496 %} 10497 10498 instruct roundDouble_nop(regD dst) 10499 %{ 10500 match(Set dst (RoundDouble dst)); 10501 10502 ins_cost(0); 10503 ins_encode(); 10504 ins_pipe(empty); 10505 %} 10506 10507 instruct convF2D_reg_reg(regD dst, regF src) 10508 %{ 10509 match(Set dst (ConvF2D src)); 10510 10511 format %{ "cvtss2sd $dst, $src" %} 10512 ins_encode %{ 10513 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10514 %} 10515 ins_pipe(pipe_slow); // XXX 10516 %} 10517 10518 instruct convF2D_reg_mem(regD dst, memory src) 10519 %{ 10520 match(Set dst (ConvF2D (LoadF src))); 10521 10522 format %{ "cvtss2sd $dst, $src" %} 10523 ins_encode %{ 10524 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10525 %} 10526 ins_pipe(pipe_slow); // XXX 10527 %} 10528 10529 instruct convD2F_reg_reg(regF dst, regD src) 10530 %{ 10531 match(Set dst (ConvD2F src)); 10532 10533 format %{ "cvtsd2ss $dst, $src" %} 10534 ins_encode %{ 10535 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10536 %} 10537 ins_pipe(pipe_slow); // XXX 10538 %} 10539 10540 instruct convD2F_reg_mem(regF dst, memory src) 10541 %{ 10542 match(Set dst (ConvD2F (LoadD src))); 10543 10544 format %{ "cvtsd2ss $dst, $src" %} 10545 ins_encode %{ 10546 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10547 %} 10548 ins_pipe(pipe_slow); // XXX 10549 %} 10550 10551 // XXX do mem variants 10552 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10553 %{ 10554 match(Set dst (ConvF2I src)); 10555 effect(KILL cr); 10556 10557 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10558 "cmpl $dst, #0x80000000\n\t" 10559 "jne,s done\n\t" 10560 "subq rsp, #8\n\t" 10561 "movss [rsp], $src\n\t" 10562 "call f2i_fixup\n\t" 10563 "popq $dst\n" 10564 "done: "%} 10565 ins_encode %{ 10566 Label done; 10567 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10568 __ cmpl($dst$$Register, 0x80000000); 10569 __ jccb(Assembler::notEqual, done); 10570 __ subptr(rsp, 8); 10571 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10572 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10573 __ pop($dst$$Register); 10574 __ bind(done); 10575 %} 10576 ins_pipe(pipe_slow); 10577 %} 10578 10579 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10580 %{ 10581 match(Set dst (ConvF2L src)); 10582 effect(KILL cr); 10583 10584 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10585 "cmpq $dst, [0x8000000000000000]\n\t" 10586 "jne,s done\n\t" 10587 "subq rsp, #8\n\t" 10588 "movss [rsp], $src\n\t" 10589 "call f2l_fixup\n\t" 10590 "popq $dst\n" 10591 "done: "%} 10592 ins_encode %{ 10593 Label done; 10594 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10595 __ cmp64($dst$$Register, 10596 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10597 __ jccb(Assembler::notEqual, done); 10598 __ subptr(rsp, 8); 10599 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10600 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10601 __ pop($dst$$Register); 10602 __ bind(done); 10603 %} 10604 ins_pipe(pipe_slow); 10605 %} 10606 10607 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10608 %{ 10609 match(Set dst (ConvD2I src)); 10610 effect(KILL cr); 10611 10612 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10613 "cmpl $dst, #0x80000000\n\t" 10614 "jne,s done\n\t" 10615 "subq rsp, #8\n\t" 10616 "movsd [rsp], $src\n\t" 10617 "call d2i_fixup\n\t" 10618 "popq $dst\n" 10619 "done: "%} 10620 ins_encode %{ 10621 Label done; 10622 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10623 __ cmpl($dst$$Register, 0x80000000); 10624 __ jccb(Assembler::notEqual, done); 10625 __ subptr(rsp, 8); 10626 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10627 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10628 __ pop($dst$$Register); 10629 __ bind(done); 10630 %} 10631 ins_pipe(pipe_slow); 10632 %} 10633 10634 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10635 %{ 10636 match(Set dst (ConvD2L src)); 10637 effect(KILL cr); 10638 10639 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10640 "cmpq $dst, [0x8000000000000000]\n\t" 10641 "jne,s done\n\t" 10642 "subq rsp, #8\n\t" 10643 "movsd [rsp], $src\n\t" 10644 "call d2l_fixup\n\t" 10645 "popq $dst\n" 10646 "done: "%} 10647 ins_encode %{ 10648 Label done; 10649 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10650 __ cmp64($dst$$Register, 10651 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10652 __ jccb(Assembler::notEqual, done); 10653 __ subptr(rsp, 8); 10654 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10655 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10656 __ pop($dst$$Register); 10657 __ bind(done); 10658 %} 10659 ins_pipe(pipe_slow); 10660 %} 10661 10662 instruct convI2F_reg_reg(regF dst, rRegI src) 10663 %{ 10664 predicate(!UseXmmI2F); 10665 match(Set dst (ConvI2F src)); 10666 10667 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10668 ins_encode %{ 10669 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10670 %} 10671 ins_pipe(pipe_slow); // XXX 10672 %} 10673 10674 instruct convI2F_reg_mem(regF dst, memory src) 10675 %{ 10676 match(Set dst (ConvI2F (LoadI src))); 10677 10678 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10679 ins_encode %{ 10680 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10681 %} 10682 ins_pipe(pipe_slow); // XXX 10683 %} 10684 10685 instruct convI2D_reg_reg(regD dst, rRegI src) 10686 %{ 10687 predicate(!UseXmmI2D); 10688 match(Set dst (ConvI2D src)); 10689 10690 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10691 ins_encode %{ 10692 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10693 %} 10694 ins_pipe(pipe_slow); // XXX 10695 %} 10696 10697 instruct convI2D_reg_mem(regD dst, memory src) 10698 %{ 10699 match(Set dst (ConvI2D (LoadI src))); 10700 10701 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10702 ins_encode %{ 10703 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10704 %} 10705 ins_pipe(pipe_slow); // XXX 10706 %} 10707 10708 instruct convXI2F_reg(regF dst, rRegI src) 10709 %{ 10710 predicate(UseXmmI2F); 10711 match(Set dst (ConvI2F src)); 10712 10713 format %{ "movdl $dst, $src\n\t" 10714 "cvtdq2psl $dst, $dst\t# i2f" %} 10715 ins_encode %{ 10716 __ movdl($dst$$XMMRegister, $src$$Register); 10717 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10718 %} 10719 ins_pipe(pipe_slow); // XXX 10720 %} 10721 10722 instruct convXI2D_reg(regD dst, rRegI src) 10723 %{ 10724 predicate(UseXmmI2D); 10725 match(Set dst (ConvI2D src)); 10726 10727 format %{ "movdl $dst, $src\n\t" 10728 "cvtdq2pdl $dst, $dst\t# i2d" %} 10729 ins_encode %{ 10730 __ movdl($dst$$XMMRegister, $src$$Register); 10731 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10732 %} 10733 ins_pipe(pipe_slow); // XXX 10734 %} 10735 10736 instruct convL2F_reg_reg(regF dst, rRegL src) 10737 %{ 10738 match(Set dst (ConvL2F src)); 10739 10740 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10741 ins_encode %{ 10742 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10743 %} 10744 ins_pipe(pipe_slow); // XXX 10745 %} 10746 10747 instruct convL2F_reg_mem(regF dst, memory src) 10748 %{ 10749 match(Set dst (ConvL2F (LoadL src))); 10750 10751 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10752 ins_encode %{ 10753 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10754 %} 10755 ins_pipe(pipe_slow); // XXX 10756 %} 10757 10758 instruct convL2D_reg_reg(regD dst, rRegL src) 10759 %{ 10760 match(Set dst (ConvL2D src)); 10761 10762 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10763 ins_encode %{ 10764 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10765 %} 10766 ins_pipe(pipe_slow); // XXX 10767 %} 10768 10769 instruct convL2D_reg_mem(regD dst, memory src) 10770 %{ 10771 match(Set dst (ConvL2D (LoadL src))); 10772 10773 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10774 ins_encode %{ 10775 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10776 %} 10777 ins_pipe(pipe_slow); // XXX 10778 %} 10779 10780 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10781 %{ 10782 match(Set dst (ConvI2L src)); 10783 10784 ins_cost(125); 10785 format %{ "movslq $dst, $src\t# i2l" %} 10786 ins_encode %{ 10787 __ movslq($dst$$Register, $src$$Register); 10788 %} 10789 ins_pipe(ialu_reg_reg); 10790 %} 10791 10792 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10793 // %{ 10794 // match(Set dst (ConvI2L src)); 10795 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10796 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10797 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10798 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10799 // ((const TypeNode*) n)->type()->is_long()->_lo == 10800 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10801 10802 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10803 // ins_encode(enc_copy(dst, src)); 10804 // // opcode(0x63); // needs REX.W 10805 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10806 // ins_pipe(ialu_reg_reg); 10807 // %} 10808 10809 // Zero-extend convert int to long 10810 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10811 %{ 10812 match(Set dst (AndL (ConvI2L src) mask)); 10813 10814 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10815 ins_encode %{ 10816 if ($dst$$reg != $src$$reg) { 10817 __ movl($dst$$Register, $src$$Register); 10818 } 10819 %} 10820 ins_pipe(ialu_reg_reg); 10821 %} 10822 10823 // Zero-extend convert int to long 10824 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10825 %{ 10826 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10827 10828 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10829 ins_encode %{ 10830 __ movl($dst$$Register, $src$$Address); 10831 %} 10832 ins_pipe(ialu_reg_mem); 10833 %} 10834 10835 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10836 %{ 10837 match(Set dst (AndL src mask)); 10838 10839 format %{ "movl $dst, $src\t# zero-extend long" %} 10840 ins_encode %{ 10841 __ movl($dst$$Register, $src$$Register); 10842 %} 10843 ins_pipe(ialu_reg_reg); 10844 %} 10845 10846 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10847 %{ 10848 match(Set dst (ConvL2I src)); 10849 10850 format %{ "movl $dst, $src\t# l2i" %} 10851 ins_encode %{ 10852 __ movl($dst$$Register, $src$$Register); 10853 %} 10854 ins_pipe(ialu_reg_reg); 10855 %} 10856 10857 10858 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10859 match(Set dst (MoveF2I src)); 10860 effect(DEF dst, USE src); 10861 10862 ins_cost(125); 10863 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10864 ins_encode %{ 10865 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10866 %} 10867 ins_pipe(ialu_reg_mem); 10868 %} 10869 10870 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10871 match(Set dst (MoveI2F src)); 10872 effect(DEF dst, USE src); 10873 10874 ins_cost(125); 10875 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10876 ins_encode %{ 10877 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10878 %} 10879 ins_pipe(pipe_slow); 10880 %} 10881 10882 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10883 match(Set dst (MoveD2L src)); 10884 effect(DEF dst, USE src); 10885 10886 ins_cost(125); 10887 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10888 ins_encode %{ 10889 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10890 %} 10891 ins_pipe(ialu_reg_mem); 10892 %} 10893 10894 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10895 predicate(!UseXmmLoadAndClearUpper); 10896 match(Set dst (MoveL2D src)); 10897 effect(DEF dst, USE src); 10898 10899 ins_cost(125); 10900 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10901 ins_encode %{ 10902 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10903 %} 10904 ins_pipe(pipe_slow); 10905 %} 10906 10907 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10908 predicate(UseXmmLoadAndClearUpper); 10909 match(Set dst (MoveL2D src)); 10910 effect(DEF dst, USE src); 10911 10912 ins_cost(125); 10913 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10914 ins_encode %{ 10915 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10916 %} 10917 ins_pipe(pipe_slow); 10918 %} 10919 10920 10921 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10922 match(Set dst (MoveF2I src)); 10923 effect(DEF dst, USE src); 10924 10925 ins_cost(95); // XXX 10926 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10927 ins_encode %{ 10928 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10929 %} 10930 ins_pipe(pipe_slow); 10931 %} 10932 10933 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10934 match(Set dst (MoveI2F src)); 10935 effect(DEF dst, USE src); 10936 10937 ins_cost(100); 10938 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10939 ins_encode %{ 10940 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10941 %} 10942 ins_pipe( ialu_mem_reg ); 10943 %} 10944 10945 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10946 match(Set dst (MoveD2L src)); 10947 effect(DEF dst, USE src); 10948 10949 ins_cost(95); // XXX 10950 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10951 ins_encode %{ 10952 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10953 %} 10954 ins_pipe(pipe_slow); 10955 %} 10956 10957 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10958 match(Set dst (MoveL2D src)); 10959 effect(DEF dst, USE src); 10960 10961 ins_cost(100); 10962 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10963 ins_encode %{ 10964 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10965 %} 10966 ins_pipe(ialu_mem_reg); 10967 %} 10968 10969 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10970 match(Set dst (MoveF2I src)); 10971 effect(DEF dst, USE src); 10972 ins_cost(85); 10973 format %{ "movd $dst,$src\t# MoveF2I" %} 10974 ins_encode %{ 10975 __ movdl($dst$$Register, $src$$XMMRegister); 10976 %} 10977 ins_pipe( pipe_slow ); 10978 %} 10979 10980 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10981 match(Set dst (MoveD2L src)); 10982 effect(DEF dst, USE src); 10983 ins_cost(85); 10984 format %{ "movd $dst,$src\t# MoveD2L" %} 10985 ins_encode %{ 10986 __ movdq($dst$$Register, $src$$XMMRegister); 10987 %} 10988 ins_pipe( pipe_slow ); 10989 %} 10990 10991 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10992 match(Set dst (MoveI2F src)); 10993 effect(DEF dst, USE src); 10994 ins_cost(100); 10995 format %{ "movd $dst,$src\t# MoveI2F" %} 10996 ins_encode %{ 10997 __ movdl($dst$$XMMRegister, $src$$Register); 10998 %} 10999 ins_pipe( pipe_slow ); 11000 %} 11001 11002 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 11003 match(Set dst (MoveL2D src)); 11004 effect(DEF dst, USE src); 11005 ins_cost(100); 11006 format %{ "movd $dst,$src\t# MoveL2D" %} 11007 ins_encode %{ 11008 __ movdq($dst$$XMMRegister, $src$$Register); 11009 %} 11010 ins_pipe( pipe_slow ); 11011 %} 11012 11013 11014 // ======================================================================= 11015 // fast clearing of an array 11016 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 11017 Universe dummy, rFlagsReg cr) 11018 %{ 11019 predicate(!((ClearArrayNode*)n)->is_large()); 11020 match(Set dummy (ClearArray cnt base)); 11021 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 11022 11023 format %{ $$template 11024 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11025 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 11026 $$emit$$"jg LARGE\n\t" 11027 $$emit$$"dec rcx\n\t" 11028 $$emit$$"js DONE\t# Zero length\n\t" 11029 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 11030 $$emit$$"dec rcx\n\t" 11031 $$emit$$"jge LOOP\n\t" 11032 $$emit$$"jmp DONE\n\t" 11033 $$emit$$"# LARGE:\n\t" 11034 if (UseFastStosb) { 11035 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11036 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 11037 } else if (UseXMMForObjInit) { 11038 $$emit$$"mov rdi,rax\n\t" 11039 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 11040 $$emit$$"jmpq L_zero_64_bytes\n\t" 11041 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11042 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11043 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11044 $$emit$$"add 0x40,rax\n\t" 11045 $$emit$$"# L_zero_64_bytes:\n\t" 11046 $$emit$$"sub 0x8,rcx\n\t" 11047 $$emit$$"jge L_loop\n\t" 11048 $$emit$$"add 0x4,rcx\n\t" 11049 $$emit$$"jl L_tail\n\t" 11050 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11051 $$emit$$"add 0x20,rax\n\t" 11052 $$emit$$"sub 0x4,rcx\n\t" 11053 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11054 $$emit$$"add 0x4,rcx\n\t" 11055 $$emit$$"jle L_end\n\t" 11056 $$emit$$"dec rcx\n\t" 11057 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11058 $$emit$$"vmovq xmm0,(rax)\n\t" 11059 $$emit$$"add 0x8,rax\n\t" 11060 $$emit$$"dec rcx\n\t" 11061 $$emit$$"jge L_sloop\n\t" 11062 $$emit$$"# L_end:\n\t" 11063 } else { 11064 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 11065 } 11066 $$emit$$"# DONE" 11067 %} 11068 ins_encode %{ 11069 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11070 $tmp$$XMMRegister, false); 11071 %} 11072 ins_pipe(pipe_slow); 11073 %} 11074 11075 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 11076 Universe dummy, rFlagsReg cr) 11077 %{ 11078 predicate(((ClearArrayNode*)n)->is_large()); 11079 match(Set dummy (ClearArray cnt base)); 11080 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 11081 11082 format %{ $$template 11083 if (UseFastStosb) { 11084 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11085 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11086 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 11087 } else if (UseXMMForObjInit) { 11088 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 11089 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 11090 $$emit$$"jmpq L_zero_64_bytes\n\t" 11091 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11092 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11093 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11094 $$emit$$"add 0x40,rax\n\t" 11095 $$emit$$"# L_zero_64_bytes:\n\t" 11096 $$emit$$"sub 0x8,rcx\n\t" 11097 $$emit$$"jge L_loop\n\t" 11098 $$emit$$"add 0x4,rcx\n\t" 11099 $$emit$$"jl L_tail\n\t" 11100 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11101 $$emit$$"add 0x20,rax\n\t" 11102 $$emit$$"sub 0x4,rcx\n\t" 11103 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11104 $$emit$$"add 0x4,rcx\n\t" 11105 $$emit$$"jle L_end\n\t" 11106 $$emit$$"dec rcx\n\t" 11107 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11108 $$emit$$"vmovq xmm0,(rax)\n\t" 11109 $$emit$$"add 0x8,rax\n\t" 11110 $$emit$$"dec rcx\n\t" 11111 $$emit$$"jge L_sloop\n\t" 11112 $$emit$$"# L_end:\n\t" 11113 } else { 11114 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11115 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11116 } 11117 %} 11118 ins_encode %{ 11119 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11120 $tmp$$XMMRegister, true); 11121 %} 11122 ins_pipe(pipe_slow); 11123 %} 11124 11125 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11126 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11127 %{ 11128 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11129 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11130 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11131 11132 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11133 ins_encode %{ 11134 __ string_compare($str1$$Register, $str2$$Register, 11135 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11136 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11137 %} 11138 ins_pipe( pipe_slow ); 11139 %} 11140 11141 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11142 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11143 %{ 11144 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11145 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11146 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11147 11148 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11149 ins_encode %{ 11150 __ string_compare($str1$$Register, $str2$$Register, 11151 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11152 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11153 %} 11154 ins_pipe( pipe_slow ); 11155 %} 11156 11157 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11158 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11159 %{ 11160 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11161 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11162 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11163 11164 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11165 ins_encode %{ 11166 __ string_compare($str1$$Register, $str2$$Register, 11167 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11168 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11169 %} 11170 ins_pipe( pipe_slow ); 11171 %} 11172 11173 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11174 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11175 %{ 11176 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11177 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11178 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11179 11180 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11181 ins_encode %{ 11182 __ string_compare($str2$$Register, $str1$$Register, 11183 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11184 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11185 %} 11186 ins_pipe( pipe_slow ); 11187 %} 11188 11189 // fast search of substring with known size. 11190 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11191 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11192 %{ 11193 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11194 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11195 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11196 11197 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11198 ins_encode %{ 11199 int icnt2 = (int)$int_cnt2$$constant; 11200 if (icnt2 >= 16) { 11201 // IndexOf for constant substrings with size >= 16 elements 11202 // which don't need to be loaded through stack. 11203 __ string_indexofC8($str1$$Register, $str2$$Register, 11204 $cnt1$$Register, $cnt2$$Register, 11205 icnt2, $result$$Register, 11206 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11207 } else { 11208 // Small strings are loaded through stack if they cross page boundary. 11209 __ string_indexof($str1$$Register, $str2$$Register, 11210 $cnt1$$Register, $cnt2$$Register, 11211 icnt2, $result$$Register, 11212 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11213 } 11214 %} 11215 ins_pipe( pipe_slow ); 11216 %} 11217 11218 // fast search of substring with known size. 11219 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11220 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11221 %{ 11222 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11223 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11224 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11225 11226 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11227 ins_encode %{ 11228 int icnt2 = (int)$int_cnt2$$constant; 11229 if (icnt2 >= 8) { 11230 // IndexOf for constant substrings with size >= 8 elements 11231 // which don't need to be loaded through stack. 11232 __ string_indexofC8($str1$$Register, $str2$$Register, 11233 $cnt1$$Register, $cnt2$$Register, 11234 icnt2, $result$$Register, 11235 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11236 } else { 11237 // Small strings are loaded through stack if they cross page boundary. 11238 __ string_indexof($str1$$Register, $str2$$Register, 11239 $cnt1$$Register, $cnt2$$Register, 11240 icnt2, $result$$Register, 11241 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11242 } 11243 %} 11244 ins_pipe( pipe_slow ); 11245 %} 11246 11247 // fast search of substring with known size. 11248 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11249 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11250 %{ 11251 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11252 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11253 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11254 11255 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11256 ins_encode %{ 11257 int icnt2 = (int)$int_cnt2$$constant; 11258 if (icnt2 >= 8) { 11259 // IndexOf for constant substrings with size >= 8 elements 11260 // which don't need to be loaded through stack. 11261 __ string_indexofC8($str1$$Register, $str2$$Register, 11262 $cnt1$$Register, $cnt2$$Register, 11263 icnt2, $result$$Register, 11264 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11265 } else { 11266 // Small strings are loaded through stack if they cross page boundary. 11267 __ string_indexof($str1$$Register, $str2$$Register, 11268 $cnt1$$Register, $cnt2$$Register, 11269 icnt2, $result$$Register, 11270 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11271 } 11272 %} 11273 ins_pipe( pipe_slow ); 11274 %} 11275 11276 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11277 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11278 %{ 11279 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11280 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11281 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11282 11283 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11284 ins_encode %{ 11285 __ string_indexof($str1$$Register, $str2$$Register, 11286 $cnt1$$Register, $cnt2$$Register, 11287 (-1), $result$$Register, 11288 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11289 %} 11290 ins_pipe( pipe_slow ); 11291 %} 11292 11293 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11294 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11295 %{ 11296 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11297 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11298 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11299 11300 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11301 ins_encode %{ 11302 __ string_indexof($str1$$Register, $str2$$Register, 11303 $cnt1$$Register, $cnt2$$Register, 11304 (-1), $result$$Register, 11305 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11306 %} 11307 ins_pipe( pipe_slow ); 11308 %} 11309 11310 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11311 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11312 %{ 11313 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11314 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11315 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11316 11317 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11318 ins_encode %{ 11319 __ string_indexof($str1$$Register, $str2$$Register, 11320 $cnt1$$Register, $cnt2$$Register, 11321 (-1), $result$$Register, 11322 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11323 %} 11324 ins_pipe( pipe_slow ); 11325 %} 11326 11327 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11328 rbx_RegI result, legVecS vec1, legVecS vec2, legVecS vec3, rcx_RegI tmp, rFlagsReg cr) 11329 %{ 11330 predicate(UseSSE42Intrinsics); 11331 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11332 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11333 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11334 ins_encode %{ 11335 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11336 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11337 %} 11338 ins_pipe( pipe_slow ); 11339 %} 11340 11341 // fast string equals 11342 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11343 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11344 %{ 11345 match(Set result (StrEquals (Binary str1 str2) cnt)); 11346 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11347 11348 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11349 ins_encode %{ 11350 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11351 $cnt$$Register, $result$$Register, $tmp3$$Register, 11352 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11353 %} 11354 ins_pipe( pipe_slow ); 11355 %} 11356 11357 // fast array equals 11358 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11359 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11360 %{ 11361 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11362 match(Set result (AryEq ary1 ary2)); 11363 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11364 11365 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11366 ins_encode %{ 11367 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11368 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11369 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11370 %} 11371 ins_pipe( pipe_slow ); 11372 %} 11373 11374 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11375 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11376 %{ 11377 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11378 match(Set result (AryEq ary1 ary2)); 11379 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11380 11381 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11382 ins_encode %{ 11383 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11384 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11385 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11386 %} 11387 ins_pipe( pipe_slow ); 11388 %} 11389 11390 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11391 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11392 %{ 11393 match(Set result (HasNegatives ary1 len)); 11394 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11395 11396 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11397 ins_encode %{ 11398 __ has_negatives($ary1$$Register, $len$$Register, 11399 $result$$Register, $tmp3$$Register, 11400 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11401 %} 11402 ins_pipe( pipe_slow ); 11403 %} 11404 11405 // fast char[] to byte[] compression 11406 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11407 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11408 match(Set result (StrCompressedCopy src (Binary dst len))); 11409 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11410 11411 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11412 ins_encode %{ 11413 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11414 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11415 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11416 %} 11417 ins_pipe( pipe_slow ); 11418 %} 11419 11420 // fast byte[] to char[] inflation 11421 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11422 legVecS tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11423 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11424 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11425 11426 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11427 ins_encode %{ 11428 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11429 $tmp1$$XMMRegister, $tmp2$$Register); 11430 %} 11431 ins_pipe( pipe_slow ); 11432 %} 11433 11434 // encode char[] to byte[] in ISO_8859_1 11435 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11436 legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11437 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11438 match(Set result (EncodeISOArray src (Binary dst len))); 11439 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11440 11441 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11442 ins_encode %{ 11443 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11444 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11445 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11446 %} 11447 ins_pipe( pipe_slow ); 11448 %} 11449 11450 //----------Overflow Math Instructions----------------------------------------- 11451 11452 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11453 %{ 11454 match(Set cr (OverflowAddI op1 op2)); 11455 effect(DEF cr, USE_KILL op1, USE op2); 11456 11457 format %{ "addl $op1, $op2\t# overflow check int" %} 11458 11459 ins_encode %{ 11460 __ addl($op1$$Register, $op2$$Register); 11461 %} 11462 ins_pipe(ialu_reg_reg); 11463 %} 11464 11465 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11466 %{ 11467 match(Set cr (OverflowAddI op1 op2)); 11468 effect(DEF cr, USE_KILL op1, USE op2); 11469 11470 format %{ "addl $op1, $op2\t# overflow check int" %} 11471 11472 ins_encode %{ 11473 __ addl($op1$$Register, $op2$$constant); 11474 %} 11475 ins_pipe(ialu_reg_reg); 11476 %} 11477 11478 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11479 %{ 11480 match(Set cr (OverflowAddL op1 op2)); 11481 effect(DEF cr, USE_KILL op1, USE op2); 11482 11483 format %{ "addq $op1, $op2\t# overflow check long" %} 11484 ins_encode %{ 11485 __ addq($op1$$Register, $op2$$Register); 11486 %} 11487 ins_pipe(ialu_reg_reg); 11488 %} 11489 11490 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11491 %{ 11492 match(Set cr (OverflowAddL op1 op2)); 11493 effect(DEF cr, USE_KILL op1, USE op2); 11494 11495 format %{ "addq $op1, $op2\t# overflow check long" %} 11496 ins_encode %{ 11497 __ addq($op1$$Register, $op2$$constant); 11498 %} 11499 ins_pipe(ialu_reg_reg); 11500 %} 11501 11502 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11503 %{ 11504 match(Set cr (OverflowSubI op1 op2)); 11505 11506 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11507 ins_encode %{ 11508 __ cmpl($op1$$Register, $op2$$Register); 11509 %} 11510 ins_pipe(ialu_reg_reg); 11511 %} 11512 11513 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11514 %{ 11515 match(Set cr (OverflowSubI op1 op2)); 11516 11517 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11518 ins_encode %{ 11519 __ cmpl($op1$$Register, $op2$$constant); 11520 %} 11521 ins_pipe(ialu_reg_reg); 11522 %} 11523 11524 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11525 %{ 11526 match(Set cr (OverflowSubL op1 op2)); 11527 11528 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11529 ins_encode %{ 11530 __ cmpq($op1$$Register, $op2$$Register); 11531 %} 11532 ins_pipe(ialu_reg_reg); 11533 %} 11534 11535 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11536 %{ 11537 match(Set cr (OverflowSubL op1 op2)); 11538 11539 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11540 ins_encode %{ 11541 __ cmpq($op1$$Register, $op2$$constant); 11542 %} 11543 ins_pipe(ialu_reg_reg); 11544 %} 11545 11546 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11547 %{ 11548 match(Set cr (OverflowSubI zero op2)); 11549 effect(DEF cr, USE_KILL op2); 11550 11551 format %{ "negl $op2\t# overflow check int" %} 11552 ins_encode %{ 11553 __ negl($op2$$Register); 11554 %} 11555 ins_pipe(ialu_reg_reg); 11556 %} 11557 11558 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11559 %{ 11560 match(Set cr (OverflowSubL zero op2)); 11561 effect(DEF cr, USE_KILL op2); 11562 11563 format %{ "negq $op2\t# overflow check long" %} 11564 ins_encode %{ 11565 __ negq($op2$$Register); 11566 %} 11567 ins_pipe(ialu_reg_reg); 11568 %} 11569 11570 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11571 %{ 11572 match(Set cr (OverflowMulI op1 op2)); 11573 effect(DEF cr, USE_KILL op1, USE op2); 11574 11575 format %{ "imull $op1, $op2\t# overflow check int" %} 11576 ins_encode %{ 11577 __ imull($op1$$Register, $op2$$Register); 11578 %} 11579 ins_pipe(ialu_reg_reg_alu0); 11580 %} 11581 11582 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11583 %{ 11584 match(Set cr (OverflowMulI op1 op2)); 11585 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11586 11587 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11588 ins_encode %{ 11589 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11590 %} 11591 ins_pipe(ialu_reg_reg_alu0); 11592 %} 11593 11594 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11595 %{ 11596 match(Set cr (OverflowMulL op1 op2)); 11597 effect(DEF cr, USE_KILL op1, USE op2); 11598 11599 format %{ "imulq $op1, $op2\t# overflow check long" %} 11600 ins_encode %{ 11601 __ imulq($op1$$Register, $op2$$Register); 11602 %} 11603 ins_pipe(ialu_reg_reg_alu0); 11604 %} 11605 11606 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11607 %{ 11608 match(Set cr (OverflowMulL op1 op2)); 11609 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11610 11611 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11612 ins_encode %{ 11613 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11614 %} 11615 ins_pipe(ialu_reg_reg_alu0); 11616 %} 11617 11618 11619 //----------Control Flow Instructions------------------------------------------ 11620 // Signed compare Instructions 11621 11622 // XXX more variants!! 11623 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11624 %{ 11625 match(Set cr (CmpI op1 op2)); 11626 effect(DEF cr, USE op1, USE op2); 11627 11628 format %{ "cmpl $op1, $op2" %} 11629 opcode(0x3B); /* Opcode 3B /r */ 11630 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11631 ins_pipe(ialu_cr_reg_reg); 11632 %} 11633 11634 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11635 %{ 11636 match(Set cr (CmpI op1 op2)); 11637 11638 format %{ "cmpl $op1, $op2" %} 11639 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11640 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11641 ins_pipe(ialu_cr_reg_imm); 11642 %} 11643 11644 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11645 %{ 11646 match(Set cr (CmpI op1 (LoadI op2))); 11647 11648 ins_cost(500); // XXX 11649 format %{ "cmpl $op1, $op2" %} 11650 opcode(0x3B); /* Opcode 3B /r */ 11651 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11652 ins_pipe(ialu_cr_reg_mem); 11653 %} 11654 11655 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11656 %{ 11657 match(Set cr (CmpI src zero)); 11658 11659 format %{ "testl $src, $src" %} 11660 opcode(0x85); 11661 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11662 ins_pipe(ialu_cr_reg_imm); 11663 %} 11664 11665 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11666 %{ 11667 match(Set cr (CmpI (AndI src con) zero)); 11668 11669 format %{ "testl $src, $con" %} 11670 opcode(0xF7, 0x00); 11671 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11672 ins_pipe(ialu_cr_reg_imm); 11673 %} 11674 11675 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11676 %{ 11677 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11678 11679 format %{ "testl $src, $mem" %} 11680 opcode(0x85); 11681 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11682 ins_pipe(ialu_cr_reg_mem); 11683 %} 11684 11685 // Unsigned compare Instructions; really, same as signed except they 11686 // produce an rFlagsRegU instead of rFlagsReg. 11687 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11688 %{ 11689 match(Set cr (CmpU op1 op2)); 11690 11691 format %{ "cmpl $op1, $op2\t# unsigned" %} 11692 opcode(0x3B); /* Opcode 3B /r */ 11693 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11694 ins_pipe(ialu_cr_reg_reg); 11695 %} 11696 11697 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11698 %{ 11699 match(Set cr (CmpU op1 op2)); 11700 11701 format %{ "cmpl $op1, $op2\t# unsigned" %} 11702 opcode(0x81,0x07); /* Opcode 81 /7 */ 11703 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11704 ins_pipe(ialu_cr_reg_imm); 11705 %} 11706 11707 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11708 %{ 11709 match(Set cr (CmpU op1 (LoadI op2))); 11710 11711 ins_cost(500); // XXX 11712 format %{ "cmpl $op1, $op2\t# unsigned" %} 11713 opcode(0x3B); /* Opcode 3B /r */ 11714 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11715 ins_pipe(ialu_cr_reg_mem); 11716 %} 11717 11718 // // // Cisc-spilled version of cmpU_rReg 11719 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11720 // //%{ 11721 // // match(Set cr (CmpU (LoadI op1) op2)); 11722 // // 11723 // // format %{ "CMPu $op1,$op2" %} 11724 // // ins_cost(500); 11725 // // opcode(0x39); /* Opcode 39 /r */ 11726 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11727 // //%} 11728 11729 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11730 %{ 11731 match(Set cr (CmpU src zero)); 11732 11733 format %{ "testl $src, $src\t# unsigned" %} 11734 opcode(0x85); 11735 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11736 ins_pipe(ialu_cr_reg_imm); 11737 %} 11738 11739 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11740 %{ 11741 match(Set cr (CmpP op1 op2)); 11742 11743 format %{ "cmpq $op1, $op2\t# ptr" %} 11744 opcode(0x3B); /* Opcode 3B /r */ 11745 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11746 ins_pipe(ialu_cr_reg_reg); 11747 %} 11748 11749 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11750 %{ 11751 match(Set cr (CmpP op1 (LoadP op2))); 11752 11753 ins_cost(500); // XXX 11754 format %{ "cmpq $op1, $op2\t# ptr" %} 11755 opcode(0x3B); /* Opcode 3B /r */ 11756 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11757 ins_pipe(ialu_cr_reg_mem); 11758 %} 11759 11760 // // // Cisc-spilled version of cmpP_rReg 11761 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11762 // //%{ 11763 // // match(Set cr (CmpP (LoadP op1) op2)); 11764 // // 11765 // // format %{ "CMPu $op1,$op2" %} 11766 // // ins_cost(500); 11767 // // opcode(0x39); /* Opcode 39 /r */ 11768 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11769 // //%} 11770 11771 // XXX this is generalized by compP_rReg_mem??? 11772 // Compare raw pointer (used in out-of-heap check). 11773 // Only works because non-oop pointers must be raw pointers 11774 // and raw pointers have no anti-dependencies. 11775 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11776 %{ 11777 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11778 match(Set cr (CmpP op1 (LoadP op2))); 11779 11780 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11781 opcode(0x3B); /* Opcode 3B /r */ 11782 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11783 ins_pipe(ialu_cr_reg_mem); 11784 %} 11785 11786 // This will generate a signed flags result. This should be OK since 11787 // any compare to a zero should be eq/neq. 11788 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11789 %{ 11790 match(Set cr (CmpP src zero)); 11791 11792 format %{ "testq $src, $src\t# ptr" %} 11793 opcode(0x85); 11794 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11795 ins_pipe(ialu_cr_reg_imm); 11796 %} 11797 11798 // This will generate a signed flags result. This should be OK since 11799 // any compare to a zero should be eq/neq. 11800 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11801 %{ 11802 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11803 match(Set cr (CmpP (LoadP op) zero)); 11804 11805 ins_cost(500); // XXX 11806 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11807 opcode(0xF7); /* Opcode F7 /0 */ 11808 ins_encode(REX_mem_wide(op), 11809 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11810 ins_pipe(ialu_cr_reg_imm); 11811 %} 11812 11813 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11814 %{ 11815 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11816 match(Set cr (CmpP (LoadP mem) zero)); 11817 11818 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11819 ins_encode %{ 11820 __ cmpq(r12, $mem$$Address); 11821 %} 11822 ins_pipe(ialu_cr_reg_mem); 11823 %} 11824 11825 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11826 %{ 11827 match(Set cr (CmpN op1 op2)); 11828 11829 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11830 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11831 ins_pipe(ialu_cr_reg_reg); 11832 %} 11833 11834 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11835 %{ 11836 match(Set cr (CmpN src (LoadN mem))); 11837 11838 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11839 ins_encode %{ 11840 __ cmpl($src$$Register, $mem$$Address); 11841 %} 11842 ins_pipe(ialu_cr_reg_mem); 11843 %} 11844 11845 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11846 match(Set cr (CmpN op1 op2)); 11847 11848 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11849 ins_encode %{ 11850 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11851 %} 11852 ins_pipe(ialu_cr_reg_imm); 11853 %} 11854 11855 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11856 %{ 11857 match(Set cr (CmpN src (LoadN mem))); 11858 11859 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11860 ins_encode %{ 11861 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11862 %} 11863 ins_pipe(ialu_cr_reg_mem); 11864 %} 11865 11866 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11867 match(Set cr (CmpN op1 op2)); 11868 11869 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11870 ins_encode %{ 11871 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11872 %} 11873 ins_pipe(ialu_cr_reg_imm); 11874 %} 11875 11876 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11877 %{ 11878 match(Set cr (CmpN src (LoadNKlass mem))); 11879 11880 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11881 ins_encode %{ 11882 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11883 %} 11884 ins_pipe(ialu_cr_reg_mem); 11885 %} 11886 11887 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11888 match(Set cr (CmpN src zero)); 11889 11890 format %{ "testl $src, $src\t# compressed ptr" %} 11891 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11892 ins_pipe(ialu_cr_reg_imm); 11893 %} 11894 11895 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11896 %{ 11897 predicate(Universe::narrow_oop_base() != NULL); 11898 match(Set cr (CmpN (LoadN mem) zero)); 11899 11900 ins_cost(500); // XXX 11901 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11902 ins_encode %{ 11903 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11904 %} 11905 ins_pipe(ialu_cr_reg_mem); 11906 %} 11907 11908 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11909 %{ 11910 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11911 match(Set cr (CmpN (LoadN mem) zero)); 11912 11913 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11914 ins_encode %{ 11915 __ cmpl(r12, $mem$$Address); 11916 %} 11917 ins_pipe(ialu_cr_reg_mem); 11918 %} 11919 11920 // Yanked all unsigned pointer compare operations. 11921 // Pointer compares are done with CmpP which is already unsigned. 11922 11923 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11924 %{ 11925 match(Set cr (CmpL op1 op2)); 11926 11927 format %{ "cmpq $op1, $op2" %} 11928 opcode(0x3B); /* Opcode 3B /r */ 11929 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11930 ins_pipe(ialu_cr_reg_reg); 11931 %} 11932 11933 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11934 %{ 11935 match(Set cr (CmpL op1 op2)); 11936 11937 format %{ "cmpq $op1, $op2" %} 11938 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11939 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11940 ins_pipe(ialu_cr_reg_imm); 11941 %} 11942 11943 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11944 %{ 11945 match(Set cr (CmpL op1 (LoadL op2))); 11946 11947 format %{ "cmpq $op1, $op2" %} 11948 opcode(0x3B); /* Opcode 3B /r */ 11949 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11950 ins_pipe(ialu_cr_reg_mem); 11951 %} 11952 11953 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11954 %{ 11955 match(Set cr (CmpL src zero)); 11956 11957 format %{ "testq $src, $src" %} 11958 opcode(0x85); 11959 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11960 ins_pipe(ialu_cr_reg_imm); 11961 %} 11962 11963 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11964 %{ 11965 match(Set cr (CmpL (AndL src con) zero)); 11966 11967 format %{ "testq $src, $con\t# long" %} 11968 opcode(0xF7, 0x00); 11969 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11970 ins_pipe(ialu_cr_reg_imm); 11971 %} 11972 11973 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11974 %{ 11975 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11976 11977 format %{ "testq $src, $mem" %} 11978 opcode(0x85); 11979 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11980 ins_pipe(ialu_cr_reg_mem); 11981 %} 11982 11983 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11984 %{ 11985 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11986 11987 format %{ "testq $src, $mem" %} 11988 opcode(0x85); 11989 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11990 ins_pipe(ialu_cr_reg_mem); 11991 %} 11992 11993 // Manifest a CmpL result in an integer register. Very painful. 11994 // This is the test to avoid. 11995 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11996 %{ 11997 match(Set dst (CmpL3 src1 src2)); 11998 effect(KILL flags); 11999 12000 ins_cost(275); // XXX 12001 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12002 "movl $dst, -1\n\t" 12003 "jl,s done\n\t" 12004 "setne $dst\n\t" 12005 "movzbl $dst, $dst\n\t" 12006 "done:" %} 12007 ins_encode(cmpl3_flag(src1, src2, dst)); 12008 ins_pipe(pipe_slow); 12009 %} 12010 12011 // Unsigned long compare Instructions; really, same as signed long except they 12012 // produce an rFlagsRegU instead of rFlagsReg. 12013 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 12014 %{ 12015 match(Set cr (CmpUL op1 op2)); 12016 12017 format %{ "cmpq $op1, $op2\t# unsigned" %} 12018 opcode(0x3B); /* Opcode 3B /r */ 12019 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12020 ins_pipe(ialu_cr_reg_reg); 12021 %} 12022 12023 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 12024 %{ 12025 match(Set cr (CmpUL op1 op2)); 12026 12027 format %{ "cmpq $op1, $op2\t# unsigned" %} 12028 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12029 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12030 ins_pipe(ialu_cr_reg_imm); 12031 %} 12032 12033 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 12034 %{ 12035 match(Set cr (CmpUL op1 (LoadL op2))); 12036 12037 format %{ "cmpq $op1, $op2\t# unsigned" %} 12038 opcode(0x3B); /* Opcode 3B /r */ 12039 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12040 ins_pipe(ialu_cr_reg_mem); 12041 %} 12042 12043 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 12044 %{ 12045 match(Set cr (CmpUL src zero)); 12046 12047 format %{ "testq $src, $src\t# unsigned" %} 12048 opcode(0x85); 12049 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12050 ins_pipe(ialu_cr_reg_imm); 12051 %} 12052 12053 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 12054 %{ 12055 match(Set cr (CmpI (LoadB mem) imm)); 12056 12057 ins_cost(125); 12058 format %{ "cmpb $mem, $imm" %} 12059 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 12060 ins_pipe(ialu_cr_reg_mem); 12061 %} 12062 12063 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU8 imm, immI0 zero) 12064 %{ 12065 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 12066 12067 ins_cost(125); 12068 format %{ "testb $mem, $imm\t# ubyte" %} 12069 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12070 ins_pipe(ialu_cr_reg_mem); 12071 %} 12072 12073 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 12074 %{ 12075 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12076 12077 ins_cost(125); 12078 format %{ "testb $mem, $imm\t# byte" %} 12079 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12080 ins_pipe(ialu_cr_reg_mem); 12081 %} 12082 12083 //----------Max and Min-------------------------------------------------------- 12084 // Min Instructions 12085 12086 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12087 %{ 12088 effect(USE_DEF dst, USE src, USE cr); 12089 12090 format %{ "cmovlgt $dst, $src\t# min" %} 12091 opcode(0x0F, 0x4F); 12092 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12093 ins_pipe(pipe_cmov_reg); 12094 %} 12095 12096 12097 instruct minI_rReg(rRegI dst, rRegI src) 12098 %{ 12099 match(Set dst (MinI dst src)); 12100 12101 ins_cost(200); 12102 expand %{ 12103 rFlagsReg cr; 12104 compI_rReg(cr, dst, src); 12105 cmovI_reg_g(dst, src, cr); 12106 %} 12107 %} 12108 12109 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12110 %{ 12111 effect(USE_DEF dst, USE src, USE cr); 12112 12113 format %{ "cmovllt $dst, $src\t# max" %} 12114 opcode(0x0F, 0x4C); 12115 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12116 ins_pipe(pipe_cmov_reg); 12117 %} 12118 12119 12120 instruct maxI_rReg(rRegI dst, rRegI src) 12121 %{ 12122 match(Set dst (MaxI dst src)); 12123 12124 ins_cost(200); 12125 expand %{ 12126 rFlagsReg cr; 12127 compI_rReg(cr, dst, src); 12128 cmovI_reg_l(dst, src, cr); 12129 %} 12130 %} 12131 12132 // ============================================================================ 12133 // Branch Instructions 12134 12135 // Jump Direct - Label defines a relative address from JMP+1 12136 instruct jmpDir(label labl) 12137 %{ 12138 match(Goto); 12139 effect(USE labl); 12140 12141 ins_cost(300); 12142 format %{ "jmp $labl" %} 12143 size(5); 12144 ins_encode %{ 12145 Label* L = $labl$$label; 12146 __ jmp(*L, false); // Always long jump 12147 %} 12148 ins_pipe(pipe_jmp); 12149 %} 12150 12151 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12152 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12153 %{ 12154 match(If cop cr); 12155 effect(USE labl); 12156 12157 ins_cost(300); 12158 format %{ "j$cop $labl" %} 12159 size(6); 12160 ins_encode %{ 12161 Label* L = $labl$$label; 12162 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12163 %} 12164 ins_pipe(pipe_jcc); 12165 %} 12166 12167 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12168 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12169 %{ 12170 predicate(!n->has_vector_mask_set()); 12171 match(CountedLoopEnd cop cr); 12172 effect(USE labl); 12173 12174 ins_cost(300); 12175 format %{ "j$cop $labl\t# loop end" %} 12176 size(6); 12177 ins_encode %{ 12178 Label* L = $labl$$label; 12179 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12180 %} 12181 ins_pipe(pipe_jcc); 12182 %} 12183 12184 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12185 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12186 predicate(!n->has_vector_mask_set()); 12187 match(CountedLoopEnd cop cmp); 12188 effect(USE labl); 12189 12190 ins_cost(300); 12191 format %{ "j$cop,u $labl\t# loop end" %} 12192 size(6); 12193 ins_encode %{ 12194 Label* L = $labl$$label; 12195 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12196 %} 12197 ins_pipe(pipe_jcc); 12198 %} 12199 12200 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12201 predicate(!n->has_vector_mask_set()); 12202 match(CountedLoopEnd cop cmp); 12203 effect(USE labl); 12204 12205 ins_cost(200); 12206 format %{ "j$cop,u $labl\t# loop end" %} 12207 size(6); 12208 ins_encode %{ 12209 Label* L = $labl$$label; 12210 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12211 %} 12212 ins_pipe(pipe_jcc); 12213 %} 12214 12215 // mask version 12216 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12217 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12218 %{ 12219 predicate(n->has_vector_mask_set()); 12220 match(CountedLoopEnd cop cr); 12221 effect(USE labl); 12222 12223 ins_cost(400); 12224 format %{ "j$cop $labl\t# loop end\n\t" 12225 "restorevectmask \t# vector mask restore for loops" %} 12226 size(10); 12227 ins_encode %{ 12228 Label* L = $labl$$label; 12229 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12230 __ restorevectmask(); 12231 %} 12232 ins_pipe(pipe_jcc); 12233 %} 12234 12235 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12236 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12237 predicate(n->has_vector_mask_set()); 12238 match(CountedLoopEnd cop cmp); 12239 effect(USE labl); 12240 12241 ins_cost(400); 12242 format %{ "j$cop,u $labl\t# loop end\n\t" 12243 "restorevectmask \t# vector mask restore for loops" %} 12244 size(10); 12245 ins_encode %{ 12246 Label* L = $labl$$label; 12247 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12248 __ restorevectmask(); 12249 %} 12250 ins_pipe(pipe_jcc); 12251 %} 12252 12253 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12254 predicate(n->has_vector_mask_set()); 12255 match(CountedLoopEnd cop cmp); 12256 effect(USE labl); 12257 12258 ins_cost(300); 12259 format %{ "j$cop,u $labl\t# loop end\n\t" 12260 "restorevectmask \t# vector mask restore for loops" %} 12261 size(10); 12262 ins_encode %{ 12263 Label* L = $labl$$label; 12264 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12265 __ restorevectmask(); 12266 %} 12267 ins_pipe(pipe_jcc); 12268 %} 12269 12270 // Jump Direct Conditional - using unsigned comparison 12271 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12272 match(If cop cmp); 12273 effect(USE labl); 12274 12275 ins_cost(300); 12276 format %{ "j$cop,u $labl" %} 12277 size(6); 12278 ins_encode %{ 12279 Label* L = $labl$$label; 12280 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12281 %} 12282 ins_pipe(pipe_jcc); 12283 %} 12284 12285 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12286 match(If cop cmp); 12287 effect(USE labl); 12288 12289 ins_cost(200); 12290 format %{ "j$cop,u $labl" %} 12291 size(6); 12292 ins_encode %{ 12293 Label* L = $labl$$label; 12294 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12295 %} 12296 ins_pipe(pipe_jcc); 12297 %} 12298 12299 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12300 match(If cop cmp); 12301 effect(USE labl); 12302 12303 ins_cost(200); 12304 format %{ $$template 12305 if ($cop$$cmpcode == Assembler::notEqual) { 12306 $$emit$$"jp,u $labl\n\t" 12307 $$emit$$"j$cop,u $labl" 12308 } else { 12309 $$emit$$"jp,u done\n\t" 12310 $$emit$$"j$cop,u $labl\n\t" 12311 $$emit$$"done:" 12312 } 12313 %} 12314 ins_encode %{ 12315 Label* l = $labl$$label; 12316 if ($cop$$cmpcode == Assembler::notEqual) { 12317 __ jcc(Assembler::parity, *l, false); 12318 __ jcc(Assembler::notEqual, *l, false); 12319 } else if ($cop$$cmpcode == Assembler::equal) { 12320 Label done; 12321 __ jccb(Assembler::parity, done); 12322 __ jcc(Assembler::equal, *l, false); 12323 __ bind(done); 12324 } else { 12325 ShouldNotReachHere(); 12326 } 12327 %} 12328 ins_pipe(pipe_jcc); 12329 %} 12330 12331 // ============================================================================ 12332 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12333 // superklass array for an instance of the superklass. Set a hidden 12334 // internal cache on a hit (cache is checked with exposed code in 12335 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12336 // encoding ALSO sets flags. 12337 12338 instruct partialSubtypeCheck(rdi_RegP result, 12339 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12340 rFlagsReg cr) 12341 %{ 12342 match(Set result (PartialSubtypeCheck sub super)); 12343 effect(KILL rcx, KILL cr); 12344 12345 ins_cost(1100); // slightly larger than the next version 12346 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12347 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12348 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12349 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12350 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12351 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12352 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12353 "miss:\t" %} 12354 12355 opcode(0x1); // Force a XOR of RDI 12356 ins_encode(enc_PartialSubtypeCheck()); 12357 ins_pipe(pipe_slow); 12358 %} 12359 12360 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12361 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12362 immP0 zero, 12363 rdi_RegP result) 12364 %{ 12365 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12366 effect(KILL rcx, KILL result); 12367 12368 ins_cost(1000); 12369 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12370 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12371 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12372 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12373 "jne,s miss\t\t# Missed: flags nz\n\t" 12374 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12375 "miss:\t" %} 12376 12377 opcode(0x0); // No need to XOR RDI 12378 ins_encode(enc_PartialSubtypeCheck()); 12379 ins_pipe(pipe_slow); 12380 %} 12381 12382 // ============================================================================ 12383 // Branch Instructions -- short offset versions 12384 // 12385 // These instructions are used to replace jumps of a long offset (the default 12386 // match) with jumps of a shorter offset. These instructions are all tagged 12387 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12388 // match rules in general matching. Instead, the ADLC generates a conversion 12389 // method in the MachNode which can be used to do in-place replacement of the 12390 // long variant with the shorter variant. The compiler will determine if a 12391 // branch can be taken by the is_short_branch_offset() predicate in the machine 12392 // specific code section of the file. 12393 12394 // Jump Direct - Label defines a relative address from JMP+1 12395 instruct jmpDir_short(label labl) %{ 12396 match(Goto); 12397 effect(USE labl); 12398 12399 ins_cost(300); 12400 format %{ "jmp,s $labl" %} 12401 size(2); 12402 ins_encode %{ 12403 Label* L = $labl$$label; 12404 __ jmpb(*L); 12405 %} 12406 ins_pipe(pipe_jmp); 12407 ins_short_branch(1); 12408 %} 12409 12410 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12411 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12412 match(If cop cr); 12413 effect(USE labl); 12414 12415 ins_cost(300); 12416 format %{ "j$cop,s $labl" %} 12417 size(2); 12418 ins_encode %{ 12419 Label* L = $labl$$label; 12420 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12421 %} 12422 ins_pipe(pipe_jcc); 12423 ins_short_branch(1); 12424 %} 12425 12426 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12427 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12428 match(CountedLoopEnd cop cr); 12429 effect(USE labl); 12430 12431 ins_cost(300); 12432 format %{ "j$cop,s $labl\t# loop end" %} 12433 size(2); 12434 ins_encode %{ 12435 Label* L = $labl$$label; 12436 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12437 %} 12438 ins_pipe(pipe_jcc); 12439 ins_short_branch(1); 12440 %} 12441 12442 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12443 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12444 match(CountedLoopEnd cop cmp); 12445 effect(USE labl); 12446 12447 ins_cost(300); 12448 format %{ "j$cop,us $labl\t# loop end" %} 12449 size(2); 12450 ins_encode %{ 12451 Label* L = $labl$$label; 12452 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12453 %} 12454 ins_pipe(pipe_jcc); 12455 ins_short_branch(1); 12456 %} 12457 12458 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12459 match(CountedLoopEnd cop cmp); 12460 effect(USE labl); 12461 12462 ins_cost(300); 12463 format %{ "j$cop,us $labl\t# loop end" %} 12464 size(2); 12465 ins_encode %{ 12466 Label* L = $labl$$label; 12467 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12468 %} 12469 ins_pipe(pipe_jcc); 12470 ins_short_branch(1); 12471 %} 12472 12473 // Jump Direct Conditional - using unsigned comparison 12474 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12475 match(If cop cmp); 12476 effect(USE labl); 12477 12478 ins_cost(300); 12479 format %{ "j$cop,us $labl" %} 12480 size(2); 12481 ins_encode %{ 12482 Label* L = $labl$$label; 12483 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12484 %} 12485 ins_pipe(pipe_jcc); 12486 ins_short_branch(1); 12487 %} 12488 12489 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12490 match(If cop cmp); 12491 effect(USE labl); 12492 12493 ins_cost(300); 12494 format %{ "j$cop,us $labl" %} 12495 size(2); 12496 ins_encode %{ 12497 Label* L = $labl$$label; 12498 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12499 %} 12500 ins_pipe(pipe_jcc); 12501 ins_short_branch(1); 12502 %} 12503 12504 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12505 match(If cop cmp); 12506 effect(USE labl); 12507 12508 ins_cost(300); 12509 format %{ $$template 12510 if ($cop$$cmpcode == Assembler::notEqual) { 12511 $$emit$$"jp,u,s $labl\n\t" 12512 $$emit$$"j$cop,u,s $labl" 12513 } else { 12514 $$emit$$"jp,u,s done\n\t" 12515 $$emit$$"j$cop,u,s $labl\n\t" 12516 $$emit$$"done:" 12517 } 12518 %} 12519 size(4); 12520 ins_encode %{ 12521 Label* l = $labl$$label; 12522 if ($cop$$cmpcode == Assembler::notEqual) { 12523 __ jccb(Assembler::parity, *l); 12524 __ jccb(Assembler::notEqual, *l); 12525 } else if ($cop$$cmpcode == Assembler::equal) { 12526 Label done; 12527 __ jccb(Assembler::parity, done); 12528 __ jccb(Assembler::equal, *l); 12529 __ bind(done); 12530 } else { 12531 ShouldNotReachHere(); 12532 } 12533 %} 12534 ins_pipe(pipe_jcc); 12535 ins_short_branch(1); 12536 %} 12537 12538 // ============================================================================ 12539 // inlined locking and unlocking 12540 12541 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12542 predicate(Compile::current()->use_rtm()); 12543 match(Set cr (FastLock object box)); 12544 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12545 ins_cost(300); 12546 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12547 ins_encode %{ 12548 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12549 $scr$$Register, $cx1$$Register, $cx2$$Register, 12550 _counters, _rtm_counters, _stack_rtm_counters, 12551 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12552 true, ra_->C->profile_rtm()); 12553 %} 12554 ins_pipe(pipe_slow); 12555 %} 12556 12557 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12558 predicate(!Compile::current()->use_rtm()); 12559 match(Set cr (FastLock object box)); 12560 effect(TEMP tmp, TEMP scr, USE_KILL box); 12561 ins_cost(300); 12562 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12563 ins_encode %{ 12564 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12565 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12566 %} 12567 ins_pipe(pipe_slow); 12568 %} 12569 12570 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12571 match(Set cr (FastUnlock object box)); 12572 effect(TEMP tmp, USE_KILL box); 12573 ins_cost(300); 12574 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12575 ins_encode %{ 12576 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12577 %} 12578 ins_pipe(pipe_slow); 12579 %} 12580 12581 12582 // ============================================================================ 12583 // Safepoint Instructions 12584 instruct safePoint_poll(rFlagsReg cr) 12585 %{ 12586 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12587 match(SafePoint); 12588 effect(KILL cr); 12589 12590 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12591 "# Safepoint: poll for GC" %} 12592 ins_cost(125); 12593 ins_encode %{ 12594 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12595 __ testl(rax, addr); 12596 %} 12597 ins_pipe(ialu_reg_mem); 12598 %} 12599 12600 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12601 %{ 12602 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12603 match(SafePoint poll); 12604 effect(KILL cr, USE poll); 12605 12606 format %{ "testl rax, [$poll]\t" 12607 "# Safepoint: poll for GC" %} 12608 ins_cost(125); 12609 ins_encode %{ 12610 __ relocate(relocInfo::poll_type); 12611 __ testl(rax, Address($poll$$Register, 0)); 12612 %} 12613 ins_pipe(ialu_reg_mem); 12614 %} 12615 12616 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12617 %{ 12618 predicate(SafepointMechanism::uses_thread_local_poll()); 12619 match(SafePoint poll); 12620 effect(KILL cr, USE poll); 12621 12622 format %{ "testl rax, [$poll]\t" 12623 "# Safepoint: poll for GC" %} 12624 ins_cost(125); 12625 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12626 ins_encode %{ 12627 __ relocate(relocInfo::poll_type); 12628 address pre_pc = __ pc(); 12629 __ testl(rax, Address($poll$$Register, 0)); 12630 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12631 %} 12632 ins_pipe(ialu_reg_mem); 12633 %} 12634 12635 // ============================================================================ 12636 // Procedure Call/Return Instructions 12637 // Call Java Static Instruction 12638 // Note: If this code changes, the corresponding ret_addr_offset() and 12639 // compute_padding() functions will have to be adjusted. 12640 instruct CallStaticJavaDirect(method meth) %{ 12641 match(CallStaticJava); 12642 effect(USE meth); 12643 12644 ins_cost(300); 12645 format %{ "call,static " %} 12646 opcode(0xE8); /* E8 cd */ 12647 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12648 ins_pipe(pipe_slow); 12649 ins_alignment(4); 12650 %} 12651 12652 // Call Java Dynamic Instruction 12653 // Note: If this code changes, the corresponding ret_addr_offset() and 12654 // compute_padding() functions will have to be adjusted. 12655 instruct CallDynamicJavaDirect(method meth) 12656 %{ 12657 match(CallDynamicJava); 12658 effect(USE meth); 12659 12660 ins_cost(300); 12661 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12662 "call,dynamic " %} 12663 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12664 ins_pipe(pipe_slow); 12665 ins_alignment(4); 12666 %} 12667 12668 // Call Runtime Instruction 12669 instruct CallRuntimeDirect(method meth) 12670 %{ 12671 match(CallRuntime); 12672 effect(USE meth); 12673 12674 ins_cost(300); 12675 format %{ "call,runtime " %} 12676 ins_encode(clear_avx, Java_To_Runtime(meth)); 12677 ins_pipe(pipe_slow); 12678 %} 12679 12680 // Call runtime without safepoint 12681 instruct CallLeafDirect(method meth) 12682 %{ 12683 match(CallLeaf); 12684 effect(USE meth); 12685 12686 ins_cost(300); 12687 format %{ "call_leaf,runtime " %} 12688 ins_encode(clear_avx, Java_To_Runtime(meth)); 12689 ins_pipe(pipe_slow); 12690 %} 12691 12692 // Call runtime without safepoint 12693 instruct CallLeafNoFPDirect(method meth) 12694 %{ 12695 match(CallLeafNoFP); 12696 effect(USE meth); 12697 12698 ins_cost(300); 12699 format %{ "call_leaf_nofp,runtime " %} 12700 ins_encode(clear_avx, Java_To_Runtime(meth)); 12701 ins_pipe(pipe_slow); 12702 %} 12703 12704 // Return Instruction 12705 // Remove the return address & jump to it. 12706 // Notice: We always emit a nop after a ret to make sure there is room 12707 // for safepoint patching 12708 instruct Ret() 12709 %{ 12710 match(Return); 12711 12712 format %{ "ret" %} 12713 opcode(0xC3); 12714 ins_encode(OpcP); 12715 ins_pipe(pipe_jmp); 12716 %} 12717 12718 // Tail Call; Jump from runtime stub to Java code. 12719 // Also known as an 'interprocedural jump'. 12720 // Target of jump will eventually return to caller. 12721 // TailJump below removes the return address. 12722 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12723 %{ 12724 match(TailCall jump_target method_oop); 12725 12726 ins_cost(300); 12727 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12728 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12729 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12730 ins_pipe(pipe_jmp); 12731 %} 12732 12733 // Tail Jump; remove the return address; jump to target. 12734 // TailCall above leaves the return address around. 12735 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12736 %{ 12737 match(TailJump jump_target ex_oop); 12738 12739 ins_cost(300); 12740 format %{ "popq rdx\t# pop return address\n\t" 12741 "jmp $jump_target" %} 12742 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12743 ins_encode(Opcode(0x5a), // popq rdx 12744 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12745 ins_pipe(pipe_jmp); 12746 %} 12747 12748 // Create exception oop: created by stack-crawling runtime code. 12749 // Created exception is now available to this handler, and is setup 12750 // just prior to jumping to this handler. No code emitted. 12751 instruct CreateException(rax_RegP ex_oop) 12752 %{ 12753 match(Set ex_oop (CreateEx)); 12754 12755 size(0); 12756 // use the following format syntax 12757 format %{ "# exception oop is in rax; no code emitted" %} 12758 ins_encode(); 12759 ins_pipe(empty); 12760 %} 12761 12762 // Rethrow exception: 12763 // The exception oop will come in the first argument position. 12764 // Then JUMP (not call) to the rethrow stub code. 12765 instruct RethrowException() 12766 %{ 12767 match(Rethrow); 12768 12769 // use the following format syntax 12770 format %{ "jmp rethrow_stub" %} 12771 ins_encode(enc_rethrow); 12772 ins_pipe(pipe_jmp); 12773 %} 12774 12775 // 12776 // Execute ZGC load barrier (strong) slow path 12777 // 12778 12779 // For XMM and YMM enabled processors 12780 instruct loadBarrierSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12781 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12782 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12783 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12784 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12785 12786 match(Set dst (LoadBarrierSlowReg mem)); 12787 predicate(UseAVX <= 2); 12788 12789 effect(DEF dst, KILL cr, 12790 KILL x0, KILL x1, KILL x2, KILL x3, 12791 KILL x4, KILL x5, KILL x6, KILL x7, 12792 KILL x8, KILL x9, KILL x10, KILL x11, 12793 KILL x12, KILL x13, KILL x14, KILL x15); 12794 12795 format %{"LoadBarrierSlowRegXmmAndYmm $dst, $mem" %} 12796 ins_encode %{ 12797 #if INCLUDE_ZGC 12798 Register d = $dst$$Register; 12799 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12800 12801 assert(d != r12, "Can't be R12!"); 12802 assert(d != r15, "Can't be R15!"); 12803 assert(d != rsp, "Can't be RSP!"); 12804 12805 __ lea(d, $mem$$Address); 12806 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12807 #else 12808 ShouldNotReachHere(); 12809 #endif 12810 %} 12811 ins_pipe(pipe_slow); 12812 %} 12813 12814 // For ZMM enabled processors 12815 instruct loadBarrierSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12816 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12817 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12818 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12819 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12820 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12821 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12822 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12823 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12824 12825 match(Set dst (LoadBarrierSlowReg mem)); 12826 predicate(UseAVX == 3); 12827 12828 effect(DEF dst, KILL cr, 12829 KILL x0, KILL x1, KILL x2, KILL x3, 12830 KILL x4, KILL x5, KILL x6, KILL x7, 12831 KILL x8, KILL x9, KILL x10, KILL x11, 12832 KILL x12, KILL x13, KILL x14, KILL x15, 12833 KILL x16, KILL x17, KILL x18, KILL x19, 12834 KILL x20, KILL x21, KILL x22, KILL x23, 12835 KILL x24, KILL x25, KILL x26, KILL x27, 12836 KILL x28, KILL x29, KILL x30, KILL x31); 12837 12838 format %{"LoadBarrierSlowRegZmm $dst, $mem" %} 12839 ins_encode %{ 12840 #if INCLUDE_ZGC 12841 Register d = $dst$$Register; 12842 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12843 12844 assert(d != r12, "Can't be R12!"); 12845 assert(d != r15, "Can't be R15!"); 12846 assert(d != rsp, "Can't be RSP!"); 12847 12848 __ lea(d, $mem$$Address); 12849 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12850 #else 12851 ShouldNotReachHere(); 12852 #endif 12853 %} 12854 ins_pipe(pipe_slow); 12855 %} 12856 12857 // 12858 // Execute ZGC load barrier (weak) slow path 12859 // 12860 12861 // For XMM and YMM enabled processors 12862 instruct loadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12863 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12864 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12865 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12866 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12867 12868 match(Set dst (LoadBarrierWeakSlowReg mem)); 12869 predicate(UseAVX <= 2); 12870 12871 effect(DEF dst, KILL cr, 12872 KILL x0, KILL x1, KILL x2, KILL x3, 12873 KILL x4, KILL x5, KILL x6, KILL x7, 12874 KILL x8, KILL x9, KILL x10, KILL x11, 12875 KILL x12, KILL x13, KILL x14, KILL x15); 12876 12877 format %{"LoadBarrierWeakSlowRegXmmAndYmm $dst, $mem" %} 12878 ins_encode %{ 12879 #if INCLUDE_ZGC 12880 Register d = $dst$$Register; 12881 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12882 12883 assert(d != r12, "Can't be R12!"); 12884 assert(d != r15, "Can't be R15!"); 12885 assert(d != rsp, "Can't be RSP!"); 12886 12887 __ lea(d,$mem$$Address); 12888 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12889 #else 12890 ShouldNotReachHere(); 12891 #endif 12892 %} 12893 ins_pipe(pipe_slow); 12894 %} 12895 12896 // For ZMM enabled processors 12897 instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12898 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12899 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12900 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12901 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12902 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12903 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12904 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12905 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12906 12907 match(Set dst (LoadBarrierWeakSlowReg mem)); 12908 predicate(UseAVX == 3); 12909 12910 effect(DEF dst, KILL cr, 12911 KILL x0, KILL x1, KILL x2, KILL x3, 12912 KILL x4, KILL x5, KILL x6, KILL x7, 12913 KILL x8, KILL x9, KILL x10, KILL x11, 12914 KILL x12, KILL x13, KILL x14, KILL x15, 12915 KILL x16, KILL x17, KILL x18, KILL x19, 12916 KILL x20, KILL x21, KILL x22, KILL x23, 12917 KILL x24, KILL x25, KILL x26, KILL x27, 12918 KILL x28, KILL x29, KILL x30, KILL x31); 12919 12920 format %{"LoadBarrierWeakSlowRegZmm $dst, $mem" %} 12921 ins_encode %{ 12922 #if INCLUDE_ZGC 12923 Register d = $dst$$Register; 12924 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12925 12926 assert(d != r12, "Can't be R12!"); 12927 assert(d != r15, "Can't be R15!"); 12928 assert(d != rsp, "Can't be RSP!"); 12929 12930 __ lea(d,$mem$$Address); 12931 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12932 #else 12933 ShouldNotReachHere(); 12934 #endif 12935 %} 12936 ins_pipe(pipe_slow); 12937 %} 12938 12939 // ============================================================================ 12940 // This name is KNOWN by the ADLC and cannot be changed. 12941 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12942 // for this guy. 12943 instruct tlsLoadP(r15_RegP dst) %{ 12944 match(Set dst (ThreadLocal)); 12945 effect(DEF dst); 12946 12947 size(0); 12948 format %{ "# TLS is in R15" %} 12949 ins_encode( /*empty encoding*/ ); 12950 ins_pipe(ialu_reg_reg); 12951 %} 12952 12953 12954 //----------PEEPHOLE RULES----------------------------------------------------- 12955 // These must follow all instruction definitions as they use the names 12956 // defined in the instructions definitions. 12957 // 12958 // peepmatch ( root_instr_name [preceding_instruction]* ); 12959 // 12960 // peepconstraint %{ 12961 // (instruction_number.operand_name relational_op instruction_number.operand_name 12962 // [, ...] ); 12963 // // instruction numbers are zero-based using left to right order in peepmatch 12964 // 12965 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12966 // // provide an instruction_number.operand_name for each operand that appears 12967 // // in the replacement instruction's match rule 12968 // 12969 // ---------VM FLAGS--------------------------------------------------------- 12970 // 12971 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12972 // 12973 // Each peephole rule is given an identifying number starting with zero and 12974 // increasing by one in the order seen by the parser. An individual peephole 12975 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12976 // on the command-line. 12977 // 12978 // ---------CURRENT LIMITATIONS---------------------------------------------- 12979 // 12980 // Only match adjacent instructions in same basic block 12981 // Only equality constraints 12982 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12983 // Only one replacement instruction 12984 // 12985 // ---------EXAMPLE---------------------------------------------------------- 12986 // 12987 // // pertinent parts of existing instructions in architecture description 12988 // instruct movI(rRegI dst, rRegI src) 12989 // %{ 12990 // match(Set dst (CopyI src)); 12991 // %} 12992 // 12993 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12994 // %{ 12995 // match(Set dst (AddI dst src)); 12996 // effect(KILL cr); 12997 // %} 12998 // 12999 // // Change (inc mov) to lea 13000 // peephole %{ 13001 // // increment preceeded by register-register move 13002 // peepmatch ( incI_rReg movI ); 13003 // // require that the destination register of the increment 13004 // // match the destination register of the move 13005 // peepconstraint ( 0.dst == 1.dst ); 13006 // // construct a replacement instruction that sets 13007 // // the destination to ( move's source register + one ) 13008 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 13009 // %} 13010 // 13011 13012 // Implementation no longer uses movX instructions since 13013 // machine-independent system no longer uses CopyX nodes. 13014 // 13015 // peephole 13016 // %{ 13017 // peepmatch (incI_rReg movI); 13018 // peepconstraint (0.dst == 1.dst); 13019 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13020 // %} 13021 13022 // peephole 13023 // %{ 13024 // peepmatch (decI_rReg movI); 13025 // peepconstraint (0.dst == 1.dst); 13026 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13027 // %} 13028 13029 // peephole 13030 // %{ 13031 // peepmatch (addI_rReg_imm movI); 13032 // peepconstraint (0.dst == 1.dst); 13033 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13034 // %} 13035 13036 // peephole 13037 // %{ 13038 // peepmatch (incL_rReg movL); 13039 // peepconstraint (0.dst == 1.dst); 13040 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13041 // %} 13042 13043 // peephole 13044 // %{ 13045 // peepmatch (decL_rReg movL); 13046 // peepconstraint (0.dst == 1.dst); 13047 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13048 // %} 13049 13050 // peephole 13051 // %{ 13052 // peepmatch (addL_rReg_imm movL); 13053 // peepconstraint (0.dst == 1.dst); 13054 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13055 // %} 13056 13057 // peephole 13058 // %{ 13059 // peepmatch (addP_rReg_imm movP); 13060 // peepconstraint (0.dst == 1.dst); 13061 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 13062 // %} 13063 13064 // // Change load of spilled value to only a spill 13065 // instruct storeI(memory mem, rRegI src) 13066 // %{ 13067 // match(Set mem (StoreI mem src)); 13068 // %} 13069 // 13070 // instruct loadI(rRegI dst, memory mem) 13071 // %{ 13072 // match(Set dst (LoadI mem)); 13073 // %} 13074 // 13075 13076 peephole 13077 %{ 13078 peepmatch (loadI storeI); 13079 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13080 peepreplace (storeI(1.mem 1.mem 1.src)); 13081 %} 13082 13083 peephole 13084 %{ 13085 peepmatch (loadL storeL); 13086 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13087 peepreplace (storeL(1.mem 1.mem 1.src)); 13088 %} 13089 13090 //----------SMARTSPILL RULES--------------------------------------------------- 13091 // These must follow all instruction definitions as they use the names 13092 // defined in the instructions definitions.