1 // 2 // Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // Specify priority of register selection within phases of register 135 // allocation. Highest priority is first. A useful heuristic is to 136 // give registers a low priority when they are required by machine 137 // instructions, like EAX and EDX on I486, and choose no-save registers 138 // before save-on-call, & save-on-call before save-on-entry. Registers 139 // which participate in fixed calling sequences should come last. 140 // Registers which are used as pairs must fall on an even boundary. 141 142 alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160 //----------Architecture Description Register Classes-------------------------- 161 // Several register classes are automatically defined based upon information in 162 // this architecture description. 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167 // 168 169 // Empty register class. 170 reg_class no_reg(); 171 172 // Class for all pointer registers (including RSP and RBP) 173 reg_class any_reg_with_rbp(RAX, RAX_H, 174 RDX, RDX_H, 175 RBP, RBP_H, 176 RDI, RDI_H, 177 RSI, RSI_H, 178 RCX, RCX_H, 179 RBX, RBX_H, 180 RSP, RSP_H, 181 R8, R8_H, 182 R9, R9_H, 183 R10, R10_H, 184 R11, R11_H, 185 R12, R12_H, 186 R13, R13_H, 187 R14, R14_H, 188 R15, R15_H); 189 190 // Class for all pointer registers (including RSP, but excluding RBP) 191 reg_class any_reg_no_rbp(RAX, RAX_H, 192 RDX, RDX_H, 193 RDI, RDI_H, 194 RSI, RSI_H, 195 RCX, RCX_H, 196 RBX, RBX_H, 197 RSP, RSP_H, 198 R8, R8_H, 199 R9, R9_H, 200 R10, R10_H, 201 R11, R11_H, 202 R12, R12_H, 203 R13, R13_H, 204 R14, R14_H, 205 R15, R15_H); 206 207 // Dynamic register class that selects at runtime between register classes 208 // any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer). 209 // Equivalent to: return PreserveFramePointer ? any_reg_no_rbp : any_reg_with_rbp; 210 reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %}); 211 212 // Class for all pointer registers (excluding RSP) 213 reg_class ptr_reg_with_rbp(RAX, RAX_H, 214 RDX, RDX_H, 215 RBP, RBP_H, 216 RDI, RDI_H, 217 RSI, RSI_H, 218 RCX, RCX_H, 219 RBX, RBX_H, 220 R8, R8_H, 221 R9, R9_H, 222 R10, R10_H, 223 R11, R11_H, 224 R13, R13_H, 225 R14, R14_H); 226 227 // Class for all pointer registers (excluding RSP and RBP) 228 reg_class ptr_reg_no_rbp(RAX, RAX_H, 229 RDX, RDX_H, 230 RDI, RDI_H, 231 RSI, RSI_H, 232 RCX, RCX_H, 233 RBX, RBX_H, 234 R8, R8_H, 235 R9, R9_H, 236 R10, R10_H, 237 R11, R11_H, 238 R13, R13_H, 239 R14, R14_H); 240 241 // Dynamic register class that selects between ptr_reg_no_rbp and ptr_reg_with_rbp. 242 reg_class_dynamic ptr_reg(ptr_reg_no_rbp, ptr_reg_with_rbp, %{ PreserveFramePointer %}); 243 244 // Class for all pointer registers (excluding RAX and RSP) 245 reg_class ptr_no_rax_reg_with_rbp(RDX, RDX_H, 246 RBP, RBP_H, 247 RDI, RDI_H, 248 RSI, RSI_H, 249 RCX, RCX_H, 250 RBX, RBX_H, 251 R8, R8_H, 252 R9, R9_H, 253 R10, R10_H, 254 R11, R11_H, 255 R13, R13_H, 256 R14, R14_H); 257 258 // Class for all pointer registers (excluding RAX, RSP, and RBP) 259 reg_class ptr_no_rax_reg_no_rbp(RDX, RDX_H, 260 RDI, RDI_H, 261 RSI, RSI_H, 262 RCX, RCX_H, 263 RBX, RBX_H, 264 R8, R8_H, 265 R9, R9_H, 266 R10, R10_H, 267 R11, R11_H, 268 R13, R13_H, 269 R14, R14_H); 270 271 // Dynamic register class that selects between ptr_no_rax_reg_no_rbp and ptr_no_rax_reg_with_rbp. 272 reg_class_dynamic ptr_no_rax_reg(ptr_no_rax_reg_no_rbp, ptr_no_rax_reg_with_rbp, %{ PreserveFramePointer %}); 273 274 // Class for all pointer registers (excluding RAX, RBX, and RSP) 275 reg_class ptr_no_rax_rbx_reg_with_rbp(RDX, RDX_H, 276 RBP, RBP_H, 277 RDI, RDI_H, 278 RSI, RSI_H, 279 RCX, RCX_H, 280 R8, R8_H, 281 R9, R9_H, 282 R10, R10_H, 283 R11, R11_H, 284 R13, R13_H, 285 R14, R14_H); 286 287 // Class for all pointer registers (excluding RAX, RBX, RSP, and RBP) 288 reg_class ptr_no_rax_rbx_reg_no_rbp(RDX, RDX_H, 289 RDI, RDI_H, 290 RSI, RSI_H, 291 RCX, RCX_H, 292 R8, R8_H, 293 R9, R9_H, 294 R10, R10_H, 295 R11, R11_H, 296 R13, R13_H, 297 R14, R14_H); 298 299 // Dynamic register class that selects between ptr_no_rax_rbx_reg_no_rbp and ptr_no_rax_rbx_reg_with_rbp. 300 reg_class_dynamic ptr_no_rax_rbx_reg(ptr_no_rax_rbx_reg_no_rbp, ptr_no_rax_rbx_reg_with_rbp, %{ PreserveFramePointer %}); 301 302 // Singleton class for RAX pointer register 303 reg_class ptr_rax_reg(RAX, RAX_H); 304 305 // Singleton class for RBX pointer register 306 reg_class ptr_rbx_reg(RBX, RBX_H); 307 308 // Singleton class for RSI pointer register 309 reg_class ptr_rsi_reg(RSI, RSI_H); 310 311 // Singleton class for RDI pointer register 312 reg_class ptr_rdi_reg(RDI, RDI_H); 313 314 // Singleton class for stack pointer 315 reg_class ptr_rsp_reg(RSP, RSP_H); 316 317 // Singleton class for TLS pointer 318 reg_class ptr_r15_reg(R15, R15_H); 319 320 // The registers which can be used for 321 // a thread local safepoint poll 322 // * R12 is reserved for heap base 323 // * R13 cannot be encoded for addressing without an offset byte 324 // * R15 is reserved for the JavaThread 325 reg_class ptr_rex_reg(R8, R8_H, 326 R9, R9_H, 327 R10, R10_H, 328 R11, R11_H, 329 R14, R14_H); 330 331 332 reg_class long_r12_reg(R12, R12_H); 333 334 // Class for all long registers (excluding RSP) 335 reg_class long_reg_with_rbp(RAX, RAX_H, 336 RDX, RDX_H, 337 RBP, RBP_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 // Class for all long registers (excluding RSP and RBP) 350 reg_class long_reg_no_rbp(RAX, RAX_H, 351 RDX, RDX_H, 352 RDI, RDI_H, 353 RSI, RSI_H, 354 RCX, RCX_H, 355 RBX, RBX_H, 356 R8, R8_H, 357 R9, R9_H, 358 R10, R10_H, 359 R11, R11_H, 360 R13, R13_H, 361 R14, R14_H); 362 363 // Dynamic register class that selects between long_reg_no_rbp and long_reg_with_rbp. 364 reg_class_dynamic long_reg(long_reg_no_rbp, long_reg_with_rbp, %{ PreserveFramePointer %}); 365 366 // Class for all long registers (excluding RAX, RDX and RSP) 367 reg_class long_no_rax_rdx_reg_with_rbp(RBP, RBP_H, 368 RDI, RDI_H, 369 RSI, RSI_H, 370 RCX, RCX_H, 371 RBX, RBX_H, 372 R8, R8_H, 373 R9, R9_H, 374 R10, R10_H, 375 R11, R11_H, 376 R13, R13_H, 377 R14, R14_H); 378 379 // Class for all long registers (excluding RAX, RDX, RSP, and RBP) 380 reg_class long_no_rax_rdx_reg_no_rbp(RDI, RDI_H, 381 RSI, RSI_H, 382 RCX, RCX_H, 383 RBX, RBX_H, 384 R8, R8_H, 385 R9, R9_H, 386 R10, R10_H, 387 R11, R11_H, 388 R13, R13_H, 389 R14, R14_H); 390 391 // Dynamic register class that selects between long_no_rax_rdx_reg_no_rbp and long_no_rax_rdx_reg_with_rbp. 392 reg_class_dynamic long_no_rax_rdx_reg(long_no_rax_rdx_reg_no_rbp, long_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 393 394 // Class for all long registers (excluding RCX and RSP) 395 reg_class long_no_rcx_reg_with_rbp(RBP, RBP_H, 396 RDI, RDI_H, 397 RSI, RSI_H, 398 RAX, RAX_H, 399 RDX, RDX_H, 400 RBX, RBX_H, 401 R8, R8_H, 402 R9, R9_H, 403 R10, R10_H, 404 R11, R11_H, 405 R13, R13_H, 406 R14, R14_H); 407 408 // Class for all long registers (excluding RCX, RSP, and RBP) 409 reg_class long_no_rcx_reg_no_rbp(RDI, RDI_H, 410 RSI, RSI_H, 411 RAX, RAX_H, 412 RDX, RDX_H, 413 RBX, RBX_H, 414 R8, R8_H, 415 R9, R9_H, 416 R10, R10_H, 417 R11, R11_H, 418 R13, R13_H, 419 R14, R14_H); 420 421 // Dynamic register class that selects between long_no_rcx_reg_no_rbp and long_no_rcx_reg_with_rbp. 422 reg_class_dynamic long_no_rcx_reg(long_no_rcx_reg_no_rbp, long_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 423 424 // Singleton class for RAX long register 425 reg_class long_rax_reg(RAX, RAX_H); 426 427 // Singleton class for RCX long register 428 reg_class long_rcx_reg(RCX, RCX_H); 429 430 // Singleton class for RDX long register 431 reg_class long_rdx_reg(RDX, RDX_H); 432 433 // Class for all int registers (excluding RSP) 434 reg_class int_reg_with_rbp(RAX, 435 RDX, 436 RBP, 437 RDI, 438 RSI, 439 RCX, 440 RBX, 441 R8, 442 R9, 443 R10, 444 R11, 445 R13, 446 R14); 447 448 // Class for all int registers (excluding RSP and RBP) 449 reg_class int_reg_no_rbp(RAX, 450 RDX, 451 RDI, 452 RSI, 453 RCX, 454 RBX, 455 R8, 456 R9, 457 R10, 458 R11, 459 R13, 460 R14); 461 462 // Dynamic register class that selects between int_reg_no_rbp and int_reg_with_rbp. 463 reg_class_dynamic int_reg(int_reg_no_rbp, int_reg_with_rbp, %{ PreserveFramePointer %}); 464 465 // Class for all int registers (excluding RCX and RSP) 466 reg_class int_no_rcx_reg_with_rbp(RAX, 467 RDX, 468 RBP, 469 RDI, 470 RSI, 471 RBX, 472 R8, 473 R9, 474 R10, 475 R11, 476 R13, 477 R14); 478 479 // Class for all int registers (excluding RCX, RSP, and RBP) 480 reg_class int_no_rcx_reg_no_rbp(RAX, 481 RDX, 482 RDI, 483 RSI, 484 RBX, 485 R8, 486 R9, 487 R10, 488 R11, 489 R13, 490 R14); 491 492 // Dynamic register class that selects between int_no_rcx_reg_no_rbp and int_no_rcx_reg_with_rbp. 493 reg_class_dynamic int_no_rcx_reg(int_no_rcx_reg_no_rbp, int_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 494 495 // Class for all int registers (excluding RAX, RDX, and RSP) 496 reg_class int_no_rax_rdx_reg_with_rbp(RBP, 497 RDI, 498 RSI, 499 RCX, 500 RBX, 501 R8, 502 R9, 503 R10, 504 R11, 505 R13, 506 R14); 507 508 // Class for all int registers (excluding RAX, RDX, RSP, and RBP) 509 reg_class int_no_rax_rdx_reg_no_rbp(RDI, 510 RSI, 511 RCX, 512 RBX, 513 R8, 514 R9, 515 R10, 516 R11, 517 R13, 518 R14); 519 520 // Dynamic register class that selects between int_no_rax_rdx_reg_no_rbp and int_no_rax_rdx_reg_with_rbp. 521 reg_class_dynamic int_no_rax_rdx_reg(int_no_rax_rdx_reg_no_rbp, int_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 522 523 // Singleton class for RAX int register 524 reg_class int_rax_reg(RAX); 525 526 // Singleton class for RBX int register 527 reg_class int_rbx_reg(RBX); 528 529 // Singleton class for RCX int register 530 reg_class int_rcx_reg(RCX); 531 532 // Singleton class for RCX int register 533 reg_class int_rdx_reg(RDX); 534 535 // Singleton class for RCX int register 536 reg_class int_rdi_reg(RDI); 537 538 // Singleton class for instruction pointer 539 // reg_class ip_reg(RIP); 540 541 %} 542 543 source_hpp %{ 544 bool is_far(intptr_t addr); 545 %} 546 547 //----------SOURCE BLOCK------------------------------------------------------- 548 // This is a block of C++ code which provides values, functions, and 549 // definitions necessary in the rest of the architecture description 550 source %{ 551 #define RELOC_IMM64 Assembler::imm_operand 552 #define RELOC_DISP32 Assembler::disp32_operand 553 554 #define __ _masm. 555 556 static bool generate_vzeroupper(Compile* C) { 557 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 558 } 559 560 static int clear_avx_size() { 561 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 562 } 563 564 // !!!!! Special hack to get all types of calls to specify the byte offset 565 // from the start of the call to the point where the return address 566 // will point. 567 int MachCallStaticJavaNode::ret_addr_offset() 568 { 569 int offset = 5; // 5 bytes from start of call to where return address points 570 offset += clear_avx_size(); 571 return offset; 572 } 573 574 int MachCallDynamicJavaNode::ret_addr_offset() 575 { 576 int offset = 15; // 15 bytes from start of call to where return address points 577 offset += clear_avx_size(); 578 return offset; 579 } 580 581 int MachCallRuntimeNode::ret_addr_offset() { 582 int offset = 13; // movq r10,#addr; callq (r10) 583 offset += clear_avx_size(); 584 return offset; 585 } 586 587 // Indicate if the safepoint node needs the polling page as an input, 588 // it does if the polling page is more than disp32 away. 589 bool SafePointNode::needs_polling_address_input() 590 { 591 return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far(); 592 } 593 594 // 595 // Compute padding required for nodes which need alignment 596 // 597 598 // The address of the call instruction needs to be 4-byte aligned to 599 // ensure that it does not span a cache line so that it can be patched. 600 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 601 { 602 current_offset += clear_avx_size(); // skip vzeroupper 603 current_offset += 1; // skip call opcode byte 604 return align_up(current_offset, alignment_required()) - current_offset; 605 } 606 607 // The address of the call instruction needs to be 4-byte aligned to 608 // ensure that it does not span a cache line so that it can be patched. 609 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 610 { 611 current_offset += clear_avx_size(); // skip vzeroupper 612 current_offset += 11; // skip movq instruction + call opcode byte 613 return align_up(current_offset, alignment_required()) - current_offset; 614 } 615 616 // EMIT_RM() 617 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 618 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 619 cbuf.insts()->emit_int8(c); 620 } 621 622 // EMIT_CC() 623 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 624 unsigned char c = (unsigned char) (f1 | f2); 625 cbuf.insts()->emit_int8(c); 626 } 627 628 // EMIT_OPCODE() 629 void emit_opcode(CodeBuffer &cbuf, int code) { 630 cbuf.insts()->emit_int8((unsigned char) code); 631 } 632 633 // EMIT_OPCODE() w/ relocation information 634 void emit_opcode(CodeBuffer &cbuf, 635 int code, relocInfo::relocType reloc, int offset, int format) 636 { 637 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 638 emit_opcode(cbuf, code); 639 } 640 641 // EMIT_D8() 642 void emit_d8(CodeBuffer &cbuf, int d8) { 643 cbuf.insts()->emit_int8((unsigned char) d8); 644 } 645 646 // EMIT_D16() 647 void emit_d16(CodeBuffer &cbuf, int d16) { 648 cbuf.insts()->emit_int16(d16); 649 } 650 651 // EMIT_D32() 652 void emit_d32(CodeBuffer &cbuf, int d32) { 653 cbuf.insts()->emit_int32(d32); 654 } 655 656 // EMIT_D64() 657 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 658 cbuf.insts()->emit_int64(d64); 659 } 660 661 // emit 32 bit value and construct relocation entry from relocInfo::relocType 662 void emit_d32_reloc(CodeBuffer& cbuf, 663 int d32, 664 relocInfo::relocType reloc, 665 int format) 666 { 667 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 668 cbuf.relocate(cbuf.insts_mark(), reloc, format); 669 cbuf.insts()->emit_int32(d32); 670 } 671 672 // emit 32 bit value and construct relocation entry from RelocationHolder 673 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 674 #ifdef ASSERT 675 if (rspec.reloc()->type() == relocInfo::oop_type && 676 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 677 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 678 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)) && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 679 } 680 #endif 681 cbuf.relocate(cbuf.insts_mark(), rspec, format); 682 cbuf.insts()->emit_int32(d32); 683 } 684 685 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 686 address next_ip = cbuf.insts_end() + 4; 687 emit_d32_reloc(cbuf, (int) (addr - next_ip), 688 external_word_Relocation::spec(addr), 689 RELOC_DISP32); 690 } 691 692 693 // emit 64 bit value and construct relocation entry from relocInfo::relocType 694 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 695 cbuf.relocate(cbuf.insts_mark(), reloc, format); 696 cbuf.insts()->emit_int64(d64); 697 } 698 699 // emit 64 bit value and construct relocation entry from RelocationHolder 700 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 701 #ifdef ASSERT 702 if (rspec.reloc()->type() == relocInfo::oop_type && 703 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 704 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 705 assert(oopDesc::is_oop(cast_to_oop(d64)) && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()), 706 "cannot embed scavengable oops in code"); 707 } 708 #endif 709 cbuf.relocate(cbuf.insts_mark(), rspec, format); 710 cbuf.insts()->emit_int64(d64); 711 } 712 713 // Access stack slot for load or store 714 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 715 { 716 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 717 if (-0x80 <= disp && disp < 0x80) { 718 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 719 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 720 emit_d8(cbuf, disp); // Displacement // R/M byte 721 } else { 722 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 723 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 724 emit_d32(cbuf, disp); // Displacement // R/M byte 725 } 726 } 727 728 // rRegI ereg, memory mem) %{ // emit_reg_mem 729 void encode_RegMem(CodeBuffer &cbuf, 730 int reg, 731 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 732 { 733 assert(disp_reloc == relocInfo::none, "cannot have disp"); 734 int regenc = reg & 7; 735 int baseenc = base & 7; 736 int indexenc = index & 7; 737 738 // There is no index & no scale, use form without SIB byte 739 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 740 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 741 if (disp == 0 && base != RBP_enc && base != R13_enc) { 742 emit_rm(cbuf, 0x0, regenc, baseenc); // * 743 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 744 // If 8-bit displacement, mode 0x1 745 emit_rm(cbuf, 0x1, regenc, baseenc); // * 746 emit_d8(cbuf, disp); 747 } else { 748 // If 32-bit displacement 749 if (base == -1) { // Special flag for absolute address 750 emit_rm(cbuf, 0x0, regenc, 0x5); // * 751 if (disp_reloc != relocInfo::none) { 752 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 753 } else { 754 emit_d32(cbuf, disp); 755 } 756 } else { 757 // Normal base + offset 758 emit_rm(cbuf, 0x2, regenc, baseenc); // * 759 if (disp_reloc != relocInfo::none) { 760 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 761 } else { 762 emit_d32(cbuf, disp); 763 } 764 } 765 } 766 } else { 767 // Else, encode with the SIB byte 768 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 769 if (disp == 0 && base != RBP_enc && base != R13_enc) { 770 // If no displacement 771 emit_rm(cbuf, 0x0, regenc, 0x4); // * 772 emit_rm(cbuf, scale, indexenc, baseenc); 773 } else { 774 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 775 // If 8-bit displacement, mode 0x1 776 emit_rm(cbuf, 0x1, regenc, 0x4); // * 777 emit_rm(cbuf, scale, indexenc, baseenc); 778 emit_d8(cbuf, disp); 779 } else { 780 // If 32-bit displacement 781 if (base == 0x04 ) { 782 emit_rm(cbuf, 0x2, regenc, 0x4); 783 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 784 } else { 785 emit_rm(cbuf, 0x2, regenc, 0x4); 786 emit_rm(cbuf, scale, indexenc, baseenc); // * 787 } 788 if (disp_reloc != relocInfo::none) { 789 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 790 } else { 791 emit_d32(cbuf, disp); 792 } 793 } 794 } 795 } 796 } 797 798 // This could be in MacroAssembler but it's fairly C2 specific 799 void emit_cmpfp_fixup(MacroAssembler& _masm) { 800 Label exit; 801 __ jccb(Assembler::noParity, exit); 802 __ pushf(); 803 // 804 // comiss/ucomiss instructions set ZF,PF,CF flags and 805 // zero OF,AF,SF for NaN values. 806 // Fixup flags by zeroing ZF,PF so that compare of NaN 807 // values returns 'less than' result (CF is set). 808 // Leave the rest of flags unchanged. 809 // 810 // 7 6 5 4 3 2 1 0 811 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 812 // 0 0 1 0 1 0 1 1 (0x2B) 813 // 814 __ andq(Address(rsp, 0), 0xffffff2b); 815 __ popf(); 816 __ bind(exit); 817 } 818 819 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 820 Label done; 821 __ movl(dst, -1); 822 __ jcc(Assembler::parity, done); 823 __ jcc(Assembler::below, done); 824 __ setb(Assembler::notEqual, dst); 825 __ movzbl(dst, dst); 826 __ bind(done); 827 } 828 829 830 //============================================================================= 831 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 832 833 int Compile::ConstantTable::calculate_table_base_offset() const { 834 return 0; // absolute addressing, no offset 835 } 836 837 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 838 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 839 ShouldNotReachHere(); 840 } 841 842 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 843 // Empty encoding 844 } 845 846 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 847 return 0; 848 } 849 850 #ifndef PRODUCT 851 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 852 st->print("# MachConstantBaseNode (empty encoding)"); 853 } 854 #endif 855 856 857 //============================================================================= 858 #ifndef PRODUCT 859 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 860 Compile* C = ra_->C; 861 862 int framesize = C->frame_size_in_bytes(); 863 int bangsize = C->bang_size_in_bytes(); 864 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 865 // Remove wordSize for return addr which is already pushed. 866 framesize -= wordSize; 867 868 if (C->need_stack_bang(bangsize)) { 869 framesize -= wordSize; 870 st->print("# stack bang (%d bytes)", bangsize); 871 st->print("\n\t"); 872 st->print("pushq rbp\t# Save rbp"); 873 if (PreserveFramePointer) { 874 st->print("\n\t"); 875 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 876 } 877 if (framesize) { 878 st->print("\n\t"); 879 st->print("subq rsp, #%d\t# Create frame",framesize); 880 } 881 } else { 882 st->print("subq rsp, #%d\t# Create frame",framesize); 883 st->print("\n\t"); 884 framesize -= wordSize; 885 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 886 if (PreserveFramePointer) { 887 st->print("\n\t"); 888 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 889 if (framesize > 0) { 890 st->print("\n\t"); 891 st->print("addq rbp, #%d", framesize); 892 } 893 } 894 } 895 896 if (VerifyStackAtCalls) { 897 st->print("\n\t"); 898 framesize -= wordSize; 899 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 900 #ifdef ASSERT 901 st->print("\n\t"); 902 st->print("# stack alignment check"); 903 #endif 904 } 905 st->cr(); 906 } 907 #endif 908 909 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 910 Compile* C = ra_->C; 911 MacroAssembler _masm(&cbuf); 912 913 int framesize = C->frame_size_in_bytes(); 914 int bangsize = C->bang_size_in_bytes(); 915 916 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); 917 918 C->set_frame_complete(cbuf.insts_size()); 919 920 if (C->has_mach_constant_base_node()) { 921 // NOTE: We set the table base offset here because users might be 922 // emitted before MachConstantBaseNode. 923 Compile::ConstantTable& constant_table = C->constant_table(); 924 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 925 } 926 } 927 928 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 929 { 930 return MachNode::size(ra_); // too many variables; just compute it 931 // the hard way 932 } 933 934 int MachPrologNode::reloc() const 935 { 936 return 0; // a large enough number 937 } 938 939 //============================================================================= 940 #ifndef PRODUCT 941 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 942 { 943 Compile* C = ra_->C; 944 if (generate_vzeroupper(C)) { 945 st->print("vzeroupper"); 946 st->cr(); st->print("\t"); 947 } 948 949 int framesize = C->frame_size_in_bytes(); 950 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 951 // Remove word for return adr already pushed 952 // and RBP 953 framesize -= 2*wordSize; 954 955 if (framesize) { 956 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 957 st->print("\t"); 958 } 959 960 st->print_cr("popq rbp"); 961 if (do_polling() && C->is_method_compilation()) { 962 st->print("\t"); 963 if (SafepointMechanism::uses_thread_local_poll()) { 964 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 965 "testl rax, [rscratch1]\t" 966 "# Safepoint: poll for GC"); 967 } else if (Assembler::is_polling_page_far()) { 968 st->print_cr("movq rscratch1, #polling_page_address\n\t" 969 "testl rax, [rscratch1]\t" 970 "# Safepoint: poll for GC"); 971 } else { 972 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 973 "# Safepoint: poll for GC"); 974 } 975 } 976 } 977 #endif 978 979 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 980 { 981 Compile* C = ra_->C; 982 MacroAssembler _masm(&cbuf); 983 984 if (generate_vzeroupper(C)) { 985 // Clear upper bits of YMM registers when current compiled code uses 986 // wide vectors to avoid AVX <-> SSE transition penalty during call. 987 __ vzeroupper(); 988 } 989 990 int framesize = C->frame_size_in_bytes(); 991 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 992 // Remove word for return adr already pushed 993 // and RBP 994 framesize -= 2*wordSize; 995 996 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 997 998 if (framesize) { 999 emit_opcode(cbuf, Assembler::REX_W); 1000 if (framesize < 0x80) { 1001 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 1002 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1003 emit_d8(cbuf, framesize); 1004 } else { 1005 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 1006 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1007 emit_d32(cbuf, framesize); 1008 } 1009 } 1010 1011 // popq rbp 1012 emit_opcode(cbuf, 0x58 | RBP_enc); 1013 1014 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1015 __ reserved_stack_check(); 1016 } 1017 1018 if (do_polling() && C->is_method_compilation()) { 1019 MacroAssembler _masm(&cbuf); 1020 if (SafepointMechanism::uses_thread_local_poll()) { 1021 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 1022 __ relocate(relocInfo::poll_return_type); 1023 __ testl(rax, Address(rscratch1, 0)); 1024 } else { 1025 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1026 if (Assembler::is_polling_page_far()) { 1027 __ lea(rscratch1, polling_page); 1028 __ relocate(relocInfo::poll_return_type); 1029 __ testl(rax, Address(rscratch1, 0)); 1030 } else { 1031 __ testl(rax, polling_page); 1032 } 1033 } 1034 } 1035 } 1036 1037 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1038 { 1039 return MachNode::size(ra_); // too many variables; just compute it 1040 // the hard way 1041 } 1042 1043 int MachEpilogNode::reloc() const 1044 { 1045 return 2; // a large enough number 1046 } 1047 1048 const Pipeline* MachEpilogNode::pipeline() const 1049 { 1050 return MachNode::pipeline_class(); 1051 } 1052 1053 int MachEpilogNode::safepoint_offset() const 1054 { 1055 return 0; 1056 } 1057 1058 //============================================================================= 1059 1060 enum RC { 1061 rc_bad, 1062 rc_int, 1063 rc_float, 1064 rc_stack 1065 }; 1066 1067 static enum RC rc_class(OptoReg::Name reg) 1068 { 1069 if( !OptoReg::is_valid(reg) ) return rc_bad; 1070 1071 if (OptoReg::is_stack(reg)) return rc_stack; 1072 1073 VMReg r = OptoReg::as_VMReg(reg); 1074 1075 if (r->is_Register()) return rc_int; 1076 1077 assert(r->is_XMMRegister(), "must be"); 1078 return rc_float; 1079 } 1080 1081 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1082 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1083 int src_hi, int dst_hi, uint ireg, outputStream* st); 1084 1085 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1086 int stack_offset, int reg, uint ireg, outputStream* st); 1087 1088 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1089 int dst_offset, uint ireg, outputStream* st) { 1090 if (cbuf) { 1091 MacroAssembler _masm(cbuf); 1092 switch (ireg) { 1093 case Op_VecS: 1094 __ movq(Address(rsp, -8), rax); 1095 __ movl(rax, Address(rsp, src_offset)); 1096 __ movl(Address(rsp, dst_offset), rax); 1097 __ movq(rax, Address(rsp, -8)); 1098 break; 1099 case Op_VecD: 1100 __ pushq(Address(rsp, src_offset)); 1101 __ popq (Address(rsp, dst_offset)); 1102 break; 1103 case Op_VecX: 1104 __ pushq(Address(rsp, src_offset)); 1105 __ popq (Address(rsp, dst_offset)); 1106 __ pushq(Address(rsp, src_offset+8)); 1107 __ popq (Address(rsp, dst_offset+8)); 1108 break; 1109 case Op_VecY: 1110 __ vmovdqu(Address(rsp, -32), xmm0); 1111 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1112 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1113 __ vmovdqu(xmm0, Address(rsp, -32)); 1114 break; 1115 case Op_VecZ: 1116 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1117 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1118 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1119 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1120 break; 1121 default: 1122 ShouldNotReachHere(); 1123 } 1124 #ifndef PRODUCT 1125 } else { 1126 switch (ireg) { 1127 case Op_VecS: 1128 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1129 "movl rax, [rsp + #%d]\n\t" 1130 "movl [rsp + #%d], rax\n\t" 1131 "movq rax, [rsp - #8]", 1132 src_offset, dst_offset); 1133 break; 1134 case Op_VecD: 1135 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1136 "popq [rsp + #%d]", 1137 src_offset, dst_offset); 1138 break; 1139 case Op_VecX: 1140 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1141 "popq [rsp + #%d]\n\t" 1142 "pushq [rsp + #%d]\n\t" 1143 "popq [rsp + #%d]", 1144 src_offset, dst_offset, src_offset+8, dst_offset+8); 1145 break; 1146 case Op_VecY: 1147 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1148 "vmovdqu xmm0, [rsp + #%d]\n\t" 1149 "vmovdqu [rsp + #%d], xmm0\n\t" 1150 "vmovdqu xmm0, [rsp - #32]", 1151 src_offset, dst_offset); 1152 break; 1153 case Op_VecZ: 1154 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1155 "vmovdqu xmm0, [rsp + #%d]\n\t" 1156 "vmovdqu [rsp + #%d], xmm0\n\t" 1157 "vmovdqu xmm0, [rsp - #64]", 1158 src_offset, dst_offset); 1159 break; 1160 default: 1161 ShouldNotReachHere(); 1162 } 1163 #endif 1164 } 1165 } 1166 1167 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1168 PhaseRegAlloc* ra_, 1169 bool do_size, 1170 outputStream* st) const { 1171 assert(cbuf != NULL || st != NULL, "sanity"); 1172 // Get registers to move 1173 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1174 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1175 OptoReg::Name dst_second = ra_->get_reg_second(this); 1176 OptoReg::Name dst_first = ra_->get_reg_first(this); 1177 1178 enum RC src_second_rc = rc_class(src_second); 1179 enum RC src_first_rc = rc_class(src_first); 1180 enum RC dst_second_rc = rc_class(dst_second); 1181 enum RC dst_first_rc = rc_class(dst_first); 1182 1183 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1184 "must move at least 1 register" ); 1185 1186 if (src_first == dst_first && src_second == dst_second) { 1187 // Self copy, no move 1188 return 0; 1189 } 1190 if (bottom_type()->isa_vect() != NULL) { 1191 uint ireg = ideal_reg(); 1192 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1193 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1194 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1195 // mem -> mem 1196 int src_offset = ra_->reg2offset(src_first); 1197 int dst_offset = ra_->reg2offset(dst_first); 1198 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1199 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1200 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1201 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1202 int stack_offset = ra_->reg2offset(dst_first); 1203 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1204 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1205 int stack_offset = ra_->reg2offset(src_first); 1206 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1207 } else { 1208 ShouldNotReachHere(); 1209 } 1210 return 0; 1211 } 1212 if (src_first_rc == rc_stack) { 1213 // mem -> 1214 if (dst_first_rc == rc_stack) { 1215 // mem -> mem 1216 assert(src_second != dst_first, "overlap"); 1217 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1218 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1219 // 64-bit 1220 int src_offset = ra_->reg2offset(src_first); 1221 int dst_offset = ra_->reg2offset(dst_first); 1222 if (cbuf) { 1223 MacroAssembler _masm(cbuf); 1224 __ pushq(Address(rsp, src_offset)); 1225 __ popq (Address(rsp, dst_offset)); 1226 #ifndef PRODUCT 1227 } else { 1228 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1229 "popq [rsp + #%d]", 1230 src_offset, dst_offset); 1231 #endif 1232 } 1233 } else { 1234 // 32-bit 1235 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1236 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1237 // No pushl/popl, so: 1238 int src_offset = ra_->reg2offset(src_first); 1239 int dst_offset = ra_->reg2offset(dst_first); 1240 if (cbuf) { 1241 MacroAssembler _masm(cbuf); 1242 __ movq(Address(rsp, -8), rax); 1243 __ movl(rax, Address(rsp, src_offset)); 1244 __ movl(Address(rsp, dst_offset), rax); 1245 __ movq(rax, Address(rsp, -8)); 1246 #ifndef PRODUCT 1247 } else { 1248 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1249 "movl rax, [rsp + #%d]\n\t" 1250 "movl [rsp + #%d], rax\n\t" 1251 "movq rax, [rsp - #8]", 1252 src_offset, dst_offset); 1253 #endif 1254 } 1255 } 1256 return 0; 1257 } else if (dst_first_rc == rc_int) { 1258 // mem -> gpr 1259 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1260 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1261 // 64-bit 1262 int offset = ra_->reg2offset(src_first); 1263 if (cbuf) { 1264 MacroAssembler _masm(cbuf); 1265 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1266 #ifndef PRODUCT 1267 } else { 1268 st->print("movq %s, [rsp + #%d]\t# spill", 1269 Matcher::regName[dst_first], 1270 offset); 1271 #endif 1272 } 1273 } else { 1274 // 32-bit 1275 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1276 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1277 int offset = ra_->reg2offset(src_first); 1278 if (cbuf) { 1279 MacroAssembler _masm(cbuf); 1280 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1281 #ifndef PRODUCT 1282 } else { 1283 st->print("movl %s, [rsp + #%d]\t# spill", 1284 Matcher::regName[dst_first], 1285 offset); 1286 #endif 1287 } 1288 } 1289 return 0; 1290 } else if (dst_first_rc == rc_float) { 1291 // mem-> xmm 1292 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1293 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1294 // 64-bit 1295 int offset = ra_->reg2offset(src_first); 1296 if (cbuf) { 1297 MacroAssembler _masm(cbuf); 1298 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1299 #ifndef PRODUCT 1300 } else { 1301 st->print("%s %s, [rsp + #%d]\t# spill", 1302 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1303 Matcher::regName[dst_first], 1304 offset); 1305 #endif 1306 } 1307 } else { 1308 // 32-bit 1309 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1310 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1311 int offset = ra_->reg2offset(src_first); 1312 if (cbuf) { 1313 MacroAssembler _masm(cbuf); 1314 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1315 #ifndef PRODUCT 1316 } else { 1317 st->print("movss %s, [rsp + #%d]\t# spill", 1318 Matcher::regName[dst_first], 1319 offset); 1320 #endif 1321 } 1322 } 1323 return 0; 1324 } 1325 } else if (src_first_rc == rc_int) { 1326 // gpr -> 1327 if (dst_first_rc == rc_stack) { 1328 // gpr -> mem 1329 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1330 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1331 // 64-bit 1332 int offset = ra_->reg2offset(dst_first); 1333 if (cbuf) { 1334 MacroAssembler _masm(cbuf); 1335 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1336 #ifndef PRODUCT 1337 } else { 1338 st->print("movq [rsp + #%d], %s\t# spill", 1339 offset, 1340 Matcher::regName[src_first]); 1341 #endif 1342 } 1343 } else { 1344 // 32-bit 1345 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1346 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1347 int offset = ra_->reg2offset(dst_first); 1348 if (cbuf) { 1349 MacroAssembler _masm(cbuf); 1350 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1351 #ifndef PRODUCT 1352 } else { 1353 st->print("movl [rsp + #%d], %s\t# spill", 1354 offset, 1355 Matcher::regName[src_first]); 1356 #endif 1357 } 1358 } 1359 return 0; 1360 } else if (dst_first_rc == rc_int) { 1361 // gpr -> gpr 1362 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1363 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1364 // 64-bit 1365 if (cbuf) { 1366 MacroAssembler _masm(cbuf); 1367 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1368 as_Register(Matcher::_regEncode[src_first])); 1369 #ifndef PRODUCT 1370 } else { 1371 st->print("movq %s, %s\t# spill", 1372 Matcher::regName[dst_first], 1373 Matcher::regName[src_first]); 1374 #endif 1375 } 1376 return 0; 1377 } else { 1378 // 32-bit 1379 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1380 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1381 if (cbuf) { 1382 MacroAssembler _masm(cbuf); 1383 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1384 as_Register(Matcher::_regEncode[src_first])); 1385 #ifndef PRODUCT 1386 } else { 1387 st->print("movl %s, %s\t# spill", 1388 Matcher::regName[dst_first], 1389 Matcher::regName[src_first]); 1390 #endif 1391 } 1392 return 0; 1393 } 1394 } else if (dst_first_rc == rc_float) { 1395 // gpr -> xmm 1396 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1397 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1398 // 64-bit 1399 if (cbuf) { 1400 MacroAssembler _masm(cbuf); 1401 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1402 #ifndef PRODUCT 1403 } else { 1404 st->print("movdq %s, %s\t# spill", 1405 Matcher::regName[dst_first], 1406 Matcher::regName[src_first]); 1407 #endif 1408 } 1409 } else { 1410 // 32-bit 1411 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1412 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1413 if (cbuf) { 1414 MacroAssembler _masm(cbuf); 1415 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1416 #ifndef PRODUCT 1417 } else { 1418 st->print("movdl %s, %s\t# spill", 1419 Matcher::regName[dst_first], 1420 Matcher::regName[src_first]); 1421 #endif 1422 } 1423 } 1424 return 0; 1425 } 1426 } else if (src_first_rc == rc_float) { 1427 // xmm -> 1428 if (dst_first_rc == rc_stack) { 1429 // xmm -> mem 1430 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1431 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1432 // 64-bit 1433 int offset = ra_->reg2offset(dst_first); 1434 if (cbuf) { 1435 MacroAssembler _masm(cbuf); 1436 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1437 #ifndef PRODUCT 1438 } else { 1439 st->print("movsd [rsp + #%d], %s\t# spill", 1440 offset, 1441 Matcher::regName[src_first]); 1442 #endif 1443 } 1444 } else { 1445 // 32-bit 1446 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1447 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1448 int offset = ra_->reg2offset(dst_first); 1449 if (cbuf) { 1450 MacroAssembler _masm(cbuf); 1451 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1452 #ifndef PRODUCT 1453 } else { 1454 st->print("movss [rsp + #%d], %s\t# spill", 1455 offset, 1456 Matcher::regName[src_first]); 1457 #endif 1458 } 1459 } 1460 return 0; 1461 } else if (dst_first_rc == rc_int) { 1462 // xmm -> gpr 1463 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1464 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1465 // 64-bit 1466 if (cbuf) { 1467 MacroAssembler _masm(cbuf); 1468 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1469 #ifndef PRODUCT 1470 } else { 1471 st->print("movdq %s, %s\t# spill", 1472 Matcher::regName[dst_first], 1473 Matcher::regName[src_first]); 1474 #endif 1475 } 1476 } else { 1477 // 32-bit 1478 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1479 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1480 if (cbuf) { 1481 MacroAssembler _masm(cbuf); 1482 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1483 #ifndef PRODUCT 1484 } else { 1485 st->print("movdl %s, %s\t# spill", 1486 Matcher::regName[dst_first], 1487 Matcher::regName[src_first]); 1488 #endif 1489 } 1490 } 1491 return 0; 1492 } else if (dst_first_rc == rc_float) { 1493 // xmm -> xmm 1494 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1495 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1496 // 64-bit 1497 if (cbuf) { 1498 MacroAssembler _masm(cbuf); 1499 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1500 #ifndef PRODUCT 1501 } else { 1502 st->print("%s %s, %s\t# spill", 1503 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1504 Matcher::regName[dst_first], 1505 Matcher::regName[src_first]); 1506 #endif 1507 } 1508 } else { 1509 // 32-bit 1510 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1511 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1512 if (cbuf) { 1513 MacroAssembler _masm(cbuf); 1514 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1515 #ifndef PRODUCT 1516 } else { 1517 st->print("%s %s, %s\t# spill", 1518 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1519 Matcher::regName[dst_first], 1520 Matcher::regName[src_first]); 1521 #endif 1522 } 1523 } 1524 return 0; 1525 } 1526 } 1527 1528 assert(0," foo "); 1529 Unimplemented(); 1530 return 0; 1531 } 1532 1533 #ifndef PRODUCT 1534 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1535 implementation(NULL, ra_, false, st); 1536 } 1537 #endif 1538 1539 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1540 implementation(&cbuf, ra_, false, NULL); 1541 } 1542 1543 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1544 return MachNode::size(ra_); 1545 } 1546 1547 //============================================================================= 1548 #ifndef PRODUCT 1549 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1550 { 1551 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1552 int reg = ra_->get_reg_first(this); 1553 st->print("leaq %s, [rsp + #%d]\t# box lock", 1554 Matcher::regName[reg], offset); 1555 } 1556 #endif 1557 1558 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1559 { 1560 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1561 int reg = ra_->get_encode(this); 1562 if (offset >= 0x80) { 1563 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1564 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1565 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1566 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1567 emit_d32(cbuf, offset); 1568 } else { 1569 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1570 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1571 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1572 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1573 emit_d8(cbuf, offset); 1574 } 1575 } 1576 1577 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1578 { 1579 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1580 return (offset < 0x80) ? 5 : 8; // REX 1581 } 1582 1583 //============================================================================= 1584 #ifndef PRODUCT 1585 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1586 { 1587 if (UseCompressedClassPointers) { 1588 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1589 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1590 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1591 } else { 1592 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1593 "# Inline cache check"); 1594 } 1595 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1596 st->print_cr("\tnop\t# nops to align entry point"); 1597 } 1598 #endif 1599 1600 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1601 { 1602 MacroAssembler masm(&cbuf); 1603 uint insts_size = cbuf.insts_size(); 1604 if (UseCompressedClassPointers) { 1605 masm.load_klass(rscratch1, j_rarg0); 1606 masm.cmpptr(rax, rscratch1); 1607 } else { 1608 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1609 } 1610 1611 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1612 1613 /* WARNING these NOPs are critical so that verified entry point is properly 1614 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1615 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1616 if (OptoBreakpoint) { 1617 // Leave space for int3 1618 nops_cnt -= 1; 1619 } 1620 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1621 if (nops_cnt > 0) 1622 masm.nop(nops_cnt); 1623 } 1624 1625 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1626 { 1627 return MachNode::size(ra_); // too many variables; just compute it 1628 // the hard way 1629 } 1630 1631 1632 //============================================================================= 1633 1634 int Matcher::regnum_to_fpu_offset(int regnum) 1635 { 1636 return regnum - 32; // The FP registers are in the second chunk 1637 } 1638 1639 // This is UltraSparc specific, true just means we have fast l2f conversion 1640 const bool Matcher::convL2FSupported(void) { 1641 return true; 1642 } 1643 1644 // Is this branch offset short enough that a short branch can be used? 1645 // 1646 // NOTE: If the platform does not provide any short branch variants, then 1647 // this method should return false for offset 0. 1648 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1649 // The passed offset is relative to address of the branch. 1650 // On 86 a branch displacement is calculated relative to address 1651 // of a next instruction. 1652 offset -= br_size; 1653 1654 // the short version of jmpConUCF2 contains multiple branches, 1655 // making the reach slightly less 1656 if (rule == jmpConUCF2_rule) 1657 return (-126 <= offset && offset <= 125); 1658 return (-128 <= offset && offset <= 127); 1659 } 1660 1661 const bool Matcher::isSimpleConstant64(jlong value) { 1662 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1663 //return value == (int) value; // Cf. storeImmL and immL32. 1664 1665 // Probably always true, even if a temp register is required. 1666 return true; 1667 } 1668 1669 // The ecx parameter to rep stosq for the ClearArray node is in words. 1670 const bool Matcher::init_array_count_is_in_bytes = false; 1671 1672 // No additional cost for CMOVL. 1673 const int Matcher::long_cmove_cost() { return 0; } 1674 1675 // No CMOVF/CMOVD with SSE2 1676 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1677 1678 // Does the CPU require late expand (see block.cpp for description of late expand)? 1679 const bool Matcher::require_postalloc_expand = false; 1680 1681 // Do we need to mask the count passed to shift instructions or does 1682 // the cpu only look at the lower 5/6 bits anyway? 1683 const bool Matcher::need_masked_shift_count = false; 1684 1685 bool Matcher::narrow_oop_use_complex_address() { 1686 assert(UseCompressedOops, "only for compressed oops code"); 1687 return (LogMinObjAlignmentInBytes <= 3); 1688 } 1689 1690 bool Matcher::narrow_klass_use_complex_address() { 1691 assert(UseCompressedClassPointers, "only for compressed klass code"); 1692 return (LogKlassAlignmentInBytes <= 3); 1693 } 1694 1695 bool Matcher::const_oop_prefer_decode() { 1696 // Prefer ConN+DecodeN over ConP. 1697 return true; 1698 } 1699 1700 bool Matcher::const_klass_prefer_decode() { 1701 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1702 // or condisider the following: 1703 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1704 //return Universe::narrow_klass_base() == NULL; 1705 return true; 1706 } 1707 1708 // Is it better to copy float constants, or load them directly from 1709 // memory? Intel can load a float constant from a direct address, 1710 // requiring no extra registers. Most RISCs will have to materialize 1711 // an address into a register first, so they would do better to copy 1712 // the constant from stack. 1713 const bool Matcher::rematerialize_float_constants = true; // XXX 1714 1715 // If CPU can load and store mis-aligned doubles directly then no 1716 // fixup is needed. Else we split the double into 2 integer pieces 1717 // and move it piece-by-piece. Only happens when passing doubles into 1718 // C code as the Java calling convention forces doubles to be aligned. 1719 const bool Matcher::misaligned_doubles_ok = true; 1720 1721 // No-op on amd64 1722 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1723 1724 // Advertise here if the CPU requires explicit rounding operations to 1725 // implement the UseStrictFP mode. 1726 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1727 1728 // Are floats conerted to double when stored to stack during deoptimization? 1729 // On x64 it is stored without convertion so we can use normal access. 1730 bool Matcher::float_in_double() { return false; } 1731 1732 // Do ints take an entire long register or just half? 1733 const bool Matcher::int_in_long = true; 1734 1735 // Return whether or not this register is ever used as an argument. 1736 // This function is used on startup to build the trampoline stubs in 1737 // generateOptoStub. Registers not mentioned will be killed by the VM 1738 // call in the trampoline, and arguments in those registers not be 1739 // available to the callee. 1740 bool Matcher::can_be_java_arg(int reg) 1741 { 1742 return 1743 reg == RDI_num || reg == RDI_H_num || 1744 reg == RSI_num || reg == RSI_H_num || 1745 reg == RDX_num || reg == RDX_H_num || 1746 reg == RCX_num || reg == RCX_H_num || 1747 reg == R8_num || reg == R8_H_num || 1748 reg == R9_num || reg == R9_H_num || 1749 reg == R12_num || reg == R12_H_num || 1750 reg == XMM0_num || reg == XMM0b_num || 1751 reg == XMM1_num || reg == XMM1b_num || 1752 reg == XMM2_num || reg == XMM2b_num || 1753 reg == XMM3_num || reg == XMM3b_num || 1754 reg == XMM4_num || reg == XMM4b_num || 1755 reg == XMM5_num || reg == XMM5b_num || 1756 reg == XMM6_num || reg == XMM6b_num || 1757 reg == XMM7_num || reg == XMM7b_num; 1758 } 1759 1760 bool Matcher::is_spillable_arg(int reg) 1761 { 1762 return can_be_java_arg(reg); 1763 } 1764 1765 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1766 // In 64 bit mode a code which use multiply when 1767 // devisor is constant is faster than hardware 1768 // DIV instruction (it uses MulHiL). 1769 return false; 1770 } 1771 1772 // Register for DIVI projection of divmodI 1773 RegMask Matcher::divI_proj_mask() { 1774 return INT_RAX_REG_mask(); 1775 } 1776 1777 // Register for MODI projection of divmodI 1778 RegMask Matcher::modI_proj_mask() { 1779 return INT_RDX_REG_mask(); 1780 } 1781 1782 // Register for DIVL projection of divmodL 1783 RegMask Matcher::divL_proj_mask() { 1784 return LONG_RAX_REG_mask(); 1785 } 1786 1787 // Register for MODL projection of divmodL 1788 RegMask Matcher::modL_proj_mask() { 1789 return LONG_RDX_REG_mask(); 1790 } 1791 1792 // Register for saving SP into on method handle invokes. Not used on x86_64. 1793 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1794 return NO_REG_mask(); 1795 } 1796 1797 bool is_far(intptr_t addr) { 1798 return !Assembler::is_simm32(addr - (intptr_t)CodeCache::low_bound()) || 1799 !Assembler::is_simm32(addr - (intptr_t)CodeCache::high_bound()); 1800 } 1801 1802 %} 1803 1804 //----------ENCODING BLOCK----------------------------------------------------- 1805 // This block specifies the encoding classes used by the compiler to 1806 // output byte streams. Encoding classes are parameterized macros 1807 // used by Machine Instruction Nodes in order to generate the bit 1808 // encoding of the instruction. Operands specify their base encoding 1809 // interface with the interface keyword. There are currently 1810 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1811 // COND_INTER. REG_INTER causes an operand to generate a function 1812 // which returns its register number when queried. CONST_INTER causes 1813 // an operand to generate a function which returns the value of the 1814 // constant when queried. MEMORY_INTER causes an operand to generate 1815 // four functions which return the Base Register, the Index Register, 1816 // the Scale Value, and the Offset Value of the operand when queried. 1817 // COND_INTER causes an operand to generate six functions which return 1818 // the encoding code (ie - encoding bits for the instruction) 1819 // associated with each basic boolean condition for a conditional 1820 // instruction. 1821 // 1822 // Instructions specify two basic values for encoding. Again, a 1823 // function is available to check if the constant displacement is an 1824 // oop. They use the ins_encode keyword to specify their encoding 1825 // classes (which must be a sequence of enc_class names, and their 1826 // parameters, specified in the encoding block), and they use the 1827 // opcode keyword to specify, in order, their primary, secondary, and 1828 // tertiary opcode. Only the opcode sections which a particular 1829 // instruction needs for encoding need to be specified. 1830 encode %{ 1831 // Build emit functions for each basic byte or larger field in the 1832 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1833 // from C++ code in the enc_class source block. Emit functions will 1834 // live in the main source block for now. In future, we can 1835 // generalize this by adding a syntax that specifies the sizes of 1836 // fields in an order, so that the adlc can build the emit functions 1837 // automagically 1838 1839 // Emit primary opcode 1840 enc_class OpcP 1841 %{ 1842 emit_opcode(cbuf, $primary); 1843 %} 1844 1845 // Emit secondary opcode 1846 enc_class OpcS 1847 %{ 1848 emit_opcode(cbuf, $secondary); 1849 %} 1850 1851 // Emit tertiary opcode 1852 enc_class OpcT 1853 %{ 1854 emit_opcode(cbuf, $tertiary); 1855 %} 1856 1857 // Emit opcode directly 1858 enc_class Opcode(immI d8) 1859 %{ 1860 emit_opcode(cbuf, $d8$$constant); 1861 %} 1862 1863 // Emit size prefix 1864 enc_class SizePrefix 1865 %{ 1866 emit_opcode(cbuf, 0x66); 1867 %} 1868 1869 enc_class reg(rRegI reg) 1870 %{ 1871 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1872 %} 1873 1874 enc_class reg_reg(rRegI dst, rRegI src) 1875 %{ 1876 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1877 %} 1878 1879 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1880 %{ 1881 emit_opcode(cbuf, $opcode$$constant); 1882 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1883 %} 1884 1885 enc_class cdql_enc(no_rax_rdx_RegI div) 1886 %{ 1887 // Full implementation of Java idiv and irem; checks for 1888 // special case as described in JVM spec., p.243 & p.271. 1889 // 1890 // normal case special case 1891 // 1892 // input : rax: dividend min_int 1893 // reg: divisor -1 1894 // 1895 // output: rax: quotient (= rax idiv reg) min_int 1896 // rdx: remainder (= rax irem reg) 0 1897 // 1898 // Code sequnce: 1899 // 1900 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1901 // 5: 75 07/08 jne e <normal> 1902 // 7: 33 d2 xor %edx,%edx 1903 // [div >= 8 -> offset + 1] 1904 // [REX_B] 1905 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1906 // c: 74 03/04 je 11 <done> 1907 // 000000000000000e <normal>: 1908 // e: 99 cltd 1909 // [div >= 8 -> offset + 1] 1910 // [REX_B] 1911 // f: f7 f9 idiv $div 1912 // 0000000000000011 <done>: 1913 1914 // cmp $0x80000000,%eax 1915 emit_opcode(cbuf, 0x3d); 1916 emit_d8(cbuf, 0x00); 1917 emit_d8(cbuf, 0x00); 1918 emit_d8(cbuf, 0x00); 1919 emit_d8(cbuf, 0x80); 1920 1921 // jne e <normal> 1922 emit_opcode(cbuf, 0x75); 1923 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1924 1925 // xor %edx,%edx 1926 emit_opcode(cbuf, 0x33); 1927 emit_d8(cbuf, 0xD2); 1928 1929 // cmp $0xffffffffffffffff,%ecx 1930 if ($div$$reg >= 8) { 1931 emit_opcode(cbuf, Assembler::REX_B); 1932 } 1933 emit_opcode(cbuf, 0x83); 1934 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1935 emit_d8(cbuf, 0xFF); 1936 1937 // je 11 <done> 1938 emit_opcode(cbuf, 0x74); 1939 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1940 1941 // <normal> 1942 // cltd 1943 emit_opcode(cbuf, 0x99); 1944 1945 // idivl (note: must be emitted by the user of this rule) 1946 // <done> 1947 %} 1948 1949 enc_class cdqq_enc(no_rax_rdx_RegL div) 1950 %{ 1951 // Full implementation of Java ldiv and lrem; checks for 1952 // special case as described in JVM spec., p.243 & p.271. 1953 // 1954 // normal case special case 1955 // 1956 // input : rax: dividend min_long 1957 // reg: divisor -1 1958 // 1959 // output: rax: quotient (= rax idiv reg) min_long 1960 // rdx: remainder (= rax irem reg) 0 1961 // 1962 // Code sequnce: 1963 // 1964 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1965 // 7: 00 00 80 1966 // a: 48 39 d0 cmp %rdx,%rax 1967 // d: 75 08 jne 17 <normal> 1968 // f: 33 d2 xor %edx,%edx 1969 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1970 // 15: 74 05 je 1c <done> 1971 // 0000000000000017 <normal>: 1972 // 17: 48 99 cqto 1973 // 19: 48 f7 f9 idiv $div 1974 // 000000000000001c <done>: 1975 1976 // mov $0x8000000000000000,%rdx 1977 emit_opcode(cbuf, Assembler::REX_W); 1978 emit_opcode(cbuf, 0xBA); 1979 emit_d8(cbuf, 0x00); 1980 emit_d8(cbuf, 0x00); 1981 emit_d8(cbuf, 0x00); 1982 emit_d8(cbuf, 0x00); 1983 emit_d8(cbuf, 0x00); 1984 emit_d8(cbuf, 0x00); 1985 emit_d8(cbuf, 0x00); 1986 emit_d8(cbuf, 0x80); 1987 1988 // cmp %rdx,%rax 1989 emit_opcode(cbuf, Assembler::REX_W); 1990 emit_opcode(cbuf, 0x39); 1991 emit_d8(cbuf, 0xD0); 1992 1993 // jne 17 <normal> 1994 emit_opcode(cbuf, 0x75); 1995 emit_d8(cbuf, 0x08); 1996 1997 // xor %edx,%edx 1998 emit_opcode(cbuf, 0x33); 1999 emit_d8(cbuf, 0xD2); 2000 2001 // cmp $0xffffffffffffffff,$div 2002 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 2003 emit_opcode(cbuf, 0x83); 2004 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2005 emit_d8(cbuf, 0xFF); 2006 2007 // je 1e <done> 2008 emit_opcode(cbuf, 0x74); 2009 emit_d8(cbuf, 0x05); 2010 2011 // <normal> 2012 // cqto 2013 emit_opcode(cbuf, Assembler::REX_W); 2014 emit_opcode(cbuf, 0x99); 2015 2016 // idivq (note: must be emitted by the user of this rule) 2017 // <done> 2018 %} 2019 2020 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2021 enc_class OpcSE(immI imm) 2022 %{ 2023 // Emit primary opcode and set sign-extend bit 2024 // Check for 8-bit immediate, and set sign extend bit in opcode 2025 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2026 emit_opcode(cbuf, $primary | 0x02); 2027 } else { 2028 // 32-bit immediate 2029 emit_opcode(cbuf, $primary); 2030 } 2031 %} 2032 2033 enc_class OpcSErm(rRegI dst, immI imm) 2034 %{ 2035 // OpcSEr/m 2036 int dstenc = $dst$$reg; 2037 if (dstenc >= 8) { 2038 emit_opcode(cbuf, Assembler::REX_B); 2039 dstenc -= 8; 2040 } 2041 // Emit primary opcode and set sign-extend bit 2042 // Check for 8-bit immediate, and set sign extend bit in opcode 2043 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2044 emit_opcode(cbuf, $primary | 0x02); 2045 } else { 2046 // 32-bit immediate 2047 emit_opcode(cbuf, $primary); 2048 } 2049 // Emit r/m byte with secondary opcode, after primary opcode. 2050 emit_rm(cbuf, 0x3, $secondary, dstenc); 2051 %} 2052 2053 enc_class OpcSErm_wide(rRegL dst, immI imm) 2054 %{ 2055 // OpcSEr/m 2056 int dstenc = $dst$$reg; 2057 if (dstenc < 8) { 2058 emit_opcode(cbuf, Assembler::REX_W); 2059 } else { 2060 emit_opcode(cbuf, Assembler::REX_WB); 2061 dstenc -= 8; 2062 } 2063 // Emit primary opcode and set sign-extend bit 2064 // Check for 8-bit immediate, and set sign extend bit in opcode 2065 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2066 emit_opcode(cbuf, $primary | 0x02); 2067 } else { 2068 // 32-bit immediate 2069 emit_opcode(cbuf, $primary); 2070 } 2071 // Emit r/m byte with secondary opcode, after primary opcode. 2072 emit_rm(cbuf, 0x3, $secondary, dstenc); 2073 %} 2074 2075 enc_class Con8or32(immI imm) 2076 %{ 2077 // Check for 8-bit immediate, and set sign extend bit in opcode 2078 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2079 $$$emit8$imm$$constant; 2080 } else { 2081 // 32-bit immediate 2082 $$$emit32$imm$$constant; 2083 } 2084 %} 2085 2086 enc_class opc2_reg(rRegI dst) 2087 %{ 2088 // BSWAP 2089 emit_cc(cbuf, $secondary, $dst$$reg); 2090 %} 2091 2092 enc_class opc3_reg(rRegI dst) 2093 %{ 2094 // BSWAP 2095 emit_cc(cbuf, $tertiary, $dst$$reg); 2096 %} 2097 2098 enc_class reg_opc(rRegI div) 2099 %{ 2100 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2101 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2102 %} 2103 2104 enc_class enc_cmov(cmpOp cop) 2105 %{ 2106 // CMOV 2107 $$$emit8$primary; 2108 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2109 %} 2110 2111 enc_class enc_PartialSubtypeCheck() 2112 %{ 2113 Register Rrdi = as_Register(RDI_enc); // result register 2114 Register Rrax = as_Register(RAX_enc); // super class 2115 Register Rrcx = as_Register(RCX_enc); // killed 2116 Register Rrsi = as_Register(RSI_enc); // sub class 2117 Label miss; 2118 const bool set_cond_codes = true; 2119 2120 MacroAssembler _masm(&cbuf); 2121 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2122 NULL, &miss, 2123 /*set_cond_codes:*/ true); 2124 if ($primary) { 2125 __ xorptr(Rrdi, Rrdi); 2126 } 2127 __ bind(miss); 2128 %} 2129 2130 enc_class clear_avx %{ 2131 debug_only(int off0 = cbuf.insts_size()); 2132 if (generate_vzeroupper(Compile::current())) { 2133 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2134 // Clear upper bits of YMM registers when current compiled code uses 2135 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2136 MacroAssembler _masm(&cbuf); 2137 __ vzeroupper(); 2138 } 2139 debug_only(int off1 = cbuf.insts_size()); 2140 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2141 %} 2142 2143 enc_class Java_To_Runtime(method meth) %{ 2144 // No relocation needed 2145 MacroAssembler _masm(&cbuf); 2146 __ mov64(r10, (int64_t) $meth$$method); 2147 __ call(r10); 2148 %} 2149 2150 enc_class Java_To_Interpreter(method meth) 2151 %{ 2152 // CALL Java_To_Interpreter 2153 // This is the instruction starting address for relocation info. 2154 cbuf.set_insts_mark(); 2155 $$$emit8$primary; 2156 // CALL directly to the runtime 2157 emit_d32_reloc(cbuf, 2158 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2159 runtime_call_Relocation::spec(), 2160 RELOC_DISP32); 2161 %} 2162 2163 enc_class Java_Static_Call(method meth) 2164 %{ 2165 // JAVA STATIC CALL 2166 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2167 // determine who we intended to call. 2168 cbuf.set_insts_mark(); 2169 $$$emit8$primary; 2170 2171 if (!_method) { 2172 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2173 runtime_call_Relocation::spec(), 2174 RELOC_DISP32); 2175 } else { 2176 int method_index = resolved_method_index(cbuf); 2177 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2178 : static_call_Relocation::spec(method_index); 2179 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2180 rspec, RELOC_DISP32); 2181 // Emit stubs for static call. 2182 address mark = cbuf.insts_mark(); 2183 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2184 if (stub == NULL) { 2185 ciEnv::current()->record_failure("CodeCache is full"); 2186 return; 2187 } 2188 #if INCLUDE_AOT 2189 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2190 #endif 2191 } 2192 %} 2193 2194 enc_class Java_Dynamic_Call(method meth) %{ 2195 MacroAssembler _masm(&cbuf); 2196 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2197 %} 2198 2199 enc_class Java_Compiled_Call(method meth) 2200 %{ 2201 // JAVA COMPILED CALL 2202 int disp = in_bytes(Method:: from_compiled_offset()); 2203 2204 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2205 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2206 2207 // callq *disp(%rax) 2208 cbuf.set_insts_mark(); 2209 $$$emit8$primary; 2210 if (disp < 0x80) { 2211 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2212 emit_d8(cbuf, disp); // Displacement 2213 } else { 2214 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2215 emit_d32(cbuf, disp); // Displacement 2216 } 2217 %} 2218 2219 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2220 %{ 2221 // SAL, SAR, SHR 2222 int dstenc = $dst$$reg; 2223 if (dstenc >= 8) { 2224 emit_opcode(cbuf, Assembler::REX_B); 2225 dstenc -= 8; 2226 } 2227 $$$emit8$primary; 2228 emit_rm(cbuf, 0x3, $secondary, dstenc); 2229 $$$emit8$shift$$constant; 2230 %} 2231 2232 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2233 %{ 2234 // SAL, SAR, SHR 2235 int dstenc = $dst$$reg; 2236 if (dstenc < 8) { 2237 emit_opcode(cbuf, Assembler::REX_W); 2238 } else { 2239 emit_opcode(cbuf, Assembler::REX_WB); 2240 dstenc -= 8; 2241 } 2242 $$$emit8$primary; 2243 emit_rm(cbuf, 0x3, $secondary, dstenc); 2244 $$$emit8$shift$$constant; 2245 %} 2246 2247 enc_class load_immI(rRegI dst, immI src) 2248 %{ 2249 int dstenc = $dst$$reg; 2250 if (dstenc >= 8) { 2251 emit_opcode(cbuf, Assembler::REX_B); 2252 dstenc -= 8; 2253 } 2254 emit_opcode(cbuf, 0xB8 | dstenc); 2255 $$$emit32$src$$constant; 2256 %} 2257 2258 enc_class load_immL(rRegL dst, immL src) 2259 %{ 2260 int dstenc = $dst$$reg; 2261 if (dstenc < 8) { 2262 emit_opcode(cbuf, Assembler::REX_W); 2263 } else { 2264 emit_opcode(cbuf, Assembler::REX_WB); 2265 dstenc -= 8; 2266 } 2267 emit_opcode(cbuf, 0xB8 | dstenc); 2268 emit_d64(cbuf, $src$$constant); 2269 %} 2270 2271 enc_class load_immUL32(rRegL dst, immUL32 src) 2272 %{ 2273 // same as load_immI, but this time we care about zeroes in the high word 2274 int dstenc = $dst$$reg; 2275 if (dstenc >= 8) { 2276 emit_opcode(cbuf, Assembler::REX_B); 2277 dstenc -= 8; 2278 } 2279 emit_opcode(cbuf, 0xB8 | dstenc); 2280 $$$emit32$src$$constant; 2281 %} 2282 2283 enc_class load_immL32(rRegL dst, immL32 src) 2284 %{ 2285 int dstenc = $dst$$reg; 2286 if (dstenc < 8) { 2287 emit_opcode(cbuf, Assembler::REX_W); 2288 } else { 2289 emit_opcode(cbuf, Assembler::REX_WB); 2290 dstenc -= 8; 2291 } 2292 emit_opcode(cbuf, 0xC7); 2293 emit_rm(cbuf, 0x03, 0x00, dstenc); 2294 $$$emit32$src$$constant; 2295 %} 2296 2297 enc_class load_immP31(rRegP dst, immP32 src) 2298 %{ 2299 // same as load_immI, but this time we care about zeroes in the high word 2300 int dstenc = $dst$$reg; 2301 if (dstenc >= 8) { 2302 emit_opcode(cbuf, Assembler::REX_B); 2303 dstenc -= 8; 2304 } 2305 emit_opcode(cbuf, 0xB8 | dstenc); 2306 $$$emit32$src$$constant; 2307 %} 2308 2309 enc_class load_immP(rRegP dst, immP src) 2310 %{ 2311 int dstenc = $dst$$reg; 2312 if (dstenc < 8) { 2313 emit_opcode(cbuf, Assembler::REX_W); 2314 } else { 2315 emit_opcode(cbuf, Assembler::REX_WB); 2316 dstenc -= 8; 2317 } 2318 emit_opcode(cbuf, 0xB8 | dstenc); 2319 // This next line should be generated from ADLC 2320 if ($src->constant_reloc() != relocInfo::none) { 2321 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2322 } else { 2323 emit_d64(cbuf, $src$$constant); 2324 } 2325 %} 2326 2327 enc_class Con32(immI src) 2328 %{ 2329 // Output immediate 2330 $$$emit32$src$$constant; 2331 %} 2332 2333 enc_class Con32F_as_bits(immF src) 2334 %{ 2335 // Output Float immediate bits 2336 jfloat jf = $src$$constant; 2337 jint jf_as_bits = jint_cast(jf); 2338 emit_d32(cbuf, jf_as_bits); 2339 %} 2340 2341 enc_class Con16(immI src) 2342 %{ 2343 // Output immediate 2344 $$$emit16$src$$constant; 2345 %} 2346 2347 // How is this different from Con32??? XXX 2348 enc_class Con_d32(immI src) 2349 %{ 2350 emit_d32(cbuf,$src$$constant); 2351 %} 2352 2353 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2354 // Output immediate memory reference 2355 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2356 emit_d32(cbuf, 0x00); 2357 %} 2358 2359 enc_class lock_prefix() 2360 %{ 2361 if (os::is_MP()) { 2362 emit_opcode(cbuf, 0xF0); // lock 2363 } 2364 %} 2365 2366 enc_class REX_mem(memory mem) 2367 %{ 2368 if ($mem$$base >= 8) { 2369 if ($mem$$index < 8) { 2370 emit_opcode(cbuf, Assembler::REX_B); 2371 } else { 2372 emit_opcode(cbuf, Assembler::REX_XB); 2373 } 2374 } else { 2375 if ($mem$$index >= 8) { 2376 emit_opcode(cbuf, Assembler::REX_X); 2377 } 2378 } 2379 %} 2380 2381 enc_class REX_mem_wide(memory mem) 2382 %{ 2383 if ($mem$$base >= 8) { 2384 if ($mem$$index < 8) { 2385 emit_opcode(cbuf, Assembler::REX_WB); 2386 } else { 2387 emit_opcode(cbuf, Assembler::REX_WXB); 2388 } 2389 } else { 2390 if ($mem$$index < 8) { 2391 emit_opcode(cbuf, Assembler::REX_W); 2392 } else { 2393 emit_opcode(cbuf, Assembler::REX_WX); 2394 } 2395 } 2396 %} 2397 2398 // for byte regs 2399 enc_class REX_breg(rRegI reg) 2400 %{ 2401 if ($reg$$reg >= 4) { 2402 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2403 } 2404 %} 2405 2406 // for byte regs 2407 enc_class REX_reg_breg(rRegI dst, rRegI src) 2408 %{ 2409 if ($dst$$reg < 8) { 2410 if ($src$$reg >= 4) { 2411 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2412 } 2413 } else { 2414 if ($src$$reg < 8) { 2415 emit_opcode(cbuf, Assembler::REX_R); 2416 } else { 2417 emit_opcode(cbuf, Assembler::REX_RB); 2418 } 2419 } 2420 %} 2421 2422 // for byte regs 2423 enc_class REX_breg_mem(rRegI reg, memory mem) 2424 %{ 2425 if ($reg$$reg < 8) { 2426 if ($mem$$base < 8) { 2427 if ($mem$$index >= 8) { 2428 emit_opcode(cbuf, Assembler::REX_X); 2429 } else if ($reg$$reg >= 4) { 2430 emit_opcode(cbuf, Assembler::REX); 2431 } 2432 } else { 2433 if ($mem$$index < 8) { 2434 emit_opcode(cbuf, Assembler::REX_B); 2435 } else { 2436 emit_opcode(cbuf, Assembler::REX_XB); 2437 } 2438 } 2439 } else { 2440 if ($mem$$base < 8) { 2441 if ($mem$$index < 8) { 2442 emit_opcode(cbuf, Assembler::REX_R); 2443 } else { 2444 emit_opcode(cbuf, Assembler::REX_RX); 2445 } 2446 } else { 2447 if ($mem$$index < 8) { 2448 emit_opcode(cbuf, Assembler::REX_RB); 2449 } else { 2450 emit_opcode(cbuf, Assembler::REX_RXB); 2451 } 2452 } 2453 } 2454 %} 2455 2456 enc_class REX_reg(rRegI reg) 2457 %{ 2458 if ($reg$$reg >= 8) { 2459 emit_opcode(cbuf, Assembler::REX_B); 2460 } 2461 %} 2462 2463 enc_class REX_reg_wide(rRegI reg) 2464 %{ 2465 if ($reg$$reg < 8) { 2466 emit_opcode(cbuf, Assembler::REX_W); 2467 } else { 2468 emit_opcode(cbuf, Assembler::REX_WB); 2469 } 2470 %} 2471 2472 enc_class REX_reg_reg(rRegI dst, rRegI src) 2473 %{ 2474 if ($dst$$reg < 8) { 2475 if ($src$$reg >= 8) { 2476 emit_opcode(cbuf, Assembler::REX_B); 2477 } 2478 } else { 2479 if ($src$$reg < 8) { 2480 emit_opcode(cbuf, Assembler::REX_R); 2481 } else { 2482 emit_opcode(cbuf, Assembler::REX_RB); 2483 } 2484 } 2485 %} 2486 2487 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2488 %{ 2489 if ($dst$$reg < 8) { 2490 if ($src$$reg < 8) { 2491 emit_opcode(cbuf, Assembler::REX_W); 2492 } else { 2493 emit_opcode(cbuf, Assembler::REX_WB); 2494 } 2495 } else { 2496 if ($src$$reg < 8) { 2497 emit_opcode(cbuf, Assembler::REX_WR); 2498 } else { 2499 emit_opcode(cbuf, Assembler::REX_WRB); 2500 } 2501 } 2502 %} 2503 2504 enc_class REX_reg_mem(rRegI reg, memory mem) 2505 %{ 2506 if ($reg$$reg < 8) { 2507 if ($mem$$base < 8) { 2508 if ($mem$$index >= 8) { 2509 emit_opcode(cbuf, Assembler::REX_X); 2510 } 2511 } else { 2512 if ($mem$$index < 8) { 2513 emit_opcode(cbuf, Assembler::REX_B); 2514 } else { 2515 emit_opcode(cbuf, Assembler::REX_XB); 2516 } 2517 } 2518 } else { 2519 if ($mem$$base < 8) { 2520 if ($mem$$index < 8) { 2521 emit_opcode(cbuf, Assembler::REX_R); 2522 } else { 2523 emit_opcode(cbuf, Assembler::REX_RX); 2524 } 2525 } else { 2526 if ($mem$$index < 8) { 2527 emit_opcode(cbuf, Assembler::REX_RB); 2528 } else { 2529 emit_opcode(cbuf, Assembler::REX_RXB); 2530 } 2531 } 2532 } 2533 %} 2534 2535 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2536 %{ 2537 if ($reg$$reg < 8) { 2538 if ($mem$$base < 8) { 2539 if ($mem$$index < 8) { 2540 emit_opcode(cbuf, Assembler::REX_W); 2541 } else { 2542 emit_opcode(cbuf, Assembler::REX_WX); 2543 } 2544 } else { 2545 if ($mem$$index < 8) { 2546 emit_opcode(cbuf, Assembler::REX_WB); 2547 } else { 2548 emit_opcode(cbuf, Assembler::REX_WXB); 2549 } 2550 } 2551 } else { 2552 if ($mem$$base < 8) { 2553 if ($mem$$index < 8) { 2554 emit_opcode(cbuf, Assembler::REX_WR); 2555 } else { 2556 emit_opcode(cbuf, Assembler::REX_WRX); 2557 } 2558 } else { 2559 if ($mem$$index < 8) { 2560 emit_opcode(cbuf, Assembler::REX_WRB); 2561 } else { 2562 emit_opcode(cbuf, Assembler::REX_WRXB); 2563 } 2564 } 2565 } 2566 %} 2567 2568 enc_class reg_mem(rRegI ereg, memory mem) 2569 %{ 2570 // High registers handle in encode_RegMem 2571 int reg = $ereg$$reg; 2572 int base = $mem$$base; 2573 int index = $mem$$index; 2574 int scale = $mem$$scale; 2575 int disp = $mem$$disp; 2576 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2577 2578 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2579 %} 2580 2581 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2582 %{ 2583 int rm_byte_opcode = $rm_opcode$$constant; 2584 2585 // High registers handle in encode_RegMem 2586 int base = $mem$$base; 2587 int index = $mem$$index; 2588 int scale = $mem$$scale; 2589 int displace = $mem$$disp; 2590 2591 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2592 // working with static 2593 // globals 2594 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2595 disp_reloc); 2596 %} 2597 2598 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2599 %{ 2600 int reg_encoding = $dst$$reg; 2601 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2602 int index = 0x04; // 0x04 indicates no index 2603 int scale = 0x00; // 0x00 indicates no scale 2604 int displace = $src1$$constant; // 0x00 indicates no displacement 2605 relocInfo::relocType disp_reloc = relocInfo::none; 2606 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2607 disp_reloc); 2608 %} 2609 2610 enc_class neg_reg(rRegI dst) 2611 %{ 2612 int dstenc = $dst$$reg; 2613 if (dstenc >= 8) { 2614 emit_opcode(cbuf, Assembler::REX_B); 2615 dstenc -= 8; 2616 } 2617 // NEG $dst 2618 emit_opcode(cbuf, 0xF7); 2619 emit_rm(cbuf, 0x3, 0x03, dstenc); 2620 %} 2621 2622 enc_class neg_reg_wide(rRegI dst) 2623 %{ 2624 int dstenc = $dst$$reg; 2625 if (dstenc < 8) { 2626 emit_opcode(cbuf, Assembler::REX_W); 2627 } else { 2628 emit_opcode(cbuf, Assembler::REX_WB); 2629 dstenc -= 8; 2630 } 2631 // NEG $dst 2632 emit_opcode(cbuf, 0xF7); 2633 emit_rm(cbuf, 0x3, 0x03, dstenc); 2634 %} 2635 2636 enc_class setLT_reg(rRegI dst) 2637 %{ 2638 int dstenc = $dst$$reg; 2639 if (dstenc >= 8) { 2640 emit_opcode(cbuf, Assembler::REX_B); 2641 dstenc -= 8; 2642 } else if (dstenc >= 4) { 2643 emit_opcode(cbuf, Assembler::REX); 2644 } 2645 // SETLT $dst 2646 emit_opcode(cbuf, 0x0F); 2647 emit_opcode(cbuf, 0x9C); 2648 emit_rm(cbuf, 0x3, 0x0, dstenc); 2649 %} 2650 2651 enc_class setNZ_reg(rRegI dst) 2652 %{ 2653 int dstenc = $dst$$reg; 2654 if (dstenc >= 8) { 2655 emit_opcode(cbuf, Assembler::REX_B); 2656 dstenc -= 8; 2657 } else if (dstenc >= 4) { 2658 emit_opcode(cbuf, Assembler::REX); 2659 } 2660 // SETNZ $dst 2661 emit_opcode(cbuf, 0x0F); 2662 emit_opcode(cbuf, 0x95); 2663 emit_rm(cbuf, 0x3, 0x0, dstenc); 2664 %} 2665 2666 2667 // Compare the lonogs and set -1, 0, or 1 into dst 2668 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2669 %{ 2670 int src1enc = $src1$$reg; 2671 int src2enc = $src2$$reg; 2672 int dstenc = $dst$$reg; 2673 2674 // cmpq $src1, $src2 2675 if (src1enc < 8) { 2676 if (src2enc < 8) { 2677 emit_opcode(cbuf, Assembler::REX_W); 2678 } else { 2679 emit_opcode(cbuf, Assembler::REX_WB); 2680 } 2681 } else { 2682 if (src2enc < 8) { 2683 emit_opcode(cbuf, Assembler::REX_WR); 2684 } else { 2685 emit_opcode(cbuf, Assembler::REX_WRB); 2686 } 2687 } 2688 emit_opcode(cbuf, 0x3B); 2689 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2690 2691 // movl $dst, -1 2692 if (dstenc >= 8) { 2693 emit_opcode(cbuf, Assembler::REX_B); 2694 } 2695 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2696 emit_d32(cbuf, -1); 2697 2698 // jl,s done 2699 emit_opcode(cbuf, 0x7C); 2700 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2701 2702 // setne $dst 2703 if (dstenc >= 4) { 2704 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2705 } 2706 emit_opcode(cbuf, 0x0F); 2707 emit_opcode(cbuf, 0x95); 2708 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2709 2710 // movzbl $dst, $dst 2711 if (dstenc >= 4) { 2712 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2713 } 2714 emit_opcode(cbuf, 0x0F); 2715 emit_opcode(cbuf, 0xB6); 2716 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2717 %} 2718 2719 enc_class Push_ResultXD(regD dst) %{ 2720 MacroAssembler _masm(&cbuf); 2721 __ fstp_d(Address(rsp, 0)); 2722 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2723 __ addptr(rsp, 8); 2724 %} 2725 2726 enc_class Push_SrcXD(regD src) %{ 2727 MacroAssembler _masm(&cbuf); 2728 __ subptr(rsp, 8); 2729 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2730 __ fld_d(Address(rsp, 0)); 2731 %} 2732 2733 2734 enc_class enc_rethrow() 2735 %{ 2736 cbuf.set_insts_mark(); 2737 emit_opcode(cbuf, 0xE9); // jmp entry 2738 emit_d32_reloc(cbuf, 2739 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2740 runtime_call_Relocation::spec(), 2741 RELOC_DISP32); 2742 %} 2743 2744 %} 2745 2746 2747 2748 //----------FRAME-------------------------------------------------------------- 2749 // Definition of frame structure and management information. 2750 // 2751 // S T A C K L A Y O U T Allocators stack-slot number 2752 // | (to get allocators register number 2753 // G Owned by | | v add OptoReg::stack0()) 2754 // r CALLER | | 2755 // o | +--------+ pad to even-align allocators stack-slot 2756 // w V | pad0 | numbers; owned by CALLER 2757 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2758 // h ^ | in | 5 2759 // | | args | 4 Holes in incoming args owned by SELF 2760 // | | | | 3 2761 // | | +--------+ 2762 // V | | old out| Empty on Intel, window on Sparc 2763 // | old |preserve| Must be even aligned. 2764 // | SP-+--------+----> Matcher::_old_SP, even aligned 2765 // | | in | 3 area for Intel ret address 2766 // Owned by |preserve| Empty on Sparc. 2767 // SELF +--------+ 2768 // | | pad2 | 2 pad to align old SP 2769 // | +--------+ 1 2770 // | | locks | 0 2771 // | +--------+----> OptoReg::stack0(), even aligned 2772 // | | pad1 | 11 pad to align new SP 2773 // | +--------+ 2774 // | | | 10 2775 // | | spills | 9 spills 2776 // V | | 8 (pad0 slot for callee) 2777 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2778 // ^ | out | 7 2779 // | | args | 6 Holes in outgoing args owned by CALLEE 2780 // Owned by +--------+ 2781 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2782 // | new |preserve| Must be even-aligned. 2783 // | SP-+--------+----> Matcher::_new_SP, even aligned 2784 // | | | 2785 // 2786 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2787 // known from SELF's arguments and the Java calling convention. 2788 // Region 6-7 is determined per call site. 2789 // Note 2: If the calling convention leaves holes in the incoming argument 2790 // area, those holes are owned by SELF. Holes in the outgoing area 2791 // are owned by the CALLEE. Holes should not be nessecary in the 2792 // incoming area, as the Java calling convention is completely under 2793 // the control of the AD file. Doubles can be sorted and packed to 2794 // avoid holes. Holes in the outgoing arguments may be nessecary for 2795 // varargs C calling conventions. 2796 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2797 // even aligned with pad0 as needed. 2798 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2799 // region 6-11 is even aligned; it may be padded out more so that 2800 // the region from SP to FP meets the minimum stack alignment. 2801 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2802 // alignment. Region 11, pad1, may be dynamically extended so that 2803 // SP meets the minimum alignment. 2804 2805 frame 2806 %{ 2807 // What direction does stack grow in (assumed to be same for C & Java) 2808 stack_direction(TOWARDS_LOW); 2809 2810 // These three registers define part of the calling convention 2811 // between compiled code and the interpreter. 2812 inline_cache_reg(RAX); // Inline Cache Register 2813 interpreter_method_oop_reg(RBX); // Method Oop Register when 2814 // calling interpreter 2815 2816 // Optional: name the operand used by cisc-spilling to access 2817 // [stack_pointer + offset] 2818 cisc_spilling_operand_name(indOffset32); 2819 2820 // Number of stack slots consumed by locking an object 2821 sync_stack_slots(2); 2822 2823 // Compiled code's Frame Pointer 2824 frame_pointer(RSP); 2825 2826 // Interpreter stores its frame pointer in a register which is 2827 // stored to the stack by I2CAdaptors. 2828 // I2CAdaptors convert from interpreted java to compiled java. 2829 interpreter_frame_pointer(RBP); 2830 2831 // Stack alignment requirement 2832 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2833 2834 // Number of stack slots between incoming argument block and the start of 2835 // a new frame. The PROLOG must add this many slots to the stack. The 2836 // EPILOG must remove this many slots. amd64 needs two slots for 2837 // return address. 2838 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2839 2840 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2841 // for calls to C. Supports the var-args backing area for register parms. 2842 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2843 2844 // The after-PROLOG location of the return address. Location of 2845 // return address specifies a type (REG or STACK) and a number 2846 // representing the register number (i.e. - use a register name) or 2847 // stack slot. 2848 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2849 // Otherwise, it is above the locks and verification slot and alignment word 2850 return_addr(STACK - 2 + 2851 align_up((Compile::current()->in_preserve_stack_slots() + 2852 Compile::current()->fixed_slots()), 2853 stack_alignment_in_slots())); 2854 2855 // Body of function which returns an integer array locating 2856 // arguments either in registers or in stack slots. Passed an array 2857 // of ideal registers called "sig" and a "length" count. Stack-slot 2858 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2859 // arguments for a CALLEE. Incoming stack arguments are 2860 // automatically biased by the preserve_stack_slots field above. 2861 2862 calling_convention 2863 %{ 2864 // No difference between ingoing/outgoing just pass false 2865 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2866 %} 2867 2868 c_calling_convention 2869 %{ 2870 // This is obviously always outgoing 2871 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2872 %} 2873 2874 // Location of compiled Java return values. Same as C for now. 2875 return_value 2876 %{ 2877 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2878 "only return normal values"); 2879 2880 static const int lo[Op_RegL + 1] = { 2881 0, 2882 0, 2883 RAX_num, // Op_RegN 2884 RAX_num, // Op_RegI 2885 RAX_num, // Op_RegP 2886 XMM0_num, // Op_RegF 2887 XMM0_num, // Op_RegD 2888 RAX_num // Op_RegL 2889 }; 2890 static const int hi[Op_RegL + 1] = { 2891 0, 2892 0, 2893 OptoReg::Bad, // Op_RegN 2894 OptoReg::Bad, // Op_RegI 2895 RAX_H_num, // Op_RegP 2896 OptoReg::Bad, // Op_RegF 2897 XMM0b_num, // Op_RegD 2898 RAX_H_num // Op_RegL 2899 }; 2900 // Excluded flags and vector registers. 2901 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2902 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2903 %} 2904 %} 2905 2906 //----------ATTRIBUTES--------------------------------------------------------- 2907 //----------Operand Attributes------------------------------------------------- 2908 op_attrib op_cost(0); // Required cost attribute 2909 2910 //----------Instruction Attributes--------------------------------------------- 2911 ins_attrib ins_cost(100); // Required cost attribute 2912 ins_attrib ins_size(8); // Required size attribute (in bits) 2913 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2914 // a non-matching short branch variant 2915 // of some long branch? 2916 ins_attrib ins_alignment(1); // Required alignment attribute (must 2917 // be a power of 2) specifies the 2918 // alignment that some part of the 2919 // instruction (not necessarily the 2920 // start) requires. If > 1, a 2921 // compute_padding() function must be 2922 // provided for the instruction 2923 2924 //----------OPERANDS----------------------------------------------------------- 2925 // Operand definitions must precede instruction definitions for correct parsing 2926 // in the ADLC because operands constitute user defined types which are used in 2927 // instruction definitions. 2928 2929 //----------Simple Operands---------------------------------------------------- 2930 // Immediate Operands 2931 // Integer Immediate 2932 operand immI() 2933 %{ 2934 match(ConI); 2935 2936 op_cost(10); 2937 format %{ %} 2938 interface(CONST_INTER); 2939 %} 2940 2941 // Constant for test vs zero 2942 operand immI0() 2943 %{ 2944 predicate(n->get_int() == 0); 2945 match(ConI); 2946 2947 op_cost(0); 2948 format %{ %} 2949 interface(CONST_INTER); 2950 %} 2951 2952 // Constant for increment 2953 operand immI1() 2954 %{ 2955 predicate(n->get_int() == 1); 2956 match(ConI); 2957 2958 op_cost(0); 2959 format %{ %} 2960 interface(CONST_INTER); 2961 %} 2962 2963 // Constant for decrement 2964 operand immI_M1() 2965 %{ 2966 predicate(n->get_int() == -1); 2967 match(ConI); 2968 2969 op_cost(0); 2970 format %{ %} 2971 interface(CONST_INTER); 2972 %} 2973 2974 // Valid scale values for addressing modes 2975 operand immI2() 2976 %{ 2977 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2978 match(ConI); 2979 2980 format %{ %} 2981 interface(CONST_INTER); 2982 %} 2983 2984 operand immI8() 2985 %{ 2986 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 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 rex_RegP() 3556 %{ 3557 constraint(ALLOC_IN_RC(ptr_rex_reg)); 3558 match(RegP); 3559 match(rRegP); 3560 3561 format %{ %} 3562 interface(REG_INTER); 3563 %} 3564 3565 operand r12_RegL() 3566 %{ 3567 constraint(ALLOC_IN_RC(long_r12_reg)); 3568 match(RegL); 3569 match(rRegL); 3570 3571 format %{ %} 3572 interface(REG_INTER); 3573 %} 3574 3575 operand rRegL() 3576 %{ 3577 constraint(ALLOC_IN_RC(long_reg)); 3578 match(RegL); 3579 match(rax_RegL); 3580 match(rdx_RegL); 3581 match(r12_RegL); 3582 3583 format %{ %} 3584 interface(REG_INTER); 3585 %} 3586 3587 // Special Registers 3588 operand no_rax_rdx_RegL() 3589 %{ 3590 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3591 match(RegL); 3592 match(rRegL); 3593 3594 format %{ %} 3595 interface(REG_INTER); 3596 %} 3597 3598 operand no_rax_RegL() 3599 %{ 3600 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3601 match(RegL); 3602 match(rRegL); 3603 match(rdx_RegL); 3604 3605 format %{ %} 3606 interface(REG_INTER); 3607 %} 3608 3609 operand no_rcx_RegL() 3610 %{ 3611 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3612 match(RegL); 3613 match(rRegL); 3614 3615 format %{ %} 3616 interface(REG_INTER); 3617 %} 3618 3619 operand rax_RegL() 3620 %{ 3621 constraint(ALLOC_IN_RC(long_rax_reg)); 3622 match(RegL); 3623 match(rRegL); 3624 3625 format %{ "RAX" %} 3626 interface(REG_INTER); 3627 %} 3628 3629 operand rcx_RegL() 3630 %{ 3631 constraint(ALLOC_IN_RC(long_rcx_reg)); 3632 match(RegL); 3633 match(rRegL); 3634 3635 format %{ %} 3636 interface(REG_INTER); 3637 %} 3638 3639 operand rdx_RegL() 3640 %{ 3641 constraint(ALLOC_IN_RC(long_rdx_reg)); 3642 match(RegL); 3643 match(rRegL); 3644 3645 format %{ %} 3646 interface(REG_INTER); 3647 %} 3648 3649 // Flags register, used as output of compare instructions 3650 operand rFlagsReg() 3651 %{ 3652 constraint(ALLOC_IN_RC(int_flags)); 3653 match(RegFlags); 3654 3655 format %{ "RFLAGS" %} 3656 interface(REG_INTER); 3657 %} 3658 3659 // Flags register, used as output of FLOATING POINT compare instructions 3660 operand rFlagsRegU() 3661 %{ 3662 constraint(ALLOC_IN_RC(int_flags)); 3663 match(RegFlags); 3664 3665 format %{ "RFLAGS_U" %} 3666 interface(REG_INTER); 3667 %} 3668 3669 operand rFlagsRegUCF() %{ 3670 constraint(ALLOC_IN_RC(int_flags)); 3671 match(RegFlags); 3672 predicate(false); 3673 3674 format %{ "RFLAGS_U_CF" %} 3675 interface(REG_INTER); 3676 %} 3677 3678 // Float register operands 3679 operand regF() %{ 3680 constraint(ALLOC_IN_RC(float_reg)); 3681 match(RegF); 3682 3683 format %{ %} 3684 interface(REG_INTER); 3685 %} 3686 3687 // Double register operands 3688 operand regD() %{ 3689 constraint(ALLOC_IN_RC(double_reg)); 3690 match(RegD); 3691 3692 format %{ %} 3693 interface(REG_INTER); 3694 %} 3695 3696 // Vectors 3697 operand vecS() %{ 3698 constraint(ALLOC_IN_RC(vectors_reg)); 3699 match(VecS); 3700 3701 format %{ %} 3702 interface(REG_INTER); 3703 %} 3704 3705 operand vecD() %{ 3706 constraint(ALLOC_IN_RC(vectord_reg)); 3707 match(VecD); 3708 3709 format %{ %} 3710 interface(REG_INTER); 3711 %} 3712 3713 operand vecX() %{ 3714 constraint(ALLOC_IN_RC(vectorx_reg)); 3715 match(VecX); 3716 3717 format %{ %} 3718 interface(REG_INTER); 3719 %} 3720 3721 operand vecY() %{ 3722 constraint(ALLOC_IN_RC(vectory_reg)); 3723 match(VecY); 3724 3725 format %{ %} 3726 interface(REG_INTER); 3727 %} 3728 3729 //----------Memory Operands---------------------------------------------------- 3730 // Direct Memory Operand 3731 // operand direct(immP addr) 3732 // %{ 3733 // match(addr); 3734 3735 // format %{ "[$addr]" %} 3736 // interface(MEMORY_INTER) %{ 3737 // base(0xFFFFFFFF); 3738 // index(0x4); 3739 // scale(0x0); 3740 // disp($addr); 3741 // %} 3742 // %} 3743 3744 // Indirect Memory Operand 3745 operand indirect(any_RegP reg) 3746 %{ 3747 constraint(ALLOC_IN_RC(ptr_reg)); 3748 match(reg); 3749 3750 format %{ "[$reg]" %} 3751 interface(MEMORY_INTER) %{ 3752 base($reg); 3753 index(0x4); 3754 scale(0x0); 3755 disp(0x0); 3756 %} 3757 %} 3758 3759 // Indirect Memory Plus Short Offset Operand 3760 operand indOffset8(any_RegP reg, immL8 off) 3761 %{ 3762 constraint(ALLOC_IN_RC(ptr_reg)); 3763 match(AddP reg off); 3764 3765 format %{ "[$reg + $off (8-bit)]" %} 3766 interface(MEMORY_INTER) %{ 3767 base($reg); 3768 index(0x4); 3769 scale(0x0); 3770 disp($off); 3771 %} 3772 %} 3773 3774 // Indirect Memory Plus Long Offset Operand 3775 operand indOffset32(any_RegP reg, immL32 off) 3776 %{ 3777 constraint(ALLOC_IN_RC(ptr_reg)); 3778 match(AddP reg off); 3779 3780 format %{ "[$reg + $off (32-bit)]" %} 3781 interface(MEMORY_INTER) %{ 3782 base($reg); 3783 index(0x4); 3784 scale(0x0); 3785 disp($off); 3786 %} 3787 %} 3788 3789 // Indirect Memory Plus Index Register Plus Offset Operand 3790 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3791 %{ 3792 constraint(ALLOC_IN_RC(ptr_reg)); 3793 match(AddP (AddP reg lreg) off); 3794 3795 op_cost(10); 3796 format %{"[$reg + $off + $lreg]" %} 3797 interface(MEMORY_INTER) %{ 3798 base($reg); 3799 index($lreg); 3800 scale(0x0); 3801 disp($off); 3802 %} 3803 %} 3804 3805 // Indirect Memory Plus Index Register Plus Offset Operand 3806 operand indIndex(any_RegP reg, rRegL lreg) 3807 %{ 3808 constraint(ALLOC_IN_RC(ptr_reg)); 3809 match(AddP reg lreg); 3810 3811 op_cost(10); 3812 format %{"[$reg + $lreg]" %} 3813 interface(MEMORY_INTER) %{ 3814 base($reg); 3815 index($lreg); 3816 scale(0x0); 3817 disp(0x0); 3818 %} 3819 %} 3820 3821 // Indirect Memory Times Scale Plus Index Register 3822 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3823 %{ 3824 constraint(ALLOC_IN_RC(ptr_reg)); 3825 match(AddP reg (LShiftL lreg scale)); 3826 3827 op_cost(10); 3828 format %{"[$reg + $lreg << $scale]" %} 3829 interface(MEMORY_INTER) %{ 3830 base($reg); 3831 index($lreg); 3832 scale($scale); 3833 disp(0x0); 3834 %} 3835 %} 3836 3837 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3838 %{ 3839 constraint(ALLOC_IN_RC(ptr_reg)); 3840 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3841 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3842 3843 op_cost(10); 3844 format %{"[$reg + pos $idx << $scale]" %} 3845 interface(MEMORY_INTER) %{ 3846 base($reg); 3847 index($idx); 3848 scale($scale); 3849 disp(0x0); 3850 %} 3851 %} 3852 3853 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3854 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3855 %{ 3856 constraint(ALLOC_IN_RC(ptr_reg)); 3857 match(AddP (AddP reg (LShiftL lreg scale)) off); 3858 3859 op_cost(10); 3860 format %{"[$reg + $off + $lreg << $scale]" %} 3861 interface(MEMORY_INTER) %{ 3862 base($reg); 3863 index($lreg); 3864 scale($scale); 3865 disp($off); 3866 %} 3867 %} 3868 3869 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3870 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3871 %{ 3872 constraint(ALLOC_IN_RC(ptr_reg)); 3873 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3874 match(AddP (AddP reg (ConvI2L idx)) off); 3875 3876 op_cost(10); 3877 format %{"[$reg + $off + $idx]" %} 3878 interface(MEMORY_INTER) %{ 3879 base($reg); 3880 index($idx); 3881 scale(0x0); 3882 disp($off); 3883 %} 3884 %} 3885 3886 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3887 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3888 %{ 3889 constraint(ALLOC_IN_RC(ptr_reg)); 3890 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3891 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3892 3893 op_cost(10); 3894 format %{"[$reg + $off + $idx << $scale]" %} 3895 interface(MEMORY_INTER) %{ 3896 base($reg); 3897 index($idx); 3898 scale($scale); 3899 disp($off); 3900 %} 3901 %} 3902 3903 // Indirect Narrow Oop Plus Offset Operand 3904 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3905 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3906 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3907 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3908 constraint(ALLOC_IN_RC(ptr_reg)); 3909 match(AddP (DecodeN reg) off); 3910 3911 op_cost(10); 3912 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3913 interface(MEMORY_INTER) %{ 3914 base(0xc); // R12 3915 index($reg); 3916 scale(0x3); 3917 disp($off); 3918 %} 3919 %} 3920 3921 // Indirect Memory Operand 3922 operand indirectNarrow(rRegN reg) 3923 %{ 3924 predicate(Universe::narrow_oop_shift() == 0); 3925 constraint(ALLOC_IN_RC(ptr_reg)); 3926 match(DecodeN reg); 3927 3928 format %{ "[$reg]" %} 3929 interface(MEMORY_INTER) %{ 3930 base($reg); 3931 index(0x4); 3932 scale(0x0); 3933 disp(0x0); 3934 %} 3935 %} 3936 3937 // Indirect Memory Plus Short Offset Operand 3938 operand indOffset8Narrow(rRegN reg, immL8 off) 3939 %{ 3940 predicate(Universe::narrow_oop_shift() == 0); 3941 constraint(ALLOC_IN_RC(ptr_reg)); 3942 match(AddP (DecodeN reg) off); 3943 3944 format %{ "[$reg + $off (8-bit)]" %} 3945 interface(MEMORY_INTER) %{ 3946 base($reg); 3947 index(0x4); 3948 scale(0x0); 3949 disp($off); 3950 %} 3951 %} 3952 3953 // Indirect Memory Plus Long Offset Operand 3954 operand indOffset32Narrow(rRegN reg, immL32 off) 3955 %{ 3956 predicate(Universe::narrow_oop_shift() == 0); 3957 constraint(ALLOC_IN_RC(ptr_reg)); 3958 match(AddP (DecodeN reg) off); 3959 3960 format %{ "[$reg + $off (32-bit)]" %} 3961 interface(MEMORY_INTER) %{ 3962 base($reg); 3963 index(0x4); 3964 scale(0x0); 3965 disp($off); 3966 %} 3967 %} 3968 3969 // Indirect Memory Plus Index Register Plus Offset Operand 3970 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3971 %{ 3972 predicate(Universe::narrow_oop_shift() == 0); 3973 constraint(ALLOC_IN_RC(ptr_reg)); 3974 match(AddP (AddP (DecodeN reg) lreg) off); 3975 3976 op_cost(10); 3977 format %{"[$reg + $off + $lreg]" %} 3978 interface(MEMORY_INTER) %{ 3979 base($reg); 3980 index($lreg); 3981 scale(0x0); 3982 disp($off); 3983 %} 3984 %} 3985 3986 // Indirect Memory Plus Index Register Plus Offset Operand 3987 operand indIndexNarrow(rRegN reg, rRegL lreg) 3988 %{ 3989 predicate(Universe::narrow_oop_shift() == 0); 3990 constraint(ALLOC_IN_RC(ptr_reg)); 3991 match(AddP (DecodeN reg) lreg); 3992 3993 op_cost(10); 3994 format %{"[$reg + $lreg]" %} 3995 interface(MEMORY_INTER) %{ 3996 base($reg); 3997 index($lreg); 3998 scale(0x0); 3999 disp(0x0); 4000 %} 4001 %} 4002 4003 // Indirect Memory Times Scale Plus Index Register 4004 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4005 %{ 4006 predicate(Universe::narrow_oop_shift() == 0); 4007 constraint(ALLOC_IN_RC(ptr_reg)); 4008 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4009 4010 op_cost(10); 4011 format %{"[$reg + $lreg << $scale]" %} 4012 interface(MEMORY_INTER) %{ 4013 base($reg); 4014 index($lreg); 4015 scale($scale); 4016 disp(0x0); 4017 %} 4018 %} 4019 4020 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4021 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4022 %{ 4023 predicate(Universe::narrow_oop_shift() == 0); 4024 constraint(ALLOC_IN_RC(ptr_reg)); 4025 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4026 4027 op_cost(10); 4028 format %{"[$reg + $off + $lreg << $scale]" %} 4029 interface(MEMORY_INTER) %{ 4030 base($reg); 4031 index($lreg); 4032 scale($scale); 4033 disp($off); 4034 %} 4035 %} 4036 4037 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4038 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4039 %{ 4040 constraint(ALLOC_IN_RC(ptr_reg)); 4041 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4042 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4043 4044 op_cost(10); 4045 format %{"[$reg + $off + $idx]" %} 4046 interface(MEMORY_INTER) %{ 4047 base($reg); 4048 index($idx); 4049 scale(0x0); 4050 disp($off); 4051 %} 4052 %} 4053 4054 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4055 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4056 %{ 4057 constraint(ALLOC_IN_RC(ptr_reg)); 4058 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4059 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4060 4061 op_cost(10); 4062 format %{"[$reg + $off + $idx << $scale]" %} 4063 interface(MEMORY_INTER) %{ 4064 base($reg); 4065 index($idx); 4066 scale($scale); 4067 disp($off); 4068 %} 4069 %} 4070 4071 //----------Special Memory Operands-------------------------------------------- 4072 // Stack Slot Operand - This operand is used for loading and storing temporary 4073 // values on the stack where a match requires a value to 4074 // flow through memory. 4075 operand stackSlotP(sRegP reg) 4076 %{ 4077 constraint(ALLOC_IN_RC(stack_slots)); 4078 // No match rule because this operand is only generated in matching 4079 4080 format %{ "[$reg]" %} 4081 interface(MEMORY_INTER) %{ 4082 base(0x4); // RSP 4083 index(0x4); // No Index 4084 scale(0x0); // No Scale 4085 disp($reg); // Stack Offset 4086 %} 4087 %} 4088 4089 operand stackSlotI(sRegI reg) 4090 %{ 4091 constraint(ALLOC_IN_RC(stack_slots)); 4092 // No match rule because this operand is only generated in matching 4093 4094 format %{ "[$reg]" %} 4095 interface(MEMORY_INTER) %{ 4096 base(0x4); // RSP 4097 index(0x4); // No Index 4098 scale(0x0); // No Scale 4099 disp($reg); // Stack Offset 4100 %} 4101 %} 4102 4103 operand stackSlotF(sRegF reg) 4104 %{ 4105 constraint(ALLOC_IN_RC(stack_slots)); 4106 // No match rule because this operand is only generated in matching 4107 4108 format %{ "[$reg]" %} 4109 interface(MEMORY_INTER) %{ 4110 base(0x4); // RSP 4111 index(0x4); // No Index 4112 scale(0x0); // No Scale 4113 disp($reg); // Stack Offset 4114 %} 4115 %} 4116 4117 operand stackSlotD(sRegD reg) 4118 %{ 4119 constraint(ALLOC_IN_RC(stack_slots)); 4120 // No match rule because this operand is only generated in matching 4121 4122 format %{ "[$reg]" %} 4123 interface(MEMORY_INTER) %{ 4124 base(0x4); // RSP 4125 index(0x4); // No Index 4126 scale(0x0); // No Scale 4127 disp($reg); // Stack Offset 4128 %} 4129 %} 4130 operand stackSlotL(sRegL reg) 4131 %{ 4132 constraint(ALLOC_IN_RC(stack_slots)); 4133 // No match rule because this operand is only generated in matching 4134 4135 format %{ "[$reg]" %} 4136 interface(MEMORY_INTER) %{ 4137 base(0x4); // RSP 4138 index(0x4); // No Index 4139 scale(0x0); // No Scale 4140 disp($reg); // Stack Offset 4141 %} 4142 %} 4143 4144 //----------Conditional Branch Operands---------------------------------------- 4145 // Comparison Op - This is the operation of the comparison, and is limited to 4146 // the following set of codes: 4147 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4148 // 4149 // Other attributes of the comparison, such as unsignedness, are specified 4150 // by the comparison instruction that sets a condition code flags register. 4151 // That result is represented by a flags operand whose subtype is appropriate 4152 // to the unsignedness (etc.) of the comparison. 4153 // 4154 // Later, the instruction which matches both the Comparison Op (a Bool) and 4155 // the flags (produced by the Cmp) specifies the coding of the comparison op 4156 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4157 4158 // Comparision Code 4159 operand cmpOp() 4160 %{ 4161 match(Bool); 4162 4163 format %{ "" %} 4164 interface(COND_INTER) %{ 4165 equal(0x4, "e"); 4166 not_equal(0x5, "ne"); 4167 less(0xC, "l"); 4168 greater_equal(0xD, "ge"); 4169 less_equal(0xE, "le"); 4170 greater(0xF, "g"); 4171 overflow(0x0, "o"); 4172 no_overflow(0x1, "no"); 4173 %} 4174 %} 4175 4176 // Comparison Code, unsigned compare. Used by FP also, with 4177 // C2 (unordered) turned into GT or LT already. The other bits 4178 // C0 and C3 are turned into Carry & Zero flags. 4179 operand cmpOpU() 4180 %{ 4181 match(Bool); 4182 4183 format %{ "" %} 4184 interface(COND_INTER) %{ 4185 equal(0x4, "e"); 4186 not_equal(0x5, "ne"); 4187 less(0x2, "b"); 4188 greater_equal(0x3, "nb"); 4189 less_equal(0x6, "be"); 4190 greater(0x7, "nbe"); 4191 overflow(0x0, "o"); 4192 no_overflow(0x1, "no"); 4193 %} 4194 %} 4195 4196 4197 // Floating comparisons that don't require any fixup for the unordered case 4198 operand cmpOpUCF() %{ 4199 match(Bool); 4200 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4201 n->as_Bool()->_test._test == BoolTest::ge || 4202 n->as_Bool()->_test._test == BoolTest::le || 4203 n->as_Bool()->_test._test == BoolTest::gt); 4204 format %{ "" %} 4205 interface(COND_INTER) %{ 4206 equal(0x4, "e"); 4207 not_equal(0x5, "ne"); 4208 less(0x2, "b"); 4209 greater_equal(0x3, "nb"); 4210 less_equal(0x6, "be"); 4211 greater(0x7, "nbe"); 4212 overflow(0x0, "o"); 4213 no_overflow(0x1, "no"); 4214 %} 4215 %} 4216 4217 4218 // Floating comparisons that can be fixed up with extra conditional jumps 4219 operand cmpOpUCF2() %{ 4220 match(Bool); 4221 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4222 n->as_Bool()->_test._test == BoolTest::eq); 4223 format %{ "" %} 4224 interface(COND_INTER) %{ 4225 equal(0x4, "e"); 4226 not_equal(0x5, "ne"); 4227 less(0x2, "b"); 4228 greater_equal(0x3, "nb"); 4229 less_equal(0x6, "be"); 4230 greater(0x7, "nbe"); 4231 overflow(0x0, "o"); 4232 no_overflow(0x1, "no"); 4233 %} 4234 %} 4235 4236 // Operands for bound floating pointer register arguments 4237 operand rxmm0() %{ 4238 constraint(ALLOC_IN_RC(xmm0_reg)); match(VecX); 4239 predicate((UseSSE > 0) && (UseAVX<= 2)); format%{%} interface(REG_INTER); 4240 %} 4241 operand rxmm1() %{ 4242 constraint(ALLOC_IN_RC(xmm1_reg)); match(VecX); 4243 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4244 %} 4245 operand rxmm2() %{ 4246 constraint(ALLOC_IN_RC(xmm2_reg)); match(VecX); 4247 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4248 %} 4249 operand rxmm3() %{ 4250 constraint(ALLOC_IN_RC(xmm3_reg)); match(VecX); 4251 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4252 %} 4253 operand rxmm4() %{ 4254 constraint(ALLOC_IN_RC(xmm4_reg)); match(VecX); 4255 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4256 %} 4257 operand rxmm5() %{ 4258 constraint(ALLOC_IN_RC(xmm5_reg)); match(VecX); 4259 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4260 %} 4261 operand rxmm6() %{ 4262 constraint(ALLOC_IN_RC(xmm6_reg)); match(VecX); 4263 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4264 %} 4265 operand rxmm7() %{ 4266 constraint(ALLOC_IN_RC(xmm7_reg)); match(VecX); 4267 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4268 %} 4269 operand rxmm8() %{ 4270 constraint(ALLOC_IN_RC(xmm8_reg)); match(VecX); 4271 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4272 %} 4273 operand rxmm9() %{ 4274 constraint(ALLOC_IN_RC(xmm9_reg)); match(VecX); 4275 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4276 %} 4277 operand rxmm10() %{ 4278 constraint(ALLOC_IN_RC(xmm10_reg)); match(VecX); 4279 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4280 %} 4281 operand rxmm11() %{ 4282 constraint(ALLOC_IN_RC(xmm11_reg)); match(VecX); 4283 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4284 %} 4285 operand rxmm12() %{ 4286 constraint(ALLOC_IN_RC(xmm12_reg)); match(VecX); 4287 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4288 %} 4289 operand rxmm13() %{ 4290 constraint(ALLOC_IN_RC(xmm13_reg)); match(VecX); 4291 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4292 %} 4293 operand rxmm14() %{ 4294 constraint(ALLOC_IN_RC(xmm14_reg)); match(VecX); 4295 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4296 %} 4297 operand rxmm15() %{ 4298 constraint(ALLOC_IN_RC(xmm15_reg)); match(VecX); 4299 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4300 %} 4301 operand rxmm16() %{ 4302 constraint(ALLOC_IN_RC(xmm16_reg)); match(VecX); 4303 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4304 %} 4305 operand rxmm17() %{ 4306 constraint(ALLOC_IN_RC(xmm17_reg)); match(VecX); 4307 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4308 %} 4309 operand rxmm18() %{ 4310 constraint(ALLOC_IN_RC(xmm18_reg)); match(VecX); 4311 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4312 %} 4313 operand rxmm19() %{ 4314 constraint(ALLOC_IN_RC(xmm19_reg)); match(VecX); 4315 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4316 %} 4317 operand rxmm20() %{ 4318 constraint(ALLOC_IN_RC(xmm20_reg)); match(VecX); 4319 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4320 %} 4321 operand rxmm21() %{ 4322 constraint(ALLOC_IN_RC(xmm21_reg)); match(VecX); 4323 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4324 %} 4325 operand rxmm22() %{ 4326 constraint(ALLOC_IN_RC(xmm22_reg)); match(VecX); 4327 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4328 %} 4329 operand rxmm23() %{ 4330 constraint(ALLOC_IN_RC(xmm23_reg)); match(VecX); 4331 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4332 %} 4333 operand rxmm24() %{ 4334 constraint(ALLOC_IN_RC(xmm24_reg)); match(VecX); 4335 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4336 %} 4337 operand rxmm25() %{ 4338 constraint(ALLOC_IN_RC(xmm25_reg)); match(VecX); 4339 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4340 %} 4341 operand rxmm26() %{ 4342 constraint(ALLOC_IN_RC(xmm26_reg)); match(VecX); 4343 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4344 %} 4345 operand rxmm27() %{ 4346 constraint(ALLOC_IN_RC(xmm27_reg)); match(VecX); 4347 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4348 %} 4349 operand rxmm28() %{ 4350 constraint(ALLOC_IN_RC(xmm28_reg)); match(VecX); 4351 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4352 %} 4353 operand rxmm29() %{ 4354 constraint(ALLOC_IN_RC(xmm29_reg)); match(VecX); 4355 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4356 %} 4357 operand rxmm30() %{ 4358 constraint(ALLOC_IN_RC(xmm30_reg)); match(VecX); 4359 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4360 %} 4361 operand rxmm31() %{ 4362 constraint(ALLOC_IN_RC(xmm31_reg)); match(VecX); 4363 predicate((UseAVX == 3)); format%{%} interface(REG_INTER); 4364 %} 4365 4366 4367 4368 //----------OPERAND CLASSES---------------------------------------------------- 4369 // Operand Classes are groups of operands that are used as to simplify 4370 // instruction definitions by not requiring the AD writer to specify separate 4371 // instructions for every form of operand when the instruction accepts 4372 // multiple operand types with the same basic encoding and format. The classic 4373 // case of this is memory operands. 4374 4375 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4376 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4377 indCompressedOopOffset, 4378 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4379 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4380 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4381 4382 //----------PIPELINE----------------------------------------------------------- 4383 // Rules which define the behavior of the target architectures pipeline. 4384 pipeline %{ 4385 4386 //----------ATTRIBUTES--------------------------------------------------------- 4387 attributes %{ 4388 variable_size_instructions; // Fixed size instructions 4389 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4390 instruction_unit_size = 1; // An instruction is 1 bytes long 4391 instruction_fetch_unit_size = 16; // The processor fetches one line 4392 instruction_fetch_units = 1; // of 16 bytes 4393 4394 // List of nop instructions 4395 nops( MachNop ); 4396 %} 4397 4398 //----------RESOURCES---------------------------------------------------------- 4399 // Resources are the functional units available to the machine 4400 4401 // Generic P2/P3 pipeline 4402 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4403 // 3 instructions decoded per cycle. 4404 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4405 // 3 ALU op, only ALU0 handles mul instructions. 4406 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4407 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4408 BR, FPU, 4409 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4410 4411 //----------PIPELINE DESCRIPTION----------------------------------------------- 4412 // Pipeline Description specifies the stages in the machine's pipeline 4413 4414 // Generic P2/P3 pipeline 4415 pipe_desc(S0, S1, S2, S3, S4, S5); 4416 4417 //----------PIPELINE CLASSES--------------------------------------------------- 4418 // Pipeline Classes describe the stages in which input and output are 4419 // referenced by the hardware pipeline. 4420 4421 // Naming convention: ialu or fpu 4422 // Then: _reg 4423 // Then: _reg if there is a 2nd register 4424 // Then: _long if it's a pair of instructions implementing a long 4425 // Then: _fat if it requires the big decoder 4426 // Or: _mem if it requires the big decoder and a memory unit. 4427 4428 // Integer ALU reg operation 4429 pipe_class ialu_reg(rRegI dst) 4430 %{ 4431 single_instruction; 4432 dst : S4(write); 4433 dst : S3(read); 4434 DECODE : S0; // any decoder 4435 ALU : S3; // any alu 4436 %} 4437 4438 // Long ALU reg operation 4439 pipe_class ialu_reg_long(rRegL dst) 4440 %{ 4441 instruction_count(2); 4442 dst : S4(write); 4443 dst : S3(read); 4444 DECODE : S0(2); // any 2 decoders 4445 ALU : S3(2); // both alus 4446 %} 4447 4448 // Integer ALU reg operation using big decoder 4449 pipe_class ialu_reg_fat(rRegI dst) 4450 %{ 4451 single_instruction; 4452 dst : S4(write); 4453 dst : S3(read); 4454 D0 : S0; // big decoder only 4455 ALU : S3; // any alu 4456 %} 4457 4458 // Long ALU reg operation using big decoder 4459 pipe_class ialu_reg_long_fat(rRegL dst) 4460 %{ 4461 instruction_count(2); 4462 dst : S4(write); 4463 dst : S3(read); 4464 D0 : S0(2); // big decoder only; twice 4465 ALU : S3(2); // any 2 alus 4466 %} 4467 4468 // Integer ALU reg-reg operation 4469 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4470 %{ 4471 single_instruction; 4472 dst : S4(write); 4473 src : S3(read); 4474 DECODE : S0; // any decoder 4475 ALU : S3; // any alu 4476 %} 4477 4478 // Long ALU reg-reg operation 4479 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4480 %{ 4481 instruction_count(2); 4482 dst : S4(write); 4483 src : S3(read); 4484 DECODE : S0(2); // any 2 decoders 4485 ALU : S3(2); // both alus 4486 %} 4487 4488 // Integer ALU reg-reg operation 4489 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4490 %{ 4491 single_instruction; 4492 dst : S4(write); 4493 src : S3(read); 4494 D0 : S0; // big decoder only 4495 ALU : S3; // any alu 4496 %} 4497 4498 // Long ALU reg-reg operation 4499 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4500 %{ 4501 instruction_count(2); 4502 dst : S4(write); 4503 src : S3(read); 4504 D0 : S0(2); // big decoder only; twice 4505 ALU : S3(2); // both alus 4506 %} 4507 4508 // Integer ALU reg-mem operation 4509 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4510 %{ 4511 single_instruction; 4512 dst : S5(write); 4513 mem : S3(read); 4514 D0 : S0; // big decoder only 4515 ALU : S4; // any alu 4516 MEM : S3; // any mem 4517 %} 4518 4519 // Integer mem operation (prefetch) 4520 pipe_class ialu_mem(memory mem) 4521 %{ 4522 single_instruction; 4523 mem : S3(read); 4524 D0 : S0; // big decoder only 4525 MEM : S3; // any mem 4526 %} 4527 4528 // Integer Store to Memory 4529 pipe_class ialu_mem_reg(memory mem, rRegI src) 4530 %{ 4531 single_instruction; 4532 mem : S3(read); 4533 src : S5(read); 4534 D0 : S0; // big decoder only 4535 ALU : S4; // any alu 4536 MEM : S3; 4537 %} 4538 4539 // // Long Store to Memory 4540 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4541 // %{ 4542 // instruction_count(2); 4543 // mem : S3(read); 4544 // src : S5(read); 4545 // D0 : S0(2); // big decoder only; twice 4546 // ALU : S4(2); // any 2 alus 4547 // MEM : S3(2); // Both mems 4548 // %} 4549 4550 // Integer Store to Memory 4551 pipe_class ialu_mem_imm(memory mem) 4552 %{ 4553 single_instruction; 4554 mem : S3(read); 4555 D0 : S0; // big decoder only 4556 ALU : S4; // any alu 4557 MEM : S3; 4558 %} 4559 4560 // Integer ALU0 reg-reg operation 4561 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4562 %{ 4563 single_instruction; 4564 dst : S4(write); 4565 src : S3(read); 4566 D0 : S0; // Big decoder only 4567 ALU0 : S3; // only alu0 4568 %} 4569 4570 // Integer ALU0 reg-mem operation 4571 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4572 %{ 4573 single_instruction; 4574 dst : S5(write); 4575 mem : S3(read); 4576 D0 : S0; // big decoder only 4577 ALU0 : S4; // ALU0 only 4578 MEM : S3; // any mem 4579 %} 4580 4581 // Integer ALU reg-reg operation 4582 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4583 %{ 4584 single_instruction; 4585 cr : S4(write); 4586 src1 : S3(read); 4587 src2 : S3(read); 4588 DECODE : S0; // any decoder 4589 ALU : S3; // any alu 4590 %} 4591 4592 // Integer ALU reg-imm operation 4593 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4594 %{ 4595 single_instruction; 4596 cr : S4(write); 4597 src1 : S3(read); 4598 DECODE : S0; // any decoder 4599 ALU : S3; // any alu 4600 %} 4601 4602 // Integer ALU reg-mem operation 4603 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4604 %{ 4605 single_instruction; 4606 cr : S4(write); 4607 src1 : S3(read); 4608 src2 : S3(read); 4609 D0 : S0; // big decoder only 4610 ALU : S4; // any alu 4611 MEM : S3; 4612 %} 4613 4614 // Conditional move reg-reg 4615 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4616 %{ 4617 instruction_count(4); 4618 y : S4(read); 4619 q : S3(read); 4620 p : S3(read); 4621 DECODE : S0(4); // any decoder 4622 %} 4623 4624 // Conditional move reg-reg 4625 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4626 %{ 4627 single_instruction; 4628 dst : S4(write); 4629 src : S3(read); 4630 cr : S3(read); 4631 DECODE : S0; // any decoder 4632 %} 4633 4634 // Conditional move reg-mem 4635 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4636 %{ 4637 single_instruction; 4638 dst : S4(write); 4639 src : S3(read); 4640 cr : S3(read); 4641 DECODE : S0; // any decoder 4642 MEM : S3; 4643 %} 4644 4645 // Conditional move reg-reg long 4646 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4647 %{ 4648 single_instruction; 4649 dst : S4(write); 4650 src : S3(read); 4651 cr : S3(read); 4652 DECODE : S0(2); // any 2 decoders 4653 %} 4654 4655 // XXX 4656 // // Conditional move double reg-reg 4657 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4658 // %{ 4659 // single_instruction; 4660 // dst : S4(write); 4661 // src : S3(read); 4662 // cr : S3(read); 4663 // DECODE : S0; // any decoder 4664 // %} 4665 4666 // Float reg-reg operation 4667 pipe_class fpu_reg(regD dst) 4668 %{ 4669 instruction_count(2); 4670 dst : S3(read); 4671 DECODE : S0(2); // any 2 decoders 4672 FPU : S3; 4673 %} 4674 4675 // Float reg-reg operation 4676 pipe_class fpu_reg_reg(regD dst, regD src) 4677 %{ 4678 instruction_count(2); 4679 dst : S4(write); 4680 src : S3(read); 4681 DECODE : S0(2); // any 2 decoders 4682 FPU : S3; 4683 %} 4684 4685 // Float reg-reg operation 4686 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4687 %{ 4688 instruction_count(3); 4689 dst : S4(write); 4690 src1 : S3(read); 4691 src2 : S3(read); 4692 DECODE : S0(3); // any 3 decoders 4693 FPU : S3(2); 4694 %} 4695 4696 // Float reg-reg operation 4697 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4698 %{ 4699 instruction_count(4); 4700 dst : S4(write); 4701 src1 : S3(read); 4702 src2 : S3(read); 4703 src3 : S3(read); 4704 DECODE : S0(4); // any 3 decoders 4705 FPU : S3(2); 4706 %} 4707 4708 // Float reg-reg operation 4709 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4710 %{ 4711 instruction_count(4); 4712 dst : S4(write); 4713 src1 : S3(read); 4714 src2 : S3(read); 4715 src3 : S3(read); 4716 DECODE : S1(3); // any 3 decoders 4717 D0 : S0; // Big decoder only 4718 FPU : S3(2); 4719 MEM : S3; 4720 %} 4721 4722 // Float reg-mem operation 4723 pipe_class fpu_reg_mem(regD dst, memory mem) 4724 %{ 4725 instruction_count(2); 4726 dst : S5(write); 4727 mem : S3(read); 4728 D0 : S0; // big decoder only 4729 DECODE : S1; // any decoder for FPU POP 4730 FPU : S4; 4731 MEM : S3; // any mem 4732 %} 4733 4734 // Float reg-mem operation 4735 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4736 %{ 4737 instruction_count(3); 4738 dst : S5(write); 4739 src1 : S3(read); 4740 mem : S3(read); 4741 D0 : S0; // big decoder only 4742 DECODE : S1(2); // any decoder for FPU POP 4743 FPU : S4; 4744 MEM : S3; // any mem 4745 %} 4746 4747 // Float mem-reg operation 4748 pipe_class fpu_mem_reg(memory mem, regD src) 4749 %{ 4750 instruction_count(2); 4751 src : S5(read); 4752 mem : S3(read); 4753 DECODE : S0; // any decoder for FPU PUSH 4754 D0 : S1; // big decoder only 4755 FPU : S4; 4756 MEM : S3; // any mem 4757 %} 4758 4759 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4760 %{ 4761 instruction_count(3); 4762 src1 : S3(read); 4763 src2 : S3(read); 4764 mem : S3(read); 4765 DECODE : S0(2); // any decoder for FPU PUSH 4766 D0 : S1; // big decoder only 4767 FPU : S4; 4768 MEM : S3; // any mem 4769 %} 4770 4771 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4772 %{ 4773 instruction_count(3); 4774 src1 : S3(read); 4775 src2 : S3(read); 4776 mem : S4(read); 4777 DECODE : S0; // any decoder for FPU PUSH 4778 D0 : S0(2); // big decoder only 4779 FPU : S4; 4780 MEM : S3(2); // any mem 4781 %} 4782 4783 pipe_class fpu_mem_mem(memory dst, memory src1) 4784 %{ 4785 instruction_count(2); 4786 src1 : S3(read); 4787 dst : S4(read); 4788 D0 : S0(2); // big decoder only 4789 MEM : S3(2); // any mem 4790 %} 4791 4792 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4793 %{ 4794 instruction_count(3); 4795 src1 : S3(read); 4796 src2 : S3(read); 4797 dst : S4(read); 4798 D0 : S0(3); // big decoder only 4799 FPU : S4; 4800 MEM : S3(3); // any mem 4801 %} 4802 4803 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4804 %{ 4805 instruction_count(3); 4806 src1 : S4(read); 4807 mem : S4(read); 4808 DECODE : S0; // any decoder for FPU PUSH 4809 D0 : S0(2); // big decoder only 4810 FPU : S4; 4811 MEM : S3(2); // any mem 4812 %} 4813 4814 // Float load constant 4815 pipe_class fpu_reg_con(regD dst) 4816 %{ 4817 instruction_count(2); 4818 dst : S5(write); 4819 D0 : S0; // big decoder only for the load 4820 DECODE : S1; // any decoder for FPU POP 4821 FPU : S4; 4822 MEM : S3; // any mem 4823 %} 4824 4825 // Float load constant 4826 pipe_class fpu_reg_reg_con(regD dst, regD src) 4827 %{ 4828 instruction_count(3); 4829 dst : S5(write); 4830 src : S3(read); 4831 D0 : S0; // big decoder only for the load 4832 DECODE : S1(2); // any decoder for FPU POP 4833 FPU : S4; 4834 MEM : S3; // any mem 4835 %} 4836 4837 // UnConditional branch 4838 pipe_class pipe_jmp(label labl) 4839 %{ 4840 single_instruction; 4841 BR : S3; 4842 %} 4843 4844 // Conditional branch 4845 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4846 %{ 4847 single_instruction; 4848 cr : S1(read); 4849 BR : S3; 4850 %} 4851 4852 // Allocation idiom 4853 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4854 %{ 4855 instruction_count(1); force_serialization; 4856 fixed_latency(6); 4857 heap_ptr : S3(read); 4858 DECODE : S0(3); 4859 D0 : S2; 4860 MEM : S3; 4861 ALU : S3(2); 4862 dst : S5(write); 4863 BR : S5; 4864 %} 4865 4866 // Generic big/slow expanded idiom 4867 pipe_class pipe_slow() 4868 %{ 4869 instruction_count(10); multiple_bundles; force_serialization; 4870 fixed_latency(100); 4871 D0 : S0(2); 4872 MEM : S3(2); 4873 %} 4874 4875 // The real do-nothing guy 4876 pipe_class empty() 4877 %{ 4878 instruction_count(0); 4879 %} 4880 4881 // Define the class for the Nop node 4882 define 4883 %{ 4884 MachNop = empty; 4885 %} 4886 4887 %} 4888 4889 //----------INSTRUCTIONS------------------------------------------------------- 4890 // 4891 // match -- States which machine-independent subtree may be replaced 4892 // by this instruction. 4893 // ins_cost -- The estimated cost of this instruction is used by instruction 4894 // selection to identify a minimum cost tree of machine 4895 // instructions that matches a tree of machine-independent 4896 // instructions. 4897 // format -- A string providing the disassembly for this instruction. 4898 // The value of an instruction's operand may be inserted 4899 // by referring to it with a '$' prefix. 4900 // opcode -- Three instruction opcodes may be provided. These are referred 4901 // to within an encode class as $primary, $secondary, and $tertiary 4902 // rrspectively. The primary opcode is commonly used to 4903 // indicate the type of machine instruction, while secondary 4904 // and tertiary are often used for prefix options or addressing 4905 // modes. 4906 // ins_encode -- A list of encode classes with parameters. The encode class 4907 // name must have been defined in an 'enc_class' specification 4908 // in the encode section of the architecture description. 4909 4910 4911 //----------Load/Store/Move Instructions--------------------------------------- 4912 //----------Load Instructions-------------------------------------------------- 4913 4914 // Load Byte (8 bit signed) 4915 instruct loadB(rRegI dst, memory mem) 4916 %{ 4917 match(Set dst (LoadB mem)); 4918 4919 ins_cost(125); 4920 format %{ "movsbl $dst, $mem\t# byte" %} 4921 4922 ins_encode %{ 4923 __ movsbl($dst$$Register, $mem$$Address); 4924 %} 4925 4926 ins_pipe(ialu_reg_mem); 4927 %} 4928 4929 // Load Byte (8 bit signed) into Long Register 4930 instruct loadB2L(rRegL dst, memory mem) 4931 %{ 4932 match(Set dst (ConvI2L (LoadB mem))); 4933 4934 ins_cost(125); 4935 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4936 4937 ins_encode %{ 4938 __ movsbq($dst$$Register, $mem$$Address); 4939 %} 4940 4941 ins_pipe(ialu_reg_mem); 4942 %} 4943 4944 // Load Unsigned Byte (8 bit UNsigned) 4945 instruct loadUB(rRegI dst, memory mem) 4946 %{ 4947 match(Set dst (LoadUB mem)); 4948 4949 ins_cost(125); 4950 format %{ "movzbl $dst, $mem\t# ubyte" %} 4951 4952 ins_encode %{ 4953 __ movzbl($dst$$Register, $mem$$Address); 4954 %} 4955 4956 ins_pipe(ialu_reg_mem); 4957 %} 4958 4959 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4960 instruct loadUB2L(rRegL dst, memory mem) 4961 %{ 4962 match(Set dst (ConvI2L (LoadUB mem))); 4963 4964 ins_cost(125); 4965 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4966 4967 ins_encode %{ 4968 __ movzbq($dst$$Register, $mem$$Address); 4969 %} 4970 4971 ins_pipe(ialu_reg_mem); 4972 %} 4973 4974 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4975 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4976 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4977 effect(KILL cr); 4978 4979 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4980 "andl $dst, right_n_bits($mask, 8)" %} 4981 ins_encode %{ 4982 Register Rdst = $dst$$Register; 4983 __ movzbq(Rdst, $mem$$Address); 4984 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4985 %} 4986 ins_pipe(ialu_reg_mem); 4987 %} 4988 4989 // Load Short (16 bit signed) 4990 instruct loadS(rRegI dst, memory mem) 4991 %{ 4992 match(Set dst (LoadS mem)); 4993 4994 ins_cost(125); 4995 format %{ "movswl $dst, $mem\t# short" %} 4996 4997 ins_encode %{ 4998 __ movswl($dst$$Register, $mem$$Address); 4999 %} 5000 5001 ins_pipe(ialu_reg_mem); 5002 %} 5003 5004 // Load Short (16 bit signed) to Byte (8 bit signed) 5005 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5006 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5007 5008 ins_cost(125); 5009 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5010 ins_encode %{ 5011 __ movsbl($dst$$Register, $mem$$Address); 5012 %} 5013 ins_pipe(ialu_reg_mem); 5014 %} 5015 5016 // Load Short (16 bit signed) into Long Register 5017 instruct loadS2L(rRegL dst, memory mem) 5018 %{ 5019 match(Set dst (ConvI2L (LoadS mem))); 5020 5021 ins_cost(125); 5022 format %{ "movswq $dst, $mem\t# short -> long" %} 5023 5024 ins_encode %{ 5025 __ movswq($dst$$Register, $mem$$Address); 5026 %} 5027 5028 ins_pipe(ialu_reg_mem); 5029 %} 5030 5031 // Load Unsigned Short/Char (16 bit UNsigned) 5032 instruct loadUS(rRegI dst, memory mem) 5033 %{ 5034 match(Set dst (LoadUS mem)); 5035 5036 ins_cost(125); 5037 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5038 5039 ins_encode %{ 5040 __ movzwl($dst$$Register, $mem$$Address); 5041 %} 5042 5043 ins_pipe(ialu_reg_mem); 5044 %} 5045 5046 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5047 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5048 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5049 5050 ins_cost(125); 5051 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5052 ins_encode %{ 5053 __ movsbl($dst$$Register, $mem$$Address); 5054 %} 5055 ins_pipe(ialu_reg_mem); 5056 %} 5057 5058 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5059 instruct loadUS2L(rRegL dst, memory mem) 5060 %{ 5061 match(Set dst (ConvI2L (LoadUS mem))); 5062 5063 ins_cost(125); 5064 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5065 5066 ins_encode %{ 5067 __ movzwq($dst$$Register, $mem$$Address); 5068 %} 5069 5070 ins_pipe(ialu_reg_mem); 5071 %} 5072 5073 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5074 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5075 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5076 5077 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5078 ins_encode %{ 5079 __ movzbq($dst$$Register, $mem$$Address); 5080 %} 5081 ins_pipe(ialu_reg_mem); 5082 %} 5083 5084 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 5085 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5086 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5087 effect(KILL cr); 5088 5089 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 5090 "andl $dst, right_n_bits($mask, 16)" %} 5091 ins_encode %{ 5092 Register Rdst = $dst$$Register; 5093 __ movzwq(Rdst, $mem$$Address); 5094 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 5095 %} 5096 ins_pipe(ialu_reg_mem); 5097 %} 5098 5099 // Load Integer 5100 instruct loadI(rRegI dst, memory mem) 5101 %{ 5102 match(Set dst (LoadI mem)); 5103 5104 ins_cost(125); 5105 format %{ "movl $dst, $mem\t# int" %} 5106 5107 ins_encode %{ 5108 __ movl($dst$$Register, $mem$$Address); 5109 %} 5110 5111 ins_pipe(ialu_reg_mem); 5112 %} 5113 5114 // Load Integer (32 bit signed) to Byte (8 bit signed) 5115 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5116 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5117 5118 ins_cost(125); 5119 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5120 ins_encode %{ 5121 __ movsbl($dst$$Register, $mem$$Address); 5122 %} 5123 ins_pipe(ialu_reg_mem); 5124 %} 5125 5126 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5127 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5128 match(Set dst (AndI (LoadI mem) mask)); 5129 5130 ins_cost(125); 5131 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5132 ins_encode %{ 5133 __ movzbl($dst$$Register, $mem$$Address); 5134 %} 5135 ins_pipe(ialu_reg_mem); 5136 %} 5137 5138 // Load Integer (32 bit signed) to Short (16 bit signed) 5139 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5140 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5141 5142 ins_cost(125); 5143 format %{ "movswl $dst, $mem\t# int -> short" %} 5144 ins_encode %{ 5145 __ movswl($dst$$Register, $mem$$Address); 5146 %} 5147 ins_pipe(ialu_reg_mem); 5148 %} 5149 5150 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5151 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5152 match(Set dst (AndI (LoadI mem) mask)); 5153 5154 ins_cost(125); 5155 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5156 ins_encode %{ 5157 __ movzwl($dst$$Register, $mem$$Address); 5158 %} 5159 ins_pipe(ialu_reg_mem); 5160 %} 5161 5162 // Load Integer into Long Register 5163 instruct loadI2L(rRegL dst, memory mem) 5164 %{ 5165 match(Set dst (ConvI2L (LoadI mem))); 5166 5167 ins_cost(125); 5168 format %{ "movslq $dst, $mem\t# int -> long" %} 5169 5170 ins_encode %{ 5171 __ movslq($dst$$Register, $mem$$Address); 5172 %} 5173 5174 ins_pipe(ialu_reg_mem); 5175 %} 5176 5177 // Load Integer with mask 0xFF into Long Register 5178 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5179 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5180 5181 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5182 ins_encode %{ 5183 __ movzbq($dst$$Register, $mem$$Address); 5184 %} 5185 ins_pipe(ialu_reg_mem); 5186 %} 5187 5188 // Load Integer with mask 0xFFFF into Long Register 5189 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5190 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5191 5192 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5193 ins_encode %{ 5194 __ movzwq($dst$$Register, $mem$$Address); 5195 %} 5196 ins_pipe(ialu_reg_mem); 5197 %} 5198 5199 // Load Integer with a 31-bit mask into Long Register 5200 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5201 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5202 effect(KILL cr); 5203 5204 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5205 "andl $dst, $mask" %} 5206 ins_encode %{ 5207 Register Rdst = $dst$$Register; 5208 __ movl(Rdst, $mem$$Address); 5209 __ andl(Rdst, $mask$$constant); 5210 %} 5211 ins_pipe(ialu_reg_mem); 5212 %} 5213 5214 // Load Unsigned Integer into Long Register 5215 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5216 %{ 5217 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5218 5219 ins_cost(125); 5220 format %{ "movl $dst, $mem\t# uint -> long" %} 5221 5222 ins_encode %{ 5223 __ movl($dst$$Register, $mem$$Address); 5224 %} 5225 5226 ins_pipe(ialu_reg_mem); 5227 %} 5228 5229 // Load Long 5230 instruct loadL(rRegL dst, memory mem) 5231 %{ 5232 match(Set dst (LoadL mem)); 5233 5234 ins_cost(125); 5235 format %{ "movq $dst, $mem\t# long" %} 5236 5237 ins_encode %{ 5238 __ movq($dst$$Register, $mem$$Address); 5239 %} 5240 5241 ins_pipe(ialu_reg_mem); // XXX 5242 %} 5243 5244 // Load Range 5245 instruct loadRange(rRegI dst, memory mem) 5246 %{ 5247 match(Set dst (LoadRange mem)); 5248 5249 ins_cost(125); // XXX 5250 format %{ "movl $dst, $mem\t# range" %} 5251 opcode(0x8B); 5252 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5253 ins_pipe(ialu_reg_mem); 5254 %} 5255 5256 // Load Pointer 5257 instruct loadP(rRegP dst, memory mem) 5258 %{ 5259 match(Set dst (LoadP mem)); 5260 5261 ins_cost(125); // XXX 5262 format %{ "movq $dst, $mem\t# ptr" %} 5263 opcode(0x8B); 5264 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5265 ins_pipe(ialu_reg_mem); // XXX 5266 %} 5267 5268 // Load Compressed Pointer 5269 instruct loadN(rRegN dst, memory mem) 5270 %{ 5271 match(Set dst (LoadN mem)); 5272 5273 ins_cost(125); // XXX 5274 format %{ "movl $dst, $mem\t# compressed ptr" %} 5275 ins_encode %{ 5276 __ movl($dst$$Register, $mem$$Address); 5277 %} 5278 ins_pipe(ialu_reg_mem); // XXX 5279 %} 5280 5281 5282 // Load Klass Pointer 5283 instruct loadKlass(rRegP dst, memory mem) 5284 %{ 5285 match(Set dst (LoadKlass mem)); 5286 5287 ins_cost(125); // XXX 5288 format %{ "movq $dst, $mem\t# class" %} 5289 opcode(0x8B); 5290 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5291 ins_pipe(ialu_reg_mem); // XXX 5292 %} 5293 5294 // Load narrow Klass Pointer 5295 instruct loadNKlass(rRegN dst, memory mem) 5296 %{ 5297 match(Set dst (LoadNKlass mem)); 5298 5299 ins_cost(125); // XXX 5300 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5301 ins_encode %{ 5302 __ movl($dst$$Register, $mem$$Address); 5303 %} 5304 ins_pipe(ialu_reg_mem); // XXX 5305 %} 5306 5307 // Load Float 5308 instruct loadF(regF dst, memory mem) 5309 %{ 5310 match(Set dst (LoadF mem)); 5311 5312 ins_cost(145); // XXX 5313 format %{ "movss $dst, $mem\t# float" %} 5314 ins_encode %{ 5315 __ movflt($dst$$XMMRegister, $mem$$Address); 5316 %} 5317 ins_pipe(pipe_slow); // XXX 5318 %} 5319 5320 // Load Double 5321 instruct loadD_partial(regD dst, memory mem) 5322 %{ 5323 predicate(!UseXmmLoadAndClearUpper); 5324 match(Set dst (LoadD mem)); 5325 5326 ins_cost(145); // XXX 5327 format %{ "movlpd $dst, $mem\t# double" %} 5328 ins_encode %{ 5329 __ movdbl($dst$$XMMRegister, $mem$$Address); 5330 %} 5331 ins_pipe(pipe_slow); // XXX 5332 %} 5333 5334 instruct loadD(regD dst, memory mem) 5335 %{ 5336 predicate(UseXmmLoadAndClearUpper); 5337 match(Set dst (LoadD mem)); 5338 5339 ins_cost(145); // XXX 5340 format %{ "movsd $dst, $mem\t# double" %} 5341 ins_encode %{ 5342 __ movdbl($dst$$XMMRegister, $mem$$Address); 5343 %} 5344 ins_pipe(pipe_slow); // XXX 5345 %} 5346 5347 // Load Effective Address 5348 instruct leaP8(rRegP dst, indOffset8 mem) 5349 %{ 5350 match(Set dst mem); 5351 5352 ins_cost(110); // XXX 5353 format %{ "leaq $dst, $mem\t# ptr 8" %} 5354 opcode(0x8D); 5355 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5356 ins_pipe(ialu_reg_reg_fat); 5357 %} 5358 5359 instruct leaP32(rRegP dst, indOffset32 mem) 5360 %{ 5361 match(Set dst mem); 5362 5363 ins_cost(110); 5364 format %{ "leaq $dst, $mem\t# ptr 32" %} 5365 opcode(0x8D); 5366 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5367 ins_pipe(ialu_reg_reg_fat); 5368 %} 5369 5370 // instruct leaPIdx(rRegP dst, indIndex mem) 5371 // %{ 5372 // match(Set dst mem); 5373 5374 // ins_cost(110); 5375 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5376 // opcode(0x8D); 5377 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5378 // ins_pipe(ialu_reg_reg_fat); 5379 // %} 5380 5381 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5382 %{ 5383 match(Set dst mem); 5384 5385 ins_cost(110); 5386 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5387 opcode(0x8D); 5388 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5389 ins_pipe(ialu_reg_reg_fat); 5390 %} 5391 5392 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5393 %{ 5394 match(Set dst mem); 5395 5396 ins_cost(110); 5397 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5398 opcode(0x8D); 5399 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5400 ins_pipe(ialu_reg_reg_fat); 5401 %} 5402 5403 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5404 %{ 5405 match(Set dst mem); 5406 5407 ins_cost(110); 5408 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5409 opcode(0x8D); 5410 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5411 ins_pipe(ialu_reg_reg_fat); 5412 %} 5413 5414 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5415 %{ 5416 match(Set dst mem); 5417 5418 ins_cost(110); 5419 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5420 opcode(0x8D); 5421 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5422 ins_pipe(ialu_reg_reg_fat); 5423 %} 5424 5425 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5426 %{ 5427 match(Set dst mem); 5428 5429 ins_cost(110); 5430 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5431 opcode(0x8D); 5432 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5433 ins_pipe(ialu_reg_reg_fat); 5434 %} 5435 5436 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5437 %{ 5438 match(Set dst mem); 5439 5440 ins_cost(110); 5441 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5442 opcode(0x8D); 5443 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5444 ins_pipe(ialu_reg_reg_fat); 5445 %} 5446 5447 // Load Effective Address which uses Narrow (32-bits) oop 5448 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5449 %{ 5450 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5451 match(Set dst mem); 5452 5453 ins_cost(110); 5454 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5455 opcode(0x8D); 5456 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5457 ins_pipe(ialu_reg_reg_fat); 5458 %} 5459 5460 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5461 %{ 5462 predicate(Universe::narrow_oop_shift() == 0); 5463 match(Set dst mem); 5464 5465 ins_cost(110); // XXX 5466 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5467 opcode(0x8D); 5468 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5469 ins_pipe(ialu_reg_reg_fat); 5470 %} 5471 5472 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5473 %{ 5474 predicate(Universe::narrow_oop_shift() == 0); 5475 match(Set dst mem); 5476 5477 ins_cost(110); 5478 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5479 opcode(0x8D); 5480 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5481 ins_pipe(ialu_reg_reg_fat); 5482 %} 5483 5484 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5485 %{ 5486 predicate(Universe::narrow_oop_shift() == 0); 5487 match(Set dst mem); 5488 5489 ins_cost(110); 5490 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5491 opcode(0x8D); 5492 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5493 ins_pipe(ialu_reg_reg_fat); 5494 %} 5495 5496 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5497 %{ 5498 predicate(Universe::narrow_oop_shift() == 0); 5499 match(Set dst mem); 5500 5501 ins_cost(110); 5502 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5503 opcode(0x8D); 5504 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5505 ins_pipe(ialu_reg_reg_fat); 5506 %} 5507 5508 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5509 %{ 5510 predicate(Universe::narrow_oop_shift() == 0); 5511 match(Set dst mem); 5512 5513 ins_cost(110); 5514 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5515 opcode(0x8D); 5516 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5517 ins_pipe(ialu_reg_reg_fat); 5518 %} 5519 5520 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5521 %{ 5522 predicate(Universe::narrow_oop_shift() == 0); 5523 match(Set dst mem); 5524 5525 ins_cost(110); 5526 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5527 opcode(0x8D); 5528 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5529 ins_pipe(ialu_reg_reg_fat); 5530 %} 5531 5532 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5533 %{ 5534 predicate(Universe::narrow_oop_shift() == 0); 5535 match(Set dst mem); 5536 5537 ins_cost(110); 5538 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5539 opcode(0x8D); 5540 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5541 ins_pipe(ialu_reg_reg_fat); 5542 %} 5543 5544 instruct loadConI(rRegI dst, immI src) 5545 %{ 5546 match(Set dst src); 5547 5548 format %{ "movl $dst, $src\t# int" %} 5549 ins_encode(load_immI(dst, src)); 5550 ins_pipe(ialu_reg_fat); // XXX 5551 %} 5552 5553 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5554 %{ 5555 match(Set dst src); 5556 effect(KILL cr); 5557 5558 ins_cost(50); 5559 format %{ "xorl $dst, $dst\t# int" %} 5560 opcode(0x33); /* + rd */ 5561 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5562 ins_pipe(ialu_reg); 5563 %} 5564 5565 instruct loadConL(rRegL dst, immL src) 5566 %{ 5567 match(Set dst src); 5568 5569 ins_cost(150); 5570 format %{ "movq $dst, $src\t# long" %} 5571 ins_encode(load_immL(dst, src)); 5572 ins_pipe(ialu_reg); 5573 %} 5574 5575 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5576 %{ 5577 match(Set dst src); 5578 effect(KILL cr); 5579 5580 ins_cost(50); 5581 format %{ "xorl $dst, $dst\t# long" %} 5582 opcode(0x33); /* + rd */ 5583 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5584 ins_pipe(ialu_reg); // XXX 5585 %} 5586 5587 instruct loadConUL32(rRegL dst, immUL32 src) 5588 %{ 5589 match(Set dst src); 5590 5591 ins_cost(60); 5592 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5593 ins_encode(load_immUL32(dst, src)); 5594 ins_pipe(ialu_reg); 5595 %} 5596 5597 instruct loadConL32(rRegL dst, immL32 src) 5598 %{ 5599 match(Set dst src); 5600 5601 ins_cost(70); 5602 format %{ "movq $dst, $src\t# long (32-bit)" %} 5603 ins_encode(load_immL32(dst, src)); 5604 ins_pipe(ialu_reg); 5605 %} 5606 5607 instruct loadConP(rRegP dst, immP con) %{ 5608 match(Set dst con); 5609 5610 format %{ "movq $dst, $con\t# ptr" %} 5611 ins_encode(load_immP(dst, con)); 5612 ins_pipe(ialu_reg_fat); // XXX 5613 %} 5614 5615 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5616 %{ 5617 match(Set dst src); 5618 effect(KILL cr); 5619 5620 ins_cost(50); 5621 format %{ "xorl $dst, $dst\t# ptr" %} 5622 opcode(0x33); /* + rd */ 5623 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5624 ins_pipe(ialu_reg); 5625 %} 5626 5627 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5628 %{ 5629 match(Set dst src); 5630 effect(KILL cr); 5631 5632 ins_cost(60); 5633 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5634 ins_encode(load_immP31(dst, src)); 5635 ins_pipe(ialu_reg); 5636 %} 5637 5638 instruct loadConF(regF dst, immF con) %{ 5639 match(Set dst con); 5640 ins_cost(125); 5641 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5642 ins_encode %{ 5643 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5644 %} 5645 ins_pipe(pipe_slow); 5646 %} 5647 5648 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5649 match(Set dst src); 5650 effect(KILL cr); 5651 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5652 ins_encode %{ 5653 __ xorq($dst$$Register, $dst$$Register); 5654 %} 5655 ins_pipe(ialu_reg); 5656 %} 5657 5658 instruct loadConN(rRegN dst, immN src) %{ 5659 match(Set dst src); 5660 5661 ins_cost(125); 5662 format %{ "movl $dst, $src\t# compressed ptr" %} 5663 ins_encode %{ 5664 address con = (address)$src$$constant; 5665 if (con == NULL) { 5666 ShouldNotReachHere(); 5667 } else { 5668 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5669 } 5670 %} 5671 ins_pipe(ialu_reg_fat); // XXX 5672 %} 5673 5674 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5675 match(Set dst src); 5676 5677 ins_cost(125); 5678 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5679 ins_encode %{ 5680 address con = (address)$src$$constant; 5681 if (con == NULL) { 5682 ShouldNotReachHere(); 5683 } else { 5684 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5685 } 5686 %} 5687 ins_pipe(ialu_reg_fat); // XXX 5688 %} 5689 5690 instruct loadConF0(regF dst, immF0 src) 5691 %{ 5692 match(Set dst src); 5693 ins_cost(100); 5694 5695 format %{ "xorps $dst, $dst\t# float 0.0" %} 5696 ins_encode %{ 5697 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5698 %} 5699 ins_pipe(pipe_slow); 5700 %} 5701 5702 // Use the same format since predicate() can not be used here. 5703 instruct loadConD(regD dst, immD con) %{ 5704 match(Set dst con); 5705 ins_cost(125); 5706 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5707 ins_encode %{ 5708 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5709 %} 5710 ins_pipe(pipe_slow); 5711 %} 5712 5713 instruct loadConD0(regD dst, immD0 src) 5714 %{ 5715 match(Set dst src); 5716 ins_cost(100); 5717 5718 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5719 ins_encode %{ 5720 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5721 %} 5722 ins_pipe(pipe_slow); 5723 %} 5724 5725 instruct loadSSI(rRegI dst, stackSlotI src) 5726 %{ 5727 match(Set dst src); 5728 5729 ins_cost(125); 5730 format %{ "movl $dst, $src\t# int stk" %} 5731 opcode(0x8B); 5732 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5733 ins_pipe(ialu_reg_mem); 5734 %} 5735 5736 instruct loadSSL(rRegL dst, stackSlotL src) 5737 %{ 5738 match(Set dst src); 5739 5740 ins_cost(125); 5741 format %{ "movq $dst, $src\t# long stk" %} 5742 opcode(0x8B); 5743 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5744 ins_pipe(ialu_reg_mem); 5745 %} 5746 5747 instruct loadSSP(rRegP dst, stackSlotP src) 5748 %{ 5749 match(Set dst src); 5750 5751 ins_cost(125); 5752 format %{ "movq $dst, $src\t# ptr stk" %} 5753 opcode(0x8B); 5754 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5755 ins_pipe(ialu_reg_mem); 5756 %} 5757 5758 instruct loadSSF(regF dst, stackSlotF src) 5759 %{ 5760 match(Set dst src); 5761 5762 ins_cost(125); 5763 format %{ "movss $dst, $src\t# float stk" %} 5764 ins_encode %{ 5765 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5766 %} 5767 ins_pipe(pipe_slow); // XXX 5768 %} 5769 5770 // Use the same format since predicate() can not be used here. 5771 instruct loadSSD(regD dst, stackSlotD src) 5772 %{ 5773 match(Set dst src); 5774 5775 ins_cost(125); 5776 format %{ "movsd $dst, $src\t# double stk" %} 5777 ins_encode %{ 5778 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5779 %} 5780 ins_pipe(pipe_slow); // XXX 5781 %} 5782 5783 // Prefetch instructions for allocation. 5784 // Must be safe to execute with invalid address (cannot fault). 5785 5786 instruct prefetchAlloc( memory mem ) %{ 5787 predicate(AllocatePrefetchInstr==3); 5788 match(PrefetchAllocation mem); 5789 ins_cost(125); 5790 5791 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5792 ins_encode %{ 5793 __ prefetchw($mem$$Address); 5794 %} 5795 ins_pipe(ialu_mem); 5796 %} 5797 5798 instruct prefetchAllocNTA( memory mem ) %{ 5799 predicate(AllocatePrefetchInstr==0); 5800 match(PrefetchAllocation mem); 5801 ins_cost(125); 5802 5803 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5804 ins_encode %{ 5805 __ prefetchnta($mem$$Address); 5806 %} 5807 ins_pipe(ialu_mem); 5808 %} 5809 5810 instruct prefetchAllocT0( memory mem ) %{ 5811 predicate(AllocatePrefetchInstr==1); 5812 match(PrefetchAllocation mem); 5813 ins_cost(125); 5814 5815 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5816 ins_encode %{ 5817 __ prefetcht0($mem$$Address); 5818 %} 5819 ins_pipe(ialu_mem); 5820 %} 5821 5822 instruct prefetchAllocT2( memory mem ) %{ 5823 predicate(AllocatePrefetchInstr==2); 5824 match(PrefetchAllocation mem); 5825 ins_cost(125); 5826 5827 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5828 ins_encode %{ 5829 __ prefetcht2($mem$$Address); 5830 %} 5831 ins_pipe(ialu_mem); 5832 %} 5833 5834 //----------Store Instructions------------------------------------------------- 5835 5836 // Store Byte 5837 instruct storeB(memory mem, rRegI src) 5838 %{ 5839 match(Set mem (StoreB mem src)); 5840 5841 ins_cost(125); // XXX 5842 format %{ "movb $mem, $src\t# byte" %} 5843 opcode(0x88); 5844 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5845 ins_pipe(ialu_mem_reg); 5846 %} 5847 5848 // Store Char/Short 5849 instruct storeC(memory mem, rRegI src) 5850 %{ 5851 match(Set mem (StoreC mem src)); 5852 5853 ins_cost(125); // XXX 5854 format %{ "movw $mem, $src\t# char/short" %} 5855 opcode(0x89); 5856 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5857 ins_pipe(ialu_mem_reg); 5858 %} 5859 5860 // Store Integer 5861 instruct storeI(memory mem, rRegI src) 5862 %{ 5863 match(Set mem (StoreI mem src)); 5864 5865 ins_cost(125); // XXX 5866 format %{ "movl $mem, $src\t# int" %} 5867 opcode(0x89); 5868 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5869 ins_pipe(ialu_mem_reg); 5870 %} 5871 5872 // Store Long 5873 instruct storeL(memory mem, rRegL src) 5874 %{ 5875 match(Set mem (StoreL mem src)); 5876 5877 ins_cost(125); // XXX 5878 format %{ "movq $mem, $src\t# long" %} 5879 opcode(0x89); 5880 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5881 ins_pipe(ialu_mem_reg); // XXX 5882 %} 5883 5884 // Store Pointer 5885 instruct storeP(memory mem, any_RegP src) 5886 %{ 5887 match(Set mem (StoreP mem src)); 5888 5889 ins_cost(125); // XXX 5890 format %{ "movq $mem, $src\t# ptr" %} 5891 opcode(0x89); 5892 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5893 ins_pipe(ialu_mem_reg); 5894 %} 5895 5896 instruct storeImmP0(memory mem, immP0 zero) 5897 %{ 5898 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5899 match(Set mem (StoreP mem zero)); 5900 5901 ins_cost(125); // XXX 5902 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5903 ins_encode %{ 5904 __ movq($mem$$Address, r12); 5905 %} 5906 ins_pipe(ialu_mem_reg); 5907 %} 5908 5909 // Store NULL Pointer, mark word, or other simple pointer constant. 5910 instruct storeImmP(memory mem, immP31 src) 5911 %{ 5912 match(Set mem (StoreP mem src)); 5913 5914 ins_cost(150); // XXX 5915 format %{ "movq $mem, $src\t# ptr" %} 5916 opcode(0xC7); /* C7 /0 */ 5917 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5918 ins_pipe(ialu_mem_imm); 5919 %} 5920 5921 // Store Compressed Pointer 5922 instruct storeN(memory mem, rRegN src) 5923 %{ 5924 match(Set mem (StoreN mem src)); 5925 5926 ins_cost(125); // XXX 5927 format %{ "movl $mem, $src\t# compressed ptr" %} 5928 ins_encode %{ 5929 __ movl($mem$$Address, $src$$Register); 5930 %} 5931 ins_pipe(ialu_mem_reg); 5932 %} 5933 5934 instruct storeNKlass(memory mem, rRegN src) 5935 %{ 5936 match(Set mem (StoreNKlass mem src)); 5937 5938 ins_cost(125); // XXX 5939 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5940 ins_encode %{ 5941 __ movl($mem$$Address, $src$$Register); 5942 %} 5943 ins_pipe(ialu_mem_reg); 5944 %} 5945 5946 instruct storeImmN0(memory mem, immN0 zero) 5947 %{ 5948 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5949 match(Set mem (StoreN mem zero)); 5950 5951 ins_cost(125); // XXX 5952 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5953 ins_encode %{ 5954 __ movl($mem$$Address, r12); 5955 %} 5956 ins_pipe(ialu_mem_reg); 5957 %} 5958 5959 instruct storeImmN(memory mem, immN src) 5960 %{ 5961 match(Set mem (StoreN mem src)); 5962 5963 ins_cost(150); // XXX 5964 format %{ "movl $mem, $src\t# compressed ptr" %} 5965 ins_encode %{ 5966 address con = (address)$src$$constant; 5967 if (con == NULL) { 5968 __ movl($mem$$Address, (int32_t)0); 5969 } else { 5970 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5971 } 5972 %} 5973 ins_pipe(ialu_mem_imm); 5974 %} 5975 5976 instruct storeImmNKlass(memory mem, immNKlass src) 5977 %{ 5978 match(Set mem (StoreNKlass mem src)); 5979 5980 ins_cost(150); // XXX 5981 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5982 ins_encode %{ 5983 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5984 %} 5985 ins_pipe(ialu_mem_imm); 5986 %} 5987 5988 // Store Integer Immediate 5989 instruct storeImmI0(memory mem, immI0 zero) 5990 %{ 5991 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5992 match(Set mem (StoreI mem zero)); 5993 5994 ins_cost(125); // XXX 5995 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5996 ins_encode %{ 5997 __ movl($mem$$Address, r12); 5998 %} 5999 ins_pipe(ialu_mem_reg); 6000 %} 6001 6002 instruct storeImmI(memory mem, immI src) 6003 %{ 6004 match(Set mem (StoreI mem src)); 6005 6006 ins_cost(150); 6007 format %{ "movl $mem, $src\t# int" %} 6008 opcode(0xC7); /* C7 /0 */ 6009 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6010 ins_pipe(ialu_mem_imm); 6011 %} 6012 6013 // Store Long Immediate 6014 instruct storeImmL0(memory mem, immL0 zero) 6015 %{ 6016 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6017 match(Set mem (StoreL mem zero)); 6018 6019 ins_cost(125); // XXX 6020 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6021 ins_encode %{ 6022 __ movq($mem$$Address, r12); 6023 %} 6024 ins_pipe(ialu_mem_reg); 6025 %} 6026 6027 instruct storeImmL(memory mem, immL32 src) 6028 %{ 6029 match(Set mem (StoreL mem src)); 6030 6031 ins_cost(150); 6032 format %{ "movq $mem, $src\t# long" %} 6033 opcode(0xC7); /* C7 /0 */ 6034 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6035 ins_pipe(ialu_mem_imm); 6036 %} 6037 6038 // Store Short/Char Immediate 6039 instruct storeImmC0(memory mem, immI0 zero) 6040 %{ 6041 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6042 match(Set mem (StoreC mem zero)); 6043 6044 ins_cost(125); // XXX 6045 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6046 ins_encode %{ 6047 __ movw($mem$$Address, r12); 6048 %} 6049 ins_pipe(ialu_mem_reg); 6050 %} 6051 6052 instruct storeImmI16(memory mem, immI16 src) 6053 %{ 6054 predicate(UseStoreImmI16); 6055 match(Set mem (StoreC mem src)); 6056 6057 ins_cost(150); 6058 format %{ "movw $mem, $src\t# short/char" %} 6059 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6060 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6061 ins_pipe(ialu_mem_imm); 6062 %} 6063 6064 // Store Byte Immediate 6065 instruct storeImmB0(memory mem, immI0 zero) 6066 %{ 6067 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6068 match(Set mem (StoreB mem zero)); 6069 6070 ins_cost(125); // XXX 6071 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6072 ins_encode %{ 6073 __ movb($mem$$Address, r12); 6074 %} 6075 ins_pipe(ialu_mem_reg); 6076 %} 6077 6078 instruct storeImmB(memory mem, immI8 src) 6079 %{ 6080 match(Set mem (StoreB mem src)); 6081 6082 ins_cost(150); // XXX 6083 format %{ "movb $mem, $src\t# byte" %} 6084 opcode(0xC6); /* C6 /0 */ 6085 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6086 ins_pipe(ialu_mem_imm); 6087 %} 6088 6089 // Store CMS card-mark Immediate 6090 instruct storeImmCM0_reg(memory mem, immI0 zero) 6091 %{ 6092 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6093 match(Set mem (StoreCM mem zero)); 6094 6095 ins_cost(125); // XXX 6096 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6097 ins_encode %{ 6098 __ movb($mem$$Address, r12); 6099 %} 6100 ins_pipe(ialu_mem_reg); 6101 %} 6102 6103 instruct storeImmCM0(memory mem, immI0 src) 6104 %{ 6105 match(Set mem (StoreCM mem src)); 6106 6107 ins_cost(150); // XXX 6108 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6109 opcode(0xC6); /* C6 /0 */ 6110 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6111 ins_pipe(ialu_mem_imm); 6112 %} 6113 6114 // Store Float 6115 instruct storeF(memory mem, regF src) 6116 %{ 6117 match(Set mem (StoreF mem src)); 6118 6119 ins_cost(95); // XXX 6120 format %{ "movss $mem, $src\t# float" %} 6121 ins_encode %{ 6122 __ movflt($mem$$Address, $src$$XMMRegister); 6123 %} 6124 ins_pipe(pipe_slow); // XXX 6125 %} 6126 6127 // Store immediate Float value (it is faster than store from XMM register) 6128 instruct storeF0(memory mem, immF0 zero) 6129 %{ 6130 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6131 match(Set mem (StoreF mem zero)); 6132 6133 ins_cost(25); // XXX 6134 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6135 ins_encode %{ 6136 __ movl($mem$$Address, r12); 6137 %} 6138 ins_pipe(ialu_mem_reg); 6139 %} 6140 6141 instruct storeF_imm(memory mem, immF src) 6142 %{ 6143 match(Set mem (StoreF mem src)); 6144 6145 ins_cost(50); 6146 format %{ "movl $mem, $src\t# float" %} 6147 opcode(0xC7); /* C7 /0 */ 6148 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6149 ins_pipe(ialu_mem_imm); 6150 %} 6151 6152 // Store Double 6153 instruct storeD(memory mem, regD src) 6154 %{ 6155 match(Set mem (StoreD mem src)); 6156 6157 ins_cost(95); // XXX 6158 format %{ "movsd $mem, $src\t# double" %} 6159 ins_encode %{ 6160 __ movdbl($mem$$Address, $src$$XMMRegister); 6161 %} 6162 ins_pipe(pipe_slow); // XXX 6163 %} 6164 6165 // Store immediate double 0.0 (it is faster than store from XMM register) 6166 instruct storeD0_imm(memory mem, immD0 src) 6167 %{ 6168 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6169 match(Set mem (StoreD mem src)); 6170 6171 ins_cost(50); 6172 format %{ "movq $mem, $src\t# double 0." %} 6173 opcode(0xC7); /* C7 /0 */ 6174 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6175 ins_pipe(ialu_mem_imm); 6176 %} 6177 6178 instruct storeD0(memory mem, immD0 zero) 6179 %{ 6180 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6181 match(Set mem (StoreD mem zero)); 6182 6183 ins_cost(25); // XXX 6184 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6185 ins_encode %{ 6186 __ movq($mem$$Address, r12); 6187 %} 6188 ins_pipe(ialu_mem_reg); 6189 %} 6190 6191 instruct storeSSI(stackSlotI dst, rRegI src) 6192 %{ 6193 match(Set dst src); 6194 6195 ins_cost(100); 6196 format %{ "movl $dst, $src\t# int stk" %} 6197 opcode(0x89); 6198 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6199 ins_pipe( ialu_mem_reg ); 6200 %} 6201 6202 instruct storeSSL(stackSlotL dst, rRegL src) 6203 %{ 6204 match(Set dst src); 6205 6206 ins_cost(100); 6207 format %{ "movq $dst, $src\t# long stk" %} 6208 opcode(0x89); 6209 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6210 ins_pipe(ialu_mem_reg); 6211 %} 6212 6213 instruct storeSSP(stackSlotP dst, rRegP src) 6214 %{ 6215 match(Set dst src); 6216 6217 ins_cost(100); 6218 format %{ "movq $dst, $src\t# ptr stk" %} 6219 opcode(0x89); 6220 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6221 ins_pipe(ialu_mem_reg); 6222 %} 6223 6224 instruct storeSSF(stackSlotF dst, regF src) 6225 %{ 6226 match(Set dst src); 6227 6228 ins_cost(95); // XXX 6229 format %{ "movss $dst, $src\t# float stk" %} 6230 ins_encode %{ 6231 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6232 %} 6233 ins_pipe(pipe_slow); // XXX 6234 %} 6235 6236 instruct storeSSD(stackSlotD dst, regD src) 6237 %{ 6238 match(Set dst src); 6239 6240 ins_cost(95); // XXX 6241 format %{ "movsd $dst, $src\t# double stk" %} 6242 ins_encode %{ 6243 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6244 %} 6245 ins_pipe(pipe_slow); // XXX 6246 %} 6247 6248 //----------BSWAP Instructions------------------------------------------------- 6249 instruct bytes_reverse_int(rRegI dst) %{ 6250 match(Set dst (ReverseBytesI dst)); 6251 6252 format %{ "bswapl $dst" %} 6253 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6254 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6255 ins_pipe( ialu_reg ); 6256 %} 6257 6258 instruct bytes_reverse_long(rRegL dst) %{ 6259 match(Set dst (ReverseBytesL dst)); 6260 6261 format %{ "bswapq $dst" %} 6262 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6263 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6264 ins_pipe( ialu_reg); 6265 %} 6266 6267 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6268 match(Set dst (ReverseBytesUS dst)); 6269 effect(KILL cr); 6270 6271 format %{ "bswapl $dst\n\t" 6272 "shrl $dst,16\n\t" %} 6273 ins_encode %{ 6274 __ bswapl($dst$$Register); 6275 __ shrl($dst$$Register, 16); 6276 %} 6277 ins_pipe( ialu_reg ); 6278 %} 6279 6280 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6281 match(Set dst (ReverseBytesS dst)); 6282 effect(KILL cr); 6283 6284 format %{ "bswapl $dst\n\t" 6285 "sar $dst,16\n\t" %} 6286 ins_encode %{ 6287 __ bswapl($dst$$Register); 6288 __ sarl($dst$$Register, 16); 6289 %} 6290 ins_pipe( ialu_reg ); 6291 %} 6292 6293 //---------- Zeros Count Instructions ------------------------------------------ 6294 6295 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6296 predicate(UseCountLeadingZerosInstruction); 6297 match(Set dst (CountLeadingZerosI src)); 6298 effect(KILL cr); 6299 6300 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6301 ins_encode %{ 6302 __ lzcntl($dst$$Register, $src$$Register); 6303 %} 6304 ins_pipe(ialu_reg); 6305 %} 6306 6307 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6308 predicate(!UseCountLeadingZerosInstruction); 6309 match(Set dst (CountLeadingZerosI src)); 6310 effect(KILL cr); 6311 6312 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6313 "jnz skip\n\t" 6314 "movl $dst, -1\n" 6315 "skip:\n\t" 6316 "negl $dst\n\t" 6317 "addl $dst, 31" %} 6318 ins_encode %{ 6319 Register Rdst = $dst$$Register; 6320 Register Rsrc = $src$$Register; 6321 Label skip; 6322 __ bsrl(Rdst, Rsrc); 6323 __ jccb(Assembler::notZero, skip); 6324 __ movl(Rdst, -1); 6325 __ bind(skip); 6326 __ negl(Rdst); 6327 __ addl(Rdst, BitsPerInt - 1); 6328 %} 6329 ins_pipe(ialu_reg); 6330 %} 6331 6332 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6333 predicate(UseCountLeadingZerosInstruction); 6334 match(Set dst (CountLeadingZerosL src)); 6335 effect(KILL cr); 6336 6337 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6338 ins_encode %{ 6339 __ lzcntq($dst$$Register, $src$$Register); 6340 %} 6341 ins_pipe(ialu_reg); 6342 %} 6343 6344 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6345 predicate(!UseCountLeadingZerosInstruction); 6346 match(Set dst (CountLeadingZerosL src)); 6347 effect(KILL cr); 6348 6349 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6350 "jnz skip\n\t" 6351 "movl $dst, -1\n" 6352 "skip:\n\t" 6353 "negl $dst\n\t" 6354 "addl $dst, 63" %} 6355 ins_encode %{ 6356 Register Rdst = $dst$$Register; 6357 Register Rsrc = $src$$Register; 6358 Label skip; 6359 __ bsrq(Rdst, Rsrc); 6360 __ jccb(Assembler::notZero, skip); 6361 __ movl(Rdst, -1); 6362 __ bind(skip); 6363 __ negl(Rdst); 6364 __ addl(Rdst, BitsPerLong - 1); 6365 %} 6366 ins_pipe(ialu_reg); 6367 %} 6368 6369 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6370 predicate(UseCountTrailingZerosInstruction); 6371 match(Set dst (CountTrailingZerosI src)); 6372 effect(KILL cr); 6373 6374 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6375 ins_encode %{ 6376 __ tzcntl($dst$$Register, $src$$Register); 6377 %} 6378 ins_pipe(ialu_reg); 6379 %} 6380 6381 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6382 predicate(!UseCountTrailingZerosInstruction); 6383 match(Set dst (CountTrailingZerosI src)); 6384 effect(KILL cr); 6385 6386 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6387 "jnz done\n\t" 6388 "movl $dst, 32\n" 6389 "done:" %} 6390 ins_encode %{ 6391 Register Rdst = $dst$$Register; 6392 Label done; 6393 __ bsfl(Rdst, $src$$Register); 6394 __ jccb(Assembler::notZero, done); 6395 __ movl(Rdst, BitsPerInt); 6396 __ bind(done); 6397 %} 6398 ins_pipe(ialu_reg); 6399 %} 6400 6401 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6402 predicate(UseCountTrailingZerosInstruction); 6403 match(Set dst (CountTrailingZerosL src)); 6404 effect(KILL cr); 6405 6406 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6407 ins_encode %{ 6408 __ tzcntq($dst$$Register, $src$$Register); 6409 %} 6410 ins_pipe(ialu_reg); 6411 %} 6412 6413 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6414 predicate(!UseCountTrailingZerosInstruction); 6415 match(Set dst (CountTrailingZerosL src)); 6416 effect(KILL cr); 6417 6418 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6419 "jnz done\n\t" 6420 "movl $dst, 64\n" 6421 "done:" %} 6422 ins_encode %{ 6423 Register Rdst = $dst$$Register; 6424 Label done; 6425 __ bsfq(Rdst, $src$$Register); 6426 __ jccb(Assembler::notZero, done); 6427 __ movl(Rdst, BitsPerLong); 6428 __ bind(done); 6429 %} 6430 ins_pipe(ialu_reg); 6431 %} 6432 6433 6434 //---------- Population Count Instructions ------------------------------------- 6435 6436 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6437 predicate(UsePopCountInstruction); 6438 match(Set dst (PopCountI src)); 6439 effect(KILL cr); 6440 6441 format %{ "popcnt $dst, $src" %} 6442 ins_encode %{ 6443 __ popcntl($dst$$Register, $src$$Register); 6444 %} 6445 ins_pipe(ialu_reg); 6446 %} 6447 6448 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6449 predicate(UsePopCountInstruction); 6450 match(Set dst (PopCountI (LoadI mem))); 6451 effect(KILL cr); 6452 6453 format %{ "popcnt $dst, $mem" %} 6454 ins_encode %{ 6455 __ popcntl($dst$$Register, $mem$$Address); 6456 %} 6457 ins_pipe(ialu_reg); 6458 %} 6459 6460 // Note: Long.bitCount(long) returns an int. 6461 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6462 predicate(UsePopCountInstruction); 6463 match(Set dst (PopCountL src)); 6464 effect(KILL cr); 6465 6466 format %{ "popcnt $dst, $src" %} 6467 ins_encode %{ 6468 __ popcntq($dst$$Register, $src$$Register); 6469 %} 6470 ins_pipe(ialu_reg); 6471 %} 6472 6473 // Note: Long.bitCount(long) returns an int. 6474 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6475 predicate(UsePopCountInstruction); 6476 match(Set dst (PopCountL (LoadL mem))); 6477 effect(KILL cr); 6478 6479 format %{ "popcnt $dst, $mem" %} 6480 ins_encode %{ 6481 __ popcntq($dst$$Register, $mem$$Address); 6482 %} 6483 ins_pipe(ialu_reg); 6484 %} 6485 6486 6487 //----------MemBar Instructions----------------------------------------------- 6488 // Memory barrier flavors 6489 6490 instruct membar_acquire() 6491 %{ 6492 match(MemBarAcquire); 6493 match(LoadFence); 6494 ins_cost(0); 6495 6496 size(0); 6497 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6498 ins_encode(); 6499 ins_pipe(empty); 6500 %} 6501 6502 instruct membar_acquire_lock() 6503 %{ 6504 match(MemBarAcquireLock); 6505 ins_cost(0); 6506 6507 size(0); 6508 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6509 ins_encode(); 6510 ins_pipe(empty); 6511 %} 6512 6513 instruct membar_release() 6514 %{ 6515 match(MemBarRelease); 6516 match(StoreFence); 6517 ins_cost(0); 6518 6519 size(0); 6520 format %{ "MEMBAR-release ! (empty encoding)" %} 6521 ins_encode(); 6522 ins_pipe(empty); 6523 %} 6524 6525 instruct membar_release_lock() 6526 %{ 6527 match(MemBarReleaseLock); 6528 ins_cost(0); 6529 6530 size(0); 6531 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6532 ins_encode(); 6533 ins_pipe(empty); 6534 %} 6535 6536 instruct membar_volatile(rFlagsReg cr) %{ 6537 match(MemBarVolatile); 6538 effect(KILL cr); 6539 ins_cost(400); 6540 6541 format %{ 6542 $$template 6543 if (os::is_MP()) { 6544 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6545 } else { 6546 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6547 } 6548 %} 6549 ins_encode %{ 6550 __ membar(Assembler::StoreLoad); 6551 %} 6552 ins_pipe(pipe_slow); 6553 %} 6554 6555 instruct unnecessary_membar_volatile() 6556 %{ 6557 match(MemBarVolatile); 6558 predicate(Matcher::post_store_load_barrier(n)); 6559 ins_cost(0); 6560 6561 size(0); 6562 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6563 ins_encode(); 6564 ins_pipe(empty); 6565 %} 6566 6567 instruct membar_storestore() %{ 6568 match(MemBarStoreStore); 6569 ins_cost(0); 6570 6571 size(0); 6572 format %{ "MEMBAR-storestore (empty encoding)" %} 6573 ins_encode( ); 6574 ins_pipe(empty); 6575 %} 6576 6577 //----------Move Instructions-------------------------------------------------- 6578 6579 instruct castX2P(rRegP dst, rRegL src) 6580 %{ 6581 match(Set dst (CastX2P src)); 6582 6583 format %{ "movq $dst, $src\t# long->ptr" %} 6584 ins_encode %{ 6585 if ($dst$$reg != $src$$reg) { 6586 __ movptr($dst$$Register, $src$$Register); 6587 } 6588 %} 6589 ins_pipe(ialu_reg_reg); // XXX 6590 %} 6591 6592 instruct castP2X(rRegL dst, rRegP src) 6593 %{ 6594 match(Set dst (CastP2X src)); 6595 6596 format %{ "movq $dst, $src\t# ptr -> long" %} 6597 ins_encode %{ 6598 if ($dst$$reg != $src$$reg) { 6599 __ movptr($dst$$Register, $src$$Register); 6600 } 6601 %} 6602 ins_pipe(ialu_reg_reg); // XXX 6603 %} 6604 6605 // Convert oop into int for vectors alignment masking 6606 instruct convP2I(rRegI dst, rRegP src) 6607 %{ 6608 match(Set dst (ConvL2I (CastP2X src))); 6609 6610 format %{ "movl $dst, $src\t# ptr -> int" %} 6611 ins_encode %{ 6612 __ movl($dst$$Register, $src$$Register); 6613 %} 6614 ins_pipe(ialu_reg_reg); // XXX 6615 %} 6616 6617 // Convert compressed oop into int for vectors alignment masking 6618 // in case of 32bit oops (heap < 4Gb). 6619 instruct convN2I(rRegI dst, rRegN src) 6620 %{ 6621 predicate(Universe::narrow_oop_shift() == 0); 6622 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6623 6624 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6625 ins_encode %{ 6626 __ movl($dst$$Register, $src$$Register); 6627 %} 6628 ins_pipe(ialu_reg_reg); // XXX 6629 %} 6630 6631 // Convert oop pointer into compressed form 6632 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6633 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6634 match(Set dst (EncodeP src)); 6635 effect(KILL cr); 6636 format %{ "encode_heap_oop $dst,$src" %} 6637 ins_encode %{ 6638 Register s = $src$$Register; 6639 Register d = $dst$$Register; 6640 if (s != d) { 6641 __ movq(d, s); 6642 } 6643 __ encode_heap_oop(d); 6644 %} 6645 ins_pipe(ialu_reg_long); 6646 %} 6647 6648 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6649 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6650 match(Set dst (EncodeP src)); 6651 effect(KILL cr); 6652 format %{ "encode_heap_oop_not_null $dst,$src" %} 6653 ins_encode %{ 6654 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6655 %} 6656 ins_pipe(ialu_reg_long); 6657 %} 6658 6659 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6660 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6661 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6662 match(Set dst (DecodeN src)); 6663 effect(KILL cr); 6664 format %{ "decode_heap_oop $dst,$src" %} 6665 ins_encode %{ 6666 Register s = $src$$Register; 6667 Register d = $dst$$Register; 6668 if (s != d) { 6669 __ movq(d, s); 6670 } 6671 __ decode_heap_oop(d); 6672 %} 6673 ins_pipe(ialu_reg_long); 6674 %} 6675 6676 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6677 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6678 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6679 match(Set dst (DecodeN src)); 6680 effect(KILL cr); 6681 format %{ "decode_heap_oop_not_null $dst,$src" %} 6682 ins_encode %{ 6683 Register s = $src$$Register; 6684 Register d = $dst$$Register; 6685 if (s != d) { 6686 __ decode_heap_oop_not_null(d, s); 6687 } else { 6688 __ decode_heap_oop_not_null(d); 6689 } 6690 %} 6691 ins_pipe(ialu_reg_long); 6692 %} 6693 6694 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6695 match(Set dst (EncodePKlass src)); 6696 effect(KILL cr); 6697 format %{ "encode_klass_not_null $dst,$src" %} 6698 ins_encode %{ 6699 __ encode_klass_not_null($dst$$Register, $src$$Register); 6700 %} 6701 ins_pipe(ialu_reg_long); 6702 %} 6703 6704 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6705 match(Set dst (DecodeNKlass src)); 6706 effect(KILL cr); 6707 format %{ "decode_klass_not_null $dst,$src" %} 6708 ins_encode %{ 6709 Register s = $src$$Register; 6710 Register d = $dst$$Register; 6711 if (s != d) { 6712 __ decode_klass_not_null(d, s); 6713 } else { 6714 __ decode_klass_not_null(d); 6715 } 6716 %} 6717 ins_pipe(ialu_reg_long); 6718 %} 6719 6720 6721 //----------Conditional Move--------------------------------------------------- 6722 // Jump 6723 // dummy instruction for generating temp registers 6724 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6725 match(Jump (LShiftL switch_val shift)); 6726 ins_cost(350); 6727 predicate(false); 6728 effect(TEMP dest); 6729 6730 format %{ "leaq $dest, [$constantaddress]\n\t" 6731 "jmp [$dest + $switch_val << $shift]\n\t" %} 6732 ins_encode %{ 6733 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6734 // to do that and the compiler is using that register as one it can allocate. 6735 // So we build it all by hand. 6736 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6737 // ArrayAddress dispatch(table, index); 6738 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6739 __ lea($dest$$Register, $constantaddress); 6740 __ jmp(dispatch); 6741 %} 6742 ins_pipe(pipe_jmp); 6743 %} 6744 6745 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6746 match(Jump (AddL (LShiftL switch_val shift) offset)); 6747 ins_cost(350); 6748 effect(TEMP dest); 6749 6750 format %{ "leaq $dest, [$constantaddress]\n\t" 6751 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6752 ins_encode %{ 6753 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6754 // to do that and the compiler is using that register as one it can allocate. 6755 // So we build it all by hand. 6756 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6757 // ArrayAddress dispatch(table, index); 6758 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6759 __ lea($dest$$Register, $constantaddress); 6760 __ jmp(dispatch); 6761 %} 6762 ins_pipe(pipe_jmp); 6763 %} 6764 6765 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6766 match(Jump switch_val); 6767 ins_cost(350); 6768 effect(TEMP dest); 6769 6770 format %{ "leaq $dest, [$constantaddress]\n\t" 6771 "jmp [$dest + $switch_val]\n\t" %} 6772 ins_encode %{ 6773 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6774 // to do that and the compiler is using that register as one it can allocate. 6775 // So we build it all by hand. 6776 // Address index(noreg, switch_reg, Address::times_1); 6777 // ArrayAddress dispatch(table, index); 6778 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6779 __ lea($dest$$Register, $constantaddress); 6780 __ jmp(dispatch); 6781 %} 6782 ins_pipe(pipe_jmp); 6783 %} 6784 6785 // Conditional move 6786 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6787 %{ 6788 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6789 6790 ins_cost(200); // XXX 6791 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6792 opcode(0x0F, 0x40); 6793 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6794 ins_pipe(pipe_cmov_reg); 6795 %} 6796 6797 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6798 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6799 6800 ins_cost(200); // XXX 6801 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6802 opcode(0x0F, 0x40); 6803 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6804 ins_pipe(pipe_cmov_reg); 6805 %} 6806 6807 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6808 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6809 ins_cost(200); 6810 expand %{ 6811 cmovI_regU(cop, cr, dst, src); 6812 %} 6813 %} 6814 6815 // Conditional move 6816 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6817 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6818 6819 ins_cost(250); // XXX 6820 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6821 opcode(0x0F, 0x40); 6822 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6823 ins_pipe(pipe_cmov_mem); 6824 %} 6825 6826 // Conditional move 6827 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6828 %{ 6829 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6830 6831 ins_cost(250); // XXX 6832 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6833 opcode(0x0F, 0x40); 6834 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6835 ins_pipe(pipe_cmov_mem); 6836 %} 6837 6838 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6839 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6840 ins_cost(250); 6841 expand %{ 6842 cmovI_memU(cop, cr, dst, src); 6843 %} 6844 %} 6845 6846 // Conditional move 6847 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6848 %{ 6849 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6850 6851 ins_cost(200); // XXX 6852 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6853 opcode(0x0F, 0x40); 6854 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6855 ins_pipe(pipe_cmov_reg); 6856 %} 6857 6858 // Conditional move 6859 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6860 %{ 6861 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6862 6863 ins_cost(200); // XXX 6864 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6865 opcode(0x0F, 0x40); 6866 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6867 ins_pipe(pipe_cmov_reg); 6868 %} 6869 6870 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6871 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6872 ins_cost(200); 6873 expand %{ 6874 cmovN_regU(cop, cr, dst, src); 6875 %} 6876 %} 6877 6878 // Conditional move 6879 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6880 %{ 6881 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6882 6883 ins_cost(200); // XXX 6884 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6885 opcode(0x0F, 0x40); 6886 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6887 ins_pipe(pipe_cmov_reg); // XXX 6888 %} 6889 6890 // Conditional move 6891 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6892 %{ 6893 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6894 6895 ins_cost(200); // XXX 6896 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6897 opcode(0x0F, 0x40); 6898 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6899 ins_pipe(pipe_cmov_reg); // XXX 6900 %} 6901 6902 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6903 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6904 ins_cost(200); 6905 expand %{ 6906 cmovP_regU(cop, cr, dst, src); 6907 %} 6908 %} 6909 6910 // DISABLED: Requires the ADLC to emit a bottom_type call that 6911 // correctly meets the two pointer arguments; one is an incoming 6912 // register but the other is a memory operand. ALSO appears to 6913 // be buggy with implicit null checks. 6914 // 6915 //// Conditional move 6916 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6917 //%{ 6918 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6919 // ins_cost(250); 6920 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6921 // opcode(0x0F,0x40); 6922 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6923 // ins_pipe( pipe_cmov_mem ); 6924 //%} 6925 // 6926 //// Conditional move 6927 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6928 //%{ 6929 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6930 // ins_cost(250); 6931 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6932 // opcode(0x0F,0x40); 6933 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6934 // ins_pipe( pipe_cmov_mem ); 6935 //%} 6936 6937 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6938 %{ 6939 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6940 6941 ins_cost(200); // XXX 6942 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6943 opcode(0x0F, 0x40); 6944 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6945 ins_pipe(pipe_cmov_reg); // XXX 6946 %} 6947 6948 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6949 %{ 6950 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6951 6952 ins_cost(200); // XXX 6953 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6954 opcode(0x0F, 0x40); 6955 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6956 ins_pipe(pipe_cmov_mem); // XXX 6957 %} 6958 6959 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6960 %{ 6961 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6962 6963 ins_cost(200); // XXX 6964 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6965 opcode(0x0F, 0x40); 6966 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6967 ins_pipe(pipe_cmov_reg); // XXX 6968 %} 6969 6970 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6971 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6972 ins_cost(200); 6973 expand %{ 6974 cmovL_regU(cop, cr, dst, src); 6975 %} 6976 %} 6977 6978 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6979 %{ 6980 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6981 6982 ins_cost(200); // XXX 6983 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6984 opcode(0x0F, 0x40); 6985 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6986 ins_pipe(pipe_cmov_mem); // XXX 6987 %} 6988 6989 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6990 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6991 ins_cost(200); 6992 expand %{ 6993 cmovL_memU(cop, cr, dst, src); 6994 %} 6995 %} 6996 6997 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6998 %{ 6999 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7000 7001 ins_cost(200); // XXX 7002 format %{ "jn$cop skip\t# signed cmove float\n\t" 7003 "movss $dst, $src\n" 7004 "skip:" %} 7005 ins_encode %{ 7006 Label Lskip; 7007 // Invert sense of branch from sense of CMOV 7008 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7009 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7010 __ bind(Lskip); 7011 %} 7012 ins_pipe(pipe_slow); 7013 %} 7014 7015 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7016 // %{ 7017 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7018 7019 // ins_cost(200); // XXX 7020 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7021 // "movss $dst, $src\n" 7022 // "skip:" %} 7023 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7024 // ins_pipe(pipe_slow); 7025 // %} 7026 7027 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7028 %{ 7029 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7030 7031 ins_cost(200); // XXX 7032 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7033 "movss $dst, $src\n" 7034 "skip:" %} 7035 ins_encode %{ 7036 Label Lskip; 7037 // Invert sense of branch from sense of CMOV 7038 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7039 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7040 __ bind(Lskip); 7041 %} 7042 ins_pipe(pipe_slow); 7043 %} 7044 7045 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7046 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7047 ins_cost(200); 7048 expand %{ 7049 cmovF_regU(cop, cr, dst, src); 7050 %} 7051 %} 7052 7053 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7054 %{ 7055 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7056 7057 ins_cost(200); // XXX 7058 format %{ "jn$cop skip\t# signed cmove double\n\t" 7059 "movsd $dst, $src\n" 7060 "skip:" %} 7061 ins_encode %{ 7062 Label Lskip; 7063 // Invert sense of branch from sense of CMOV 7064 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7065 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7066 __ bind(Lskip); 7067 %} 7068 ins_pipe(pipe_slow); 7069 %} 7070 7071 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7072 %{ 7073 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7074 7075 ins_cost(200); // XXX 7076 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7077 "movsd $dst, $src\n" 7078 "skip:" %} 7079 ins_encode %{ 7080 Label Lskip; 7081 // Invert sense of branch from sense of CMOV 7082 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7083 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7084 __ bind(Lskip); 7085 %} 7086 ins_pipe(pipe_slow); 7087 %} 7088 7089 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7090 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7091 ins_cost(200); 7092 expand %{ 7093 cmovD_regU(cop, cr, dst, src); 7094 %} 7095 %} 7096 7097 //----------Arithmetic Instructions-------------------------------------------- 7098 //----------Addition Instructions---------------------------------------------- 7099 7100 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7101 %{ 7102 match(Set dst (AddI dst src)); 7103 effect(KILL cr); 7104 7105 format %{ "addl $dst, $src\t# int" %} 7106 opcode(0x03); 7107 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7108 ins_pipe(ialu_reg_reg); 7109 %} 7110 7111 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7112 %{ 7113 match(Set dst (AddI dst src)); 7114 effect(KILL cr); 7115 7116 format %{ "addl $dst, $src\t# int" %} 7117 opcode(0x81, 0x00); /* /0 id */ 7118 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7119 ins_pipe( ialu_reg ); 7120 %} 7121 7122 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7123 %{ 7124 match(Set dst (AddI dst (LoadI src))); 7125 effect(KILL cr); 7126 7127 ins_cost(125); // XXX 7128 format %{ "addl $dst, $src\t# int" %} 7129 opcode(0x03); 7130 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7131 ins_pipe(ialu_reg_mem); 7132 %} 7133 7134 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7135 %{ 7136 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7137 effect(KILL cr); 7138 7139 ins_cost(150); // XXX 7140 format %{ "addl $dst, $src\t# int" %} 7141 opcode(0x01); /* Opcode 01 /r */ 7142 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7143 ins_pipe(ialu_mem_reg); 7144 %} 7145 7146 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7147 %{ 7148 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7149 effect(KILL cr); 7150 7151 ins_cost(125); // XXX 7152 format %{ "addl $dst, $src\t# int" %} 7153 opcode(0x81); /* Opcode 81 /0 id */ 7154 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7155 ins_pipe(ialu_mem_imm); 7156 %} 7157 7158 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7159 %{ 7160 predicate(UseIncDec); 7161 match(Set dst (AddI dst src)); 7162 effect(KILL cr); 7163 7164 format %{ "incl $dst\t# int" %} 7165 opcode(0xFF, 0x00); // FF /0 7166 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7167 ins_pipe(ialu_reg); 7168 %} 7169 7170 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7171 %{ 7172 predicate(UseIncDec); 7173 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7174 effect(KILL cr); 7175 7176 ins_cost(125); // XXX 7177 format %{ "incl $dst\t# int" %} 7178 opcode(0xFF); /* Opcode FF /0 */ 7179 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7180 ins_pipe(ialu_mem_imm); 7181 %} 7182 7183 // XXX why does that use AddI 7184 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7185 %{ 7186 predicate(UseIncDec); 7187 match(Set dst (AddI dst src)); 7188 effect(KILL cr); 7189 7190 format %{ "decl $dst\t# int" %} 7191 opcode(0xFF, 0x01); // FF /1 7192 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7193 ins_pipe(ialu_reg); 7194 %} 7195 7196 // XXX why does that use AddI 7197 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7198 %{ 7199 predicate(UseIncDec); 7200 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7201 effect(KILL cr); 7202 7203 ins_cost(125); // XXX 7204 format %{ "decl $dst\t# int" %} 7205 opcode(0xFF); /* Opcode FF /1 */ 7206 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7207 ins_pipe(ialu_mem_imm); 7208 %} 7209 7210 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7211 %{ 7212 match(Set dst (AddI src0 src1)); 7213 7214 ins_cost(110); 7215 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7216 opcode(0x8D); /* 0x8D /r */ 7217 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7218 ins_pipe(ialu_reg_reg); 7219 %} 7220 7221 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7222 %{ 7223 match(Set dst (AddL dst src)); 7224 effect(KILL cr); 7225 7226 format %{ "addq $dst, $src\t# long" %} 7227 opcode(0x03); 7228 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7229 ins_pipe(ialu_reg_reg); 7230 %} 7231 7232 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7233 %{ 7234 match(Set dst (AddL dst src)); 7235 effect(KILL cr); 7236 7237 format %{ "addq $dst, $src\t# long" %} 7238 opcode(0x81, 0x00); /* /0 id */ 7239 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7240 ins_pipe( ialu_reg ); 7241 %} 7242 7243 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7244 %{ 7245 match(Set dst (AddL dst (LoadL src))); 7246 effect(KILL cr); 7247 7248 ins_cost(125); // XXX 7249 format %{ "addq $dst, $src\t# long" %} 7250 opcode(0x03); 7251 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7252 ins_pipe(ialu_reg_mem); 7253 %} 7254 7255 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7256 %{ 7257 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7258 effect(KILL cr); 7259 7260 ins_cost(150); // XXX 7261 format %{ "addq $dst, $src\t# long" %} 7262 opcode(0x01); /* Opcode 01 /r */ 7263 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7264 ins_pipe(ialu_mem_reg); 7265 %} 7266 7267 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7268 %{ 7269 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7270 effect(KILL cr); 7271 7272 ins_cost(125); // XXX 7273 format %{ "addq $dst, $src\t# long" %} 7274 opcode(0x81); /* Opcode 81 /0 id */ 7275 ins_encode(REX_mem_wide(dst), 7276 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7277 ins_pipe(ialu_mem_imm); 7278 %} 7279 7280 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7281 %{ 7282 predicate(UseIncDec); 7283 match(Set dst (AddL dst src)); 7284 effect(KILL cr); 7285 7286 format %{ "incq $dst\t# long" %} 7287 opcode(0xFF, 0x00); // FF /0 7288 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7289 ins_pipe(ialu_reg); 7290 %} 7291 7292 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7293 %{ 7294 predicate(UseIncDec); 7295 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7296 effect(KILL cr); 7297 7298 ins_cost(125); // XXX 7299 format %{ "incq $dst\t# long" %} 7300 opcode(0xFF); /* Opcode FF /0 */ 7301 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7302 ins_pipe(ialu_mem_imm); 7303 %} 7304 7305 // XXX why does that use AddL 7306 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7307 %{ 7308 predicate(UseIncDec); 7309 match(Set dst (AddL dst src)); 7310 effect(KILL cr); 7311 7312 format %{ "decq $dst\t# long" %} 7313 opcode(0xFF, 0x01); // FF /1 7314 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7315 ins_pipe(ialu_reg); 7316 %} 7317 7318 // XXX why does that use AddL 7319 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7320 %{ 7321 predicate(UseIncDec); 7322 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7323 effect(KILL cr); 7324 7325 ins_cost(125); // XXX 7326 format %{ "decq $dst\t# long" %} 7327 opcode(0xFF); /* Opcode FF /1 */ 7328 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7329 ins_pipe(ialu_mem_imm); 7330 %} 7331 7332 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7333 %{ 7334 match(Set dst (AddL src0 src1)); 7335 7336 ins_cost(110); 7337 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7338 opcode(0x8D); /* 0x8D /r */ 7339 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7340 ins_pipe(ialu_reg_reg); 7341 %} 7342 7343 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7344 %{ 7345 match(Set dst (AddP dst src)); 7346 effect(KILL cr); 7347 7348 format %{ "addq $dst, $src\t# ptr" %} 7349 opcode(0x03); 7350 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7351 ins_pipe(ialu_reg_reg); 7352 %} 7353 7354 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7355 %{ 7356 match(Set dst (AddP dst src)); 7357 effect(KILL cr); 7358 7359 format %{ "addq $dst, $src\t# ptr" %} 7360 opcode(0x81, 0x00); /* /0 id */ 7361 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7362 ins_pipe( ialu_reg ); 7363 %} 7364 7365 // XXX addP mem ops ???? 7366 7367 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7368 %{ 7369 match(Set dst (AddP src0 src1)); 7370 7371 ins_cost(110); 7372 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7373 opcode(0x8D); /* 0x8D /r */ 7374 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7375 ins_pipe(ialu_reg_reg); 7376 %} 7377 7378 instruct checkCastPP(rRegP dst) 7379 %{ 7380 match(Set dst (CheckCastPP dst)); 7381 7382 size(0); 7383 format %{ "# checkcastPP of $dst" %} 7384 ins_encode(/* empty encoding */); 7385 ins_pipe(empty); 7386 %} 7387 7388 instruct castPP(rRegP dst) 7389 %{ 7390 match(Set dst (CastPP dst)); 7391 7392 size(0); 7393 format %{ "# castPP of $dst" %} 7394 ins_encode(/* empty encoding */); 7395 ins_pipe(empty); 7396 %} 7397 7398 instruct castII(rRegI dst) 7399 %{ 7400 match(Set dst (CastII dst)); 7401 7402 size(0); 7403 format %{ "# castII of $dst" %} 7404 ins_encode(/* empty encoding */); 7405 ins_cost(0); 7406 ins_pipe(empty); 7407 %} 7408 7409 // LoadP-locked same as a regular LoadP when used with compare-swap 7410 instruct loadPLocked(rRegP dst, memory mem) 7411 %{ 7412 match(Set dst (LoadPLocked mem)); 7413 7414 ins_cost(125); // XXX 7415 format %{ "movq $dst, $mem\t# ptr locked" %} 7416 opcode(0x8B); 7417 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7418 ins_pipe(ialu_reg_mem); // XXX 7419 %} 7420 7421 // Conditional-store of the updated heap-top. 7422 // Used during allocation of the shared heap. 7423 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7424 7425 instruct storePConditional(memory heap_top_ptr, 7426 rax_RegP oldval, rRegP newval, 7427 rFlagsReg cr) 7428 %{ 7429 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7430 7431 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7432 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7433 opcode(0x0F, 0xB1); 7434 ins_encode(lock_prefix, 7435 REX_reg_mem_wide(newval, heap_top_ptr), 7436 OpcP, OpcS, 7437 reg_mem(newval, heap_top_ptr)); 7438 ins_pipe(pipe_cmpxchg); 7439 %} 7440 7441 // Conditional-store of an int value. 7442 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7443 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7444 %{ 7445 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7446 effect(KILL oldval); 7447 7448 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7449 opcode(0x0F, 0xB1); 7450 ins_encode(lock_prefix, 7451 REX_reg_mem(newval, mem), 7452 OpcP, OpcS, 7453 reg_mem(newval, mem)); 7454 ins_pipe(pipe_cmpxchg); 7455 %} 7456 7457 // Conditional-store of a long value. 7458 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7459 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7460 %{ 7461 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7462 effect(KILL oldval); 7463 7464 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7465 opcode(0x0F, 0xB1); 7466 ins_encode(lock_prefix, 7467 REX_reg_mem_wide(newval, mem), 7468 OpcP, OpcS, 7469 reg_mem(newval, mem)); 7470 ins_pipe(pipe_cmpxchg); 7471 %} 7472 7473 7474 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7475 instruct compareAndSwapP(rRegI res, 7476 memory mem_ptr, 7477 rax_RegP oldval, rRegP newval, 7478 rFlagsReg cr) 7479 %{ 7480 predicate(VM_Version::supports_cx8()); 7481 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7482 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7483 effect(KILL cr, KILL oldval); 7484 7485 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7486 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7487 "sete $res\n\t" 7488 "movzbl $res, $res" %} 7489 opcode(0x0F, 0xB1); 7490 ins_encode(lock_prefix, 7491 REX_reg_mem_wide(newval, mem_ptr), 7492 OpcP, OpcS, 7493 reg_mem(newval, mem_ptr), 7494 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7495 REX_reg_breg(res, res), // movzbl 7496 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7497 ins_pipe( pipe_cmpxchg ); 7498 %} 7499 7500 instruct compareAndSwapL(rRegI res, 7501 memory mem_ptr, 7502 rax_RegL oldval, rRegL newval, 7503 rFlagsReg cr) 7504 %{ 7505 predicate(VM_Version::supports_cx8()); 7506 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7507 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7508 effect(KILL cr, KILL oldval); 7509 7510 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7511 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7512 "sete $res\n\t" 7513 "movzbl $res, $res" %} 7514 opcode(0x0F, 0xB1); 7515 ins_encode(lock_prefix, 7516 REX_reg_mem_wide(newval, mem_ptr), 7517 OpcP, OpcS, 7518 reg_mem(newval, mem_ptr), 7519 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7520 REX_reg_breg(res, res), // movzbl 7521 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7522 ins_pipe( pipe_cmpxchg ); 7523 %} 7524 7525 instruct compareAndSwapI(rRegI res, 7526 memory mem_ptr, 7527 rax_RegI oldval, rRegI newval, 7528 rFlagsReg cr) 7529 %{ 7530 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7531 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7532 effect(KILL cr, KILL oldval); 7533 7534 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7535 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7536 "sete $res\n\t" 7537 "movzbl $res, $res" %} 7538 opcode(0x0F, 0xB1); 7539 ins_encode(lock_prefix, 7540 REX_reg_mem(newval, mem_ptr), 7541 OpcP, OpcS, 7542 reg_mem(newval, mem_ptr), 7543 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7544 REX_reg_breg(res, res), // movzbl 7545 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7546 ins_pipe( pipe_cmpxchg ); 7547 %} 7548 7549 instruct compareAndSwapB(rRegI res, 7550 memory mem_ptr, 7551 rax_RegI oldval, rRegI newval, 7552 rFlagsReg cr) 7553 %{ 7554 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7555 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7556 effect(KILL cr, KILL oldval); 7557 7558 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7559 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7560 "sete $res\n\t" 7561 "movzbl $res, $res" %} 7562 opcode(0x0F, 0xB0); 7563 ins_encode(lock_prefix, 7564 REX_breg_mem(newval, mem_ptr), 7565 OpcP, OpcS, 7566 reg_mem(newval, mem_ptr), 7567 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7568 REX_reg_breg(res, res), // movzbl 7569 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7570 ins_pipe( pipe_cmpxchg ); 7571 %} 7572 7573 instruct compareAndSwapS(rRegI res, 7574 memory mem_ptr, 7575 rax_RegI oldval, rRegI newval, 7576 rFlagsReg cr) 7577 %{ 7578 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7579 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7580 effect(KILL cr, KILL oldval); 7581 7582 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7583 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7584 "sete $res\n\t" 7585 "movzbl $res, $res" %} 7586 opcode(0x0F, 0xB1); 7587 ins_encode(lock_prefix, 7588 SizePrefix, 7589 REX_reg_mem(newval, mem_ptr), 7590 OpcP, OpcS, 7591 reg_mem(newval, mem_ptr), 7592 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7593 REX_reg_breg(res, res), // movzbl 7594 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7595 ins_pipe( pipe_cmpxchg ); 7596 %} 7597 7598 7599 instruct compareAndSwapN(rRegI res, 7600 memory mem_ptr, 7601 rax_RegN oldval, rRegN newval, 7602 rFlagsReg cr) %{ 7603 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7604 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7605 effect(KILL cr, KILL oldval); 7606 7607 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7608 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7609 "sete $res\n\t" 7610 "movzbl $res, $res" %} 7611 opcode(0x0F, 0xB1); 7612 ins_encode(lock_prefix, 7613 REX_reg_mem(newval, mem_ptr), 7614 OpcP, OpcS, 7615 reg_mem(newval, mem_ptr), 7616 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7617 REX_reg_breg(res, res), // movzbl 7618 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7619 ins_pipe( pipe_cmpxchg ); 7620 %} 7621 7622 instruct compareAndExchangeB( 7623 memory mem_ptr, 7624 rax_RegI oldval, rRegI newval, 7625 rFlagsReg cr) 7626 %{ 7627 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7628 effect(KILL cr); 7629 7630 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7631 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7632 opcode(0x0F, 0xB0); 7633 ins_encode(lock_prefix, 7634 REX_breg_mem(newval, mem_ptr), 7635 OpcP, OpcS, 7636 reg_mem(newval, mem_ptr) // lock cmpxchg 7637 ); 7638 ins_pipe( pipe_cmpxchg ); 7639 %} 7640 7641 instruct compareAndExchangeS( 7642 memory mem_ptr, 7643 rax_RegI oldval, rRegI newval, 7644 rFlagsReg cr) 7645 %{ 7646 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7647 effect(KILL cr); 7648 7649 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7650 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7651 opcode(0x0F, 0xB1); 7652 ins_encode(lock_prefix, 7653 SizePrefix, 7654 REX_reg_mem(newval, mem_ptr), 7655 OpcP, OpcS, 7656 reg_mem(newval, mem_ptr) // lock cmpxchg 7657 ); 7658 ins_pipe( pipe_cmpxchg ); 7659 %} 7660 7661 instruct compareAndExchangeI( 7662 memory mem_ptr, 7663 rax_RegI oldval, rRegI newval, 7664 rFlagsReg cr) 7665 %{ 7666 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7667 effect(KILL cr); 7668 7669 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7670 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7671 opcode(0x0F, 0xB1); 7672 ins_encode(lock_prefix, 7673 REX_reg_mem(newval, mem_ptr), 7674 OpcP, OpcS, 7675 reg_mem(newval, mem_ptr) // lock cmpxchg 7676 ); 7677 ins_pipe( pipe_cmpxchg ); 7678 %} 7679 7680 instruct compareAndExchangeL( 7681 memory mem_ptr, 7682 rax_RegL oldval, rRegL newval, 7683 rFlagsReg cr) 7684 %{ 7685 predicate(VM_Version::supports_cx8()); 7686 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7687 effect(KILL cr); 7688 7689 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7690 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7691 opcode(0x0F, 0xB1); 7692 ins_encode(lock_prefix, 7693 REX_reg_mem_wide(newval, mem_ptr), 7694 OpcP, OpcS, 7695 reg_mem(newval, mem_ptr) // lock cmpxchg 7696 ); 7697 ins_pipe( pipe_cmpxchg ); 7698 %} 7699 7700 instruct compareAndExchangeN( 7701 memory mem_ptr, 7702 rax_RegN oldval, rRegN newval, 7703 rFlagsReg cr) %{ 7704 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7705 effect(KILL cr); 7706 7707 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7708 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7709 opcode(0x0F, 0xB1); 7710 ins_encode(lock_prefix, 7711 REX_reg_mem(newval, mem_ptr), 7712 OpcP, OpcS, 7713 reg_mem(newval, mem_ptr) // lock cmpxchg 7714 ); 7715 ins_pipe( pipe_cmpxchg ); 7716 %} 7717 7718 instruct compareAndExchangeP( 7719 memory mem_ptr, 7720 rax_RegP oldval, rRegP newval, 7721 rFlagsReg cr) 7722 %{ 7723 predicate(VM_Version::supports_cx8()); 7724 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7725 effect(KILL cr); 7726 7727 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7728 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7729 opcode(0x0F, 0xB1); 7730 ins_encode(lock_prefix, 7731 REX_reg_mem_wide(newval, mem_ptr), 7732 OpcP, OpcS, 7733 reg_mem(newval, mem_ptr) // lock cmpxchg 7734 ); 7735 ins_pipe( pipe_cmpxchg ); 7736 %} 7737 7738 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7739 predicate(n->as_LoadStore()->result_not_used()); 7740 match(Set dummy (GetAndAddB mem add)); 7741 effect(KILL cr); 7742 format %{ "ADDB [$mem],$add" %} 7743 ins_encode %{ 7744 if (os::is_MP()) { __ lock(); } 7745 __ addb($mem$$Address, $add$$constant); 7746 %} 7747 ins_pipe( pipe_cmpxchg ); 7748 %} 7749 7750 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7751 match(Set newval (GetAndAddB mem newval)); 7752 effect(KILL cr); 7753 format %{ "XADDB [$mem],$newval" %} 7754 ins_encode %{ 7755 if (os::is_MP()) { __ lock(); } 7756 __ xaddb($mem$$Address, $newval$$Register); 7757 %} 7758 ins_pipe( pipe_cmpxchg ); 7759 %} 7760 7761 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7762 predicate(n->as_LoadStore()->result_not_used()); 7763 match(Set dummy (GetAndAddS mem add)); 7764 effect(KILL cr); 7765 format %{ "ADDW [$mem],$add" %} 7766 ins_encode %{ 7767 if (os::is_MP()) { __ lock(); } 7768 __ addw($mem$$Address, $add$$constant); 7769 %} 7770 ins_pipe( pipe_cmpxchg ); 7771 %} 7772 7773 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7774 match(Set newval (GetAndAddS mem newval)); 7775 effect(KILL cr); 7776 format %{ "XADDW [$mem],$newval" %} 7777 ins_encode %{ 7778 if (os::is_MP()) { __ lock(); } 7779 __ xaddw($mem$$Address, $newval$$Register); 7780 %} 7781 ins_pipe( pipe_cmpxchg ); 7782 %} 7783 7784 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7785 predicate(n->as_LoadStore()->result_not_used()); 7786 match(Set dummy (GetAndAddI mem add)); 7787 effect(KILL cr); 7788 format %{ "ADDL [$mem],$add" %} 7789 ins_encode %{ 7790 if (os::is_MP()) { __ lock(); } 7791 __ addl($mem$$Address, $add$$constant); 7792 %} 7793 ins_pipe( pipe_cmpxchg ); 7794 %} 7795 7796 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7797 match(Set newval (GetAndAddI mem newval)); 7798 effect(KILL cr); 7799 format %{ "XADDL [$mem],$newval" %} 7800 ins_encode %{ 7801 if (os::is_MP()) { __ lock(); } 7802 __ xaddl($mem$$Address, $newval$$Register); 7803 %} 7804 ins_pipe( pipe_cmpxchg ); 7805 %} 7806 7807 instruct compareAndSwap2L(rax_RegL res, 7808 memory mem_ptr, 7809 rax_RegL oldval, rRegL newval, 7810 rFlagsReg cr) 7811 %{ 7812 predicate(VM_Version::supports_cx8()); 7813 match(Set res (CompareAndSwap2L mem_ptr (Binary oldval newval))); 7814 effect(KILL cr); 7815 7816 format %{ "cmpxchgq $mem_ptr,$newval" %} 7817 7818 ins_encode %{ 7819 if (os::is_MP()) { 7820 __ lock(); 7821 } 7822 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7823 %} 7824 7825 7826 ins_pipe( pipe_cmpxchg ); 7827 %} 7828 7829 instruct compareAndSwap2I(rax_RegI res, 7830 memory mem_ptr, 7831 rax_RegI oldval, rRegI newval, 7832 rFlagsReg cr) 7833 %{ 7834 match(Set res (CompareAndSwap2I mem_ptr (Binary oldval newval))); 7835 effect(KILL cr); 7836 7837 format %{ "cmpxchgl $mem_ptr,$newval" %} 7838 7839 ins_encode %{ 7840 if (os::is_MP()) { 7841 __ lock(); 7842 } 7843 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7844 %} 7845 7846 ins_pipe( pipe_cmpxchg ); 7847 %} 7848 7849 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7850 predicate(n->as_LoadStore()->result_not_used()); 7851 match(Set dummy (GetAndAddL mem add)); 7852 effect(KILL cr); 7853 format %{ "ADDQ [$mem],$add" %} 7854 ins_encode %{ 7855 if (os::is_MP()) { __ lock(); } 7856 __ addq($mem$$Address, $add$$constant); 7857 %} 7858 ins_pipe( pipe_cmpxchg ); 7859 %} 7860 7861 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7862 match(Set newval (GetAndAddL mem newval)); 7863 effect(KILL cr); 7864 format %{ "XADDQ [$mem],$newval" %} 7865 ins_encode %{ 7866 if (os::is_MP()) { __ lock(); } 7867 __ xaddq($mem$$Address, $newval$$Register); 7868 %} 7869 ins_pipe( pipe_cmpxchg ); 7870 %} 7871 7872 instruct xchgB( memory mem, rRegI newval) %{ 7873 match(Set newval (GetAndSetB mem newval)); 7874 format %{ "XCHGB $newval,[$mem]" %} 7875 ins_encode %{ 7876 __ xchgb($newval$$Register, $mem$$Address); 7877 %} 7878 ins_pipe( pipe_cmpxchg ); 7879 %} 7880 7881 instruct xchgS( memory mem, rRegI newval) %{ 7882 match(Set newval (GetAndSetS mem newval)); 7883 format %{ "XCHGW $newval,[$mem]" %} 7884 ins_encode %{ 7885 __ xchgw($newval$$Register, $mem$$Address); 7886 %} 7887 ins_pipe( pipe_cmpxchg ); 7888 %} 7889 7890 instruct xchgI( memory mem, rRegI newval) %{ 7891 match(Set newval (GetAndSetI mem newval)); 7892 format %{ "XCHGL $newval,[$mem]" %} 7893 ins_encode %{ 7894 __ xchgl($newval$$Register, $mem$$Address); 7895 %} 7896 ins_pipe( pipe_cmpxchg ); 7897 %} 7898 7899 instruct xchgL( memory mem, rRegL newval) %{ 7900 match(Set newval (GetAndSetL mem newval)); 7901 format %{ "XCHGL $newval,[$mem]" %} 7902 ins_encode %{ 7903 __ xchgq($newval$$Register, $mem$$Address); 7904 %} 7905 ins_pipe( pipe_cmpxchg ); 7906 %} 7907 7908 instruct xchgP( memory mem, rRegP newval) %{ 7909 match(Set newval (GetAndSetP mem newval)); 7910 format %{ "XCHGQ $newval,[$mem]" %} 7911 ins_encode %{ 7912 __ xchgq($newval$$Register, $mem$$Address); 7913 %} 7914 ins_pipe( pipe_cmpxchg ); 7915 %} 7916 7917 instruct xchgN( memory mem, rRegN newval) %{ 7918 match(Set newval (GetAndSetN mem newval)); 7919 format %{ "XCHGL $newval,$mem]" %} 7920 ins_encode %{ 7921 __ xchgl($newval$$Register, $mem$$Address); 7922 %} 7923 ins_pipe( pipe_cmpxchg ); 7924 %} 7925 7926 //----------Subtraction Instructions------------------------------------------- 7927 7928 // Integer Subtraction Instructions 7929 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7930 %{ 7931 match(Set dst (SubI dst src)); 7932 effect(KILL cr); 7933 7934 format %{ "subl $dst, $src\t# int" %} 7935 opcode(0x2B); 7936 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7937 ins_pipe(ialu_reg_reg); 7938 %} 7939 7940 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7941 %{ 7942 match(Set dst (SubI dst src)); 7943 effect(KILL cr); 7944 7945 format %{ "subl $dst, $src\t# int" %} 7946 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7947 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7948 ins_pipe(ialu_reg); 7949 %} 7950 7951 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7952 %{ 7953 match(Set dst (SubI dst (LoadI src))); 7954 effect(KILL cr); 7955 7956 ins_cost(125); 7957 format %{ "subl $dst, $src\t# int" %} 7958 opcode(0x2B); 7959 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7960 ins_pipe(ialu_reg_mem); 7961 %} 7962 7963 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7964 %{ 7965 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7966 effect(KILL cr); 7967 7968 ins_cost(150); 7969 format %{ "subl $dst, $src\t# int" %} 7970 opcode(0x29); /* Opcode 29 /r */ 7971 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7972 ins_pipe(ialu_mem_reg); 7973 %} 7974 7975 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7976 %{ 7977 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7978 effect(KILL cr); 7979 7980 ins_cost(125); // XXX 7981 format %{ "subl $dst, $src\t# int" %} 7982 opcode(0x81); /* Opcode 81 /5 id */ 7983 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7984 ins_pipe(ialu_mem_imm); 7985 %} 7986 7987 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7988 %{ 7989 match(Set dst (SubL dst src)); 7990 effect(KILL cr); 7991 7992 format %{ "subq $dst, $src\t# long" %} 7993 opcode(0x2B); 7994 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7995 ins_pipe(ialu_reg_reg); 7996 %} 7997 7998 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7999 %{ 8000 match(Set dst (SubL dst src)); 8001 effect(KILL cr); 8002 8003 format %{ "subq $dst, $src\t# long" %} 8004 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8005 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8006 ins_pipe(ialu_reg); 8007 %} 8008 8009 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8010 %{ 8011 match(Set dst (SubL dst (LoadL src))); 8012 effect(KILL cr); 8013 8014 ins_cost(125); 8015 format %{ "subq $dst, $src\t# long" %} 8016 opcode(0x2B); 8017 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8018 ins_pipe(ialu_reg_mem); 8019 %} 8020 8021 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8022 %{ 8023 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8024 effect(KILL cr); 8025 8026 ins_cost(150); 8027 format %{ "subq $dst, $src\t# long" %} 8028 opcode(0x29); /* Opcode 29 /r */ 8029 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8030 ins_pipe(ialu_mem_reg); 8031 %} 8032 8033 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8034 %{ 8035 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8036 effect(KILL cr); 8037 8038 ins_cost(125); // XXX 8039 format %{ "subq $dst, $src\t# long" %} 8040 opcode(0x81); /* Opcode 81 /5 id */ 8041 ins_encode(REX_mem_wide(dst), 8042 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8043 ins_pipe(ialu_mem_imm); 8044 %} 8045 8046 // Subtract from a pointer 8047 // XXX hmpf??? 8048 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8049 %{ 8050 match(Set dst (AddP dst (SubI zero src))); 8051 effect(KILL cr); 8052 8053 format %{ "subq $dst, $src\t# ptr - int" %} 8054 opcode(0x2B); 8055 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8056 ins_pipe(ialu_reg_reg); 8057 %} 8058 8059 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8060 %{ 8061 match(Set dst (SubI zero dst)); 8062 effect(KILL cr); 8063 8064 format %{ "negl $dst\t# int" %} 8065 opcode(0xF7, 0x03); // Opcode F7 /3 8066 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8067 ins_pipe(ialu_reg); 8068 %} 8069 8070 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8071 %{ 8072 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8073 effect(KILL cr); 8074 8075 format %{ "negl $dst\t# int" %} 8076 opcode(0xF7, 0x03); // Opcode F7 /3 8077 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8078 ins_pipe(ialu_reg); 8079 %} 8080 8081 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8082 %{ 8083 match(Set dst (SubL zero dst)); 8084 effect(KILL cr); 8085 8086 format %{ "negq $dst\t# long" %} 8087 opcode(0xF7, 0x03); // Opcode F7 /3 8088 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8089 ins_pipe(ialu_reg); 8090 %} 8091 8092 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8093 %{ 8094 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8095 effect(KILL cr); 8096 8097 format %{ "negq $dst\t# long" %} 8098 opcode(0xF7, 0x03); // Opcode F7 /3 8099 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8100 ins_pipe(ialu_reg); 8101 %} 8102 8103 //----------Multiplication/Division Instructions------------------------------- 8104 // Integer Multiplication Instructions 8105 // Multiply Register 8106 8107 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8108 %{ 8109 match(Set dst (MulI dst src)); 8110 effect(KILL cr); 8111 8112 ins_cost(300); 8113 format %{ "imull $dst, $src\t# int" %} 8114 opcode(0x0F, 0xAF); 8115 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8116 ins_pipe(ialu_reg_reg_alu0); 8117 %} 8118 8119 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8120 %{ 8121 match(Set dst (MulI src imm)); 8122 effect(KILL cr); 8123 8124 ins_cost(300); 8125 format %{ "imull $dst, $src, $imm\t# int" %} 8126 opcode(0x69); /* 69 /r id */ 8127 ins_encode(REX_reg_reg(dst, src), 8128 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8129 ins_pipe(ialu_reg_reg_alu0); 8130 %} 8131 8132 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8133 %{ 8134 match(Set dst (MulI dst (LoadI src))); 8135 effect(KILL cr); 8136 8137 ins_cost(350); 8138 format %{ "imull $dst, $src\t# int" %} 8139 opcode(0x0F, 0xAF); 8140 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8141 ins_pipe(ialu_reg_mem_alu0); 8142 %} 8143 8144 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8145 %{ 8146 match(Set dst (MulI (LoadI src) imm)); 8147 effect(KILL cr); 8148 8149 ins_cost(300); 8150 format %{ "imull $dst, $src, $imm\t# int" %} 8151 opcode(0x69); /* 69 /r id */ 8152 ins_encode(REX_reg_mem(dst, src), 8153 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8154 ins_pipe(ialu_reg_mem_alu0); 8155 %} 8156 8157 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8158 %{ 8159 match(Set dst (MulL dst src)); 8160 effect(KILL cr); 8161 8162 ins_cost(300); 8163 format %{ "imulq $dst, $src\t# long" %} 8164 opcode(0x0F, 0xAF); 8165 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8166 ins_pipe(ialu_reg_reg_alu0); 8167 %} 8168 8169 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8170 %{ 8171 match(Set dst (MulL src imm)); 8172 effect(KILL cr); 8173 8174 ins_cost(300); 8175 format %{ "imulq $dst, $src, $imm\t# long" %} 8176 opcode(0x69); /* 69 /r id */ 8177 ins_encode(REX_reg_reg_wide(dst, src), 8178 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8179 ins_pipe(ialu_reg_reg_alu0); 8180 %} 8181 8182 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8183 %{ 8184 match(Set dst (MulL dst (LoadL src))); 8185 effect(KILL cr); 8186 8187 ins_cost(350); 8188 format %{ "imulq $dst, $src\t# long" %} 8189 opcode(0x0F, 0xAF); 8190 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8191 ins_pipe(ialu_reg_mem_alu0); 8192 %} 8193 8194 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8195 %{ 8196 match(Set dst (MulL (LoadL src) imm)); 8197 effect(KILL cr); 8198 8199 ins_cost(300); 8200 format %{ "imulq $dst, $src, $imm\t# long" %} 8201 opcode(0x69); /* 69 /r id */ 8202 ins_encode(REX_reg_mem_wide(dst, src), 8203 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8204 ins_pipe(ialu_reg_mem_alu0); 8205 %} 8206 8207 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8208 %{ 8209 match(Set dst (MulHiL src rax)); 8210 effect(USE_KILL rax, KILL cr); 8211 8212 ins_cost(300); 8213 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8214 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8215 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8216 ins_pipe(ialu_reg_reg_alu0); 8217 %} 8218 8219 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8220 rFlagsReg cr) 8221 %{ 8222 match(Set rax (DivI rax div)); 8223 effect(KILL rdx, KILL cr); 8224 8225 ins_cost(30*100+10*100); // XXX 8226 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8227 "jne,s normal\n\t" 8228 "xorl rdx, rdx\n\t" 8229 "cmpl $div, -1\n\t" 8230 "je,s done\n" 8231 "normal: cdql\n\t" 8232 "idivl $div\n" 8233 "done:" %} 8234 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8235 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8236 ins_pipe(ialu_reg_reg_alu0); 8237 %} 8238 8239 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8240 rFlagsReg cr) 8241 %{ 8242 match(Set rax (DivL rax div)); 8243 effect(KILL rdx, KILL cr); 8244 8245 ins_cost(30*100+10*100); // XXX 8246 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8247 "cmpq rax, rdx\n\t" 8248 "jne,s normal\n\t" 8249 "xorl rdx, rdx\n\t" 8250 "cmpq $div, -1\n\t" 8251 "je,s done\n" 8252 "normal: cdqq\n\t" 8253 "idivq $div\n" 8254 "done:" %} 8255 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8256 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8257 ins_pipe(ialu_reg_reg_alu0); 8258 %} 8259 8260 // Integer DIVMOD with Register, both quotient and mod results 8261 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8262 rFlagsReg cr) 8263 %{ 8264 match(DivModI rax div); 8265 effect(KILL cr); 8266 8267 ins_cost(30*100+10*100); // XXX 8268 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8269 "jne,s normal\n\t" 8270 "xorl rdx, rdx\n\t" 8271 "cmpl $div, -1\n\t" 8272 "je,s done\n" 8273 "normal: cdql\n\t" 8274 "idivl $div\n" 8275 "done:" %} 8276 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8277 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8278 ins_pipe(pipe_slow); 8279 %} 8280 8281 // Long DIVMOD with Register, both quotient and mod results 8282 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8283 rFlagsReg cr) 8284 %{ 8285 match(DivModL rax div); 8286 effect(KILL cr); 8287 8288 ins_cost(30*100+10*100); // XXX 8289 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8290 "cmpq rax, rdx\n\t" 8291 "jne,s normal\n\t" 8292 "xorl rdx, rdx\n\t" 8293 "cmpq $div, -1\n\t" 8294 "je,s done\n" 8295 "normal: cdqq\n\t" 8296 "idivq $div\n" 8297 "done:" %} 8298 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8299 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8300 ins_pipe(pipe_slow); 8301 %} 8302 8303 //----------- DivL-By-Constant-Expansions-------------------------------------- 8304 // DivI cases are handled by the compiler 8305 8306 // Magic constant, reciprocal of 10 8307 instruct loadConL_0x6666666666666667(rRegL dst) 8308 %{ 8309 effect(DEF dst); 8310 8311 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8312 ins_encode(load_immL(dst, 0x6666666666666667)); 8313 ins_pipe(ialu_reg); 8314 %} 8315 8316 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8317 %{ 8318 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8319 8320 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8321 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8322 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8323 ins_pipe(ialu_reg_reg_alu0); 8324 %} 8325 8326 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8327 %{ 8328 effect(USE_DEF dst, KILL cr); 8329 8330 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8331 opcode(0xC1, 0x7); /* C1 /7 ib */ 8332 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8333 ins_pipe(ialu_reg); 8334 %} 8335 8336 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8337 %{ 8338 effect(USE_DEF dst, KILL cr); 8339 8340 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8341 opcode(0xC1, 0x7); /* C1 /7 ib */ 8342 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8343 ins_pipe(ialu_reg); 8344 %} 8345 8346 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8347 %{ 8348 match(Set dst (DivL src div)); 8349 8350 ins_cost((5+8)*100); 8351 expand %{ 8352 rax_RegL rax; // Killed temp 8353 rFlagsReg cr; // Killed 8354 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8355 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8356 sarL_rReg_63(src, cr); // sarq src, 63 8357 sarL_rReg_2(dst, cr); // sarq rdx, 2 8358 subL_rReg(dst, src, cr); // subl rdx, src 8359 %} 8360 %} 8361 8362 //----------------------------------------------------------------------------- 8363 8364 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8365 rFlagsReg cr) 8366 %{ 8367 match(Set rdx (ModI rax div)); 8368 effect(KILL rax, KILL cr); 8369 8370 ins_cost(300); // XXX 8371 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8372 "jne,s normal\n\t" 8373 "xorl rdx, rdx\n\t" 8374 "cmpl $div, -1\n\t" 8375 "je,s done\n" 8376 "normal: cdql\n\t" 8377 "idivl $div\n" 8378 "done:" %} 8379 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8380 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8381 ins_pipe(ialu_reg_reg_alu0); 8382 %} 8383 8384 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8385 rFlagsReg cr) 8386 %{ 8387 match(Set rdx (ModL rax div)); 8388 effect(KILL rax, KILL cr); 8389 8390 ins_cost(300); // XXX 8391 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8392 "cmpq rax, rdx\n\t" 8393 "jne,s normal\n\t" 8394 "xorl rdx, rdx\n\t" 8395 "cmpq $div, -1\n\t" 8396 "je,s done\n" 8397 "normal: cdqq\n\t" 8398 "idivq $div\n" 8399 "done:" %} 8400 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8401 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8402 ins_pipe(ialu_reg_reg_alu0); 8403 %} 8404 8405 // Integer Shift Instructions 8406 // Shift Left by one 8407 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8408 %{ 8409 match(Set dst (LShiftI dst shift)); 8410 effect(KILL cr); 8411 8412 format %{ "sall $dst, $shift" %} 8413 opcode(0xD1, 0x4); /* D1 /4 */ 8414 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8415 ins_pipe(ialu_reg); 8416 %} 8417 8418 // Shift Left by one 8419 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8420 %{ 8421 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8422 effect(KILL cr); 8423 8424 format %{ "sall $dst, $shift\t" %} 8425 opcode(0xD1, 0x4); /* D1 /4 */ 8426 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8427 ins_pipe(ialu_mem_imm); 8428 %} 8429 8430 // Shift Left by 8-bit immediate 8431 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8432 %{ 8433 match(Set dst (LShiftI dst shift)); 8434 effect(KILL cr); 8435 8436 format %{ "sall $dst, $shift" %} 8437 opcode(0xC1, 0x4); /* C1 /4 ib */ 8438 ins_encode(reg_opc_imm(dst, shift)); 8439 ins_pipe(ialu_reg); 8440 %} 8441 8442 // Shift Left by 8-bit immediate 8443 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8444 %{ 8445 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8446 effect(KILL cr); 8447 8448 format %{ "sall $dst, $shift" %} 8449 opcode(0xC1, 0x4); /* C1 /4 ib */ 8450 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8451 ins_pipe(ialu_mem_imm); 8452 %} 8453 8454 // Shift Left by variable 8455 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8456 %{ 8457 match(Set dst (LShiftI dst shift)); 8458 effect(KILL cr); 8459 8460 format %{ "sall $dst, $shift" %} 8461 opcode(0xD3, 0x4); /* D3 /4 */ 8462 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8463 ins_pipe(ialu_reg_reg); 8464 %} 8465 8466 // Shift Left by variable 8467 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8468 %{ 8469 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8470 effect(KILL cr); 8471 8472 format %{ "sall $dst, $shift" %} 8473 opcode(0xD3, 0x4); /* D3 /4 */ 8474 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8475 ins_pipe(ialu_mem_reg); 8476 %} 8477 8478 // Arithmetic shift right by one 8479 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8480 %{ 8481 match(Set dst (RShiftI dst shift)); 8482 effect(KILL cr); 8483 8484 format %{ "sarl $dst, $shift" %} 8485 opcode(0xD1, 0x7); /* D1 /7 */ 8486 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8487 ins_pipe(ialu_reg); 8488 %} 8489 8490 // Arithmetic shift right by one 8491 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8492 %{ 8493 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8494 effect(KILL cr); 8495 8496 format %{ "sarl $dst, $shift" %} 8497 opcode(0xD1, 0x7); /* D1 /7 */ 8498 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8499 ins_pipe(ialu_mem_imm); 8500 %} 8501 8502 // Arithmetic Shift Right by 8-bit immediate 8503 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8504 %{ 8505 match(Set dst (RShiftI dst shift)); 8506 effect(KILL cr); 8507 8508 format %{ "sarl $dst, $shift" %} 8509 opcode(0xC1, 0x7); /* C1 /7 ib */ 8510 ins_encode(reg_opc_imm(dst, shift)); 8511 ins_pipe(ialu_mem_imm); 8512 %} 8513 8514 // Arithmetic Shift Right by 8-bit immediate 8515 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8516 %{ 8517 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8518 effect(KILL cr); 8519 8520 format %{ "sarl $dst, $shift" %} 8521 opcode(0xC1, 0x7); /* C1 /7 ib */ 8522 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8523 ins_pipe(ialu_mem_imm); 8524 %} 8525 8526 // Arithmetic Shift Right by variable 8527 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8528 %{ 8529 match(Set dst (RShiftI dst shift)); 8530 effect(KILL cr); 8531 8532 format %{ "sarl $dst, $shift" %} 8533 opcode(0xD3, 0x7); /* D3 /7 */ 8534 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8535 ins_pipe(ialu_reg_reg); 8536 %} 8537 8538 // Arithmetic Shift Right by variable 8539 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8540 %{ 8541 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8542 effect(KILL cr); 8543 8544 format %{ "sarl $dst, $shift" %} 8545 opcode(0xD3, 0x7); /* D3 /7 */ 8546 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8547 ins_pipe(ialu_mem_reg); 8548 %} 8549 8550 // Logical shift right by one 8551 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8552 %{ 8553 match(Set dst (URShiftI dst shift)); 8554 effect(KILL cr); 8555 8556 format %{ "shrl $dst, $shift" %} 8557 opcode(0xD1, 0x5); /* D1 /5 */ 8558 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8559 ins_pipe(ialu_reg); 8560 %} 8561 8562 // Logical shift right by one 8563 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8564 %{ 8565 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8566 effect(KILL cr); 8567 8568 format %{ "shrl $dst, $shift" %} 8569 opcode(0xD1, 0x5); /* D1 /5 */ 8570 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8571 ins_pipe(ialu_mem_imm); 8572 %} 8573 8574 // Logical Shift Right by 8-bit immediate 8575 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8576 %{ 8577 match(Set dst (URShiftI dst shift)); 8578 effect(KILL cr); 8579 8580 format %{ "shrl $dst, $shift" %} 8581 opcode(0xC1, 0x5); /* C1 /5 ib */ 8582 ins_encode(reg_opc_imm(dst, shift)); 8583 ins_pipe(ialu_reg); 8584 %} 8585 8586 // Logical Shift Right by 8-bit immediate 8587 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8588 %{ 8589 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8590 effect(KILL cr); 8591 8592 format %{ "shrl $dst, $shift" %} 8593 opcode(0xC1, 0x5); /* C1 /5 ib */ 8594 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8595 ins_pipe(ialu_mem_imm); 8596 %} 8597 8598 // Logical Shift Right by variable 8599 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8600 %{ 8601 match(Set dst (URShiftI dst shift)); 8602 effect(KILL cr); 8603 8604 format %{ "shrl $dst, $shift" %} 8605 opcode(0xD3, 0x5); /* D3 /5 */ 8606 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8607 ins_pipe(ialu_reg_reg); 8608 %} 8609 8610 // Logical Shift Right by variable 8611 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8612 %{ 8613 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8614 effect(KILL cr); 8615 8616 format %{ "shrl $dst, $shift" %} 8617 opcode(0xD3, 0x5); /* D3 /5 */ 8618 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8619 ins_pipe(ialu_mem_reg); 8620 %} 8621 8622 // Long Shift Instructions 8623 // Shift Left by one 8624 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8625 %{ 8626 match(Set dst (LShiftL dst shift)); 8627 effect(KILL cr); 8628 8629 format %{ "salq $dst, $shift" %} 8630 opcode(0xD1, 0x4); /* D1 /4 */ 8631 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8632 ins_pipe(ialu_reg); 8633 %} 8634 8635 // Shift Left by one 8636 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8637 %{ 8638 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8639 effect(KILL cr); 8640 8641 format %{ "salq $dst, $shift" %} 8642 opcode(0xD1, 0x4); /* D1 /4 */ 8643 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8644 ins_pipe(ialu_mem_imm); 8645 %} 8646 8647 // Shift Left by 8-bit immediate 8648 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8649 %{ 8650 match(Set dst (LShiftL dst shift)); 8651 effect(KILL cr); 8652 8653 format %{ "salq $dst, $shift" %} 8654 opcode(0xC1, 0x4); /* C1 /4 ib */ 8655 ins_encode(reg_opc_imm_wide(dst, shift)); 8656 ins_pipe(ialu_reg); 8657 %} 8658 8659 // Shift Left by 8-bit immediate 8660 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8661 %{ 8662 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8663 effect(KILL cr); 8664 8665 format %{ "salq $dst, $shift" %} 8666 opcode(0xC1, 0x4); /* C1 /4 ib */ 8667 ins_encode(REX_mem_wide(dst), OpcP, 8668 RM_opc_mem(secondary, dst), Con8or32(shift)); 8669 ins_pipe(ialu_mem_imm); 8670 %} 8671 8672 // Shift Left by variable 8673 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8674 %{ 8675 match(Set dst (LShiftL dst shift)); 8676 effect(KILL cr); 8677 8678 format %{ "salq $dst, $shift" %} 8679 opcode(0xD3, 0x4); /* D3 /4 */ 8680 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8681 ins_pipe(ialu_reg_reg); 8682 %} 8683 8684 // Shift Left by variable 8685 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8686 %{ 8687 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8688 effect(KILL cr); 8689 8690 format %{ "salq $dst, $shift" %} 8691 opcode(0xD3, 0x4); /* D3 /4 */ 8692 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8693 ins_pipe(ialu_mem_reg); 8694 %} 8695 8696 // Arithmetic shift right by one 8697 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8698 %{ 8699 match(Set dst (RShiftL dst shift)); 8700 effect(KILL cr); 8701 8702 format %{ "sarq $dst, $shift" %} 8703 opcode(0xD1, 0x7); /* D1 /7 */ 8704 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8705 ins_pipe(ialu_reg); 8706 %} 8707 8708 // Arithmetic shift right by one 8709 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8710 %{ 8711 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8712 effect(KILL cr); 8713 8714 format %{ "sarq $dst, $shift" %} 8715 opcode(0xD1, 0x7); /* D1 /7 */ 8716 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8717 ins_pipe(ialu_mem_imm); 8718 %} 8719 8720 // Arithmetic Shift Right by 8-bit immediate 8721 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8722 %{ 8723 match(Set dst (RShiftL dst shift)); 8724 effect(KILL cr); 8725 8726 format %{ "sarq $dst, $shift" %} 8727 opcode(0xC1, 0x7); /* C1 /7 ib */ 8728 ins_encode(reg_opc_imm_wide(dst, shift)); 8729 ins_pipe(ialu_mem_imm); 8730 %} 8731 8732 // Arithmetic Shift Right by 8-bit immediate 8733 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8734 %{ 8735 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8736 effect(KILL cr); 8737 8738 format %{ "sarq $dst, $shift" %} 8739 opcode(0xC1, 0x7); /* C1 /7 ib */ 8740 ins_encode(REX_mem_wide(dst), OpcP, 8741 RM_opc_mem(secondary, dst), Con8or32(shift)); 8742 ins_pipe(ialu_mem_imm); 8743 %} 8744 8745 // Arithmetic Shift Right by variable 8746 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8747 %{ 8748 match(Set dst (RShiftL dst shift)); 8749 effect(KILL cr); 8750 8751 format %{ "sarq $dst, $shift" %} 8752 opcode(0xD3, 0x7); /* D3 /7 */ 8753 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8754 ins_pipe(ialu_reg_reg); 8755 %} 8756 8757 // Arithmetic Shift Right by variable 8758 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8759 %{ 8760 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8761 effect(KILL cr); 8762 8763 format %{ "sarq $dst, $shift" %} 8764 opcode(0xD3, 0x7); /* D3 /7 */ 8765 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8766 ins_pipe(ialu_mem_reg); 8767 %} 8768 8769 // Logical shift right by one 8770 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8771 %{ 8772 match(Set dst (URShiftL dst shift)); 8773 effect(KILL cr); 8774 8775 format %{ "shrq $dst, $shift" %} 8776 opcode(0xD1, 0x5); /* D1 /5 */ 8777 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8778 ins_pipe(ialu_reg); 8779 %} 8780 8781 // Logical shift right by one 8782 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8783 %{ 8784 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8785 effect(KILL cr); 8786 8787 format %{ "shrq $dst, $shift" %} 8788 opcode(0xD1, 0x5); /* D1 /5 */ 8789 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8790 ins_pipe(ialu_mem_imm); 8791 %} 8792 8793 // Logical Shift Right by 8-bit immediate 8794 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8795 %{ 8796 match(Set dst (URShiftL dst shift)); 8797 effect(KILL cr); 8798 8799 format %{ "shrq $dst, $shift" %} 8800 opcode(0xC1, 0x5); /* C1 /5 ib */ 8801 ins_encode(reg_opc_imm_wide(dst, shift)); 8802 ins_pipe(ialu_reg); 8803 %} 8804 8805 8806 // Logical Shift Right by 8-bit immediate 8807 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8808 %{ 8809 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8810 effect(KILL cr); 8811 8812 format %{ "shrq $dst, $shift" %} 8813 opcode(0xC1, 0x5); /* C1 /5 ib */ 8814 ins_encode(REX_mem_wide(dst), OpcP, 8815 RM_opc_mem(secondary, dst), Con8or32(shift)); 8816 ins_pipe(ialu_mem_imm); 8817 %} 8818 8819 // Logical Shift Right by variable 8820 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8821 %{ 8822 match(Set dst (URShiftL dst shift)); 8823 effect(KILL cr); 8824 8825 format %{ "shrq $dst, $shift" %} 8826 opcode(0xD3, 0x5); /* D3 /5 */ 8827 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8828 ins_pipe(ialu_reg_reg); 8829 %} 8830 8831 // Logical Shift Right by variable 8832 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8833 %{ 8834 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8835 effect(KILL cr); 8836 8837 format %{ "shrq $dst, $shift" %} 8838 opcode(0xD3, 0x5); /* D3 /5 */ 8839 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8840 ins_pipe(ialu_mem_reg); 8841 %} 8842 8843 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8844 // This idiom is used by the compiler for the i2b bytecode. 8845 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8846 %{ 8847 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8848 8849 format %{ "movsbl $dst, $src\t# i2b" %} 8850 opcode(0x0F, 0xBE); 8851 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8852 ins_pipe(ialu_reg_reg); 8853 %} 8854 8855 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8856 // This idiom is used by the compiler the i2s bytecode. 8857 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8858 %{ 8859 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8860 8861 format %{ "movswl $dst, $src\t# i2s" %} 8862 opcode(0x0F, 0xBF); 8863 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8864 ins_pipe(ialu_reg_reg); 8865 %} 8866 8867 // ROL/ROR instructions 8868 8869 // ROL expand 8870 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8871 effect(KILL cr, USE_DEF dst); 8872 8873 format %{ "roll $dst" %} 8874 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8875 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8876 ins_pipe(ialu_reg); 8877 %} 8878 8879 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8880 effect(USE_DEF dst, USE shift, KILL cr); 8881 8882 format %{ "roll $dst, $shift" %} 8883 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8884 ins_encode( reg_opc_imm(dst, shift) ); 8885 ins_pipe(ialu_reg); 8886 %} 8887 8888 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8889 %{ 8890 effect(USE_DEF dst, USE shift, KILL cr); 8891 8892 format %{ "roll $dst, $shift" %} 8893 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8894 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8895 ins_pipe(ialu_reg_reg); 8896 %} 8897 // end of ROL expand 8898 8899 // Rotate Left by one 8900 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8901 %{ 8902 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8903 8904 expand %{ 8905 rolI_rReg_imm1(dst, cr); 8906 %} 8907 %} 8908 8909 // Rotate Left by 8-bit immediate 8910 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8911 %{ 8912 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8913 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8914 8915 expand %{ 8916 rolI_rReg_imm8(dst, lshift, cr); 8917 %} 8918 %} 8919 8920 // Rotate Left by variable 8921 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8922 %{ 8923 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8924 8925 expand %{ 8926 rolI_rReg_CL(dst, shift, cr); 8927 %} 8928 %} 8929 8930 // Rotate Left by variable 8931 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8932 %{ 8933 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8934 8935 expand %{ 8936 rolI_rReg_CL(dst, shift, cr); 8937 %} 8938 %} 8939 8940 // ROR expand 8941 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8942 %{ 8943 effect(USE_DEF dst, KILL cr); 8944 8945 format %{ "rorl $dst" %} 8946 opcode(0xD1, 0x1); /* D1 /1 */ 8947 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8948 ins_pipe(ialu_reg); 8949 %} 8950 8951 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8952 %{ 8953 effect(USE_DEF dst, USE shift, KILL cr); 8954 8955 format %{ "rorl $dst, $shift" %} 8956 opcode(0xC1, 0x1); /* C1 /1 ib */ 8957 ins_encode(reg_opc_imm(dst, shift)); 8958 ins_pipe(ialu_reg); 8959 %} 8960 8961 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8962 %{ 8963 effect(USE_DEF dst, USE shift, KILL cr); 8964 8965 format %{ "rorl $dst, $shift" %} 8966 opcode(0xD3, 0x1); /* D3 /1 */ 8967 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8968 ins_pipe(ialu_reg_reg); 8969 %} 8970 // end of ROR expand 8971 8972 // Rotate Right by one 8973 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8974 %{ 8975 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8976 8977 expand %{ 8978 rorI_rReg_imm1(dst, cr); 8979 %} 8980 %} 8981 8982 // Rotate Right by 8-bit immediate 8983 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8984 %{ 8985 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8986 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8987 8988 expand %{ 8989 rorI_rReg_imm8(dst, rshift, cr); 8990 %} 8991 %} 8992 8993 // Rotate Right by variable 8994 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8995 %{ 8996 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8997 8998 expand %{ 8999 rorI_rReg_CL(dst, shift, cr); 9000 %} 9001 %} 9002 9003 // Rotate Right by variable 9004 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9005 %{ 9006 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9007 9008 expand %{ 9009 rorI_rReg_CL(dst, shift, cr); 9010 %} 9011 %} 9012 9013 // for long rotate 9014 // ROL expand 9015 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9016 effect(USE_DEF dst, KILL cr); 9017 9018 format %{ "rolq $dst" %} 9019 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9020 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9021 ins_pipe(ialu_reg); 9022 %} 9023 9024 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9025 effect(USE_DEF dst, USE shift, KILL cr); 9026 9027 format %{ "rolq $dst, $shift" %} 9028 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9029 ins_encode( reg_opc_imm_wide(dst, shift) ); 9030 ins_pipe(ialu_reg); 9031 %} 9032 9033 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9034 %{ 9035 effect(USE_DEF dst, USE shift, KILL cr); 9036 9037 format %{ "rolq $dst, $shift" %} 9038 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9039 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9040 ins_pipe(ialu_reg_reg); 9041 %} 9042 // end of ROL expand 9043 9044 // Rotate Left by one 9045 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9046 %{ 9047 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9048 9049 expand %{ 9050 rolL_rReg_imm1(dst, cr); 9051 %} 9052 %} 9053 9054 // Rotate Left by 8-bit immediate 9055 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9056 %{ 9057 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9058 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9059 9060 expand %{ 9061 rolL_rReg_imm8(dst, lshift, cr); 9062 %} 9063 %} 9064 9065 // Rotate Left by variable 9066 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9067 %{ 9068 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9069 9070 expand %{ 9071 rolL_rReg_CL(dst, shift, cr); 9072 %} 9073 %} 9074 9075 // Rotate Left by variable 9076 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9077 %{ 9078 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9079 9080 expand %{ 9081 rolL_rReg_CL(dst, shift, cr); 9082 %} 9083 %} 9084 9085 // ROR expand 9086 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9087 %{ 9088 effect(USE_DEF dst, KILL cr); 9089 9090 format %{ "rorq $dst" %} 9091 opcode(0xD1, 0x1); /* D1 /1 */ 9092 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9093 ins_pipe(ialu_reg); 9094 %} 9095 9096 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9097 %{ 9098 effect(USE_DEF dst, USE shift, KILL cr); 9099 9100 format %{ "rorq $dst, $shift" %} 9101 opcode(0xC1, 0x1); /* C1 /1 ib */ 9102 ins_encode(reg_opc_imm_wide(dst, shift)); 9103 ins_pipe(ialu_reg); 9104 %} 9105 9106 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9107 %{ 9108 effect(USE_DEF dst, USE shift, KILL cr); 9109 9110 format %{ "rorq $dst, $shift" %} 9111 opcode(0xD3, 0x1); /* D3 /1 */ 9112 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9113 ins_pipe(ialu_reg_reg); 9114 %} 9115 // end of ROR expand 9116 9117 // Rotate Right by one 9118 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9119 %{ 9120 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9121 9122 expand %{ 9123 rorL_rReg_imm1(dst, cr); 9124 %} 9125 %} 9126 9127 // Rotate Right by 8-bit immediate 9128 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9129 %{ 9130 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9131 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9132 9133 expand %{ 9134 rorL_rReg_imm8(dst, rshift, cr); 9135 %} 9136 %} 9137 9138 // Rotate Right by variable 9139 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9140 %{ 9141 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9142 9143 expand %{ 9144 rorL_rReg_CL(dst, shift, cr); 9145 %} 9146 %} 9147 9148 // Rotate Right by variable 9149 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9150 %{ 9151 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9152 9153 expand %{ 9154 rorL_rReg_CL(dst, shift, cr); 9155 %} 9156 %} 9157 9158 // Logical Instructions 9159 9160 // Integer Logical Instructions 9161 9162 // And Instructions 9163 // And Register with Register 9164 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9165 %{ 9166 match(Set dst (AndI dst src)); 9167 effect(KILL cr); 9168 9169 format %{ "andl $dst, $src\t# int" %} 9170 opcode(0x23); 9171 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9172 ins_pipe(ialu_reg_reg); 9173 %} 9174 9175 // And Register with Immediate 255 9176 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9177 %{ 9178 match(Set dst (AndI dst src)); 9179 9180 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9181 opcode(0x0F, 0xB6); 9182 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9183 ins_pipe(ialu_reg); 9184 %} 9185 9186 // And Register with Immediate 255 and promote to long 9187 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9188 %{ 9189 match(Set dst (ConvI2L (AndI src mask))); 9190 9191 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9192 opcode(0x0F, 0xB6); 9193 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9194 ins_pipe(ialu_reg); 9195 %} 9196 9197 // And Register with Immediate 65535 9198 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9199 %{ 9200 match(Set dst (AndI dst src)); 9201 9202 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9203 opcode(0x0F, 0xB7); 9204 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9205 ins_pipe(ialu_reg); 9206 %} 9207 9208 // And Register with Immediate 65535 and promote to long 9209 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9210 %{ 9211 match(Set dst (ConvI2L (AndI src mask))); 9212 9213 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9214 opcode(0x0F, 0xB7); 9215 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9216 ins_pipe(ialu_reg); 9217 %} 9218 9219 // And Register with Immediate 9220 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9221 %{ 9222 match(Set dst (AndI dst src)); 9223 effect(KILL cr); 9224 9225 format %{ "andl $dst, $src\t# int" %} 9226 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9227 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9228 ins_pipe(ialu_reg); 9229 %} 9230 9231 // And Register with Memory 9232 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9233 %{ 9234 match(Set dst (AndI dst (LoadI src))); 9235 effect(KILL cr); 9236 9237 ins_cost(125); 9238 format %{ "andl $dst, $src\t# int" %} 9239 opcode(0x23); 9240 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9241 ins_pipe(ialu_reg_mem); 9242 %} 9243 9244 // And Memory with Register 9245 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9246 %{ 9247 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9248 effect(KILL cr); 9249 9250 ins_cost(150); 9251 format %{ "andl $dst, $src\t# int" %} 9252 opcode(0x21); /* Opcode 21 /r */ 9253 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9254 ins_pipe(ialu_mem_reg); 9255 %} 9256 9257 // And Memory with Immediate 9258 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9259 %{ 9260 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9261 effect(KILL cr); 9262 9263 ins_cost(125); 9264 format %{ "andl $dst, $src\t# int" %} 9265 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9266 ins_encode(REX_mem(dst), OpcSE(src), 9267 RM_opc_mem(secondary, dst), Con8or32(src)); 9268 ins_pipe(ialu_mem_imm); 9269 %} 9270 9271 // BMI1 instructions 9272 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9273 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9274 predicate(UseBMI1Instructions); 9275 effect(KILL cr); 9276 9277 ins_cost(125); 9278 format %{ "andnl $dst, $src1, $src2" %} 9279 9280 ins_encode %{ 9281 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9282 %} 9283 ins_pipe(ialu_reg_mem); 9284 %} 9285 9286 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9287 match(Set dst (AndI (XorI src1 minus_1) src2)); 9288 predicate(UseBMI1Instructions); 9289 effect(KILL cr); 9290 9291 format %{ "andnl $dst, $src1, $src2" %} 9292 9293 ins_encode %{ 9294 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9295 %} 9296 ins_pipe(ialu_reg); 9297 %} 9298 9299 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9300 match(Set dst (AndI (SubI imm_zero src) src)); 9301 predicate(UseBMI1Instructions); 9302 effect(KILL cr); 9303 9304 format %{ "blsil $dst, $src" %} 9305 9306 ins_encode %{ 9307 __ blsil($dst$$Register, $src$$Register); 9308 %} 9309 ins_pipe(ialu_reg); 9310 %} 9311 9312 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9313 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9314 predicate(UseBMI1Instructions); 9315 effect(KILL cr); 9316 9317 ins_cost(125); 9318 format %{ "blsil $dst, $src" %} 9319 9320 ins_encode %{ 9321 __ blsil($dst$$Register, $src$$Address); 9322 %} 9323 ins_pipe(ialu_reg_mem); 9324 %} 9325 9326 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9327 %{ 9328 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9329 predicate(UseBMI1Instructions); 9330 effect(KILL cr); 9331 9332 ins_cost(125); 9333 format %{ "blsmskl $dst, $src" %} 9334 9335 ins_encode %{ 9336 __ blsmskl($dst$$Register, $src$$Address); 9337 %} 9338 ins_pipe(ialu_reg_mem); 9339 %} 9340 9341 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9342 %{ 9343 match(Set dst (XorI (AddI src minus_1) src)); 9344 predicate(UseBMI1Instructions); 9345 effect(KILL cr); 9346 9347 format %{ "blsmskl $dst, $src" %} 9348 9349 ins_encode %{ 9350 __ blsmskl($dst$$Register, $src$$Register); 9351 %} 9352 9353 ins_pipe(ialu_reg); 9354 %} 9355 9356 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9357 %{ 9358 match(Set dst (AndI (AddI src minus_1) src) ); 9359 predicate(UseBMI1Instructions); 9360 effect(KILL cr); 9361 9362 format %{ "blsrl $dst, $src" %} 9363 9364 ins_encode %{ 9365 __ blsrl($dst$$Register, $src$$Register); 9366 %} 9367 9368 ins_pipe(ialu_reg_mem); 9369 %} 9370 9371 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9372 %{ 9373 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9374 predicate(UseBMI1Instructions); 9375 effect(KILL cr); 9376 9377 ins_cost(125); 9378 format %{ "blsrl $dst, $src" %} 9379 9380 ins_encode %{ 9381 __ blsrl($dst$$Register, $src$$Address); 9382 %} 9383 9384 ins_pipe(ialu_reg); 9385 %} 9386 9387 // Or Instructions 9388 // Or Register with Register 9389 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9390 %{ 9391 match(Set dst (OrI dst src)); 9392 effect(KILL cr); 9393 9394 format %{ "orl $dst, $src\t# int" %} 9395 opcode(0x0B); 9396 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9397 ins_pipe(ialu_reg_reg); 9398 %} 9399 9400 // Or Register with Immediate 9401 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9402 %{ 9403 match(Set dst (OrI dst src)); 9404 effect(KILL cr); 9405 9406 format %{ "orl $dst, $src\t# int" %} 9407 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9408 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9409 ins_pipe(ialu_reg); 9410 %} 9411 9412 // Or Register with Memory 9413 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9414 %{ 9415 match(Set dst (OrI dst (LoadI src))); 9416 effect(KILL cr); 9417 9418 ins_cost(125); 9419 format %{ "orl $dst, $src\t# int" %} 9420 opcode(0x0B); 9421 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9422 ins_pipe(ialu_reg_mem); 9423 %} 9424 9425 // Or Memory with Register 9426 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9427 %{ 9428 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9429 effect(KILL cr); 9430 9431 ins_cost(150); 9432 format %{ "orl $dst, $src\t# int" %} 9433 opcode(0x09); /* Opcode 09 /r */ 9434 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9435 ins_pipe(ialu_mem_reg); 9436 %} 9437 9438 // Or Memory with Immediate 9439 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9440 %{ 9441 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9442 effect(KILL cr); 9443 9444 ins_cost(125); 9445 format %{ "orl $dst, $src\t# int" %} 9446 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9447 ins_encode(REX_mem(dst), OpcSE(src), 9448 RM_opc_mem(secondary, dst), Con8or32(src)); 9449 ins_pipe(ialu_mem_imm); 9450 %} 9451 9452 // Xor Instructions 9453 // Xor Register with Register 9454 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9455 %{ 9456 match(Set dst (XorI dst src)); 9457 effect(KILL cr); 9458 9459 format %{ "xorl $dst, $src\t# int" %} 9460 opcode(0x33); 9461 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9462 ins_pipe(ialu_reg_reg); 9463 %} 9464 9465 // Xor Register with Immediate -1 9466 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9467 match(Set dst (XorI dst imm)); 9468 9469 format %{ "not $dst" %} 9470 ins_encode %{ 9471 __ notl($dst$$Register); 9472 %} 9473 ins_pipe(ialu_reg); 9474 %} 9475 9476 // Xor Register with Immediate 9477 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9478 %{ 9479 match(Set dst (XorI dst src)); 9480 effect(KILL cr); 9481 9482 format %{ "xorl $dst, $src\t# int" %} 9483 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9484 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9485 ins_pipe(ialu_reg); 9486 %} 9487 9488 // Xor Register with Memory 9489 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9490 %{ 9491 match(Set dst (XorI dst (LoadI src))); 9492 effect(KILL cr); 9493 9494 ins_cost(125); 9495 format %{ "xorl $dst, $src\t# int" %} 9496 opcode(0x33); 9497 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9498 ins_pipe(ialu_reg_mem); 9499 %} 9500 9501 // Xor Memory with Register 9502 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9503 %{ 9504 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9505 effect(KILL cr); 9506 9507 ins_cost(150); 9508 format %{ "xorl $dst, $src\t# int" %} 9509 opcode(0x31); /* Opcode 31 /r */ 9510 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9511 ins_pipe(ialu_mem_reg); 9512 %} 9513 9514 // Xor Memory with Immediate 9515 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9516 %{ 9517 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9518 effect(KILL cr); 9519 9520 ins_cost(125); 9521 format %{ "xorl $dst, $src\t# int" %} 9522 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9523 ins_encode(REX_mem(dst), OpcSE(src), 9524 RM_opc_mem(secondary, dst), Con8or32(src)); 9525 ins_pipe(ialu_mem_imm); 9526 %} 9527 9528 9529 // Long Logical Instructions 9530 9531 // And Instructions 9532 // And Register with Register 9533 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9534 %{ 9535 match(Set dst (AndL dst src)); 9536 effect(KILL cr); 9537 9538 format %{ "andq $dst, $src\t# long" %} 9539 opcode(0x23); 9540 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9541 ins_pipe(ialu_reg_reg); 9542 %} 9543 9544 // And Register with Immediate 255 9545 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9546 %{ 9547 match(Set dst (AndL dst src)); 9548 9549 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9550 opcode(0x0F, 0xB6); 9551 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9552 ins_pipe(ialu_reg); 9553 %} 9554 9555 // And Register with Immediate 65535 9556 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9557 %{ 9558 match(Set dst (AndL dst src)); 9559 9560 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9561 opcode(0x0F, 0xB7); 9562 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9563 ins_pipe(ialu_reg); 9564 %} 9565 9566 // And Register with Immediate 9567 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9568 %{ 9569 match(Set dst (AndL dst src)); 9570 effect(KILL cr); 9571 9572 format %{ "andq $dst, $src\t# long" %} 9573 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9574 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9575 ins_pipe(ialu_reg); 9576 %} 9577 9578 // And Register with Memory 9579 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9580 %{ 9581 match(Set dst (AndL dst (LoadL src))); 9582 effect(KILL cr); 9583 9584 ins_cost(125); 9585 format %{ "andq $dst, $src\t# long" %} 9586 opcode(0x23); 9587 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9588 ins_pipe(ialu_reg_mem); 9589 %} 9590 9591 // And Memory with Register 9592 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9593 %{ 9594 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9595 effect(KILL cr); 9596 9597 ins_cost(150); 9598 format %{ "andq $dst, $src\t# long" %} 9599 opcode(0x21); /* Opcode 21 /r */ 9600 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9601 ins_pipe(ialu_mem_reg); 9602 %} 9603 9604 // And Memory with Immediate 9605 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9606 %{ 9607 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9608 effect(KILL cr); 9609 9610 ins_cost(125); 9611 format %{ "andq $dst, $src\t# long" %} 9612 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9613 ins_encode(REX_mem_wide(dst), OpcSE(src), 9614 RM_opc_mem(secondary, dst), Con8or32(src)); 9615 ins_pipe(ialu_mem_imm); 9616 %} 9617 9618 // BMI1 instructions 9619 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9620 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9621 predicate(UseBMI1Instructions); 9622 effect(KILL cr); 9623 9624 ins_cost(125); 9625 format %{ "andnq $dst, $src1, $src2" %} 9626 9627 ins_encode %{ 9628 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9629 %} 9630 ins_pipe(ialu_reg_mem); 9631 %} 9632 9633 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9634 match(Set dst (AndL (XorL src1 minus_1) src2)); 9635 predicate(UseBMI1Instructions); 9636 effect(KILL cr); 9637 9638 format %{ "andnq $dst, $src1, $src2" %} 9639 9640 ins_encode %{ 9641 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9642 %} 9643 ins_pipe(ialu_reg_mem); 9644 %} 9645 9646 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9647 match(Set dst (AndL (SubL imm_zero src) src)); 9648 predicate(UseBMI1Instructions); 9649 effect(KILL cr); 9650 9651 format %{ "blsiq $dst, $src" %} 9652 9653 ins_encode %{ 9654 __ blsiq($dst$$Register, $src$$Register); 9655 %} 9656 ins_pipe(ialu_reg); 9657 %} 9658 9659 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9660 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9661 predicate(UseBMI1Instructions); 9662 effect(KILL cr); 9663 9664 ins_cost(125); 9665 format %{ "blsiq $dst, $src" %} 9666 9667 ins_encode %{ 9668 __ blsiq($dst$$Register, $src$$Address); 9669 %} 9670 ins_pipe(ialu_reg_mem); 9671 %} 9672 9673 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9674 %{ 9675 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9676 predicate(UseBMI1Instructions); 9677 effect(KILL cr); 9678 9679 ins_cost(125); 9680 format %{ "blsmskq $dst, $src" %} 9681 9682 ins_encode %{ 9683 __ blsmskq($dst$$Register, $src$$Address); 9684 %} 9685 ins_pipe(ialu_reg_mem); 9686 %} 9687 9688 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9689 %{ 9690 match(Set dst (XorL (AddL src minus_1) src)); 9691 predicate(UseBMI1Instructions); 9692 effect(KILL cr); 9693 9694 format %{ "blsmskq $dst, $src" %} 9695 9696 ins_encode %{ 9697 __ blsmskq($dst$$Register, $src$$Register); 9698 %} 9699 9700 ins_pipe(ialu_reg); 9701 %} 9702 9703 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9704 %{ 9705 match(Set dst (AndL (AddL src minus_1) src) ); 9706 predicate(UseBMI1Instructions); 9707 effect(KILL cr); 9708 9709 format %{ "blsrq $dst, $src" %} 9710 9711 ins_encode %{ 9712 __ blsrq($dst$$Register, $src$$Register); 9713 %} 9714 9715 ins_pipe(ialu_reg); 9716 %} 9717 9718 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9719 %{ 9720 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9721 predicate(UseBMI1Instructions); 9722 effect(KILL cr); 9723 9724 ins_cost(125); 9725 format %{ "blsrq $dst, $src" %} 9726 9727 ins_encode %{ 9728 __ blsrq($dst$$Register, $src$$Address); 9729 %} 9730 9731 ins_pipe(ialu_reg); 9732 %} 9733 9734 // Or Instructions 9735 // Or Register with Register 9736 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9737 %{ 9738 match(Set dst (OrL dst src)); 9739 effect(KILL cr); 9740 9741 format %{ "orq $dst, $src\t# long" %} 9742 opcode(0x0B); 9743 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9744 ins_pipe(ialu_reg_reg); 9745 %} 9746 9747 // Use any_RegP to match R15 (TLS register) without spilling. 9748 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9749 match(Set dst (OrL dst (CastP2X src))); 9750 effect(KILL cr); 9751 9752 format %{ "orq $dst, $src\t# long" %} 9753 opcode(0x0B); 9754 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9755 ins_pipe(ialu_reg_reg); 9756 %} 9757 9758 9759 // Or Register with Immediate 9760 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9761 %{ 9762 match(Set dst (OrL dst src)); 9763 effect(KILL cr); 9764 9765 format %{ "orq $dst, $src\t# long" %} 9766 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9767 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9768 ins_pipe(ialu_reg); 9769 %} 9770 9771 // Or Register with Memory 9772 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9773 %{ 9774 match(Set dst (OrL dst (LoadL src))); 9775 effect(KILL cr); 9776 9777 ins_cost(125); 9778 format %{ "orq $dst, $src\t# long" %} 9779 opcode(0x0B); 9780 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9781 ins_pipe(ialu_reg_mem); 9782 %} 9783 9784 // Or Memory with Register 9785 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9786 %{ 9787 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9788 effect(KILL cr); 9789 9790 ins_cost(150); 9791 format %{ "orq $dst, $src\t# long" %} 9792 opcode(0x09); /* Opcode 09 /r */ 9793 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9794 ins_pipe(ialu_mem_reg); 9795 %} 9796 9797 // Or Memory with Immediate 9798 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9799 %{ 9800 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9801 effect(KILL cr); 9802 9803 ins_cost(125); 9804 format %{ "orq $dst, $src\t# long" %} 9805 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9806 ins_encode(REX_mem_wide(dst), OpcSE(src), 9807 RM_opc_mem(secondary, dst), Con8or32(src)); 9808 ins_pipe(ialu_mem_imm); 9809 %} 9810 9811 // Xor Instructions 9812 // Xor Register with Register 9813 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9814 %{ 9815 match(Set dst (XorL dst src)); 9816 effect(KILL cr); 9817 9818 format %{ "xorq $dst, $src\t# long" %} 9819 opcode(0x33); 9820 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9821 ins_pipe(ialu_reg_reg); 9822 %} 9823 9824 // Xor Register with Immediate -1 9825 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9826 match(Set dst (XorL dst imm)); 9827 9828 format %{ "notq $dst" %} 9829 ins_encode %{ 9830 __ notq($dst$$Register); 9831 %} 9832 ins_pipe(ialu_reg); 9833 %} 9834 9835 // Xor Register with Immediate 9836 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9837 %{ 9838 match(Set dst (XorL dst src)); 9839 effect(KILL cr); 9840 9841 format %{ "xorq $dst, $src\t# long" %} 9842 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9843 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9844 ins_pipe(ialu_reg); 9845 %} 9846 9847 // Xor Register with Memory 9848 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9849 %{ 9850 match(Set dst (XorL dst (LoadL src))); 9851 effect(KILL cr); 9852 9853 ins_cost(125); 9854 format %{ "xorq $dst, $src\t# long" %} 9855 opcode(0x33); 9856 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9857 ins_pipe(ialu_reg_mem); 9858 %} 9859 9860 // Xor Memory with Register 9861 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9862 %{ 9863 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9864 effect(KILL cr); 9865 9866 ins_cost(150); 9867 format %{ "xorq $dst, $src\t# long" %} 9868 opcode(0x31); /* Opcode 31 /r */ 9869 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9870 ins_pipe(ialu_mem_reg); 9871 %} 9872 9873 // Xor Memory with Immediate 9874 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9875 %{ 9876 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9877 effect(KILL cr); 9878 9879 ins_cost(125); 9880 format %{ "xorq $dst, $src\t# long" %} 9881 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9882 ins_encode(REX_mem_wide(dst), OpcSE(src), 9883 RM_opc_mem(secondary, dst), Con8or32(src)); 9884 ins_pipe(ialu_mem_imm); 9885 %} 9886 9887 // Convert Int to Boolean 9888 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9889 %{ 9890 match(Set dst (Conv2B src)); 9891 effect(KILL cr); 9892 9893 format %{ "testl $src, $src\t# ci2b\n\t" 9894 "setnz $dst\n\t" 9895 "movzbl $dst, $dst" %} 9896 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9897 setNZ_reg(dst), 9898 REX_reg_breg(dst, dst), // movzbl 9899 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9900 ins_pipe(pipe_slow); // XXX 9901 %} 9902 9903 // Convert Pointer to Boolean 9904 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9905 %{ 9906 match(Set dst (Conv2B src)); 9907 effect(KILL cr); 9908 9909 format %{ "testq $src, $src\t# cp2b\n\t" 9910 "setnz $dst\n\t" 9911 "movzbl $dst, $dst" %} 9912 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9913 setNZ_reg(dst), 9914 REX_reg_breg(dst, dst), // movzbl 9915 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9916 ins_pipe(pipe_slow); // XXX 9917 %} 9918 9919 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9920 %{ 9921 match(Set dst (CmpLTMask p q)); 9922 effect(KILL cr); 9923 9924 ins_cost(400); 9925 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9926 "setlt $dst\n\t" 9927 "movzbl $dst, $dst\n\t" 9928 "negl $dst" %} 9929 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9930 setLT_reg(dst), 9931 REX_reg_breg(dst, dst), // movzbl 9932 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9933 neg_reg(dst)); 9934 ins_pipe(pipe_slow); 9935 %} 9936 9937 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9938 %{ 9939 match(Set dst (CmpLTMask dst zero)); 9940 effect(KILL cr); 9941 9942 ins_cost(100); 9943 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9944 ins_encode %{ 9945 __ sarl($dst$$Register, 31); 9946 %} 9947 ins_pipe(ialu_reg); 9948 %} 9949 9950 /* Better to save a register than avoid a branch */ 9951 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9952 %{ 9953 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9954 effect(KILL cr); 9955 ins_cost(300); 9956 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9957 "jge done\n\t" 9958 "addl $p,$y\n" 9959 "done: " %} 9960 ins_encode %{ 9961 Register Rp = $p$$Register; 9962 Register Rq = $q$$Register; 9963 Register Ry = $y$$Register; 9964 Label done; 9965 __ subl(Rp, Rq); 9966 __ jccb(Assembler::greaterEqual, done); 9967 __ addl(Rp, Ry); 9968 __ bind(done); 9969 %} 9970 ins_pipe(pipe_cmplt); 9971 %} 9972 9973 /* Better to save a register than avoid a branch */ 9974 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9975 %{ 9976 match(Set y (AndI (CmpLTMask p q) y)); 9977 effect(KILL cr); 9978 9979 ins_cost(300); 9980 9981 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9982 "jlt done\n\t" 9983 "xorl $y, $y\n" 9984 "done: " %} 9985 ins_encode %{ 9986 Register Rp = $p$$Register; 9987 Register Rq = $q$$Register; 9988 Register Ry = $y$$Register; 9989 Label done; 9990 __ cmpl(Rp, Rq); 9991 __ jccb(Assembler::less, done); 9992 __ xorl(Ry, Ry); 9993 __ bind(done); 9994 %} 9995 ins_pipe(pipe_cmplt); 9996 %} 9997 9998 9999 //---------- FP Instructions------------------------------------------------ 10000 10001 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10002 %{ 10003 match(Set cr (CmpF src1 src2)); 10004 10005 ins_cost(145); 10006 format %{ "ucomiss $src1, $src2\n\t" 10007 "jnp,s exit\n\t" 10008 "pushfq\t# saw NaN, set CF\n\t" 10009 "andq [rsp], #0xffffff2b\n\t" 10010 "popfq\n" 10011 "exit:" %} 10012 ins_encode %{ 10013 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10014 emit_cmpfp_fixup(_masm); 10015 %} 10016 ins_pipe(pipe_slow); 10017 %} 10018 10019 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10020 match(Set cr (CmpF src1 src2)); 10021 10022 ins_cost(100); 10023 format %{ "ucomiss $src1, $src2" %} 10024 ins_encode %{ 10025 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10026 %} 10027 ins_pipe(pipe_slow); 10028 %} 10029 10030 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10031 %{ 10032 match(Set cr (CmpF src1 (LoadF src2))); 10033 10034 ins_cost(145); 10035 format %{ "ucomiss $src1, $src2\n\t" 10036 "jnp,s exit\n\t" 10037 "pushfq\t# saw NaN, set CF\n\t" 10038 "andq [rsp], #0xffffff2b\n\t" 10039 "popfq\n" 10040 "exit:" %} 10041 ins_encode %{ 10042 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10043 emit_cmpfp_fixup(_masm); 10044 %} 10045 ins_pipe(pipe_slow); 10046 %} 10047 10048 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10049 match(Set cr (CmpF src1 (LoadF src2))); 10050 10051 ins_cost(100); 10052 format %{ "ucomiss $src1, $src2" %} 10053 ins_encode %{ 10054 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10055 %} 10056 ins_pipe(pipe_slow); 10057 %} 10058 10059 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10060 match(Set cr (CmpF src con)); 10061 10062 ins_cost(145); 10063 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10064 "jnp,s exit\n\t" 10065 "pushfq\t# saw NaN, set CF\n\t" 10066 "andq [rsp], #0xffffff2b\n\t" 10067 "popfq\n" 10068 "exit:" %} 10069 ins_encode %{ 10070 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10071 emit_cmpfp_fixup(_masm); 10072 %} 10073 ins_pipe(pipe_slow); 10074 %} 10075 10076 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10077 match(Set cr (CmpF src con)); 10078 ins_cost(100); 10079 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10080 ins_encode %{ 10081 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10082 %} 10083 ins_pipe(pipe_slow); 10084 %} 10085 10086 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10087 %{ 10088 match(Set cr (CmpD src1 src2)); 10089 10090 ins_cost(145); 10091 format %{ "ucomisd $src1, $src2\n\t" 10092 "jnp,s exit\n\t" 10093 "pushfq\t# saw NaN, set CF\n\t" 10094 "andq [rsp], #0xffffff2b\n\t" 10095 "popfq\n" 10096 "exit:" %} 10097 ins_encode %{ 10098 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10099 emit_cmpfp_fixup(_masm); 10100 %} 10101 ins_pipe(pipe_slow); 10102 %} 10103 10104 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10105 match(Set cr (CmpD src1 src2)); 10106 10107 ins_cost(100); 10108 format %{ "ucomisd $src1, $src2 test" %} 10109 ins_encode %{ 10110 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10111 %} 10112 ins_pipe(pipe_slow); 10113 %} 10114 10115 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10116 %{ 10117 match(Set cr (CmpD src1 (LoadD src2))); 10118 10119 ins_cost(145); 10120 format %{ "ucomisd $src1, $src2\n\t" 10121 "jnp,s exit\n\t" 10122 "pushfq\t# saw NaN, set CF\n\t" 10123 "andq [rsp], #0xffffff2b\n\t" 10124 "popfq\n" 10125 "exit:" %} 10126 ins_encode %{ 10127 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10128 emit_cmpfp_fixup(_masm); 10129 %} 10130 ins_pipe(pipe_slow); 10131 %} 10132 10133 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10134 match(Set cr (CmpD src1 (LoadD src2))); 10135 10136 ins_cost(100); 10137 format %{ "ucomisd $src1, $src2" %} 10138 ins_encode %{ 10139 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10140 %} 10141 ins_pipe(pipe_slow); 10142 %} 10143 10144 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10145 match(Set cr (CmpD src con)); 10146 10147 ins_cost(145); 10148 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10149 "jnp,s exit\n\t" 10150 "pushfq\t# saw NaN, set CF\n\t" 10151 "andq [rsp], #0xffffff2b\n\t" 10152 "popfq\n" 10153 "exit:" %} 10154 ins_encode %{ 10155 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10156 emit_cmpfp_fixup(_masm); 10157 %} 10158 ins_pipe(pipe_slow); 10159 %} 10160 10161 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10162 match(Set cr (CmpD src con)); 10163 ins_cost(100); 10164 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10165 ins_encode %{ 10166 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10167 %} 10168 ins_pipe(pipe_slow); 10169 %} 10170 10171 // Compare into -1,0,1 10172 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10173 %{ 10174 match(Set dst (CmpF3 src1 src2)); 10175 effect(KILL cr); 10176 10177 ins_cost(275); 10178 format %{ "ucomiss $src1, $src2\n\t" 10179 "movl $dst, #-1\n\t" 10180 "jp,s done\n\t" 10181 "jb,s done\n\t" 10182 "setne $dst\n\t" 10183 "movzbl $dst, $dst\n" 10184 "done:" %} 10185 ins_encode %{ 10186 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10187 emit_cmpfp3(_masm, $dst$$Register); 10188 %} 10189 ins_pipe(pipe_slow); 10190 %} 10191 10192 // Compare into -1,0,1 10193 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10194 %{ 10195 match(Set dst (CmpF3 src1 (LoadF src2))); 10196 effect(KILL cr); 10197 10198 ins_cost(275); 10199 format %{ "ucomiss $src1, $src2\n\t" 10200 "movl $dst, #-1\n\t" 10201 "jp,s done\n\t" 10202 "jb,s done\n\t" 10203 "setne $dst\n\t" 10204 "movzbl $dst, $dst\n" 10205 "done:" %} 10206 ins_encode %{ 10207 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10208 emit_cmpfp3(_masm, $dst$$Register); 10209 %} 10210 ins_pipe(pipe_slow); 10211 %} 10212 10213 // Compare into -1,0,1 10214 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10215 match(Set dst (CmpF3 src con)); 10216 effect(KILL cr); 10217 10218 ins_cost(275); 10219 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10220 "movl $dst, #-1\n\t" 10221 "jp,s done\n\t" 10222 "jb,s done\n\t" 10223 "setne $dst\n\t" 10224 "movzbl $dst, $dst\n" 10225 "done:" %} 10226 ins_encode %{ 10227 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10228 emit_cmpfp3(_masm, $dst$$Register); 10229 %} 10230 ins_pipe(pipe_slow); 10231 %} 10232 10233 // Compare into -1,0,1 10234 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10235 %{ 10236 match(Set dst (CmpD3 src1 src2)); 10237 effect(KILL cr); 10238 10239 ins_cost(275); 10240 format %{ "ucomisd $src1, $src2\n\t" 10241 "movl $dst, #-1\n\t" 10242 "jp,s done\n\t" 10243 "jb,s done\n\t" 10244 "setne $dst\n\t" 10245 "movzbl $dst, $dst\n" 10246 "done:" %} 10247 ins_encode %{ 10248 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10249 emit_cmpfp3(_masm, $dst$$Register); 10250 %} 10251 ins_pipe(pipe_slow); 10252 %} 10253 10254 // Compare into -1,0,1 10255 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10256 %{ 10257 match(Set dst (CmpD3 src1 (LoadD src2))); 10258 effect(KILL cr); 10259 10260 ins_cost(275); 10261 format %{ "ucomisd $src1, $src2\n\t" 10262 "movl $dst, #-1\n\t" 10263 "jp,s done\n\t" 10264 "jb,s done\n\t" 10265 "setne $dst\n\t" 10266 "movzbl $dst, $dst\n" 10267 "done:" %} 10268 ins_encode %{ 10269 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10270 emit_cmpfp3(_masm, $dst$$Register); 10271 %} 10272 ins_pipe(pipe_slow); 10273 %} 10274 10275 // Compare into -1,0,1 10276 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10277 match(Set dst (CmpD3 src con)); 10278 effect(KILL cr); 10279 10280 ins_cost(275); 10281 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10282 "movl $dst, #-1\n\t" 10283 "jp,s done\n\t" 10284 "jb,s done\n\t" 10285 "setne $dst\n\t" 10286 "movzbl $dst, $dst\n" 10287 "done:" %} 10288 ins_encode %{ 10289 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10290 emit_cmpfp3(_masm, $dst$$Register); 10291 %} 10292 ins_pipe(pipe_slow); 10293 %} 10294 10295 //----------Arithmetic Conversion Instructions--------------------------------- 10296 10297 instruct roundFloat_nop(regF dst) 10298 %{ 10299 match(Set dst (RoundFloat dst)); 10300 10301 ins_cost(0); 10302 ins_encode(); 10303 ins_pipe(empty); 10304 %} 10305 10306 instruct roundDouble_nop(regD dst) 10307 %{ 10308 match(Set dst (RoundDouble dst)); 10309 10310 ins_cost(0); 10311 ins_encode(); 10312 ins_pipe(empty); 10313 %} 10314 10315 instruct convF2D_reg_reg(regD dst, regF src) 10316 %{ 10317 match(Set dst (ConvF2D src)); 10318 10319 format %{ "cvtss2sd $dst, $src" %} 10320 ins_encode %{ 10321 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10322 %} 10323 ins_pipe(pipe_slow); // XXX 10324 %} 10325 10326 instruct convF2D_reg_mem(regD dst, memory src) 10327 %{ 10328 match(Set dst (ConvF2D (LoadF src))); 10329 10330 format %{ "cvtss2sd $dst, $src" %} 10331 ins_encode %{ 10332 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10333 %} 10334 ins_pipe(pipe_slow); // XXX 10335 %} 10336 10337 instruct convD2F_reg_reg(regF dst, regD src) 10338 %{ 10339 match(Set dst (ConvD2F src)); 10340 10341 format %{ "cvtsd2ss $dst, $src" %} 10342 ins_encode %{ 10343 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10344 %} 10345 ins_pipe(pipe_slow); // XXX 10346 %} 10347 10348 instruct convD2F_reg_mem(regF dst, memory src) 10349 %{ 10350 match(Set dst (ConvD2F (LoadD src))); 10351 10352 format %{ "cvtsd2ss $dst, $src" %} 10353 ins_encode %{ 10354 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10355 %} 10356 ins_pipe(pipe_slow); // XXX 10357 %} 10358 10359 // XXX do mem variants 10360 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10361 %{ 10362 match(Set dst (ConvF2I src)); 10363 effect(KILL cr); 10364 10365 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10366 "cmpl $dst, #0x80000000\n\t" 10367 "jne,s done\n\t" 10368 "subq rsp, #8\n\t" 10369 "movss [rsp], $src\n\t" 10370 "call f2i_fixup\n\t" 10371 "popq $dst\n" 10372 "done: "%} 10373 ins_encode %{ 10374 Label done; 10375 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10376 __ cmpl($dst$$Register, 0x80000000); 10377 __ jccb(Assembler::notEqual, done); 10378 __ subptr(rsp, 8); 10379 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10380 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10381 __ pop($dst$$Register); 10382 __ bind(done); 10383 %} 10384 ins_pipe(pipe_slow); 10385 %} 10386 10387 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10388 %{ 10389 match(Set dst (ConvF2L src)); 10390 effect(KILL cr); 10391 10392 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10393 "cmpq $dst, [0x8000000000000000]\n\t" 10394 "jne,s done\n\t" 10395 "subq rsp, #8\n\t" 10396 "movss [rsp], $src\n\t" 10397 "call f2l_fixup\n\t" 10398 "popq $dst\n" 10399 "done: "%} 10400 ins_encode %{ 10401 Label done; 10402 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10403 __ cmp64($dst$$Register, 10404 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10405 __ jccb(Assembler::notEqual, done); 10406 __ subptr(rsp, 8); 10407 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10408 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10409 __ pop($dst$$Register); 10410 __ bind(done); 10411 %} 10412 ins_pipe(pipe_slow); 10413 %} 10414 10415 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10416 %{ 10417 match(Set dst (ConvD2I src)); 10418 effect(KILL cr); 10419 10420 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10421 "cmpl $dst, #0x80000000\n\t" 10422 "jne,s done\n\t" 10423 "subq rsp, #8\n\t" 10424 "movsd [rsp], $src\n\t" 10425 "call d2i_fixup\n\t" 10426 "popq $dst\n" 10427 "done: "%} 10428 ins_encode %{ 10429 Label done; 10430 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10431 __ cmpl($dst$$Register, 0x80000000); 10432 __ jccb(Assembler::notEqual, done); 10433 __ subptr(rsp, 8); 10434 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10435 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10436 __ pop($dst$$Register); 10437 __ bind(done); 10438 %} 10439 ins_pipe(pipe_slow); 10440 %} 10441 10442 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10443 %{ 10444 match(Set dst (ConvD2L src)); 10445 effect(KILL cr); 10446 10447 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10448 "cmpq $dst, [0x8000000000000000]\n\t" 10449 "jne,s done\n\t" 10450 "subq rsp, #8\n\t" 10451 "movsd [rsp], $src\n\t" 10452 "call d2l_fixup\n\t" 10453 "popq $dst\n" 10454 "done: "%} 10455 ins_encode %{ 10456 Label done; 10457 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10458 __ cmp64($dst$$Register, 10459 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10460 __ jccb(Assembler::notEqual, done); 10461 __ subptr(rsp, 8); 10462 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10463 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10464 __ pop($dst$$Register); 10465 __ bind(done); 10466 %} 10467 ins_pipe(pipe_slow); 10468 %} 10469 10470 instruct convI2F_reg_reg(regF dst, rRegI src) 10471 %{ 10472 predicate(!UseXmmI2F); 10473 match(Set dst (ConvI2F src)); 10474 10475 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10476 ins_encode %{ 10477 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10478 %} 10479 ins_pipe(pipe_slow); // XXX 10480 %} 10481 10482 instruct convI2F_reg_mem(regF dst, memory src) 10483 %{ 10484 match(Set dst (ConvI2F (LoadI src))); 10485 10486 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10487 ins_encode %{ 10488 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10489 %} 10490 ins_pipe(pipe_slow); // XXX 10491 %} 10492 10493 instruct convI2D_reg_reg(regD dst, rRegI src) 10494 %{ 10495 predicate(!UseXmmI2D); 10496 match(Set dst (ConvI2D src)); 10497 10498 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10499 ins_encode %{ 10500 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10501 %} 10502 ins_pipe(pipe_slow); // XXX 10503 %} 10504 10505 instruct convI2D_reg_mem(regD dst, memory src) 10506 %{ 10507 match(Set dst (ConvI2D (LoadI src))); 10508 10509 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10510 ins_encode %{ 10511 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10512 %} 10513 ins_pipe(pipe_slow); // XXX 10514 %} 10515 10516 instruct convXI2F_reg(regF dst, rRegI src) 10517 %{ 10518 predicate(UseXmmI2F); 10519 match(Set dst (ConvI2F src)); 10520 10521 format %{ "movdl $dst, $src\n\t" 10522 "cvtdq2psl $dst, $dst\t# i2f" %} 10523 ins_encode %{ 10524 __ movdl($dst$$XMMRegister, $src$$Register); 10525 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10526 %} 10527 ins_pipe(pipe_slow); // XXX 10528 %} 10529 10530 instruct convXI2D_reg(regD dst, rRegI src) 10531 %{ 10532 predicate(UseXmmI2D); 10533 match(Set dst (ConvI2D src)); 10534 10535 format %{ "movdl $dst, $src\n\t" 10536 "cvtdq2pdl $dst, $dst\t# i2d" %} 10537 ins_encode %{ 10538 __ movdl($dst$$XMMRegister, $src$$Register); 10539 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10540 %} 10541 ins_pipe(pipe_slow); // XXX 10542 %} 10543 10544 instruct convL2F_reg_reg(regF dst, rRegL src) 10545 %{ 10546 match(Set dst (ConvL2F src)); 10547 10548 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10549 ins_encode %{ 10550 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10551 %} 10552 ins_pipe(pipe_slow); // XXX 10553 %} 10554 10555 instruct convL2F_reg_mem(regF dst, memory src) 10556 %{ 10557 match(Set dst (ConvL2F (LoadL src))); 10558 10559 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10560 ins_encode %{ 10561 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10562 %} 10563 ins_pipe(pipe_slow); // XXX 10564 %} 10565 10566 instruct convL2D_reg_reg(regD dst, rRegL src) 10567 %{ 10568 match(Set dst (ConvL2D src)); 10569 10570 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10571 ins_encode %{ 10572 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10573 %} 10574 ins_pipe(pipe_slow); // XXX 10575 %} 10576 10577 instruct convL2D_reg_mem(regD dst, memory src) 10578 %{ 10579 match(Set dst (ConvL2D (LoadL src))); 10580 10581 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10582 ins_encode %{ 10583 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10584 %} 10585 ins_pipe(pipe_slow); // XXX 10586 %} 10587 10588 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10589 %{ 10590 match(Set dst (ConvI2L src)); 10591 10592 ins_cost(125); 10593 format %{ "movslq $dst, $src\t# i2l" %} 10594 ins_encode %{ 10595 __ movslq($dst$$Register, $src$$Register); 10596 %} 10597 ins_pipe(ialu_reg_reg); 10598 %} 10599 10600 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10601 // %{ 10602 // match(Set dst (ConvI2L src)); 10603 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10604 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10605 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10606 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10607 // ((const TypeNode*) n)->type()->is_long()->_lo == 10608 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10609 10610 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10611 // ins_encode(enc_copy(dst, src)); 10612 // // opcode(0x63); // needs REX.W 10613 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10614 // ins_pipe(ialu_reg_reg); 10615 // %} 10616 10617 // Zero-extend convert int to long 10618 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10619 %{ 10620 match(Set dst (AndL (ConvI2L src) mask)); 10621 10622 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10623 ins_encode %{ 10624 if ($dst$$reg != $src$$reg) { 10625 __ movl($dst$$Register, $src$$Register); 10626 } 10627 %} 10628 ins_pipe(ialu_reg_reg); 10629 %} 10630 10631 // Zero-extend convert int to long 10632 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10633 %{ 10634 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10635 10636 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10637 ins_encode %{ 10638 __ movl($dst$$Register, $src$$Address); 10639 %} 10640 ins_pipe(ialu_reg_mem); 10641 %} 10642 10643 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10644 %{ 10645 match(Set dst (AndL src mask)); 10646 10647 format %{ "movl $dst, $src\t# zero-extend long" %} 10648 ins_encode %{ 10649 __ movl($dst$$Register, $src$$Register); 10650 %} 10651 ins_pipe(ialu_reg_reg); 10652 %} 10653 10654 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10655 %{ 10656 match(Set dst (ConvL2I src)); 10657 10658 format %{ "movl $dst, $src\t# l2i" %} 10659 ins_encode %{ 10660 __ movl($dst$$Register, $src$$Register); 10661 %} 10662 ins_pipe(ialu_reg_reg); 10663 %} 10664 10665 10666 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10667 match(Set dst (MoveF2I src)); 10668 effect(DEF dst, USE src); 10669 10670 ins_cost(125); 10671 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10672 ins_encode %{ 10673 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10674 %} 10675 ins_pipe(ialu_reg_mem); 10676 %} 10677 10678 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10679 match(Set dst (MoveI2F src)); 10680 effect(DEF dst, USE src); 10681 10682 ins_cost(125); 10683 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10684 ins_encode %{ 10685 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10686 %} 10687 ins_pipe(pipe_slow); 10688 %} 10689 10690 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10691 match(Set dst (MoveD2L src)); 10692 effect(DEF dst, USE src); 10693 10694 ins_cost(125); 10695 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10696 ins_encode %{ 10697 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10698 %} 10699 ins_pipe(ialu_reg_mem); 10700 %} 10701 10702 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10703 predicate(!UseXmmLoadAndClearUpper); 10704 match(Set dst (MoveL2D src)); 10705 effect(DEF dst, USE src); 10706 10707 ins_cost(125); 10708 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10709 ins_encode %{ 10710 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10711 %} 10712 ins_pipe(pipe_slow); 10713 %} 10714 10715 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10716 predicate(UseXmmLoadAndClearUpper); 10717 match(Set dst (MoveL2D src)); 10718 effect(DEF dst, USE src); 10719 10720 ins_cost(125); 10721 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10722 ins_encode %{ 10723 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10724 %} 10725 ins_pipe(pipe_slow); 10726 %} 10727 10728 10729 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10730 match(Set dst (MoveF2I src)); 10731 effect(DEF dst, USE src); 10732 10733 ins_cost(95); // XXX 10734 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10735 ins_encode %{ 10736 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10737 %} 10738 ins_pipe(pipe_slow); 10739 %} 10740 10741 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10742 match(Set dst (MoveI2F src)); 10743 effect(DEF dst, USE src); 10744 10745 ins_cost(100); 10746 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10747 ins_encode %{ 10748 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10749 %} 10750 ins_pipe( ialu_mem_reg ); 10751 %} 10752 10753 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10754 match(Set dst (MoveD2L src)); 10755 effect(DEF dst, USE src); 10756 10757 ins_cost(95); // XXX 10758 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10759 ins_encode %{ 10760 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10761 %} 10762 ins_pipe(pipe_slow); 10763 %} 10764 10765 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10766 match(Set dst (MoveL2D src)); 10767 effect(DEF dst, USE src); 10768 10769 ins_cost(100); 10770 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10771 ins_encode %{ 10772 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10773 %} 10774 ins_pipe(ialu_mem_reg); 10775 %} 10776 10777 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10778 match(Set dst (MoveF2I src)); 10779 effect(DEF dst, USE src); 10780 ins_cost(85); 10781 format %{ "movd $dst,$src\t# MoveF2I" %} 10782 ins_encode %{ 10783 __ movdl($dst$$Register, $src$$XMMRegister); 10784 %} 10785 ins_pipe( pipe_slow ); 10786 %} 10787 10788 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10789 match(Set dst (MoveD2L src)); 10790 effect(DEF dst, USE src); 10791 ins_cost(85); 10792 format %{ "movd $dst,$src\t# MoveD2L" %} 10793 ins_encode %{ 10794 __ movdq($dst$$Register, $src$$XMMRegister); 10795 %} 10796 ins_pipe( pipe_slow ); 10797 %} 10798 10799 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10800 match(Set dst (MoveI2F src)); 10801 effect(DEF dst, USE src); 10802 ins_cost(100); 10803 format %{ "movd $dst,$src\t# MoveI2F" %} 10804 ins_encode %{ 10805 __ movdl($dst$$XMMRegister, $src$$Register); 10806 %} 10807 ins_pipe( pipe_slow ); 10808 %} 10809 10810 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10811 match(Set dst (MoveL2D src)); 10812 effect(DEF dst, USE src); 10813 ins_cost(100); 10814 format %{ "movd $dst,$src\t# MoveL2D" %} 10815 ins_encode %{ 10816 __ movdq($dst$$XMMRegister, $src$$Register); 10817 %} 10818 ins_pipe( pipe_slow ); 10819 %} 10820 10821 10822 // ======================================================================= 10823 // fast clearing of an array 10824 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10825 rFlagsReg cr) 10826 %{ 10827 predicate(!((ClearArrayNode*)n)->is_large()); 10828 match(Set dummy (ClearArray cnt base)); 10829 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10830 10831 format %{ $$template 10832 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10833 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10834 $$emit$$"jg LARGE\n\t" 10835 $$emit$$"dec rcx\n\t" 10836 $$emit$$"js DONE\t# Zero length\n\t" 10837 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10838 $$emit$$"dec rcx\n\t" 10839 $$emit$$"jge LOOP\n\t" 10840 $$emit$$"jmp DONE\n\t" 10841 $$emit$$"# LARGE:\n\t" 10842 if (UseFastStosb) { 10843 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10844 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10845 } else { 10846 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10847 } 10848 $$emit$$"# DONE" 10849 %} 10850 ins_encode %{ 10851 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, false); 10852 %} 10853 ins_pipe(pipe_slow); 10854 %} 10855 10856 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10857 rFlagsReg cr) 10858 %{ 10859 predicate(((ClearArrayNode*)n)->is_large()); 10860 match(Set dummy (ClearArray cnt base)); 10861 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10862 10863 format %{ $$template 10864 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10865 if (UseFastStosb) { 10866 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10867 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10868 } else { 10869 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10870 } 10871 %} 10872 ins_encode %{ 10873 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, true); 10874 %} 10875 ins_pipe(pipe_slow); 10876 %} 10877 10878 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10879 rax_RegI result, regD tmp1, rFlagsReg cr) 10880 %{ 10881 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10882 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10883 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10884 10885 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10886 ins_encode %{ 10887 __ string_compare($str1$$Register, $str2$$Register, 10888 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10889 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 10890 %} 10891 ins_pipe( pipe_slow ); 10892 %} 10893 10894 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10895 rax_RegI result, regD tmp1, rFlagsReg cr) 10896 %{ 10897 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10898 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10899 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10900 10901 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10902 ins_encode %{ 10903 __ string_compare($str1$$Register, $str2$$Register, 10904 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10905 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 10906 %} 10907 ins_pipe( pipe_slow ); 10908 %} 10909 10910 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10911 rax_RegI result, regD tmp1, rFlagsReg cr) 10912 %{ 10913 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10914 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10915 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10916 10917 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10918 ins_encode %{ 10919 __ string_compare($str1$$Register, $str2$$Register, 10920 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10921 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 10922 %} 10923 ins_pipe( pipe_slow ); 10924 %} 10925 10926 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10927 rax_RegI result, regD tmp1, rFlagsReg cr) 10928 %{ 10929 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10930 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10931 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10932 10933 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10934 ins_encode %{ 10935 __ string_compare($str2$$Register, $str1$$Register, 10936 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10937 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 10938 %} 10939 ins_pipe( pipe_slow ); 10940 %} 10941 10942 // fast search of substring with known size. 10943 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10944 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10945 %{ 10946 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10947 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10948 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10949 10950 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10951 ins_encode %{ 10952 int icnt2 = (int)$int_cnt2$$constant; 10953 if (icnt2 >= 16) { 10954 // IndexOf for constant substrings with size >= 16 elements 10955 // which don't need to be loaded through stack. 10956 __ string_indexofC8($str1$$Register, $str2$$Register, 10957 $cnt1$$Register, $cnt2$$Register, 10958 icnt2, $result$$Register, 10959 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10960 } else { 10961 // Small strings are loaded through stack if they cross page boundary. 10962 __ string_indexof($str1$$Register, $str2$$Register, 10963 $cnt1$$Register, $cnt2$$Register, 10964 icnt2, $result$$Register, 10965 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10966 } 10967 %} 10968 ins_pipe( pipe_slow ); 10969 %} 10970 10971 // fast search of substring with known size. 10972 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10973 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10974 %{ 10975 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10976 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10977 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10978 10979 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10980 ins_encode %{ 10981 int icnt2 = (int)$int_cnt2$$constant; 10982 if (icnt2 >= 8) { 10983 // IndexOf for constant substrings with size >= 8 elements 10984 // which don't need to be loaded through stack. 10985 __ string_indexofC8($str1$$Register, $str2$$Register, 10986 $cnt1$$Register, $cnt2$$Register, 10987 icnt2, $result$$Register, 10988 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10989 } else { 10990 // Small strings are loaded through stack if they cross page boundary. 10991 __ string_indexof($str1$$Register, $str2$$Register, 10992 $cnt1$$Register, $cnt2$$Register, 10993 icnt2, $result$$Register, 10994 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10995 } 10996 %} 10997 ins_pipe( pipe_slow ); 10998 %} 10999 11000 // fast search of substring with known size. 11001 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11002 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11003 %{ 11004 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11005 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11006 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11007 11008 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11009 ins_encode %{ 11010 int icnt2 = (int)$int_cnt2$$constant; 11011 if (icnt2 >= 8) { 11012 // IndexOf for constant substrings with size >= 8 elements 11013 // which don't need to be loaded through stack. 11014 __ string_indexofC8($str1$$Register, $str2$$Register, 11015 $cnt1$$Register, $cnt2$$Register, 11016 icnt2, $result$$Register, 11017 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11018 } else { 11019 // Small strings are loaded through stack if they cross page boundary. 11020 __ string_indexof($str1$$Register, $str2$$Register, 11021 $cnt1$$Register, $cnt2$$Register, 11022 icnt2, $result$$Register, 11023 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11024 } 11025 %} 11026 ins_pipe( pipe_slow ); 11027 %} 11028 11029 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11030 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11031 %{ 11032 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11033 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11034 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11035 11036 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11037 ins_encode %{ 11038 __ string_indexof($str1$$Register, $str2$$Register, 11039 $cnt1$$Register, $cnt2$$Register, 11040 (-1), $result$$Register, 11041 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11042 %} 11043 ins_pipe( pipe_slow ); 11044 %} 11045 11046 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11047 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11048 %{ 11049 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11050 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11051 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11052 11053 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11054 ins_encode %{ 11055 __ string_indexof($str1$$Register, $str2$$Register, 11056 $cnt1$$Register, $cnt2$$Register, 11057 (-1), $result$$Register, 11058 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11059 %} 11060 ins_pipe( pipe_slow ); 11061 %} 11062 11063 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11064 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11065 %{ 11066 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11067 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11068 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11069 11070 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11071 ins_encode %{ 11072 __ string_indexof($str1$$Register, $str2$$Register, 11073 $cnt1$$Register, $cnt2$$Register, 11074 (-1), $result$$Register, 11075 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11076 %} 11077 ins_pipe( pipe_slow ); 11078 %} 11079 11080 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11081 rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr) 11082 %{ 11083 predicate(UseSSE42Intrinsics); 11084 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11085 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11086 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11087 ins_encode %{ 11088 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11089 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11090 %} 11091 ins_pipe( pipe_slow ); 11092 %} 11093 11094 // fast string equals 11095 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11096 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11097 %{ 11098 match(Set result (StrEquals (Binary str1 str2) cnt)); 11099 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11100 11101 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11102 ins_encode %{ 11103 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11104 $cnt$$Register, $result$$Register, $tmp3$$Register, 11105 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11106 %} 11107 ins_pipe( pipe_slow ); 11108 %} 11109 11110 // fast array equals 11111 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11112 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11113 %{ 11114 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11115 match(Set result (AryEq ary1 ary2)); 11116 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11117 11118 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11119 ins_encode %{ 11120 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11121 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11122 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11123 %} 11124 ins_pipe( pipe_slow ); 11125 %} 11126 11127 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11128 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11129 %{ 11130 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11131 match(Set result (AryEq ary1 ary2)); 11132 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11133 11134 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11135 ins_encode %{ 11136 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11137 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11138 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11139 %} 11140 ins_pipe( pipe_slow ); 11141 %} 11142 11143 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11144 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11145 %{ 11146 match(Set result (HasNegatives ary1 len)); 11147 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11148 11149 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11150 ins_encode %{ 11151 __ has_negatives($ary1$$Register, $len$$Register, 11152 $result$$Register, $tmp3$$Register, 11153 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11154 %} 11155 ins_pipe( pipe_slow ); 11156 %} 11157 11158 // fast char[] to byte[] compression 11159 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11160 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11161 match(Set result (StrCompressedCopy src (Binary dst len))); 11162 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11163 11164 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11165 ins_encode %{ 11166 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11167 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11168 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11169 %} 11170 ins_pipe( pipe_slow ); 11171 %} 11172 11173 // fast byte[] to char[] inflation 11174 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11175 regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11176 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11177 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11178 11179 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11180 ins_encode %{ 11181 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11182 $tmp1$$XMMRegister, $tmp2$$Register); 11183 %} 11184 ins_pipe( pipe_slow ); 11185 %} 11186 11187 // encode char[] to byte[] in ISO_8859_1 11188 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11189 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11190 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11191 match(Set result (EncodeISOArray src (Binary dst len))); 11192 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11193 11194 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11195 ins_encode %{ 11196 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11197 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11198 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11199 %} 11200 ins_pipe( pipe_slow ); 11201 %} 11202 11203 //----------Overflow Math Instructions----------------------------------------- 11204 11205 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11206 %{ 11207 match(Set cr (OverflowAddI op1 op2)); 11208 effect(DEF cr, USE_KILL op1, USE op2); 11209 11210 format %{ "addl $op1, $op2\t# overflow check int" %} 11211 11212 ins_encode %{ 11213 __ addl($op1$$Register, $op2$$Register); 11214 %} 11215 ins_pipe(ialu_reg_reg); 11216 %} 11217 11218 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11219 %{ 11220 match(Set cr (OverflowAddI op1 op2)); 11221 effect(DEF cr, USE_KILL op1, USE op2); 11222 11223 format %{ "addl $op1, $op2\t# overflow check int" %} 11224 11225 ins_encode %{ 11226 __ addl($op1$$Register, $op2$$constant); 11227 %} 11228 ins_pipe(ialu_reg_reg); 11229 %} 11230 11231 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11232 %{ 11233 match(Set cr (OverflowAddL op1 op2)); 11234 effect(DEF cr, USE_KILL op1, USE op2); 11235 11236 format %{ "addq $op1, $op2\t# overflow check long" %} 11237 ins_encode %{ 11238 __ addq($op1$$Register, $op2$$Register); 11239 %} 11240 ins_pipe(ialu_reg_reg); 11241 %} 11242 11243 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11244 %{ 11245 match(Set cr (OverflowAddL op1 op2)); 11246 effect(DEF cr, USE_KILL op1, USE op2); 11247 11248 format %{ "addq $op1, $op2\t# overflow check long" %} 11249 ins_encode %{ 11250 __ addq($op1$$Register, $op2$$constant); 11251 %} 11252 ins_pipe(ialu_reg_reg); 11253 %} 11254 11255 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11256 %{ 11257 match(Set cr (OverflowSubI op1 op2)); 11258 11259 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11260 ins_encode %{ 11261 __ cmpl($op1$$Register, $op2$$Register); 11262 %} 11263 ins_pipe(ialu_reg_reg); 11264 %} 11265 11266 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11267 %{ 11268 match(Set cr (OverflowSubI op1 op2)); 11269 11270 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11271 ins_encode %{ 11272 __ cmpl($op1$$Register, $op2$$constant); 11273 %} 11274 ins_pipe(ialu_reg_reg); 11275 %} 11276 11277 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11278 %{ 11279 match(Set cr (OverflowSubL op1 op2)); 11280 11281 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11282 ins_encode %{ 11283 __ cmpq($op1$$Register, $op2$$Register); 11284 %} 11285 ins_pipe(ialu_reg_reg); 11286 %} 11287 11288 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11289 %{ 11290 match(Set cr (OverflowSubL op1 op2)); 11291 11292 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11293 ins_encode %{ 11294 __ cmpq($op1$$Register, $op2$$constant); 11295 %} 11296 ins_pipe(ialu_reg_reg); 11297 %} 11298 11299 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11300 %{ 11301 match(Set cr (OverflowSubI zero op2)); 11302 effect(DEF cr, USE_KILL op2); 11303 11304 format %{ "negl $op2\t# overflow check int" %} 11305 ins_encode %{ 11306 __ negl($op2$$Register); 11307 %} 11308 ins_pipe(ialu_reg_reg); 11309 %} 11310 11311 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11312 %{ 11313 match(Set cr (OverflowSubL zero op2)); 11314 effect(DEF cr, USE_KILL op2); 11315 11316 format %{ "negq $op2\t# overflow check long" %} 11317 ins_encode %{ 11318 __ negq($op2$$Register); 11319 %} 11320 ins_pipe(ialu_reg_reg); 11321 %} 11322 11323 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11324 %{ 11325 match(Set cr (OverflowMulI op1 op2)); 11326 effect(DEF cr, USE_KILL op1, USE op2); 11327 11328 format %{ "imull $op1, $op2\t# overflow check int" %} 11329 ins_encode %{ 11330 __ imull($op1$$Register, $op2$$Register); 11331 %} 11332 ins_pipe(ialu_reg_reg_alu0); 11333 %} 11334 11335 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11336 %{ 11337 match(Set cr (OverflowMulI op1 op2)); 11338 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11339 11340 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11341 ins_encode %{ 11342 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11343 %} 11344 ins_pipe(ialu_reg_reg_alu0); 11345 %} 11346 11347 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11348 %{ 11349 match(Set cr (OverflowMulL op1 op2)); 11350 effect(DEF cr, USE_KILL op1, USE op2); 11351 11352 format %{ "imulq $op1, $op2\t# overflow check long" %} 11353 ins_encode %{ 11354 __ imulq($op1$$Register, $op2$$Register); 11355 %} 11356 ins_pipe(ialu_reg_reg_alu0); 11357 %} 11358 11359 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11360 %{ 11361 match(Set cr (OverflowMulL op1 op2)); 11362 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11363 11364 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11365 ins_encode %{ 11366 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11367 %} 11368 ins_pipe(ialu_reg_reg_alu0); 11369 %} 11370 11371 11372 //----------Control Flow Instructions------------------------------------------ 11373 // Signed compare Instructions 11374 11375 // XXX more variants!! 11376 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11377 %{ 11378 match(Set cr (CmpI op1 op2)); 11379 effect(DEF cr, USE op1, USE op2); 11380 11381 format %{ "cmpl $op1, $op2" %} 11382 opcode(0x3B); /* Opcode 3B /r */ 11383 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11384 ins_pipe(ialu_cr_reg_reg); 11385 %} 11386 11387 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11388 %{ 11389 match(Set cr (CmpI op1 op2)); 11390 11391 format %{ "cmpl $op1, $op2" %} 11392 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11393 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11394 ins_pipe(ialu_cr_reg_imm); 11395 %} 11396 11397 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11398 %{ 11399 match(Set cr (CmpI op1 (LoadI op2))); 11400 11401 ins_cost(500); // XXX 11402 format %{ "cmpl $op1, $op2" %} 11403 opcode(0x3B); /* Opcode 3B /r */ 11404 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11405 ins_pipe(ialu_cr_reg_mem); 11406 %} 11407 11408 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11409 %{ 11410 match(Set cr (CmpI src zero)); 11411 11412 format %{ "testl $src, $src" %} 11413 opcode(0x85); 11414 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11415 ins_pipe(ialu_cr_reg_imm); 11416 %} 11417 11418 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11419 %{ 11420 match(Set cr (CmpI (AndI src con) zero)); 11421 11422 format %{ "testl $src, $con" %} 11423 opcode(0xF7, 0x00); 11424 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11425 ins_pipe(ialu_cr_reg_imm); 11426 %} 11427 11428 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11429 %{ 11430 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11431 11432 format %{ "testl $src, $mem" %} 11433 opcode(0x85); 11434 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11435 ins_pipe(ialu_cr_reg_mem); 11436 %} 11437 11438 // Unsigned compare Instructions; really, same as signed except they 11439 // produce an rFlagsRegU instead of rFlagsReg. 11440 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11441 %{ 11442 match(Set cr (CmpU op1 op2)); 11443 11444 format %{ "cmpl $op1, $op2\t# unsigned" %} 11445 opcode(0x3B); /* Opcode 3B /r */ 11446 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11447 ins_pipe(ialu_cr_reg_reg); 11448 %} 11449 11450 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11451 %{ 11452 match(Set cr (CmpU op1 op2)); 11453 11454 format %{ "cmpl $op1, $op2\t# unsigned" %} 11455 opcode(0x81,0x07); /* Opcode 81 /7 */ 11456 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11457 ins_pipe(ialu_cr_reg_imm); 11458 %} 11459 11460 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11461 %{ 11462 match(Set cr (CmpU op1 (LoadI op2))); 11463 11464 ins_cost(500); // XXX 11465 format %{ "cmpl $op1, $op2\t# unsigned" %} 11466 opcode(0x3B); /* Opcode 3B /r */ 11467 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11468 ins_pipe(ialu_cr_reg_mem); 11469 %} 11470 11471 // // // Cisc-spilled version of cmpU_rReg 11472 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11473 // //%{ 11474 // // match(Set cr (CmpU (LoadI op1) op2)); 11475 // // 11476 // // format %{ "CMPu $op1,$op2" %} 11477 // // ins_cost(500); 11478 // // opcode(0x39); /* Opcode 39 /r */ 11479 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11480 // //%} 11481 11482 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11483 %{ 11484 match(Set cr (CmpU src zero)); 11485 11486 format %{ "testl $src, $src\t# unsigned" %} 11487 opcode(0x85); 11488 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11489 ins_pipe(ialu_cr_reg_imm); 11490 %} 11491 11492 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11493 %{ 11494 match(Set cr (CmpP op1 op2)); 11495 11496 format %{ "cmpq $op1, $op2\t# ptr" %} 11497 opcode(0x3B); /* Opcode 3B /r */ 11498 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11499 ins_pipe(ialu_cr_reg_reg); 11500 %} 11501 11502 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11503 %{ 11504 match(Set cr (CmpP op1 (LoadP op2))); 11505 11506 ins_cost(500); // XXX 11507 format %{ "cmpq $op1, $op2\t# ptr" %} 11508 opcode(0x3B); /* Opcode 3B /r */ 11509 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11510 ins_pipe(ialu_cr_reg_mem); 11511 %} 11512 11513 // // // Cisc-spilled version of cmpP_rReg 11514 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11515 // //%{ 11516 // // match(Set cr (CmpP (LoadP op1) op2)); 11517 // // 11518 // // format %{ "CMPu $op1,$op2" %} 11519 // // ins_cost(500); 11520 // // opcode(0x39); /* Opcode 39 /r */ 11521 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11522 // //%} 11523 11524 // XXX this is generalized by compP_rReg_mem??? 11525 // Compare raw pointer (used in out-of-heap check). 11526 // Only works because non-oop pointers must be raw pointers 11527 // and raw pointers have no anti-dependencies. 11528 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11529 %{ 11530 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11531 match(Set cr (CmpP op1 (LoadP op2))); 11532 11533 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11534 opcode(0x3B); /* Opcode 3B /r */ 11535 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11536 ins_pipe(ialu_cr_reg_mem); 11537 %} 11538 11539 // This will generate a signed flags result. This should be OK since 11540 // any compare to a zero should be eq/neq. 11541 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11542 %{ 11543 match(Set cr (CmpP src zero)); 11544 11545 format %{ "testq $src, $src\t# ptr" %} 11546 opcode(0x85); 11547 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11548 ins_pipe(ialu_cr_reg_imm); 11549 %} 11550 11551 // This will generate a signed flags result. This should be OK since 11552 // any compare to a zero should be eq/neq. 11553 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11554 %{ 11555 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11556 match(Set cr (CmpP (LoadP op) zero)); 11557 11558 ins_cost(500); // XXX 11559 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11560 opcode(0xF7); /* Opcode F7 /0 */ 11561 ins_encode(REX_mem_wide(op), 11562 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11563 ins_pipe(ialu_cr_reg_imm); 11564 %} 11565 11566 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11567 %{ 11568 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11569 match(Set cr (CmpP (LoadP mem) zero)); 11570 11571 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11572 ins_encode %{ 11573 __ cmpq(r12, $mem$$Address); 11574 %} 11575 ins_pipe(ialu_cr_reg_mem); 11576 %} 11577 11578 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11579 %{ 11580 match(Set cr (CmpN op1 op2)); 11581 11582 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11583 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11584 ins_pipe(ialu_cr_reg_reg); 11585 %} 11586 11587 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11588 %{ 11589 match(Set cr (CmpN src (LoadN mem))); 11590 11591 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11592 ins_encode %{ 11593 __ cmpl($src$$Register, $mem$$Address); 11594 %} 11595 ins_pipe(ialu_cr_reg_mem); 11596 %} 11597 11598 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11599 match(Set cr (CmpN op1 op2)); 11600 11601 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11602 ins_encode %{ 11603 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11604 %} 11605 ins_pipe(ialu_cr_reg_imm); 11606 %} 11607 11608 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11609 %{ 11610 match(Set cr (CmpN src (LoadN mem))); 11611 11612 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11613 ins_encode %{ 11614 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11615 %} 11616 ins_pipe(ialu_cr_reg_mem); 11617 %} 11618 11619 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11620 match(Set cr (CmpN op1 op2)); 11621 11622 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11623 ins_encode %{ 11624 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11625 %} 11626 ins_pipe(ialu_cr_reg_imm); 11627 %} 11628 11629 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11630 %{ 11631 match(Set cr (CmpN src (LoadNKlass mem))); 11632 11633 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11634 ins_encode %{ 11635 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11636 %} 11637 ins_pipe(ialu_cr_reg_mem); 11638 %} 11639 11640 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11641 match(Set cr (CmpN src zero)); 11642 11643 format %{ "testl $src, $src\t# compressed ptr" %} 11644 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11645 ins_pipe(ialu_cr_reg_imm); 11646 %} 11647 11648 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11649 %{ 11650 predicate(Universe::narrow_oop_base() != NULL); 11651 match(Set cr (CmpN (LoadN mem) zero)); 11652 11653 ins_cost(500); // XXX 11654 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11655 ins_encode %{ 11656 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11657 %} 11658 ins_pipe(ialu_cr_reg_mem); 11659 %} 11660 11661 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11662 %{ 11663 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11664 match(Set cr (CmpN (LoadN mem) zero)); 11665 11666 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11667 ins_encode %{ 11668 __ cmpl(r12, $mem$$Address); 11669 %} 11670 ins_pipe(ialu_cr_reg_mem); 11671 %} 11672 11673 // Yanked all unsigned pointer compare operations. 11674 // Pointer compares are done with CmpP which is already unsigned. 11675 11676 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11677 %{ 11678 match(Set cr (CmpL op1 op2)); 11679 11680 format %{ "cmpq $op1, $op2" %} 11681 opcode(0x3B); /* Opcode 3B /r */ 11682 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11683 ins_pipe(ialu_cr_reg_reg); 11684 %} 11685 11686 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11687 %{ 11688 match(Set cr (CmpL op1 op2)); 11689 11690 format %{ "cmpq $op1, $op2" %} 11691 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11692 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11693 ins_pipe(ialu_cr_reg_imm); 11694 %} 11695 11696 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11697 %{ 11698 match(Set cr (CmpL op1 (LoadL op2))); 11699 11700 format %{ "cmpq $op1, $op2" %} 11701 opcode(0x3B); /* Opcode 3B /r */ 11702 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11703 ins_pipe(ialu_cr_reg_mem); 11704 %} 11705 11706 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11707 %{ 11708 match(Set cr (CmpL src zero)); 11709 11710 format %{ "testq $src, $src" %} 11711 opcode(0x85); 11712 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11713 ins_pipe(ialu_cr_reg_imm); 11714 %} 11715 11716 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11717 %{ 11718 match(Set cr (CmpL (AndL src con) zero)); 11719 11720 format %{ "testq $src, $con\t# long" %} 11721 opcode(0xF7, 0x00); 11722 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11723 ins_pipe(ialu_cr_reg_imm); 11724 %} 11725 11726 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11727 %{ 11728 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11729 11730 format %{ "testq $src, $mem" %} 11731 opcode(0x85); 11732 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11733 ins_pipe(ialu_cr_reg_mem); 11734 %} 11735 11736 instruct testL_reg_reg(rFlagsReg cr, rRegP src, r12_RegL other, immL0 zero) 11737 %{ 11738 match(Set cr (CmpL (AndL (CastP2X src) other) zero)); 11739 ins_cost(50); 11740 11741 format %{ "testq $src, $other\t# long" %} 11742 ins_encode %{ 11743 __ testq($src$$Register, $other$$Register); 11744 %} 11745 ins_pipe(ialu_cr_reg_imm); 11746 %} 11747 11748 instruct testL_reg_mem3(rFlagsReg cr, rRegP src, immP addr, immL0 zero) 11749 %{ 11750 predicate(!is_far(_kids[0]->_kids[1]->_kids[0]->_leaf->bottom_type()->is_rawptr()->get_con())); 11751 match(Set cr (CmpL (AndL (CastP2X src) (LoadL addr)) zero)); 11752 11753 format %{ "testq $src, [$addr]" %} 11754 ins_encode %{ 11755 __ testq($src$$Register, AddressLiteral((address)$addr$$constant, relocInfo::external_word_type)); 11756 %} 11757 11758 ins_pipe(ialu_cr_reg_mem); 11759 %} 11760 11761 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11762 %{ 11763 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11764 11765 format %{ "testq $src, $mem" %} 11766 opcode(0x85); 11767 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11768 ins_pipe(ialu_cr_reg_mem); 11769 %} 11770 11771 // Manifest a CmpL result in an integer register. Very painful. 11772 // This is the test to avoid. 11773 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11774 %{ 11775 match(Set dst (CmpL3 src1 src2)); 11776 effect(KILL flags); 11777 11778 ins_cost(275); // XXX 11779 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11780 "movl $dst, -1\n\t" 11781 "jl,s done\n\t" 11782 "setne $dst\n\t" 11783 "movzbl $dst, $dst\n\t" 11784 "done:" %} 11785 ins_encode(cmpl3_flag(src1, src2, dst)); 11786 ins_pipe(pipe_slow); 11787 %} 11788 11789 // Unsigned long compare Instructions; really, same as signed long except they 11790 // produce an rFlagsRegU instead of rFlagsReg. 11791 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11792 %{ 11793 match(Set cr (CmpUL op1 op2)); 11794 11795 format %{ "cmpq $op1, $op2\t# unsigned" %} 11796 opcode(0x3B); /* Opcode 3B /r */ 11797 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11798 ins_pipe(ialu_cr_reg_reg); 11799 %} 11800 11801 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11802 %{ 11803 match(Set cr (CmpUL op1 op2)); 11804 11805 format %{ "cmpq $op1, $op2\t# unsigned" %} 11806 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11807 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11808 ins_pipe(ialu_cr_reg_imm); 11809 %} 11810 11811 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11812 %{ 11813 match(Set cr (CmpUL op1 (LoadL op2))); 11814 11815 format %{ "cmpq $op1, $op2\t# unsigned" %} 11816 opcode(0x3B); /* Opcode 3B /r */ 11817 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11818 ins_pipe(ialu_cr_reg_mem); 11819 %} 11820 11821 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11822 %{ 11823 match(Set cr (CmpUL src zero)); 11824 11825 format %{ "testq $src, $src\t# unsigned" %} 11826 opcode(0x85); 11827 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11828 ins_pipe(ialu_cr_reg_imm); 11829 %} 11830 11831 //----------Max and Min-------------------------------------------------------- 11832 // Min Instructions 11833 11834 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11835 %{ 11836 effect(USE_DEF dst, USE src, USE cr); 11837 11838 format %{ "cmovlgt $dst, $src\t# min" %} 11839 opcode(0x0F, 0x4F); 11840 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11841 ins_pipe(pipe_cmov_reg); 11842 %} 11843 11844 11845 instruct minI_rReg(rRegI dst, rRegI src) 11846 %{ 11847 match(Set dst (MinI dst src)); 11848 11849 ins_cost(200); 11850 expand %{ 11851 rFlagsReg cr; 11852 compI_rReg(cr, dst, src); 11853 cmovI_reg_g(dst, src, cr); 11854 %} 11855 %} 11856 11857 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11858 %{ 11859 effect(USE_DEF dst, USE src, USE cr); 11860 11861 format %{ "cmovllt $dst, $src\t# max" %} 11862 opcode(0x0F, 0x4C); 11863 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11864 ins_pipe(pipe_cmov_reg); 11865 %} 11866 11867 11868 instruct maxI_rReg(rRegI dst, rRegI src) 11869 %{ 11870 match(Set dst (MaxI dst src)); 11871 11872 ins_cost(200); 11873 expand %{ 11874 rFlagsReg cr; 11875 compI_rReg(cr, dst, src); 11876 cmovI_reg_l(dst, src, cr); 11877 %} 11878 %} 11879 11880 // ============================================================================ 11881 // Branch Instructions 11882 11883 // Jump Direct - Label defines a relative address from JMP+1 11884 instruct jmpDir(label labl) 11885 %{ 11886 match(Goto); 11887 effect(USE labl); 11888 11889 ins_cost(300); 11890 format %{ "jmp $labl" %} 11891 size(5); 11892 ins_encode %{ 11893 Label* L = $labl$$label; 11894 __ jmp(*L, false); // Always long jump 11895 %} 11896 ins_pipe(pipe_jmp); 11897 %} 11898 11899 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11900 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11901 %{ 11902 match(If cop cr); 11903 effect(USE labl); 11904 11905 ins_cost(300); 11906 format %{ "j$cop $labl" %} 11907 size(6); 11908 ins_encode %{ 11909 Label* L = $labl$$label; 11910 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11911 %} 11912 ins_pipe(pipe_jcc); 11913 %} 11914 11915 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11916 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11917 %{ 11918 predicate(!n->has_vector_mask_set()); 11919 match(CountedLoopEnd cop cr); 11920 effect(USE labl); 11921 11922 ins_cost(300); 11923 format %{ "j$cop $labl\t# loop end" %} 11924 size(6); 11925 ins_encode %{ 11926 Label* L = $labl$$label; 11927 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11928 %} 11929 ins_pipe(pipe_jcc); 11930 %} 11931 11932 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11933 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11934 predicate(!n->has_vector_mask_set()); 11935 match(CountedLoopEnd cop cmp); 11936 effect(USE labl); 11937 11938 ins_cost(300); 11939 format %{ "j$cop,u $labl\t# loop end" %} 11940 size(6); 11941 ins_encode %{ 11942 Label* L = $labl$$label; 11943 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11944 %} 11945 ins_pipe(pipe_jcc); 11946 %} 11947 11948 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11949 predicate(!n->has_vector_mask_set()); 11950 match(CountedLoopEnd cop cmp); 11951 effect(USE labl); 11952 11953 ins_cost(200); 11954 format %{ "j$cop,u $labl\t# loop end" %} 11955 size(6); 11956 ins_encode %{ 11957 Label* L = $labl$$label; 11958 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11959 %} 11960 ins_pipe(pipe_jcc); 11961 %} 11962 11963 // mask version 11964 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11965 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 11966 %{ 11967 predicate(n->has_vector_mask_set()); 11968 match(CountedLoopEnd cop cr); 11969 effect(USE labl); 11970 11971 ins_cost(400); 11972 format %{ "j$cop $labl\t# loop end\n\t" 11973 "restorevectmask \t# vector mask restore for loops" %} 11974 size(10); 11975 ins_encode %{ 11976 Label* L = $labl$$label; 11977 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11978 __ restorevectmask(); 11979 %} 11980 ins_pipe(pipe_jcc); 11981 %} 11982 11983 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11984 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11985 predicate(n->has_vector_mask_set()); 11986 match(CountedLoopEnd cop cmp); 11987 effect(USE labl); 11988 11989 ins_cost(400); 11990 format %{ "j$cop,u $labl\t# loop end\n\t" 11991 "restorevectmask \t# vector mask restore for loops" %} 11992 size(10); 11993 ins_encode %{ 11994 Label* L = $labl$$label; 11995 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11996 __ restorevectmask(); 11997 %} 11998 ins_pipe(pipe_jcc); 11999 %} 12000 12001 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12002 predicate(n->has_vector_mask_set()); 12003 match(CountedLoopEnd cop cmp); 12004 effect(USE labl); 12005 12006 ins_cost(300); 12007 format %{ "j$cop,u $labl\t# loop end\n\t" 12008 "restorevectmask \t# vector mask restore for loops" %} 12009 size(10); 12010 ins_encode %{ 12011 Label* L = $labl$$label; 12012 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12013 __ restorevectmask(); 12014 %} 12015 ins_pipe(pipe_jcc); 12016 %} 12017 12018 // Jump Direct Conditional - using unsigned comparison 12019 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12020 match(If cop cmp); 12021 effect(USE labl); 12022 12023 ins_cost(300); 12024 format %{ "j$cop,u $labl" %} 12025 size(6); 12026 ins_encode %{ 12027 Label* L = $labl$$label; 12028 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12029 %} 12030 ins_pipe(pipe_jcc); 12031 %} 12032 12033 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12034 match(If cop cmp); 12035 effect(USE labl); 12036 12037 ins_cost(200); 12038 format %{ "j$cop,u $labl" %} 12039 size(6); 12040 ins_encode %{ 12041 Label* L = $labl$$label; 12042 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12043 %} 12044 ins_pipe(pipe_jcc); 12045 %} 12046 12047 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12048 match(If cop cmp); 12049 effect(USE labl); 12050 12051 ins_cost(200); 12052 format %{ $$template 12053 if ($cop$$cmpcode == Assembler::notEqual) { 12054 $$emit$$"jp,u $labl\n\t" 12055 $$emit$$"j$cop,u $labl" 12056 } else { 12057 $$emit$$"jp,u done\n\t" 12058 $$emit$$"j$cop,u $labl\n\t" 12059 $$emit$$"done:" 12060 } 12061 %} 12062 ins_encode %{ 12063 Label* l = $labl$$label; 12064 if ($cop$$cmpcode == Assembler::notEqual) { 12065 __ jcc(Assembler::parity, *l, false); 12066 __ jcc(Assembler::notEqual, *l, false); 12067 } else if ($cop$$cmpcode == Assembler::equal) { 12068 Label done; 12069 __ jccb(Assembler::parity, done); 12070 __ jcc(Assembler::equal, *l, false); 12071 __ bind(done); 12072 } else { 12073 ShouldNotReachHere(); 12074 } 12075 %} 12076 ins_pipe(pipe_jcc); 12077 %} 12078 12079 // ============================================================================ 12080 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12081 // superklass array for an instance of the superklass. Set a hidden 12082 // internal cache on a hit (cache is checked with exposed code in 12083 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12084 // encoding ALSO sets flags. 12085 12086 instruct partialSubtypeCheck(rdi_RegP result, 12087 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12088 rFlagsReg cr) 12089 %{ 12090 match(Set result (PartialSubtypeCheck sub super)); 12091 effect(KILL rcx, KILL cr); 12092 12093 ins_cost(1100); // slightly larger than the next version 12094 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12095 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12096 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12097 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12098 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12099 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12100 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12101 "miss:\t" %} 12102 12103 opcode(0x1); // Force a XOR of RDI 12104 ins_encode(enc_PartialSubtypeCheck()); 12105 ins_pipe(pipe_slow); 12106 %} 12107 12108 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12109 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12110 immP0 zero, 12111 rdi_RegP result) 12112 %{ 12113 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12114 effect(KILL rcx, KILL result); 12115 12116 ins_cost(1000); 12117 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12118 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12119 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12120 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12121 "jne,s miss\t\t# Missed: flags nz\n\t" 12122 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12123 "miss:\t" %} 12124 12125 opcode(0x0); // No need to XOR RDI 12126 ins_encode(enc_PartialSubtypeCheck()); 12127 ins_pipe(pipe_slow); 12128 %} 12129 12130 // ============================================================================ 12131 // Branch Instructions -- short offset versions 12132 // 12133 // These instructions are used to replace jumps of a long offset (the default 12134 // match) with jumps of a shorter offset. These instructions are all tagged 12135 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12136 // match rules in general matching. Instead, the ADLC generates a conversion 12137 // method in the MachNode which can be used to do in-place replacement of the 12138 // long variant with the shorter variant. The compiler will determine if a 12139 // branch can be taken by the is_short_branch_offset() predicate in the machine 12140 // specific code section of the file. 12141 12142 // Jump Direct - Label defines a relative address from JMP+1 12143 instruct jmpDir_short(label labl) %{ 12144 match(Goto); 12145 effect(USE labl); 12146 12147 ins_cost(300); 12148 format %{ "jmp,s $labl" %} 12149 size(2); 12150 ins_encode %{ 12151 Label* L = $labl$$label; 12152 __ jmpb(*L); 12153 %} 12154 ins_pipe(pipe_jmp); 12155 ins_short_branch(1); 12156 %} 12157 12158 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12159 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12160 match(If cop cr); 12161 effect(USE labl); 12162 12163 ins_cost(300); 12164 format %{ "j$cop,s $labl" %} 12165 size(2); 12166 ins_encode %{ 12167 Label* L = $labl$$label; 12168 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12169 %} 12170 ins_pipe(pipe_jcc); 12171 ins_short_branch(1); 12172 %} 12173 12174 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12175 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12176 match(CountedLoopEnd cop cr); 12177 effect(USE labl); 12178 12179 ins_cost(300); 12180 format %{ "j$cop,s $labl\t# loop end" %} 12181 size(2); 12182 ins_encode %{ 12183 Label* L = $labl$$label; 12184 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12185 %} 12186 ins_pipe(pipe_jcc); 12187 ins_short_branch(1); 12188 %} 12189 12190 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12191 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12192 match(CountedLoopEnd cop cmp); 12193 effect(USE labl); 12194 12195 ins_cost(300); 12196 format %{ "j$cop,us $labl\t# loop end" %} 12197 size(2); 12198 ins_encode %{ 12199 Label* L = $labl$$label; 12200 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12201 %} 12202 ins_pipe(pipe_jcc); 12203 ins_short_branch(1); 12204 %} 12205 12206 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12207 match(CountedLoopEnd cop cmp); 12208 effect(USE labl); 12209 12210 ins_cost(300); 12211 format %{ "j$cop,us $labl\t# loop end" %} 12212 size(2); 12213 ins_encode %{ 12214 Label* L = $labl$$label; 12215 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12216 %} 12217 ins_pipe(pipe_jcc); 12218 ins_short_branch(1); 12219 %} 12220 12221 // Jump Direct Conditional - using unsigned comparison 12222 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12223 match(If cop cmp); 12224 effect(USE labl); 12225 12226 ins_cost(300); 12227 format %{ "j$cop,us $labl" %} 12228 size(2); 12229 ins_encode %{ 12230 Label* L = $labl$$label; 12231 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12232 %} 12233 ins_pipe(pipe_jcc); 12234 ins_short_branch(1); 12235 %} 12236 12237 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12238 match(If cop cmp); 12239 effect(USE labl); 12240 12241 ins_cost(300); 12242 format %{ "j$cop,us $labl" %} 12243 size(2); 12244 ins_encode %{ 12245 Label* L = $labl$$label; 12246 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12247 %} 12248 ins_pipe(pipe_jcc); 12249 ins_short_branch(1); 12250 %} 12251 12252 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12253 match(If cop cmp); 12254 effect(USE labl); 12255 12256 ins_cost(300); 12257 format %{ $$template 12258 if ($cop$$cmpcode == Assembler::notEqual) { 12259 $$emit$$"jp,u,s $labl\n\t" 12260 $$emit$$"j$cop,u,s $labl" 12261 } else { 12262 $$emit$$"jp,u,s done\n\t" 12263 $$emit$$"j$cop,u,s $labl\n\t" 12264 $$emit$$"done:" 12265 } 12266 %} 12267 size(4); 12268 ins_encode %{ 12269 Label* l = $labl$$label; 12270 if ($cop$$cmpcode == Assembler::notEqual) { 12271 __ jccb(Assembler::parity, *l); 12272 __ jccb(Assembler::notEqual, *l); 12273 } else if ($cop$$cmpcode == Assembler::equal) { 12274 Label done; 12275 __ jccb(Assembler::parity, done); 12276 __ jccb(Assembler::equal, *l); 12277 __ bind(done); 12278 } else { 12279 ShouldNotReachHere(); 12280 } 12281 %} 12282 ins_pipe(pipe_jcc); 12283 ins_short_branch(1); 12284 %} 12285 12286 // ============================================================================ 12287 // inlined locking and unlocking 12288 12289 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12290 predicate(Compile::current()->use_rtm()); 12291 match(Set cr (FastLock object box)); 12292 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12293 ins_cost(300); 12294 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12295 ins_encode %{ 12296 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12297 $scr$$Register, $cx1$$Register, $cx2$$Register, 12298 _counters, _rtm_counters, _stack_rtm_counters, 12299 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12300 true, ra_->C->profile_rtm()); 12301 %} 12302 ins_pipe(pipe_slow); 12303 %} 12304 12305 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12306 predicate(!Compile::current()->use_rtm()); 12307 match(Set cr (FastLock object box)); 12308 effect(TEMP tmp, TEMP scr, USE_KILL box); 12309 ins_cost(300); 12310 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12311 ins_encode %{ 12312 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12313 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12314 %} 12315 ins_pipe(pipe_slow); 12316 %} 12317 12318 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12319 match(Set cr (FastUnlock object box)); 12320 effect(TEMP tmp, USE_KILL box); 12321 ins_cost(300); 12322 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12323 ins_encode %{ 12324 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12325 %} 12326 ins_pipe(pipe_slow); 12327 %} 12328 12329 12330 // ============================================================================ 12331 // Safepoint Instructions 12332 instruct safePoint_poll(rFlagsReg cr) 12333 %{ 12334 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12335 match(SafePoint); 12336 effect(KILL cr); 12337 12338 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12339 "# Safepoint: poll for GC" %} 12340 ins_cost(125); 12341 ins_encode %{ 12342 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12343 __ testl(rax, addr); 12344 %} 12345 ins_pipe(ialu_reg_mem); 12346 %} 12347 12348 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12349 %{ 12350 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12351 match(SafePoint poll); 12352 effect(KILL cr, USE poll); 12353 12354 format %{ "testl rax, [$poll]\t" 12355 "# Safepoint: poll for GC" %} 12356 ins_cost(125); 12357 ins_encode %{ 12358 __ relocate(relocInfo::poll_type); 12359 __ testl(rax, Address($poll$$Register, 0)); 12360 %} 12361 ins_pipe(ialu_reg_mem); 12362 %} 12363 12364 instruct safePoint_poll_tls(rFlagsReg cr, rex_RegP poll) 12365 %{ 12366 predicate(SafepointMechanism::uses_thread_local_poll()); 12367 match(SafePoint poll); 12368 effect(KILL cr, USE poll); 12369 12370 format %{ "testl rax, [$poll]\t" 12371 "# Safepoint: poll for GC" %} 12372 ins_cost(125); 12373 size(3); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12374 ins_encode %{ 12375 __ relocate(relocInfo::poll_type); 12376 address pre_pc = __ pc(); 12377 __ testl(rax, Address($poll$$Register, 0)); 12378 address post_pc = __ pc(); 12379 guarantee(pre_pc[0] == 0x41 && pre_pc[1] == 0x85, "must emit #rex test-ax [reg]"); 12380 %} 12381 ins_pipe(ialu_reg_mem); 12382 %} 12383 12384 // ============================================================================ 12385 // Procedure Call/Return Instructions 12386 // Call Java Static Instruction 12387 // Note: If this code changes, the corresponding ret_addr_offset() and 12388 // compute_padding() functions will have to be adjusted. 12389 instruct CallStaticJavaDirect(method meth) %{ 12390 match(CallStaticJava); 12391 effect(USE meth); 12392 12393 ins_cost(300); 12394 format %{ "call,static " %} 12395 opcode(0xE8); /* E8 cd */ 12396 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12397 ins_pipe(pipe_slow); 12398 ins_alignment(4); 12399 %} 12400 12401 // Call Java Dynamic Instruction 12402 // Note: If this code changes, the corresponding ret_addr_offset() and 12403 // compute_padding() functions will have to be adjusted. 12404 instruct CallDynamicJavaDirect(method meth) 12405 %{ 12406 match(CallDynamicJava); 12407 effect(USE meth); 12408 12409 ins_cost(300); 12410 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12411 "call,dynamic " %} 12412 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12413 ins_pipe(pipe_slow); 12414 ins_alignment(4); 12415 %} 12416 12417 // Call Runtime Instruction 12418 instruct CallRuntimeDirect(method meth) 12419 %{ 12420 match(CallRuntime); 12421 effect(USE meth); 12422 12423 ins_cost(300); 12424 format %{ "call,runtime " %} 12425 ins_encode(clear_avx, Java_To_Runtime(meth)); 12426 ins_pipe(pipe_slow); 12427 %} 12428 12429 // Call runtime without safepoint 12430 instruct CallLeafDirect(method meth) 12431 %{ 12432 match(CallLeaf); 12433 effect(USE meth); 12434 12435 ins_cost(300); 12436 format %{ "call_leaf,runtime " %} 12437 ins_encode(clear_avx, Java_To_Runtime(meth)); 12438 ins_pipe(pipe_slow); 12439 %} 12440 12441 // Call runtime without safepoint 12442 instruct CallLeafNoFPDirect(method meth) 12443 %{ 12444 match(CallLeafNoFP); 12445 effect(USE meth); 12446 12447 ins_cost(300); 12448 format %{ "call_leaf_nofp,runtime " %} 12449 ins_encode(clear_avx, Java_To_Runtime(meth)); 12450 ins_pipe(pipe_slow); 12451 %} 12452 12453 // Return Instruction 12454 // Remove the return address & jump to it. 12455 // Notice: We always emit a nop after a ret to make sure there is room 12456 // for safepoint patching 12457 instruct Ret() 12458 %{ 12459 match(Return); 12460 12461 format %{ "ret" %} 12462 opcode(0xC3); 12463 ins_encode(OpcP); 12464 ins_pipe(pipe_jmp); 12465 %} 12466 12467 // Tail Call; Jump from runtime stub to Java code. 12468 // Also known as an 'interprocedural jump'. 12469 // Target of jump will eventually return to caller. 12470 // TailJump below removes the return address. 12471 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12472 %{ 12473 match(TailCall jump_target method_oop); 12474 12475 ins_cost(300); 12476 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12477 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12478 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12479 ins_pipe(pipe_jmp); 12480 %} 12481 12482 // Tail Jump; remove the return address; jump to target. 12483 // TailCall above leaves the return address around. 12484 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12485 %{ 12486 match(TailJump jump_target ex_oop); 12487 12488 ins_cost(300); 12489 format %{ "popq rdx\t# pop return address\n\t" 12490 "jmp $jump_target" %} 12491 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12492 ins_encode(Opcode(0x5a), // popq rdx 12493 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12494 ins_pipe(pipe_jmp); 12495 %} 12496 12497 // Create exception oop: created by stack-crawling runtime code. 12498 // Created exception is now available to this handler, and is setup 12499 // just prior to jumping to this handler. No code emitted. 12500 instruct CreateException(rax_RegP ex_oop) 12501 %{ 12502 match(Set ex_oop (CreateEx)); 12503 12504 size(0); 12505 // use the following format syntax 12506 format %{ "# exception oop is in rax; no code emitted" %} 12507 ins_encode(); 12508 ins_pipe(empty); 12509 %} 12510 12511 // Rethrow exception: 12512 // The exception oop will come in the first argument position. 12513 // Then JUMP (not call) to the rethrow stub code. 12514 instruct RethrowException() 12515 %{ 12516 match(Rethrow); 12517 12518 // use the following format syntax 12519 format %{ "jmp rethrow_stub" %} 12520 ins_encode(enc_rethrow); 12521 ins_pipe(pipe_jmp); 12522 %} 12523 12524 // Execute GC load barrier (strong) slow path 12525 12526 // When running without XMM regs 12527 12528 instruct loadBarrierSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12529 12530 match(Set dst (LoadBarrierSlowReg mem)); 12531 predicate(MaxVectorSize < 16); 12532 12533 effect(DEF dst, KILL cr); 12534 12535 format %{"LoadBarrierSlowRegNoVec $dst,$mem" %} 12536 ins_encode %{ 12537 Register d = $dst$$Register; 12538 12539 assert( d != r12, "Can't be R12!"); 12540 assert( d != r15, "Can't be R15!"); 12541 assert( d != rsp, "Can't be RSP!"); 12542 __ lea(d,$mem$$Address); 12543 __ call(RuntimeAddress(StubRoutines::x86::load_barrier_slow_stub(d))); 12544 %} 12545 ins_pipe(pipe_slow); 12546 %} 12547 12548 // For XMM and YMM enabled processors 12549 12550 instruct loadBarrierSlowRegXmm(rRegP dst, memory mem, rFlagsReg cr, 12551 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12552 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15 12553 ) %{ 12554 12555 match(Set dst (LoadBarrierSlowReg mem)); 12556 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12557 12558 effect(DEF dst, KILL cr, 12559 KILL x0, KILL x1, KILL x2, KILL x3, KILL x4, KILL x5, KILL x6, KILL x7, 12560 KILL x8, KILL x9, KILL x10, KILL x11, KILL x12, KILL x13, KILL x14, KILL x15 12561 ); 12562 12563 format %{"LoadBarrierSlowRegXmm $dst,$mem" %} 12564 ins_encode %{ 12565 Register d = $dst$$Register; 12566 12567 assert( d != r12, "Can't be R12!"); 12568 assert( d != r15, "Can't be R15!"); 12569 assert( d != rsp, "Can't be RSP!"); 12570 __ lea(d,$mem$$Address); 12571 __ call(RuntimeAddress(StubRoutines::x86::load_barrier_slow_stub(d))); 12572 %} 12573 ins_pipe(pipe_slow); 12574 %} 12575 12576 // For ZMM enabled processors 12577 12578 instruct loadBarrierSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12579 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12580 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12581 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12582 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31 12583 ) %{ 12584 12585 match(Set dst (LoadBarrierSlowReg mem)); 12586 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12587 12588 effect(DEF dst, KILL cr, 12589 KILL x0, KILL x1, KILL x2, KILL x3, KILL x4, KILL x5, KILL x6, KILL x7, 12590 KILL x8, KILL x9, KILL x10, KILL x11, KILL x12, KILL x13, KILL x14, KILL x15, 12591 KILL x16, KILL x17, KILL x18, KILL x19, KILL x20, KILL x21, KILL x22, KILL x23, 12592 KILL x24, KILL x25, KILL x26, KILL x27, KILL x28, KILL x29, KILL x30, KILL x31 12593 ); 12594 12595 format %{"LoadBarrierSlowRegZmm $dst,$mem" %} 12596 ins_encode %{ 12597 Register d = $dst$$Register; 12598 12599 assert( d != r12, "Can't be R12!"); 12600 assert( d != r15, "Can't be R15!"); 12601 assert( d != rsp, "Can't be RSP!"); 12602 __ lea(d,$mem$$Address); 12603 __ call(RuntimeAddress(StubRoutines::x86::load_barrier_slow_stub(d))); 12604 %} 12605 ins_pipe(pipe_slow); 12606 %} 12607 12608 // Execute GC load barrier weak slow path 12609 12610 // When running without XMM regs 12611 12612 instruct loadBarrierWeakSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12613 12614 match(Set dst (LoadBarrierSlowReg mem)); 12615 predicate(MaxVectorSize < 16); 12616 12617 effect(DEF dst, KILL cr); 12618 12619 format %{"LoadBarrierSlowRegNoVec $dst,$mem" %} 12620 ins_encode %{ 12621 Register d = $dst$$Register; 12622 12623 assert( d != r12, "Can't be R12!"); 12624 assert( d != r15, "Can't be R15!"); 12625 assert( d != rsp, "Can't be RSP!"); 12626 __ lea(d,$mem$$Address); 12627 __ call(RuntimeAddress(StubRoutines::x86::load_barrier_weak_slow_stub(d))); 12628 %} 12629 ins_pipe(pipe_slow); 12630 %} 12631 12632 // For XMM and YMM enabled processors 12633 12634 instruct loadBarrierWeakSlowRegXmm(rRegP dst, memory mem, rFlagsReg cr, 12635 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12636 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15 12637 ) %{ 12638 12639 match(Set dst (LoadBarrierWeakSlowReg mem)); 12640 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12641 12642 effect(DEF dst, KILL cr, 12643 KILL x0, KILL x1, KILL x2, KILL x3, KILL x4, KILL x5, KILL x6, KILL x7, 12644 KILL x8, KILL x9, KILL x10, KILL x11, KILL x12, KILL x13, KILL x14, KILL x15 12645 ); 12646 12647 format %{"LoadBarrierWeakSlowRegXmm $dst,$mem" %} 12648 ins_encode %{ 12649 Register d = $dst$$Register; 12650 12651 assert( d != r12, "Can't be R12!"); 12652 assert( d != r15, "Can't be R15!"); 12653 assert( d != rsp, "Can't be RSP!"); 12654 __ lea(d,$mem$$Address); 12655 __ call(RuntimeAddress(StubRoutines::x86::load_barrier_weak_slow_stub(d))); 12656 %} 12657 ins_pipe(pipe_slow); 12658 %} 12659 12660 // For ZMM enabled processors 12661 12662 instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12663 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12664 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12665 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12666 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31 12667 ) %{ 12668 12669 match(Set dst (LoadBarrierWeakSlowReg mem)); 12670 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12671 12672 effect(DEF dst, KILL cr, 12673 KILL x0, KILL x1, KILL x2, KILL x3, KILL x4, KILL x5, KILL x6, KILL x7, 12674 KILL x8, KILL x9, KILL x10, KILL x11, KILL x12, KILL x13, KILL x14, KILL x15, 12675 KILL x16, KILL x17, KILL x18, KILL x19, KILL x20, KILL x21, KILL x22, KILL x23, 12676 KILL x24, KILL x25, KILL x26, KILL x27, KILL x28, KILL x29, KILL x30, KILL x31 12677 ); 12678 12679 format %{"LoadBarrierWeakSlowRegZmm $dst,$mem" %} 12680 ins_encode %{ 12681 Register d = $dst$$Register; 12682 12683 assert( d != r12, "Can't be R12!"); 12684 assert( d != r15, "Can't be R15!"); 12685 assert( d != rsp, "Can't be RSP!"); 12686 __ lea(d,$mem$$Address); 12687 __ call(RuntimeAddress(StubRoutines::x86::load_barrier_weak_slow_stub(d))); 12688 %} 12689 ins_pipe(pipe_slow); 12690 %} 12691 12692 // ============================================================================ 12693 // This name is KNOWN by the ADLC and cannot be changed. 12694 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12695 // for this guy. 12696 instruct tlsLoadP(r15_RegP dst) %{ 12697 match(Set dst (ThreadLocal)); 12698 effect(DEF dst); 12699 12700 size(0); 12701 format %{ "# TLS is in R15" %} 12702 ins_encode( /*empty encoding*/ ); 12703 ins_pipe(ialu_reg_reg); 12704 %} 12705 12706 instruct addr_bad_bit(r12_RegL dst) %{ 12707 match(Set dst (AddrBadBit)); 12708 effect(DEF dst); 12709 12710 size(0); 12711 ins_cost(0); 12712 format %{ "# addr_bad_bit in r12" %} 12713 ins_encode( /*empty encoding*/ ); 12714 ins_pipe(ialu_reg_reg); 12715 %} 12716 12717 12718 //----------PEEPHOLE RULES----------------------------------------------------- 12719 // These must follow all instruction definitions as they use the names 12720 // defined in the instructions definitions. 12721 // 12722 // peepmatch ( root_instr_name [preceding_instruction]* ); 12723 // 12724 // peepconstraint %{ 12725 // (instruction_number.operand_name relational_op instruction_number.operand_name 12726 // [, ...] ); 12727 // // instruction numbers are zero-based using left to right order in peepmatch 12728 // 12729 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12730 // // provide an instruction_number.operand_name for each operand that appears 12731 // // in the replacement instruction's match rule 12732 // 12733 // ---------VM FLAGS--------------------------------------------------------- 12734 // 12735 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12736 // 12737 // Each peephole rule is given an identifying number starting with zero and 12738 // increasing by one in the order seen by the parser. An individual peephole 12739 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12740 // on the command-line. 12741 // 12742 // ---------CURRENT LIMITATIONS---------------------------------------------- 12743 // 12744 // Only match adjacent instructions in same basic block 12745 // Only equality constraints 12746 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12747 // Only one replacement instruction 12748 // 12749 // ---------EXAMPLE---------------------------------------------------------- 12750 // 12751 // // pertinent parts of existing instructions in architecture description 12752 // instruct movI(rRegI dst, rRegI src) 12753 // %{ 12754 // match(Set dst (CopyI src)); 12755 // %} 12756 // 12757 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12758 // %{ 12759 // match(Set dst (AddI dst src)); 12760 // effect(KILL cr); 12761 // %} 12762 // 12763 // // Change (inc mov) to lea 12764 // peephole %{ 12765 // // increment preceeded by register-register move 12766 // peepmatch ( incI_rReg movI ); 12767 // // require that the destination register of the increment 12768 // // match the destination register of the move 12769 // peepconstraint ( 0.dst == 1.dst ); 12770 // // construct a replacement instruction that sets 12771 // // the destination to ( move's source register + one ) 12772 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12773 // %} 12774 // 12775 12776 // Implementation no longer uses movX instructions since 12777 // machine-independent system no longer uses CopyX nodes. 12778 // 12779 // peephole 12780 // %{ 12781 // peepmatch (incI_rReg movI); 12782 // peepconstraint (0.dst == 1.dst); 12783 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12784 // %} 12785 12786 // peephole 12787 // %{ 12788 // peepmatch (decI_rReg movI); 12789 // peepconstraint (0.dst == 1.dst); 12790 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12791 // %} 12792 12793 // peephole 12794 // %{ 12795 // peepmatch (addI_rReg_imm movI); 12796 // peepconstraint (0.dst == 1.dst); 12797 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12798 // %} 12799 12800 // peephole 12801 // %{ 12802 // peepmatch (incL_rReg movL); 12803 // peepconstraint (0.dst == 1.dst); 12804 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12805 // %} 12806 12807 // peephole 12808 // %{ 12809 // peepmatch (decL_rReg movL); 12810 // peepconstraint (0.dst == 1.dst); 12811 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12812 // %} 12813 12814 // peephole 12815 // %{ 12816 // peepmatch (addL_rReg_imm movL); 12817 // peepconstraint (0.dst == 1.dst); 12818 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12819 // %} 12820 12821 // peephole 12822 // %{ 12823 // peepmatch (addP_rReg_imm movP); 12824 // peepconstraint (0.dst == 1.dst); 12825 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12826 // %} 12827 12828 // // Change load of spilled value to only a spill 12829 // instruct storeI(memory mem, rRegI src) 12830 // %{ 12831 // match(Set mem (StoreI mem src)); 12832 // %} 12833 // 12834 // instruct loadI(rRegI dst, memory mem) 12835 // %{ 12836 // match(Set dst (LoadI mem)); 12837 // %} 12838 // 12839 12840 peephole 12841 %{ 12842 peepmatch (loadI storeI); 12843 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12844 peepreplace (storeI(1.mem 1.mem 1.src)); 12845 %} 12846 12847 peephole 12848 %{ 12849 peepmatch (loadL storeL); 12850 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12851 peepreplace (storeL(1.mem 1.mem 1.src)); 12852 %} 12853 12854 //----------SMARTSPILL RULES--------------------------------------------------- 12855 // These must follow all instruction definitions as they use the names 12856 // defined in the instructions definitions.