1 // 2 // Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // Specify priority of register selection within phases of register 135 // allocation. Highest priority is first. A useful heuristic is to 136 // give registers a low priority when they are required by machine 137 // instructions, like EAX and EDX on I486, and choose no-save registers 138 // before save-on-call, & save-on-call before save-on-entry. Registers 139 // which participate in fixed calling sequences should come last. 140 // Registers which are used as pairs must fall on an even boundary. 141 142 alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160 //----------Architecture Description Register Classes-------------------------- 161 // Several register classes are automatically defined based upon information in 162 // this architecture description. 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167 // 168 169 // Empty register class. 170 reg_class no_reg(); 171 172 // Class for all pointer registers (including RSP and RBP) 173 reg_class any_reg_with_rbp(RAX, RAX_H, 174 RDX, RDX_H, 175 RBP, RBP_H, 176 RDI, RDI_H, 177 RSI, RSI_H, 178 RCX, RCX_H, 179 RBX, RBX_H, 180 RSP, RSP_H, 181 R8, R8_H, 182 R9, R9_H, 183 R10, R10_H, 184 R11, R11_H, 185 R12, R12_H, 186 R13, R13_H, 187 R14, R14_H, 188 R15, R15_H); 189 190 // Class for all pointer registers (including RSP, but excluding RBP) 191 reg_class any_reg_no_rbp(RAX, RAX_H, 192 RDX, RDX_H, 193 RDI, RDI_H, 194 RSI, RSI_H, 195 RCX, RCX_H, 196 RBX, RBX_H, 197 RSP, RSP_H, 198 R8, R8_H, 199 R9, R9_H, 200 R10, R10_H, 201 R11, R11_H, 202 R12, R12_H, 203 R13, R13_H, 204 R14, R14_H, 205 R15, R15_H); 206 207 // Dynamic register class that selects at runtime between register classes 208 // any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer). 209 // Equivalent to: return PreserveFramePointer ? any_reg_no_rbp : any_reg_with_rbp; 210 reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %}); 211 212 // Class for all pointer registers (excluding RSP) 213 reg_class ptr_reg_with_rbp(RAX, RAX_H, 214 RDX, RDX_H, 215 RBP, RBP_H, 216 RDI, RDI_H, 217 RSI, RSI_H, 218 RCX, RCX_H, 219 RBX, RBX_H, 220 R8, R8_H, 221 R9, R9_H, 222 R10, R10_H, 223 R11, R11_H, 224 R13, R13_H, 225 R14, R14_H); 226 227 // Class for all pointer registers (excluding RSP and RBP) 228 reg_class ptr_reg_no_rbp(RAX, RAX_H, 229 RDX, RDX_H, 230 RDI, RDI_H, 231 RSI, RSI_H, 232 RCX, RCX_H, 233 RBX, RBX_H, 234 R8, R8_H, 235 R9, R9_H, 236 R10, R10_H, 237 R11, R11_H, 238 R13, R13_H, 239 R14, R14_H); 240 241 // Dynamic register class that selects between ptr_reg_no_rbp and ptr_reg_with_rbp. 242 reg_class_dynamic ptr_reg(ptr_reg_no_rbp, ptr_reg_with_rbp, %{ PreserveFramePointer %}); 243 244 // Class for all pointer registers (excluding RAX and RSP) 245 reg_class ptr_no_rax_reg_with_rbp(RDX, RDX_H, 246 RBP, RBP_H, 247 RDI, RDI_H, 248 RSI, RSI_H, 249 RCX, RCX_H, 250 RBX, RBX_H, 251 R8, R8_H, 252 R9, R9_H, 253 R10, R10_H, 254 R11, R11_H, 255 R13, R13_H, 256 R14, R14_H); 257 258 // Class for all pointer registers (excluding RAX, RSP, and RBP) 259 reg_class ptr_no_rax_reg_no_rbp(RDX, RDX_H, 260 RDI, RDI_H, 261 RSI, RSI_H, 262 RCX, RCX_H, 263 RBX, RBX_H, 264 R8, R8_H, 265 R9, R9_H, 266 R10, R10_H, 267 R11, R11_H, 268 R13, R13_H, 269 R14, R14_H); 270 271 // Dynamic register class that selects between ptr_no_rax_reg_no_rbp and ptr_no_rax_reg_with_rbp. 272 reg_class_dynamic ptr_no_rax_reg(ptr_no_rax_reg_no_rbp, ptr_no_rax_reg_with_rbp, %{ PreserveFramePointer %}); 273 274 // Class for all pointer registers (excluding RAX, RBX, and RSP) 275 reg_class ptr_no_rax_rbx_reg_with_rbp(RDX, RDX_H, 276 RBP, RBP_H, 277 RDI, RDI_H, 278 RSI, RSI_H, 279 RCX, RCX_H, 280 R8, R8_H, 281 R9, R9_H, 282 R10, R10_H, 283 R11, R11_H, 284 R13, R13_H, 285 R14, R14_H); 286 287 // Class for all pointer registers (excluding RAX, RBX, RSP, and RBP) 288 reg_class ptr_no_rax_rbx_reg_no_rbp(RDX, RDX_H, 289 RDI, RDI_H, 290 RSI, RSI_H, 291 RCX, RCX_H, 292 R8, R8_H, 293 R9, R9_H, 294 R10, R10_H, 295 R11, R11_H, 296 R13, R13_H, 297 R14, R14_H); 298 299 // Dynamic register class that selects between ptr_no_rax_rbx_reg_no_rbp and ptr_no_rax_rbx_reg_with_rbp. 300 reg_class_dynamic ptr_no_rax_rbx_reg(ptr_no_rax_rbx_reg_no_rbp, ptr_no_rax_rbx_reg_with_rbp, %{ PreserveFramePointer %}); 301 302 // Singleton class for RAX pointer register 303 reg_class ptr_rax_reg(RAX, RAX_H); 304 305 // Singleton class for RBX pointer register 306 reg_class ptr_rbx_reg(RBX, RBX_H); 307 308 // Singleton class for RSI pointer register 309 reg_class ptr_rsi_reg(RSI, RSI_H); 310 311 // Singleton class for RDI pointer register 312 reg_class ptr_rdi_reg(RDI, RDI_H); 313 314 // Singleton class for stack pointer 315 reg_class ptr_rsp_reg(RSP, RSP_H); 316 317 // Singleton class for TLS pointer 318 reg_class ptr_r15_reg(R15, R15_H); 319 320 // Class for all long registers (excluding RSP) 321 reg_class long_reg_with_rbp(RAX, RAX_H, 322 RDX, RDX_H, 323 RBP, RBP_H, 324 RDI, RDI_H, 325 RSI, RSI_H, 326 RCX, RCX_H, 327 RBX, RBX_H, 328 R8, R8_H, 329 R9, R9_H, 330 R10, R10_H, 331 R11, R11_H, 332 R13, R13_H, 333 R14, R14_H); 334 335 // Class for all long registers (excluding RSP and RBP) 336 reg_class long_reg_no_rbp(RAX, RAX_H, 337 RDX, RDX_H, 338 RDI, RDI_H, 339 RSI, RSI_H, 340 RCX, RCX_H, 341 RBX, RBX_H, 342 R8, R8_H, 343 R9, R9_H, 344 R10, R10_H, 345 R11, R11_H, 346 R13, R13_H, 347 R14, R14_H); 348 349 // Dynamic register class that selects between long_reg_no_rbp and long_reg_with_rbp. 350 reg_class_dynamic long_reg(long_reg_no_rbp, long_reg_with_rbp, %{ PreserveFramePointer %}); 351 352 // Class for all long registers (excluding RAX, RDX and RSP) 353 reg_class long_no_rax_rdx_reg_with_rbp(RBP, RBP_H, 354 RDI, RDI_H, 355 RSI, RSI_H, 356 RCX, RCX_H, 357 RBX, RBX_H, 358 R8, R8_H, 359 R9, R9_H, 360 R10, R10_H, 361 R11, R11_H, 362 R13, R13_H, 363 R14, R14_H); 364 365 // Class for all long registers (excluding RAX, RDX, RSP, and RBP) 366 reg_class long_no_rax_rdx_reg_no_rbp(RDI, RDI_H, 367 RSI, RSI_H, 368 RCX, RCX_H, 369 RBX, RBX_H, 370 R8, R8_H, 371 R9, R9_H, 372 R10, R10_H, 373 R11, R11_H, 374 R13, R13_H, 375 R14, R14_H); 376 377 // Dynamic register class that selects between long_no_rax_rdx_reg_no_rbp and long_no_rax_rdx_reg_with_rbp. 378 reg_class_dynamic long_no_rax_rdx_reg(long_no_rax_rdx_reg_no_rbp, long_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 379 380 // Class for all long registers (excluding RCX and RSP) 381 reg_class long_no_rcx_reg_with_rbp(RBP, RBP_H, 382 RDI, RDI_H, 383 RSI, RSI_H, 384 RAX, RAX_H, 385 RDX, RDX_H, 386 RBX, RBX_H, 387 R8, R8_H, 388 R9, R9_H, 389 R10, R10_H, 390 R11, R11_H, 391 R13, R13_H, 392 R14, R14_H); 393 394 // Class for all long registers (excluding RCX, RSP, and RBP) 395 reg_class long_no_rcx_reg_no_rbp(RDI, RDI_H, 396 RSI, RSI_H, 397 RAX, RAX_H, 398 RDX, RDX_H, 399 RBX, RBX_H, 400 R8, R8_H, 401 R9, R9_H, 402 R10, R10_H, 403 R11, R11_H, 404 R13, R13_H, 405 R14, R14_H); 406 407 // Dynamic register class that selects between long_no_rcx_reg_no_rbp and long_no_rcx_reg_with_rbp. 408 reg_class_dynamic long_no_rcx_reg(long_no_rcx_reg_no_rbp, long_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 409 410 // Singleton class for RAX long register 411 reg_class long_rax_reg(RAX, RAX_H); 412 413 // Singleton class for RCX long register 414 reg_class long_rcx_reg(RCX, RCX_H); 415 416 // Singleton class for RDX long register 417 reg_class long_rdx_reg(RDX, RDX_H); 418 419 // Class for all int registers (excluding RSP) 420 reg_class int_reg_with_rbp(RAX, 421 RDX, 422 RBP, 423 RDI, 424 RSI, 425 RCX, 426 RBX, 427 R8, 428 R9, 429 R10, 430 R11, 431 R13, 432 R14); 433 434 // Class for all int registers (excluding RSP and RBP) 435 reg_class int_reg_no_rbp(RAX, 436 RDX, 437 RDI, 438 RSI, 439 RCX, 440 RBX, 441 R8, 442 R9, 443 R10, 444 R11, 445 R13, 446 R14); 447 448 // Dynamic register class that selects between int_reg_no_rbp and int_reg_with_rbp. 449 reg_class_dynamic int_reg(int_reg_no_rbp, int_reg_with_rbp, %{ PreserveFramePointer %}); 450 451 // Class for all int registers (excluding RCX and RSP) 452 reg_class int_no_rcx_reg_with_rbp(RAX, 453 RDX, 454 RBP, 455 RDI, 456 RSI, 457 RBX, 458 R8, 459 R9, 460 R10, 461 R11, 462 R13, 463 R14); 464 465 // Class for all int registers (excluding RCX, RSP, and RBP) 466 reg_class int_no_rcx_reg_no_rbp(RAX, 467 RDX, 468 RDI, 469 RSI, 470 RBX, 471 R8, 472 R9, 473 R10, 474 R11, 475 R13, 476 R14); 477 478 // Dynamic register class that selects between int_no_rcx_reg_no_rbp and int_no_rcx_reg_with_rbp. 479 reg_class_dynamic int_no_rcx_reg(int_no_rcx_reg_no_rbp, int_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 480 481 // Class for all int registers (excluding RAX, RDX, and RSP) 482 reg_class int_no_rax_rdx_reg_with_rbp(RBP, 483 RDI, 484 RSI, 485 RCX, 486 RBX, 487 R8, 488 R9, 489 R10, 490 R11, 491 R13, 492 R14); 493 494 // Class for all int registers (excluding RAX, RDX, RSP, and RBP) 495 reg_class int_no_rax_rdx_reg_no_rbp(RDI, 496 RSI, 497 RCX, 498 RBX, 499 R8, 500 R9, 501 R10, 502 R11, 503 R13, 504 R14); 505 506 // Dynamic register class that selects between int_no_rax_rdx_reg_no_rbp and int_no_rax_rdx_reg_with_rbp. 507 reg_class_dynamic int_no_rax_rdx_reg(int_no_rax_rdx_reg_no_rbp, int_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 508 509 // Singleton class for RAX int register 510 reg_class int_rax_reg(RAX); 511 512 // Singleton class for RBX int register 513 reg_class int_rbx_reg(RBX); 514 515 // Singleton class for RCX int register 516 reg_class int_rcx_reg(RCX); 517 518 // Singleton class for RCX int register 519 reg_class int_rdx_reg(RDX); 520 521 // Singleton class for RCX int register 522 reg_class int_rdi_reg(RDI); 523 524 // Singleton class for instruction pointer 525 // reg_class ip_reg(RIP); 526 527 %} 528 529 source_hpp %{ 530 531 #include "gc/shenandoah/brooksPointer.hpp" 532 533 %} 534 535 //----------SOURCE BLOCK------------------------------------------------------- 536 // This is a block of C++ code which provides values, functions, and 537 // definitions necessary in the rest of the architecture description 538 source %{ 539 #define RELOC_IMM64 Assembler::imm_operand 540 #define RELOC_DISP32 Assembler::disp32_operand 541 542 #define __ _masm. 543 544 static int clear_avx_size() { 545 return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper 546 } 547 548 // !!!!! Special hack to get all types of calls to specify the byte offset 549 // from the start of the call to the point where the return address 550 // will point. 551 int MachCallStaticJavaNode::ret_addr_offset() 552 { 553 int offset = 5; // 5 bytes from start of call to where return address points 554 offset += clear_avx_size(); 555 return offset; 556 } 557 558 int MachCallDynamicJavaNode::ret_addr_offset() 559 { 560 int offset = 15; // 15 bytes from start of call to where return address points 561 offset += clear_avx_size(); 562 return offset; 563 } 564 565 int MachCallRuntimeNode::ret_addr_offset() { 566 int offset = 13; // movq r10,#addr; callq (r10) 567 offset += clear_avx_size(); 568 return offset; 569 } 570 571 // Indicate if the safepoint node needs the polling page as an input, 572 // it does if the polling page is more than disp32 away. 573 bool SafePointNode::needs_polling_address_input() 574 { 575 return Assembler::is_polling_page_far(); 576 } 577 578 // 579 // Compute padding required for nodes which need alignment 580 // 581 582 // The address of the call instruction needs to be 4-byte aligned to 583 // ensure that it does not span a cache line so that it can be patched. 584 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 585 { 586 current_offset += clear_avx_size(); // skip vzeroupper 587 current_offset += 1; // skip call opcode byte 588 return round_to(current_offset, alignment_required()) - current_offset; 589 } 590 591 // The address of the call instruction needs to be 4-byte aligned to 592 // ensure that it does not span a cache line so that it can be patched. 593 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 594 { 595 current_offset += clear_avx_size(); // skip vzeroupper 596 current_offset += 11; // skip movq instruction + call opcode byte 597 return round_to(current_offset, alignment_required()) - current_offset; 598 } 599 600 // EMIT_RM() 601 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 602 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 603 cbuf.insts()->emit_int8(c); 604 } 605 606 // EMIT_CC() 607 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 608 unsigned char c = (unsigned char) (f1 | f2); 609 cbuf.insts()->emit_int8(c); 610 } 611 612 // EMIT_OPCODE() 613 void emit_opcode(CodeBuffer &cbuf, int code) { 614 cbuf.insts()->emit_int8((unsigned char) code); 615 } 616 617 // EMIT_OPCODE() w/ relocation information 618 void emit_opcode(CodeBuffer &cbuf, 619 int code, relocInfo::relocType reloc, int offset, int format) 620 { 621 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 622 emit_opcode(cbuf, code); 623 } 624 625 // EMIT_D8() 626 void emit_d8(CodeBuffer &cbuf, int d8) { 627 cbuf.insts()->emit_int8((unsigned char) d8); 628 } 629 630 // EMIT_D16() 631 void emit_d16(CodeBuffer &cbuf, int d16) { 632 cbuf.insts()->emit_int16(d16); 633 } 634 635 // EMIT_D32() 636 void emit_d32(CodeBuffer &cbuf, int d32) { 637 cbuf.insts()->emit_int32(d32); 638 } 639 640 // EMIT_D64() 641 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 642 cbuf.insts()->emit_int64(d64); 643 } 644 645 // emit 32 bit value and construct relocation entry from relocInfo::relocType 646 void emit_d32_reloc(CodeBuffer& cbuf, 647 int d32, 648 relocInfo::relocType reloc, 649 int format) 650 { 651 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 652 cbuf.relocate(cbuf.insts_mark(), reloc, format); 653 cbuf.insts()->emit_int32(d32); 654 } 655 656 // emit 32 bit value and construct relocation entry from RelocationHolder 657 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 658 #ifdef ASSERT 659 if (rspec.reloc()->type() == relocInfo::oop_type && 660 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 661 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 662 assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 663 } 664 #endif 665 cbuf.relocate(cbuf.insts_mark(), rspec, format); 666 cbuf.insts()->emit_int32(d32); 667 } 668 669 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 670 address next_ip = cbuf.insts_end() + 4; 671 emit_d32_reloc(cbuf, (int) (addr - next_ip), 672 external_word_Relocation::spec(addr), 673 RELOC_DISP32); 674 } 675 676 677 // emit 64 bit value and construct relocation entry from relocInfo::relocType 678 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 679 cbuf.relocate(cbuf.insts_mark(), reloc, format); 680 cbuf.insts()->emit_int64(d64); 681 } 682 683 // emit 64 bit value and construct relocation entry from RelocationHolder 684 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 685 #ifdef ASSERT 686 if (rspec.reloc()->type() == relocInfo::oop_type && 687 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 688 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 689 assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()), 690 "cannot embed scavengable oops in code"); 691 } 692 #endif 693 cbuf.relocate(cbuf.insts_mark(), rspec, format); 694 cbuf.insts()->emit_int64(d64); 695 } 696 697 // Access stack slot for load or store 698 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 699 { 700 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 701 if (-0x80 <= disp && disp < 0x80) { 702 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 703 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 704 emit_d8(cbuf, disp); // Displacement // R/M byte 705 } else { 706 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 707 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 708 emit_d32(cbuf, disp); // Displacement // R/M byte 709 } 710 } 711 712 // rRegI ereg, memory mem) %{ // emit_reg_mem 713 void encode_RegMem(CodeBuffer &cbuf, 714 int reg, 715 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 716 { 717 assert(disp_reloc == relocInfo::none, "cannot have disp"); 718 int regenc = reg & 7; 719 int baseenc = base & 7; 720 int indexenc = index & 7; 721 722 // There is no index & no scale, use form without SIB byte 723 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 724 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 725 if (disp == 0 && base != RBP_enc && base != R13_enc) { 726 emit_rm(cbuf, 0x0, regenc, baseenc); // * 727 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 728 // If 8-bit displacement, mode 0x1 729 emit_rm(cbuf, 0x1, regenc, baseenc); // * 730 emit_d8(cbuf, disp); 731 } else { 732 // If 32-bit displacement 733 if (base == -1) { // Special flag for absolute address 734 emit_rm(cbuf, 0x0, regenc, 0x5); // * 735 if (disp_reloc != relocInfo::none) { 736 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 737 } else { 738 emit_d32(cbuf, disp); 739 } 740 } else { 741 // Normal base + offset 742 emit_rm(cbuf, 0x2, regenc, baseenc); // * 743 if (disp_reloc != relocInfo::none) { 744 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 745 } else { 746 emit_d32(cbuf, disp); 747 } 748 } 749 } 750 } else { 751 // Else, encode with the SIB byte 752 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 753 if (disp == 0 && base != RBP_enc && base != R13_enc) { 754 // If no displacement 755 emit_rm(cbuf, 0x0, regenc, 0x4); // * 756 emit_rm(cbuf, scale, indexenc, baseenc); 757 } else { 758 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 759 // If 8-bit displacement, mode 0x1 760 emit_rm(cbuf, 0x1, regenc, 0x4); // * 761 emit_rm(cbuf, scale, indexenc, baseenc); 762 emit_d8(cbuf, disp); 763 } else { 764 // If 32-bit displacement 765 if (base == 0x04 ) { 766 emit_rm(cbuf, 0x2, regenc, 0x4); 767 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 768 } else { 769 emit_rm(cbuf, 0x2, regenc, 0x4); 770 emit_rm(cbuf, scale, indexenc, baseenc); // * 771 } 772 if (disp_reloc != relocInfo::none) { 773 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 774 } else { 775 emit_d32(cbuf, disp); 776 } 777 } 778 } 779 } 780 } 781 782 // This could be in MacroAssembler but it's fairly C2 specific 783 void emit_cmpfp_fixup(MacroAssembler& _masm) { 784 Label exit; 785 __ jccb(Assembler::noParity, exit); 786 __ pushf(); 787 // 788 // comiss/ucomiss instructions set ZF,PF,CF flags and 789 // zero OF,AF,SF for NaN values. 790 // Fixup flags by zeroing ZF,PF so that compare of NaN 791 // values returns 'less than' result (CF is set). 792 // Leave the rest of flags unchanged. 793 // 794 // 7 6 5 4 3 2 1 0 795 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 796 // 0 0 1 0 1 0 1 1 (0x2B) 797 // 798 __ andq(Address(rsp, 0), 0xffffff2b); 799 __ popf(); 800 __ bind(exit); 801 } 802 803 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 804 Label done; 805 __ movl(dst, -1); 806 __ jcc(Assembler::parity, done); 807 __ jcc(Assembler::below, done); 808 __ setb(Assembler::notEqual, dst); 809 __ movzbl(dst, dst); 810 __ bind(done); 811 } 812 813 814 //============================================================================= 815 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 816 817 int Compile::ConstantTable::calculate_table_base_offset() const { 818 return 0; // absolute addressing, no offset 819 } 820 821 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 822 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 823 ShouldNotReachHere(); 824 } 825 826 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 827 // Empty encoding 828 } 829 830 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 831 return 0; 832 } 833 834 #ifndef PRODUCT 835 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 836 st->print("# MachConstantBaseNode (empty encoding)"); 837 } 838 #endif 839 840 841 //============================================================================= 842 #ifndef PRODUCT 843 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 844 Compile* C = ra_->C; 845 846 int framesize = C->frame_size_in_bytes(); 847 int bangsize = C->bang_size_in_bytes(); 848 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 849 // Remove wordSize for return addr which is already pushed. 850 framesize -= wordSize; 851 852 if (C->need_stack_bang(bangsize)) { 853 framesize -= wordSize; 854 st->print("# stack bang (%d bytes)", bangsize); 855 st->print("\n\t"); 856 st->print("pushq rbp\t# Save rbp"); 857 if (PreserveFramePointer) { 858 st->print("\n\t"); 859 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 860 } 861 if (framesize) { 862 st->print("\n\t"); 863 st->print("subq rsp, #%d\t# Create frame",framesize); 864 } 865 } else { 866 st->print("subq rsp, #%d\t# Create frame",framesize); 867 st->print("\n\t"); 868 framesize -= wordSize; 869 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 870 if (PreserveFramePointer) { 871 st->print("\n\t"); 872 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 873 if (framesize > 0) { 874 st->print("\n\t"); 875 st->print("addq rbp, #%d", framesize); 876 } 877 } 878 } 879 880 if (VerifyStackAtCalls) { 881 st->print("\n\t"); 882 framesize -= wordSize; 883 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 884 #ifdef ASSERT 885 st->print("\n\t"); 886 st->print("# stack alignment check"); 887 #endif 888 } 889 st->cr(); 890 } 891 #endif 892 893 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 894 Compile* C = ra_->C; 895 MacroAssembler _masm(&cbuf); 896 897 int framesize = C->frame_size_in_bytes(); 898 int bangsize = C->bang_size_in_bytes(); 899 900 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); 901 902 C->set_frame_complete(cbuf.insts_size()); 903 904 if (C->has_mach_constant_base_node()) { 905 // NOTE: We set the table base offset here because users might be 906 // emitted before MachConstantBaseNode. 907 Compile::ConstantTable& constant_table = C->constant_table(); 908 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 909 } 910 } 911 912 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 913 { 914 return MachNode::size(ra_); // too many variables; just compute it 915 // the hard way 916 } 917 918 int MachPrologNode::reloc() const 919 { 920 return 0; // a large enough number 921 } 922 923 //============================================================================= 924 #ifndef PRODUCT 925 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 926 { 927 Compile* C = ra_->C; 928 if (C->max_vector_size() > 16) { 929 st->print("vzeroupper"); 930 st->cr(); st->print("\t"); 931 } 932 933 int framesize = C->frame_size_in_bytes(); 934 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 935 // Remove word for return adr already pushed 936 // and RBP 937 framesize -= 2*wordSize; 938 939 if (framesize) { 940 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 941 st->print("\t"); 942 } 943 944 st->print_cr("popq rbp"); 945 if (do_polling() && C->is_method_compilation()) { 946 st->print("\t"); 947 if (Assembler::is_polling_page_far()) { 948 st->print_cr("movq rscratch1, #polling_page_address\n\t" 949 "testl rax, [rscratch1]\t" 950 "# Safepoint: poll for GC"); 951 } else { 952 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 953 "# Safepoint: poll for GC"); 954 } 955 } 956 } 957 #endif 958 959 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 960 { 961 Compile* C = ra_->C; 962 MacroAssembler _masm(&cbuf); 963 964 if (C->max_vector_size() > 16) { 965 // Clear upper bits of YMM registers when current compiled code uses 966 // wide vectors to avoid AVX <-> SSE transition penalty during call. 967 __ vzeroupper(); 968 } 969 970 int framesize = C->frame_size_in_bytes(); 971 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 972 // Remove word for return adr already pushed 973 // and RBP 974 framesize -= 2*wordSize; 975 976 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 977 978 if (framesize) { 979 emit_opcode(cbuf, Assembler::REX_W); 980 if (framesize < 0x80) { 981 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 982 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 983 emit_d8(cbuf, framesize); 984 } else { 985 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 986 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 987 emit_d32(cbuf, framesize); 988 } 989 } 990 991 // popq rbp 992 emit_opcode(cbuf, 0x58 | RBP_enc); 993 994 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 995 __ reserved_stack_check(); 996 } 997 998 if (do_polling() && C->is_method_compilation()) { 999 MacroAssembler _masm(&cbuf); 1000 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1001 if (Assembler::is_polling_page_far()) { 1002 __ lea(rscratch1, polling_page); 1003 __ relocate(relocInfo::poll_return_type); 1004 __ testl(rax, Address(rscratch1, 0)); 1005 } else { 1006 __ testl(rax, polling_page); 1007 } 1008 } 1009 } 1010 1011 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1012 { 1013 return MachNode::size(ra_); // too many variables; just compute it 1014 // the hard way 1015 } 1016 1017 int MachEpilogNode::reloc() const 1018 { 1019 return 2; // a large enough number 1020 } 1021 1022 const Pipeline* MachEpilogNode::pipeline() const 1023 { 1024 return MachNode::pipeline_class(); 1025 } 1026 1027 int MachEpilogNode::safepoint_offset() const 1028 { 1029 return 0; 1030 } 1031 1032 //============================================================================= 1033 1034 enum RC { 1035 rc_bad, 1036 rc_int, 1037 rc_float, 1038 rc_stack 1039 }; 1040 1041 static enum RC rc_class(OptoReg::Name reg) 1042 { 1043 if( !OptoReg::is_valid(reg) ) return rc_bad; 1044 1045 if (OptoReg::is_stack(reg)) return rc_stack; 1046 1047 VMReg r = OptoReg::as_VMReg(reg); 1048 1049 if (r->is_Register()) return rc_int; 1050 1051 assert(r->is_XMMRegister(), "must be"); 1052 return rc_float; 1053 } 1054 1055 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1056 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1057 int src_hi, int dst_hi, uint ireg, outputStream* st); 1058 1059 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1060 int stack_offset, int reg, uint ireg, outputStream* st); 1061 1062 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1063 int dst_offset, uint ireg, outputStream* st) { 1064 if (cbuf) { 1065 MacroAssembler _masm(cbuf); 1066 switch (ireg) { 1067 case Op_VecS: 1068 __ movq(Address(rsp, -8), rax); 1069 __ movl(rax, Address(rsp, src_offset)); 1070 __ movl(Address(rsp, dst_offset), rax); 1071 __ movq(rax, Address(rsp, -8)); 1072 break; 1073 case Op_VecD: 1074 __ pushq(Address(rsp, src_offset)); 1075 __ popq (Address(rsp, dst_offset)); 1076 break; 1077 case Op_VecX: 1078 __ pushq(Address(rsp, src_offset)); 1079 __ popq (Address(rsp, dst_offset)); 1080 __ pushq(Address(rsp, src_offset+8)); 1081 __ popq (Address(rsp, dst_offset+8)); 1082 break; 1083 case Op_VecY: 1084 __ vmovdqu(Address(rsp, -32), xmm0); 1085 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1086 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1087 __ vmovdqu(xmm0, Address(rsp, -32)); 1088 break; 1089 case Op_VecZ: 1090 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1091 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1092 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1093 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1094 break; 1095 default: 1096 ShouldNotReachHere(); 1097 } 1098 #ifndef PRODUCT 1099 } else { 1100 switch (ireg) { 1101 case Op_VecS: 1102 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1103 "movl rax, [rsp + #%d]\n\t" 1104 "movl [rsp + #%d], rax\n\t" 1105 "movq rax, [rsp - #8]", 1106 src_offset, dst_offset); 1107 break; 1108 case Op_VecD: 1109 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1110 "popq [rsp + #%d]", 1111 src_offset, dst_offset); 1112 break; 1113 case Op_VecX: 1114 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1115 "popq [rsp + #%d]\n\t" 1116 "pushq [rsp + #%d]\n\t" 1117 "popq [rsp + #%d]", 1118 src_offset, dst_offset, src_offset+8, dst_offset+8); 1119 break; 1120 case Op_VecY: 1121 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1122 "vmovdqu xmm0, [rsp + #%d]\n\t" 1123 "vmovdqu [rsp + #%d], xmm0\n\t" 1124 "vmovdqu xmm0, [rsp - #32]", 1125 src_offset, dst_offset); 1126 break; 1127 case Op_VecZ: 1128 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1129 "vmovdqu xmm0, [rsp + #%d]\n\t" 1130 "vmovdqu [rsp + #%d], xmm0\n\t" 1131 "vmovdqu xmm0, [rsp - #64]", 1132 src_offset, dst_offset); 1133 break; 1134 default: 1135 ShouldNotReachHere(); 1136 } 1137 #endif 1138 } 1139 } 1140 1141 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1142 PhaseRegAlloc* ra_, 1143 bool do_size, 1144 outputStream* st) const { 1145 assert(cbuf != NULL || st != NULL, "sanity"); 1146 // Get registers to move 1147 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1148 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1149 OptoReg::Name dst_second = ra_->get_reg_second(this); 1150 OptoReg::Name dst_first = ra_->get_reg_first(this); 1151 1152 enum RC src_second_rc = rc_class(src_second); 1153 enum RC src_first_rc = rc_class(src_first); 1154 enum RC dst_second_rc = rc_class(dst_second); 1155 enum RC dst_first_rc = rc_class(dst_first); 1156 1157 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1158 "must move at least 1 register" ); 1159 1160 if (src_first == dst_first && src_second == dst_second) { 1161 // Self copy, no move 1162 return 0; 1163 } 1164 if (bottom_type()->isa_vect() != NULL) { 1165 uint ireg = ideal_reg(); 1166 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1167 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1168 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1169 // mem -> mem 1170 int src_offset = ra_->reg2offset(src_first); 1171 int dst_offset = ra_->reg2offset(dst_first); 1172 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1173 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1174 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1175 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1176 int stack_offset = ra_->reg2offset(dst_first); 1177 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1178 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1179 int stack_offset = ra_->reg2offset(src_first); 1180 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1181 } else { 1182 ShouldNotReachHere(); 1183 } 1184 return 0; 1185 } 1186 if (src_first_rc == rc_stack) { 1187 // mem -> 1188 if (dst_first_rc == rc_stack) { 1189 // mem -> mem 1190 assert(src_second != dst_first, "overlap"); 1191 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1192 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1193 // 64-bit 1194 int src_offset = ra_->reg2offset(src_first); 1195 int dst_offset = ra_->reg2offset(dst_first); 1196 if (cbuf) { 1197 MacroAssembler _masm(cbuf); 1198 __ pushq(Address(rsp, src_offset)); 1199 __ popq (Address(rsp, dst_offset)); 1200 #ifndef PRODUCT 1201 } else { 1202 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1203 "popq [rsp + #%d]", 1204 src_offset, dst_offset); 1205 #endif 1206 } 1207 } else { 1208 // 32-bit 1209 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1210 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1211 // No pushl/popl, so: 1212 int src_offset = ra_->reg2offset(src_first); 1213 int dst_offset = ra_->reg2offset(dst_first); 1214 if (cbuf) { 1215 MacroAssembler _masm(cbuf); 1216 __ movq(Address(rsp, -8), rax); 1217 __ movl(rax, Address(rsp, src_offset)); 1218 __ movl(Address(rsp, dst_offset), rax); 1219 __ movq(rax, Address(rsp, -8)); 1220 #ifndef PRODUCT 1221 } else { 1222 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1223 "movl rax, [rsp + #%d]\n\t" 1224 "movl [rsp + #%d], rax\n\t" 1225 "movq rax, [rsp - #8]", 1226 src_offset, dst_offset); 1227 #endif 1228 } 1229 } 1230 return 0; 1231 } else if (dst_first_rc == rc_int) { 1232 // mem -> gpr 1233 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1234 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1235 // 64-bit 1236 int offset = ra_->reg2offset(src_first); 1237 if (cbuf) { 1238 MacroAssembler _masm(cbuf); 1239 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1240 #ifndef PRODUCT 1241 } else { 1242 st->print("movq %s, [rsp + #%d]\t# spill", 1243 Matcher::regName[dst_first], 1244 offset); 1245 #endif 1246 } 1247 } else { 1248 // 32-bit 1249 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1250 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1251 int offset = ra_->reg2offset(src_first); 1252 if (cbuf) { 1253 MacroAssembler _masm(cbuf); 1254 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1255 #ifndef PRODUCT 1256 } else { 1257 st->print("movl %s, [rsp + #%d]\t# spill", 1258 Matcher::regName[dst_first], 1259 offset); 1260 #endif 1261 } 1262 } 1263 return 0; 1264 } else if (dst_first_rc == rc_float) { 1265 // mem-> xmm 1266 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1267 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1268 // 64-bit 1269 int offset = ra_->reg2offset(src_first); 1270 if (cbuf) { 1271 MacroAssembler _masm(cbuf); 1272 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1273 #ifndef PRODUCT 1274 } else { 1275 st->print("%s %s, [rsp + #%d]\t# spill", 1276 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1277 Matcher::regName[dst_first], 1278 offset); 1279 #endif 1280 } 1281 } else { 1282 // 32-bit 1283 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1284 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1285 int offset = ra_->reg2offset(src_first); 1286 if (cbuf) { 1287 MacroAssembler _masm(cbuf); 1288 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1289 #ifndef PRODUCT 1290 } else { 1291 st->print("movss %s, [rsp + #%d]\t# spill", 1292 Matcher::regName[dst_first], 1293 offset); 1294 #endif 1295 } 1296 } 1297 return 0; 1298 } 1299 } else if (src_first_rc == rc_int) { 1300 // gpr -> 1301 if (dst_first_rc == rc_stack) { 1302 // gpr -> mem 1303 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1304 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1305 // 64-bit 1306 int offset = ra_->reg2offset(dst_first); 1307 if (cbuf) { 1308 MacroAssembler _masm(cbuf); 1309 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1310 #ifndef PRODUCT 1311 } else { 1312 st->print("movq [rsp + #%d], %s\t# spill", 1313 offset, 1314 Matcher::regName[src_first]); 1315 #endif 1316 } 1317 } else { 1318 // 32-bit 1319 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1320 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1321 int offset = ra_->reg2offset(dst_first); 1322 if (cbuf) { 1323 MacroAssembler _masm(cbuf); 1324 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1325 #ifndef PRODUCT 1326 } else { 1327 st->print("movl [rsp + #%d], %s\t# spill", 1328 offset, 1329 Matcher::regName[src_first]); 1330 #endif 1331 } 1332 } 1333 return 0; 1334 } else if (dst_first_rc == rc_int) { 1335 // gpr -> gpr 1336 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1337 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1338 // 64-bit 1339 if (cbuf) { 1340 MacroAssembler _masm(cbuf); 1341 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1342 as_Register(Matcher::_regEncode[src_first])); 1343 #ifndef PRODUCT 1344 } else { 1345 st->print("movq %s, %s\t# spill", 1346 Matcher::regName[dst_first], 1347 Matcher::regName[src_first]); 1348 #endif 1349 } 1350 return 0; 1351 } else { 1352 // 32-bit 1353 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1354 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1355 if (cbuf) { 1356 MacroAssembler _masm(cbuf); 1357 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1358 as_Register(Matcher::_regEncode[src_first])); 1359 #ifndef PRODUCT 1360 } else { 1361 st->print("movl %s, %s\t# spill", 1362 Matcher::regName[dst_first], 1363 Matcher::regName[src_first]); 1364 #endif 1365 } 1366 return 0; 1367 } 1368 } else if (dst_first_rc == rc_float) { 1369 // gpr -> xmm 1370 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1371 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1372 // 64-bit 1373 if (cbuf) { 1374 MacroAssembler _masm(cbuf); 1375 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1376 #ifndef PRODUCT 1377 } else { 1378 st->print("movdq %s, %s\t# spill", 1379 Matcher::regName[dst_first], 1380 Matcher::regName[src_first]); 1381 #endif 1382 } 1383 } else { 1384 // 32-bit 1385 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1386 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1387 if (cbuf) { 1388 MacroAssembler _masm(cbuf); 1389 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1390 #ifndef PRODUCT 1391 } else { 1392 st->print("movdl %s, %s\t# spill", 1393 Matcher::regName[dst_first], 1394 Matcher::regName[src_first]); 1395 #endif 1396 } 1397 } 1398 return 0; 1399 } 1400 } else if (src_first_rc == rc_float) { 1401 // xmm -> 1402 if (dst_first_rc == rc_stack) { 1403 // xmm -> mem 1404 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1405 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1406 // 64-bit 1407 int offset = ra_->reg2offset(dst_first); 1408 if (cbuf) { 1409 MacroAssembler _masm(cbuf); 1410 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1411 #ifndef PRODUCT 1412 } else { 1413 st->print("movsd [rsp + #%d], %s\t# spill", 1414 offset, 1415 Matcher::regName[src_first]); 1416 #endif 1417 } 1418 } else { 1419 // 32-bit 1420 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1421 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1422 int offset = ra_->reg2offset(dst_first); 1423 if (cbuf) { 1424 MacroAssembler _masm(cbuf); 1425 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1426 #ifndef PRODUCT 1427 } else { 1428 st->print("movss [rsp + #%d], %s\t# spill", 1429 offset, 1430 Matcher::regName[src_first]); 1431 #endif 1432 } 1433 } 1434 return 0; 1435 } else if (dst_first_rc == rc_int) { 1436 // xmm -> gpr 1437 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1438 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1439 // 64-bit 1440 if (cbuf) { 1441 MacroAssembler _masm(cbuf); 1442 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1443 #ifndef PRODUCT 1444 } else { 1445 st->print("movdq %s, %s\t# spill", 1446 Matcher::regName[dst_first], 1447 Matcher::regName[src_first]); 1448 #endif 1449 } 1450 } else { 1451 // 32-bit 1452 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1453 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1454 if (cbuf) { 1455 MacroAssembler _masm(cbuf); 1456 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1457 #ifndef PRODUCT 1458 } else { 1459 st->print("movdl %s, %s\t# spill", 1460 Matcher::regName[dst_first], 1461 Matcher::regName[src_first]); 1462 #endif 1463 } 1464 } 1465 return 0; 1466 } else if (dst_first_rc == rc_float) { 1467 // xmm -> xmm 1468 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1469 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1470 // 64-bit 1471 if (cbuf) { 1472 MacroAssembler _masm(cbuf); 1473 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1474 #ifndef PRODUCT 1475 } else { 1476 st->print("%s %s, %s\t# spill", 1477 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1478 Matcher::regName[dst_first], 1479 Matcher::regName[src_first]); 1480 #endif 1481 } 1482 } else { 1483 // 32-bit 1484 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1485 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1486 if (cbuf) { 1487 MacroAssembler _masm(cbuf); 1488 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1489 #ifndef PRODUCT 1490 } else { 1491 st->print("%s %s, %s\t# spill", 1492 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1493 Matcher::regName[dst_first], 1494 Matcher::regName[src_first]); 1495 #endif 1496 } 1497 } 1498 return 0; 1499 } 1500 } 1501 1502 assert(0," foo "); 1503 Unimplemented(); 1504 return 0; 1505 } 1506 1507 #ifndef PRODUCT 1508 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1509 implementation(NULL, ra_, false, st); 1510 } 1511 #endif 1512 1513 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1514 implementation(&cbuf, ra_, false, NULL); 1515 } 1516 1517 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1518 return MachNode::size(ra_); 1519 } 1520 1521 //============================================================================= 1522 #ifndef PRODUCT 1523 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1524 { 1525 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1526 int reg = ra_->get_reg_first(this); 1527 st->print("leaq %s, [rsp + #%d]\t# box lock", 1528 Matcher::regName[reg], offset); 1529 } 1530 #endif 1531 1532 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1533 { 1534 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1535 int reg = ra_->get_encode(this); 1536 if (offset >= 0x80) { 1537 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1538 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1539 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1540 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1541 emit_d32(cbuf, offset); 1542 } else { 1543 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1544 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1545 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1546 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1547 emit_d8(cbuf, offset); 1548 } 1549 } 1550 1551 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1552 { 1553 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1554 return (offset < 0x80) ? 5 : 8; // REX 1555 } 1556 1557 //============================================================================= 1558 #ifndef PRODUCT 1559 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1560 { 1561 if (UseCompressedClassPointers) { 1562 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1563 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1564 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1565 } else { 1566 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1567 "# Inline cache check"); 1568 } 1569 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1570 st->print_cr("\tnop\t# nops to align entry point"); 1571 } 1572 #endif 1573 1574 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1575 { 1576 MacroAssembler masm(&cbuf); 1577 uint insts_size = cbuf.insts_size(); 1578 if (UseCompressedClassPointers) { 1579 masm.load_klass(rscratch1, j_rarg0); 1580 masm.cmpptr(rax, rscratch1); 1581 } else { 1582 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1583 } 1584 1585 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1586 1587 /* WARNING these NOPs are critical so that verified entry point is properly 1588 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1589 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1590 if (OptoBreakpoint) { 1591 // Leave space for int3 1592 nops_cnt -= 1; 1593 } 1594 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1595 if (nops_cnt > 0) 1596 masm.nop(nops_cnt); 1597 } 1598 1599 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1600 { 1601 return MachNode::size(ra_); // too many variables; just compute it 1602 // the hard way 1603 } 1604 1605 1606 //============================================================================= 1607 1608 int Matcher::regnum_to_fpu_offset(int regnum) 1609 { 1610 return regnum - 32; // The FP registers are in the second chunk 1611 } 1612 1613 // This is UltraSparc specific, true just means we have fast l2f conversion 1614 const bool Matcher::convL2FSupported(void) { 1615 return true; 1616 } 1617 1618 // Is this branch offset short enough that a short branch can be used? 1619 // 1620 // NOTE: If the platform does not provide any short branch variants, then 1621 // this method should return false for offset 0. 1622 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1623 // The passed offset is relative to address of the branch. 1624 // On 86 a branch displacement is calculated relative to address 1625 // of a next instruction. 1626 offset -= br_size; 1627 1628 // the short version of jmpConUCF2 contains multiple branches, 1629 // making the reach slightly less 1630 if (rule == jmpConUCF2_rule) 1631 return (-126 <= offset && offset <= 125); 1632 return (-128 <= offset && offset <= 127); 1633 } 1634 1635 const bool Matcher::isSimpleConstant64(jlong value) { 1636 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1637 //return value == (int) value; // Cf. storeImmL and immL32. 1638 1639 // Probably always true, even if a temp register is required. 1640 return true; 1641 } 1642 1643 // The ecx parameter to rep stosq for the ClearArray node is in words. 1644 const bool Matcher::init_array_count_is_in_bytes = false; 1645 1646 // No additional cost for CMOVL. 1647 const int Matcher::long_cmove_cost() { return 0; } 1648 1649 // No CMOVF/CMOVD with SSE2 1650 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1651 1652 // Does the CPU require late expand (see block.cpp for description of late expand)? 1653 const bool Matcher::require_postalloc_expand = false; 1654 1655 // Do we need to mask the count passed to shift instructions or does 1656 // the cpu only look at the lower 5/6 bits anyway? 1657 const bool Matcher::need_masked_shift_count = false; 1658 1659 bool Matcher::narrow_oop_use_complex_address() { 1660 assert(UseCompressedOops, "only for compressed oops code"); 1661 return (LogMinObjAlignmentInBytes <= 3); 1662 } 1663 1664 bool Matcher::narrow_klass_use_complex_address() { 1665 assert(UseCompressedClassPointers, "only for compressed klass code"); 1666 return (LogKlassAlignmentInBytes <= 3); 1667 } 1668 1669 // Is it better to copy float constants, or load them directly from 1670 // memory? Intel can load a float constant from a direct address, 1671 // requiring no extra registers. Most RISCs will have to materialize 1672 // an address into a register first, so they would do better to copy 1673 // the constant from stack. 1674 const bool Matcher::rematerialize_float_constants = true; // XXX 1675 1676 // If CPU can load and store mis-aligned doubles directly then no 1677 // fixup is needed. Else we split the double into 2 integer pieces 1678 // and move it piece-by-piece. Only happens when passing doubles into 1679 // C code as the Java calling convention forces doubles to be aligned. 1680 const bool Matcher::misaligned_doubles_ok = true; 1681 1682 // No-op on amd64 1683 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1684 1685 // Advertise here if the CPU requires explicit rounding operations to 1686 // implement the UseStrictFP mode. 1687 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1688 1689 // Are floats conerted to double when stored to stack during deoptimization? 1690 // On x64 it is stored without convertion so we can use normal access. 1691 bool Matcher::float_in_double() { return false; } 1692 1693 // Do ints take an entire long register or just half? 1694 const bool Matcher::int_in_long = true; 1695 1696 // Return whether or not this register is ever used as an argument. 1697 // This function is used on startup to build the trampoline stubs in 1698 // generateOptoStub. Registers not mentioned will be killed by the VM 1699 // call in the trampoline, and arguments in those registers not be 1700 // available to the callee. 1701 bool Matcher::can_be_java_arg(int reg) 1702 { 1703 return 1704 reg == RDI_num || reg == RDI_H_num || 1705 reg == RSI_num || reg == RSI_H_num || 1706 reg == RDX_num || reg == RDX_H_num || 1707 reg == RCX_num || reg == RCX_H_num || 1708 reg == R8_num || reg == R8_H_num || 1709 reg == R9_num || reg == R9_H_num || 1710 reg == R12_num || reg == R12_H_num || 1711 reg == XMM0_num || reg == XMM0b_num || 1712 reg == XMM1_num || reg == XMM1b_num || 1713 reg == XMM2_num || reg == XMM2b_num || 1714 reg == XMM3_num || reg == XMM3b_num || 1715 reg == XMM4_num || reg == XMM4b_num || 1716 reg == XMM5_num || reg == XMM5b_num || 1717 reg == XMM6_num || reg == XMM6b_num || 1718 reg == XMM7_num || reg == XMM7b_num; 1719 } 1720 1721 bool Matcher::is_spillable_arg(int reg) 1722 { 1723 return can_be_java_arg(reg); 1724 } 1725 1726 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1727 // In 64 bit mode a code which use multiply when 1728 // devisor is constant is faster than hardware 1729 // DIV instruction (it uses MulHiL). 1730 return false; 1731 } 1732 1733 // Register for DIVI projection of divmodI 1734 RegMask Matcher::divI_proj_mask() { 1735 return INT_RAX_REG_mask(); 1736 } 1737 1738 // Register for MODI projection of divmodI 1739 RegMask Matcher::modI_proj_mask() { 1740 return INT_RDX_REG_mask(); 1741 } 1742 1743 // Register for DIVL projection of divmodL 1744 RegMask Matcher::divL_proj_mask() { 1745 return LONG_RAX_REG_mask(); 1746 } 1747 1748 // Register for MODL projection of divmodL 1749 RegMask Matcher::modL_proj_mask() { 1750 return LONG_RDX_REG_mask(); 1751 } 1752 1753 // Register for saving SP into on method handle invokes. Not used on x86_64. 1754 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1755 return NO_REG_mask(); 1756 } 1757 1758 %} 1759 1760 //----------ENCODING BLOCK----------------------------------------------------- 1761 // This block specifies the encoding classes used by the compiler to 1762 // output byte streams. Encoding classes are parameterized macros 1763 // used by Machine Instruction Nodes in order to generate the bit 1764 // encoding of the instruction. Operands specify their base encoding 1765 // interface with the interface keyword. There are currently 1766 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1767 // COND_INTER. REG_INTER causes an operand to generate a function 1768 // which returns its register number when queried. CONST_INTER causes 1769 // an operand to generate a function which returns the value of the 1770 // constant when queried. MEMORY_INTER causes an operand to generate 1771 // four functions which return the Base Register, the Index Register, 1772 // the Scale Value, and the Offset Value of the operand when queried. 1773 // COND_INTER causes an operand to generate six functions which return 1774 // the encoding code (ie - encoding bits for the instruction) 1775 // associated with each basic boolean condition for a conditional 1776 // instruction. 1777 // 1778 // Instructions specify two basic values for encoding. Again, a 1779 // function is available to check if the constant displacement is an 1780 // oop. They use the ins_encode keyword to specify their encoding 1781 // classes (which must be a sequence of enc_class names, and their 1782 // parameters, specified in the encoding block), and they use the 1783 // opcode keyword to specify, in order, their primary, secondary, and 1784 // tertiary opcode. Only the opcode sections which a particular 1785 // instruction needs for encoding need to be specified. 1786 encode %{ 1787 // Build emit functions for each basic byte or larger field in the 1788 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1789 // from C++ code in the enc_class source block. Emit functions will 1790 // live in the main source block for now. In future, we can 1791 // generalize this by adding a syntax that specifies the sizes of 1792 // fields in an order, so that the adlc can build the emit functions 1793 // automagically 1794 1795 // Emit primary opcode 1796 enc_class OpcP 1797 %{ 1798 emit_opcode(cbuf, $primary); 1799 %} 1800 1801 // Emit secondary opcode 1802 enc_class OpcS 1803 %{ 1804 emit_opcode(cbuf, $secondary); 1805 %} 1806 1807 // Emit tertiary opcode 1808 enc_class OpcT 1809 %{ 1810 emit_opcode(cbuf, $tertiary); 1811 %} 1812 1813 // Emit opcode directly 1814 enc_class Opcode(immI d8) 1815 %{ 1816 emit_opcode(cbuf, $d8$$constant); 1817 %} 1818 1819 // Emit size prefix 1820 enc_class SizePrefix 1821 %{ 1822 emit_opcode(cbuf, 0x66); 1823 %} 1824 1825 enc_class reg(rRegI reg) 1826 %{ 1827 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1828 %} 1829 1830 enc_class reg_reg(rRegI dst, rRegI src) 1831 %{ 1832 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1833 %} 1834 1835 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1836 %{ 1837 emit_opcode(cbuf, $opcode$$constant); 1838 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1839 %} 1840 1841 enc_class cdql_enc(no_rax_rdx_RegI div) 1842 %{ 1843 // Full implementation of Java idiv and irem; checks for 1844 // special case as described in JVM spec., p.243 & p.271. 1845 // 1846 // normal case special case 1847 // 1848 // input : rax: dividend min_int 1849 // reg: divisor -1 1850 // 1851 // output: rax: quotient (= rax idiv reg) min_int 1852 // rdx: remainder (= rax irem reg) 0 1853 // 1854 // Code sequnce: 1855 // 1856 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1857 // 5: 75 07/08 jne e <normal> 1858 // 7: 33 d2 xor %edx,%edx 1859 // [div >= 8 -> offset + 1] 1860 // [REX_B] 1861 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1862 // c: 74 03/04 je 11 <done> 1863 // 000000000000000e <normal>: 1864 // e: 99 cltd 1865 // [div >= 8 -> offset + 1] 1866 // [REX_B] 1867 // f: f7 f9 idiv $div 1868 // 0000000000000011 <done>: 1869 1870 // cmp $0x80000000,%eax 1871 emit_opcode(cbuf, 0x3d); 1872 emit_d8(cbuf, 0x00); 1873 emit_d8(cbuf, 0x00); 1874 emit_d8(cbuf, 0x00); 1875 emit_d8(cbuf, 0x80); 1876 1877 // jne e <normal> 1878 emit_opcode(cbuf, 0x75); 1879 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1880 1881 // xor %edx,%edx 1882 emit_opcode(cbuf, 0x33); 1883 emit_d8(cbuf, 0xD2); 1884 1885 // cmp $0xffffffffffffffff,%ecx 1886 if ($div$$reg >= 8) { 1887 emit_opcode(cbuf, Assembler::REX_B); 1888 } 1889 emit_opcode(cbuf, 0x83); 1890 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1891 emit_d8(cbuf, 0xFF); 1892 1893 // je 11 <done> 1894 emit_opcode(cbuf, 0x74); 1895 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1896 1897 // <normal> 1898 // cltd 1899 emit_opcode(cbuf, 0x99); 1900 1901 // idivl (note: must be emitted by the user of this rule) 1902 // <done> 1903 %} 1904 1905 enc_class cdqq_enc(no_rax_rdx_RegL div) 1906 %{ 1907 // Full implementation of Java ldiv and lrem; checks for 1908 // special case as described in JVM spec., p.243 & p.271. 1909 // 1910 // normal case special case 1911 // 1912 // input : rax: dividend min_long 1913 // reg: divisor -1 1914 // 1915 // output: rax: quotient (= rax idiv reg) min_long 1916 // rdx: remainder (= rax irem reg) 0 1917 // 1918 // Code sequnce: 1919 // 1920 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1921 // 7: 00 00 80 1922 // a: 48 39 d0 cmp %rdx,%rax 1923 // d: 75 08 jne 17 <normal> 1924 // f: 33 d2 xor %edx,%edx 1925 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1926 // 15: 74 05 je 1c <done> 1927 // 0000000000000017 <normal>: 1928 // 17: 48 99 cqto 1929 // 19: 48 f7 f9 idiv $div 1930 // 000000000000001c <done>: 1931 1932 // mov $0x8000000000000000,%rdx 1933 emit_opcode(cbuf, Assembler::REX_W); 1934 emit_opcode(cbuf, 0xBA); 1935 emit_d8(cbuf, 0x00); 1936 emit_d8(cbuf, 0x00); 1937 emit_d8(cbuf, 0x00); 1938 emit_d8(cbuf, 0x00); 1939 emit_d8(cbuf, 0x00); 1940 emit_d8(cbuf, 0x00); 1941 emit_d8(cbuf, 0x00); 1942 emit_d8(cbuf, 0x80); 1943 1944 // cmp %rdx,%rax 1945 emit_opcode(cbuf, Assembler::REX_W); 1946 emit_opcode(cbuf, 0x39); 1947 emit_d8(cbuf, 0xD0); 1948 1949 // jne 17 <normal> 1950 emit_opcode(cbuf, 0x75); 1951 emit_d8(cbuf, 0x08); 1952 1953 // xor %edx,%edx 1954 emit_opcode(cbuf, 0x33); 1955 emit_d8(cbuf, 0xD2); 1956 1957 // cmp $0xffffffffffffffff,$div 1958 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1959 emit_opcode(cbuf, 0x83); 1960 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1961 emit_d8(cbuf, 0xFF); 1962 1963 // je 1e <done> 1964 emit_opcode(cbuf, 0x74); 1965 emit_d8(cbuf, 0x05); 1966 1967 // <normal> 1968 // cqto 1969 emit_opcode(cbuf, Assembler::REX_W); 1970 emit_opcode(cbuf, 0x99); 1971 1972 // idivq (note: must be emitted by the user of this rule) 1973 // <done> 1974 %} 1975 1976 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1977 enc_class OpcSE(immI imm) 1978 %{ 1979 // Emit primary opcode and set sign-extend bit 1980 // Check for 8-bit immediate, and set sign extend bit in opcode 1981 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1982 emit_opcode(cbuf, $primary | 0x02); 1983 } else { 1984 // 32-bit immediate 1985 emit_opcode(cbuf, $primary); 1986 } 1987 %} 1988 1989 enc_class OpcSErm(rRegI dst, immI imm) 1990 %{ 1991 // OpcSEr/m 1992 int dstenc = $dst$$reg; 1993 if (dstenc >= 8) { 1994 emit_opcode(cbuf, Assembler::REX_B); 1995 dstenc -= 8; 1996 } 1997 // Emit primary opcode and set sign-extend bit 1998 // Check for 8-bit immediate, and set sign extend bit in opcode 1999 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2000 emit_opcode(cbuf, $primary | 0x02); 2001 } else { 2002 // 32-bit immediate 2003 emit_opcode(cbuf, $primary); 2004 } 2005 // Emit r/m byte with secondary opcode, after primary opcode. 2006 emit_rm(cbuf, 0x3, $secondary, dstenc); 2007 %} 2008 2009 enc_class OpcSErm_wide(rRegL dst, immI imm) 2010 %{ 2011 // OpcSEr/m 2012 int dstenc = $dst$$reg; 2013 if (dstenc < 8) { 2014 emit_opcode(cbuf, Assembler::REX_W); 2015 } else { 2016 emit_opcode(cbuf, Assembler::REX_WB); 2017 dstenc -= 8; 2018 } 2019 // Emit primary opcode and set sign-extend bit 2020 // Check for 8-bit immediate, and set sign extend bit in opcode 2021 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2022 emit_opcode(cbuf, $primary | 0x02); 2023 } else { 2024 // 32-bit immediate 2025 emit_opcode(cbuf, $primary); 2026 } 2027 // Emit r/m byte with secondary opcode, after primary opcode. 2028 emit_rm(cbuf, 0x3, $secondary, dstenc); 2029 %} 2030 2031 enc_class Con8or32(immI imm) 2032 %{ 2033 // Check for 8-bit immediate, and set sign extend bit in opcode 2034 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2035 $$$emit8$imm$$constant; 2036 } else { 2037 // 32-bit immediate 2038 $$$emit32$imm$$constant; 2039 } 2040 %} 2041 2042 enc_class opc2_reg(rRegI dst) 2043 %{ 2044 // BSWAP 2045 emit_cc(cbuf, $secondary, $dst$$reg); 2046 %} 2047 2048 enc_class opc3_reg(rRegI dst) 2049 %{ 2050 // BSWAP 2051 emit_cc(cbuf, $tertiary, $dst$$reg); 2052 %} 2053 2054 enc_class reg_opc(rRegI div) 2055 %{ 2056 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2057 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2058 %} 2059 2060 enc_class enc_cmov(cmpOp cop) 2061 %{ 2062 // CMOV 2063 $$$emit8$primary; 2064 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2065 %} 2066 2067 enc_class enc_PartialSubtypeCheck() 2068 %{ 2069 Register Rrdi = as_Register(RDI_enc); // result register 2070 Register Rrax = as_Register(RAX_enc); // super class 2071 Register Rrcx = as_Register(RCX_enc); // killed 2072 Register Rrsi = as_Register(RSI_enc); // sub class 2073 Label miss; 2074 const bool set_cond_codes = true; 2075 2076 MacroAssembler _masm(&cbuf); 2077 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2078 NULL, &miss, 2079 /*set_cond_codes:*/ true); 2080 if ($primary) { 2081 __ xorptr(Rrdi, Rrdi); 2082 } 2083 __ bind(miss); 2084 %} 2085 2086 enc_class clear_avx %{ 2087 debug_only(int off0 = cbuf.insts_size()); 2088 if (ra_->C->max_vector_size() > 16) { 2089 // Clear upper bits of YMM registers when current compiled code uses 2090 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2091 MacroAssembler _masm(&cbuf); 2092 __ vzeroupper(); 2093 } 2094 debug_only(int off1 = cbuf.insts_size()); 2095 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2096 %} 2097 2098 enc_class Java_To_Runtime(method meth) %{ 2099 // No relocation needed 2100 MacroAssembler _masm(&cbuf); 2101 __ mov64(r10, (int64_t) $meth$$method); 2102 __ call(r10); 2103 %} 2104 2105 enc_class Java_To_Interpreter(method meth) 2106 %{ 2107 // CALL Java_To_Interpreter 2108 // This is the instruction starting address for relocation info. 2109 cbuf.set_insts_mark(); 2110 $$$emit8$primary; 2111 // CALL directly to the runtime 2112 emit_d32_reloc(cbuf, 2113 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2114 runtime_call_Relocation::spec(), 2115 RELOC_DISP32); 2116 %} 2117 2118 enc_class Java_Static_Call(method meth) 2119 %{ 2120 // JAVA STATIC CALL 2121 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2122 // determine who we intended to call. 2123 cbuf.set_insts_mark(); 2124 $$$emit8$primary; 2125 2126 if (!_method) { 2127 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2128 runtime_call_Relocation::spec(), 2129 RELOC_DISP32); 2130 } else { 2131 int method_index = resolved_method_index(cbuf); 2132 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2133 : static_call_Relocation::spec(method_index); 2134 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2135 rspec, RELOC_DISP32); 2136 // Emit stubs for static call. 2137 address mark = cbuf.insts_mark(); 2138 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2139 if (stub == NULL) { 2140 ciEnv::current()->record_failure("CodeCache is full"); 2141 return; 2142 } 2143 } 2144 %} 2145 2146 enc_class Java_Dynamic_Call(method meth) %{ 2147 MacroAssembler _masm(&cbuf); 2148 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2149 %} 2150 2151 enc_class Java_Compiled_Call(method meth) 2152 %{ 2153 // JAVA COMPILED CALL 2154 int disp = in_bytes(Method:: from_compiled_offset()); 2155 2156 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2157 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2158 2159 // callq *disp(%rax) 2160 cbuf.set_insts_mark(); 2161 $$$emit8$primary; 2162 if (disp < 0x80) { 2163 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2164 emit_d8(cbuf, disp); // Displacement 2165 } else { 2166 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2167 emit_d32(cbuf, disp); // Displacement 2168 } 2169 %} 2170 2171 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2172 %{ 2173 // SAL, SAR, SHR 2174 int dstenc = $dst$$reg; 2175 if (dstenc >= 8) { 2176 emit_opcode(cbuf, Assembler::REX_B); 2177 dstenc -= 8; 2178 } 2179 $$$emit8$primary; 2180 emit_rm(cbuf, 0x3, $secondary, dstenc); 2181 $$$emit8$shift$$constant; 2182 %} 2183 2184 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2185 %{ 2186 // SAL, SAR, SHR 2187 int dstenc = $dst$$reg; 2188 if (dstenc < 8) { 2189 emit_opcode(cbuf, Assembler::REX_W); 2190 } else { 2191 emit_opcode(cbuf, Assembler::REX_WB); 2192 dstenc -= 8; 2193 } 2194 $$$emit8$primary; 2195 emit_rm(cbuf, 0x3, $secondary, dstenc); 2196 $$$emit8$shift$$constant; 2197 %} 2198 2199 enc_class load_immI(rRegI dst, immI src) 2200 %{ 2201 int dstenc = $dst$$reg; 2202 if (dstenc >= 8) { 2203 emit_opcode(cbuf, Assembler::REX_B); 2204 dstenc -= 8; 2205 } 2206 emit_opcode(cbuf, 0xB8 | dstenc); 2207 $$$emit32$src$$constant; 2208 %} 2209 2210 enc_class load_immL(rRegL dst, immL src) 2211 %{ 2212 int dstenc = $dst$$reg; 2213 if (dstenc < 8) { 2214 emit_opcode(cbuf, Assembler::REX_W); 2215 } else { 2216 emit_opcode(cbuf, Assembler::REX_WB); 2217 dstenc -= 8; 2218 } 2219 emit_opcode(cbuf, 0xB8 | dstenc); 2220 emit_d64(cbuf, $src$$constant); 2221 %} 2222 2223 enc_class load_immUL32(rRegL dst, immUL32 src) 2224 %{ 2225 // same as load_immI, but this time we care about zeroes in the high word 2226 int dstenc = $dst$$reg; 2227 if (dstenc >= 8) { 2228 emit_opcode(cbuf, Assembler::REX_B); 2229 dstenc -= 8; 2230 } 2231 emit_opcode(cbuf, 0xB8 | dstenc); 2232 $$$emit32$src$$constant; 2233 %} 2234 2235 enc_class load_immL32(rRegL dst, immL32 src) 2236 %{ 2237 int dstenc = $dst$$reg; 2238 if (dstenc < 8) { 2239 emit_opcode(cbuf, Assembler::REX_W); 2240 } else { 2241 emit_opcode(cbuf, Assembler::REX_WB); 2242 dstenc -= 8; 2243 } 2244 emit_opcode(cbuf, 0xC7); 2245 emit_rm(cbuf, 0x03, 0x00, dstenc); 2246 $$$emit32$src$$constant; 2247 %} 2248 2249 enc_class load_immP31(rRegP dst, immP32 src) 2250 %{ 2251 // same as load_immI, but this time we care about zeroes in the high word 2252 int dstenc = $dst$$reg; 2253 if (dstenc >= 8) { 2254 emit_opcode(cbuf, Assembler::REX_B); 2255 dstenc -= 8; 2256 } 2257 emit_opcode(cbuf, 0xB8 | dstenc); 2258 $$$emit32$src$$constant; 2259 %} 2260 2261 enc_class load_immP(rRegP dst, immP src) 2262 %{ 2263 int dstenc = $dst$$reg; 2264 if (dstenc < 8) { 2265 emit_opcode(cbuf, Assembler::REX_W); 2266 } else { 2267 emit_opcode(cbuf, Assembler::REX_WB); 2268 dstenc -= 8; 2269 } 2270 emit_opcode(cbuf, 0xB8 | dstenc); 2271 // This next line should be generated from ADLC 2272 if ($src->constant_reloc() != relocInfo::none) { 2273 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2274 } else { 2275 emit_d64(cbuf, $src$$constant); 2276 } 2277 %} 2278 2279 enc_class Con32(immI src) 2280 %{ 2281 // Output immediate 2282 $$$emit32$src$$constant; 2283 %} 2284 2285 enc_class Con32F_as_bits(immF src) 2286 %{ 2287 // Output Float immediate bits 2288 jfloat jf = $src$$constant; 2289 jint jf_as_bits = jint_cast(jf); 2290 emit_d32(cbuf, jf_as_bits); 2291 %} 2292 2293 enc_class Con16(immI src) 2294 %{ 2295 // Output immediate 2296 $$$emit16$src$$constant; 2297 %} 2298 2299 // How is this different from Con32??? XXX 2300 enc_class Con_d32(immI src) 2301 %{ 2302 emit_d32(cbuf,$src$$constant); 2303 %} 2304 2305 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2306 // Output immediate memory reference 2307 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2308 emit_d32(cbuf, 0x00); 2309 %} 2310 2311 enc_class lock_prefix() 2312 %{ 2313 if (os::is_MP()) { 2314 emit_opcode(cbuf, 0xF0); // lock 2315 } 2316 %} 2317 2318 enc_class REX_mem(memory mem) 2319 %{ 2320 if ($mem$$base >= 8) { 2321 if ($mem$$index < 8) { 2322 emit_opcode(cbuf, Assembler::REX_B); 2323 } else { 2324 emit_opcode(cbuf, Assembler::REX_XB); 2325 } 2326 } else { 2327 if ($mem$$index >= 8) { 2328 emit_opcode(cbuf, Assembler::REX_X); 2329 } 2330 } 2331 %} 2332 2333 enc_class REX_mem_wide(memory mem) 2334 %{ 2335 if ($mem$$base >= 8) { 2336 if ($mem$$index < 8) { 2337 emit_opcode(cbuf, Assembler::REX_WB); 2338 } else { 2339 emit_opcode(cbuf, Assembler::REX_WXB); 2340 } 2341 } else { 2342 if ($mem$$index < 8) { 2343 emit_opcode(cbuf, Assembler::REX_W); 2344 } else { 2345 emit_opcode(cbuf, Assembler::REX_WX); 2346 } 2347 } 2348 %} 2349 2350 // for byte regs 2351 enc_class REX_breg(rRegI reg) 2352 %{ 2353 if ($reg$$reg >= 4) { 2354 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2355 } 2356 %} 2357 2358 // for byte regs 2359 enc_class REX_reg_breg(rRegI dst, rRegI src) 2360 %{ 2361 if ($dst$$reg < 8) { 2362 if ($src$$reg >= 4) { 2363 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2364 } 2365 } else { 2366 if ($src$$reg < 8) { 2367 emit_opcode(cbuf, Assembler::REX_R); 2368 } else { 2369 emit_opcode(cbuf, Assembler::REX_RB); 2370 } 2371 } 2372 %} 2373 2374 // for byte regs 2375 enc_class REX_breg_mem(rRegI reg, memory mem) 2376 %{ 2377 if ($reg$$reg < 8) { 2378 if ($mem$$base < 8) { 2379 if ($mem$$index >= 8) { 2380 emit_opcode(cbuf, Assembler::REX_X); 2381 } else if ($reg$$reg >= 4) { 2382 emit_opcode(cbuf, Assembler::REX); 2383 } 2384 } else { 2385 if ($mem$$index < 8) { 2386 emit_opcode(cbuf, Assembler::REX_B); 2387 } else { 2388 emit_opcode(cbuf, Assembler::REX_XB); 2389 } 2390 } 2391 } else { 2392 if ($mem$$base < 8) { 2393 if ($mem$$index < 8) { 2394 emit_opcode(cbuf, Assembler::REX_R); 2395 } else { 2396 emit_opcode(cbuf, Assembler::REX_RX); 2397 } 2398 } else { 2399 if ($mem$$index < 8) { 2400 emit_opcode(cbuf, Assembler::REX_RB); 2401 } else { 2402 emit_opcode(cbuf, Assembler::REX_RXB); 2403 } 2404 } 2405 } 2406 %} 2407 2408 enc_class REX_reg(rRegI reg) 2409 %{ 2410 if ($reg$$reg >= 8) { 2411 emit_opcode(cbuf, Assembler::REX_B); 2412 } 2413 %} 2414 2415 enc_class REX_reg_wide(rRegI reg) 2416 %{ 2417 if ($reg$$reg < 8) { 2418 emit_opcode(cbuf, Assembler::REX_W); 2419 } else { 2420 emit_opcode(cbuf, Assembler::REX_WB); 2421 } 2422 %} 2423 2424 enc_class REX_reg_reg(rRegI dst, rRegI src) 2425 %{ 2426 if ($dst$$reg < 8) { 2427 if ($src$$reg >= 8) { 2428 emit_opcode(cbuf, Assembler::REX_B); 2429 } 2430 } else { 2431 if ($src$$reg < 8) { 2432 emit_opcode(cbuf, Assembler::REX_R); 2433 } else { 2434 emit_opcode(cbuf, Assembler::REX_RB); 2435 } 2436 } 2437 %} 2438 2439 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2440 %{ 2441 if ($dst$$reg < 8) { 2442 if ($src$$reg < 8) { 2443 emit_opcode(cbuf, Assembler::REX_W); 2444 } else { 2445 emit_opcode(cbuf, Assembler::REX_WB); 2446 } 2447 } else { 2448 if ($src$$reg < 8) { 2449 emit_opcode(cbuf, Assembler::REX_WR); 2450 } else { 2451 emit_opcode(cbuf, Assembler::REX_WRB); 2452 } 2453 } 2454 %} 2455 2456 enc_class REX_reg_mem(rRegI reg, memory mem) 2457 %{ 2458 if ($reg$$reg < 8) { 2459 if ($mem$$base < 8) { 2460 if ($mem$$index >= 8) { 2461 emit_opcode(cbuf, Assembler::REX_X); 2462 } 2463 } else { 2464 if ($mem$$index < 8) { 2465 emit_opcode(cbuf, Assembler::REX_B); 2466 } else { 2467 emit_opcode(cbuf, Assembler::REX_XB); 2468 } 2469 } 2470 } else { 2471 if ($mem$$base < 8) { 2472 if ($mem$$index < 8) { 2473 emit_opcode(cbuf, Assembler::REX_R); 2474 } else { 2475 emit_opcode(cbuf, Assembler::REX_RX); 2476 } 2477 } else { 2478 if ($mem$$index < 8) { 2479 emit_opcode(cbuf, Assembler::REX_RB); 2480 } else { 2481 emit_opcode(cbuf, Assembler::REX_RXB); 2482 } 2483 } 2484 } 2485 %} 2486 2487 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2488 %{ 2489 if ($reg$$reg < 8) { 2490 if ($mem$$base < 8) { 2491 if ($mem$$index < 8) { 2492 emit_opcode(cbuf, Assembler::REX_W); 2493 } else { 2494 emit_opcode(cbuf, Assembler::REX_WX); 2495 } 2496 } else { 2497 if ($mem$$index < 8) { 2498 emit_opcode(cbuf, Assembler::REX_WB); 2499 } else { 2500 emit_opcode(cbuf, Assembler::REX_WXB); 2501 } 2502 } 2503 } else { 2504 if ($mem$$base < 8) { 2505 if ($mem$$index < 8) { 2506 emit_opcode(cbuf, Assembler::REX_WR); 2507 } else { 2508 emit_opcode(cbuf, Assembler::REX_WRX); 2509 } 2510 } else { 2511 if ($mem$$index < 8) { 2512 emit_opcode(cbuf, Assembler::REX_WRB); 2513 } else { 2514 emit_opcode(cbuf, Assembler::REX_WRXB); 2515 } 2516 } 2517 } 2518 %} 2519 2520 enc_class reg_mem(rRegI ereg, memory mem) 2521 %{ 2522 // High registers handle in encode_RegMem 2523 int reg = $ereg$$reg; 2524 int base = $mem$$base; 2525 int index = $mem$$index; 2526 int scale = $mem$$scale; 2527 int disp = $mem$$disp; 2528 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2529 2530 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2531 %} 2532 2533 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2534 %{ 2535 int rm_byte_opcode = $rm_opcode$$constant; 2536 2537 // High registers handle in encode_RegMem 2538 int base = $mem$$base; 2539 int index = $mem$$index; 2540 int scale = $mem$$scale; 2541 int displace = $mem$$disp; 2542 2543 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2544 // working with static 2545 // globals 2546 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2547 disp_reloc); 2548 %} 2549 2550 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2551 %{ 2552 int reg_encoding = $dst$$reg; 2553 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2554 int index = 0x04; // 0x04 indicates no index 2555 int scale = 0x00; // 0x00 indicates no scale 2556 int displace = $src1$$constant; // 0x00 indicates no displacement 2557 relocInfo::relocType disp_reloc = relocInfo::none; 2558 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2559 disp_reloc); 2560 %} 2561 2562 enc_class neg_reg(rRegI dst) 2563 %{ 2564 int dstenc = $dst$$reg; 2565 if (dstenc >= 8) { 2566 emit_opcode(cbuf, Assembler::REX_B); 2567 dstenc -= 8; 2568 } 2569 // NEG $dst 2570 emit_opcode(cbuf, 0xF7); 2571 emit_rm(cbuf, 0x3, 0x03, dstenc); 2572 %} 2573 2574 enc_class neg_reg_wide(rRegI dst) 2575 %{ 2576 int dstenc = $dst$$reg; 2577 if (dstenc < 8) { 2578 emit_opcode(cbuf, Assembler::REX_W); 2579 } else { 2580 emit_opcode(cbuf, Assembler::REX_WB); 2581 dstenc -= 8; 2582 } 2583 // NEG $dst 2584 emit_opcode(cbuf, 0xF7); 2585 emit_rm(cbuf, 0x3, 0x03, dstenc); 2586 %} 2587 2588 enc_class setLT_reg(rRegI dst) 2589 %{ 2590 int dstenc = $dst$$reg; 2591 if (dstenc >= 8) { 2592 emit_opcode(cbuf, Assembler::REX_B); 2593 dstenc -= 8; 2594 } else if (dstenc >= 4) { 2595 emit_opcode(cbuf, Assembler::REX); 2596 } 2597 // SETLT $dst 2598 emit_opcode(cbuf, 0x0F); 2599 emit_opcode(cbuf, 0x9C); 2600 emit_rm(cbuf, 0x3, 0x0, dstenc); 2601 %} 2602 2603 enc_class setNZ_reg(rRegI dst) 2604 %{ 2605 int dstenc = $dst$$reg; 2606 if (dstenc >= 8) { 2607 emit_opcode(cbuf, Assembler::REX_B); 2608 dstenc -= 8; 2609 } else if (dstenc >= 4) { 2610 emit_opcode(cbuf, Assembler::REX); 2611 } 2612 // SETNZ $dst 2613 emit_opcode(cbuf, 0x0F); 2614 emit_opcode(cbuf, 0x95); 2615 emit_rm(cbuf, 0x3, 0x0, dstenc); 2616 %} 2617 2618 2619 // Compare the lonogs and set -1, 0, or 1 into dst 2620 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2621 %{ 2622 int src1enc = $src1$$reg; 2623 int src2enc = $src2$$reg; 2624 int dstenc = $dst$$reg; 2625 2626 // cmpq $src1, $src2 2627 if (src1enc < 8) { 2628 if (src2enc < 8) { 2629 emit_opcode(cbuf, Assembler::REX_W); 2630 } else { 2631 emit_opcode(cbuf, Assembler::REX_WB); 2632 } 2633 } else { 2634 if (src2enc < 8) { 2635 emit_opcode(cbuf, Assembler::REX_WR); 2636 } else { 2637 emit_opcode(cbuf, Assembler::REX_WRB); 2638 } 2639 } 2640 emit_opcode(cbuf, 0x3B); 2641 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2642 2643 // movl $dst, -1 2644 if (dstenc >= 8) { 2645 emit_opcode(cbuf, Assembler::REX_B); 2646 } 2647 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2648 emit_d32(cbuf, -1); 2649 2650 // jl,s done 2651 emit_opcode(cbuf, 0x7C); 2652 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2653 2654 // setne $dst 2655 if (dstenc >= 4) { 2656 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2657 } 2658 emit_opcode(cbuf, 0x0F); 2659 emit_opcode(cbuf, 0x95); 2660 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2661 2662 // movzbl $dst, $dst 2663 if (dstenc >= 4) { 2664 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2665 } 2666 emit_opcode(cbuf, 0x0F); 2667 emit_opcode(cbuf, 0xB6); 2668 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2669 %} 2670 2671 enc_class Push_ResultXD(regD dst) %{ 2672 MacroAssembler _masm(&cbuf); 2673 __ fstp_d(Address(rsp, 0)); 2674 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2675 __ addptr(rsp, 8); 2676 %} 2677 2678 enc_class Push_SrcXD(regD src) %{ 2679 MacroAssembler _masm(&cbuf); 2680 __ subptr(rsp, 8); 2681 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2682 __ fld_d(Address(rsp, 0)); 2683 %} 2684 2685 2686 enc_class enc_rethrow() 2687 %{ 2688 cbuf.set_insts_mark(); 2689 emit_opcode(cbuf, 0xE9); // jmp entry 2690 emit_d32_reloc(cbuf, 2691 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2692 runtime_call_Relocation::spec(), 2693 RELOC_DISP32); 2694 %} 2695 2696 enc_class shenandoah_store_check(memory mem, any_RegP src) %{ 2697 MacroAssembler _masm(&cbuf); 2698 __ shenandoah_store_check($mem$$Address, $src$$Register); 2699 %} 2700 2701 enc_class shenandoah_store_addr_check(memory mem) %{ 2702 MacroAssembler _masm(&cbuf); 2703 __ shenandoah_store_addr_check($mem$$Address); 2704 %} 2705 %} 2706 2707 2708 2709 //----------FRAME-------------------------------------------------------------- 2710 // Definition of frame structure and management information. 2711 // 2712 // S T A C K L A Y O U T Allocators stack-slot number 2713 // | (to get allocators register number 2714 // G Owned by | | v add OptoReg::stack0()) 2715 // r CALLER | | 2716 // o | +--------+ pad to even-align allocators stack-slot 2717 // w V | pad0 | numbers; owned by CALLER 2718 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2719 // h ^ | in | 5 2720 // | | args | 4 Holes in incoming args owned by SELF 2721 // | | | | 3 2722 // | | +--------+ 2723 // V | | old out| Empty on Intel, window on Sparc 2724 // | old |preserve| Must be even aligned. 2725 // | SP-+--------+----> Matcher::_old_SP, even aligned 2726 // | | in | 3 area for Intel ret address 2727 // Owned by |preserve| Empty on Sparc. 2728 // SELF +--------+ 2729 // | | pad2 | 2 pad to align old SP 2730 // | +--------+ 1 2731 // | | locks | 0 2732 // | +--------+----> OptoReg::stack0(), even aligned 2733 // | | pad1 | 11 pad to align new SP 2734 // | +--------+ 2735 // | | | 10 2736 // | | spills | 9 spills 2737 // V | | 8 (pad0 slot for callee) 2738 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2739 // ^ | out | 7 2740 // | | args | 6 Holes in outgoing args owned by CALLEE 2741 // Owned by +--------+ 2742 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2743 // | new |preserve| Must be even-aligned. 2744 // | SP-+--------+----> Matcher::_new_SP, even aligned 2745 // | | | 2746 // 2747 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2748 // known from SELF's arguments and the Java calling convention. 2749 // Region 6-7 is determined per call site. 2750 // Note 2: If the calling convention leaves holes in the incoming argument 2751 // area, those holes are owned by SELF. Holes in the outgoing area 2752 // are owned by the CALLEE. Holes should not be nessecary in the 2753 // incoming area, as the Java calling convention is completely under 2754 // the control of the AD file. Doubles can be sorted and packed to 2755 // avoid holes. Holes in the outgoing arguments may be nessecary for 2756 // varargs C calling conventions. 2757 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2758 // even aligned with pad0 as needed. 2759 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2760 // region 6-11 is even aligned; it may be padded out more so that 2761 // the region from SP to FP meets the minimum stack alignment. 2762 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2763 // alignment. Region 11, pad1, may be dynamically extended so that 2764 // SP meets the minimum alignment. 2765 2766 frame 2767 %{ 2768 // What direction does stack grow in (assumed to be same for C & Java) 2769 stack_direction(TOWARDS_LOW); 2770 2771 // These three registers define part of the calling convention 2772 // between compiled code and the interpreter. 2773 inline_cache_reg(RAX); // Inline Cache Register 2774 interpreter_method_oop_reg(RBX); // Method Oop Register when 2775 // calling interpreter 2776 2777 // Optional: name the operand used by cisc-spilling to access 2778 // [stack_pointer + offset] 2779 cisc_spilling_operand_name(indOffset32); 2780 2781 // Number of stack slots consumed by locking an object 2782 sync_stack_slots(2); 2783 2784 // Compiled code's Frame Pointer 2785 frame_pointer(RSP); 2786 2787 // Interpreter stores its frame pointer in a register which is 2788 // stored to the stack by I2CAdaptors. 2789 // I2CAdaptors convert from interpreted java to compiled java. 2790 interpreter_frame_pointer(RBP); 2791 2792 // Stack alignment requirement 2793 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2794 2795 // Number of stack slots between incoming argument block and the start of 2796 // a new frame. The PROLOG must add this many slots to the stack. The 2797 // EPILOG must remove this many slots. amd64 needs two slots for 2798 // return address. 2799 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2800 2801 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2802 // for calls to C. Supports the var-args backing area for register parms. 2803 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2804 2805 // The after-PROLOG location of the return address. Location of 2806 // return address specifies a type (REG or STACK) and a number 2807 // representing the register number (i.e. - use a register name) or 2808 // stack slot. 2809 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2810 // Otherwise, it is above the locks and verification slot and alignment word 2811 return_addr(STACK - 2 + 2812 round_to((Compile::current()->in_preserve_stack_slots() + 2813 Compile::current()->fixed_slots()), 2814 stack_alignment_in_slots())); 2815 2816 // Body of function which returns an integer array locating 2817 // arguments either in registers or in stack slots. Passed an array 2818 // of ideal registers called "sig" and a "length" count. Stack-slot 2819 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2820 // arguments for a CALLEE. Incoming stack arguments are 2821 // automatically biased by the preserve_stack_slots field above. 2822 2823 calling_convention 2824 %{ 2825 // No difference between ingoing/outgoing just pass false 2826 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2827 %} 2828 2829 c_calling_convention 2830 %{ 2831 // This is obviously always outgoing 2832 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2833 %} 2834 2835 // Location of compiled Java return values. Same as C for now. 2836 return_value 2837 %{ 2838 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2839 "only return normal values"); 2840 2841 static const int lo[Op_RegL + 1] = { 2842 0, 2843 0, 2844 RAX_num, // Op_RegN 2845 RAX_num, // Op_RegI 2846 RAX_num, // Op_RegP 2847 XMM0_num, // Op_RegF 2848 XMM0_num, // Op_RegD 2849 RAX_num // Op_RegL 2850 }; 2851 static const int hi[Op_RegL + 1] = { 2852 0, 2853 0, 2854 OptoReg::Bad, // Op_RegN 2855 OptoReg::Bad, // Op_RegI 2856 RAX_H_num, // Op_RegP 2857 OptoReg::Bad, // Op_RegF 2858 XMM0b_num, // Op_RegD 2859 RAX_H_num // Op_RegL 2860 }; 2861 // Excluded flags and vector registers. 2862 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2863 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2864 %} 2865 %} 2866 2867 //----------ATTRIBUTES--------------------------------------------------------- 2868 //----------Operand Attributes------------------------------------------------- 2869 op_attrib op_cost(0); // Required cost attribute 2870 2871 //----------Instruction Attributes--------------------------------------------- 2872 ins_attrib ins_cost(100); // Required cost attribute 2873 ins_attrib ins_size(8); // Required size attribute (in bits) 2874 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2875 // a non-matching short branch variant 2876 // of some long branch? 2877 ins_attrib ins_alignment(1); // Required alignment attribute (must 2878 // be a power of 2) specifies the 2879 // alignment that some part of the 2880 // instruction (not necessarily the 2881 // start) requires. If > 1, a 2882 // compute_padding() function must be 2883 // provided for the instruction 2884 2885 //----------OPERANDS----------------------------------------------------------- 2886 // Operand definitions must precede instruction definitions for correct parsing 2887 // in the ADLC because operands constitute user defined types which are used in 2888 // instruction definitions. 2889 2890 //----------Simple Operands---------------------------------------------------- 2891 // Immediate Operands 2892 // Integer Immediate 2893 operand immI() 2894 %{ 2895 match(ConI); 2896 2897 op_cost(10); 2898 format %{ %} 2899 interface(CONST_INTER); 2900 %} 2901 2902 // Constant for test vs zero 2903 operand immI0() 2904 %{ 2905 predicate(n->get_int() == 0); 2906 match(ConI); 2907 2908 op_cost(0); 2909 format %{ %} 2910 interface(CONST_INTER); 2911 %} 2912 2913 // Constant for increment 2914 operand immI1() 2915 %{ 2916 predicate(n->get_int() == 1); 2917 match(ConI); 2918 2919 op_cost(0); 2920 format %{ %} 2921 interface(CONST_INTER); 2922 %} 2923 2924 // Constant for decrement 2925 operand immI_M1() 2926 %{ 2927 predicate(n->get_int() == -1); 2928 match(ConI); 2929 2930 op_cost(0); 2931 format %{ %} 2932 interface(CONST_INTER); 2933 %} 2934 2935 // Valid scale values for addressing modes 2936 operand immI2() 2937 %{ 2938 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2939 match(ConI); 2940 2941 format %{ %} 2942 interface(CONST_INTER); 2943 %} 2944 2945 operand immI8() 2946 %{ 2947 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2948 match(ConI); 2949 2950 op_cost(5); 2951 format %{ %} 2952 interface(CONST_INTER); 2953 %} 2954 2955 operand immI16() 2956 %{ 2957 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2958 match(ConI); 2959 2960 op_cost(10); 2961 format %{ %} 2962 interface(CONST_INTER); 2963 %} 2964 2965 // Int Immediate non-negative 2966 operand immU31() 2967 %{ 2968 predicate(n->get_int() >= 0); 2969 match(ConI); 2970 2971 op_cost(0); 2972 format %{ %} 2973 interface(CONST_INTER); 2974 %} 2975 2976 // Constant for long shifts 2977 operand immI_32() 2978 %{ 2979 predicate( n->get_int() == 32 ); 2980 match(ConI); 2981 2982 op_cost(0); 2983 format %{ %} 2984 interface(CONST_INTER); 2985 %} 2986 2987 // Constant for long shifts 2988 operand immI_64() 2989 %{ 2990 predicate( n->get_int() == 64 ); 2991 match(ConI); 2992 2993 op_cost(0); 2994 format %{ %} 2995 interface(CONST_INTER); 2996 %} 2997 2998 // Pointer Immediate 2999 operand immP() 3000 %{ 3001 match(ConP); 3002 3003 op_cost(10); 3004 format %{ %} 3005 interface(CONST_INTER); 3006 %} 3007 3008 // NULL Pointer Immediate 3009 operand immP0() 3010 %{ 3011 predicate(n->get_ptr() == 0); 3012 match(ConP); 3013 3014 op_cost(5); 3015 format %{ %} 3016 interface(CONST_INTER); 3017 %} 3018 3019 // Pointer Immediate 3020 operand immN() %{ 3021 match(ConN); 3022 3023 op_cost(10); 3024 format %{ %} 3025 interface(CONST_INTER); 3026 %} 3027 3028 operand immNKlass() %{ 3029 match(ConNKlass); 3030 3031 op_cost(10); 3032 format %{ %} 3033 interface(CONST_INTER); 3034 %} 3035 3036 // NULL Pointer Immediate 3037 operand immN0() %{ 3038 predicate(n->get_narrowcon() == 0); 3039 match(ConN); 3040 3041 op_cost(5); 3042 format %{ %} 3043 interface(CONST_INTER); 3044 %} 3045 3046 operand immP31() 3047 %{ 3048 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3049 && (n->get_ptr() >> 31) == 0); 3050 match(ConP); 3051 3052 op_cost(5); 3053 format %{ %} 3054 interface(CONST_INTER); 3055 %} 3056 3057 3058 // Long Immediate 3059 operand immL() 3060 %{ 3061 match(ConL); 3062 3063 op_cost(20); 3064 format %{ %} 3065 interface(CONST_INTER); 3066 %} 3067 3068 // Long Immediate 8-bit 3069 operand immL8() 3070 %{ 3071 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3072 match(ConL); 3073 3074 op_cost(5); 3075 format %{ %} 3076 interface(CONST_INTER); 3077 %} 3078 3079 // Long Immediate 32-bit unsigned 3080 operand immUL32() 3081 %{ 3082 predicate(n->get_long() == (unsigned int) (n->get_long())); 3083 match(ConL); 3084 3085 op_cost(10); 3086 format %{ %} 3087 interface(CONST_INTER); 3088 %} 3089 3090 // Long Immediate 32-bit signed 3091 operand immL32() 3092 %{ 3093 predicate(n->get_long() == (int) (n->get_long())); 3094 match(ConL); 3095 3096 op_cost(15); 3097 format %{ %} 3098 interface(CONST_INTER); 3099 %} 3100 3101 // Long Immediate zero 3102 operand immL0() 3103 %{ 3104 predicate(n->get_long() == 0L); 3105 match(ConL); 3106 3107 op_cost(10); 3108 format %{ %} 3109 interface(CONST_INTER); 3110 %} 3111 3112 // Constant for increment 3113 operand immL1() 3114 %{ 3115 predicate(n->get_long() == 1); 3116 match(ConL); 3117 3118 format %{ %} 3119 interface(CONST_INTER); 3120 %} 3121 3122 // Constant for decrement 3123 operand immL_M1() 3124 %{ 3125 predicate(n->get_long() == -1); 3126 match(ConL); 3127 3128 format %{ %} 3129 interface(CONST_INTER); 3130 %} 3131 3132 // Long Immediate: the value 10 3133 operand immL10() 3134 %{ 3135 predicate(n->get_long() == 10); 3136 match(ConL); 3137 3138 format %{ %} 3139 interface(CONST_INTER); 3140 %} 3141 3142 // Long immediate from 0 to 127. 3143 // Used for a shorter form of long mul by 10. 3144 operand immL_127() 3145 %{ 3146 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3147 match(ConL); 3148 3149 op_cost(10); 3150 format %{ %} 3151 interface(CONST_INTER); 3152 %} 3153 3154 // Long Immediate: low 32-bit mask 3155 operand immL_32bits() 3156 %{ 3157 predicate(n->get_long() == 0xFFFFFFFFL); 3158 match(ConL); 3159 op_cost(20); 3160 3161 format %{ %} 3162 interface(CONST_INTER); 3163 %} 3164 3165 // Float Immediate zero 3166 operand immF0() 3167 %{ 3168 predicate(jint_cast(n->getf()) == 0); 3169 match(ConF); 3170 3171 op_cost(5); 3172 format %{ %} 3173 interface(CONST_INTER); 3174 %} 3175 3176 // Float Immediate 3177 operand immF() 3178 %{ 3179 match(ConF); 3180 3181 op_cost(15); 3182 format %{ %} 3183 interface(CONST_INTER); 3184 %} 3185 3186 // Double Immediate zero 3187 operand immD0() 3188 %{ 3189 predicate(jlong_cast(n->getd()) == 0); 3190 match(ConD); 3191 3192 op_cost(5); 3193 format %{ %} 3194 interface(CONST_INTER); 3195 %} 3196 3197 // Double Immediate 3198 operand immD() 3199 %{ 3200 match(ConD); 3201 3202 op_cost(15); 3203 format %{ %} 3204 interface(CONST_INTER); 3205 %} 3206 3207 // Immediates for special shifts (sign extend) 3208 3209 // Constants for increment 3210 operand immI_16() 3211 %{ 3212 predicate(n->get_int() == 16); 3213 match(ConI); 3214 3215 format %{ %} 3216 interface(CONST_INTER); 3217 %} 3218 3219 operand immI_24() 3220 %{ 3221 predicate(n->get_int() == 24); 3222 match(ConI); 3223 3224 format %{ %} 3225 interface(CONST_INTER); 3226 %} 3227 3228 // Constant for byte-wide masking 3229 operand immI_255() 3230 %{ 3231 predicate(n->get_int() == 255); 3232 match(ConI); 3233 3234 format %{ %} 3235 interface(CONST_INTER); 3236 %} 3237 3238 // Constant for short-wide masking 3239 operand immI_65535() 3240 %{ 3241 predicate(n->get_int() == 65535); 3242 match(ConI); 3243 3244 format %{ %} 3245 interface(CONST_INTER); 3246 %} 3247 3248 // Constant for byte-wide masking 3249 operand immL_255() 3250 %{ 3251 predicate(n->get_long() == 255); 3252 match(ConL); 3253 3254 format %{ %} 3255 interface(CONST_INTER); 3256 %} 3257 3258 // Constant for short-wide masking 3259 operand immL_65535() 3260 %{ 3261 predicate(n->get_long() == 65535); 3262 match(ConL); 3263 3264 format %{ %} 3265 interface(CONST_INTER); 3266 %} 3267 3268 // Register Operands 3269 // Integer Register 3270 operand rRegI() 3271 %{ 3272 constraint(ALLOC_IN_RC(int_reg)); 3273 match(RegI); 3274 3275 match(rax_RegI); 3276 match(rbx_RegI); 3277 match(rcx_RegI); 3278 match(rdx_RegI); 3279 match(rdi_RegI); 3280 3281 format %{ %} 3282 interface(REG_INTER); 3283 %} 3284 3285 // Special Registers 3286 operand rax_RegI() 3287 %{ 3288 constraint(ALLOC_IN_RC(int_rax_reg)); 3289 match(RegI); 3290 match(rRegI); 3291 3292 format %{ "RAX" %} 3293 interface(REG_INTER); 3294 %} 3295 3296 // Special Registers 3297 operand rbx_RegI() 3298 %{ 3299 constraint(ALLOC_IN_RC(int_rbx_reg)); 3300 match(RegI); 3301 match(rRegI); 3302 3303 format %{ "RBX" %} 3304 interface(REG_INTER); 3305 %} 3306 3307 operand rcx_RegI() 3308 %{ 3309 constraint(ALLOC_IN_RC(int_rcx_reg)); 3310 match(RegI); 3311 match(rRegI); 3312 3313 format %{ "RCX" %} 3314 interface(REG_INTER); 3315 %} 3316 3317 operand rdx_RegI() 3318 %{ 3319 constraint(ALLOC_IN_RC(int_rdx_reg)); 3320 match(RegI); 3321 match(rRegI); 3322 3323 format %{ "RDX" %} 3324 interface(REG_INTER); 3325 %} 3326 3327 operand rdi_RegI() 3328 %{ 3329 constraint(ALLOC_IN_RC(int_rdi_reg)); 3330 match(RegI); 3331 match(rRegI); 3332 3333 format %{ "RDI" %} 3334 interface(REG_INTER); 3335 %} 3336 3337 operand no_rcx_RegI() 3338 %{ 3339 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3340 match(RegI); 3341 match(rax_RegI); 3342 match(rbx_RegI); 3343 match(rdx_RegI); 3344 match(rdi_RegI); 3345 3346 format %{ %} 3347 interface(REG_INTER); 3348 %} 3349 3350 operand no_rax_rdx_RegI() 3351 %{ 3352 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3353 match(RegI); 3354 match(rbx_RegI); 3355 match(rcx_RegI); 3356 match(rdi_RegI); 3357 3358 format %{ %} 3359 interface(REG_INTER); 3360 %} 3361 3362 // Pointer Register 3363 operand any_RegP() 3364 %{ 3365 constraint(ALLOC_IN_RC(any_reg)); 3366 match(RegP); 3367 match(rax_RegP); 3368 match(rbx_RegP); 3369 match(rdi_RegP); 3370 match(rsi_RegP); 3371 match(rbp_RegP); 3372 match(r15_RegP); 3373 match(rRegP); 3374 3375 format %{ %} 3376 interface(REG_INTER); 3377 %} 3378 3379 operand rRegP() 3380 %{ 3381 constraint(ALLOC_IN_RC(ptr_reg)); 3382 match(RegP); 3383 match(rax_RegP); 3384 match(rbx_RegP); 3385 match(rdi_RegP); 3386 match(rsi_RegP); 3387 match(rbp_RegP); // See Q&A below about 3388 match(r15_RegP); // r15_RegP and rbp_RegP. 3389 3390 format %{ %} 3391 interface(REG_INTER); 3392 %} 3393 3394 operand rRegN() %{ 3395 constraint(ALLOC_IN_RC(int_reg)); 3396 match(RegN); 3397 3398 format %{ %} 3399 interface(REG_INTER); 3400 %} 3401 3402 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3403 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3404 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3405 // The output of an instruction is controlled by the allocator, which respects 3406 // register class masks, not match rules. Unless an instruction mentions 3407 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3408 // by the allocator as an input. 3409 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3410 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3411 // result, RBP is not included in the output of the instruction either. 3412 3413 operand no_rax_RegP() 3414 %{ 3415 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3416 match(RegP); 3417 match(rbx_RegP); 3418 match(rsi_RegP); 3419 match(rdi_RegP); 3420 3421 format %{ %} 3422 interface(REG_INTER); 3423 %} 3424 3425 // This operand is not allowed to use RBP even if 3426 // RBP is not used to hold the frame pointer. 3427 operand no_rbp_RegP() 3428 %{ 3429 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3430 match(RegP); 3431 match(rbx_RegP); 3432 match(rsi_RegP); 3433 match(rdi_RegP); 3434 3435 format %{ %} 3436 interface(REG_INTER); 3437 %} 3438 3439 operand no_rax_rbx_RegP() 3440 %{ 3441 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3442 match(RegP); 3443 match(rsi_RegP); 3444 match(rdi_RegP); 3445 3446 format %{ %} 3447 interface(REG_INTER); 3448 %} 3449 3450 // Special Registers 3451 // Return a pointer value 3452 operand rax_RegP() 3453 %{ 3454 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3455 match(RegP); 3456 match(rRegP); 3457 3458 format %{ %} 3459 interface(REG_INTER); 3460 %} 3461 3462 // Special Registers 3463 // Return a compressed pointer value 3464 operand rax_RegN() 3465 %{ 3466 constraint(ALLOC_IN_RC(int_rax_reg)); 3467 match(RegN); 3468 match(rRegN); 3469 3470 format %{ %} 3471 interface(REG_INTER); 3472 %} 3473 3474 // Used in AtomicAdd 3475 operand rbx_RegP() 3476 %{ 3477 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3478 match(RegP); 3479 match(rRegP); 3480 3481 format %{ %} 3482 interface(REG_INTER); 3483 %} 3484 3485 operand rsi_RegP() 3486 %{ 3487 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3488 match(RegP); 3489 match(rRegP); 3490 3491 format %{ %} 3492 interface(REG_INTER); 3493 %} 3494 3495 // Used in rep stosq 3496 operand rdi_RegP() 3497 %{ 3498 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3499 match(RegP); 3500 match(rRegP); 3501 3502 format %{ %} 3503 interface(REG_INTER); 3504 %} 3505 3506 operand r15_RegP() 3507 %{ 3508 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3509 match(RegP); 3510 match(rRegP); 3511 3512 format %{ %} 3513 interface(REG_INTER); 3514 %} 3515 3516 operand rRegL() 3517 %{ 3518 constraint(ALLOC_IN_RC(long_reg)); 3519 match(RegL); 3520 match(rax_RegL); 3521 match(rdx_RegL); 3522 3523 format %{ %} 3524 interface(REG_INTER); 3525 %} 3526 3527 // Special Registers 3528 operand no_rax_rdx_RegL() 3529 %{ 3530 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3531 match(RegL); 3532 match(rRegL); 3533 3534 format %{ %} 3535 interface(REG_INTER); 3536 %} 3537 3538 operand no_rax_RegL() 3539 %{ 3540 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3541 match(RegL); 3542 match(rRegL); 3543 match(rdx_RegL); 3544 3545 format %{ %} 3546 interface(REG_INTER); 3547 %} 3548 3549 operand no_rcx_RegL() 3550 %{ 3551 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3552 match(RegL); 3553 match(rRegL); 3554 3555 format %{ %} 3556 interface(REG_INTER); 3557 %} 3558 3559 operand rax_RegL() 3560 %{ 3561 constraint(ALLOC_IN_RC(long_rax_reg)); 3562 match(RegL); 3563 match(rRegL); 3564 3565 format %{ "RAX" %} 3566 interface(REG_INTER); 3567 %} 3568 3569 operand rcx_RegL() 3570 %{ 3571 constraint(ALLOC_IN_RC(long_rcx_reg)); 3572 match(RegL); 3573 match(rRegL); 3574 3575 format %{ %} 3576 interface(REG_INTER); 3577 %} 3578 3579 operand rdx_RegL() 3580 %{ 3581 constraint(ALLOC_IN_RC(long_rdx_reg)); 3582 match(RegL); 3583 match(rRegL); 3584 3585 format %{ %} 3586 interface(REG_INTER); 3587 %} 3588 3589 // Flags register, used as output of compare instructions 3590 operand rFlagsReg() 3591 %{ 3592 constraint(ALLOC_IN_RC(int_flags)); 3593 match(RegFlags); 3594 3595 format %{ "RFLAGS" %} 3596 interface(REG_INTER); 3597 %} 3598 3599 // Flags register, used as output of FLOATING POINT compare instructions 3600 operand rFlagsRegU() 3601 %{ 3602 constraint(ALLOC_IN_RC(int_flags)); 3603 match(RegFlags); 3604 3605 format %{ "RFLAGS_U" %} 3606 interface(REG_INTER); 3607 %} 3608 3609 operand rFlagsRegUCF() %{ 3610 constraint(ALLOC_IN_RC(int_flags)); 3611 match(RegFlags); 3612 predicate(false); 3613 3614 format %{ "RFLAGS_U_CF" %} 3615 interface(REG_INTER); 3616 %} 3617 3618 // Float register operands 3619 operand regF() %{ 3620 constraint(ALLOC_IN_RC(float_reg)); 3621 match(RegF); 3622 3623 format %{ %} 3624 interface(REG_INTER); 3625 %} 3626 3627 // Double register operands 3628 operand regD() %{ 3629 constraint(ALLOC_IN_RC(double_reg)); 3630 match(RegD); 3631 3632 format %{ %} 3633 interface(REG_INTER); 3634 %} 3635 3636 // Vectors 3637 operand vecS() %{ 3638 constraint(ALLOC_IN_RC(vectors_reg)); 3639 match(VecS); 3640 3641 format %{ %} 3642 interface(REG_INTER); 3643 %} 3644 3645 operand vecD() %{ 3646 constraint(ALLOC_IN_RC(vectord_reg)); 3647 match(VecD); 3648 3649 format %{ %} 3650 interface(REG_INTER); 3651 %} 3652 3653 operand vecX() %{ 3654 constraint(ALLOC_IN_RC(vectorx_reg)); 3655 match(VecX); 3656 3657 format %{ %} 3658 interface(REG_INTER); 3659 %} 3660 3661 operand vecY() %{ 3662 constraint(ALLOC_IN_RC(vectory_reg)); 3663 match(VecY); 3664 3665 format %{ %} 3666 interface(REG_INTER); 3667 %} 3668 3669 //----------Memory Operands---------------------------------------------------- 3670 // Direct Memory Operand 3671 // operand direct(immP addr) 3672 // %{ 3673 // match(addr); 3674 3675 // format %{ "[$addr]" %} 3676 // interface(MEMORY_INTER) %{ 3677 // base(0xFFFFFFFF); 3678 // index(0x4); 3679 // scale(0x0); 3680 // disp($addr); 3681 // %} 3682 // %} 3683 3684 // Indirect Memory Operand 3685 operand indirect(any_RegP reg) 3686 %{ 3687 constraint(ALLOC_IN_RC(ptr_reg)); 3688 match(reg); 3689 3690 format %{ "[$reg]" %} 3691 interface(MEMORY_INTER) %{ 3692 base($reg); 3693 index(0x4); 3694 scale(0x0); 3695 disp(0x0); 3696 %} 3697 %} 3698 3699 // Indirect Memory Plus Short Offset Operand 3700 operand indOffset8(any_RegP reg, immL8 off) 3701 %{ 3702 constraint(ALLOC_IN_RC(ptr_reg)); 3703 match(AddP reg off); 3704 3705 format %{ "[$reg + $off (8-bit)]" %} 3706 interface(MEMORY_INTER) %{ 3707 base($reg); 3708 index(0x4); 3709 scale(0x0); 3710 disp($off); 3711 %} 3712 %} 3713 3714 // Indirect Memory Plus Long Offset Operand 3715 operand indOffset32(any_RegP reg, immL32 off) 3716 %{ 3717 constraint(ALLOC_IN_RC(ptr_reg)); 3718 match(AddP reg off); 3719 3720 format %{ "[$reg + $off (32-bit)]" %} 3721 interface(MEMORY_INTER) %{ 3722 base($reg); 3723 index(0x4); 3724 scale(0x0); 3725 disp($off); 3726 %} 3727 %} 3728 3729 // Indirect Memory Plus Index Register Plus Offset Operand 3730 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3731 %{ 3732 constraint(ALLOC_IN_RC(ptr_reg)); 3733 match(AddP (AddP reg lreg) off); 3734 3735 op_cost(10); 3736 format %{"[$reg + $off + $lreg]" %} 3737 interface(MEMORY_INTER) %{ 3738 base($reg); 3739 index($lreg); 3740 scale(0x0); 3741 disp($off); 3742 %} 3743 %} 3744 3745 // Indirect Memory Plus Index Register Plus Offset Operand 3746 operand indIndex(any_RegP reg, rRegL lreg) 3747 %{ 3748 constraint(ALLOC_IN_RC(ptr_reg)); 3749 match(AddP reg lreg); 3750 3751 op_cost(10); 3752 format %{"[$reg + $lreg]" %} 3753 interface(MEMORY_INTER) %{ 3754 base($reg); 3755 index($lreg); 3756 scale(0x0); 3757 disp(0x0); 3758 %} 3759 %} 3760 3761 // Indirect Memory Times Scale Plus Index Register 3762 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3763 %{ 3764 constraint(ALLOC_IN_RC(ptr_reg)); 3765 match(AddP reg (LShiftL lreg scale)); 3766 3767 op_cost(10); 3768 format %{"[$reg + $lreg << $scale]" %} 3769 interface(MEMORY_INTER) %{ 3770 base($reg); 3771 index($lreg); 3772 scale($scale); 3773 disp(0x0); 3774 %} 3775 %} 3776 3777 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3778 %{ 3779 constraint(ALLOC_IN_RC(ptr_reg)); 3780 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3781 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3782 3783 op_cost(10); 3784 format %{"[$reg + pos $idx << $scale]" %} 3785 interface(MEMORY_INTER) %{ 3786 base($reg); 3787 index($idx); 3788 scale($scale); 3789 disp(0x0); 3790 %} 3791 %} 3792 3793 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3794 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3795 %{ 3796 constraint(ALLOC_IN_RC(ptr_reg)); 3797 match(AddP (AddP reg (LShiftL lreg scale)) off); 3798 3799 op_cost(10); 3800 format %{"[$reg + $off + $lreg << $scale]" %} 3801 interface(MEMORY_INTER) %{ 3802 base($reg); 3803 index($lreg); 3804 scale($scale); 3805 disp($off); 3806 %} 3807 %} 3808 3809 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3810 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3811 %{ 3812 constraint(ALLOC_IN_RC(ptr_reg)); 3813 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3814 match(AddP (AddP reg (ConvI2L idx)) off); 3815 3816 op_cost(10); 3817 format %{"[$reg + $off + $idx]" %} 3818 interface(MEMORY_INTER) %{ 3819 base($reg); 3820 index($idx); 3821 scale(0x0); 3822 disp($off); 3823 %} 3824 %} 3825 3826 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3827 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3828 %{ 3829 constraint(ALLOC_IN_RC(ptr_reg)); 3830 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3831 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3832 3833 op_cost(10); 3834 format %{"[$reg + $off + $idx << $scale]" %} 3835 interface(MEMORY_INTER) %{ 3836 base($reg); 3837 index($idx); 3838 scale($scale); 3839 disp($off); 3840 %} 3841 %} 3842 3843 // Indirect Narrow Oop Plus Offset Operand 3844 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3845 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3846 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3847 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3848 constraint(ALLOC_IN_RC(ptr_reg)); 3849 match(AddP (DecodeN reg) off); 3850 3851 op_cost(10); 3852 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3853 interface(MEMORY_INTER) %{ 3854 base(0xc); // R12 3855 index($reg); 3856 scale(0x3); 3857 disp($off); 3858 %} 3859 %} 3860 3861 // Indirect Memory Operand 3862 operand indirectNarrow(rRegN reg) 3863 %{ 3864 predicate(Universe::narrow_oop_shift() == 0); 3865 constraint(ALLOC_IN_RC(ptr_reg)); 3866 match(DecodeN reg); 3867 3868 format %{ "[$reg]" %} 3869 interface(MEMORY_INTER) %{ 3870 base($reg); 3871 index(0x4); 3872 scale(0x0); 3873 disp(0x0); 3874 %} 3875 %} 3876 3877 // Indirect Memory Plus Short Offset Operand 3878 operand indOffset8Narrow(rRegN reg, immL8 off) 3879 %{ 3880 predicate(Universe::narrow_oop_shift() == 0); 3881 constraint(ALLOC_IN_RC(ptr_reg)); 3882 match(AddP (DecodeN reg) off); 3883 3884 format %{ "[$reg + $off (8-bit)]" %} 3885 interface(MEMORY_INTER) %{ 3886 base($reg); 3887 index(0x4); 3888 scale(0x0); 3889 disp($off); 3890 %} 3891 %} 3892 3893 // Indirect Memory Plus Long Offset Operand 3894 operand indOffset32Narrow(rRegN reg, immL32 off) 3895 %{ 3896 predicate(Universe::narrow_oop_shift() == 0); 3897 constraint(ALLOC_IN_RC(ptr_reg)); 3898 match(AddP (DecodeN reg) off); 3899 3900 format %{ "[$reg + $off (32-bit)]" %} 3901 interface(MEMORY_INTER) %{ 3902 base($reg); 3903 index(0x4); 3904 scale(0x0); 3905 disp($off); 3906 %} 3907 %} 3908 3909 // Indirect Memory Plus Index Register Plus Offset Operand 3910 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3911 %{ 3912 predicate(Universe::narrow_oop_shift() == 0); 3913 constraint(ALLOC_IN_RC(ptr_reg)); 3914 match(AddP (AddP (DecodeN reg) lreg) off); 3915 3916 op_cost(10); 3917 format %{"[$reg + $off + $lreg]" %} 3918 interface(MEMORY_INTER) %{ 3919 base($reg); 3920 index($lreg); 3921 scale(0x0); 3922 disp($off); 3923 %} 3924 %} 3925 3926 // Indirect Memory Plus Index Register Plus Offset Operand 3927 operand indIndexNarrow(rRegN reg, rRegL lreg) 3928 %{ 3929 predicate(Universe::narrow_oop_shift() == 0); 3930 constraint(ALLOC_IN_RC(ptr_reg)); 3931 match(AddP (DecodeN reg) lreg); 3932 3933 op_cost(10); 3934 format %{"[$reg + $lreg]" %} 3935 interface(MEMORY_INTER) %{ 3936 base($reg); 3937 index($lreg); 3938 scale(0x0); 3939 disp(0x0); 3940 %} 3941 %} 3942 3943 // Indirect Memory Times Scale Plus Index Register 3944 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3945 %{ 3946 predicate(Universe::narrow_oop_shift() == 0); 3947 constraint(ALLOC_IN_RC(ptr_reg)); 3948 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3949 3950 op_cost(10); 3951 format %{"[$reg + $lreg << $scale]" %} 3952 interface(MEMORY_INTER) %{ 3953 base($reg); 3954 index($lreg); 3955 scale($scale); 3956 disp(0x0); 3957 %} 3958 %} 3959 3960 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3961 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3962 %{ 3963 predicate(Universe::narrow_oop_shift() == 0); 3964 constraint(ALLOC_IN_RC(ptr_reg)); 3965 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3966 3967 op_cost(10); 3968 format %{"[$reg + $off + $lreg << $scale]" %} 3969 interface(MEMORY_INTER) %{ 3970 base($reg); 3971 index($lreg); 3972 scale($scale); 3973 disp($off); 3974 %} 3975 %} 3976 3977 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3978 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3979 %{ 3980 constraint(ALLOC_IN_RC(ptr_reg)); 3981 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3982 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3983 3984 op_cost(10); 3985 format %{"[$reg + $off + $idx]" %} 3986 interface(MEMORY_INTER) %{ 3987 base($reg); 3988 index($idx); 3989 scale(0x0); 3990 disp($off); 3991 %} 3992 %} 3993 3994 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3995 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3996 %{ 3997 constraint(ALLOC_IN_RC(ptr_reg)); 3998 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3999 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4000 4001 op_cost(10); 4002 format %{"[$reg + $off + $idx << $scale]" %} 4003 interface(MEMORY_INTER) %{ 4004 base($reg); 4005 index($idx); 4006 scale($scale); 4007 disp($off); 4008 %} 4009 %} 4010 4011 //----------Special Memory Operands-------------------------------------------- 4012 // Stack Slot Operand - This operand is used for loading and storing temporary 4013 // values on the stack where a match requires a value to 4014 // flow through memory. 4015 operand stackSlotP(sRegP reg) 4016 %{ 4017 constraint(ALLOC_IN_RC(stack_slots)); 4018 // No match rule because this operand is only generated in matching 4019 4020 format %{ "[$reg]" %} 4021 interface(MEMORY_INTER) %{ 4022 base(0x4); // RSP 4023 index(0x4); // No Index 4024 scale(0x0); // No Scale 4025 disp($reg); // Stack Offset 4026 %} 4027 %} 4028 4029 operand stackSlotI(sRegI reg) 4030 %{ 4031 constraint(ALLOC_IN_RC(stack_slots)); 4032 // No match rule because this operand is only generated in matching 4033 4034 format %{ "[$reg]" %} 4035 interface(MEMORY_INTER) %{ 4036 base(0x4); // RSP 4037 index(0x4); // No Index 4038 scale(0x0); // No Scale 4039 disp($reg); // Stack Offset 4040 %} 4041 %} 4042 4043 operand stackSlotF(sRegF reg) 4044 %{ 4045 constraint(ALLOC_IN_RC(stack_slots)); 4046 // No match rule because this operand is only generated in matching 4047 4048 format %{ "[$reg]" %} 4049 interface(MEMORY_INTER) %{ 4050 base(0x4); // RSP 4051 index(0x4); // No Index 4052 scale(0x0); // No Scale 4053 disp($reg); // Stack Offset 4054 %} 4055 %} 4056 4057 operand stackSlotD(sRegD reg) 4058 %{ 4059 constraint(ALLOC_IN_RC(stack_slots)); 4060 // No match rule because this operand is only generated in matching 4061 4062 format %{ "[$reg]" %} 4063 interface(MEMORY_INTER) %{ 4064 base(0x4); // RSP 4065 index(0x4); // No Index 4066 scale(0x0); // No Scale 4067 disp($reg); // Stack Offset 4068 %} 4069 %} 4070 operand stackSlotL(sRegL reg) 4071 %{ 4072 constraint(ALLOC_IN_RC(stack_slots)); 4073 // No match rule because this operand is only generated in matching 4074 4075 format %{ "[$reg]" %} 4076 interface(MEMORY_INTER) %{ 4077 base(0x4); // RSP 4078 index(0x4); // No Index 4079 scale(0x0); // No Scale 4080 disp($reg); // Stack Offset 4081 %} 4082 %} 4083 4084 //----------Conditional Branch Operands---------------------------------------- 4085 // Comparison Op - This is the operation of the comparison, and is limited to 4086 // the following set of codes: 4087 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4088 // 4089 // Other attributes of the comparison, such as unsignedness, are specified 4090 // by the comparison instruction that sets a condition code flags register. 4091 // That result is represented by a flags operand whose subtype is appropriate 4092 // to the unsignedness (etc.) of the comparison. 4093 // 4094 // Later, the instruction which matches both the Comparison Op (a Bool) and 4095 // the flags (produced by the Cmp) specifies the coding of the comparison op 4096 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4097 4098 // Comparision Code 4099 operand cmpOp() 4100 %{ 4101 match(Bool); 4102 4103 format %{ "" %} 4104 interface(COND_INTER) %{ 4105 equal(0x4, "e"); 4106 not_equal(0x5, "ne"); 4107 less(0xC, "l"); 4108 greater_equal(0xD, "ge"); 4109 less_equal(0xE, "le"); 4110 greater(0xF, "g"); 4111 overflow(0x0, "o"); 4112 no_overflow(0x1, "no"); 4113 %} 4114 %} 4115 4116 // Comparison Code, unsigned compare. Used by FP also, with 4117 // C2 (unordered) turned into GT or LT already. The other bits 4118 // C0 and C3 are turned into Carry & Zero flags. 4119 operand cmpOpU() 4120 %{ 4121 match(Bool); 4122 4123 format %{ "" %} 4124 interface(COND_INTER) %{ 4125 equal(0x4, "e"); 4126 not_equal(0x5, "ne"); 4127 less(0x2, "b"); 4128 greater_equal(0x3, "nb"); 4129 less_equal(0x6, "be"); 4130 greater(0x7, "nbe"); 4131 overflow(0x0, "o"); 4132 no_overflow(0x1, "no"); 4133 %} 4134 %} 4135 4136 4137 // Floating comparisons that don't require any fixup for the unordered case 4138 operand cmpOpUCF() %{ 4139 match(Bool); 4140 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4141 n->as_Bool()->_test._test == BoolTest::ge || 4142 n->as_Bool()->_test._test == BoolTest::le || 4143 n->as_Bool()->_test._test == BoolTest::gt); 4144 format %{ "" %} 4145 interface(COND_INTER) %{ 4146 equal(0x4, "e"); 4147 not_equal(0x5, "ne"); 4148 less(0x2, "b"); 4149 greater_equal(0x3, "nb"); 4150 less_equal(0x6, "be"); 4151 greater(0x7, "nbe"); 4152 overflow(0x0, "o"); 4153 no_overflow(0x1, "no"); 4154 %} 4155 %} 4156 4157 4158 // Floating comparisons that can be fixed up with extra conditional jumps 4159 operand cmpOpUCF2() %{ 4160 match(Bool); 4161 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4162 n->as_Bool()->_test._test == BoolTest::eq); 4163 format %{ "" %} 4164 interface(COND_INTER) %{ 4165 equal(0x4, "e"); 4166 not_equal(0x5, "ne"); 4167 less(0x2, "b"); 4168 greater_equal(0x3, "nb"); 4169 less_equal(0x6, "be"); 4170 greater(0x7, "nbe"); 4171 overflow(0x0, "o"); 4172 no_overflow(0x1, "no"); 4173 %} 4174 %} 4175 4176 4177 //----------OPERAND CLASSES---------------------------------------------------- 4178 // Operand Classes are groups of operands that are used as to simplify 4179 // instruction definitions by not requiring the AD writer to specify separate 4180 // instructions for every form of operand when the instruction accepts 4181 // multiple operand types with the same basic encoding and format. The classic 4182 // case of this is memory operands. 4183 4184 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4185 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4186 indCompressedOopOffset, 4187 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4188 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4189 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4190 4191 //----------PIPELINE----------------------------------------------------------- 4192 // Rules which define the behavior of the target architectures pipeline. 4193 pipeline %{ 4194 4195 //----------ATTRIBUTES--------------------------------------------------------- 4196 attributes %{ 4197 variable_size_instructions; // Fixed size instructions 4198 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4199 instruction_unit_size = 1; // An instruction is 1 bytes long 4200 instruction_fetch_unit_size = 16; // The processor fetches one line 4201 instruction_fetch_units = 1; // of 16 bytes 4202 4203 // List of nop instructions 4204 nops( MachNop ); 4205 %} 4206 4207 //----------RESOURCES---------------------------------------------------------- 4208 // Resources are the functional units available to the machine 4209 4210 // Generic P2/P3 pipeline 4211 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4212 // 3 instructions decoded per cycle. 4213 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4214 // 3 ALU op, only ALU0 handles mul instructions. 4215 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4216 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4217 BR, FPU, 4218 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4219 4220 //----------PIPELINE DESCRIPTION----------------------------------------------- 4221 // Pipeline Description specifies the stages in the machine's pipeline 4222 4223 // Generic P2/P3 pipeline 4224 pipe_desc(S0, S1, S2, S3, S4, S5); 4225 4226 //----------PIPELINE CLASSES--------------------------------------------------- 4227 // Pipeline Classes describe the stages in which input and output are 4228 // referenced by the hardware pipeline. 4229 4230 // Naming convention: ialu or fpu 4231 // Then: _reg 4232 // Then: _reg if there is a 2nd register 4233 // Then: _long if it's a pair of instructions implementing a long 4234 // Then: _fat if it requires the big decoder 4235 // Or: _mem if it requires the big decoder and a memory unit. 4236 4237 // Integer ALU reg operation 4238 pipe_class ialu_reg(rRegI dst) 4239 %{ 4240 single_instruction; 4241 dst : S4(write); 4242 dst : S3(read); 4243 DECODE : S0; // any decoder 4244 ALU : S3; // any alu 4245 %} 4246 4247 // Long ALU reg operation 4248 pipe_class ialu_reg_long(rRegL dst) 4249 %{ 4250 instruction_count(2); 4251 dst : S4(write); 4252 dst : S3(read); 4253 DECODE : S0(2); // any 2 decoders 4254 ALU : S3(2); // both alus 4255 %} 4256 4257 // Integer ALU reg operation using big decoder 4258 pipe_class ialu_reg_fat(rRegI dst) 4259 %{ 4260 single_instruction; 4261 dst : S4(write); 4262 dst : S3(read); 4263 D0 : S0; // big decoder only 4264 ALU : S3; // any alu 4265 %} 4266 4267 // Long ALU reg operation using big decoder 4268 pipe_class ialu_reg_long_fat(rRegL dst) 4269 %{ 4270 instruction_count(2); 4271 dst : S4(write); 4272 dst : S3(read); 4273 D0 : S0(2); // big decoder only; twice 4274 ALU : S3(2); // any 2 alus 4275 %} 4276 4277 // Integer ALU reg-reg operation 4278 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4279 %{ 4280 single_instruction; 4281 dst : S4(write); 4282 src : S3(read); 4283 DECODE : S0; // any decoder 4284 ALU : S3; // any alu 4285 %} 4286 4287 // Long ALU reg-reg operation 4288 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4289 %{ 4290 instruction_count(2); 4291 dst : S4(write); 4292 src : S3(read); 4293 DECODE : S0(2); // any 2 decoders 4294 ALU : S3(2); // both alus 4295 %} 4296 4297 // Integer ALU reg-reg operation 4298 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4299 %{ 4300 single_instruction; 4301 dst : S4(write); 4302 src : S3(read); 4303 D0 : S0; // big decoder only 4304 ALU : S3; // any alu 4305 %} 4306 4307 // Long ALU reg-reg operation 4308 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4309 %{ 4310 instruction_count(2); 4311 dst : S4(write); 4312 src : S3(read); 4313 D0 : S0(2); // big decoder only; twice 4314 ALU : S3(2); // both alus 4315 %} 4316 4317 // Integer ALU reg-mem operation 4318 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4319 %{ 4320 single_instruction; 4321 dst : S5(write); 4322 mem : S3(read); 4323 D0 : S0; // big decoder only 4324 ALU : S4; // any alu 4325 MEM : S3; // any mem 4326 %} 4327 4328 // Integer mem operation (prefetch) 4329 pipe_class ialu_mem(memory mem) 4330 %{ 4331 single_instruction; 4332 mem : S3(read); 4333 D0 : S0; // big decoder only 4334 MEM : S3; // any mem 4335 %} 4336 4337 // Integer Store to Memory 4338 pipe_class ialu_mem_reg(memory mem, rRegI src) 4339 %{ 4340 single_instruction; 4341 mem : S3(read); 4342 src : S5(read); 4343 D0 : S0; // big decoder only 4344 ALU : S4; // any alu 4345 MEM : S3; 4346 %} 4347 4348 // // Long Store to Memory 4349 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4350 // %{ 4351 // instruction_count(2); 4352 // mem : S3(read); 4353 // src : S5(read); 4354 // D0 : S0(2); // big decoder only; twice 4355 // ALU : S4(2); // any 2 alus 4356 // MEM : S3(2); // Both mems 4357 // %} 4358 4359 // Integer Store to Memory 4360 pipe_class ialu_mem_imm(memory mem) 4361 %{ 4362 single_instruction; 4363 mem : S3(read); 4364 D0 : S0; // big decoder only 4365 ALU : S4; // any alu 4366 MEM : S3; 4367 %} 4368 4369 // Integer ALU0 reg-reg operation 4370 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4371 %{ 4372 single_instruction; 4373 dst : S4(write); 4374 src : S3(read); 4375 D0 : S0; // Big decoder only 4376 ALU0 : S3; // only alu0 4377 %} 4378 4379 // Integer ALU0 reg-mem operation 4380 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4381 %{ 4382 single_instruction; 4383 dst : S5(write); 4384 mem : S3(read); 4385 D0 : S0; // big decoder only 4386 ALU0 : S4; // ALU0 only 4387 MEM : S3; // any mem 4388 %} 4389 4390 // Integer ALU reg-reg operation 4391 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4392 %{ 4393 single_instruction; 4394 cr : S4(write); 4395 src1 : S3(read); 4396 src2 : S3(read); 4397 DECODE : S0; // any decoder 4398 ALU : S3; // any alu 4399 %} 4400 4401 // Integer ALU reg-imm operation 4402 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4403 %{ 4404 single_instruction; 4405 cr : S4(write); 4406 src1 : S3(read); 4407 DECODE : S0; // any decoder 4408 ALU : S3; // any alu 4409 %} 4410 4411 // Integer ALU reg-mem operation 4412 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4413 %{ 4414 single_instruction; 4415 cr : S4(write); 4416 src1 : S3(read); 4417 src2 : S3(read); 4418 D0 : S0; // big decoder only 4419 ALU : S4; // any alu 4420 MEM : S3; 4421 %} 4422 4423 // Conditional move reg-reg 4424 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4425 %{ 4426 instruction_count(4); 4427 y : S4(read); 4428 q : S3(read); 4429 p : S3(read); 4430 DECODE : S0(4); // any decoder 4431 %} 4432 4433 // Conditional move reg-reg 4434 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4435 %{ 4436 single_instruction; 4437 dst : S4(write); 4438 src : S3(read); 4439 cr : S3(read); 4440 DECODE : S0; // any decoder 4441 %} 4442 4443 // Conditional move reg-mem 4444 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4445 %{ 4446 single_instruction; 4447 dst : S4(write); 4448 src : S3(read); 4449 cr : S3(read); 4450 DECODE : S0; // any decoder 4451 MEM : S3; 4452 %} 4453 4454 // Conditional move reg-reg long 4455 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4456 %{ 4457 single_instruction; 4458 dst : S4(write); 4459 src : S3(read); 4460 cr : S3(read); 4461 DECODE : S0(2); // any 2 decoders 4462 %} 4463 4464 // XXX 4465 // // Conditional move double reg-reg 4466 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4467 // %{ 4468 // single_instruction; 4469 // dst : S4(write); 4470 // src : S3(read); 4471 // cr : S3(read); 4472 // DECODE : S0; // any decoder 4473 // %} 4474 4475 // Float reg-reg operation 4476 pipe_class fpu_reg(regD dst) 4477 %{ 4478 instruction_count(2); 4479 dst : S3(read); 4480 DECODE : S0(2); // any 2 decoders 4481 FPU : S3; 4482 %} 4483 4484 // Float reg-reg operation 4485 pipe_class fpu_reg_reg(regD dst, regD src) 4486 %{ 4487 instruction_count(2); 4488 dst : S4(write); 4489 src : S3(read); 4490 DECODE : S0(2); // any 2 decoders 4491 FPU : S3; 4492 %} 4493 4494 // Float reg-reg operation 4495 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4496 %{ 4497 instruction_count(3); 4498 dst : S4(write); 4499 src1 : S3(read); 4500 src2 : S3(read); 4501 DECODE : S0(3); // any 3 decoders 4502 FPU : S3(2); 4503 %} 4504 4505 // Float reg-reg operation 4506 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4507 %{ 4508 instruction_count(4); 4509 dst : S4(write); 4510 src1 : S3(read); 4511 src2 : S3(read); 4512 src3 : S3(read); 4513 DECODE : S0(4); // any 3 decoders 4514 FPU : S3(2); 4515 %} 4516 4517 // Float reg-reg operation 4518 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4519 %{ 4520 instruction_count(4); 4521 dst : S4(write); 4522 src1 : S3(read); 4523 src2 : S3(read); 4524 src3 : S3(read); 4525 DECODE : S1(3); // any 3 decoders 4526 D0 : S0; // Big decoder only 4527 FPU : S3(2); 4528 MEM : S3; 4529 %} 4530 4531 // Float reg-mem operation 4532 pipe_class fpu_reg_mem(regD dst, memory mem) 4533 %{ 4534 instruction_count(2); 4535 dst : S5(write); 4536 mem : S3(read); 4537 D0 : S0; // big decoder only 4538 DECODE : S1; // any decoder for FPU POP 4539 FPU : S4; 4540 MEM : S3; // any mem 4541 %} 4542 4543 // Float reg-mem operation 4544 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4545 %{ 4546 instruction_count(3); 4547 dst : S5(write); 4548 src1 : S3(read); 4549 mem : S3(read); 4550 D0 : S0; // big decoder only 4551 DECODE : S1(2); // any decoder for FPU POP 4552 FPU : S4; 4553 MEM : S3; // any mem 4554 %} 4555 4556 // Float mem-reg operation 4557 pipe_class fpu_mem_reg(memory mem, regD src) 4558 %{ 4559 instruction_count(2); 4560 src : S5(read); 4561 mem : S3(read); 4562 DECODE : S0; // any decoder for FPU PUSH 4563 D0 : S1; // big decoder only 4564 FPU : S4; 4565 MEM : S3; // any mem 4566 %} 4567 4568 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4569 %{ 4570 instruction_count(3); 4571 src1 : S3(read); 4572 src2 : S3(read); 4573 mem : S3(read); 4574 DECODE : S0(2); // any decoder for FPU PUSH 4575 D0 : S1; // big decoder only 4576 FPU : S4; 4577 MEM : S3; // any mem 4578 %} 4579 4580 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4581 %{ 4582 instruction_count(3); 4583 src1 : S3(read); 4584 src2 : S3(read); 4585 mem : S4(read); 4586 DECODE : S0; // any decoder for FPU PUSH 4587 D0 : S0(2); // big decoder only 4588 FPU : S4; 4589 MEM : S3(2); // any mem 4590 %} 4591 4592 pipe_class fpu_mem_mem(memory dst, memory src1) 4593 %{ 4594 instruction_count(2); 4595 src1 : S3(read); 4596 dst : S4(read); 4597 D0 : S0(2); // big decoder only 4598 MEM : S3(2); // any mem 4599 %} 4600 4601 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4602 %{ 4603 instruction_count(3); 4604 src1 : S3(read); 4605 src2 : S3(read); 4606 dst : S4(read); 4607 D0 : S0(3); // big decoder only 4608 FPU : S4; 4609 MEM : S3(3); // any mem 4610 %} 4611 4612 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4613 %{ 4614 instruction_count(3); 4615 src1 : S4(read); 4616 mem : S4(read); 4617 DECODE : S0; // any decoder for FPU PUSH 4618 D0 : S0(2); // big decoder only 4619 FPU : S4; 4620 MEM : S3(2); // any mem 4621 %} 4622 4623 // Float load constant 4624 pipe_class fpu_reg_con(regD dst) 4625 %{ 4626 instruction_count(2); 4627 dst : S5(write); 4628 D0 : S0; // big decoder only for the load 4629 DECODE : S1; // any decoder for FPU POP 4630 FPU : S4; 4631 MEM : S3; // any mem 4632 %} 4633 4634 // Float load constant 4635 pipe_class fpu_reg_reg_con(regD dst, regD src) 4636 %{ 4637 instruction_count(3); 4638 dst : S5(write); 4639 src : S3(read); 4640 D0 : S0; // big decoder only for the load 4641 DECODE : S1(2); // any decoder for FPU POP 4642 FPU : S4; 4643 MEM : S3; // any mem 4644 %} 4645 4646 // UnConditional branch 4647 pipe_class pipe_jmp(label labl) 4648 %{ 4649 single_instruction; 4650 BR : S3; 4651 %} 4652 4653 // Conditional branch 4654 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4655 %{ 4656 single_instruction; 4657 cr : S1(read); 4658 BR : S3; 4659 %} 4660 4661 // Allocation idiom 4662 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4663 %{ 4664 instruction_count(1); force_serialization; 4665 fixed_latency(6); 4666 heap_ptr : S3(read); 4667 DECODE : S0(3); 4668 D0 : S2; 4669 MEM : S3; 4670 ALU : S3(2); 4671 dst : S5(write); 4672 BR : S5; 4673 %} 4674 4675 // Generic big/slow expanded idiom 4676 pipe_class pipe_slow() 4677 %{ 4678 instruction_count(10); multiple_bundles; force_serialization; 4679 fixed_latency(100); 4680 D0 : S0(2); 4681 MEM : S3(2); 4682 %} 4683 4684 // The real do-nothing guy 4685 pipe_class empty() 4686 %{ 4687 instruction_count(0); 4688 %} 4689 4690 // Define the class for the Nop node 4691 define 4692 %{ 4693 MachNop = empty; 4694 %} 4695 4696 %} 4697 4698 //----------INSTRUCTIONS------------------------------------------------------- 4699 // 4700 // match -- States which machine-independent subtree may be replaced 4701 // by this instruction. 4702 // ins_cost -- The estimated cost of this instruction is used by instruction 4703 // selection to identify a minimum cost tree of machine 4704 // instructions that matches a tree of machine-independent 4705 // instructions. 4706 // format -- A string providing the disassembly for this instruction. 4707 // The value of an instruction's operand may be inserted 4708 // by referring to it with a '$' prefix. 4709 // opcode -- Three instruction opcodes may be provided. These are referred 4710 // to within an encode class as $primary, $secondary, and $tertiary 4711 // rrspectively. The primary opcode is commonly used to 4712 // indicate the type of machine instruction, while secondary 4713 // and tertiary are often used for prefix options or addressing 4714 // modes. 4715 // ins_encode -- A list of encode classes with parameters. The encode class 4716 // name must have been defined in an 'enc_class' specification 4717 // in the encode section of the architecture description. 4718 4719 4720 //----------Load/Store/Move Instructions--------------------------------------- 4721 //----------Load Instructions-------------------------------------------------- 4722 4723 // Load Byte (8 bit signed) 4724 instruct loadB(rRegI dst, memory mem) 4725 %{ 4726 match(Set dst (LoadB mem)); 4727 4728 ins_cost(125); 4729 format %{ "movsbl $dst, $mem\t# byte" %} 4730 4731 ins_encode %{ 4732 __ movsbl($dst$$Register, $mem$$Address); 4733 %} 4734 4735 ins_pipe(ialu_reg_mem); 4736 %} 4737 4738 // Load Byte (8 bit signed) into Long Register 4739 instruct loadB2L(rRegL dst, memory mem) 4740 %{ 4741 match(Set dst (ConvI2L (LoadB mem))); 4742 4743 ins_cost(125); 4744 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4745 4746 ins_encode %{ 4747 __ movsbq($dst$$Register, $mem$$Address); 4748 %} 4749 4750 ins_pipe(ialu_reg_mem); 4751 %} 4752 4753 // Load Unsigned Byte (8 bit UNsigned) 4754 instruct loadUB(rRegI dst, memory mem) 4755 %{ 4756 match(Set dst (LoadUB mem)); 4757 4758 ins_cost(125); 4759 format %{ "movzbl $dst, $mem\t# ubyte" %} 4760 4761 ins_encode %{ 4762 __ movzbl($dst$$Register, $mem$$Address); 4763 %} 4764 4765 ins_pipe(ialu_reg_mem); 4766 %} 4767 4768 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4769 instruct loadUB2L(rRegL dst, memory mem) 4770 %{ 4771 match(Set dst (ConvI2L (LoadUB mem))); 4772 4773 ins_cost(125); 4774 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4775 4776 ins_encode %{ 4777 __ movzbq($dst$$Register, $mem$$Address); 4778 %} 4779 4780 ins_pipe(ialu_reg_mem); 4781 %} 4782 4783 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4784 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4785 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4786 effect(KILL cr); 4787 4788 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4789 "andl $dst, right_n_bits($mask, 8)" %} 4790 ins_encode %{ 4791 Register Rdst = $dst$$Register; 4792 __ movzbq(Rdst, $mem$$Address); 4793 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4794 %} 4795 ins_pipe(ialu_reg_mem); 4796 %} 4797 4798 // Load Short (16 bit signed) 4799 instruct loadS(rRegI dst, memory mem) 4800 %{ 4801 match(Set dst (LoadS mem)); 4802 4803 ins_cost(125); 4804 format %{ "movswl $dst, $mem\t# short" %} 4805 4806 ins_encode %{ 4807 __ movswl($dst$$Register, $mem$$Address); 4808 %} 4809 4810 ins_pipe(ialu_reg_mem); 4811 %} 4812 4813 // Load Short (16 bit signed) to Byte (8 bit signed) 4814 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4815 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4816 4817 ins_cost(125); 4818 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4819 ins_encode %{ 4820 __ movsbl($dst$$Register, $mem$$Address); 4821 %} 4822 ins_pipe(ialu_reg_mem); 4823 %} 4824 4825 // Load Short (16 bit signed) into Long Register 4826 instruct loadS2L(rRegL dst, memory mem) 4827 %{ 4828 match(Set dst (ConvI2L (LoadS mem))); 4829 4830 ins_cost(125); 4831 format %{ "movswq $dst, $mem\t# short -> long" %} 4832 4833 ins_encode %{ 4834 __ movswq($dst$$Register, $mem$$Address); 4835 %} 4836 4837 ins_pipe(ialu_reg_mem); 4838 %} 4839 4840 // Load Unsigned Short/Char (16 bit UNsigned) 4841 instruct loadUS(rRegI dst, memory mem) 4842 %{ 4843 match(Set dst (LoadUS mem)); 4844 4845 ins_cost(125); 4846 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4847 4848 ins_encode %{ 4849 __ movzwl($dst$$Register, $mem$$Address); 4850 %} 4851 4852 ins_pipe(ialu_reg_mem); 4853 %} 4854 4855 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4856 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4857 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4858 4859 ins_cost(125); 4860 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4861 ins_encode %{ 4862 __ movsbl($dst$$Register, $mem$$Address); 4863 %} 4864 ins_pipe(ialu_reg_mem); 4865 %} 4866 4867 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4868 instruct loadUS2L(rRegL dst, memory mem) 4869 %{ 4870 match(Set dst (ConvI2L (LoadUS mem))); 4871 4872 ins_cost(125); 4873 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4874 4875 ins_encode %{ 4876 __ movzwq($dst$$Register, $mem$$Address); 4877 %} 4878 4879 ins_pipe(ialu_reg_mem); 4880 %} 4881 4882 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4883 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4884 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4885 4886 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4887 ins_encode %{ 4888 __ movzbq($dst$$Register, $mem$$Address); 4889 %} 4890 ins_pipe(ialu_reg_mem); 4891 %} 4892 4893 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4894 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4895 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4896 effect(KILL cr); 4897 4898 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4899 "andl $dst, right_n_bits($mask, 16)" %} 4900 ins_encode %{ 4901 Register Rdst = $dst$$Register; 4902 __ movzwq(Rdst, $mem$$Address); 4903 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4904 %} 4905 ins_pipe(ialu_reg_mem); 4906 %} 4907 4908 // Load Integer 4909 instruct loadI(rRegI dst, memory mem) 4910 %{ 4911 match(Set dst (LoadI mem)); 4912 4913 ins_cost(125); 4914 format %{ "movl $dst, $mem\t# int" %} 4915 4916 ins_encode %{ 4917 __ movl($dst$$Register, $mem$$Address); 4918 %} 4919 4920 ins_pipe(ialu_reg_mem); 4921 %} 4922 4923 // Load Integer (32 bit signed) to Byte (8 bit signed) 4924 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4925 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4926 4927 ins_cost(125); 4928 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4929 ins_encode %{ 4930 __ movsbl($dst$$Register, $mem$$Address); 4931 %} 4932 ins_pipe(ialu_reg_mem); 4933 %} 4934 4935 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4936 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4937 match(Set dst (AndI (LoadI mem) mask)); 4938 4939 ins_cost(125); 4940 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4941 ins_encode %{ 4942 __ movzbl($dst$$Register, $mem$$Address); 4943 %} 4944 ins_pipe(ialu_reg_mem); 4945 %} 4946 4947 // Load Integer (32 bit signed) to Short (16 bit signed) 4948 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4949 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4950 4951 ins_cost(125); 4952 format %{ "movswl $dst, $mem\t# int -> short" %} 4953 ins_encode %{ 4954 __ movswl($dst$$Register, $mem$$Address); 4955 %} 4956 ins_pipe(ialu_reg_mem); 4957 %} 4958 4959 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4960 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4961 match(Set dst (AndI (LoadI mem) mask)); 4962 4963 ins_cost(125); 4964 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4965 ins_encode %{ 4966 __ movzwl($dst$$Register, $mem$$Address); 4967 %} 4968 ins_pipe(ialu_reg_mem); 4969 %} 4970 4971 // Load Integer into Long Register 4972 instruct loadI2L(rRegL dst, memory mem) 4973 %{ 4974 match(Set dst (ConvI2L (LoadI mem))); 4975 4976 ins_cost(125); 4977 format %{ "movslq $dst, $mem\t# int -> long" %} 4978 4979 ins_encode %{ 4980 __ movslq($dst$$Register, $mem$$Address); 4981 %} 4982 4983 ins_pipe(ialu_reg_mem); 4984 %} 4985 4986 // Load Integer with mask 0xFF into Long Register 4987 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4988 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4989 4990 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4991 ins_encode %{ 4992 __ movzbq($dst$$Register, $mem$$Address); 4993 %} 4994 ins_pipe(ialu_reg_mem); 4995 %} 4996 4997 // Load Integer with mask 0xFFFF into Long Register 4998 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4999 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5000 5001 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5002 ins_encode %{ 5003 __ movzwq($dst$$Register, $mem$$Address); 5004 %} 5005 ins_pipe(ialu_reg_mem); 5006 %} 5007 5008 // Load Integer with a 31-bit mask into Long Register 5009 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5010 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5011 effect(KILL cr); 5012 5013 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5014 "andl $dst, $mask" %} 5015 ins_encode %{ 5016 Register Rdst = $dst$$Register; 5017 __ movl(Rdst, $mem$$Address); 5018 __ andl(Rdst, $mask$$constant); 5019 %} 5020 ins_pipe(ialu_reg_mem); 5021 %} 5022 5023 // Load Unsigned Integer into Long Register 5024 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5025 %{ 5026 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5027 5028 ins_cost(125); 5029 format %{ "movl $dst, $mem\t# uint -> long" %} 5030 5031 ins_encode %{ 5032 __ movl($dst$$Register, $mem$$Address); 5033 %} 5034 5035 ins_pipe(ialu_reg_mem); 5036 %} 5037 5038 // Load Long 5039 instruct loadL(rRegL dst, memory mem) 5040 %{ 5041 match(Set dst (LoadL mem)); 5042 5043 ins_cost(125); 5044 format %{ "movq $dst, $mem\t# long" %} 5045 5046 ins_encode %{ 5047 __ movq($dst$$Register, $mem$$Address); 5048 %} 5049 5050 ins_pipe(ialu_reg_mem); // XXX 5051 %} 5052 5053 // Load Range 5054 instruct loadRange(rRegI dst, memory mem) 5055 %{ 5056 match(Set dst (LoadRange mem)); 5057 5058 ins_cost(125); // XXX 5059 format %{ "movl $dst, $mem\t# range" %} 5060 opcode(0x8B); 5061 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5062 ins_pipe(ialu_reg_mem); 5063 %} 5064 5065 // Load Pointer 5066 instruct loadP(rRegP dst, memory mem) 5067 %{ 5068 match(Set dst (LoadP mem)); 5069 5070 ins_cost(125); // XXX 5071 format %{ "movq $dst, $mem\t# ptr" %} 5072 opcode(0x8B); 5073 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5074 ins_pipe(ialu_reg_mem); // XXX 5075 %} 5076 5077 // Load Compressed Pointer 5078 instruct loadN(rRegN dst, memory mem) 5079 %{ 5080 match(Set dst (LoadN mem)); 5081 5082 ins_cost(125); // XXX 5083 format %{ "movl $dst, $mem\t# compressed ptr" %} 5084 ins_encode %{ 5085 __ movl($dst$$Register, $mem$$Address); 5086 %} 5087 ins_pipe(ialu_reg_mem); // XXX 5088 %} 5089 5090 5091 // Load Klass Pointer 5092 instruct loadKlass(rRegP dst, memory mem) 5093 %{ 5094 match(Set dst (LoadKlass mem)); 5095 5096 ins_cost(125); // XXX 5097 format %{ "movq $dst, $mem\t# class" %} 5098 opcode(0x8B); 5099 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5100 ins_pipe(ialu_reg_mem); // XXX 5101 %} 5102 5103 // Load narrow Klass Pointer 5104 instruct loadNKlass(rRegN dst, memory mem) 5105 %{ 5106 match(Set dst (LoadNKlass mem)); 5107 5108 ins_cost(125); // XXX 5109 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5110 ins_encode %{ 5111 __ movl($dst$$Register, $mem$$Address); 5112 %} 5113 ins_pipe(ialu_reg_mem); // XXX 5114 %} 5115 5116 // Load Float 5117 instruct loadF(regF dst, memory mem) 5118 %{ 5119 match(Set dst (LoadF mem)); 5120 5121 ins_cost(145); // XXX 5122 format %{ "movss $dst, $mem\t# float" %} 5123 ins_encode %{ 5124 __ movflt($dst$$XMMRegister, $mem$$Address); 5125 %} 5126 ins_pipe(pipe_slow); // XXX 5127 %} 5128 5129 // Load Double 5130 instruct loadD_partial(regD dst, memory mem) 5131 %{ 5132 predicate(!UseXmmLoadAndClearUpper); 5133 match(Set dst (LoadD mem)); 5134 5135 ins_cost(145); // XXX 5136 format %{ "movlpd $dst, $mem\t# double" %} 5137 ins_encode %{ 5138 __ movdbl($dst$$XMMRegister, $mem$$Address); 5139 %} 5140 ins_pipe(pipe_slow); // XXX 5141 %} 5142 5143 instruct loadD(regD dst, memory mem) 5144 %{ 5145 predicate(UseXmmLoadAndClearUpper); 5146 match(Set dst (LoadD mem)); 5147 5148 ins_cost(145); // XXX 5149 format %{ "movsd $dst, $mem\t# double" %} 5150 ins_encode %{ 5151 __ movdbl($dst$$XMMRegister, $mem$$Address); 5152 %} 5153 ins_pipe(pipe_slow); // XXX 5154 %} 5155 5156 // Load Effective Address 5157 instruct leaP8(rRegP dst, indOffset8 mem) 5158 %{ 5159 match(Set dst mem); 5160 5161 ins_cost(110); // XXX 5162 format %{ "leaq $dst, $mem\t# ptr 8" %} 5163 opcode(0x8D); 5164 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5165 ins_pipe(ialu_reg_reg_fat); 5166 %} 5167 5168 instruct leaP32(rRegP dst, indOffset32 mem) 5169 %{ 5170 match(Set dst mem); 5171 5172 ins_cost(110); 5173 format %{ "leaq $dst, $mem\t# ptr 32" %} 5174 opcode(0x8D); 5175 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5176 ins_pipe(ialu_reg_reg_fat); 5177 %} 5178 5179 // instruct leaPIdx(rRegP dst, indIndex mem) 5180 // %{ 5181 // match(Set dst mem); 5182 5183 // ins_cost(110); 5184 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5185 // opcode(0x8D); 5186 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5187 // ins_pipe(ialu_reg_reg_fat); 5188 // %} 5189 5190 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5191 %{ 5192 match(Set dst mem); 5193 5194 ins_cost(110); 5195 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5196 opcode(0x8D); 5197 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5198 ins_pipe(ialu_reg_reg_fat); 5199 %} 5200 5201 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5202 %{ 5203 match(Set dst mem); 5204 5205 ins_cost(110); 5206 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5207 opcode(0x8D); 5208 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5209 ins_pipe(ialu_reg_reg_fat); 5210 %} 5211 5212 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5213 %{ 5214 match(Set dst mem); 5215 5216 ins_cost(110); 5217 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5218 opcode(0x8D); 5219 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5220 ins_pipe(ialu_reg_reg_fat); 5221 %} 5222 5223 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5224 %{ 5225 match(Set dst mem); 5226 5227 ins_cost(110); 5228 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5229 opcode(0x8D); 5230 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5231 ins_pipe(ialu_reg_reg_fat); 5232 %} 5233 5234 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5235 %{ 5236 match(Set dst mem); 5237 5238 ins_cost(110); 5239 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5240 opcode(0x8D); 5241 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5242 ins_pipe(ialu_reg_reg_fat); 5243 %} 5244 5245 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5246 %{ 5247 match(Set dst mem); 5248 5249 ins_cost(110); 5250 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5251 opcode(0x8D); 5252 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5253 ins_pipe(ialu_reg_reg_fat); 5254 %} 5255 5256 // Load Effective Address which uses Narrow (32-bits) oop 5257 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5258 %{ 5259 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5260 match(Set dst mem); 5261 5262 ins_cost(110); 5263 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5264 opcode(0x8D); 5265 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5266 ins_pipe(ialu_reg_reg_fat); 5267 %} 5268 5269 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5270 %{ 5271 predicate(Universe::narrow_oop_shift() == 0); 5272 match(Set dst mem); 5273 5274 ins_cost(110); // XXX 5275 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5276 opcode(0x8D); 5277 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5278 ins_pipe(ialu_reg_reg_fat); 5279 %} 5280 5281 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5282 %{ 5283 predicate(Universe::narrow_oop_shift() == 0); 5284 match(Set dst mem); 5285 5286 ins_cost(110); 5287 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5288 opcode(0x8D); 5289 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5290 ins_pipe(ialu_reg_reg_fat); 5291 %} 5292 5293 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5294 %{ 5295 predicate(Universe::narrow_oop_shift() == 0); 5296 match(Set dst mem); 5297 5298 ins_cost(110); 5299 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5300 opcode(0x8D); 5301 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5302 ins_pipe(ialu_reg_reg_fat); 5303 %} 5304 5305 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5306 %{ 5307 predicate(Universe::narrow_oop_shift() == 0); 5308 match(Set dst mem); 5309 5310 ins_cost(110); 5311 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5312 opcode(0x8D); 5313 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5314 ins_pipe(ialu_reg_reg_fat); 5315 %} 5316 5317 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5318 %{ 5319 predicate(Universe::narrow_oop_shift() == 0); 5320 match(Set dst mem); 5321 5322 ins_cost(110); 5323 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5324 opcode(0x8D); 5325 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5326 ins_pipe(ialu_reg_reg_fat); 5327 %} 5328 5329 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5330 %{ 5331 predicate(Universe::narrow_oop_shift() == 0); 5332 match(Set dst mem); 5333 5334 ins_cost(110); 5335 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5336 opcode(0x8D); 5337 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5338 ins_pipe(ialu_reg_reg_fat); 5339 %} 5340 5341 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5342 %{ 5343 predicate(Universe::narrow_oop_shift() == 0); 5344 match(Set dst mem); 5345 5346 ins_cost(110); 5347 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5348 opcode(0x8D); 5349 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5350 ins_pipe(ialu_reg_reg_fat); 5351 %} 5352 5353 instruct loadConI(rRegI dst, immI src) 5354 %{ 5355 match(Set dst src); 5356 5357 format %{ "movl $dst, $src\t# int" %} 5358 ins_encode(load_immI(dst, src)); 5359 ins_pipe(ialu_reg_fat); // XXX 5360 %} 5361 5362 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5363 %{ 5364 match(Set dst src); 5365 effect(KILL cr); 5366 5367 ins_cost(50); 5368 format %{ "xorl $dst, $dst\t# int" %} 5369 opcode(0x33); /* + rd */ 5370 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5371 ins_pipe(ialu_reg); 5372 %} 5373 5374 instruct loadConL(rRegL dst, immL src) 5375 %{ 5376 match(Set dst src); 5377 5378 ins_cost(150); 5379 format %{ "movq $dst, $src\t# long" %} 5380 ins_encode(load_immL(dst, src)); 5381 ins_pipe(ialu_reg); 5382 %} 5383 5384 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5385 %{ 5386 match(Set dst src); 5387 effect(KILL cr); 5388 5389 ins_cost(50); 5390 format %{ "xorl $dst, $dst\t# long" %} 5391 opcode(0x33); /* + rd */ 5392 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5393 ins_pipe(ialu_reg); // XXX 5394 %} 5395 5396 instruct loadConUL32(rRegL dst, immUL32 src) 5397 %{ 5398 match(Set dst src); 5399 5400 ins_cost(60); 5401 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5402 ins_encode(load_immUL32(dst, src)); 5403 ins_pipe(ialu_reg); 5404 %} 5405 5406 instruct loadConL32(rRegL dst, immL32 src) 5407 %{ 5408 match(Set dst src); 5409 5410 ins_cost(70); 5411 format %{ "movq $dst, $src\t# long (32-bit)" %} 5412 ins_encode(load_immL32(dst, src)); 5413 ins_pipe(ialu_reg); 5414 %} 5415 5416 instruct loadConP(rRegP dst, immP con) %{ 5417 match(Set dst con); 5418 5419 format %{ "movq $dst, $con\t# ptr" %} 5420 ins_encode(load_immP(dst, con)); 5421 ins_pipe(ialu_reg_fat); // XXX 5422 %} 5423 5424 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5425 %{ 5426 match(Set dst src); 5427 effect(KILL cr); 5428 5429 ins_cost(50); 5430 format %{ "xorl $dst, $dst\t# ptr" %} 5431 opcode(0x33); /* + rd */ 5432 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5433 ins_pipe(ialu_reg); 5434 %} 5435 5436 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5437 %{ 5438 match(Set dst src); 5439 effect(KILL cr); 5440 5441 ins_cost(60); 5442 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5443 ins_encode(load_immP31(dst, src)); 5444 ins_pipe(ialu_reg); 5445 %} 5446 5447 instruct loadConF(regF dst, immF con) %{ 5448 match(Set dst con); 5449 ins_cost(125); 5450 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5451 ins_encode %{ 5452 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5453 %} 5454 ins_pipe(pipe_slow); 5455 %} 5456 5457 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5458 match(Set dst src); 5459 effect(KILL cr); 5460 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5461 ins_encode %{ 5462 __ xorq($dst$$Register, $dst$$Register); 5463 %} 5464 ins_pipe(ialu_reg); 5465 %} 5466 5467 instruct loadConN(rRegN dst, immN src) %{ 5468 match(Set dst src); 5469 5470 ins_cost(125); 5471 format %{ "movl $dst, $src\t# compressed ptr" %} 5472 ins_encode %{ 5473 address con = (address)$src$$constant; 5474 if (con == NULL) { 5475 ShouldNotReachHere(); 5476 } else { 5477 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5478 } 5479 %} 5480 ins_pipe(ialu_reg_fat); // XXX 5481 %} 5482 5483 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5484 match(Set dst src); 5485 5486 ins_cost(125); 5487 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5488 ins_encode %{ 5489 address con = (address)$src$$constant; 5490 if (con == NULL) { 5491 ShouldNotReachHere(); 5492 } else { 5493 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5494 } 5495 %} 5496 ins_pipe(ialu_reg_fat); // XXX 5497 %} 5498 5499 instruct loadConF0(regF dst, immF0 src) 5500 %{ 5501 match(Set dst src); 5502 ins_cost(100); 5503 5504 format %{ "xorps $dst, $dst\t# float 0.0" %} 5505 ins_encode %{ 5506 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5507 %} 5508 ins_pipe(pipe_slow); 5509 %} 5510 5511 // Use the same format since predicate() can not be used here. 5512 instruct loadConD(regD dst, immD con) %{ 5513 match(Set dst con); 5514 ins_cost(125); 5515 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5516 ins_encode %{ 5517 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5518 %} 5519 ins_pipe(pipe_slow); 5520 %} 5521 5522 instruct loadConD0(regD dst, immD0 src) 5523 %{ 5524 match(Set dst src); 5525 ins_cost(100); 5526 5527 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5528 ins_encode %{ 5529 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5530 %} 5531 ins_pipe(pipe_slow); 5532 %} 5533 5534 instruct loadSSI(rRegI dst, stackSlotI src) 5535 %{ 5536 match(Set dst src); 5537 5538 ins_cost(125); 5539 format %{ "movl $dst, $src\t# int stk" %} 5540 opcode(0x8B); 5541 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5542 ins_pipe(ialu_reg_mem); 5543 %} 5544 5545 instruct loadSSL(rRegL dst, stackSlotL src) 5546 %{ 5547 match(Set dst src); 5548 5549 ins_cost(125); 5550 format %{ "movq $dst, $src\t# long stk" %} 5551 opcode(0x8B); 5552 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5553 ins_pipe(ialu_reg_mem); 5554 %} 5555 5556 instruct loadSSP(rRegP dst, stackSlotP src) 5557 %{ 5558 match(Set dst src); 5559 5560 ins_cost(125); 5561 format %{ "movq $dst, $src\t# ptr stk" %} 5562 opcode(0x8B); 5563 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5564 ins_pipe(ialu_reg_mem); 5565 %} 5566 5567 instruct loadSSF(regF dst, stackSlotF src) 5568 %{ 5569 match(Set dst src); 5570 5571 ins_cost(125); 5572 format %{ "movss $dst, $src\t# float stk" %} 5573 ins_encode %{ 5574 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5575 %} 5576 ins_pipe(pipe_slow); // XXX 5577 %} 5578 5579 // Use the same format since predicate() can not be used here. 5580 instruct loadSSD(regD dst, stackSlotD src) 5581 %{ 5582 match(Set dst src); 5583 5584 ins_cost(125); 5585 format %{ "movsd $dst, $src\t# double stk" %} 5586 ins_encode %{ 5587 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5588 %} 5589 ins_pipe(pipe_slow); // XXX 5590 %} 5591 5592 // Prefetch instructions for allocation. 5593 // Must be safe to execute with invalid address (cannot fault). 5594 5595 instruct prefetchAlloc( memory mem ) %{ 5596 predicate(AllocatePrefetchInstr==3); 5597 match(PrefetchAllocation mem); 5598 ins_cost(125); 5599 5600 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5601 ins_encode %{ 5602 __ prefetchw($mem$$Address); 5603 %} 5604 ins_pipe(ialu_mem); 5605 %} 5606 5607 instruct prefetchAllocNTA( memory mem ) %{ 5608 predicate(AllocatePrefetchInstr==0); 5609 match(PrefetchAllocation mem); 5610 ins_cost(125); 5611 5612 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5613 ins_encode %{ 5614 __ prefetchnta($mem$$Address); 5615 %} 5616 ins_pipe(ialu_mem); 5617 %} 5618 5619 instruct prefetchAllocT0( memory mem ) %{ 5620 predicate(AllocatePrefetchInstr==1); 5621 match(PrefetchAllocation mem); 5622 ins_cost(125); 5623 5624 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5625 ins_encode %{ 5626 __ prefetcht0($mem$$Address); 5627 %} 5628 ins_pipe(ialu_mem); 5629 %} 5630 5631 instruct prefetchAllocT2( memory mem ) %{ 5632 predicate(AllocatePrefetchInstr==2); 5633 match(PrefetchAllocation mem); 5634 ins_cost(125); 5635 5636 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5637 ins_encode %{ 5638 __ prefetcht2($mem$$Address); 5639 %} 5640 ins_pipe(ialu_mem); 5641 %} 5642 5643 //----------Store Instructions------------------------------------------------- 5644 5645 // Store Byte 5646 instruct storeB(memory mem, rRegI src) 5647 %{ 5648 match(Set mem (StoreB mem src)); 5649 5650 ins_cost(125); // XXX 5651 format %{ "movb $mem, $src\t# byte" %} 5652 opcode(0x88); 5653 ins_encode(shenandoah_store_addr_check(mem), REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5654 ins_pipe(ialu_mem_reg); 5655 %} 5656 5657 // Store Char/Short 5658 instruct storeC(memory mem, rRegI src) 5659 %{ 5660 match(Set mem (StoreC mem src)); 5661 5662 ins_cost(125); // XXX 5663 format %{ "movw $mem, $src\t# char/short" %} 5664 opcode(0x89); 5665 ins_encode(shenandoah_store_addr_check(mem), SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5666 ins_pipe(ialu_mem_reg); 5667 %} 5668 5669 // Store Integer 5670 instruct storeI(memory mem, rRegI src) 5671 %{ 5672 match(Set mem (StoreI mem src)); 5673 5674 ins_cost(125); // XXX 5675 format %{ "movl $mem, $src\t# int" %} 5676 opcode(0x89); 5677 ins_encode(shenandoah_store_addr_check(mem), REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5678 ins_pipe(ialu_mem_reg); 5679 %} 5680 5681 // Store Long 5682 instruct storeL(memory mem, rRegL src) 5683 %{ 5684 match(Set mem (StoreL mem src)); 5685 5686 ins_cost(125); // XXX 5687 format %{ "movq $mem, $src\t# long" %} 5688 opcode(0x89); 5689 ins_encode(shenandoah_store_addr_check(mem), REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5690 ins_pipe(ialu_mem_reg); // XXX 5691 %} 5692 5693 // Store Pointer 5694 instruct storeP(memory mem, any_RegP src) 5695 %{ 5696 match(Set mem (StoreP mem src)); 5697 5698 ins_cost(125); // XXX 5699 format %{ "movq $mem, $src\t# ptr" %} 5700 opcode(0x89); 5701 ins_encode(shenandoah_store_check(mem, src), REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5702 ins_pipe(ialu_mem_reg); 5703 %} 5704 5705 instruct storeImmP0(memory mem, immP0 zero) 5706 %{ 5707 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5708 match(Set mem (StoreP mem zero)); 5709 5710 ins_cost(125); // XXX 5711 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5712 ins_encode %{ 5713 __ shenandoah_store_addr_check($mem$$Address); 5714 __ movq($mem$$Address, r12); 5715 %} 5716 ins_pipe(ialu_mem_reg); 5717 %} 5718 5719 // Store NULL Pointer, mark word, or other simple pointer constant. 5720 instruct storeImmP(memory mem, immP31 src) 5721 %{ 5722 match(Set mem (StoreP mem src)); 5723 5724 ins_cost(150); // XXX 5725 format %{ "movq $mem, $src\t# ptr" %} 5726 opcode(0xC7); /* C7 /0 */ 5727 ins_encode(shenandoah_store_addr_check(mem), REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5728 ins_pipe(ialu_mem_imm); 5729 %} 5730 5731 // Store Compressed Pointer 5732 instruct storeN(memory mem, rRegN src) 5733 %{ 5734 match(Set mem (StoreN mem src)); 5735 5736 ins_cost(125); // XXX 5737 format %{ "movl $mem, $src\t# compressed ptr" %} 5738 ins_encode %{ 5739 __ shenandoah_store_addr_check($mem$$Address); 5740 __ movl($mem$$Address, $src$$Register); 5741 %} 5742 ins_pipe(ialu_mem_reg); 5743 %} 5744 5745 instruct storeNKlass(memory mem, rRegN src) 5746 %{ 5747 match(Set mem (StoreNKlass mem src)); 5748 5749 ins_cost(125); // XXX 5750 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5751 ins_encode %{ 5752 __ shenandoah_store_addr_check($mem$$Address); 5753 __ movl($mem$$Address, $src$$Register); 5754 %} 5755 ins_pipe(ialu_mem_reg); 5756 %} 5757 5758 instruct storeImmN0(memory mem, immN0 zero) 5759 %{ 5760 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5761 match(Set mem (StoreN mem zero)); 5762 5763 ins_cost(125); // XXX 5764 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5765 ins_encode %{ 5766 __ shenandoah_store_addr_check($mem$$Address); 5767 __ movl($mem$$Address, r12); 5768 %} 5769 ins_pipe(ialu_mem_reg); 5770 %} 5771 5772 instruct storeImmN(memory mem, immN src) 5773 %{ 5774 match(Set mem (StoreN mem src)); 5775 5776 ins_cost(150); // XXX 5777 format %{ "movl $mem, $src\t# compressed ptr" %} 5778 ins_encode %{ 5779 address con = (address)$src$$constant; 5780 __ shenandoah_store_addr_check($mem$$Address); 5781 if (con == NULL) { 5782 __ movl($mem$$Address, (int32_t)0); 5783 } else { 5784 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5785 } 5786 %} 5787 ins_pipe(ialu_mem_imm); 5788 %} 5789 5790 instruct storeImmNKlass(memory mem, immNKlass src) 5791 %{ 5792 match(Set mem (StoreNKlass mem src)); 5793 5794 ins_cost(150); // XXX 5795 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5796 ins_encode %{ 5797 __ shenandoah_store_addr_check($mem$$Address); 5798 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5799 %} 5800 ins_pipe(ialu_mem_imm); 5801 %} 5802 5803 // Store Integer Immediate 5804 instruct storeImmI0(memory mem, immI0 zero) 5805 %{ 5806 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5807 match(Set mem (StoreI mem zero)); 5808 5809 ins_cost(125); // XXX 5810 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5811 ins_encode %{ 5812 __ shenandoah_store_addr_check($mem$$Address); 5813 __ movl($mem$$Address, r12); 5814 %} 5815 ins_pipe(ialu_mem_reg); 5816 %} 5817 5818 instruct storeImmI(memory mem, immI src) 5819 %{ 5820 match(Set mem (StoreI mem src)); 5821 5822 ins_cost(150); 5823 format %{ "movl $mem, $src\t# int" %} 5824 opcode(0xC7); /* C7 /0 */ 5825 ins_encode(shenandoah_store_addr_check(mem), REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5826 ins_pipe(ialu_mem_imm); 5827 %} 5828 5829 // Store Long Immediate 5830 instruct storeImmL0(memory mem, immL0 zero) 5831 %{ 5832 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5833 match(Set mem (StoreL mem zero)); 5834 5835 ins_cost(125); // XXX 5836 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5837 ins_encode %{ 5838 __ shenandoah_store_addr_check($mem$$Address); 5839 __ movq($mem$$Address, r12); 5840 %} 5841 ins_pipe(ialu_mem_reg); 5842 %} 5843 5844 instruct storeImmL(memory mem, immL32 src) 5845 %{ 5846 match(Set mem (StoreL mem src)); 5847 5848 ins_cost(150); 5849 format %{ "movq $mem, $src\t# long" %} 5850 opcode(0xC7); /* C7 /0 */ 5851 ins_encode(shenandoah_store_addr_check(mem), REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5852 ins_pipe(ialu_mem_imm); 5853 %} 5854 5855 // Store Short/Char Immediate 5856 instruct storeImmC0(memory mem, immI0 zero) 5857 %{ 5858 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5859 match(Set mem (StoreC mem zero)); 5860 5861 ins_cost(125); // XXX 5862 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5863 ins_encode %{ 5864 __ shenandoah_store_addr_check($mem$$Address); 5865 __ movw($mem$$Address, r12); 5866 %} 5867 ins_pipe(ialu_mem_reg); 5868 %} 5869 5870 instruct storeImmI16(memory mem, immI16 src) 5871 %{ 5872 predicate(UseStoreImmI16); 5873 match(Set mem (StoreC mem src)); 5874 5875 ins_cost(150); 5876 format %{ "movw $mem, $src\t# short/char" %} 5877 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 5878 ins_encode(shenandoah_store_addr_check(mem), SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 5879 ins_pipe(ialu_mem_imm); 5880 %} 5881 5882 // Store Byte Immediate 5883 instruct storeImmB0(memory mem, immI0 zero) 5884 %{ 5885 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5886 match(Set mem (StoreB mem zero)); 5887 5888 ins_cost(125); // XXX 5889 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5890 ins_encode %{ 5891 __ shenandoah_store_addr_check($mem$$Address); 5892 __ movb($mem$$Address, r12); 5893 %} 5894 ins_pipe(ialu_mem_reg); 5895 %} 5896 5897 instruct storeImmB(memory mem, immI8 src) 5898 %{ 5899 match(Set mem (StoreB mem src)); 5900 5901 ins_cost(150); // XXX 5902 format %{ "movb $mem, $src\t# byte" %} 5903 opcode(0xC6); /* C6 /0 */ 5904 ins_encode(shenandoah_store_addr_check(mem), REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5905 ins_pipe(ialu_mem_imm); 5906 %} 5907 5908 // Store CMS card-mark Immediate 5909 instruct storeImmCM0_reg(memory mem, immI0 zero) 5910 %{ 5911 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5912 match(Set mem (StoreCM mem zero)); 5913 5914 ins_cost(125); // XXX 5915 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5916 ins_encode %{ 5917 __ movb($mem$$Address, r12); 5918 %} 5919 ins_pipe(ialu_mem_reg); 5920 %} 5921 5922 instruct storeImmCM0(memory mem, immI0 src) 5923 %{ 5924 match(Set mem (StoreCM mem src)); 5925 5926 ins_cost(150); // XXX 5927 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5928 opcode(0xC6); /* C6 /0 */ 5929 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5930 ins_pipe(ialu_mem_imm); 5931 %} 5932 5933 // Store Float 5934 instruct storeF(memory mem, regF src) 5935 %{ 5936 match(Set mem (StoreF mem src)); 5937 5938 ins_cost(95); // XXX 5939 format %{ "movss $mem, $src\t# float" %} 5940 ins_encode %{ 5941 __ shenandoah_store_addr_check($mem$$Address); 5942 __ movflt($mem$$Address, $src$$XMMRegister); 5943 %} 5944 ins_pipe(pipe_slow); // XXX 5945 %} 5946 5947 // Store immediate Float value (it is faster than store from XMM register) 5948 instruct storeF0(memory mem, immF0 zero) 5949 %{ 5950 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5951 match(Set mem (StoreF mem zero)); 5952 5953 ins_cost(25); // XXX 5954 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5955 ins_encode %{ 5956 __ shenandoah_store_addr_check($mem$$Address); 5957 __ movl($mem$$Address, r12); 5958 %} 5959 ins_pipe(ialu_mem_reg); 5960 %} 5961 5962 instruct storeF_imm(memory mem, immF src) 5963 %{ 5964 match(Set mem (StoreF mem src)); 5965 5966 ins_cost(50); 5967 format %{ "movl $mem, $src\t# float" %} 5968 opcode(0xC7); /* C7 /0 */ 5969 ins_encode(shenandoah_store_addr_check(mem), REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5970 ins_pipe(ialu_mem_imm); 5971 %} 5972 5973 // Store Double 5974 instruct storeD(memory mem, regD src) 5975 %{ 5976 match(Set mem (StoreD mem src)); 5977 5978 ins_cost(95); // XXX 5979 format %{ "movsd $mem, $src\t# double" %} 5980 ins_encode %{ 5981 __ shenandoah_store_addr_check($mem$$Address); 5982 __ movdbl($mem$$Address, $src$$XMMRegister); 5983 %} 5984 ins_pipe(pipe_slow); // XXX 5985 %} 5986 5987 // Store immediate double 0.0 (it is faster than store from XMM register) 5988 instruct storeD0_imm(memory mem, immD0 src) 5989 %{ 5990 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 5991 match(Set mem (StoreD mem src)); 5992 5993 ins_cost(50); 5994 format %{ "movq $mem, $src\t# double 0." %} 5995 opcode(0xC7); /* C7 /0 */ 5996 ins_encode(shenandoah_store_addr_check(mem), REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5997 ins_pipe(ialu_mem_imm); 5998 %} 5999 6000 instruct storeD0(memory mem, immD0 zero) 6001 %{ 6002 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6003 match(Set mem (StoreD mem zero)); 6004 6005 ins_cost(25); // XXX 6006 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6007 ins_encode %{ 6008 __ shenandoah_store_addr_check($mem$$Address); 6009 __ movq($mem$$Address, r12); 6010 %} 6011 ins_pipe(ialu_mem_reg); 6012 %} 6013 6014 instruct storeSSI(stackSlotI dst, rRegI src) 6015 %{ 6016 match(Set dst src); 6017 6018 ins_cost(100); 6019 format %{ "movl $dst, $src\t# int stk" %} 6020 opcode(0x89); 6021 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6022 ins_pipe( ialu_mem_reg ); 6023 %} 6024 6025 instruct storeSSL(stackSlotL dst, rRegL src) 6026 %{ 6027 match(Set dst src); 6028 6029 ins_cost(100); 6030 format %{ "movq $dst, $src\t# long stk" %} 6031 opcode(0x89); 6032 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6033 ins_pipe(ialu_mem_reg); 6034 %} 6035 6036 instruct storeSSP(stackSlotP dst, rRegP src) 6037 %{ 6038 match(Set dst src); 6039 6040 ins_cost(100); 6041 format %{ "movq $dst, $src\t# ptr stk" %} 6042 opcode(0x89); 6043 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6044 ins_pipe(ialu_mem_reg); 6045 %} 6046 6047 instruct storeSSF(stackSlotF dst, regF src) 6048 %{ 6049 match(Set dst src); 6050 6051 ins_cost(95); // XXX 6052 format %{ "movss $dst, $src\t# float stk" %} 6053 ins_encode %{ 6054 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6055 %} 6056 ins_pipe(pipe_slow); // XXX 6057 %} 6058 6059 instruct storeSSD(stackSlotD dst, regD src) 6060 %{ 6061 match(Set dst src); 6062 6063 ins_cost(95); // XXX 6064 format %{ "movsd $dst, $src\t# double stk" %} 6065 ins_encode %{ 6066 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6067 %} 6068 ins_pipe(pipe_slow); // XXX 6069 %} 6070 6071 //----------BSWAP Instructions------------------------------------------------- 6072 instruct bytes_reverse_int(rRegI dst) %{ 6073 match(Set dst (ReverseBytesI dst)); 6074 6075 format %{ "bswapl $dst" %} 6076 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6077 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6078 ins_pipe( ialu_reg ); 6079 %} 6080 6081 instruct bytes_reverse_long(rRegL dst) %{ 6082 match(Set dst (ReverseBytesL dst)); 6083 6084 format %{ "bswapq $dst" %} 6085 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6086 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6087 ins_pipe( ialu_reg); 6088 %} 6089 6090 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6091 match(Set dst (ReverseBytesUS dst)); 6092 effect(KILL cr); 6093 6094 format %{ "bswapl $dst\n\t" 6095 "shrl $dst,16\n\t" %} 6096 ins_encode %{ 6097 __ bswapl($dst$$Register); 6098 __ shrl($dst$$Register, 16); 6099 %} 6100 ins_pipe( ialu_reg ); 6101 %} 6102 6103 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6104 match(Set dst (ReverseBytesS dst)); 6105 effect(KILL cr); 6106 6107 format %{ "bswapl $dst\n\t" 6108 "sar $dst,16\n\t" %} 6109 ins_encode %{ 6110 __ bswapl($dst$$Register); 6111 __ sarl($dst$$Register, 16); 6112 %} 6113 ins_pipe( ialu_reg ); 6114 %} 6115 6116 //---------- Zeros Count Instructions ------------------------------------------ 6117 6118 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6119 predicate(UseCountLeadingZerosInstruction); 6120 match(Set dst (CountLeadingZerosI src)); 6121 effect(KILL cr); 6122 6123 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6124 ins_encode %{ 6125 __ lzcntl($dst$$Register, $src$$Register); 6126 %} 6127 ins_pipe(ialu_reg); 6128 %} 6129 6130 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6131 predicate(!UseCountLeadingZerosInstruction); 6132 match(Set dst (CountLeadingZerosI src)); 6133 effect(KILL cr); 6134 6135 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6136 "jnz skip\n\t" 6137 "movl $dst, -1\n" 6138 "skip:\n\t" 6139 "negl $dst\n\t" 6140 "addl $dst, 31" %} 6141 ins_encode %{ 6142 Register Rdst = $dst$$Register; 6143 Register Rsrc = $src$$Register; 6144 Label skip; 6145 __ bsrl(Rdst, Rsrc); 6146 __ jccb(Assembler::notZero, skip); 6147 __ movl(Rdst, -1); 6148 __ bind(skip); 6149 __ negl(Rdst); 6150 __ addl(Rdst, BitsPerInt - 1); 6151 %} 6152 ins_pipe(ialu_reg); 6153 %} 6154 6155 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6156 predicate(UseCountLeadingZerosInstruction); 6157 match(Set dst (CountLeadingZerosL src)); 6158 effect(KILL cr); 6159 6160 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6161 ins_encode %{ 6162 __ lzcntq($dst$$Register, $src$$Register); 6163 %} 6164 ins_pipe(ialu_reg); 6165 %} 6166 6167 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6168 predicate(!UseCountLeadingZerosInstruction); 6169 match(Set dst (CountLeadingZerosL src)); 6170 effect(KILL cr); 6171 6172 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6173 "jnz skip\n\t" 6174 "movl $dst, -1\n" 6175 "skip:\n\t" 6176 "negl $dst\n\t" 6177 "addl $dst, 63" %} 6178 ins_encode %{ 6179 Register Rdst = $dst$$Register; 6180 Register Rsrc = $src$$Register; 6181 Label skip; 6182 __ bsrq(Rdst, Rsrc); 6183 __ jccb(Assembler::notZero, skip); 6184 __ movl(Rdst, -1); 6185 __ bind(skip); 6186 __ negl(Rdst); 6187 __ addl(Rdst, BitsPerLong - 1); 6188 %} 6189 ins_pipe(ialu_reg); 6190 %} 6191 6192 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6193 predicate(UseCountTrailingZerosInstruction); 6194 match(Set dst (CountTrailingZerosI src)); 6195 effect(KILL cr); 6196 6197 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6198 ins_encode %{ 6199 __ tzcntl($dst$$Register, $src$$Register); 6200 %} 6201 ins_pipe(ialu_reg); 6202 %} 6203 6204 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6205 predicate(!UseCountTrailingZerosInstruction); 6206 match(Set dst (CountTrailingZerosI src)); 6207 effect(KILL cr); 6208 6209 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6210 "jnz done\n\t" 6211 "movl $dst, 32\n" 6212 "done:" %} 6213 ins_encode %{ 6214 Register Rdst = $dst$$Register; 6215 Label done; 6216 __ bsfl(Rdst, $src$$Register); 6217 __ jccb(Assembler::notZero, done); 6218 __ movl(Rdst, BitsPerInt); 6219 __ bind(done); 6220 %} 6221 ins_pipe(ialu_reg); 6222 %} 6223 6224 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6225 predicate(UseCountTrailingZerosInstruction); 6226 match(Set dst (CountTrailingZerosL src)); 6227 effect(KILL cr); 6228 6229 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6230 ins_encode %{ 6231 __ tzcntq($dst$$Register, $src$$Register); 6232 %} 6233 ins_pipe(ialu_reg); 6234 %} 6235 6236 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6237 predicate(!UseCountTrailingZerosInstruction); 6238 match(Set dst (CountTrailingZerosL src)); 6239 effect(KILL cr); 6240 6241 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6242 "jnz done\n\t" 6243 "movl $dst, 64\n" 6244 "done:" %} 6245 ins_encode %{ 6246 Register Rdst = $dst$$Register; 6247 Label done; 6248 __ bsfq(Rdst, $src$$Register); 6249 __ jccb(Assembler::notZero, done); 6250 __ movl(Rdst, BitsPerLong); 6251 __ bind(done); 6252 %} 6253 ins_pipe(ialu_reg); 6254 %} 6255 6256 6257 //---------- Population Count Instructions ------------------------------------- 6258 6259 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6260 predicate(UsePopCountInstruction); 6261 match(Set dst (PopCountI src)); 6262 effect(KILL cr); 6263 6264 format %{ "popcnt $dst, $src" %} 6265 ins_encode %{ 6266 __ popcntl($dst$$Register, $src$$Register); 6267 %} 6268 ins_pipe(ialu_reg); 6269 %} 6270 6271 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6272 predicate(UsePopCountInstruction); 6273 match(Set dst (PopCountI (LoadI mem))); 6274 effect(KILL cr); 6275 6276 format %{ "popcnt $dst, $mem" %} 6277 ins_encode %{ 6278 __ popcntl($dst$$Register, $mem$$Address); 6279 %} 6280 ins_pipe(ialu_reg); 6281 %} 6282 6283 // Note: Long.bitCount(long) returns an int. 6284 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6285 predicate(UsePopCountInstruction); 6286 match(Set dst (PopCountL src)); 6287 effect(KILL cr); 6288 6289 format %{ "popcnt $dst, $src" %} 6290 ins_encode %{ 6291 __ popcntq($dst$$Register, $src$$Register); 6292 %} 6293 ins_pipe(ialu_reg); 6294 %} 6295 6296 // Note: Long.bitCount(long) returns an int. 6297 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6298 predicate(UsePopCountInstruction); 6299 match(Set dst (PopCountL (LoadL mem))); 6300 effect(KILL cr); 6301 6302 format %{ "popcnt $dst, $mem" %} 6303 ins_encode %{ 6304 __ popcntq($dst$$Register, $mem$$Address); 6305 %} 6306 ins_pipe(ialu_reg); 6307 %} 6308 6309 6310 //----------MemBar Instructions----------------------------------------------- 6311 // Memory barrier flavors 6312 6313 instruct membar_acquire() 6314 %{ 6315 match(MemBarAcquire); 6316 match(LoadFence); 6317 ins_cost(0); 6318 6319 size(0); 6320 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6321 ins_encode(); 6322 ins_pipe(empty); 6323 %} 6324 6325 instruct membar_acquire_lock() 6326 %{ 6327 match(MemBarAcquireLock); 6328 ins_cost(0); 6329 6330 size(0); 6331 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6332 ins_encode(); 6333 ins_pipe(empty); 6334 %} 6335 6336 instruct membar_release() 6337 %{ 6338 match(MemBarRelease); 6339 match(StoreFence); 6340 ins_cost(0); 6341 6342 size(0); 6343 format %{ "MEMBAR-release ! (empty encoding)" %} 6344 ins_encode(); 6345 ins_pipe(empty); 6346 %} 6347 6348 instruct membar_release_lock() 6349 %{ 6350 match(MemBarReleaseLock); 6351 ins_cost(0); 6352 6353 size(0); 6354 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6355 ins_encode(); 6356 ins_pipe(empty); 6357 %} 6358 6359 instruct membar_volatile(rFlagsReg cr) %{ 6360 match(MemBarVolatile); 6361 effect(KILL cr); 6362 ins_cost(400); 6363 6364 format %{ 6365 $$template 6366 if (os::is_MP()) { 6367 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6368 } else { 6369 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6370 } 6371 %} 6372 ins_encode %{ 6373 __ membar(Assembler::StoreLoad); 6374 %} 6375 ins_pipe(pipe_slow); 6376 %} 6377 6378 instruct unnecessary_membar_volatile() 6379 %{ 6380 match(MemBarVolatile); 6381 predicate(Matcher::post_store_load_barrier(n)); 6382 ins_cost(0); 6383 6384 size(0); 6385 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6386 ins_encode(); 6387 ins_pipe(empty); 6388 %} 6389 6390 instruct membar_storestore() %{ 6391 match(MemBarStoreStore); 6392 ins_cost(0); 6393 6394 size(0); 6395 format %{ "MEMBAR-storestore (empty encoding)" %} 6396 ins_encode( ); 6397 ins_pipe(empty); 6398 %} 6399 6400 //----------Move Instructions-------------------------------------------------- 6401 6402 instruct castX2P(rRegP dst, rRegL src) 6403 %{ 6404 match(Set dst (CastX2P src)); 6405 6406 format %{ "movq $dst, $src\t# long->ptr" %} 6407 ins_encode %{ 6408 if ($dst$$reg != $src$$reg) { 6409 __ movptr($dst$$Register, $src$$Register); 6410 } 6411 %} 6412 ins_pipe(ialu_reg_reg); // XXX 6413 %} 6414 6415 instruct castP2X(rRegL dst, rRegP src) 6416 %{ 6417 match(Set dst (CastP2X src)); 6418 6419 format %{ "movq $dst, $src\t# ptr -> long" %} 6420 ins_encode %{ 6421 if ($dst$$reg != $src$$reg) { 6422 __ movptr($dst$$Register, $src$$Register); 6423 } 6424 %} 6425 ins_pipe(ialu_reg_reg); // XXX 6426 %} 6427 6428 // Convert oop into int for vectors alignment masking 6429 instruct convP2I(rRegI dst, rRegP src) 6430 %{ 6431 match(Set dst (ConvL2I (CastP2X src))); 6432 6433 format %{ "movl $dst, $src\t# ptr -> int" %} 6434 ins_encode %{ 6435 __ movl($dst$$Register, $src$$Register); 6436 %} 6437 ins_pipe(ialu_reg_reg); // XXX 6438 %} 6439 6440 // Convert compressed oop into int for vectors alignment masking 6441 // in case of 32bit oops (heap < 4Gb). 6442 instruct convN2I(rRegI dst, rRegN src) 6443 %{ 6444 predicate(Universe::narrow_oop_shift() == 0); 6445 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6446 6447 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6448 ins_encode %{ 6449 __ movl($dst$$Register, $src$$Register); 6450 %} 6451 ins_pipe(ialu_reg_reg); // XXX 6452 %} 6453 6454 instruct shenandoahRB(rRegP dst, rRegP src, rFlagsReg cr) %{ 6455 match(Set dst (ShenandoahReadBarrier src)); 6456 effect(DEF dst, USE src); 6457 ins_cost(125); // XXX 6458 format %{ "shenandoah_rb $dst, $src" %} 6459 ins_encode %{ 6460 Register d = $dst$$Register; 6461 Register s = $src$$Register; 6462 __ movptr(d, Address(s, BrooksPointer::byte_offset())); 6463 %} 6464 ins_pipe(ialu_reg_mem); 6465 %} 6466 6467 instruct shenandoahRBNarrow(rRegP dst, rRegN src) %{ 6468 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == 0)); 6469 match(Set dst (ShenandoahReadBarrier (DecodeN src))); 6470 effect(DEF dst, USE src); 6471 ins_cost(125); // XXX 6472 format %{ "shenandoah_rb $dst, $src" %} 6473 ins_encode %{ 6474 Register d = $dst$$Register; 6475 Register s = $src$$Register; 6476 __ movptr(d, Address(r12, s, Address::times_1, BrooksPointer::byte_offset())); 6477 %} 6478 ins_pipe(ialu_reg_mem); 6479 %} 6480 6481 instruct shenandoahRBNarrowShift(rRegP dst, rRegN src) %{ 6482 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 6483 match(Set dst (ShenandoahReadBarrier (DecodeN src))); 6484 effect(DEF dst, USE src); 6485 ins_cost(125); // XXX 6486 format %{ "shenandoah_rb $dst, $src" %} 6487 ins_encode %{ 6488 Register d = $dst$$Register; 6489 Register s = $src$$Register; 6490 __ movptr(d, Address(r12, s, Address::times_8, BrooksPointer::byte_offset())); 6491 %} 6492 ins_pipe(ialu_reg_mem); 6493 %} 6494 6495 instruct shenandoahWB(rRegP dst, rRegP src, rFlagsReg cr) %{ 6496 match(Set dst (ShenandoahWriteBarrier src)); 6497 effect(DEF dst, USE src, KILL cr); 6498 ins_cost(300); // XXX 6499 format %{ "shenandoah_wb $dst,$src" %} 6500 ins_encode %{ 6501 Label done; 6502 Register s = $src$$Register; 6503 Register d = $dst$$Register; 6504 Address evacuation_in_progress = Address(r15_thread, in_bytes(JavaThread::evacuation_in_progress_offset())); 6505 __ movptr(d, Address(s, BrooksPointer::byte_offset())); 6506 __ cmpb(evacuation_in_progress, 0); 6507 __ movptr(d, Address(s, BrooksPointer::byte_offset())); 6508 __ jccb(Assembler::equal, done); 6509 if (rax != d) { 6510 __ xchgptr(rax, d); 6511 } 6512 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::shenandoah_wb()))); 6513 if (rax != d) { 6514 __ xchgptr(rax, d); 6515 } 6516 __ bind(done); 6517 %} 6518 ins_pipe(pipe_slow); 6519 %} 6520 6521 // Convert oop pointer into compressed form 6522 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6523 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6524 match(Set dst (EncodeP src)); 6525 effect(KILL cr); 6526 format %{ "encode_heap_oop $dst,$src" %} 6527 ins_encode %{ 6528 Register s = $src$$Register; 6529 Register d = $dst$$Register; 6530 if (s != d) { 6531 __ movq(d, s); 6532 } 6533 __ encode_heap_oop(d); 6534 %} 6535 ins_pipe(ialu_reg_long); 6536 %} 6537 6538 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6539 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6540 match(Set dst (EncodeP src)); 6541 effect(KILL cr); 6542 format %{ "encode_heap_oop_not_null $dst,$src" %} 6543 ins_encode %{ 6544 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6545 %} 6546 ins_pipe(ialu_reg_long); 6547 %} 6548 6549 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6550 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6551 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6552 match(Set dst (DecodeN src)); 6553 effect(KILL cr); 6554 format %{ "decode_heap_oop $dst,$src" %} 6555 ins_encode %{ 6556 Register s = $src$$Register; 6557 Register d = $dst$$Register; 6558 if (s != d) { 6559 __ movq(d, s); 6560 } 6561 __ decode_heap_oop(d); 6562 %} 6563 ins_pipe(ialu_reg_long); 6564 %} 6565 6566 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6567 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6568 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6569 match(Set dst (DecodeN src)); 6570 effect(KILL cr); 6571 format %{ "decode_heap_oop_not_null $dst,$src" %} 6572 ins_encode %{ 6573 Register s = $src$$Register; 6574 Register d = $dst$$Register; 6575 if (s != d) { 6576 __ decode_heap_oop_not_null(d, s); 6577 } else { 6578 __ decode_heap_oop_not_null(d); 6579 } 6580 %} 6581 ins_pipe(ialu_reg_long); 6582 %} 6583 6584 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6585 match(Set dst (EncodePKlass src)); 6586 effect(KILL cr); 6587 format %{ "encode_klass_not_null $dst,$src" %} 6588 ins_encode %{ 6589 __ encode_klass_not_null($dst$$Register, $src$$Register); 6590 %} 6591 ins_pipe(ialu_reg_long); 6592 %} 6593 6594 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6595 match(Set dst (DecodeNKlass src)); 6596 effect(KILL cr); 6597 format %{ "decode_klass_not_null $dst,$src" %} 6598 ins_encode %{ 6599 Register s = $src$$Register; 6600 Register d = $dst$$Register; 6601 if (s != d) { 6602 __ decode_klass_not_null(d, s); 6603 } else { 6604 __ decode_klass_not_null(d); 6605 } 6606 %} 6607 ins_pipe(ialu_reg_long); 6608 %} 6609 6610 6611 //----------Conditional Move--------------------------------------------------- 6612 // Jump 6613 // dummy instruction for generating temp registers 6614 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6615 match(Jump (LShiftL switch_val shift)); 6616 ins_cost(350); 6617 predicate(false); 6618 effect(TEMP dest); 6619 6620 format %{ "leaq $dest, [$constantaddress]\n\t" 6621 "jmp [$dest + $switch_val << $shift]\n\t" %} 6622 ins_encode %{ 6623 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6624 // to do that and the compiler is using that register as one it can allocate. 6625 // So we build it all by hand. 6626 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6627 // ArrayAddress dispatch(table, index); 6628 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6629 __ lea($dest$$Register, $constantaddress); 6630 __ jmp(dispatch); 6631 %} 6632 ins_pipe(pipe_jmp); 6633 %} 6634 6635 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6636 match(Jump (AddL (LShiftL switch_val shift) offset)); 6637 ins_cost(350); 6638 effect(TEMP dest); 6639 6640 format %{ "leaq $dest, [$constantaddress]\n\t" 6641 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6642 ins_encode %{ 6643 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6644 // to do that and the compiler is using that register as one it can allocate. 6645 // So we build it all by hand. 6646 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6647 // ArrayAddress dispatch(table, index); 6648 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6649 __ lea($dest$$Register, $constantaddress); 6650 __ jmp(dispatch); 6651 %} 6652 ins_pipe(pipe_jmp); 6653 %} 6654 6655 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6656 match(Jump switch_val); 6657 ins_cost(350); 6658 effect(TEMP dest); 6659 6660 format %{ "leaq $dest, [$constantaddress]\n\t" 6661 "jmp [$dest + $switch_val]\n\t" %} 6662 ins_encode %{ 6663 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6664 // to do that and the compiler is using that register as one it can allocate. 6665 // So we build it all by hand. 6666 // Address index(noreg, switch_reg, Address::times_1); 6667 // ArrayAddress dispatch(table, index); 6668 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6669 __ lea($dest$$Register, $constantaddress); 6670 __ jmp(dispatch); 6671 %} 6672 ins_pipe(pipe_jmp); 6673 %} 6674 6675 // Conditional move 6676 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6677 %{ 6678 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6679 6680 ins_cost(200); // XXX 6681 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6682 opcode(0x0F, 0x40); 6683 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6684 ins_pipe(pipe_cmov_reg); 6685 %} 6686 6687 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6688 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6689 6690 ins_cost(200); // XXX 6691 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6692 opcode(0x0F, 0x40); 6693 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6694 ins_pipe(pipe_cmov_reg); 6695 %} 6696 6697 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6698 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6699 ins_cost(200); 6700 expand %{ 6701 cmovI_regU(cop, cr, dst, src); 6702 %} 6703 %} 6704 6705 // Conditional move 6706 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6707 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6708 6709 ins_cost(250); // XXX 6710 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6711 opcode(0x0F, 0x40); 6712 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6713 ins_pipe(pipe_cmov_mem); 6714 %} 6715 6716 // Conditional move 6717 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6718 %{ 6719 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6720 6721 ins_cost(250); // XXX 6722 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6723 opcode(0x0F, 0x40); 6724 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6725 ins_pipe(pipe_cmov_mem); 6726 %} 6727 6728 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6729 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6730 ins_cost(250); 6731 expand %{ 6732 cmovI_memU(cop, cr, dst, src); 6733 %} 6734 %} 6735 6736 // Conditional move 6737 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6738 %{ 6739 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6740 6741 ins_cost(200); // XXX 6742 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6743 opcode(0x0F, 0x40); 6744 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6745 ins_pipe(pipe_cmov_reg); 6746 %} 6747 6748 // Conditional move 6749 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6750 %{ 6751 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6752 6753 ins_cost(200); // XXX 6754 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6755 opcode(0x0F, 0x40); 6756 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6757 ins_pipe(pipe_cmov_reg); 6758 %} 6759 6760 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6761 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6762 ins_cost(200); 6763 expand %{ 6764 cmovN_regU(cop, cr, dst, src); 6765 %} 6766 %} 6767 6768 // Conditional move 6769 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6770 %{ 6771 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6772 6773 ins_cost(200); // XXX 6774 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6775 opcode(0x0F, 0x40); 6776 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6777 ins_pipe(pipe_cmov_reg); // XXX 6778 %} 6779 6780 // Conditional move 6781 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6782 %{ 6783 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6784 6785 ins_cost(200); // XXX 6786 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6787 opcode(0x0F, 0x40); 6788 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6789 ins_pipe(pipe_cmov_reg); // XXX 6790 %} 6791 6792 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6793 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6794 ins_cost(200); 6795 expand %{ 6796 cmovP_regU(cop, cr, dst, src); 6797 %} 6798 %} 6799 6800 // DISABLED: Requires the ADLC to emit a bottom_type call that 6801 // correctly meets the two pointer arguments; one is an incoming 6802 // register but the other is a memory operand. ALSO appears to 6803 // be buggy with implicit null checks. 6804 // 6805 //// Conditional move 6806 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6807 //%{ 6808 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6809 // ins_cost(250); 6810 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6811 // opcode(0x0F,0x40); 6812 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6813 // ins_pipe( pipe_cmov_mem ); 6814 //%} 6815 // 6816 //// Conditional move 6817 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6818 //%{ 6819 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6820 // ins_cost(250); 6821 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6822 // opcode(0x0F,0x40); 6823 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6824 // ins_pipe( pipe_cmov_mem ); 6825 //%} 6826 6827 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6828 %{ 6829 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6830 6831 ins_cost(200); // XXX 6832 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6833 opcode(0x0F, 0x40); 6834 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6835 ins_pipe(pipe_cmov_reg); // XXX 6836 %} 6837 6838 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6839 %{ 6840 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6841 6842 ins_cost(200); // XXX 6843 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6844 opcode(0x0F, 0x40); 6845 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6846 ins_pipe(pipe_cmov_mem); // XXX 6847 %} 6848 6849 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6850 %{ 6851 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6852 6853 ins_cost(200); // XXX 6854 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6855 opcode(0x0F, 0x40); 6856 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6857 ins_pipe(pipe_cmov_reg); // XXX 6858 %} 6859 6860 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6861 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6862 ins_cost(200); 6863 expand %{ 6864 cmovL_regU(cop, cr, dst, src); 6865 %} 6866 %} 6867 6868 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6869 %{ 6870 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6871 6872 ins_cost(200); // XXX 6873 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6874 opcode(0x0F, 0x40); 6875 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6876 ins_pipe(pipe_cmov_mem); // XXX 6877 %} 6878 6879 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6880 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6881 ins_cost(200); 6882 expand %{ 6883 cmovL_memU(cop, cr, dst, src); 6884 %} 6885 %} 6886 6887 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6888 %{ 6889 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6890 6891 ins_cost(200); // XXX 6892 format %{ "jn$cop skip\t# signed cmove float\n\t" 6893 "movss $dst, $src\n" 6894 "skip:" %} 6895 ins_encode %{ 6896 Label Lskip; 6897 // Invert sense of branch from sense of CMOV 6898 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6899 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6900 __ bind(Lskip); 6901 %} 6902 ins_pipe(pipe_slow); 6903 %} 6904 6905 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6906 // %{ 6907 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 6908 6909 // ins_cost(200); // XXX 6910 // format %{ "jn$cop skip\t# signed cmove float\n\t" 6911 // "movss $dst, $src\n" 6912 // "skip:" %} 6913 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 6914 // ins_pipe(pipe_slow); 6915 // %} 6916 6917 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6918 %{ 6919 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6920 6921 ins_cost(200); // XXX 6922 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6923 "movss $dst, $src\n" 6924 "skip:" %} 6925 ins_encode %{ 6926 Label Lskip; 6927 // Invert sense of branch from sense of CMOV 6928 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6929 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6930 __ bind(Lskip); 6931 %} 6932 ins_pipe(pipe_slow); 6933 %} 6934 6935 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6936 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6937 ins_cost(200); 6938 expand %{ 6939 cmovF_regU(cop, cr, dst, src); 6940 %} 6941 %} 6942 6943 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6944 %{ 6945 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6946 6947 ins_cost(200); // XXX 6948 format %{ "jn$cop skip\t# signed cmove double\n\t" 6949 "movsd $dst, $src\n" 6950 "skip:" %} 6951 ins_encode %{ 6952 Label Lskip; 6953 // Invert sense of branch from sense of CMOV 6954 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6955 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6956 __ bind(Lskip); 6957 %} 6958 ins_pipe(pipe_slow); 6959 %} 6960 6961 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6962 %{ 6963 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6964 6965 ins_cost(200); // XXX 6966 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6967 "movsd $dst, $src\n" 6968 "skip:" %} 6969 ins_encode %{ 6970 Label Lskip; 6971 // Invert sense of branch from sense of CMOV 6972 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6973 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6974 __ bind(Lskip); 6975 %} 6976 ins_pipe(pipe_slow); 6977 %} 6978 6979 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6980 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6981 ins_cost(200); 6982 expand %{ 6983 cmovD_regU(cop, cr, dst, src); 6984 %} 6985 %} 6986 6987 //----------Arithmetic Instructions-------------------------------------------- 6988 //----------Addition Instructions---------------------------------------------- 6989 6990 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6991 %{ 6992 match(Set dst (AddI dst src)); 6993 effect(KILL cr); 6994 6995 format %{ "addl $dst, $src\t# int" %} 6996 opcode(0x03); 6997 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 6998 ins_pipe(ialu_reg_reg); 6999 %} 7000 7001 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7002 %{ 7003 match(Set dst (AddI dst src)); 7004 effect(KILL cr); 7005 7006 format %{ "addl $dst, $src\t# int" %} 7007 opcode(0x81, 0x00); /* /0 id */ 7008 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7009 ins_pipe( ialu_reg ); 7010 %} 7011 7012 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7013 %{ 7014 match(Set dst (AddI dst (LoadI src))); 7015 effect(KILL cr); 7016 7017 ins_cost(125); // XXX 7018 format %{ "addl $dst, $src\t# int" %} 7019 opcode(0x03); 7020 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7021 ins_pipe(ialu_reg_mem); 7022 %} 7023 7024 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7025 %{ 7026 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7027 effect(KILL cr); 7028 7029 ins_cost(150); // XXX 7030 format %{ "addl $dst, $src\t# int" %} 7031 opcode(0x01); /* Opcode 01 /r */ 7032 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7033 ins_pipe(ialu_mem_reg); 7034 %} 7035 7036 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7037 %{ 7038 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7039 effect(KILL cr); 7040 7041 ins_cost(125); // XXX 7042 format %{ "addl $dst, $src\t# int" %} 7043 opcode(0x81); /* Opcode 81 /0 id */ 7044 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7045 ins_pipe(ialu_mem_imm); 7046 %} 7047 7048 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7049 %{ 7050 predicate(UseIncDec); 7051 match(Set dst (AddI dst src)); 7052 effect(KILL cr); 7053 7054 format %{ "incl $dst\t# int" %} 7055 opcode(0xFF, 0x00); // FF /0 7056 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7057 ins_pipe(ialu_reg); 7058 %} 7059 7060 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7061 %{ 7062 predicate(UseIncDec); 7063 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7064 effect(KILL cr); 7065 7066 ins_cost(125); // XXX 7067 format %{ "incl $dst\t# int" %} 7068 opcode(0xFF); /* Opcode FF /0 */ 7069 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7070 ins_pipe(ialu_mem_imm); 7071 %} 7072 7073 // XXX why does that use AddI 7074 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7075 %{ 7076 predicate(UseIncDec); 7077 match(Set dst (AddI dst src)); 7078 effect(KILL cr); 7079 7080 format %{ "decl $dst\t# int" %} 7081 opcode(0xFF, 0x01); // FF /1 7082 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7083 ins_pipe(ialu_reg); 7084 %} 7085 7086 // XXX why does that use AddI 7087 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7088 %{ 7089 predicate(UseIncDec); 7090 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7091 effect(KILL cr); 7092 7093 ins_cost(125); // XXX 7094 format %{ "decl $dst\t# int" %} 7095 opcode(0xFF); /* Opcode FF /1 */ 7096 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7097 ins_pipe(ialu_mem_imm); 7098 %} 7099 7100 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7101 %{ 7102 match(Set dst (AddI src0 src1)); 7103 7104 ins_cost(110); 7105 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7106 opcode(0x8D); /* 0x8D /r */ 7107 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7108 ins_pipe(ialu_reg_reg); 7109 %} 7110 7111 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7112 %{ 7113 match(Set dst (AddL dst src)); 7114 effect(KILL cr); 7115 7116 format %{ "addq $dst, $src\t# long" %} 7117 opcode(0x03); 7118 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7119 ins_pipe(ialu_reg_reg); 7120 %} 7121 7122 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7123 %{ 7124 match(Set dst (AddL dst src)); 7125 effect(KILL cr); 7126 7127 format %{ "addq $dst, $src\t# long" %} 7128 opcode(0x81, 0x00); /* /0 id */ 7129 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7130 ins_pipe( ialu_reg ); 7131 %} 7132 7133 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7134 %{ 7135 match(Set dst (AddL dst (LoadL src))); 7136 effect(KILL cr); 7137 7138 ins_cost(125); // XXX 7139 format %{ "addq $dst, $src\t# long" %} 7140 opcode(0x03); 7141 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7142 ins_pipe(ialu_reg_mem); 7143 %} 7144 7145 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7146 %{ 7147 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7148 effect(KILL cr); 7149 7150 ins_cost(150); // XXX 7151 format %{ "addq $dst, $src\t# long" %} 7152 opcode(0x01); /* Opcode 01 /r */ 7153 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7154 ins_pipe(ialu_mem_reg); 7155 %} 7156 7157 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7158 %{ 7159 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7160 effect(KILL cr); 7161 7162 ins_cost(125); // XXX 7163 format %{ "addq $dst, $src\t# long" %} 7164 opcode(0x81); /* Opcode 81 /0 id */ 7165 ins_encode(REX_mem_wide(dst), 7166 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7167 ins_pipe(ialu_mem_imm); 7168 %} 7169 7170 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7171 %{ 7172 predicate(UseIncDec); 7173 match(Set dst (AddL dst src)); 7174 effect(KILL cr); 7175 7176 format %{ "incq $dst\t# long" %} 7177 opcode(0xFF, 0x00); // FF /0 7178 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7179 ins_pipe(ialu_reg); 7180 %} 7181 7182 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7183 %{ 7184 predicate(UseIncDec); 7185 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7186 effect(KILL cr); 7187 7188 ins_cost(125); // XXX 7189 format %{ "incq $dst\t# long" %} 7190 opcode(0xFF); /* Opcode FF /0 */ 7191 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7192 ins_pipe(ialu_mem_imm); 7193 %} 7194 7195 // XXX why does that use AddL 7196 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7197 %{ 7198 predicate(UseIncDec); 7199 match(Set dst (AddL dst src)); 7200 effect(KILL cr); 7201 7202 format %{ "decq $dst\t# long" %} 7203 opcode(0xFF, 0x01); // FF /1 7204 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7205 ins_pipe(ialu_reg); 7206 %} 7207 7208 // XXX why does that use AddL 7209 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7210 %{ 7211 predicate(UseIncDec); 7212 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7213 effect(KILL cr); 7214 7215 ins_cost(125); // XXX 7216 format %{ "decq $dst\t# long" %} 7217 opcode(0xFF); /* Opcode FF /1 */ 7218 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7219 ins_pipe(ialu_mem_imm); 7220 %} 7221 7222 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7223 %{ 7224 match(Set dst (AddL src0 src1)); 7225 7226 ins_cost(110); 7227 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7228 opcode(0x8D); /* 0x8D /r */ 7229 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7230 ins_pipe(ialu_reg_reg); 7231 %} 7232 7233 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7234 %{ 7235 match(Set dst (AddP dst src)); 7236 effect(KILL cr); 7237 7238 format %{ "addq $dst, $src\t# ptr" %} 7239 opcode(0x03); 7240 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7241 ins_pipe(ialu_reg_reg); 7242 %} 7243 7244 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7245 %{ 7246 match(Set dst (AddP dst src)); 7247 effect(KILL cr); 7248 7249 format %{ "addq $dst, $src\t# ptr" %} 7250 opcode(0x81, 0x00); /* /0 id */ 7251 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7252 ins_pipe( ialu_reg ); 7253 %} 7254 7255 // XXX addP mem ops ???? 7256 7257 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7258 %{ 7259 match(Set dst (AddP src0 src1)); 7260 7261 ins_cost(110); 7262 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7263 opcode(0x8D); /* 0x8D /r */ 7264 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7265 ins_pipe(ialu_reg_reg); 7266 %} 7267 7268 instruct checkCastPP(rRegP dst) 7269 %{ 7270 match(Set dst (CheckCastPP dst)); 7271 7272 size(0); 7273 format %{ "# checkcastPP of $dst" %} 7274 ins_encode(/* empty encoding */); 7275 ins_pipe(empty); 7276 %} 7277 7278 instruct castPP(rRegP dst) 7279 %{ 7280 match(Set dst (CastPP dst)); 7281 7282 size(0); 7283 format %{ "# castPP of $dst" %} 7284 ins_encode(/* empty encoding */); 7285 ins_pipe(empty); 7286 %} 7287 7288 instruct castII(rRegI dst) 7289 %{ 7290 match(Set dst (CastII dst)); 7291 7292 size(0); 7293 format %{ "# castII of $dst" %} 7294 ins_encode(/* empty encoding */); 7295 ins_cost(0); 7296 ins_pipe(empty); 7297 %} 7298 7299 // LoadP-locked same as a regular LoadP when used with compare-swap 7300 instruct loadPLocked(rRegP dst, memory mem) 7301 %{ 7302 match(Set dst (LoadPLocked mem)); 7303 7304 ins_cost(125); // XXX 7305 format %{ "movq $dst, $mem\t# ptr locked" %} 7306 opcode(0x8B); 7307 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7308 ins_pipe(ialu_reg_mem); // XXX 7309 %} 7310 7311 // Conditional-store of the updated heap-top. 7312 // Used during allocation of the shared heap. 7313 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7314 7315 instruct storePConditional(memory heap_top_ptr, 7316 rax_RegP oldval, rRegP newval, 7317 rFlagsReg cr) 7318 %{ 7319 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7320 7321 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7322 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7323 opcode(0x0F, 0xB1); 7324 ins_encode(lock_prefix, 7325 REX_reg_mem_wide(newval, heap_top_ptr), 7326 OpcP, OpcS, 7327 reg_mem(newval, heap_top_ptr)); 7328 ins_pipe(pipe_cmpxchg); 7329 %} 7330 7331 // Conditional-store of an int value. 7332 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7333 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7334 %{ 7335 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7336 effect(KILL oldval); 7337 7338 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7339 opcode(0x0F, 0xB1); 7340 ins_encode(lock_prefix, 7341 REX_reg_mem(newval, mem), 7342 OpcP, OpcS, 7343 reg_mem(newval, mem)); 7344 ins_pipe(pipe_cmpxchg); 7345 %} 7346 7347 // Conditional-store of a long value. 7348 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7349 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7350 %{ 7351 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7352 effect(KILL oldval); 7353 7354 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7355 opcode(0x0F, 0xB1); 7356 ins_encode(lock_prefix, 7357 REX_reg_mem_wide(newval, mem), 7358 OpcP, OpcS, 7359 reg_mem(newval, mem)); 7360 ins_pipe(pipe_cmpxchg); 7361 %} 7362 7363 7364 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7365 instruct compareAndSwapP(rRegI res, 7366 memory mem_ptr, 7367 rax_RegP oldval, rRegP newval, 7368 rFlagsReg cr) 7369 %{ 7370 predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); 7371 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7372 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7373 effect(KILL cr, KILL oldval); 7374 7375 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7376 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7377 "sete $res\n\t" 7378 "movzbl $res, $res" %} 7379 opcode(0x0F, 0xB1); 7380 ins_encode(lock_prefix, 7381 REX_reg_mem_wide(newval, mem_ptr), 7382 OpcP, OpcS, 7383 reg_mem(newval, mem_ptr), 7384 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7385 REX_reg_breg(res, res), // movzbl 7386 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7387 ins_pipe( pipe_cmpxchg ); 7388 %} 7389 7390 instruct compareAndSwapP_shenandoah(rRegI res, 7391 memory mem_ptr, 7392 rRegP tmp1, rRegP tmp2, 7393 rax_RegP oldval, rRegP newval, 7394 rFlagsReg cr) 7395 %{ 7396 predicate(VM_Version::supports_cx8() && UseShenandoahGC); 7397 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7398 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7399 effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 7400 ins_cost(1000); 7401 7402 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7403 7404 ins_encode %{ 7405 __ cmpxchg_oop_shenandoah($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7406 false, // swap 7407 $tmp1$$Register, $tmp2$$Register 7408 ); 7409 %} 7410 ins_pipe( pipe_cmpxchg ); 7411 %} 7412 7413 instruct compareAndSwapL(rRegI res, 7414 memory mem_ptr, 7415 rax_RegL oldval, rRegL newval, 7416 rFlagsReg cr) 7417 %{ 7418 predicate(VM_Version::supports_cx8()); 7419 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7420 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7421 effect(KILL cr, KILL oldval); 7422 7423 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7424 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7425 "sete $res\n\t" 7426 "movzbl $res, $res" %} 7427 opcode(0x0F, 0xB1); 7428 ins_encode(lock_prefix, 7429 REX_reg_mem_wide(newval, mem_ptr), 7430 OpcP, OpcS, 7431 reg_mem(newval, mem_ptr), 7432 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7433 REX_reg_breg(res, res), // movzbl 7434 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7435 ins_pipe( pipe_cmpxchg ); 7436 %} 7437 7438 instruct compareAndSwapI(rRegI res, 7439 memory mem_ptr, 7440 rax_RegI oldval, rRegI newval, 7441 rFlagsReg cr) 7442 %{ 7443 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7444 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7445 effect(KILL cr, KILL oldval); 7446 7447 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7448 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7449 "sete $res\n\t" 7450 "movzbl $res, $res" %} 7451 opcode(0x0F, 0xB1); 7452 ins_encode(lock_prefix, 7453 REX_reg_mem(newval, mem_ptr), 7454 OpcP, OpcS, 7455 reg_mem(newval, mem_ptr), 7456 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7457 REX_reg_breg(res, res), // movzbl 7458 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7459 ins_pipe( pipe_cmpxchg ); 7460 %} 7461 7462 instruct compareAndSwapB(rRegI res, 7463 memory mem_ptr, 7464 rax_RegI oldval, rRegI newval, 7465 rFlagsReg cr) 7466 %{ 7467 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7468 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7469 effect(KILL cr, KILL oldval); 7470 7471 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7472 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7473 "sete $res\n\t" 7474 "movzbl $res, $res" %} 7475 opcode(0x0F, 0xB0); 7476 ins_encode(lock_prefix, 7477 REX_breg_mem(newval, mem_ptr), 7478 OpcP, OpcS, 7479 reg_mem(newval, mem_ptr), 7480 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7481 REX_reg_breg(res, res), // movzbl 7482 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7483 ins_pipe( pipe_cmpxchg ); 7484 %} 7485 7486 instruct compareAndSwapS(rRegI res, 7487 memory mem_ptr, 7488 rax_RegI oldval, rRegI newval, 7489 rFlagsReg cr) 7490 %{ 7491 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7492 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7493 effect(KILL cr, KILL oldval); 7494 7495 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7496 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7497 "sete $res\n\t" 7498 "movzbl $res, $res" %} 7499 opcode(0x0F, 0xB1); 7500 ins_encode(lock_prefix, 7501 SizePrefix, 7502 REX_reg_mem(newval, mem_ptr), 7503 OpcP, OpcS, 7504 reg_mem(newval, mem_ptr), 7505 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7506 REX_reg_breg(res, res), // movzbl 7507 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7508 ins_pipe( pipe_cmpxchg ); 7509 %} 7510 7511 instruct compareAndSwapN(rRegI res, 7512 memory mem_ptr, 7513 rax_RegN oldval, rRegN newval, 7514 rFlagsReg cr) %{ 7515 predicate(!UseShenandoahGC); 7516 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7517 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7518 effect(KILL cr, KILL oldval); 7519 7520 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7521 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7522 "sete $res\n\t" 7523 "movzbl $res, $res" %} 7524 opcode(0x0F, 0xB1); 7525 ins_encode(lock_prefix, 7526 REX_reg_mem(newval, mem_ptr), 7527 OpcP, OpcS, 7528 reg_mem(newval, mem_ptr), 7529 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7530 REX_reg_breg(res, res), // movzbl 7531 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7532 ins_pipe( pipe_cmpxchg ); 7533 %} 7534 7535 instruct compareAndSwapN_shenandoah(rRegI res, 7536 memory mem_ptr, 7537 rRegP tmp1, rRegP tmp2, 7538 rax_RegN oldval, rRegN newval, 7539 rFlagsReg cr) %{ 7540 predicate(UseShenandoahGC); 7541 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7542 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7543 effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 7544 ins_cost(1000); 7545 7546 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7547 7548 ins_encode %{ 7549 __ cmpxchg_oop_shenandoah($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7550 false, // swap 7551 $tmp1$$Register, $tmp2$$Register 7552 ); 7553 %} 7554 ins_pipe( pipe_cmpxchg ); 7555 %} 7556 7557 instruct compareAndExchangeB( 7558 memory mem_ptr, 7559 rax_RegI oldval, rRegI newval, 7560 rFlagsReg cr) 7561 %{ 7562 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7563 effect(KILL cr); 7564 7565 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7566 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7567 opcode(0x0F, 0xB0); 7568 ins_encode(lock_prefix, 7569 REX_breg_mem(newval, mem_ptr), 7570 OpcP, OpcS, 7571 reg_mem(newval, mem_ptr) // lock cmpxchg 7572 ); 7573 ins_pipe( pipe_cmpxchg ); 7574 %} 7575 7576 instruct compareAndExchangeS( 7577 memory mem_ptr, 7578 rax_RegI oldval, rRegI newval, 7579 rFlagsReg cr) 7580 %{ 7581 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7582 effect(KILL cr); 7583 7584 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7585 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 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) // lock cmpxchg 7592 ); 7593 ins_pipe( pipe_cmpxchg ); 7594 %} 7595 7596 instruct compareAndExchangeI( 7597 memory mem_ptr, 7598 rax_RegI oldval, rRegI newval, 7599 rFlagsReg cr) 7600 %{ 7601 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7602 effect(KILL cr); 7603 7604 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7605 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7606 opcode(0x0F, 0xB1); 7607 ins_encode(lock_prefix, 7608 REX_reg_mem(newval, mem_ptr), 7609 OpcP, OpcS, 7610 reg_mem(newval, mem_ptr) // lock cmpxchg 7611 ); 7612 ins_pipe( pipe_cmpxchg ); 7613 %} 7614 7615 instruct compareAndExchangeL( 7616 memory mem_ptr, 7617 rax_RegL oldval, rRegL newval, 7618 rFlagsReg cr) 7619 %{ 7620 predicate(VM_Version::supports_cx8()); 7621 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7622 effect(KILL cr); 7623 7624 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7625 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7626 opcode(0x0F, 0xB1); 7627 ins_encode(lock_prefix, 7628 REX_reg_mem_wide(newval, mem_ptr), 7629 OpcP, OpcS, 7630 reg_mem(newval, mem_ptr) // lock cmpxchg 7631 ); 7632 ins_pipe( pipe_cmpxchg ); 7633 %} 7634 7635 instruct compareAndExchangeN( 7636 memory mem_ptr, 7637 rax_RegN oldval, rRegN newval, 7638 rFlagsReg cr) %{ 7639 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7640 effect(KILL cr); 7641 7642 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7643 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7644 opcode(0x0F, 0xB1); 7645 ins_encode(lock_prefix, 7646 REX_reg_mem(newval, mem_ptr), 7647 OpcP, OpcS, 7648 reg_mem(newval, mem_ptr) // lock cmpxchg 7649 ); 7650 ins_pipe( pipe_cmpxchg ); 7651 %} 7652 7653 instruct compareAndExchangeN_shenandoah(memory mem_ptr, 7654 rax_RegN oldval, rRegN newval, 7655 rRegP tmp1, rRegP tmp2, 7656 rFlagsReg cr) %{ 7657 predicate(UseShenandoahGC); 7658 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7659 effect(TEMP tmp1, TEMP tmp2, KILL cr); 7660 ins_cost(1000); 7661 7662 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7663 7664 ins_encode %{ 7665 __ cmpxchg_oop_shenandoah(NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7666 true, // exchange 7667 $tmp1$$Register, $tmp2$$Register 7668 ); 7669 %} 7670 ins_pipe( pipe_cmpxchg ); 7671 %} 7672 7673 instruct compareAndExchangeP( 7674 memory mem_ptr, 7675 rax_RegP oldval, rRegP newval, 7676 rFlagsReg cr) 7677 %{ 7678 predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); 7679 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7680 effect(KILL cr); 7681 7682 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7683 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7684 opcode(0x0F, 0xB1); 7685 ins_encode(lock_prefix, 7686 REX_reg_mem_wide(newval, mem_ptr), 7687 OpcP, OpcS, 7688 reg_mem(newval, mem_ptr) // lock cmpxchg 7689 ); 7690 ins_pipe( pipe_cmpxchg ); 7691 %} 7692 7693 instruct compareAndExchangeP_shenandoah(memory mem_ptr, 7694 rax_RegP oldval, rRegP newval, 7695 rRegP tmp1, rRegP tmp2, 7696 rFlagsReg cr) 7697 %{ 7698 predicate(VM_Version::supports_cx8() && UseShenandoahGC); 7699 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7700 effect(KILL cr, TEMP tmp1, TEMP tmp2); 7701 ins_cost(1000); 7702 7703 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7704 7705 ins_encode %{ 7706 __ cmpxchg_oop_shenandoah(NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7707 true, // exchange 7708 $tmp1$$Register, $tmp2$$Register 7709 ); 7710 %} 7711 ins_pipe( pipe_cmpxchg ); 7712 %} 7713 7714 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7715 predicate(n->as_LoadStore()->result_not_used()); 7716 match(Set dummy (GetAndAddB mem add)); 7717 effect(KILL cr); 7718 format %{ "ADDB [$mem],$add" %} 7719 ins_encode %{ 7720 if (os::is_MP()) { __ lock(); } 7721 __ addb($mem$$Address, $add$$constant); 7722 %} 7723 ins_pipe( pipe_cmpxchg ); 7724 %} 7725 7726 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7727 match(Set newval (GetAndAddB mem newval)); 7728 effect(KILL cr); 7729 format %{ "XADDB [$mem],$newval" %} 7730 ins_encode %{ 7731 if (os::is_MP()) { __ lock(); } 7732 __ xaddb($mem$$Address, $newval$$Register); 7733 %} 7734 ins_pipe( pipe_cmpxchg ); 7735 %} 7736 7737 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7738 predicate(n->as_LoadStore()->result_not_used()); 7739 match(Set dummy (GetAndAddS mem add)); 7740 effect(KILL cr); 7741 format %{ "ADDW [$mem],$add" %} 7742 ins_encode %{ 7743 if (os::is_MP()) { __ lock(); } 7744 __ addw($mem$$Address, $add$$constant); 7745 %} 7746 ins_pipe( pipe_cmpxchg ); 7747 %} 7748 7749 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7750 match(Set newval (GetAndAddS mem newval)); 7751 effect(KILL cr); 7752 format %{ "XADDW [$mem],$newval" %} 7753 ins_encode %{ 7754 if (os::is_MP()) { __ lock(); } 7755 __ xaddw($mem$$Address, $newval$$Register); 7756 %} 7757 ins_pipe( pipe_cmpxchg ); 7758 %} 7759 7760 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7761 predicate(n->as_LoadStore()->result_not_used()); 7762 match(Set dummy (GetAndAddI mem add)); 7763 effect(KILL cr); 7764 format %{ "ADDL [$mem],$add" %} 7765 ins_encode %{ 7766 if (os::is_MP()) { __ lock(); } 7767 __ addl($mem$$Address, $add$$constant); 7768 %} 7769 ins_pipe( pipe_cmpxchg ); 7770 %} 7771 7772 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7773 match(Set newval (GetAndAddI mem newval)); 7774 effect(KILL cr); 7775 format %{ "XADDL [$mem],$newval" %} 7776 ins_encode %{ 7777 if (os::is_MP()) { __ lock(); } 7778 __ xaddl($mem$$Address, $newval$$Register); 7779 %} 7780 ins_pipe( pipe_cmpxchg ); 7781 %} 7782 7783 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7784 predicate(n->as_LoadStore()->result_not_used()); 7785 match(Set dummy (GetAndAddL mem add)); 7786 effect(KILL cr); 7787 format %{ "ADDQ [$mem],$add" %} 7788 ins_encode %{ 7789 if (os::is_MP()) { __ lock(); } 7790 __ addq($mem$$Address, $add$$constant); 7791 %} 7792 ins_pipe( pipe_cmpxchg ); 7793 %} 7794 7795 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7796 match(Set newval (GetAndAddL mem newval)); 7797 effect(KILL cr); 7798 format %{ "XADDQ [$mem],$newval" %} 7799 ins_encode %{ 7800 if (os::is_MP()) { __ lock(); } 7801 __ xaddq($mem$$Address, $newval$$Register); 7802 %} 7803 ins_pipe( pipe_cmpxchg ); 7804 %} 7805 7806 instruct xchgB( memory mem, rRegI newval) %{ 7807 match(Set newval (GetAndSetB mem newval)); 7808 format %{ "XCHGB $newval,[$mem]" %} 7809 ins_encode %{ 7810 __ xchgb($newval$$Register, $mem$$Address); 7811 %} 7812 ins_pipe( pipe_cmpxchg ); 7813 %} 7814 7815 instruct xchgS( memory mem, rRegI newval) %{ 7816 match(Set newval (GetAndSetS mem newval)); 7817 format %{ "XCHGW $newval,[$mem]" %} 7818 ins_encode %{ 7819 __ xchgw($newval$$Register, $mem$$Address); 7820 %} 7821 ins_pipe( pipe_cmpxchg ); 7822 %} 7823 7824 instruct xchgI( memory mem, rRegI newval) %{ 7825 match(Set newval (GetAndSetI mem newval)); 7826 format %{ "XCHGL $newval,[$mem]" %} 7827 ins_encode %{ 7828 __ xchgl($newval$$Register, $mem$$Address); 7829 %} 7830 ins_pipe( pipe_cmpxchg ); 7831 %} 7832 7833 instruct xchgL( memory mem, rRegL newval) %{ 7834 match(Set newval (GetAndSetL mem newval)); 7835 format %{ "XCHGL $newval,[$mem]" %} 7836 ins_encode %{ 7837 __ xchgq($newval$$Register, $mem$$Address); 7838 %} 7839 ins_pipe( pipe_cmpxchg ); 7840 %} 7841 7842 instruct xchgP( memory mem, rRegP newval) %{ 7843 match(Set newval (GetAndSetP mem newval)); 7844 format %{ "XCHGQ $newval,[$mem]" %} 7845 ins_encode %{ 7846 __ xchgq($newval$$Register, $mem$$Address); 7847 %} 7848 ins_pipe( pipe_cmpxchg ); 7849 %} 7850 7851 instruct xchgN( memory mem, rRegN newval) %{ 7852 match(Set newval (GetAndSetN mem newval)); 7853 format %{ "XCHGL $newval,$mem]" %} 7854 ins_encode %{ 7855 __ xchgl($newval$$Register, $mem$$Address); 7856 %} 7857 ins_pipe( pipe_cmpxchg ); 7858 %} 7859 7860 //----------Subtraction Instructions------------------------------------------- 7861 7862 // Integer Subtraction Instructions 7863 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7864 %{ 7865 match(Set dst (SubI dst src)); 7866 effect(KILL cr); 7867 7868 format %{ "subl $dst, $src\t# int" %} 7869 opcode(0x2B); 7870 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7871 ins_pipe(ialu_reg_reg); 7872 %} 7873 7874 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7875 %{ 7876 match(Set dst (SubI dst src)); 7877 effect(KILL cr); 7878 7879 format %{ "subl $dst, $src\t# int" %} 7880 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7881 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7882 ins_pipe(ialu_reg); 7883 %} 7884 7885 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7886 %{ 7887 match(Set dst (SubI dst (LoadI src))); 7888 effect(KILL cr); 7889 7890 ins_cost(125); 7891 format %{ "subl $dst, $src\t# int" %} 7892 opcode(0x2B); 7893 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7894 ins_pipe(ialu_reg_mem); 7895 %} 7896 7897 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7898 %{ 7899 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7900 effect(KILL cr); 7901 7902 ins_cost(150); 7903 format %{ "subl $dst, $src\t# int" %} 7904 opcode(0x29); /* Opcode 29 /r */ 7905 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7906 ins_pipe(ialu_mem_reg); 7907 %} 7908 7909 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7910 %{ 7911 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7912 effect(KILL cr); 7913 7914 ins_cost(125); // XXX 7915 format %{ "subl $dst, $src\t# int" %} 7916 opcode(0x81); /* Opcode 81 /5 id */ 7917 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7918 ins_pipe(ialu_mem_imm); 7919 %} 7920 7921 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7922 %{ 7923 match(Set dst (SubL dst src)); 7924 effect(KILL cr); 7925 7926 format %{ "subq $dst, $src\t# long" %} 7927 opcode(0x2B); 7928 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7929 ins_pipe(ialu_reg_reg); 7930 %} 7931 7932 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7933 %{ 7934 match(Set dst (SubL dst src)); 7935 effect(KILL cr); 7936 7937 format %{ "subq $dst, $src\t# long" %} 7938 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7939 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7940 ins_pipe(ialu_reg); 7941 %} 7942 7943 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7944 %{ 7945 match(Set dst (SubL dst (LoadL src))); 7946 effect(KILL cr); 7947 7948 ins_cost(125); 7949 format %{ "subq $dst, $src\t# long" %} 7950 opcode(0x2B); 7951 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7952 ins_pipe(ialu_reg_mem); 7953 %} 7954 7955 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7956 %{ 7957 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7958 effect(KILL cr); 7959 7960 ins_cost(150); 7961 format %{ "subq $dst, $src\t# long" %} 7962 opcode(0x29); /* Opcode 29 /r */ 7963 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7964 ins_pipe(ialu_mem_reg); 7965 %} 7966 7967 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7968 %{ 7969 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7970 effect(KILL cr); 7971 7972 ins_cost(125); // XXX 7973 format %{ "subq $dst, $src\t# long" %} 7974 opcode(0x81); /* Opcode 81 /5 id */ 7975 ins_encode(REX_mem_wide(dst), 7976 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7977 ins_pipe(ialu_mem_imm); 7978 %} 7979 7980 // Subtract from a pointer 7981 // XXX hmpf??? 7982 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7983 %{ 7984 match(Set dst (AddP dst (SubI zero src))); 7985 effect(KILL cr); 7986 7987 format %{ "subq $dst, $src\t# ptr - int" %} 7988 opcode(0x2B); 7989 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7990 ins_pipe(ialu_reg_reg); 7991 %} 7992 7993 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7994 %{ 7995 match(Set dst (SubI zero dst)); 7996 effect(KILL cr); 7997 7998 format %{ "negl $dst\t# int" %} 7999 opcode(0xF7, 0x03); // Opcode F7 /3 8000 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8001 ins_pipe(ialu_reg); 8002 %} 8003 8004 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8005 %{ 8006 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8007 effect(KILL cr); 8008 8009 format %{ "negl $dst\t# int" %} 8010 opcode(0xF7, 0x03); // Opcode F7 /3 8011 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8012 ins_pipe(ialu_reg); 8013 %} 8014 8015 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8016 %{ 8017 match(Set dst (SubL zero dst)); 8018 effect(KILL cr); 8019 8020 format %{ "negq $dst\t# long" %} 8021 opcode(0xF7, 0x03); // Opcode F7 /3 8022 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8023 ins_pipe(ialu_reg); 8024 %} 8025 8026 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8027 %{ 8028 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8029 effect(KILL cr); 8030 8031 format %{ "negq $dst\t# long" %} 8032 opcode(0xF7, 0x03); // Opcode F7 /3 8033 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8034 ins_pipe(ialu_reg); 8035 %} 8036 8037 //----------Multiplication/Division Instructions------------------------------- 8038 // Integer Multiplication Instructions 8039 // Multiply Register 8040 8041 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8042 %{ 8043 match(Set dst (MulI dst src)); 8044 effect(KILL cr); 8045 8046 ins_cost(300); 8047 format %{ "imull $dst, $src\t# int" %} 8048 opcode(0x0F, 0xAF); 8049 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8050 ins_pipe(ialu_reg_reg_alu0); 8051 %} 8052 8053 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8054 %{ 8055 match(Set dst (MulI src imm)); 8056 effect(KILL cr); 8057 8058 ins_cost(300); 8059 format %{ "imull $dst, $src, $imm\t# int" %} 8060 opcode(0x69); /* 69 /r id */ 8061 ins_encode(REX_reg_reg(dst, src), 8062 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8063 ins_pipe(ialu_reg_reg_alu0); 8064 %} 8065 8066 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8067 %{ 8068 match(Set dst (MulI dst (LoadI src))); 8069 effect(KILL cr); 8070 8071 ins_cost(350); 8072 format %{ "imull $dst, $src\t# int" %} 8073 opcode(0x0F, 0xAF); 8074 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8075 ins_pipe(ialu_reg_mem_alu0); 8076 %} 8077 8078 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8079 %{ 8080 match(Set dst (MulI (LoadI src) imm)); 8081 effect(KILL cr); 8082 8083 ins_cost(300); 8084 format %{ "imull $dst, $src, $imm\t# int" %} 8085 opcode(0x69); /* 69 /r id */ 8086 ins_encode(REX_reg_mem(dst, src), 8087 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8088 ins_pipe(ialu_reg_mem_alu0); 8089 %} 8090 8091 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8092 %{ 8093 match(Set dst (MulL dst src)); 8094 effect(KILL cr); 8095 8096 ins_cost(300); 8097 format %{ "imulq $dst, $src\t# long" %} 8098 opcode(0x0F, 0xAF); 8099 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8100 ins_pipe(ialu_reg_reg_alu0); 8101 %} 8102 8103 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8104 %{ 8105 match(Set dst (MulL src imm)); 8106 effect(KILL cr); 8107 8108 ins_cost(300); 8109 format %{ "imulq $dst, $src, $imm\t# long" %} 8110 opcode(0x69); /* 69 /r id */ 8111 ins_encode(REX_reg_reg_wide(dst, src), 8112 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8113 ins_pipe(ialu_reg_reg_alu0); 8114 %} 8115 8116 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8117 %{ 8118 match(Set dst (MulL dst (LoadL src))); 8119 effect(KILL cr); 8120 8121 ins_cost(350); 8122 format %{ "imulq $dst, $src\t# long" %} 8123 opcode(0x0F, 0xAF); 8124 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8125 ins_pipe(ialu_reg_mem_alu0); 8126 %} 8127 8128 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8129 %{ 8130 match(Set dst (MulL (LoadL src) imm)); 8131 effect(KILL cr); 8132 8133 ins_cost(300); 8134 format %{ "imulq $dst, $src, $imm\t# long" %} 8135 opcode(0x69); /* 69 /r id */ 8136 ins_encode(REX_reg_mem_wide(dst, src), 8137 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8138 ins_pipe(ialu_reg_mem_alu0); 8139 %} 8140 8141 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8142 %{ 8143 match(Set dst (MulHiL src rax)); 8144 effect(USE_KILL rax, KILL cr); 8145 8146 ins_cost(300); 8147 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8148 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8149 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8150 ins_pipe(ialu_reg_reg_alu0); 8151 %} 8152 8153 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8154 rFlagsReg cr) 8155 %{ 8156 match(Set rax (DivI rax div)); 8157 effect(KILL rdx, KILL cr); 8158 8159 ins_cost(30*100+10*100); // XXX 8160 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8161 "jne,s normal\n\t" 8162 "xorl rdx, rdx\n\t" 8163 "cmpl $div, -1\n\t" 8164 "je,s done\n" 8165 "normal: cdql\n\t" 8166 "idivl $div\n" 8167 "done:" %} 8168 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8169 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8170 ins_pipe(ialu_reg_reg_alu0); 8171 %} 8172 8173 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8174 rFlagsReg cr) 8175 %{ 8176 match(Set rax (DivL rax div)); 8177 effect(KILL rdx, KILL cr); 8178 8179 ins_cost(30*100+10*100); // XXX 8180 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8181 "cmpq rax, rdx\n\t" 8182 "jne,s normal\n\t" 8183 "xorl rdx, rdx\n\t" 8184 "cmpq $div, -1\n\t" 8185 "je,s done\n" 8186 "normal: cdqq\n\t" 8187 "idivq $div\n" 8188 "done:" %} 8189 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8190 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8191 ins_pipe(ialu_reg_reg_alu0); 8192 %} 8193 8194 // Integer DIVMOD with Register, both quotient and mod results 8195 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8196 rFlagsReg cr) 8197 %{ 8198 match(DivModI rax div); 8199 effect(KILL cr); 8200 8201 ins_cost(30*100+10*100); // XXX 8202 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8203 "jne,s normal\n\t" 8204 "xorl rdx, rdx\n\t" 8205 "cmpl $div, -1\n\t" 8206 "je,s done\n" 8207 "normal: cdql\n\t" 8208 "idivl $div\n" 8209 "done:" %} 8210 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8211 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8212 ins_pipe(pipe_slow); 8213 %} 8214 8215 // Long DIVMOD with Register, both quotient and mod results 8216 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8217 rFlagsReg cr) 8218 %{ 8219 match(DivModL rax div); 8220 effect(KILL cr); 8221 8222 ins_cost(30*100+10*100); // XXX 8223 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8224 "cmpq rax, rdx\n\t" 8225 "jne,s normal\n\t" 8226 "xorl rdx, rdx\n\t" 8227 "cmpq $div, -1\n\t" 8228 "je,s done\n" 8229 "normal: cdqq\n\t" 8230 "idivq $div\n" 8231 "done:" %} 8232 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8233 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8234 ins_pipe(pipe_slow); 8235 %} 8236 8237 //----------- DivL-By-Constant-Expansions-------------------------------------- 8238 // DivI cases are handled by the compiler 8239 8240 // Magic constant, reciprocal of 10 8241 instruct loadConL_0x6666666666666667(rRegL dst) 8242 %{ 8243 effect(DEF dst); 8244 8245 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8246 ins_encode(load_immL(dst, 0x6666666666666667)); 8247 ins_pipe(ialu_reg); 8248 %} 8249 8250 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8251 %{ 8252 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8253 8254 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8255 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8256 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8257 ins_pipe(ialu_reg_reg_alu0); 8258 %} 8259 8260 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8261 %{ 8262 effect(USE_DEF dst, KILL cr); 8263 8264 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8265 opcode(0xC1, 0x7); /* C1 /7 ib */ 8266 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8267 ins_pipe(ialu_reg); 8268 %} 8269 8270 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8271 %{ 8272 effect(USE_DEF dst, KILL cr); 8273 8274 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8275 opcode(0xC1, 0x7); /* C1 /7 ib */ 8276 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8277 ins_pipe(ialu_reg); 8278 %} 8279 8280 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8281 %{ 8282 match(Set dst (DivL src div)); 8283 8284 ins_cost((5+8)*100); 8285 expand %{ 8286 rax_RegL rax; // Killed temp 8287 rFlagsReg cr; // Killed 8288 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8289 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8290 sarL_rReg_63(src, cr); // sarq src, 63 8291 sarL_rReg_2(dst, cr); // sarq rdx, 2 8292 subL_rReg(dst, src, cr); // subl rdx, src 8293 %} 8294 %} 8295 8296 //----------------------------------------------------------------------------- 8297 8298 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8299 rFlagsReg cr) 8300 %{ 8301 match(Set rdx (ModI rax div)); 8302 effect(KILL rax, KILL cr); 8303 8304 ins_cost(300); // XXX 8305 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8306 "jne,s normal\n\t" 8307 "xorl rdx, rdx\n\t" 8308 "cmpl $div, -1\n\t" 8309 "je,s done\n" 8310 "normal: cdql\n\t" 8311 "idivl $div\n" 8312 "done:" %} 8313 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8314 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8315 ins_pipe(ialu_reg_reg_alu0); 8316 %} 8317 8318 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8319 rFlagsReg cr) 8320 %{ 8321 match(Set rdx (ModL rax div)); 8322 effect(KILL rax, KILL cr); 8323 8324 ins_cost(300); // XXX 8325 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8326 "cmpq rax, rdx\n\t" 8327 "jne,s normal\n\t" 8328 "xorl rdx, rdx\n\t" 8329 "cmpq $div, -1\n\t" 8330 "je,s done\n" 8331 "normal: cdqq\n\t" 8332 "idivq $div\n" 8333 "done:" %} 8334 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8335 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8336 ins_pipe(ialu_reg_reg_alu0); 8337 %} 8338 8339 // Integer Shift Instructions 8340 // Shift Left by one 8341 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8342 %{ 8343 match(Set dst (LShiftI dst shift)); 8344 effect(KILL cr); 8345 8346 format %{ "sall $dst, $shift" %} 8347 opcode(0xD1, 0x4); /* D1 /4 */ 8348 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8349 ins_pipe(ialu_reg); 8350 %} 8351 8352 // Shift Left by one 8353 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8354 %{ 8355 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8356 effect(KILL cr); 8357 8358 format %{ "sall $dst, $shift\t" %} 8359 opcode(0xD1, 0x4); /* D1 /4 */ 8360 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8361 ins_pipe(ialu_mem_imm); 8362 %} 8363 8364 // Shift Left by 8-bit immediate 8365 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8366 %{ 8367 match(Set dst (LShiftI dst shift)); 8368 effect(KILL cr); 8369 8370 format %{ "sall $dst, $shift" %} 8371 opcode(0xC1, 0x4); /* C1 /4 ib */ 8372 ins_encode(reg_opc_imm(dst, shift)); 8373 ins_pipe(ialu_reg); 8374 %} 8375 8376 // Shift Left by 8-bit immediate 8377 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8378 %{ 8379 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8380 effect(KILL cr); 8381 8382 format %{ "sall $dst, $shift" %} 8383 opcode(0xC1, 0x4); /* C1 /4 ib */ 8384 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8385 ins_pipe(ialu_mem_imm); 8386 %} 8387 8388 // Shift Left by variable 8389 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8390 %{ 8391 match(Set dst (LShiftI dst shift)); 8392 effect(KILL cr); 8393 8394 format %{ "sall $dst, $shift" %} 8395 opcode(0xD3, 0x4); /* D3 /4 */ 8396 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8397 ins_pipe(ialu_reg_reg); 8398 %} 8399 8400 // Shift Left by variable 8401 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8402 %{ 8403 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8404 effect(KILL cr); 8405 8406 format %{ "sall $dst, $shift" %} 8407 opcode(0xD3, 0x4); /* D3 /4 */ 8408 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8409 ins_pipe(ialu_mem_reg); 8410 %} 8411 8412 // Arithmetic shift right by one 8413 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8414 %{ 8415 match(Set dst (RShiftI dst shift)); 8416 effect(KILL cr); 8417 8418 format %{ "sarl $dst, $shift" %} 8419 opcode(0xD1, 0x7); /* D1 /7 */ 8420 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8421 ins_pipe(ialu_reg); 8422 %} 8423 8424 // Arithmetic shift right by one 8425 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8426 %{ 8427 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8428 effect(KILL cr); 8429 8430 format %{ "sarl $dst, $shift" %} 8431 opcode(0xD1, 0x7); /* D1 /7 */ 8432 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8433 ins_pipe(ialu_mem_imm); 8434 %} 8435 8436 // Arithmetic Shift Right by 8-bit immediate 8437 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8438 %{ 8439 match(Set dst (RShiftI dst shift)); 8440 effect(KILL cr); 8441 8442 format %{ "sarl $dst, $shift" %} 8443 opcode(0xC1, 0x7); /* C1 /7 ib */ 8444 ins_encode(reg_opc_imm(dst, shift)); 8445 ins_pipe(ialu_mem_imm); 8446 %} 8447 8448 // Arithmetic Shift Right by 8-bit immediate 8449 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8450 %{ 8451 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8452 effect(KILL cr); 8453 8454 format %{ "sarl $dst, $shift" %} 8455 opcode(0xC1, 0x7); /* C1 /7 ib */ 8456 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8457 ins_pipe(ialu_mem_imm); 8458 %} 8459 8460 // Arithmetic Shift Right by variable 8461 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8462 %{ 8463 match(Set dst (RShiftI dst shift)); 8464 effect(KILL cr); 8465 8466 format %{ "sarl $dst, $shift" %} 8467 opcode(0xD3, 0x7); /* D3 /7 */ 8468 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8469 ins_pipe(ialu_reg_reg); 8470 %} 8471 8472 // Arithmetic Shift Right by variable 8473 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8474 %{ 8475 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8476 effect(KILL cr); 8477 8478 format %{ "sarl $dst, $shift" %} 8479 opcode(0xD3, 0x7); /* D3 /7 */ 8480 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8481 ins_pipe(ialu_mem_reg); 8482 %} 8483 8484 // Logical shift right by one 8485 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8486 %{ 8487 match(Set dst (URShiftI dst shift)); 8488 effect(KILL cr); 8489 8490 format %{ "shrl $dst, $shift" %} 8491 opcode(0xD1, 0x5); /* D1 /5 */ 8492 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8493 ins_pipe(ialu_reg); 8494 %} 8495 8496 // Logical shift right by one 8497 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8498 %{ 8499 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8500 effect(KILL cr); 8501 8502 format %{ "shrl $dst, $shift" %} 8503 opcode(0xD1, 0x5); /* D1 /5 */ 8504 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8505 ins_pipe(ialu_mem_imm); 8506 %} 8507 8508 // Logical Shift Right by 8-bit immediate 8509 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8510 %{ 8511 match(Set dst (URShiftI dst shift)); 8512 effect(KILL cr); 8513 8514 format %{ "shrl $dst, $shift" %} 8515 opcode(0xC1, 0x5); /* C1 /5 ib */ 8516 ins_encode(reg_opc_imm(dst, shift)); 8517 ins_pipe(ialu_reg); 8518 %} 8519 8520 // Logical Shift Right by 8-bit immediate 8521 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8522 %{ 8523 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8524 effect(KILL cr); 8525 8526 format %{ "shrl $dst, $shift" %} 8527 opcode(0xC1, 0x5); /* C1 /5 ib */ 8528 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8529 ins_pipe(ialu_mem_imm); 8530 %} 8531 8532 // Logical Shift Right by variable 8533 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8534 %{ 8535 match(Set dst (URShiftI dst shift)); 8536 effect(KILL cr); 8537 8538 format %{ "shrl $dst, $shift" %} 8539 opcode(0xD3, 0x5); /* D3 /5 */ 8540 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8541 ins_pipe(ialu_reg_reg); 8542 %} 8543 8544 // Logical Shift Right by variable 8545 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8546 %{ 8547 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8548 effect(KILL cr); 8549 8550 format %{ "shrl $dst, $shift" %} 8551 opcode(0xD3, 0x5); /* D3 /5 */ 8552 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8553 ins_pipe(ialu_mem_reg); 8554 %} 8555 8556 // Long Shift Instructions 8557 // Shift Left by one 8558 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8559 %{ 8560 match(Set dst (LShiftL dst shift)); 8561 effect(KILL cr); 8562 8563 format %{ "salq $dst, $shift" %} 8564 opcode(0xD1, 0x4); /* D1 /4 */ 8565 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8566 ins_pipe(ialu_reg); 8567 %} 8568 8569 // Shift Left by one 8570 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8571 %{ 8572 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8573 effect(KILL cr); 8574 8575 format %{ "salq $dst, $shift" %} 8576 opcode(0xD1, 0x4); /* D1 /4 */ 8577 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8578 ins_pipe(ialu_mem_imm); 8579 %} 8580 8581 // Shift Left by 8-bit immediate 8582 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8583 %{ 8584 match(Set dst (LShiftL dst shift)); 8585 effect(KILL cr); 8586 8587 format %{ "salq $dst, $shift" %} 8588 opcode(0xC1, 0x4); /* C1 /4 ib */ 8589 ins_encode(reg_opc_imm_wide(dst, shift)); 8590 ins_pipe(ialu_reg); 8591 %} 8592 8593 // Shift Left by 8-bit immediate 8594 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8595 %{ 8596 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8597 effect(KILL cr); 8598 8599 format %{ "salq $dst, $shift" %} 8600 opcode(0xC1, 0x4); /* C1 /4 ib */ 8601 ins_encode(REX_mem_wide(dst), OpcP, 8602 RM_opc_mem(secondary, dst), Con8or32(shift)); 8603 ins_pipe(ialu_mem_imm); 8604 %} 8605 8606 // Shift Left by variable 8607 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8608 %{ 8609 match(Set dst (LShiftL dst shift)); 8610 effect(KILL cr); 8611 8612 format %{ "salq $dst, $shift" %} 8613 opcode(0xD3, 0x4); /* D3 /4 */ 8614 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8615 ins_pipe(ialu_reg_reg); 8616 %} 8617 8618 // Shift Left by variable 8619 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8620 %{ 8621 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8622 effect(KILL cr); 8623 8624 format %{ "salq $dst, $shift" %} 8625 opcode(0xD3, 0x4); /* D3 /4 */ 8626 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8627 ins_pipe(ialu_mem_reg); 8628 %} 8629 8630 // Arithmetic shift right by one 8631 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8632 %{ 8633 match(Set dst (RShiftL dst shift)); 8634 effect(KILL cr); 8635 8636 format %{ "sarq $dst, $shift" %} 8637 opcode(0xD1, 0x7); /* D1 /7 */ 8638 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8639 ins_pipe(ialu_reg); 8640 %} 8641 8642 // Arithmetic shift right by one 8643 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8644 %{ 8645 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8646 effect(KILL cr); 8647 8648 format %{ "sarq $dst, $shift" %} 8649 opcode(0xD1, 0x7); /* D1 /7 */ 8650 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8651 ins_pipe(ialu_mem_imm); 8652 %} 8653 8654 // Arithmetic Shift Right by 8-bit immediate 8655 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8656 %{ 8657 match(Set dst (RShiftL dst shift)); 8658 effect(KILL cr); 8659 8660 format %{ "sarq $dst, $shift" %} 8661 opcode(0xC1, 0x7); /* C1 /7 ib */ 8662 ins_encode(reg_opc_imm_wide(dst, shift)); 8663 ins_pipe(ialu_mem_imm); 8664 %} 8665 8666 // Arithmetic Shift Right by 8-bit immediate 8667 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8668 %{ 8669 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8670 effect(KILL cr); 8671 8672 format %{ "sarq $dst, $shift" %} 8673 opcode(0xC1, 0x7); /* C1 /7 ib */ 8674 ins_encode(REX_mem_wide(dst), OpcP, 8675 RM_opc_mem(secondary, dst), Con8or32(shift)); 8676 ins_pipe(ialu_mem_imm); 8677 %} 8678 8679 // Arithmetic Shift Right by variable 8680 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8681 %{ 8682 match(Set dst (RShiftL dst shift)); 8683 effect(KILL cr); 8684 8685 format %{ "sarq $dst, $shift" %} 8686 opcode(0xD3, 0x7); /* D3 /7 */ 8687 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8688 ins_pipe(ialu_reg_reg); 8689 %} 8690 8691 // Arithmetic Shift Right by variable 8692 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8693 %{ 8694 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8695 effect(KILL cr); 8696 8697 format %{ "sarq $dst, $shift" %} 8698 opcode(0xD3, 0x7); /* D3 /7 */ 8699 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8700 ins_pipe(ialu_mem_reg); 8701 %} 8702 8703 // Logical shift right by one 8704 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8705 %{ 8706 match(Set dst (URShiftL dst shift)); 8707 effect(KILL cr); 8708 8709 format %{ "shrq $dst, $shift" %} 8710 opcode(0xD1, 0x5); /* D1 /5 */ 8711 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8712 ins_pipe(ialu_reg); 8713 %} 8714 8715 // Logical shift right by one 8716 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8717 %{ 8718 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8719 effect(KILL cr); 8720 8721 format %{ "shrq $dst, $shift" %} 8722 opcode(0xD1, 0x5); /* D1 /5 */ 8723 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8724 ins_pipe(ialu_mem_imm); 8725 %} 8726 8727 // Logical Shift Right by 8-bit immediate 8728 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8729 %{ 8730 match(Set dst (URShiftL dst shift)); 8731 effect(KILL cr); 8732 8733 format %{ "shrq $dst, $shift" %} 8734 opcode(0xC1, 0x5); /* C1 /5 ib */ 8735 ins_encode(reg_opc_imm_wide(dst, shift)); 8736 ins_pipe(ialu_reg); 8737 %} 8738 8739 8740 // Logical Shift Right by 8-bit immediate 8741 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8742 %{ 8743 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8744 effect(KILL cr); 8745 8746 format %{ "shrq $dst, $shift" %} 8747 opcode(0xC1, 0x5); /* C1 /5 ib */ 8748 ins_encode(REX_mem_wide(dst), OpcP, 8749 RM_opc_mem(secondary, dst), Con8or32(shift)); 8750 ins_pipe(ialu_mem_imm); 8751 %} 8752 8753 // Logical Shift Right by variable 8754 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8755 %{ 8756 match(Set dst (URShiftL dst shift)); 8757 effect(KILL cr); 8758 8759 format %{ "shrq $dst, $shift" %} 8760 opcode(0xD3, 0x5); /* D3 /5 */ 8761 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8762 ins_pipe(ialu_reg_reg); 8763 %} 8764 8765 // Logical Shift Right by variable 8766 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8767 %{ 8768 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8769 effect(KILL cr); 8770 8771 format %{ "shrq $dst, $shift" %} 8772 opcode(0xD3, 0x5); /* D3 /5 */ 8773 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8774 ins_pipe(ialu_mem_reg); 8775 %} 8776 8777 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8778 // This idiom is used by the compiler for the i2b bytecode. 8779 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8780 %{ 8781 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8782 8783 format %{ "movsbl $dst, $src\t# i2b" %} 8784 opcode(0x0F, 0xBE); 8785 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8786 ins_pipe(ialu_reg_reg); 8787 %} 8788 8789 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8790 // This idiom is used by the compiler the i2s bytecode. 8791 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8792 %{ 8793 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8794 8795 format %{ "movswl $dst, $src\t# i2s" %} 8796 opcode(0x0F, 0xBF); 8797 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8798 ins_pipe(ialu_reg_reg); 8799 %} 8800 8801 // ROL/ROR instructions 8802 8803 // ROL expand 8804 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8805 effect(KILL cr, USE_DEF dst); 8806 8807 format %{ "roll $dst" %} 8808 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8809 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8810 ins_pipe(ialu_reg); 8811 %} 8812 8813 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8814 effect(USE_DEF dst, USE shift, KILL cr); 8815 8816 format %{ "roll $dst, $shift" %} 8817 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8818 ins_encode( reg_opc_imm(dst, shift) ); 8819 ins_pipe(ialu_reg); 8820 %} 8821 8822 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8823 %{ 8824 effect(USE_DEF dst, USE shift, KILL cr); 8825 8826 format %{ "roll $dst, $shift" %} 8827 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8828 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8829 ins_pipe(ialu_reg_reg); 8830 %} 8831 // end of ROL expand 8832 8833 // Rotate Left by one 8834 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8835 %{ 8836 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8837 8838 expand %{ 8839 rolI_rReg_imm1(dst, cr); 8840 %} 8841 %} 8842 8843 // Rotate Left by 8-bit immediate 8844 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8845 %{ 8846 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8847 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8848 8849 expand %{ 8850 rolI_rReg_imm8(dst, lshift, cr); 8851 %} 8852 %} 8853 8854 // Rotate Left by variable 8855 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8856 %{ 8857 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8858 8859 expand %{ 8860 rolI_rReg_CL(dst, shift, cr); 8861 %} 8862 %} 8863 8864 // Rotate Left by variable 8865 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8866 %{ 8867 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8868 8869 expand %{ 8870 rolI_rReg_CL(dst, shift, cr); 8871 %} 8872 %} 8873 8874 // ROR expand 8875 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8876 %{ 8877 effect(USE_DEF dst, KILL cr); 8878 8879 format %{ "rorl $dst" %} 8880 opcode(0xD1, 0x1); /* D1 /1 */ 8881 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8882 ins_pipe(ialu_reg); 8883 %} 8884 8885 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8886 %{ 8887 effect(USE_DEF dst, USE shift, KILL cr); 8888 8889 format %{ "rorl $dst, $shift" %} 8890 opcode(0xC1, 0x1); /* C1 /1 ib */ 8891 ins_encode(reg_opc_imm(dst, shift)); 8892 ins_pipe(ialu_reg); 8893 %} 8894 8895 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8896 %{ 8897 effect(USE_DEF dst, USE shift, KILL cr); 8898 8899 format %{ "rorl $dst, $shift" %} 8900 opcode(0xD3, 0x1); /* D3 /1 */ 8901 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8902 ins_pipe(ialu_reg_reg); 8903 %} 8904 // end of ROR expand 8905 8906 // Rotate Right by one 8907 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8908 %{ 8909 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8910 8911 expand %{ 8912 rorI_rReg_imm1(dst, cr); 8913 %} 8914 %} 8915 8916 // Rotate Right by 8-bit immediate 8917 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8918 %{ 8919 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8920 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8921 8922 expand %{ 8923 rorI_rReg_imm8(dst, rshift, cr); 8924 %} 8925 %} 8926 8927 // Rotate Right by variable 8928 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8929 %{ 8930 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8931 8932 expand %{ 8933 rorI_rReg_CL(dst, shift, cr); 8934 %} 8935 %} 8936 8937 // Rotate Right by variable 8938 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8939 %{ 8940 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8941 8942 expand %{ 8943 rorI_rReg_CL(dst, shift, cr); 8944 %} 8945 %} 8946 8947 // for long rotate 8948 // ROL expand 8949 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8950 effect(USE_DEF dst, KILL cr); 8951 8952 format %{ "rolq $dst" %} 8953 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8954 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8955 ins_pipe(ialu_reg); 8956 %} 8957 8958 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8959 effect(USE_DEF dst, USE shift, KILL cr); 8960 8961 format %{ "rolq $dst, $shift" %} 8962 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8963 ins_encode( reg_opc_imm_wide(dst, shift) ); 8964 ins_pipe(ialu_reg); 8965 %} 8966 8967 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8968 %{ 8969 effect(USE_DEF dst, USE shift, KILL cr); 8970 8971 format %{ "rolq $dst, $shift" %} 8972 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8973 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8974 ins_pipe(ialu_reg_reg); 8975 %} 8976 // end of ROL expand 8977 8978 // Rotate Left by one 8979 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8980 %{ 8981 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8982 8983 expand %{ 8984 rolL_rReg_imm1(dst, cr); 8985 %} 8986 %} 8987 8988 // Rotate Left by 8-bit immediate 8989 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8990 %{ 8991 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8992 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8993 8994 expand %{ 8995 rolL_rReg_imm8(dst, lshift, cr); 8996 %} 8997 %} 8998 8999 // Rotate Left by variable 9000 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9001 %{ 9002 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9003 9004 expand %{ 9005 rolL_rReg_CL(dst, shift, cr); 9006 %} 9007 %} 9008 9009 // Rotate Left by variable 9010 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9011 %{ 9012 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9013 9014 expand %{ 9015 rolL_rReg_CL(dst, shift, cr); 9016 %} 9017 %} 9018 9019 // ROR expand 9020 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9021 %{ 9022 effect(USE_DEF dst, KILL cr); 9023 9024 format %{ "rorq $dst" %} 9025 opcode(0xD1, 0x1); /* D1 /1 */ 9026 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9027 ins_pipe(ialu_reg); 9028 %} 9029 9030 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9031 %{ 9032 effect(USE_DEF dst, USE shift, KILL cr); 9033 9034 format %{ "rorq $dst, $shift" %} 9035 opcode(0xC1, 0x1); /* C1 /1 ib */ 9036 ins_encode(reg_opc_imm_wide(dst, shift)); 9037 ins_pipe(ialu_reg); 9038 %} 9039 9040 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9041 %{ 9042 effect(USE_DEF dst, USE shift, KILL cr); 9043 9044 format %{ "rorq $dst, $shift" %} 9045 opcode(0xD3, 0x1); /* D3 /1 */ 9046 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9047 ins_pipe(ialu_reg_reg); 9048 %} 9049 // end of ROR expand 9050 9051 // Rotate Right by one 9052 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9053 %{ 9054 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9055 9056 expand %{ 9057 rorL_rReg_imm1(dst, cr); 9058 %} 9059 %} 9060 9061 // Rotate Right by 8-bit immediate 9062 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9063 %{ 9064 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9065 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9066 9067 expand %{ 9068 rorL_rReg_imm8(dst, rshift, cr); 9069 %} 9070 %} 9071 9072 // Rotate Right by variable 9073 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9074 %{ 9075 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9076 9077 expand %{ 9078 rorL_rReg_CL(dst, shift, cr); 9079 %} 9080 %} 9081 9082 // Rotate Right by variable 9083 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9084 %{ 9085 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9086 9087 expand %{ 9088 rorL_rReg_CL(dst, shift, cr); 9089 %} 9090 %} 9091 9092 // Logical Instructions 9093 9094 // Integer Logical Instructions 9095 9096 // And Instructions 9097 // And Register with Register 9098 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9099 %{ 9100 match(Set dst (AndI dst src)); 9101 effect(KILL cr); 9102 9103 format %{ "andl $dst, $src\t# int" %} 9104 opcode(0x23); 9105 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9106 ins_pipe(ialu_reg_reg); 9107 %} 9108 9109 // And Register with Immediate 255 9110 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9111 %{ 9112 match(Set dst (AndI dst src)); 9113 9114 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9115 opcode(0x0F, 0xB6); 9116 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9117 ins_pipe(ialu_reg); 9118 %} 9119 9120 // And Register with Immediate 255 and promote to long 9121 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9122 %{ 9123 match(Set dst (ConvI2L (AndI src mask))); 9124 9125 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9126 opcode(0x0F, 0xB6); 9127 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9128 ins_pipe(ialu_reg); 9129 %} 9130 9131 // And Register with Immediate 65535 9132 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9133 %{ 9134 match(Set dst (AndI dst src)); 9135 9136 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9137 opcode(0x0F, 0xB7); 9138 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9139 ins_pipe(ialu_reg); 9140 %} 9141 9142 // And Register with Immediate 65535 and promote to long 9143 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9144 %{ 9145 match(Set dst (ConvI2L (AndI src mask))); 9146 9147 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9148 opcode(0x0F, 0xB7); 9149 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9150 ins_pipe(ialu_reg); 9151 %} 9152 9153 // And Register with Immediate 9154 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9155 %{ 9156 match(Set dst (AndI dst src)); 9157 effect(KILL cr); 9158 9159 format %{ "andl $dst, $src\t# int" %} 9160 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9161 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9162 ins_pipe(ialu_reg); 9163 %} 9164 9165 // And Register with Memory 9166 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9167 %{ 9168 match(Set dst (AndI dst (LoadI src))); 9169 effect(KILL cr); 9170 9171 ins_cost(125); 9172 format %{ "andl $dst, $src\t# int" %} 9173 opcode(0x23); 9174 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9175 ins_pipe(ialu_reg_mem); 9176 %} 9177 9178 // And Memory with Register 9179 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9180 %{ 9181 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9182 effect(KILL cr); 9183 9184 ins_cost(150); 9185 format %{ "andl $dst, $src\t# int" %} 9186 opcode(0x21); /* Opcode 21 /r */ 9187 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9188 ins_pipe(ialu_mem_reg); 9189 %} 9190 9191 // And Memory with Immediate 9192 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9193 %{ 9194 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9195 effect(KILL cr); 9196 9197 ins_cost(125); 9198 format %{ "andl $dst, $src\t# int" %} 9199 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9200 ins_encode(REX_mem(dst), OpcSE(src), 9201 RM_opc_mem(secondary, dst), Con8or32(src)); 9202 ins_pipe(ialu_mem_imm); 9203 %} 9204 9205 // BMI1 instructions 9206 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9207 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9208 predicate(UseBMI1Instructions); 9209 effect(KILL cr); 9210 9211 ins_cost(125); 9212 format %{ "andnl $dst, $src1, $src2" %} 9213 9214 ins_encode %{ 9215 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9216 %} 9217 ins_pipe(ialu_reg_mem); 9218 %} 9219 9220 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9221 match(Set dst (AndI (XorI src1 minus_1) src2)); 9222 predicate(UseBMI1Instructions); 9223 effect(KILL cr); 9224 9225 format %{ "andnl $dst, $src1, $src2" %} 9226 9227 ins_encode %{ 9228 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9229 %} 9230 ins_pipe(ialu_reg); 9231 %} 9232 9233 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9234 match(Set dst (AndI (SubI imm_zero src) src)); 9235 predicate(UseBMI1Instructions); 9236 effect(KILL cr); 9237 9238 format %{ "blsil $dst, $src" %} 9239 9240 ins_encode %{ 9241 __ blsil($dst$$Register, $src$$Register); 9242 %} 9243 ins_pipe(ialu_reg); 9244 %} 9245 9246 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9247 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9248 predicate(UseBMI1Instructions); 9249 effect(KILL cr); 9250 9251 ins_cost(125); 9252 format %{ "blsil $dst, $src" %} 9253 9254 ins_encode %{ 9255 __ blsil($dst$$Register, $src$$Address); 9256 %} 9257 ins_pipe(ialu_reg_mem); 9258 %} 9259 9260 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9261 %{ 9262 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9263 predicate(UseBMI1Instructions); 9264 effect(KILL cr); 9265 9266 ins_cost(125); 9267 format %{ "blsmskl $dst, $src" %} 9268 9269 ins_encode %{ 9270 __ blsmskl($dst$$Register, $src$$Address); 9271 %} 9272 ins_pipe(ialu_reg_mem); 9273 %} 9274 9275 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9276 %{ 9277 match(Set dst (XorI (AddI src minus_1) src)); 9278 predicate(UseBMI1Instructions); 9279 effect(KILL cr); 9280 9281 format %{ "blsmskl $dst, $src" %} 9282 9283 ins_encode %{ 9284 __ blsmskl($dst$$Register, $src$$Register); 9285 %} 9286 9287 ins_pipe(ialu_reg); 9288 %} 9289 9290 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9291 %{ 9292 match(Set dst (AndI (AddI src minus_1) src) ); 9293 predicate(UseBMI1Instructions); 9294 effect(KILL cr); 9295 9296 format %{ "blsrl $dst, $src" %} 9297 9298 ins_encode %{ 9299 __ blsrl($dst$$Register, $src$$Register); 9300 %} 9301 9302 ins_pipe(ialu_reg_mem); 9303 %} 9304 9305 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9306 %{ 9307 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9308 predicate(UseBMI1Instructions); 9309 effect(KILL cr); 9310 9311 ins_cost(125); 9312 format %{ "blsrl $dst, $src" %} 9313 9314 ins_encode %{ 9315 __ blsrl($dst$$Register, $src$$Address); 9316 %} 9317 9318 ins_pipe(ialu_reg); 9319 %} 9320 9321 // Or Instructions 9322 // Or Register with Register 9323 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9324 %{ 9325 match(Set dst (OrI dst src)); 9326 effect(KILL cr); 9327 9328 format %{ "orl $dst, $src\t# int" %} 9329 opcode(0x0B); 9330 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9331 ins_pipe(ialu_reg_reg); 9332 %} 9333 9334 // Or Register with Immediate 9335 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9336 %{ 9337 match(Set dst (OrI dst src)); 9338 effect(KILL cr); 9339 9340 format %{ "orl $dst, $src\t# int" %} 9341 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9342 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9343 ins_pipe(ialu_reg); 9344 %} 9345 9346 // Or Register with Memory 9347 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9348 %{ 9349 match(Set dst (OrI dst (LoadI src))); 9350 effect(KILL cr); 9351 9352 ins_cost(125); 9353 format %{ "orl $dst, $src\t# int" %} 9354 opcode(0x0B); 9355 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9356 ins_pipe(ialu_reg_mem); 9357 %} 9358 9359 // Or Memory with Register 9360 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9361 %{ 9362 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9363 effect(KILL cr); 9364 9365 ins_cost(150); 9366 format %{ "orl $dst, $src\t# int" %} 9367 opcode(0x09); /* Opcode 09 /r */ 9368 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9369 ins_pipe(ialu_mem_reg); 9370 %} 9371 9372 // Or Memory with Immediate 9373 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9374 %{ 9375 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9376 effect(KILL cr); 9377 9378 ins_cost(125); 9379 format %{ "orl $dst, $src\t# int" %} 9380 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9381 ins_encode(REX_mem(dst), OpcSE(src), 9382 RM_opc_mem(secondary, dst), Con8or32(src)); 9383 ins_pipe(ialu_mem_imm); 9384 %} 9385 9386 // Xor Instructions 9387 // Xor Register with Register 9388 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9389 %{ 9390 match(Set dst (XorI dst src)); 9391 effect(KILL cr); 9392 9393 format %{ "xorl $dst, $src\t# int" %} 9394 opcode(0x33); 9395 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9396 ins_pipe(ialu_reg_reg); 9397 %} 9398 9399 // Xor Register with Immediate -1 9400 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9401 match(Set dst (XorI dst imm)); 9402 9403 format %{ "not $dst" %} 9404 ins_encode %{ 9405 __ notl($dst$$Register); 9406 %} 9407 ins_pipe(ialu_reg); 9408 %} 9409 9410 // Xor Register with Immediate 9411 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9412 %{ 9413 match(Set dst (XorI dst src)); 9414 effect(KILL cr); 9415 9416 format %{ "xorl $dst, $src\t# int" %} 9417 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9418 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9419 ins_pipe(ialu_reg); 9420 %} 9421 9422 // Xor Register with Memory 9423 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9424 %{ 9425 match(Set dst (XorI dst (LoadI src))); 9426 effect(KILL cr); 9427 9428 ins_cost(125); 9429 format %{ "xorl $dst, $src\t# int" %} 9430 opcode(0x33); 9431 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9432 ins_pipe(ialu_reg_mem); 9433 %} 9434 9435 // Xor Memory with Register 9436 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9437 %{ 9438 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9439 effect(KILL cr); 9440 9441 ins_cost(150); 9442 format %{ "xorl $dst, $src\t# int" %} 9443 opcode(0x31); /* Opcode 31 /r */ 9444 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9445 ins_pipe(ialu_mem_reg); 9446 %} 9447 9448 // Xor Memory with Immediate 9449 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9450 %{ 9451 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9452 effect(KILL cr); 9453 9454 ins_cost(125); 9455 format %{ "xorl $dst, $src\t# int" %} 9456 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9457 ins_encode(REX_mem(dst), OpcSE(src), 9458 RM_opc_mem(secondary, dst), Con8or32(src)); 9459 ins_pipe(ialu_mem_imm); 9460 %} 9461 9462 9463 // Long Logical Instructions 9464 9465 // And Instructions 9466 // And Register with Register 9467 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9468 %{ 9469 match(Set dst (AndL dst src)); 9470 effect(KILL cr); 9471 9472 format %{ "andq $dst, $src\t# long" %} 9473 opcode(0x23); 9474 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9475 ins_pipe(ialu_reg_reg); 9476 %} 9477 9478 // And Register with Immediate 255 9479 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9480 %{ 9481 match(Set dst (AndL dst src)); 9482 9483 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9484 opcode(0x0F, 0xB6); 9485 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9486 ins_pipe(ialu_reg); 9487 %} 9488 9489 // And Register with Immediate 65535 9490 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9491 %{ 9492 match(Set dst (AndL dst src)); 9493 9494 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9495 opcode(0x0F, 0xB7); 9496 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9497 ins_pipe(ialu_reg); 9498 %} 9499 9500 // And Register with Immediate 9501 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9502 %{ 9503 match(Set dst (AndL dst src)); 9504 effect(KILL cr); 9505 9506 format %{ "andq $dst, $src\t# long" %} 9507 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9508 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9509 ins_pipe(ialu_reg); 9510 %} 9511 9512 // And Register with Memory 9513 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9514 %{ 9515 match(Set dst (AndL dst (LoadL src))); 9516 effect(KILL cr); 9517 9518 ins_cost(125); 9519 format %{ "andq $dst, $src\t# long" %} 9520 opcode(0x23); 9521 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9522 ins_pipe(ialu_reg_mem); 9523 %} 9524 9525 // And Memory with Register 9526 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9527 %{ 9528 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9529 effect(KILL cr); 9530 9531 ins_cost(150); 9532 format %{ "andq $dst, $src\t# long" %} 9533 opcode(0x21); /* Opcode 21 /r */ 9534 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9535 ins_pipe(ialu_mem_reg); 9536 %} 9537 9538 // And Memory with Immediate 9539 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9540 %{ 9541 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9542 effect(KILL cr); 9543 9544 ins_cost(125); 9545 format %{ "andq $dst, $src\t# long" %} 9546 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9547 ins_encode(REX_mem_wide(dst), OpcSE(src), 9548 RM_opc_mem(secondary, dst), Con8or32(src)); 9549 ins_pipe(ialu_mem_imm); 9550 %} 9551 9552 // BMI1 instructions 9553 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9554 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9555 predicate(UseBMI1Instructions); 9556 effect(KILL cr); 9557 9558 ins_cost(125); 9559 format %{ "andnq $dst, $src1, $src2" %} 9560 9561 ins_encode %{ 9562 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9563 %} 9564 ins_pipe(ialu_reg_mem); 9565 %} 9566 9567 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9568 match(Set dst (AndL (XorL src1 minus_1) src2)); 9569 predicate(UseBMI1Instructions); 9570 effect(KILL cr); 9571 9572 format %{ "andnq $dst, $src1, $src2" %} 9573 9574 ins_encode %{ 9575 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9576 %} 9577 ins_pipe(ialu_reg_mem); 9578 %} 9579 9580 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9581 match(Set dst (AndL (SubL imm_zero src) src)); 9582 predicate(UseBMI1Instructions); 9583 effect(KILL cr); 9584 9585 format %{ "blsiq $dst, $src" %} 9586 9587 ins_encode %{ 9588 __ blsiq($dst$$Register, $src$$Register); 9589 %} 9590 ins_pipe(ialu_reg); 9591 %} 9592 9593 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9594 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9595 predicate(UseBMI1Instructions); 9596 effect(KILL cr); 9597 9598 ins_cost(125); 9599 format %{ "blsiq $dst, $src" %} 9600 9601 ins_encode %{ 9602 __ blsiq($dst$$Register, $src$$Address); 9603 %} 9604 ins_pipe(ialu_reg_mem); 9605 %} 9606 9607 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9608 %{ 9609 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9610 predicate(UseBMI1Instructions); 9611 effect(KILL cr); 9612 9613 ins_cost(125); 9614 format %{ "blsmskq $dst, $src" %} 9615 9616 ins_encode %{ 9617 __ blsmskq($dst$$Register, $src$$Address); 9618 %} 9619 ins_pipe(ialu_reg_mem); 9620 %} 9621 9622 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9623 %{ 9624 match(Set dst (XorL (AddL src minus_1) src)); 9625 predicate(UseBMI1Instructions); 9626 effect(KILL cr); 9627 9628 format %{ "blsmskq $dst, $src" %} 9629 9630 ins_encode %{ 9631 __ blsmskq($dst$$Register, $src$$Register); 9632 %} 9633 9634 ins_pipe(ialu_reg); 9635 %} 9636 9637 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9638 %{ 9639 match(Set dst (AndL (AddL src minus_1) src) ); 9640 predicate(UseBMI1Instructions); 9641 effect(KILL cr); 9642 9643 format %{ "blsrq $dst, $src" %} 9644 9645 ins_encode %{ 9646 __ blsrq($dst$$Register, $src$$Register); 9647 %} 9648 9649 ins_pipe(ialu_reg); 9650 %} 9651 9652 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9653 %{ 9654 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9655 predicate(UseBMI1Instructions); 9656 effect(KILL cr); 9657 9658 ins_cost(125); 9659 format %{ "blsrq $dst, $src" %} 9660 9661 ins_encode %{ 9662 __ blsrq($dst$$Register, $src$$Address); 9663 %} 9664 9665 ins_pipe(ialu_reg); 9666 %} 9667 9668 // Or Instructions 9669 // Or Register with Register 9670 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9671 %{ 9672 match(Set dst (OrL dst src)); 9673 effect(KILL cr); 9674 9675 format %{ "orq $dst, $src\t# long" %} 9676 opcode(0x0B); 9677 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9678 ins_pipe(ialu_reg_reg); 9679 %} 9680 9681 // Use any_RegP to match R15 (TLS register) without spilling. 9682 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9683 match(Set dst (OrL dst (CastP2X src))); 9684 effect(KILL cr); 9685 9686 format %{ "orq $dst, $src\t# long" %} 9687 opcode(0x0B); 9688 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9689 ins_pipe(ialu_reg_reg); 9690 %} 9691 9692 9693 // Or Register with Immediate 9694 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9695 %{ 9696 match(Set dst (OrL dst src)); 9697 effect(KILL cr); 9698 9699 format %{ "orq $dst, $src\t# long" %} 9700 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9701 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9702 ins_pipe(ialu_reg); 9703 %} 9704 9705 // Or Register with Memory 9706 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9707 %{ 9708 match(Set dst (OrL dst (LoadL src))); 9709 effect(KILL cr); 9710 9711 ins_cost(125); 9712 format %{ "orq $dst, $src\t# long" %} 9713 opcode(0x0B); 9714 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9715 ins_pipe(ialu_reg_mem); 9716 %} 9717 9718 // Or Memory with Register 9719 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9720 %{ 9721 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9722 effect(KILL cr); 9723 9724 ins_cost(150); 9725 format %{ "orq $dst, $src\t# long" %} 9726 opcode(0x09); /* Opcode 09 /r */ 9727 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9728 ins_pipe(ialu_mem_reg); 9729 %} 9730 9731 // Or Memory with Immediate 9732 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9733 %{ 9734 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9735 effect(KILL cr); 9736 9737 ins_cost(125); 9738 format %{ "orq $dst, $src\t# long" %} 9739 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9740 ins_encode(REX_mem_wide(dst), OpcSE(src), 9741 RM_opc_mem(secondary, dst), Con8or32(src)); 9742 ins_pipe(ialu_mem_imm); 9743 %} 9744 9745 // Xor Instructions 9746 // Xor Register with Register 9747 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9748 %{ 9749 match(Set dst (XorL dst src)); 9750 effect(KILL cr); 9751 9752 format %{ "xorq $dst, $src\t# long" %} 9753 opcode(0x33); 9754 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9755 ins_pipe(ialu_reg_reg); 9756 %} 9757 9758 // Xor Register with Immediate -1 9759 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9760 match(Set dst (XorL dst imm)); 9761 9762 format %{ "notq $dst" %} 9763 ins_encode %{ 9764 __ notq($dst$$Register); 9765 %} 9766 ins_pipe(ialu_reg); 9767 %} 9768 9769 // Xor Register with Immediate 9770 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9771 %{ 9772 match(Set dst (XorL dst src)); 9773 effect(KILL cr); 9774 9775 format %{ "xorq $dst, $src\t# long" %} 9776 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9777 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9778 ins_pipe(ialu_reg); 9779 %} 9780 9781 // Xor Register with Memory 9782 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9783 %{ 9784 match(Set dst (XorL dst (LoadL src))); 9785 effect(KILL cr); 9786 9787 ins_cost(125); 9788 format %{ "xorq $dst, $src\t# long" %} 9789 opcode(0x33); 9790 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9791 ins_pipe(ialu_reg_mem); 9792 %} 9793 9794 // Xor Memory with Register 9795 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9796 %{ 9797 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9798 effect(KILL cr); 9799 9800 ins_cost(150); 9801 format %{ "xorq $dst, $src\t# long" %} 9802 opcode(0x31); /* Opcode 31 /r */ 9803 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9804 ins_pipe(ialu_mem_reg); 9805 %} 9806 9807 // Xor Memory with Immediate 9808 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9809 %{ 9810 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9811 effect(KILL cr); 9812 9813 ins_cost(125); 9814 format %{ "xorq $dst, $src\t# long" %} 9815 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9816 ins_encode(REX_mem_wide(dst), OpcSE(src), 9817 RM_opc_mem(secondary, dst), Con8or32(src)); 9818 ins_pipe(ialu_mem_imm); 9819 %} 9820 9821 // Convert Int to Boolean 9822 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9823 %{ 9824 match(Set dst (Conv2B src)); 9825 effect(KILL cr); 9826 9827 format %{ "testl $src, $src\t# ci2b\n\t" 9828 "setnz $dst\n\t" 9829 "movzbl $dst, $dst" %} 9830 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9831 setNZ_reg(dst), 9832 REX_reg_breg(dst, dst), // movzbl 9833 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9834 ins_pipe(pipe_slow); // XXX 9835 %} 9836 9837 // Convert Pointer to Boolean 9838 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9839 %{ 9840 match(Set dst (Conv2B src)); 9841 effect(KILL cr); 9842 9843 format %{ "testq $src, $src\t# cp2b\n\t" 9844 "setnz $dst\n\t" 9845 "movzbl $dst, $dst" %} 9846 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9847 setNZ_reg(dst), 9848 REX_reg_breg(dst, dst), // movzbl 9849 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9850 ins_pipe(pipe_slow); // XXX 9851 %} 9852 9853 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9854 %{ 9855 match(Set dst (CmpLTMask p q)); 9856 effect(KILL cr); 9857 9858 ins_cost(400); 9859 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9860 "setlt $dst\n\t" 9861 "movzbl $dst, $dst\n\t" 9862 "negl $dst" %} 9863 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9864 setLT_reg(dst), 9865 REX_reg_breg(dst, dst), // movzbl 9866 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9867 neg_reg(dst)); 9868 ins_pipe(pipe_slow); 9869 %} 9870 9871 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9872 %{ 9873 match(Set dst (CmpLTMask dst zero)); 9874 effect(KILL cr); 9875 9876 ins_cost(100); 9877 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9878 ins_encode %{ 9879 __ sarl($dst$$Register, 31); 9880 %} 9881 ins_pipe(ialu_reg); 9882 %} 9883 9884 /* Better to save a register than avoid a branch */ 9885 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9886 %{ 9887 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9888 effect(KILL cr); 9889 ins_cost(300); 9890 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9891 "jge done\n\t" 9892 "addl $p,$y\n" 9893 "done: " %} 9894 ins_encode %{ 9895 Register Rp = $p$$Register; 9896 Register Rq = $q$$Register; 9897 Register Ry = $y$$Register; 9898 Label done; 9899 __ subl(Rp, Rq); 9900 __ jccb(Assembler::greaterEqual, done); 9901 __ addl(Rp, Ry); 9902 __ bind(done); 9903 %} 9904 ins_pipe(pipe_cmplt); 9905 %} 9906 9907 /* Better to save a register than avoid a branch */ 9908 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9909 %{ 9910 match(Set y (AndI (CmpLTMask p q) y)); 9911 effect(KILL cr); 9912 9913 ins_cost(300); 9914 9915 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9916 "jlt done\n\t" 9917 "xorl $y, $y\n" 9918 "done: " %} 9919 ins_encode %{ 9920 Register Rp = $p$$Register; 9921 Register Rq = $q$$Register; 9922 Register Ry = $y$$Register; 9923 Label done; 9924 __ cmpl(Rp, Rq); 9925 __ jccb(Assembler::less, done); 9926 __ xorl(Ry, Ry); 9927 __ bind(done); 9928 %} 9929 ins_pipe(pipe_cmplt); 9930 %} 9931 9932 9933 //---------- FP Instructions------------------------------------------------ 9934 9935 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9936 %{ 9937 match(Set cr (CmpF src1 src2)); 9938 9939 ins_cost(145); 9940 format %{ "ucomiss $src1, $src2\n\t" 9941 "jnp,s exit\n\t" 9942 "pushfq\t# saw NaN, set CF\n\t" 9943 "andq [rsp], #0xffffff2b\n\t" 9944 "popfq\n" 9945 "exit:" %} 9946 ins_encode %{ 9947 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9948 emit_cmpfp_fixup(_masm); 9949 %} 9950 ins_pipe(pipe_slow); 9951 %} 9952 9953 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9954 match(Set cr (CmpF src1 src2)); 9955 9956 ins_cost(100); 9957 format %{ "ucomiss $src1, $src2" %} 9958 ins_encode %{ 9959 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9960 %} 9961 ins_pipe(pipe_slow); 9962 %} 9963 9964 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9965 %{ 9966 match(Set cr (CmpF src1 (LoadF src2))); 9967 9968 ins_cost(145); 9969 format %{ "ucomiss $src1, $src2\n\t" 9970 "jnp,s exit\n\t" 9971 "pushfq\t# saw NaN, set CF\n\t" 9972 "andq [rsp], #0xffffff2b\n\t" 9973 "popfq\n" 9974 "exit:" %} 9975 ins_encode %{ 9976 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9977 emit_cmpfp_fixup(_masm); 9978 %} 9979 ins_pipe(pipe_slow); 9980 %} 9981 9982 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9983 match(Set cr (CmpF src1 (LoadF src2))); 9984 9985 ins_cost(100); 9986 format %{ "ucomiss $src1, $src2" %} 9987 ins_encode %{ 9988 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9989 %} 9990 ins_pipe(pipe_slow); 9991 %} 9992 9993 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9994 match(Set cr (CmpF src con)); 9995 9996 ins_cost(145); 9997 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9998 "jnp,s exit\n\t" 9999 "pushfq\t# saw NaN, set CF\n\t" 10000 "andq [rsp], #0xffffff2b\n\t" 10001 "popfq\n" 10002 "exit:" %} 10003 ins_encode %{ 10004 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10005 emit_cmpfp_fixup(_masm); 10006 %} 10007 ins_pipe(pipe_slow); 10008 %} 10009 10010 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10011 match(Set cr (CmpF src con)); 10012 ins_cost(100); 10013 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10014 ins_encode %{ 10015 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10016 %} 10017 ins_pipe(pipe_slow); 10018 %} 10019 10020 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10021 %{ 10022 match(Set cr (CmpD src1 src2)); 10023 10024 ins_cost(145); 10025 format %{ "ucomisd $src1, $src2\n\t" 10026 "jnp,s exit\n\t" 10027 "pushfq\t# saw NaN, set CF\n\t" 10028 "andq [rsp], #0xffffff2b\n\t" 10029 "popfq\n" 10030 "exit:" %} 10031 ins_encode %{ 10032 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10033 emit_cmpfp_fixup(_masm); 10034 %} 10035 ins_pipe(pipe_slow); 10036 %} 10037 10038 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10039 match(Set cr (CmpD src1 src2)); 10040 10041 ins_cost(100); 10042 format %{ "ucomisd $src1, $src2 test" %} 10043 ins_encode %{ 10044 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10045 %} 10046 ins_pipe(pipe_slow); 10047 %} 10048 10049 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10050 %{ 10051 match(Set cr (CmpD src1 (LoadD src2))); 10052 10053 ins_cost(145); 10054 format %{ "ucomisd $src1, $src2\n\t" 10055 "jnp,s exit\n\t" 10056 "pushfq\t# saw NaN, set CF\n\t" 10057 "andq [rsp], #0xffffff2b\n\t" 10058 "popfq\n" 10059 "exit:" %} 10060 ins_encode %{ 10061 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10062 emit_cmpfp_fixup(_masm); 10063 %} 10064 ins_pipe(pipe_slow); 10065 %} 10066 10067 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10068 match(Set cr (CmpD src1 (LoadD src2))); 10069 10070 ins_cost(100); 10071 format %{ "ucomisd $src1, $src2" %} 10072 ins_encode %{ 10073 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10074 %} 10075 ins_pipe(pipe_slow); 10076 %} 10077 10078 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10079 match(Set cr (CmpD src con)); 10080 10081 ins_cost(145); 10082 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10083 "jnp,s exit\n\t" 10084 "pushfq\t# saw NaN, set CF\n\t" 10085 "andq [rsp], #0xffffff2b\n\t" 10086 "popfq\n" 10087 "exit:" %} 10088 ins_encode %{ 10089 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10090 emit_cmpfp_fixup(_masm); 10091 %} 10092 ins_pipe(pipe_slow); 10093 %} 10094 10095 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10096 match(Set cr (CmpD src con)); 10097 ins_cost(100); 10098 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10099 ins_encode %{ 10100 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10101 %} 10102 ins_pipe(pipe_slow); 10103 %} 10104 10105 // Compare into -1,0,1 10106 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10107 %{ 10108 match(Set dst (CmpF3 src1 src2)); 10109 effect(KILL cr); 10110 10111 ins_cost(275); 10112 format %{ "ucomiss $src1, $src2\n\t" 10113 "movl $dst, #-1\n\t" 10114 "jp,s done\n\t" 10115 "jb,s done\n\t" 10116 "setne $dst\n\t" 10117 "movzbl $dst, $dst\n" 10118 "done:" %} 10119 ins_encode %{ 10120 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10121 emit_cmpfp3(_masm, $dst$$Register); 10122 %} 10123 ins_pipe(pipe_slow); 10124 %} 10125 10126 // Compare into -1,0,1 10127 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10128 %{ 10129 match(Set dst (CmpF3 src1 (LoadF src2))); 10130 effect(KILL cr); 10131 10132 ins_cost(275); 10133 format %{ "ucomiss $src1, $src2\n\t" 10134 "movl $dst, #-1\n\t" 10135 "jp,s done\n\t" 10136 "jb,s done\n\t" 10137 "setne $dst\n\t" 10138 "movzbl $dst, $dst\n" 10139 "done:" %} 10140 ins_encode %{ 10141 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10142 emit_cmpfp3(_masm, $dst$$Register); 10143 %} 10144 ins_pipe(pipe_slow); 10145 %} 10146 10147 // Compare into -1,0,1 10148 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10149 match(Set dst (CmpF3 src con)); 10150 effect(KILL cr); 10151 10152 ins_cost(275); 10153 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10154 "movl $dst, #-1\n\t" 10155 "jp,s done\n\t" 10156 "jb,s done\n\t" 10157 "setne $dst\n\t" 10158 "movzbl $dst, $dst\n" 10159 "done:" %} 10160 ins_encode %{ 10161 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10162 emit_cmpfp3(_masm, $dst$$Register); 10163 %} 10164 ins_pipe(pipe_slow); 10165 %} 10166 10167 // Compare into -1,0,1 10168 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10169 %{ 10170 match(Set dst (CmpD3 src1 src2)); 10171 effect(KILL cr); 10172 10173 ins_cost(275); 10174 format %{ "ucomisd $src1, $src2\n\t" 10175 "movl $dst, #-1\n\t" 10176 "jp,s done\n\t" 10177 "jb,s done\n\t" 10178 "setne $dst\n\t" 10179 "movzbl $dst, $dst\n" 10180 "done:" %} 10181 ins_encode %{ 10182 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10183 emit_cmpfp3(_masm, $dst$$Register); 10184 %} 10185 ins_pipe(pipe_slow); 10186 %} 10187 10188 // Compare into -1,0,1 10189 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10190 %{ 10191 match(Set dst (CmpD3 src1 (LoadD src2))); 10192 effect(KILL cr); 10193 10194 ins_cost(275); 10195 format %{ "ucomisd $src1, $src2\n\t" 10196 "movl $dst, #-1\n\t" 10197 "jp,s done\n\t" 10198 "jb,s done\n\t" 10199 "setne $dst\n\t" 10200 "movzbl $dst, $dst\n" 10201 "done:" %} 10202 ins_encode %{ 10203 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10204 emit_cmpfp3(_masm, $dst$$Register); 10205 %} 10206 ins_pipe(pipe_slow); 10207 %} 10208 10209 // Compare into -1,0,1 10210 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10211 match(Set dst (CmpD3 src con)); 10212 effect(KILL cr); 10213 10214 ins_cost(275); 10215 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10216 "movl $dst, #-1\n\t" 10217 "jp,s done\n\t" 10218 "jb,s done\n\t" 10219 "setne $dst\n\t" 10220 "movzbl $dst, $dst\n" 10221 "done:" %} 10222 ins_encode %{ 10223 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10224 emit_cmpfp3(_masm, $dst$$Register); 10225 %} 10226 ins_pipe(pipe_slow); 10227 %} 10228 10229 //----------Arithmetic Conversion Instructions--------------------------------- 10230 10231 instruct roundFloat_nop(regF dst) 10232 %{ 10233 match(Set dst (RoundFloat dst)); 10234 10235 ins_cost(0); 10236 ins_encode(); 10237 ins_pipe(empty); 10238 %} 10239 10240 instruct roundDouble_nop(regD dst) 10241 %{ 10242 match(Set dst (RoundDouble dst)); 10243 10244 ins_cost(0); 10245 ins_encode(); 10246 ins_pipe(empty); 10247 %} 10248 10249 instruct convF2D_reg_reg(regD dst, regF src) 10250 %{ 10251 match(Set dst (ConvF2D src)); 10252 10253 format %{ "cvtss2sd $dst, $src" %} 10254 ins_encode %{ 10255 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10256 %} 10257 ins_pipe(pipe_slow); // XXX 10258 %} 10259 10260 instruct convF2D_reg_mem(regD dst, memory src) 10261 %{ 10262 match(Set dst (ConvF2D (LoadF src))); 10263 10264 format %{ "cvtss2sd $dst, $src" %} 10265 ins_encode %{ 10266 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10267 %} 10268 ins_pipe(pipe_slow); // XXX 10269 %} 10270 10271 instruct convD2F_reg_reg(regF dst, regD src) 10272 %{ 10273 match(Set dst (ConvD2F src)); 10274 10275 format %{ "cvtsd2ss $dst, $src" %} 10276 ins_encode %{ 10277 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10278 %} 10279 ins_pipe(pipe_slow); // XXX 10280 %} 10281 10282 instruct convD2F_reg_mem(regF dst, memory src) 10283 %{ 10284 match(Set dst (ConvD2F (LoadD src))); 10285 10286 format %{ "cvtsd2ss $dst, $src" %} 10287 ins_encode %{ 10288 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10289 %} 10290 ins_pipe(pipe_slow); // XXX 10291 %} 10292 10293 // XXX do mem variants 10294 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10295 %{ 10296 match(Set dst (ConvF2I src)); 10297 effect(KILL cr); 10298 10299 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10300 "cmpl $dst, #0x80000000\n\t" 10301 "jne,s done\n\t" 10302 "subq rsp, #8\n\t" 10303 "movss [rsp], $src\n\t" 10304 "call f2i_fixup\n\t" 10305 "popq $dst\n" 10306 "done: "%} 10307 ins_encode %{ 10308 Label done; 10309 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10310 __ cmpl($dst$$Register, 0x80000000); 10311 __ jccb(Assembler::notEqual, done); 10312 __ subptr(rsp, 8); 10313 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10314 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10315 __ pop($dst$$Register); 10316 __ bind(done); 10317 %} 10318 ins_pipe(pipe_slow); 10319 %} 10320 10321 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10322 %{ 10323 match(Set dst (ConvF2L src)); 10324 effect(KILL cr); 10325 10326 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10327 "cmpq $dst, [0x8000000000000000]\n\t" 10328 "jne,s done\n\t" 10329 "subq rsp, #8\n\t" 10330 "movss [rsp], $src\n\t" 10331 "call f2l_fixup\n\t" 10332 "popq $dst\n" 10333 "done: "%} 10334 ins_encode %{ 10335 Label done; 10336 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10337 __ cmp64($dst$$Register, 10338 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10339 __ jccb(Assembler::notEqual, done); 10340 __ subptr(rsp, 8); 10341 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10342 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10343 __ pop($dst$$Register); 10344 __ bind(done); 10345 %} 10346 ins_pipe(pipe_slow); 10347 %} 10348 10349 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10350 %{ 10351 match(Set dst (ConvD2I src)); 10352 effect(KILL cr); 10353 10354 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10355 "cmpl $dst, #0x80000000\n\t" 10356 "jne,s done\n\t" 10357 "subq rsp, #8\n\t" 10358 "movsd [rsp], $src\n\t" 10359 "call d2i_fixup\n\t" 10360 "popq $dst\n" 10361 "done: "%} 10362 ins_encode %{ 10363 Label done; 10364 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10365 __ cmpl($dst$$Register, 0x80000000); 10366 __ jccb(Assembler::notEqual, done); 10367 __ subptr(rsp, 8); 10368 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10369 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10370 __ pop($dst$$Register); 10371 __ bind(done); 10372 %} 10373 ins_pipe(pipe_slow); 10374 %} 10375 10376 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10377 %{ 10378 match(Set dst (ConvD2L src)); 10379 effect(KILL cr); 10380 10381 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10382 "cmpq $dst, [0x8000000000000000]\n\t" 10383 "jne,s done\n\t" 10384 "subq rsp, #8\n\t" 10385 "movsd [rsp], $src\n\t" 10386 "call d2l_fixup\n\t" 10387 "popq $dst\n" 10388 "done: "%} 10389 ins_encode %{ 10390 Label done; 10391 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10392 __ cmp64($dst$$Register, 10393 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10394 __ jccb(Assembler::notEqual, done); 10395 __ subptr(rsp, 8); 10396 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10397 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10398 __ pop($dst$$Register); 10399 __ bind(done); 10400 %} 10401 ins_pipe(pipe_slow); 10402 %} 10403 10404 instruct convI2F_reg_reg(regF dst, rRegI src) 10405 %{ 10406 predicate(!UseXmmI2F); 10407 match(Set dst (ConvI2F src)); 10408 10409 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10410 ins_encode %{ 10411 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10412 %} 10413 ins_pipe(pipe_slow); // XXX 10414 %} 10415 10416 instruct convI2F_reg_mem(regF dst, memory src) 10417 %{ 10418 match(Set dst (ConvI2F (LoadI src))); 10419 10420 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10421 ins_encode %{ 10422 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10423 %} 10424 ins_pipe(pipe_slow); // XXX 10425 %} 10426 10427 instruct convI2D_reg_reg(regD dst, rRegI src) 10428 %{ 10429 predicate(!UseXmmI2D); 10430 match(Set dst (ConvI2D src)); 10431 10432 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10433 ins_encode %{ 10434 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10435 %} 10436 ins_pipe(pipe_slow); // XXX 10437 %} 10438 10439 instruct convI2D_reg_mem(regD dst, memory src) 10440 %{ 10441 match(Set dst (ConvI2D (LoadI src))); 10442 10443 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10444 ins_encode %{ 10445 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10446 %} 10447 ins_pipe(pipe_slow); // XXX 10448 %} 10449 10450 instruct convXI2F_reg(regF dst, rRegI src) 10451 %{ 10452 predicate(UseXmmI2F); 10453 match(Set dst (ConvI2F src)); 10454 10455 format %{ "movdl $dst, $src\n\t" 10456 "cvtdq2psl $dst, $dst\t# i2f" %} 10457 ins_encode %{ 10458 __ movdl($dst$$XMMRegister, $src$$Register); 10459 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10460 %} 10461 ins_pipe(pipe_slow); // XXX 10462 %} 10463 10464 instruct convXI2D_reg(regD dst, rRegI src) 10465 %{ 10466 predicate(UseXmmI2D); 10467 match(Set dst (ConvI2D src)); 10468 10469 format %{ "movdl $dst, $src\n\t" 10470 "cvtdq2pdl $dst, $dst\t# i2d" %} 10471 ins_encode %{ 10472 __ movdl($dst$$XMMRegister, $src$$Register); 10473 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10474 %} 10475 ins_pipe(pipe_slow); // XXX 10476 %} 10477 10478 instruct convL2F_reg_reg(regF dst, rRegL src) 10479 %{ 10480 match(Set dst (ConvL2F src)); 10481 10482 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10483 ins_encode %{ 10484 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10485 %} 10486 ins_pipe(pipe_slow); // XXX 10487 %} 10488 10489 instruct convL2F_reg_mem(regF dst, memory src) 10490 %{ 10491 match(Set dst (ConvL2F (LoadL src))); 10492 10493 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10494 ins_encode %{ 10495 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10496 %} 10497 ins_pipe(pipe_slow); // XXX 10498 %} 10499 10500 instruct convL2D_reg_reg(regD dst, rRegL src) 10501 %{ 10502 match(Set dst (ConvL2D src)); 10503 10504 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10505 ins_encode %{ 10506 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10507 %} 10508 ins_pipe(pipe_slow); // XXX 10509 %} 10510 10511 instruct convL2D_reg_mem(regD dst, memory src) 10512 %{ 10513 match(Set dst (ConvL2D (LoadL src))); 10514 10515 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10516 ins_encode %{ 10517 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10518 %} 10519 ins_pipe(pipe_slow); // XXX 10520 %} 10521 10522 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10523 %{ 10524 match(Set dst (ConvI2L src)); 10525 10526 ins_cost(125); 10527 format %{ "movslq $dst, $src\t# i2l" %} 10528 ins_encode %{ 10529 __ movslq($dst$$Register, $src$$Register); 10530 %} 10531 ins_pipe(ialu_reg_reg); 10532 %} 10533 10534 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10535 // %{ 10536 // match(Set dst (ConvI2L src)); 10537 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10538 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10539 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10540 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10541 // ((const TypeNode*) n)->type()->is_long()->_lo == 10542 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10543 10544 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10545 // ins_encode(enc_copy(dst, src)); 10546 // // opcode(0x63); // needs REX.W 10547 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10548 // ins_pipe(ialu_reg_reg); 10549 // %} 10550 10551 // Zero-extend convert int to long 10552 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10553 %{ 10554 match(Set dst (AndL (ConvI2L src) mask)); 10555 10556 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10557 ins_encode %{ 10558 if ($dst$$reg != $src$$reg) { 10559 __ movl($dst$$Register, $src$$Register); 10560 } 10561 %} 10562 ins_pipe(ialu_reg_reg); 10563 %} 10564 10565 // Zero-extend convert int to long 10566 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10567 %{ 10568 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10569 10570 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10571 ins_encode %{ 10572 __ movl($dst$$Register, $src$$Address); 10573 %} 10574 ins_pipe(ialu_reg_mem); 10575 %} 10576 10577 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10578 %{ 10579 match(Set dst (AndL src mask)); 10580 10581 format %{ "movl $dst, $src\t# zero-extend long" %} 10582 ins_encode %{ 10583 __ movl($dst$$Register, $src$$Register); 10584 %} 10585 ins_pipe(ialu_reg_reg); 10586 %} 10587 10588 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10589 %{ 10590 match(Set dst (ConvL2I src)); 10591 10592 format %{ "movl $dst, $src\t# l2i" %} 10593 ins_encode %{ 10594 __ movl($dst$$Register, $src$$Register); 10595 %} 10596 ins_pipe(ialu_reg_reg); 10597 %} 10598 10599 10600 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10601 match(Set dst (MoveF2I src)); 10602 effect(DEF dst, USE src); 10603 10604 ins_cost(125); 10605 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10606 ins_encode %{ 10607 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10608 %} 10609 ins_pipe(ialu_reg_mem); 10610 %} 10611 10612 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10613 match(Set dst (MoveI2F src)); 10614 effect(DEF dst, USE src); 10615 10616 ins_cost(125); 10617 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10618 ins_encode %{ 10619 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10620 %} 10621 ins_pipe(pipe_slow); 10622 %} 10623 10624 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10625 match(Set dst (MoveD2L src)); 10626 effect(DEF dst, USE src); 10627 10628 ins_cost(125); 10629 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10630 ins_encode %{ 10631 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10632 %} 10633 ins_pipe(ialu_reg_mem); 10634 %} 10635 10636 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10637 predicate(!UseXmmLoadAndClearUpper); 10638 match(Set dst (MoveL2D src)); 10639 effect(DEF dst, USE src); 10640 10641 ins_cost(125); 10642 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10643 ins_encode %{ 10644 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10645 %} 10646 ins_pipe(pipe_slow); 10647 %} 10648 10649 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10650 predicate(UseXmmLoadAndClearUpper); 10651 match(Set dst (MoveL2D src)); 10652 effect(DEF dst, USE src); 10653 10654 ins_cost(125); 10655 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10656 ins_encode %{ 10657 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10658 %} 10659 ins_pipe(pipe_slow); 10660 %} 10661 10662 10663 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10664 match(Set dst (MoveF2I src)); 10665 effect(DEF dst, USE src); 10666 10667 ins_cost(95); // XXX 10668 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10669 ins_encode %{ 10670 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10671 %} 10672 ins_pipe(pipe_slow); 10673 %} 10674 10675 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10676 match(Set dst (MoveI2F src)); 10677 effect(DEF dst, USE src); 10678 10679 ins_cost(100); 10680 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10681 ins_encode %{ 10682 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10683 %} 10684 ins_pipe( ialu_mem_reg ); 10685 %} 10686 10687 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10688 match(Set dst (MoveD2L src)); 10689 effect(DEF dst, USE src); 10690 10691 ins_cost(95); // XXX 10692 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10693 ins_encode %{ 10694 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10695 %} 10696 ins_pipe(pipe_slow); 10697 %} 10698 10699 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10700 match(Set dst (MoveL2D src)); 10701 effect(DEF dst, USE src); 10702 10703 ins_cost(100); 10704 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10705 ins_encode %{ 10706 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10707 %} 10708 ins_pipe(ialu_mem_reg); 10709 %} 10710 10711 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10712 match(Set dst (MoveF2I src)); 10713 effect(DEF dst, USE src); 10714 ins_cost(85); 10715 format %{ "movd $dst,$src\t# MoveF2I" %} 10716 ins_encode %{ 10717 __ movdl($dst$$Register, $src$$XMMRegister); 10718 %} 10719 ins_pipe( pipe_slow ); 10720 %} 10721 10722 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10723 match(Set dst (MoveD2L src)); 10724 effect(DEF dst, USE src); 10725 ins_cost(85); 10726 format %{ "movd $dst,$src\t# MoveD2L" %} 10727 ins_encode %{ 10728 __ movdq($dst$$Register, $src$$XMMRegister); 10729 %} 10730 ins_pipe( pipe_slow ); 10731 %} 10732 10733 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10734 match(Set dst (MoveI2F src)); 10735 effect(DEF dst, USE src); 10736 ins_cost(100); 10737 format %{ "movd $dst,$src\t# MoveI2F" %} 10738 ins_encode %{ 10739 __ movdl($dst$$XMMRegister, $src$$Register); 10740 %} 10741 ins_pipe( pipe_slow ); 10742 %} 10743 10744 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10745 match(Set dst (MoveL2D src)); 10746 effect(DEF dst, USE src); 10747 ins_cost(100); 10748 format %{ "movd $dst,$src\t# MoveL2D" %} 10749 ins_encode %{ 10750 __ movdq($dst$$XMMRegister, $src$$Register); 10751 %} 10752 ins_pipe( pipe_slow ); 10753 %} 10754 10755 10756 // ======================================================================= 10757 // fast clearing of an array 10758 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10759 rFlagsReg cr) 10760 %{ 10761 predicate(!((ClearArrayNode*)n)->is_large()); 10762 match(Set dummy (ClearArray cnt base)); 10763 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10764 10765 format %{ $$template 10766 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10767 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10768 $$emit$$"jg LARGE\n\t" 10769 $$emit$$"dec rcx\n\t" 10770 $$emit$$"js DONE\t# Zero length\n\t" 10771 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10772 $$emit$$"dec rcx\n\t" 10773 $$emit$$"jge LOOP\n\t" 10774 $$emit$$"jmp DONE\n\t" 10775 $$emit$$"# LARGE:\n\t" 10776 if (UseFastStosb) { 10777 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10778 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10779 } else { 10780 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10781 } 10782 $$emit$$"# DONE" 10783 %} 10784 ins_encode %{ 10785 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, false); 10786 %} 10787 ins_pipe(pipe_slow); 10788 %} 10789 10790 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10791 rFlagsReg cr) 10792 %{ 10793 predicate(((ClearArrayNode*)n)->is_large()); 10794 match(Set dummy (ClearArray cnt base)); 10795 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10796 10797 format %{ $$template 10798 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10799 if (UseFastStosb) { 10800 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10801 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10802 } else { 10803 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10804 } 10805 %} 10806 ins_encode %{ 10807 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, true); 10808 %} 10809 ins_pipe(pipe_slow); 10810 %} 10811 10812 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10813 rax_RegI result, regD tmp1, rFlagsReg cr) 10814 %{ 10815 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10816 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10817 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10818 10819 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10820 ins_encode %{ 10821 __ string_compare($str1$$Register, $str2$$Register, 10822 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10823 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 10824 %} 10825 ins_pipe( pipe_slow ); 10826 %} 10827 10828 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10829 rax_RegI result, regD tmp1, rFlagsReg cr) 10830 %{ 10831 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10832 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10833 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10834 10835 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10836 ins_encode %{ 10837 __ string_compare($str1$$Register, $str2$$Register, 10838 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10839 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 10840 %} 10841 ins_pipe( pipe_slow ); 10842 %} 10843 10844 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10845 rax_RegI result, regD tmp1, rFlagsReg cr) 10846 %{ 10847 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10848 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10849 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10850 10851 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10852 ins_encode %{ 10853 __ string_compare($str1$$Register, $str2$$Register, 10854 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10855 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 10856 %} 10857 ins_pipe( pipe_slow ); 10858 %} 10859 10860 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10861 rax_RegI result, regD tmp1, rFlagsReg cr) 10862 %{ 10863 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10864 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10865 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10866 10867 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10868 ins_encode %{ 10869 __ string_compare($str2$$Register, $str1$$Register, 10870 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10871 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 10872 %} 10873 ins_pipe( pipe_slow ); 10874 %} 10875 10876 // fast search of substring with known size. 10877 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10878 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10879 %{ 10880 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10881 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10882 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10883 10884 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10885 ins_encode %{ 10886 int icnt2 = (int)$int_cnt2$$constant; 10887 if (icnt2 >= 16) { 10888 // IndexOf for constant substrings with size >= 16 elements 10889 // which don't need to be loaded through stack. 10890 __ string_indexofC8($str1$$Register, $str2$$Register, 10891 $cnt1$$Register, $cnt2$$Register, 10892 icnt2, $result$$Register, 10893 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10894 } else { 10895 // Small strings are loaded through stack if they cross page boundary. 10896 __ string_indexof($str1$$Register, $str2$$Register, 10897 $cnt1$$Register, $cnt2$$Register, 10898 icnt2, $result$$Register, 10899 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10900 } 10901 %} 10902 ins_pipe( pipe_slow ); 10903 %} 10904 10905 // fast search of substring with known size. 10906 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10907 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10908 %{ 10909 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10910 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10911 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10912 10913 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10914 ins_encode %{ 10915 int icnt2 = (int)$int_cnt2$$constant; 10916 if (icnt2 >= 8) { 10917 // IndexOf for constant substrings with size >= 8 elements 10918 // which don't need to be loaded through stack. 10919 __ string_indexofC8($str1$$Register, $str2$$Register, 10920 $cnt1$$Register, $cnt2$$Register, 10921 icnt2, $result$$Register, 10922 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10923 } else { 10924 // Small strings are loaded through stack if they cross page boundary. 10925 __ string_indexof($str1$$Register, $str2$$Register, 10926 $cnt1$$Register, $cnt2$$Register, 10927 icnt2, $result$$Register, 10928 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10929 } 10930 %} 10931 ins_pipe( pipe_slow ); 10932 %} 10933 10934 // fast search of substring with known size. 10935 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10936 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10937 %{ 10938 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10939 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10940 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10941 10942 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10943 ins_encode %{ 10944 int icnt2 = (int)$int_cnt2$$constant; 10945 if (icnt2 >= 8) { 10946 // IndexOf for constant substrings with size >= 8 elements 10947 // which don't need to be loaded through stack. 10948 __ string_indexofC8($str1$$Register, $str2$$Register, 10949 $cnt1$$Register, $cnt2$$Register, 10950 icnt2, $result$$Register, 10951 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10952 } else { 10953 // Small strings are loaded through stack if they cross page boundary. 10954 __ string_indexof($str1$$Register, $str2$$Register, 10955 $cnt1$$Register, $cnt2$$Register, 10956 icnt2, $result$$Register, 10957 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10958 } 10959 %} 10960 ins_pipe( pipe_slow ); 10961 %} 10962 10963 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10964 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10965 %{ 10966 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10967 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10968 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10969 10970 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10971 ins_encode %{ 10972 __ string_indexof($str1$$Register, $str2$$Register, 10973 $cnt1$$Register, $cnt2$$Register, 10974 (-1), $result$$Register, 10975 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10976 %} 10977 ins_pipe( pipe_slow ); 10978 %} 10979 10980 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10981 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10982 %{ 10983 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10984 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10985 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10986 10987 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10988 ins_encode %{ 10989 __ string_indexof($str1$$Register, $str2$$Register, 10990 $cnt1$$Register, $cnt2$$Register, 10991 (-1), $result$$Register, 10992 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10993 %} 10994 ins_pipe( pipe_slow ); 10995 %} 10996 10997 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10998 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10999 %{ 11000 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11001 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11002 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11003 11004 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11005 ins_encode %{ 11006 __ string_indexof($str1$$Register, $str2$$Register, 11007 $cnt1$$Register, $cnt2$$Register, 11008 (-1), $result$$Register, 11009 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11010 %} 11011 ins_pipe( pipe_slow ); 11012 %} 11013 11014 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11015 rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr) 11016 %{ 11017 predicate(UseSSE42Intrinsics); 11018 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11019 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11020 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11021 ins_encode %{ 11022 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11023 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11024 %} 11025 ins_pipe( pipe_slow ); 11026 %} 11027 11028 // fast string equals 11029 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11030 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11031 %{ 11032 match(Set result (StrEquals (Binary str1 str2) cnt)); 11033 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11034 11035 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11036 ins_encode %{ 11037 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11038 $cnt$$Register, $result$$Register, $tmp3$$Register, 11039 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11040 %} 11041 ins_pipe( pipe_slow ); 11042 %} 11043 11044 // fast array equals 11045 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11046 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11047 %{ 11048 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11049 match(Set result (AryEq ary1 ary2)); 11050 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11051 11052 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11053 ins_encode %{ 11054 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11055 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11056 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11057 %} 11058 ins_pipe( pipe_slow ); 11059 %} 11060 11061 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11062 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11063 %{ 11064 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11065 match(Set result (AryEq ary1 ary2)); 11066 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11067 11068 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11069 ins_encode %{ 11070 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11071 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11072 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11073 %} 11074 ins_pipe( pipe_slow ); 11075 %} 11076 11077 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11078 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11079 %{ 11080 match(Set result (HasNegatives ary1 len)); 11081 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11082 11083 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11084 ins_encode %{ 11085 __ has_negatives($ary1$$Register, $len$$Register, 11086 $result$$Register, $tmp3$$Register, 11087 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11088 %} 11089 ins_pipe( pipe_slow ); 11090 %} 11091 11092 // fast char[] to byte[] compression 11093 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11094 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11095 match(Set result (StrCompressedCopy src (Binary dst len))); 11096 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11097 11098 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11099 ins_encode %{ 11100 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11101 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11102 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11103 %} 11104 ins_pipe( pipe_slow ); 11105 %} 11106 11107 // fast byte[] to char[] inflation 11108 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11109 regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11110 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11111 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11112 11113 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11114 ins_encode %{ 11115 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11116 $tmp1$$XMMRegister, $tmp2$$Register); 11117 %} 11118 ins_pipe( pipe_slow ); 11119 %} 11120 11121 // encode char[] to byte[] in ISO_8859_1 11122 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11123 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11124 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11125 match(Set result (EncodeISOArray src (Binary dst len))); 11126 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11127 11128 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11129 ins_encode %{ 11130 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11131 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11132 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11133 %} 11134 ins_pipe( pipe_slow ); 11135 %} 11136 11137 //----------Overflow Math Instructions----------------------------------------- 11138 11139 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11140 %{ 11141 match(Set cr (OverflowAddI op1 op2)); 11142 effect(DEF cr, USE_KILL op1, USE op2); 11143 11144 format %{ "addl $op1, $op2\t# overflow check int" %} 11145 11146 ins_encode %{ 11147 __ addl($op1$$Register, $op2$$Register); 11148 %} 11149 ins_pipe(ialu_reg_reg); 11150 %} 11151 11152 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11153 %{ 11154 match(Set cr (OverflowAddI op1 op2)); 11155 effect(DEF cr, USE_KILL op1, USE op2); 11156 11157 format %{ "addl $op1, $op2\t# overflow check int" %} 11158 11159 ins_encode %{ 11160 __ addl($op1$$Register, $op2$$constant); 11161 %} 11162 ins_pipe(ialu_reg_reg); 11163 %} 11164 11165 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11166 %{ 11167 match(Set cr (OverflowAddL op1 op2)); 11168 effect(DEF cr, USE_KILL op1, USE op2); 11169 11170 format %{ "addq $op1, $op2\t# overflow check long" %} 11171 ins_encode %{ 11172 __ addq($op1$$Register, $op2$$Register); 11173 %} 11174 ins_pipe(ialu_reg_reg); 11175 %} 11176 11177 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11178 %{ 11179 match(Set cr (OverflowAddL op1 op2)); 11180 effect(DEF cr, USE_KILL op1, USE op2); 11181 11182 format %{ "addq $op1, $op2\t# overflow check long" %} 11183 ins_encode %{ 11184 __ addq($op1$$Register, $op2$$constant); 11185 %} 11186 ins_pipe(ialu_reg_reg); 11187 %} 11188 11189 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11190 %{ 11191 match(Set cr (OverflowSubI op1 op2)); 11192 11193 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11194 ins_encode %{ 11195 __ cmpl($op1$$Register, $op2$$Register); 11196 %} 11197 ins_pipe(ialu_reg_reg); 11198 %} 11199 11200 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11201 %{ 11202 match(Set cr (OverflowSubI op1 op2)); 11203 11204 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11205 ins_encode %{ 11206 __ cmpl($op1$$Register, $op2$$constant); 11207 %} 11208 ins_pipe(ialu_reg_reg); 11209 %} 11210 11211 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11212 %{ 11213 match(Set cr (OverflowSubL op1 op2)); 11214 11215 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11216 ins_encode %{ 11217 __ cmpq($op1$$Register, $op2$$Register); 11218 %} 11219 ins_pipe(ialu_reg_reg); 11220 %} 11221 11222 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11223 %{ 11224 match(Set cr (OverflowSubL op1 op2)); 11225 11226 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11227 ins_encode %{ 11228 __ cmpq($op1$$Register, $op2$$constant); 11229 %} 11230 ins_pipe(ialu_reg_reg); 11231 %} 11232 11233 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11234 %{ 11235 match(Set cr (OverflowSubI zero op2)); 11236 effect(DEF cr, USE_KILL op2); 11237 11238 format %{ "negl $op2\t# overflow check int" %} 11239 ins_encode %{ 11240 __ negl($op2$$Register); 11241 %} 11242 ins_pipe(ialu_reg_reg); 11243 %} 11244 11245 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11246 %{ 11247 match(Set cr (OverflowSubL zero op2)); 11248 effect(DEF cr, USE_KILL op2); 11249 11250 format %{ "negq $op2\t# overflow check long" %} 11251 ins_encode %{ 11252 __ negq($op2$$Register); 11253 %} 11254 ins_pipe(ialu_reg_reg); 11255 %} 11256 11257 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11258 %{ 11259 match(Set cr (OverflowMulI op1 op2)); 11260 effect(DEF cr, USE_KILL op1, USE op2); 11261 11262 format %{ "imull $op1, $op2\t# overflow check int" %} 11263 ins_encode %{ 11264 __ imull($op1$$Register, $op2$$Register); 11265 %} 11266 ins_pipe(ialu_reg_reg_alu0); 11267 %} 11268 11269 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11270 %{ 11271 match(Set cr (OverflowMulI op1 op2)); 11272 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11273 11274 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11275 ins_encode %{ 11276 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11277 %} 11278 ins_pipe(ialu_reg_reg_alu0); 11279 %} 11280 11281 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11282 %{ 11283 match(Set cr (OverflowMulL op1 op2)); 11284 effect(DEF cr, USE_KILL op1, USE op2); 11285 11286 format %{ "imulq $op1, $op2\t# overflow check long" %} 11287 ins_encode %{ 11288 __ imulq($op1$$Register, $op2$$Register); 11289 %} 11290 ins_pipe(ialu_reg_reg_alu0); 11291 %} 11292 11293 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11294 %{ 11295 match(Set cr (OverflowMulL op1 op2)); 11296 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11297 11298 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11299 ins_encode %{ 11300 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11301 %} 11302 ins_pipe(ialu_reg_reg_alu0); 11303 %} 11304 11305 11306 //----------Control Flow Instructions------------------------------------------ 11307 // Signed compare Instructions 11308 11309 // XXX more variants!! 11310 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11311 %{ 11312 match(Set cr (CmpI op1 op2)); 11313 effect(DEF cr, USE op1, USE op2); 11314 11315 format %{ "cmpl $op1, $op2" %} 11316 opcode(0x3B); /* Opcode 3B /r */ 11317 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11318 ins_pipe(ialu_cr_reg_reg); 11319 %} 11320 11321 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11322 %{ 11323 match(Set cr (CmpI op1 op2)); 11324 11325 format %{ "cmpl $op1, $op2" %} 11326 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11327 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11328 ins_pipe(ialu_cr_reg_imm); 11329 %} 11330 11331 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11332 %{ 11333 match(Set cr (CmpI op1 (LoadI op2))); 11334 11335 ins_cost(500); // XXX 11336 format %{ "cmpl $op1, $op2" %} 11337 opcode(0x3B); /* Opcode 3B /r */ 11338 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11339 ins_pipe(ialu_cr_reg_mem); 11340 %} 11341 11342 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11343 %{ 11344 match(Set cr (CmpI src zero)); 11345 11346 format %{ "testl $src, $src" %} 11347 opcode(0x85); 11348 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11349 ins_pipe(ialu_cr_reg_imm); 11350 %} 11351 11352 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11353 %{ 11354 match(Set cr (CmpI (AndI src con) zero)); 11355 11356 format %{ "testl $src, $con" %} 11357 opcode(0xF7, 0x00); 11358 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11359 ins_pipe(ialu_cr_reg_imm); 11360 %} 11361 11362 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11363 %{ 11364 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11365 11366 format %{ "testl $src, $mem" %} 11367 opcode(0x85); 11368 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11369 ins_pipe(ialu_cr_reg_mem); 11370 %} 11371 11372 // Unsigned compare Instructions; really, same as signed except they 11373 // produce an rFlagsRegU instead of rFlagsReg. 11374 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11375 %{ 11376 match(Set cr (CmpU op1 op2)); 11377 11378 format %{ "cmpl $op1, $op2\t# unsigned" %} 11379 opcode(0x3B); /* Opcode 3B /r */ 11380 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11381 ins_pipe(ialu_cr_reg_reg); 11382 %} 11383 11384 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11385 %{ 11386 match(Set cr (CmpU op1 op2)); 11387 11388 format %{ "cmpl $op1, $op2\t# unsigned" %} 11389 opcode(0x81,0x07); /* Opcode 81 /7 */ 11390 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11391 ins_pipe(ialu_cr_reg_imm); 11392 %} 11393 11394 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11395 %{ 11396 match(Set cr (CmpU op1 (LoadI op2))); 11397 11398 ins_cost(500); // XXX 11399 format %{ "cmpl $op1, $op2\t# unsigned" %} 11400 opcode(0x3B); /* Opcode 3B /r */ 11401 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11402 ins_pipe(ialu_cr_reg_mem); 11403 %} 11404 11405 // // // Cisc-spilled version of cmpU_rReg 11406 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11407 // //%{ 11408 // // match(Set cr (CmpU (LoadI op1) op2)); 11409 // // 11410 // // format %{ "CMPu $op1,$op2" %} 11411 // // ins_cost(500); 11412 // // opcode(0x39); /* Opcode 39 /r */ 11413 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11414 // //%} 11415 11416 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11417 %{ 11418 match(Set cr (CmpU src zero)); 11419 11420 format %{ "testl $src, $src\t# unsigned" %} 11421 opcode(0x85); 11422 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11423 ins_pipe(ialu_cr_reg_imm); 11424 %} 11425 11426 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11427 %{ 11428 match(Set cr (CmpP op1 op2)); 11429 11430 format %{ "cmpq $op1, $op2\t# ptr" %} 11431 opcode(0x3B); /* Opcode 3B /r */ 11432 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11433 ins_pipe(ialu_cr_reg_reg); 11434 %} 11435 11436 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11437 %{ 11438 match(Set cr (CmpP op1 (LoadP op2))); 11439 11440 ins_cost(500); // XXX 11441 format %{ "cmpq $op1, $op2\t# ptr" %} 11442 opcode(0x3B); /* Opcode 3B /r */ 11443 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11444 ins_pipe(ialu_cr_reg_mem); 11445 %} 11446 11447 // // // Cisc-spilled version of cmpP_rReg 11448 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11449 // //%{ 11450 // // match(Set cr (CmpP (LoadP op1) op2)); 11451 // // 11452 // // format %{ "CMPu $op1,$op2" %} 11453 // // ins_cost(500); 11454 // // opcode(0x39); /* Opcode 39 /r */ 11455 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11456 // //%} 11457 11458 // XXX this is generalized by compP_rReg_mem??? 11459 // Compare raw pointer (used in out-of-heap check). 11460 // Only works because non-oop pointers must be raw pointers 11461 // and raw pointers have no anti-dependencies. 11462 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11463 %{ 11464 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11465 match(Set cr (CmpP op1 (LoadP op2))); 11466 11467 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11468 opcode(0x3B); /* Opcode 3B /r */ 11469 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11470 ins_pipe(ialu_cr_reg_mem); 11471 %} 11472 11473 // This will generate a signed flags result. This should be OK since 11474 // any compare to a zero should be eq/neq. 11475 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11476 %{ 11477 match(Set cr (CmpP src zero)); 11478 11479 format %{ "testq $src, $src\t# ptr" %} 11480 opcode(0x85); 11481 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11482 ins_pipe(ialu_cr_reg_imm); 11483 %} 11484 11485 // This will generate a signed flags result. This should be OK since 11486 // any compare to a zero should be eq/neq. 11487 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11488 %{ 11489 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11490 match(Set cr (CmpP (LoadP op) zero)); 11491 11492 ins_cost(500); // XXX 11493 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11494 opcode(0xF7); /* Opcode F7 /0 */ 11495 ins_encode(REX_mem_wide(op), 11496 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11497 ins_pipe(ialu_cr_reg_imm); 11498 %} 11499 11500 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11501 %{ 11502 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11503 match(Set cr (CmpP (LoadP mem) zero)); 11504 11505 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11506 ins_encode %{ 11507 __ cmpq(r12, $mem$$Address); 11508 %} 11509 ins_pipe(ialu_cr_reg_mem); 11510 %} 11511 11512 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11513 %{ 11514 match(Set cr (CmpN op1 op2)); 11515 11516 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11517 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11518 ins_pipe(ialu_cr_reg_reg); 11519 %} 11520 11521 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11522 %{ 11523 match(Set cr (CmpN src (LoadN mem))); 11524 11525 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11526 ins_encode %{ 11527 __ cmpl($src$$Register, $mem$$Address); 11528 %} 11529 ins_pipe(ialu_cr_reg_mem); 11530 %} 11531 11532 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11533 match(Set cr (CmpN op1 op2)); 11534 11535 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11536 ins_encode %{ 11537 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11538 %} 11539 ins_pipe(ialu_cr_reg_imm); 11540 %} 11541 11542 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11543 %{ 11544 match(Set cr (CmpN src (LoadN mem))); 11545 11546 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11547 ins_encode %{ 11548 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11549 %} 11550 ins_pipe(ialu_cr_reg_mem); 11551 %} 11552 11553 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11554 match(Set cr (CmpN op1 op2)); 11555 11556 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11557 ins_encode %{ 11558 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11559 %} 11560 ins_pipe(ialu_cr_reg_imm); 11561 %} 11562 11563 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11564 %{ 11565 match(Set cr (CmpN src (LoadNKlass mem))); 11566 11567 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11568 ins_encode %{ 11569 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11570 %} 11571 ins_pipe(ialu_cr_reg_mem); 11572 %} 11573 11574 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11575 match(Set cr (CmpN src zero)); 11576 11577 format %{ "testl $src, $src\t# compressed ptr" %} 11578 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11579 ins_pipe(ialu_cr_reg_imm); 11580 %} 11581 11582 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11583 %{ 11584 predicate(Universe::narrow_oop_base() != NULL); 11585 match(Set cr (CmpN (LoadN mem) zero)); 11586 11587 ins_cost(500); // XXX 11588 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11589 ins_encode %{ 11590 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11591 %} 11592 ins_pipe(ialu_cr_reg_mem); 11593 %} 11594 11595 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11596 %{ 11597 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11598 match(Set cr (CmpN (LoadN mem) zero)); 11599 11600 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11601 ins_encode %{ 11602 __ cmpl(r12, $mem$$Address); 11603 %} 11604 ins_pipe(ialu_cr_reg_mem); 11605 %} 11606 11607 // Yanked all unsigned pointer compare operations. 11608 // Pointer compares are done with CmpP which is already unsigned. 11609 11610 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11611 %{ 11612 match(Set cr (CmpL op1 op2)); 11613 11614 format %{ "cmpq $op1, $op2" %} 11615 opcode(0x3B); /* Opcode 3B /r */ 11616 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11617 ins_pipe(ialu_cr_reg_reg); 11618 %} 11619 11620 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11621 %{ 11622 match(Set cr (CmpL op1 op2)); 11623 11624 format %{ "cmpq $op1, $op2" %} 11625 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11626 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11627 ins_pipe(ialu_cr_reg_imm); 11628 %} 11629 11630 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11631 %{ 11632 match(Set cr (CmpL op1 (LoadL op2))); 11633 11634 format %{ "cmpq $op1, $op2" %} 11635 opcode(0x3B); /* Opcode 3B /r */ 11636 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11637 ins_pipe(ialu_cr_reg_mem); 11638 %} 11639 11640 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11641 %{ 11642 match(Set cr (CmpL src zero)); 11643 11644 format %{ "testq $src, $src" %} 11645 opcode(0x85); 11646 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11647 ins_pipe(ialu_cr_reg_imm); 11648 %} 11649 11650 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11651 %{ 11652 match(Set cr (CmpL (AndL src con) zero)); 11653 11654 format %{ "testq $src, $con\t# long" %} 11655 opcode(0xF7, 0x00); 11656 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11657 ins_pipe(ialu_cr_reg_imm); 11658 %} 11659 11660 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11661 %{ 11662 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11663 11664 format %{ "testq $src, $mem" %} 11665 opcode(0x85); 11666 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11667 ins_pipe(ialu_cr_reg_mem); 11668 %} 11669 11670 // Manifest a CmpL result in an integer register. Very painful. 11671 // This is the test to avoid. 11672 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11673 %{ 11674 match(Set dst (CmpL3 src1 src2)); 11675 effect(KILL flags); 11676 11677 ins_cost(275); // XXX 11678 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11679 "movl $dst, -1\n\t" 11680 "jl,s done\n\t" 11681 "setne $dst\n\t" 11682 "movzbl $dst, $dst\n\t" 11683 "done:" %} 11684 ins_encode(cmpl3_flag(src1, src2, dst)); 11685 ins_pipe(pipe_slow); 11686 %} 11687 11688 //----------Max and Min-------------------------------------------------------- 11689 // Min Instructions 11690 11691 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11692 %{ 11693 effect(USE_DEF dst, USE src, USE cr); 11694 11695 format %{ "cmovlgt $dst, $src\t# min" %} 11696 opcode(0x0F, 0x4F); 11697 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11698 ins_pipe(pipe_cmov_reg); 11699 %} 11700 11701 11702 instruct minI_rReg(rRegI dst, rRegI src) 11703 %{ 11704 match(Set dst (MinI dst src)); 11705 11706 ins_cost(200); 11707 expand %{ 11708 rFlagsReg cr; 11709 compI_rReg(cr, dst, src); 11710 cmovI_reg_g(dst, src, cr); 11711 %} 11712 %} 11713 11714 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11715 %{ 11716 effect(USE_DEF dst, USE src, USE cr); 11717 11718 format %{ "cmovllt $dst, $src\t# max" %} 11719 opcode(0x0F, 0x4C); 11720 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11721 ins_pipe(pipe_cmov_reg); 11722 %} 11723 11724 11725 instruct maxI_rReg(rRegI dst, rRegI src) 11726 %{ 11727 match(Set dst (MaxI dst src)); 11728 11729 ins_cost(200); 11730 expand %{ 11731 rFlagsReg cr; 11732 compI_rReg(cr, dst, src); 11733 cmovI_reg_l(dst, src, cr); 11734 %} 11735 %} 11736 11737 // ============================================================================ 11738 // Branch Instructions 11739 11740 // Jump Direct - Label defines a relative address from JMP+1 11741 instruct jmpDir(label labl) 11742 %{ 11743 match(Goto); 11744 effect(USE labl); 11745 11746 ins_cost(300); 11747 format %{ "jmp $labl" %} 11748 size(5); 11749 ins_encode %{ 11750 Label* L = $labl$$label; 11751 __ jmp(*L, false); // Always long jump 11752 %} 11753 ins_pipe(pipe_jmp); 11754 %} 11755 11756 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11757 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11758 %{ 11759 match(If cop cr); 11760 effect(USE labl); 11761 11762 ins_cost(300); 11763 format %{ "j$cop $labl" %} 11764 size(6); 11765 ins_encode %{ 11766 Label* L = $labl$$label; 11767 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11768 %} 11769 ins_pipe(pipe_jcc); 11770 %} 11771 11772 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11773 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11774 %{ 11775 predicate(!n->has_vector_mask_set()); 11776 match(CountedLoopEnd cop cr); 11777 effect(USE labl); 11778 11779 ins_cost(300); 11780 format %{ "j$cop $labl\t# loop end" %} 11781 size(6); 11782 ins_encode %{ 11783 Label* L = $labl$$label; 11784 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11785 %} 11786 ins_pipe(pipe_jcc); 11787 %} 11788 11789 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11790 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11791 predicate(!n->has_vector_mask_set()); 11792 match(CountedLoopEnd cop cmp); 11793 effect(USE labl); 11794 11795 ins_cost(300); 11796 format %{ "j$cop,u $labl\t# loop end" %} 11797 size(6); 11798 ins_encode %{ 11799 Label* L = $labl$$label; 11800 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11801 %} 11802 ins_pipe(pipe_jcc); 11803 %} 11804 11805 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11806 predicate(!n->has_vector_mask_set()); 11807 match(CountedLoopEnd cop cmp); 11808 effect(USE labl); 11809 11810 ins_cost(200); 11811 format %{ "j$cop,u $labl\t# loop end" %} 11812 size(6); 11813 ins_encode %{ 11814 Label* L = $labl$$label; 11815 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11816 %} 11817 ins_pipe(pipe_jcc); 11818 %} 11819 11820 // mask version 11821 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11822 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 11823 %{ 11824 predicate(n->has_vector_mask_set()); 11825 match(CountedLoopEnd cop cr); 11826 effect(USE labl); 11827 11828 ins_cost(400); 11829 format %{ "j$cop $labl\t# loop end\n\t" 11830 "restorevectmask \t# vector mask restore for loops" %} 11831 size(10); 11832 ins_encode %{ 11833 Label* L = $labl$$label; 11834 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11835 __ restorevectmask(); 11836 %} 11837 ins_pipe(pipe_jcc); 11838 %} 11839 11840 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11841 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11842 predicate(n->has_vector_mask_set()); 11843 match(CountedLoopEnd cop cmp); 11844 effect(USE labl); 11845 11846 ins_cost(400); 11847 format %{ "j$cop,u $labl\t# loop end\n\t" 11848 "restorevectmask \t# vector mask restore for loops" %} 11849 size(10); 11850 ins_encode %{ 11851 Label* L = $labl$$label; 11852 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11853 __ restorevectmask(); 11854 %} 11855 ins_pipe(pipe_jcc); 11856 %} 11857 11858 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11859 predicate(n->has_vector_mask_set()); 11860 match(CountedLoopEnd cop cmp); 11861 effect(USE labl); 11862 11863 ins_cost(300); 11864 format %{ "j$cop,u $labl\t# loop end\n\t" 11865 "restorevectmask \t# vector mask restore for loops" %} 11866 size(10); 11867 ins_encode %{ 11868 Label* L = $labl$$label; 11869 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11870 __ restorevectmask(); 11871 %} 11872 ins_pipe(pipe_jcc); 11873 %} 11874 11875 // Jump Direct Conditional - using unsigned comparison 11876 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11877 match(If cop cmp); 11878 effect(USE labl); 11879 11880 ins_cost(300); 11881 format %{ "j$cop,u $labl" %} 11882 size(6); 11883 ins_encode %{ 11884 Label* L = $labl$$label; 11885 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11886 %} 11887 ins_pipe(pipe_jcc); 11888 %} 11889 11890 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11891 match(If cop cmp); 11892 effect(USE labl); 11893 11894 ins_cost(200); 11895 format %{ "j$cop,u $labl" %} 11896 size(6); 11897 ins_encode %{ 11898 Label* L = $labl$$label; 11899 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11900 %} 11901 ins_pipe(pipe_jcc); 11902 %} 11903 11904 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11905 match(If cop cmp); 11906 effect(USE labl); 11907 11908 ins_cost(200); 11909 format %{ $$template 11910 if ($cop$$cmpcode == Assembler::notEqual) { 11911 $$emit$$"jp,u $labl\n\t" 11912 $$emit$$"j$cop,u $labl" 11913 } else { 11914 $$emit$$"jp,u done\n\t" 11915 $$emit$$"j$cop,u $labl\n\t" 11916 $$emit$$"done:" 11917 } 11918 %} 11919 ins_encode %{ 11920 Label* l = $labl$$label; 11921 if ($cop$$cmpcode == Assembler::notEqual) { 11922 __ jcc(Assembler::parity, *l, false); 11923 __ jcc(Assembler::notEqual, *l, false); 11924 } else if ($cop$$cmpcode == Assembler::equal) { 11925 Label done; 11926 __ jccb(Assembler::parity, done); 11927 __ jcc(Assembler::equal, *l, false); 11928 __ bind(done); 11929 } else { 11930 ShouldNotReachHere(); 11931 } 11932 %} 11933 ins_pipe(pipe_jcc); 11934 %} 11935 11936 // ============================================================================ 11937 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11938 // superklass array for an instance of the superklass. Set a hidden 11939 // internal cache on a hit (cache is checked with exposed code in 11940 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11941 // encoding ALSO sets flags. 11942 11943 instruct partialSubtypeCheck(rdi_RegP result, 11944 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11945 rFlagsReg cr) 11946 %{ 11947 match(Set result (PartialSubtypeCheck sub super)); 11948 effect(KILL rcx, KILL cr); 11949 11950 ins_cost(1100); // slightly larger than the next version 11951 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11952 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11953 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11954 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11955 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11956 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11957 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11958 "miss:\t" %} 11959 11960 opcode(0x1); // Force a XOR of RDI 11961 ins_encode(enc_PartialSubtypeCheck()); 11962 ins_pipe(pipe_slow); 11963 %} 11964 11965 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11966 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11967 immP0 zero, 11968 rdi_RegP result) 11969 %{ 11970 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11971 effect(KILL rcx, KILL result); 11972 11973 ins_cost(1000); 11974 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11975 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11976 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11977 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11978 "jne,s miss\t\t# Missed: flags nz\n\t" 11979 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11980 "miss:\t" %} 11981 11982 opcode(0x0); // No need to XOR RDI 11983 ins_encode(enc_PartialSubtypeCheck()); 11984 ins_pipe(pipe_slow); 11985 %} 11986 11987 // ============================================================================ 11988 // Branch Instructions -- short offset versions 11989 // 11990 // These instructions are used to replace jumps of a long offset (the default 11991 // match) with jumps of a shorter offset. These instructions are all tagged 11992 // with the ins_short_branch attribute, which causes the ADLC to suppress the 11993 // match rules in general matching. Instead, the ADLC generates a conversion 11994 // method in the MachNode which can be used to do in-place replacement of the 11995 // long variant with the shorter variant. The compiler will determine if a 11996 // branch can be taken by the is_short_branch_offset() predicate in the machine 11997 // specific code section of the file. 11998 11999 // Jump Direct - Label defines a relative address from JMP+1 12000 instruct jmpDir_short(label labl) %{ 12001 match(Goto); 12002 effect(USE labl); 12003 12004 ins_cost(300); 12005 format %{ "jmp,s $labl" %} 12006 size(2); 12007 ins_encode %{ 12008 Label* L = $labl$$label; 12009 __ jmpb(*L); 12010 %} 12011 ins_pipe(pipe_jmp); 12012 ins_short_branch(1); 12013 %} 12014 12015 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12016 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12017 match(If cop cr); 12018 effect(USE labl); 12019 12020 ins_cost(300); 12021 format %{ "j$cop,s $labl" %} 12022 size(2); 12023 ins_encode %{ 12024 Label* L = $labl$$label; 12025 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12026 %} 12027 ins_pipe(pipe_jcc); 12028 ins_short_branch(1); 12029 %} 12030 12031 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12032 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12033 match(CountedLoopEnd cop cr); 12034 effect(USE labl); 12035 12036 ins_cost(300); 12037 format %{ "j$cop,s $labl\t# loop end" %} 12038 size(2); 12039 ins_encode %{ 12040 Label* L = $labl$$label; 12041 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12042 %} 12043 ins_pipe(pipe_jcc); 12044 ins_short_branch(1); 12045 %} 12046 12047 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12048 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12049 match(CountedLoopEnd cop cmp); 12050 effect(USE labl); 12051 12052 ins_cost(300); 12053 format %{ "j$cop,us $labl\t# loop end" %} 12054 size(2); 12055 ins_encode %{ 12056 Label* L = $labl$$label; 12057 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12058 %} 12059 ins_pipe(pipe_jcc); 12060 ins_short_branch(1); 12061 %} 12062 12063 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12064 match(CountedLoopEnd cop cmp); 12065 effect(USE labl); 12066 12067 ins_cost(300); 12068 format %{ "j$cop,us $labl\t# loop end" %} 12069 size(2); 12070 ins_encode %{ 12071 Label* L = $labl$$label; 12072 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12073 %} 12074 ins_pipe(pipe_jcc); 12075 ins_short_branch(1); 12076 %} 12077 12078 // Jump Direct Conditional - using unsigned comparison 12079 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12080 match(If cop cmp); 12081 effect(USE labl); 12082 12083 ins_cost(300); 12084 format %{ "j$cop,us $labl" %} 12085 size(2); 12086 ins_encode %{ 12087 Label* L = $labl$$label; 12088 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12089 %} 12090 ins_pipe(pipe_jcc); 12091 ins_short_branch(1); 12092 %} 12093 12094 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12095 match(If cop cmp); 12096 effect(USE labl); 12097 12098 ins_cost(300); 12099 format %{ "j$cop,us $labl" %} 12100 size(2); 12101 ins_encode %{ 12102 Label* L = $labl$$label; 12103 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12104 %} 12105 ins_pipe(pipe_jcc); 12106 ins_short_branch(1); 12107 %} 12108 12109 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12110 match(If cop cmp); 12111 effect(USE labl); 12112 12113 ins_cost(300); 12114 format %{ $$template 12115 if ($cop$$cmpcode == Assembler::notEqual) { 12116 $$emit$$"jp,u,s $labl\n\t" 12117 $$emit$$"j$cop,u,s $labl" 12118 } else { 12119 $$emit$$"jp,u,s done\n\t" 12120 $$emit$$"j$cop,u,s $labl\n\t" 12121 $$emit$$"done:" 12122 } 12123 %} 12124 size(4); 12125 ins_encode %{ 12126 Label* l = $labl$$label; 12127 if ($cop$$cmpcode == Assembler::notEqual) { 12128 __ jccb(Assembler::parity, *l); 12129 __ jccb(Assembler::notEqual, *l); 12130 } else if ($cop$$cmpcode == Assembler::equal) { 12131 Label done; 12132 __ jccb(Assembler::parity, done); 12133 __ jccb(Assembler::equal, *l); 12134 __ bind(done); 12135 } else { 12136 ShouldNotReachHere(); 12137 } 12138 %} 12139 ins_pipe(pipe_jcc); 12140 ins_short_branch(1); 12141 %} 12142 12143 // ============================================================================ 12144 // inlined locking and unlocking 12145 12146 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12147 predicate(Compile::current()->use_rtm()); 12148 match(Set cr (FastLock object box)); 12149 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12150 ins_cost(300); 12151 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12152 ins_encode %{ 12153 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12154 $scr$$Register, $cx1$$Register, $cx2$$Register, 12155 _counters, _rtm_counters, _stack_rtm_counters, 12156 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12157 true, ra_->C->profile_rtm()); 12158 %} 12159 ins_pipe(pipe_slow); 12160 %} 12161 12162 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12163 predicate(!Compile::current()->use_rtm()); 12164 match(Set cr (FastLock object box)); 12165 effect(TEMP tmp, TEMP scr, USE_KILL box); 12166 ins_cost(300); 12167 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12168 ins_encode %{ 12169 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12170 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12171 %} 12172 ins_pipe(pipe_slow); 12173 %} 12174 12175 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12176 match(Set cr (FastUnlock object box)); 12177 effect(TEMP tmp, USE_KILL box); 12178 ins_cost(300); 12179 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12180 ins_encode %{ 12181 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12182 %} 12183 ins_pipe(pipe_slow); 12184 %} 12185 12186 12187 // ============================================================================ 12188 // Safepoint Instructions 12189 instruct safePoint_poll(rFlagsReg cr) 12190 %{ 12191 predicate(!Assembler::is_polling_page_far()); 12192 match(SafePoint); 12193 effect(KILL cr); 12194 12195 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12196 "# Safepoint: poll for GC" %} 12197 ins_cost(125); 12198 ins_encode %{ 12199 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12200 __ testl(rax, addr); 12201 %} 12202 ins_pipe(ialu_reg_mem); 12203 %} 12204 12205 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12206 %{ 12207 predicate(Assembler::is_polling_page_far()); 12208 match(SafePoint poll); 12209 effect(KILL cr, USE poll); 12210 12211 format %{ "testl rax, [$poll]\t" 12212 "# Safepoint: poll for GC" %} 12213 ins_cost(125); 12214 ins_encode %{ 12215 __ relocate(relocInfo::poll_type); 12216 __ testl(rax, Address($poll$$Register, 0)); 12217 %} 12218 ins_pipe(ialu_reg_mem); 12219 %} 12220 12221 // ============================================================================ 12222 // Procedure Call/Return Instructions 12223 // Call Java Static Instruction 12224 // Note: If this code changes, the corresponding ret_addr_offset() and 12225 // compute_padding() functions will have to be adjusted. 12226 instruct CallStaticJavaDirect(method meth) %{ 12227 match(CallStaticJava); 12228 effect(USE meth); 12229 12230 ins_cost(300); 12231 format %{ "call,static " %} 12232 opcode(0xE8); /* E8 cd */ 12233 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12234 ins_pipe(pipe_slow); 12235 ins_alignment(4); 12236 %} 12237 12238 // Call Java Dynamic Instruction 12239 // Note: If this code changes, the corresponding ret_addr_offset() and 12240 // compute_padding() functions will have to be adjusted. 12241 instruct CallDynamicJavaDirect(method meth) 12242 %{ 12243 match(CallDynamicJava); 12244 effect(USE meth); 12245 12246 ins_cost(300); 12247 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12248 "call,dynamic " %} 12249 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12250 ins_pipe(pipe_slow); 12251 ins_alignment(4); 12252 %} 12253 12254 // Call Runtime Instruction 12255 instruct CallRuntimeDirect(method meth) 12256 %{ 12257 match(CallRuntime); 12258 effect(USE meth); 12259 12260 ins_cost(300); 12261 format %{ "call,runtime " %} 12262 ins_encode(clear_avx, Java_To_Runtime(meth)); 12263 ins_pipe(pipe_slow); 12264 %} 12265 12266 // Call runtime without safepoint 12267 instruct CallLeafDirect(method meth) 12268 %{ 12269 match(CallLeaf); 12270 effect(USE meth); 12271 12272 ins_cost(300); 12273 format %{ "call_leaf,runtime " %} 12274 ins_encode(clear_avx, Java_To_Runtime(meth)); 12275 ins_pipe(pipe_slow); 12276 %} 12277 12278 // Call runtime without safepoint 12279 instruct CallLeafNoFPDirect(method meth) 12280 %{ 12281 match(CallLeafNoFP); 12282 effect(USE meth); 12283 12284 ins_cost(300); 12285 format %{ "call_leaf_nofp,runtime " %} 12286 ins_encode(Java_To_Runtime(meth)); 12287 ins_pipe(pipe_slow); 12288 %} 12289 12290 // Return Instruction 12291 // Remove the return address & jump to it. 12292 // Notice: We always emit a nop after a ret to make sure there is room 12293 // for safepoint patching 12294 instruct Ret() 12295 %{ 12296 match(Return); 12297 12298 format %{ "ret" %} 12299 opcode(0xC3); 12300 ins_encode(OpcP); 12301 ins_pipe(pipe_jmp); 12302 %} 12303 12304 // Tail Call; Jump from runtime stub to Java code. 12305 // Also known as an 'interprocedural jump'. 12306 // Target of jump will eventually return to caller. 12307 // TailJump below removes the return address. 12308 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12309 %{ 12310 match(TailCall jump_target method_oop); 12311 12312 ins_cost(300); 12313 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12314 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12315 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12316 ins_pipe(pipe_jmp); 12317 %} 12318 12319 // Tail Jump; remove the return address; jump to target. 12320 // TailCall above leaves the return address around. 12321 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12322 %{ 12323 match(TailJump jump_target ex_oop); 12324 12325 ins_cost(300); 12326 format %{ "popq rdx\t# pop return address\n\t" 12327 "jmp $jump_target" %} 12328 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12329 ins_encode(Opcode(0x5a), // popq rdx 12330 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12331 ins_pipe(pipe_jmp); 12332 %} 12333 12334 // Create exception oop: created by stack-crawling runtime code. 12335 // Created exception is now available to this handler, and is setup 12336 // just prior to jumping to this handler. No code emitted. 12337 instruct CreateException(rax_RegP ex_oop) 12338 %{ 12339 match(Set ex_oop (CreateEx)); 12340 12341 size(0); 12342 // use the following format syntax 12343 format %{ "# exception oop is in rax; no code emitted" %} 12344 ins_encode(); 12345 ins_pipe(empty); 12346 %} 12347 12348 // Rethrow exception: 12349 // The exception oop will come in the first argument position. 12350 // Then JUMP (not call) to the rethrow stub code. 12351 instruct RethrowException() 12352 %{ 12353 match(Rethrow); 12354 12355 // use the following format syntax 12356 format %{ "jmp rethrow_stub" %} 12357 ins_encode(enc_rethrow); 12358 ins_pipe(pipe_jmp); 12359 %} 12360 12361 12362 // ============================================================================ 12363 // This name is KNOWN by the ADLC and cannot be changed. 12364 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12365 // for this guy. 12366 instruct tlsLoadP(r15_RegP dst) %{ 12367 match(Set dst (ThreadLocal)); 12368 effect(DEF dst); 12369 12370 size(0); 12371 format %{ "# TLS is in R15" %} 12372 ins_encode( /*empty encoding*/ ); 12373 ins_pipe(ialu_reg_reg); 12374 %} 12375 12376 12377 //----------PEEPHOLE RULES----------------------------------------------------- 12378 // These must follow all instruction definitions as they use the names 12379 // defined in the instructions definitions. 12380 // 12381 // peepmatch ( root_instr_name [preceding_instruction]* ); 12382 // 12383 // peepconstraint %{ 12384 // (instruction_number.operand_name relational_op instruction_number.operand_name 12385 // [, ...] ); 12386 // // instruction numbers are zero-based using left to right order in peepmatch 12387 // 12388 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12389 // // provide an instruction_number.operand_name for each operand that appears 12390 // // in the replacement instruction's match rule 12391 // 12392 // ---------VM FLAGS--------------------------------------------------------- 12393 // 12394 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12395 // 12396 // Each peephole rule is given an identifying number starting with zero and 12397 // increasing by one in the order seen by the parser. An individual peephole 12398 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12399 // on the command-line. 12400 // 12401 // ---------CURRENT LIMITATIONS---------------------------------------------- 12402 // 12403 // Only match adjacent instructions in same basic block 12404 // Only equality constraints 12405 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12406 // Only one replacement instruction 12407 // 12408 // ---------EXAMPLE---------------------------------------------------------- 12409 // 12410 // // pertinent parts of existing instructions in architecture description 12411 // instruct movI(rRegI dst, rRegI src) 12412 // %{ 12413 // match(Set dst (CopyI src)); 12414 // %} 12415 // 12416 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12417 // %{ 12418 // match(Set dst (AddI dst src)); 12419 // effect(KILL cr); 12420 // %} 12421 // 12422 // // Change (inc mov) to lea 12423 // peephole %{ 12424 // // increment preceeded by register-register move 12425 // peepmatch ( incI_rReg movI ); 12426 // // require that the destination register of the increment 12427 // // match the destination register of the move 12428 // peepconstraint ( 0.dst == 1.dst ); 12429 // // construct a replacement instruction that sets 12430 // // the destination to ( move's source register + one ) 12431 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12432 // %} 12433 // 12434 12435 // Implementation no longer uses movX instructions since 12436 // machine-independent system no longer uses CopyX nodes. 12437 // 12438 // peephole 12439 // %{ 12440 // peepmatch (incI_rReg movI); 12441 // peepconstraint (0.dst == 1.dst); 12442 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12443 // %} 12444 12445 // peephole 12446 // %{ 12447 // peepmatch (decI_rReg movI); 12448 // peepconstraint (0.dst == 1.dst); 12449 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12450 // %} 12451 12452 // peephole 12453 // %{ 12454 // peepmatch (addI_rReg_imm movI); 12455 // peepconstraint (0.dst == 1.dst); 12456 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12457 // %} 12458 12459 // peephole 12460 // %{ 12461 // peepmatch (incL_rReg movL); 12462 // peepconstraint (0.dst == 1.dst); 12463 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12464 // %} 12465 12466 // peephole 12467 // %{ 12468 // peepmatch (decL_rReg movL); 12469 // peepconstraint (0.dst == 1.dst); 12470 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12471 // %} 12472 12473 // peephole 12474 // %{ 12475 // peepmatch (addL_rReg_imm movL); 12476 // peepconstraint (0.dst == 1.dst); 12477 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12478 // %} 12479 12480 // peephole 12481 // %{ 12482 // peepmatch (addP_rReg_imm movP); 12483 // peepconstraint (0.dst == 1.dst); 12484 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12485 // %} 12486 12487 // // Change load of spilled value to only a spill 12488 // instruct storeI(memory mem, rRegI src) 12489 // %{ 12490 // match(Set mem (StoreI mem src)); 12491 // %} 12492 // 12493 // instruct loadI(rRegI dst, memory mem) 12494 // %{ 12495 // match(Set dst (LoadI mem)); 12496 // %} 12497 // 12498 12499 peephole 12500 %{ 12501 peepmatch (loadI storeI); 12502 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12503 peepreplace (storeI(1.mem 1.mem 1.src)); 12504 %} 12505 12506 peephole 12507 %{ 12508 peepmatch (loadL storeL); 12509 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12510 peepreplace (storeL(1.mem 1.mem 1.src)); 12511 %} 12512 12513 //----------SMARTSPILL RULES--------------------------------------------------- 12514 // These must follow all instruction definitions as they use the names 12515 // defined in the instructions definitions.