1 // 2 // Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // Specify priority of register selection within phases of register 135 // allocation. Highest priority is first. A useful heuristic is to 136 // give registers a low priority when they are required by machine 137 // instructions, like EAX and EDX on I486, and choose no-save registers 138 // before save-on-call, & save-on-call before save-on-entry. Registers 139 // which participate in fixed calling sequences should come last. 140 // Registers which are used as pairs must fall on an even boundary. 141 142 alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160 //----------Architecture Description Register Classes-------------------------- 161 // Several register classes are automatically defined based upon information in 162 // this architecture description. 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167 // 168 169 // Empty register class. 170 reg_class no_reg(); 171 172 // Class for all pointer registers (including RSP and RBP) 173 reg_class any_reg_with_rbp(RAX, RAX_H, 174 RDX, RDX_H, 175 RBP, RBP_H, 176 RDI, RDI_H, 177 RSI, RSI_H, 178 RCX, RCX_H, 179 RBX, RBX_H, 180 RSP, RSP_H, 181 R8, R8_H, 182 R9, R9_H, 183 R10, R10_H, 184 R11, R11_H, 185 R12, R12_H, 186 R13, R13_H, 187 R14, R14_H, 188 R15, R15_H); 189 190 // Class for all pointer registers (including RSP, but excluding RBP) 191 reg_class any_reg_no_rbp(RAX, RAX_H, 192 RDX, RDX_H, 193 RDI, RDI_H, 194 RSI, RSI_H, 195 RCX, RCX_H, 196 RBX, RBX_H, 197 RSP, RSP_H, 198 R8, R8_H, 199 R9, R9_H, 200 R10, R10_H, 201 R11, R11_H, 202 R12, R12_H, 203 R13, R13_H, 204 R14, R14_H, 205 R15, R15_H); 206 207 // Dynamic register class that selects at runtime between register classes 208 // any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer). 209 // Equivalent to: return PreserveFramePointer ? any_reg_no_rbp : any_reg_with_rbp; 210 reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %}); 211 212 // Class for all pointer registers (excluding RSP) 213 reg_class ptr_reg_with_rbp(RAX, RAX_H, 214 RDX, RDX_H, 215 RBP, RBP_H, 216 RDI, RDI_H, 217 RSI, RSI_H, 218 RCX, RCX_H, 219 RBX, RBX_H, 220 R8, R8_H, 221 R9, R9_H, 222 R10, R10_H, 223 R11, R11_H, 224 R13, R13_H, 225 R14, R14_H); 226 227 // Class for all pointer registers (excluding RSP and RBP) 228 reg_class ptr_reg_no_rbp(RAX, RAX_H, 229 RDX, RDX_H, 230 RDI, RDI_H, 231 RSI, RSI_H, 232 RCX, RCX_H, 233 RBX, RBX_H, 234 R8, R8_H, 235 R9, R9_H, 236 R10, R10_H, 237 R11, R11_H, 238 R13, R13_H, 239 R14, R14_H); 240 241 // Dynamic register class that selects between ptr_reg_no_rbp and ptr_reg_with_rbp. 242 reg_class_dynamic ptr_reg(ptr_reg_no_rbp, ptr_reg_with_rbp, %{ PreserveFramePointer %}); 243 244 // Class for all pointer registers (excluding RAX and RSP) 245 reg_class ptr_no_rax_reg_with_rbp(RDX, RDX_H, 246 RBP, RBP_H, 247 RDI, RDI_H, 248 RSI, RSI_H, 249 RCX, RCX_H, 250 RBX, RBX_H, 251 R8, R8_H, 252 R9, R9_H, 253 R10, R10_H, 254 R11, R11_H, 255 R13, R13_H, 256 R14, R14_H); 257 258 // Class for all pointer registers (excluding RAX, RSP, and RBP) 259 reg_class ptr_no_rax_reg_no_rbp(RDX, RDX_H, 260 RDI, RDI_H, 261 RSI, RSI_H, 262 RCX, RCX_H, 263 RBX, RBX_H, 264 R8, R8_H, 265 R9, R9_H, 266 R10, R10_H, 267 R11, R11_H, 268 R13, R13_H, 269 R14, R14_H); 270 271 // Dynamic register class that selects between ptr_no_rax_reg_no_rbp and ptr_no_rax_reg_with_rbp. 272 reg_class_dynamic ptr_no_rax_reg(ptr_no_rax_reg_no_rbp, ptr_no_rax_reg_with_rbp, %{ PreserveFramePointer %}); 273 274 // Class for all pointer registers (excluding RAX, RBX, and RSP) 275 reg_class ptr_no_rax_rbx_reg_with_rbp(RDX, RDX_H, 276 RBP, RBP_H, 277 RDI, RDI_H, 278 RSI, RSI_H, 279 RCX, RCX_H, 280 R8, R8_H, 281 R9, R9_H, 282 R10, R10_H, 283 R11, R11_H, 284 R13, R13_H, 285 R14, R14_H); 286 287 // Class for all pointer registers (excluding RAX, RBX, RSP, and RBP) 288 reg_class ptr_no_rax_rbx_reg_no_rbp(RDX, RDX_H, 289 RDI, RDI_H, 290 RSI, RSI_H, 291 RCX, RCX_H, 292 R8, R8_H, 293 R9, R9_H, 294 R10, R10_H, 295 R11, R11_H, 296 R13, R13_H, 297 R14, R14_H); 298 299 // Dynamic register class that selects between ptr_no_rax_rbx_reg_no_rbp and ptr_no_rax_rbx_reg_with_rbp. 300 reg_class_dynamic ptr_no_rax_rbx_reg(ptr_no_rax_rbx_reg_no_rbp, ptr_no_rax_rbx_reg_with_rbp, %{ PreserveFramePointer %}); 301 302 // Singleton class for RAX pointer register 303 reg_class ptr_rax_reg(RAX, RAX_H); 304 305 // Singleton class for RBX pointer register 306 reg_class ptr_rbx_reg(RBX, RBX_H); 307 308 // Singleton class for RSI pointer register 309 reg_class ptr_rsi_reg(RSI, RSI_H); 310 311 // Singleton class for RDI pointer register 312 reg_class ptr_rdi_reg(RDI, RDI_H); 313 314 // Singleton class for stack pointer 315 reg_class ptr_rsp_reg(RSP, RSP_H); 316 317 // Singleton class for TLS pointer 318 reg_class ptr_r15_reg(R15, R15_H); 319 320 // The registers which can be used for 321 // a thread local safepoint poll 322 // * R12 is reserved for heap base 323 // * R13 cannot be encoded for addressing without an offset byte 324 // * R15 is reserved for the JavaThread 325 reg_class ptr_rex_reg(R8, R8_H, 326 R9, R9_H, 327 R10, R10_H, 328 R11, R11_H, 329 R14, R14_H); 330 331 332 // Class for all long registers (excluding RSP) 333 reg_class long_reg_with_rbp(RAX, RAX_H, 334 RDX, RDX_H, 335 RBP, RBP_H, 336 RDI, RDI_H, 337 RSI, RSI_H, 338 RCX, RCX_H, 339 RBX, RBX_H, 340 R8, R8_H, 341 R9, R9_H, 342 R10, R10_H, 343 R11, R11_H, 344 R13, R13_H, 345 R14, R14_H); 346 347 // Class for all long registers (excluding RSP and RBP) 348 reg_class long_reg_no_rbp(RAX, RAX_H, 349 RDX, RDX_H, 350 RDI, RDI_H, 351 RSI, RSI_H, 352 RCX, RCX_H, 353 RBX, RBX_H, 354 R8, R8_H, 355 R9, R9_H, 356 R10, R10_H, 357 R11, R11_H, 358 R13, R13_H, 359 R14, R14_H); 360 361 // Dynamic register class that selects between long_reg_no_rbp and long_reg_with_rbp. 362 reg_class_dynamic long_reg(long_reg_no_rbp, long_reg_with_rbp, %{ PreserveFramePointer %}); 363 364 // Class for all long registers (excluding RAX, RDX and RSP) 365 reg_class long_no_rax_rdx_reg_with_rbp(RBP, RBP_H, 366 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 // Class for all long registers (excluding RAX, RDX, RSP, and RBP) 378 reg_class long_no_rax_rdx_reg_no_rbp(RDI, RDI_H, 379 RSI, RSI_H, 380 RCX, RCX_H, 381 RBX, RBX_H, 382 R8, R8_H, 383 R9, R9_H, 384 R10, R10_H, 385 R11, R11_H, 386 R13, R13_H, 387 R14, R14_H); 388 389 // Dynamic register class that selects between long_no_rax_rdx_reg_no_rbp and long_no_rax_rdx_reg_with_rbp. 390 reg_class_dynamic long_no_rax_rdx_reg(long_no_rax_rdx_reg_no_rbp, long_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 391 392 // Class for all long registers (excluding RCX and RSP) 393 reg_class long_no_rcx_reg_with_rbp(RBP, RBP_H, 394 RDI, RDI_H, 395 RSI, RSI_H, 396 RAX, RAX_H, 397 RDX, RDX_H, 398 RBX, RBX_H, 399 R8, R8_H, 400 R9, R9_H, 401 R10, R10_H, 402 R11, R11_H, 403 R13, R13_H, 404 R14, R14_H); 405 406 // Class for all long registers (excluding RCX, RSP, and RBP) 407 reg_class long_no_rcx_reg_no_rbp(RDI, RDI_H, 408 RSI, RSI_H, 409 RAX, RAX_H, 410 RDX, RDX_H, 411 RBX, RBX_H, 412 R8, R8_H, 413 R9, R9_H, 414 R10, R10_H, 415 R11, R11_H, 416 R13, R13_H, 417 R14, R14_H); 418 419 // Dynamic register class that selects between long_no_rcx_reg_no_rbp and long_no_rcx_reg_with_rbp. 420 reg_class_dynamic long_no_rcx_reg(long_no_rcx_reg_no_rbp, long_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 421 422 // Singleton class for RAX long register 423 reg_class long_rax_reg(RAX, RAX_H); 424 425 // Singleton class for RCX long register 426 reg_class long_rcx_reg(RCX, RCX_H); 427 428 // Singleton class for RDX long register 429 reg_class long_rdx_reg(RDX, RDX_H); 430 431 // Class for all int registers (excluding RSP) 432 reg_class int_reg_with_rbp(RAX, 433 RDX, 434 RBP, 435 RDI, 436 RSI, 437 RCX, 438 RBX, 439 R8, 440 R9, 441 R10, 442 R11, 443 R13, 444 R14); 445 446 // Class for all int registers (excluding RSP and RBP) 447 reg_class int_reg_no_rbp(RAX, 448 RDX, 449 RDI, 450 RSI, 451 RCX, 452 RBX, 453 R8, 454 R9, 455 R10, 456 R11, 457 R13, 458 R14); 459 460 // Dynamic register class that selects between int_reg_no_rbp and int_reg_with_rbp. 461 reg_class_dynamic int_reg(int_reg_no_rbp, int_reg_with_rbp, %{ PreserveFramePointer %}); 462 463 // Class for all int registers (excluding RCX and RSP) 464 reg_class int_no_rcx_reg_with_rbp(RAX, 465 RDX, 466 RBP, 467 RDI, 468 RSI, 469 RBX, 470 R8, 471 R9, 472 R10, 473 R11, 474 R13, 475 R14); 476 477 // Class for all int registers (excluding RCX, RSP, and RBP) 478 reg_class int_no_rcx_reg_no_rbp(RAX, 479 RDX, 480 RDI, 481 RSI, 482 RBX, 483 R8, 484 R9, 485 R10, 486 R11, 487 R13, 488 R14); 489 490 // Dynamic register class that selects between int_no_rcx_reg_no_rbp and int_no_rcx_reg_with_rbp. 491 reg_class_dynamic int_no_rcx_reg(int_no_rcx_reg_no_rbp, int_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 492 493 // Class for all int registers (excluding RAX, RDX, and RSP) 494 reg_class int_no_rax_rdx_reg_with_rbp(RBP, 495 RDI, 496 RSI, 497 RCX, 498 RBX, 499 R8, 500 R9, 501 R10, 502 R11, 503 R13, 504 R14); 505 506 // Class for all int registers (excluding RAX, RDX, RSP, and RBP) 507 reg_class int_no_rax_rdx_reg_no_rbp(RDI, 508 RSI, 509 RCX, 510 RBX, 511 R8, 512 R9, 513 R10, 514 R11, 515 R13, 516 R14); 517 518 // Dynamic register class that selects between int_no_rax_rdx_reg_no_rbp and int_no_rax_rdx_reg_with_rbp. 519 reg_class_dynamic int_no_rax_rdx_reg(int_no_rax_rdx_reg_no_rbp, int_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 520 521 // Singleton class for RAX int register 522 reg_class int_rax_reg(RAX); 523 524 // Singleton class for RBX int register 525 reg_class int_rbx_reg(RBX); 526 527 // Singleton class for RCX int register 528 reg_class int_rcx_reg(RCX); 529 530 // Singleton class for RCX int register 531 reg_class int_rdx_reg(RDX); 532 533 // Singleton class for RCX int register 534 reg_class int_rdi_reg(RDI); 535 536 // Singleton class for instruction pointer 537 // reg_class ip_reg(RIP); 538 539 %} 540 541 source_hpp %{ 542 543 #include "gc/shenandoah/brooksPointer.hpp" 544 545 #if INCLUDE_ZGC 546 #include "gc/z/zBarrierSetAssembler.hpp" 547 #endif 548 %} 549 550 //----------SOURCE BLOCK------------------------------------------------------- 551 // This is a block of C++ code which provides values, functions, and 552 // definitions necessary in the rest of the architecture description 553 source %{ 554 #define RELOC_IMM64 Assembler::imm_operand 555 #define RELOC_DISP32 Assembler::disp32_operand 556 557 #define __ _masm. 558 559 static bool generate_vzeroupper(Compile* C) { 560 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 561 } 562 563 static int clear_avx_size() { 564 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 565 } 566 567 // !!!!! Special hack to get all types of calls to specify the byte offset 568 // from the start of the call to the point where the return address 569 // will point. 570 int MachCallStaticJavaNode::ret_addr_offset() 571 { 572 int offset = 5; // 5 bytes from start of call to where return address points 573 offset += clear_avx_size(); 574 return offset; 575 } 576 577 int MachCallDynamicJavaNode::ret_addr_offset() 578 { 579 int offset = 15; // 15 bytes from start of call to where return address points 580 offset += clear_avx_size(); 581 return offset; 582 } 583 584 int MachCallRuntimeNode::ret_addr_offset() { 585 int offset = 13; // movq r10,#addr; callq (r10) 586 offset += clear_avx_size(); 587 return offset; 588 } 589 590 // Indicate if the safepoint node needs the polling page as an input, 591 // it does if the polling page is more than disp32 away. 592 bool SafePointNode::needs_polling_address_input() 593 { 594 return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far(); 595 } 596 597 // 598 // Compute padding required for nodes which need alignment 599 // 600 601 // The address of the call instruction needs to be 4-byte aligned to 602 // ensure that it does not span a cache line so that it can be patched. 603 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 604 { 605 current_offset += clear_avx_size(); // skip vzeroupper 606 current_offset += 1; // skip call opcode byte 607 return align_up(current_offset, alignment_required()) - current_offset; 608 } 609 610 // The address of the call instruction needs to be 4-byte aligned to 611 // ensure that it does not span a cache line so that it can be patched. 612 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 613 { 614 current_offset += clear_avx_size(); // skip vzeroupper 615 current_offset += 11; // skip movq instruction + call opcode byte 616 return align_up(current_offset, alignment_required()) - current_offset; 617 } 618 619 // EMIT_RM() 620 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 621 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 622 cbuf.insts()->emit_int8(c); 623 } 624 625 // EMIT_CC() 626 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 627 unsigned char c = (unsigned char) (f1 | f2); 628 cbuf.insts()->emit_int8(c); 629 } 630 631 // EMIT_OPCODE() 632 void emit_opcode(CodeBuffer &cbuf, int code) { 633 cbuf.insts()->emit_int8((unsigned char) code); 634 } 635 636 // EMIT_OPCODE() w/ relocation information 637 void emit_opcode(CodeBuffer &cbuf, 638 int code, relocInfo::relocType reloc, int offset, int format) 639 { 640 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 641 emit_opcode(cbuf, code); 642 } 643 644 // EMIT_D8() 645 void emit_d8(CodeBuffer &cbuf, int d8) { 646 cbuf.insts()->emit_int8((unsigned char) d8); 647 } 648 649 // EMIT_D16() 650 void emit_d16(CodeBuffer &cbuf, int d16) { 651 cbuf.insts()->emit_int16(d16); 652 } 653 654 // EMIT_D32() 655 void emit_d32(CodeBuffer &cbuf, int d32) { 656 cbuf.insts()->emit_int32(d32); 657 } 658 659 // EMIT_D64() 660 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 661 cbuf.insts()->emit_int64(d64); 662 } 663 664 // emit 32 bit value and construct relocation entry from relocInfo::relocType 665 void emit_d32_reloc(CodeBuffer& cbuf, 666 int d32, 667 relocInfo::relocType reloc, 668 int format) 669 { 670 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 671 cbuf.relocate(cbuf.insts_mark(), reloc, format); 672 cbuf.insts()->emit_int32(d32); 673 } 674 675 // emit 32 bit value and construct relocation entry from RelocationHolder 676 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 677 #ifdef ASSERT 678 if (rspec.reloc()->type() == relocInfo::oop_type && 679 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 680 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 681 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop((intptr_t)d32))), "cannot embed scavengable oops in code"); 682 } 683 #endif 684 cbuf.relocate(cbuf.insts_mark(), rspec, format); 685 cbuf.insts()->emit_int32(d32); 686 } 687 688 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 689 address next_ip = cbuf.insts_end() + 4; 690 emit_d32_reloc(cbuf, (int) (addr - next_ip), 691 external_word_Relocation::spec(addr), 692 RELOC_DISP32); 693 } 694 695 696 // emit 64 bit value and construct relocation entry from relocInfo::relocType 697 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 698 cbuf.relocate(cbuf.insts_mark(), reloc, format); 699 cbuf.insts()->emit_int64(d64); 700 } 701 702 // emit 64 bit value and construct relocation entry from RelocationHolder 703 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 704 #ifdef ASSERT 705 if (rspec.reloc()->type() == relocInfo::oop_type && 706 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 707 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 708 assert(oopDesc::is_oop(cast_to_oop(d64)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop(d64))), 709 "cannot embed scavengable oops in code"); 710 } 711 #endif 712 cbuf.relocate(cbuf.insts_mark(), rspec, format); 713 cbuf.insts()->emit_int64(d64); 714 } 715 716 // Access stack slot for load or store 717 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 718 { 719 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 720 if (-0x80 <= disp && disp < 0x80) { 721 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 722 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 723 emit_d8(cbuf, disp); // Displacement // R/M byte 724 } else { 725 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 726 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 727 emit_d32(cbuf, disp); // Displacement // R/M byte 728 } 729 } 730 731 // rRegI ereg, memory mem) %{ // emit_reg_mem 732 void encode_RegMem(CodeBuffer &cbuf, 733 int reg, 734 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 735 { 736 assert(disp_reloc == relocInfo::none, "cannot have disp"); 737 int regenc = reg & 7; 738 int baseenc = base & 7; 739 int indexenc = index & 7; 740 741 // There is no index & no scale, use form without SIB byte 742 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 743 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 744 if (disp == 0 && base != RBP_enc && base != R13_enc) { 745 emit_rm(cbuf, 0x0, regenc, baseenc); // * 746 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 747 // If 8-bit displacement, mode 0x1 748 emit_rm(cbuf, 0x1, regenc, baseenc); // * 749 emit_d8(cbuf, disp); 750 } else { 751 // If 32-bit displacement 752 if (base == -1) { // Special flag for absolute address 753 emit_rm(cbuf, 0x0, regenc, 0x5); // * 754 if (disp_reloc != relocInfo::none) { 755 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 756 } else { 757 emit_d32(cbuf, disp); 758 } 759 } else { 760 // Normal base + offset 761 emit_rm(cbuf, 0x2, regenc, baseenc); // * 762 if (disp_reloc != relocInfo::none) { 763 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 764 } else { 765 emit_d32(cbuf, disp); 766 } 767 } 768 } 769 } else { 770 // Else, encode with the SIB byte 771 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 772 if (disp == 0 && base != RBP_enc && base != R13_enc) { 773 // If no displacement 774 emit_rm(cbuf, 0x0, regenc, 0x4); // * 775 emit_rm(cbuf, scale, indexenc, baseenc); 776 } else { 777 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 778 // If 8-bit displacement, mode 0x1 779 emit_rm(cbuf, 0x1, regenc, 0x4); // * 780 emit_rm(cbuf, scale, indexenc, baseenc); 781 emit_d8(cbuf, disp); 782 } else { 783 // If 32-bit displacement 784 if (base == 0x04 ) { 785 emit_rm(cbuf, 0x2, regenc, 0x4); 786 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 787 } else { 788 emit_rm(cbuf, 0x2, regenc, 0x4); 789 emit_rm(cbuf, scale, indexenc, baseenc); // * 790 } 791 if (disp_reloc != relocInfo::none) { 792 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 793 } else { 794 emit_d32(cbuf, disp); 795 } 796 } 797 } 798 } 799 } 800 801 // This could be in MacroAssembler but it's fairly C2 specific 802 void emit_cmpfp_fixup(MacroAssembler& _masm) { 803 Label exit; 804 __ jccb(Assembler::noParity, exit); 805 __ pushf(); 806 // 807 // comiss/ucomiss instructions set ZF,PF,CF flags and 808 // zero OF,AF,SF for NaN values. 809 // Fixup flags by zeroing ZF,PF so that compare of NaN 810 // values returns 'less than' result (CF is set). 811 // Leave the rest of flags unchanged. 812 // 813 // 7 6 5 4 3 2 1 0 814 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 815 // 0 0 1 0 1 0 1 1 (0x2B) 816 // 817 __ andq(Address(rsp, 0), 0xffffff2b); 818 __ popf(); 819 __ bind(exit); 820 } 821 822 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 823 Label done; 824 __ movl(dst, -1); 825 __ jcc(Assembler::parity, done); 826 __ jcc(Assembler::below, done); 827 __ setb(Assembler::notEqual, dst); 828 __ movzbl(dst, dst); 829 __ bind(done); 830 } 831 832 833 //============================================================================= 834 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 835 836 int Compile::ConstantTable::calculate_table_base_offset() const { 837 return 0; // absolute addressing, no offset 838 } 839 840 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 841 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 842 ShouldNotReachHere(); 843 } 844 845 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 846 // Empty encoding 847 } 848 849 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 850 return 0; 851 } 852 853 #ifndef PRODUCT 854 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 855 st->print("# MachConstantBaseNode (empty encoding)"); 856 } 857 #endif 858 859 860 //============================================================================= 861 #ifndef PRODUCT 862 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 863 Compile* C = ra_->C; 864 865 int framesize = C->frame_size_in_bytes(); 866 int bangsize = C->bang_size_in_bytes(); 867 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 868 // Remove wordSize for return addr which is already pushed. 869 framesize -= wordSize; 870 871 if (C->need_stack_bang(bangsize)) { 872 framesize -= wordSize; 873 st->print("# stack bang (%d bytes)", bangsize); 874 st->print("\n\t"); 875 st->print("pushq rbp\t# Save rbp"); 876 if (PreserveFramePointer) { 877 st->print("\n\t"); 878 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 879 } 880 if (framesize) { 881 st->print("\n\t"); 882 st->print("subq rsp, #%d\t# Create frame",framesize); 883 } 884 } else { 885 st->print("subq rsp, #%d\t# Create frame",framesize); 886 st->print("\n\t"); 887 framesize -= wordSize; 888 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 889 if (PreserveFramePointer) { 890 st->print("\n\t"); 891 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 892 if (framesize > 0) { 893 st->print("\n\t"); 894 st->print("addq rbp, #%d", framesize); 895 } 896 } 897 } 898 899 if (VerifyStackAtCalls) { 900 st->print("\n\t"); 901 framesize -= wordSize; 902 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 903 #ifdef ASSERT 904 st->print("\n\t"); 905 st->print("# stack alignment check"); 906 #endif 907 } 908 st->cr(); 909 } 910 #endif 911 912 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 913 Compile* C = ra_->C; 914 MacroAssembler _masm(&cbuf); 915 916 int framesize = C->frame_size_in_bytes(); 917 int bangsize = C->bang_size_in_bytes(); 918 919 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); 920 921 C->set_frame_complete(cbuf.insts_size()); 922 923 if (C->has_mach_constant_base_node()) { 924 // NOTE: We set the table base offset here because users might be 925 // emitted before MachConstantBaseNode. 926 Compile::ConstantTable& constant_table = C->constant_table(); 927 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 928 } 929 } 930 931 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 932 { 933 return MachNode::size(ra_); // too many variables; just compute it 934 // the hard way 935 } 936 937 int MachPrologNode::reloc() const 938 { 939 return 0; // a large enough number 940 } 941 942 //============================================================================= 943 #ifndef PRODUCT 944 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 945 { 946 Compile* C = ra_->C; 947 if (generate_vzeroupper(C)) { 948 st->print("vzeroupper"); 949 st->cr(); st->print("\t"); 950 } 951 952 int framesize = C->frame_size_in_bytes(); 953 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 954 // Remove word for return adr already pushed 955 // and RBP 956 framesize -= 2*wordSize; 957 958 if (framesize) { 959 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 960 st->print("\t"); 961 } 962 963 st->print_cr("popq rbp"); 964 if (do_polling() && C->is_method_compilation()) { 965 st->print("\t"); 966 if (SafepointMechanism::uses_thread_local_poll()) { 967 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 968 "testl rax, [rscratch1]\t" 969 "# Safepoint: poll for GC"); 970 } else if (Assembler::is_polling_page_far()) { 971 st->print_cr("movq rscratch1, #polling_page_address\n\t" 972 "testl rax, [rscratch1]\t" 973 "# Safepoint: poll for GC"); 974 } else { 975 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 976 "# Safepoint: poll for GC"); 977 } 978 } 979 } 980 #endif 981 982 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 983 { 984 Compile* C = ra_->C; 985 MacroAssembler _masm(&cbuf); 986 987 if (generate_vzeroupper(C)) { 988 // Clear upper bits of YMM registers when current compiled code uses 989 // wide vectors to avoid AVX <-> SSE transition penalty during call. 990 __ vzeroupper(); 991 } 992 993 int framesize = C->frame_size_in_bytes(); 994 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 995 // Remove word for return adr already pushed 996 // and RBP 997 framesize -= 2*wordSize; 998 999 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 1000 1001 if (framesize) { 1002 emit_opcode(cbuf, Assembler::REX_W); 1003 if (framesize < 0x80) { 1004 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 1005 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1006 emit_d8(cbuf, framesize); 1007 } else { 1008 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 1009 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1010 emit_d32(cbuf, framesize); 1011 } 1012 } 1013 1014 // popq rbp 1015 emit_opcode(cbuf, 0x58 | RBP_enc); 1016 1017 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1018 __ reserved_stack_check(); 1019 } 1020 1021 if (do_polling() && C->is_method_compilation()) { 1022 MacroAssembler _masm(&cbuf); 1023 if (SafepointMechanism::uses_thread_local_poll()) { 1024 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 1025 __ relocate(relocInfo::poll_return_type); 1026 __ testl(rax, Address(rscratch1, 0)); 1027 } else { 1028 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1029 if (Assembler::is_polling_page_far()) { 1030 __ lea(rscratch1, polling_page); 1031 __ relocate(relocInfo::poll_return_type); 1032 __ testl(rax, Address(rscratch1, 0)); 1033 } else { 1034 __ testl(rax, polling_page); 1035 } 1036 } 1037 } 1038 } 1039 1040 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1041 { 1042 return MachNode::size(ra_); // too many variables; just compute it 1043 // the hard way 1044 } 1045 1046 int MachEpilogNode::reloc() const 1047 { 1048 return 2; // a large enough number 1049 } 1050 1051 const Pipeline* MachEpilogNode::pipeline() const 1052 { 1053 return MachNode::pipeline_class(); 1054 } 1055 1056 int MachEpilogNode::safepoint_offset() const 1057 { 1058 return 0; 1059 } 1060 1061 //============================================================================= 1062 1063 enum RC { 1064 rc_bad, 1065 rc_int, 1066 rc_float, 1067 rc_stack 1068 }; 1069 1070 static enum RC rc_class(OptoReg::Name reg) 1071 { 1072 if( !OptoReg::is_valid(reg) ) return rc_bad; 1073 1074 if (OptoReg::is_stack(reg)) return rc_stack; 1075 1076 VMReg r = OptoReg::as_VMReg(reg); 1077 1078 if (r->is_Register()) return rc_int; 1079 1080 assert(r->is_XMMRegister(), "must be"); 1081 return rc_float; 1082 } 1083 1084 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1085 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1086 int src_hi, int dst_hi, uint ireg, outputStream* st); 1087 1088 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1089 int stack_offset, int reg, uint ireg, outputStream* st); 1090 1091 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1092 int dst_offset, uint ireg, outputStream* st) { 1093 if (cbuf) { 1094 MacroAssembler _masm(cbuf); 1095 switch (ireg) { 1096 case Op_VecS: 1097 __ movq(Address(rsp, -8), rax); 1098 __ movl(rax, Address(rsp, src_offset)); 1099 __ movl(Address(rsp, dst_offset), rax); 1100 __ movq(rax, Address(rsp, -8)); 1101 break; 1102 case Op_VecD: 1103 __ pushq(Address(rsp, src_offset)); 1104 __ popq (Address(rsp, dst_offset)); 1105 break; 1106 case Op_VecX: 1107 __ pushq(Address(rsp, src_offset)); 1108 __ popq (Address(rsp, dst_offset)); 1109 __ pushq(Address(rsp, src_offset+8)); 1110 __ popq (Address(rsp, dst_offset+8)); 1111 break; 1112 case Op_VecY: 1113 __ vmovdqu(Address(rsp, -32), xmm0); 1114 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1115 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1116 __ vmovdqu(xmm0, Address(rsp, -32)); 1117 break; 1118 case Op_VecZ: 1119 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1120 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1121 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1122 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1123 break; 1124 default: 1125 ShouldNotReachHere(); 1126 } 1127 #ifndef PRODUCT 1128 } else { 1129 switch (ireg) { 1130 case Op_VecS: 1131 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1132 "movl rax, [rsp + #%d]\n\t" 1133 "movl [rsp + #%d], rax\n\t" 1134 "movq rax, [rsp - #8]", 1135 src_offset, dst_offset); 1136 break; 1137 case Op_VecD: 1138 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1139 "popq [rsp + #%d]", 1140 src_offset, dst_offset); 1141 break; 1142 case Op_VecX: 1143 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1144 "popq [rsp + #%d]\n\t" 1145 "pushq [rsp + #%d]\n\t" 1146 "popq [rsp + #%d]", 1147 src_offset, dst_offset, src_offset+8, dst_offset+8); 1148 break; 1149 case Op_VecY: 1150 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1151 "vmovdqu xmm0, [rsp + #%d]\n\t" 1152 "vmovdqu [rsp + #%d], xmm0\n\t" 1153 "vmovdqu xmm0, [rsp - #32]", 1154 src_offset, dst_offset); 1155 break; 1156 case Op_VecZ: 1157 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1158 "vmovdqu xmm0, [rsp + #%d]\n\t" 1159 "vmovdqu [rsp + #%d], xmm0\n\t" 1160 "vmovdqu xmm0, [rsp - #64]", 1161 src_offset, dst_offset); 1162 break; 1163 default: 1164 ShouldNotReachHere(); 1165 } 1166 #endif 1167 } 1168 } 1169 1170 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1171 PhaseRegAlloc* ra_, 1172 bool do_size, 1173 outputStream* st) const { 1174 assert(cbuf != NULL || st != NULL, "sanity"); 1175 // Get registers to move 1176 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1177 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1178 OptoReg::Name dst_second = ra_->get_reg_second(this); 1179 OptoReg::Name dst_first = ra_->get_reg_first(this); 1180 1181 enum RC src_second_rc = rc_class(src_second); 1182 enum RC src_first_rc = rc_class(src_first); 1183 enum RC dst_second_rc = rc_class(dst_second); 1184 enum RC dst_first_rc = rc_class(dst_first); 1185 1186 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1187 "must move at least 1 register" ); 1188 1189 if (src_first == dst_first && src_second == dst_second) { 1190 // Self copy, no move 1191 return 0; 1192 } 1193 if (bottom_type()->isa_vect() != NULL) { 1194 uint ireg = ideal_reg(); 1195 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1196 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1197 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1198 // mem -> mem 1199 int src_offset = ra_->reg2offset(src_first); 1200 int dst_offset = ra_->reg2offset(dst_first); 1201 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1202 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1203 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1204 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1205 int stack_offset = ra_->reg2offset(dst_first); 1206 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1207 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1208 int stack_offset = ra_->reg2offset(src_first); 1209 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1210 } else { 1211 ShouldNotReachHere(); 1212 } 1213 return 0; 1214 } 1215 if (src_first_rc == rc_stack) { 1216 // mem -> 1217 if (dst_first_rc == rc_stack) { 1218 // mem -> mem 1219 assert(src_second != dst_first, "overlap"); 1220 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1221 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1222 // 64-bit 1223 int src_offset = ra_->reg2offset(src_first); 1224 int dst_offset = ra_->reg2offset(dst_first); 1225 if (cbuf) { 1226 MacroAssembler _masm(cbuf); 1227 __ pushq(Address(rsp, src_offset)); 1228 __ popq (Address(rsp, dst_offset)); 1229 #ifndef PRODUCT 1230 } else { 1231 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1232 "popq [rsp + #%d]", 1233 src_offset, dst_offset); 1234 #endif 1235 } 1236 } else { 1237 // 32-bit 1238 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1239 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1240 // No pushl/popl, so: 1241 int src_offset = ra_->reg2offset(src_first); 1242 int dst_offset = ra_->reg2offset(dst_first); 1243 if (cbuf) { 1244 MacroAssembler _masm(cbuf); 1245 __ movq(Address(rsp, -8), rax); 1246 __ movl(rax, Address(rsp, src_offset)); 1247 __ movl(Address(rsp, dst_offset), rax); 1248 __ movq(rax, Address(rsp, -8)); 1249 #ifndef PRODUCT 1250 } else { 1251 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1252 "movl rax, [rsp + #%d]\n\t" 1253 "movl [rsp + #%d], rax\n\t" 1254 "movq rax, [rsp - #8]", 1255 src_offset, dst_offset); 1256 #endif 1257 } 1258 } 1259 return 0; 1260 } else if (dst_first_rc == rc_int) { 1261 // mem -> gpr 1262 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1263 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1264 // 64-bit 1265 int offset = ra_->reg2offset(src_first); 1266 if (cbuf) { 1267 MacroAssembler _masm(cbuf); 1268 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1269 #ifndef PRODUCT 1270 } else { 1271 st->print("movq %s, [rsp + #%d]\t# spill", 1272 Matcher::regName[dst_first], 1273 offset); 1274 #endif 1275 } 1276 } else { 1277 // 32-bit 1278 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1279 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1280 int offset = ra_->reg2offset(src_first); 1281 if (cbuf) { 1282 MacroAssembler _masm(cbuf); 1283 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1284 #ifndef PRODUCT 1285 } else { 1286 st->print("movl %s, [rsp + #%d]\t# spill", 1287 Matcher::regName[dst_first], 1288 offset); 1289 #endif 1290 } 1291 } 1292 return 0; 1293 } else if (dst_first_rc == rc_float) { 1294 // mem-> xmm 1295 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1296 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1297 // 64-bit 1298 int offset = ra_->reg2offset(src_first); 1299 if (cbuf) { 1300 MacroAssembler _masm(cbuf); 1301 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1302 #ifndef PRODUCT 1303 } else { 1304 st->print("%s %s, [rsp + #%d]\t# spill", 1305 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1306 Matcher::regName[dst_first], 1307 offset); 1308 #endif 1309 } 1310 } else { 1311 // 32-bit 1312 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1313 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1314 int offset = ra_->reg2offset(src_first); 1315 if (cbuf) { 1316 MacroAssembler _masm(cbuf); 1317 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1318 #ifndef PRODUCT 1319 } else { 1320 st->print("movss %s, [rsp + #%d]\t# spill", 1321 Matcher::regName[dst_first], 1322 offset); 1323 #endif 1324 } 1325 } 1326 return 0; 1327 } 1328 } else if (src_first_rc == rc_int) { 1329 // gpr -> 1330 if (dst_first_rc == rc_stack) { 1331 // gpr -> mem 1332 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1333 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1334 // 64-bit 1335 int offset = ra_->reg2offset(dst_first); 1336 if (cbuf) { 1337 MacroAssembler _masm(cbuf); 1338 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1339 #ifndef PRODUCT 1340 } else { 1341 st->print("movq [rsp + #%d], %s\t# spill", 1342 offset, 1343 Matcher::regName[src_first]); 1344 #endif 1345 } 1346 } else { 1347 // 32-bit 1348 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1349 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1350 int offset = ra_->reg2offset(dst_first); 1351 if (cbuf) { 1352 MacroAssembler _masm(cbuf); 1353 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1354 #ifndef PRODUCT 1355 } else { 1356 st->print("movl [rsp + #%d], %s\t# spill", 1357 offset, 1358 Matcher::regName[src_first]); 1359 #endif 1360 } 1361 } 1362 return 0; 1363 } else if (dst_first_rc == rc_int) { 1364 // gpr -> gpr 1365 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1366 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1367 // 64-bit 1368 if (cbuf) { 1369 MacroAssembler _masm(cbuf); 1370 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1371 as_Register(Matcher::_regEncode[src_first])); 1372 #ifndef PRODUCT 1373 } else { 1374 st->print("movq %s, %s\t# spill", 1375 Matcher::regName[dst_first], 1376 Matcher::regName[src_first]); 1377 #endif 1378 } 1379 return 0; 1380 } else { 1381 // 32-bit 1382 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1383 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1384 if (cbuf) { 1385 MacroAssembler _masm(cbuf); 1386 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1387 as_Register(Matcher::_regEncode[src_first])); 1388 #ifndef PRODUCT 1389 } else { 1390 st->print("movl %s, %s\t# spill", 1391 Matcher::regName[dst_first], 1392 Matcher::regName[src_first]); 1393 #endif 1394 } 1395 return 0; 1396 } 1397 } else if (dst_first_rc == rc_float) { 1398 // gpr -> xmm 1399 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1400 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1401 // 64-bit 1402 if (cbuf) { 1403 MacroAssembler _masm(cbuf); 1404 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1405 #ifndef PRODUCT 1406 } else { 1407 st->print("movdq %s, %s\t# spill", 1408 Matcher::regName[dst_first], 1409 Matcher::regName[src_first]); 1410 #endif 1411 } 1412 } else { 1413 // 32-bit 1414 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1415 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1416 if (cbuf) { 1417 MacroAssembler _masm(cbuf); 1418 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1419 #ifndef PRODUCT 1420 } else { 1421 st->print("movdl %s, %s\t# spill", 1422 Matcher::regName[dst_first], 1423 Matcher::regName[src_first]); 1424 #endif 1425 } 1426 } 1427 return 0; 1428 } 1429 } else if (src_first_rc == rc_float) { 1430 // xmm -> 1431 if (dst_first_rc == rc_stack) { 1432 // xmm -> mem 1433 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1434 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1435 // 64-bit 1436 int offset = ra_->reg2offset(dst_first); 1437 if (cbuf) { 1438 MacroAssembler _masm(cbuf); 1439 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1440 #ifndef PRODUCT 1441 } else { 1442 st->print("movsd [rsp + #%d], %s\t# spill", 1443 offset, 1444 Matcher::regName[src_first]); 1445 #endif 1446 } 1447 } else { 1448 // 32-bit 1449 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1450 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1451 int offset = ra_->reg2offset(dst_first); 1452 if (cbuf) { 1453 MacroAssembler _masm(cbuf); 1454 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1455 #ifndef PRODUCT 1456 } else { 1457 st->print("movss [rsp + #%d], %s\t# spill", 1458 offset, 1459 Matcher::regName[src_first]); 1460 #endif 1461 } 1462 } 1463 return 0; 1464 } else if (dst_first_rc == rc_int) { 1465 // xmm -> gpr 1466 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1467 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1468 // 64-bit 1469 if (cbuf) { 1470 MacroAssembler _masm(cbuf); 1471 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1472 #ifndef PRODUCT 1473 } else { 1474 st->print("movdq %s, %s\t# spill", 1475 Matcher::regName[dst_first], 1476 Matcher::regName[src_first]); 1477 #endif 1478 } 1479 } else { 1480 // 32-bit 1481 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1482 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1483 if (cbuf) { 1484 MacroAssembler _masm(cbuf); 1485 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1486 #ifndef PRODUCT 1487 } else { 1488 st->print("movdl %s, %s\t# spill", 1489 Matcher::regName[dst_first], 1490 Matcher::regName[src_first]); 1491 #endif 1492 } 1493 } 1494 return 0; 1495 } else if (dst_first_rc == rc_float) { 1496 // xmm -> xmm 1497 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1498 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1499 // 64-bit 1500 if (cbuf) { 1501 MacroAssembler _masm(cbuf); 1502 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1503 #ifndef PRODUCT 1504 } else { 1505 st->print("%s %s, %s\t# spill", 1506 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1507 Matcher::regName[dst_first], 1508 Matcher::regName[src_first]); 1509 #endif 1510 } 1511 } else { 1512 // 32-bit 1513 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1514 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1515 if (cbuf) { 1516 MacroAssembler _masm(cbuf); 1517 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1518 #ifndef PRODUCT 1519 } else { 1520 st->print("%s %s, %s\t# spill", 1521 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1522 Matcher::regName[dst_first], 1523 Matcher::regName[src_first]); 1524 #endif 1525 } 1526 } 1527 return 0; 1528 } 1529 } 1530 1531 assert(0," foo "); 1532 Unimplemented(); 1533 return 0; 1534 } 1535 1536 #ifndef PRODUCT 1537 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1538 implementation(NULL, ra_, false, st); 1539 } 1540 #endif 1541 1542 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1543 implementation(&cbuf, ra_, false, NULL); 1544 } 1545 1546 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1547 return MachNode::size(ra_); 1548 } 1549 1550 //============================================================================= 1551 #ifndef PRODUCT 1552 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1553 { 1554 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1555 int reg = ra_->get_reg_first(this); 1556 st->print("leaq %s, [rsp + #%d]\t# box lock", 1557 Matcher::regName[reg], offset); 1558 } 1559 #endif 1560 1561 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1562 { 1563 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1564 int reg = ra_->get_encode(this); 1565 if (offset >= 0x80) { 1566 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1567 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1568 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1569 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1570 emit_d32(cbuf, offset); 1571 } else { 1572 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1573 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1574 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1575 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1576 emit_d8(cbuf, offset); 1577 } 1578 } 1579 1580 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1581 { 1582 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1583 return (offset < 0x80) ? 5 : 8; // REX 1584 } 1585 1586 //============================================================================= 1587 #ifndef PRODUCT 1588 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1589 { 1590 if (UseCompressedClassPointers) { 1591 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1592 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1593 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1594 } else { 1595 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1596 "# Inline cache check"); 1597 } 1598 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1599 st->print_cr("\tnop\t# nops to align entry point"); 1600 } 1601 #endif 1602 1603 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1604 { 1605 MacroAssembler masm(&cbuf); 1606 uint insts_size = cbuf.insts_size(); 1607 if (UseCompressedClassPointers) { 1608 masm.load_klass(rscratch1, j_rarg0); 1609 masm.cmpptr(rax, rscratch1); 1610 } else { 1611 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1612 } 1613 1614 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1615 1616 /* WARNING these NOPs are critical so that verified entry point is properly 1617 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1618 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1619 if (OptoBreakpoint) { 1620 // Leave space for int3 1621 nops_cnt -= 1; 1622 } 1623 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1624 if (nops_cnt > 0) 1625 masm.nop(nops_cnt); 1626 } 1627 1628 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1629 { 1630 return MachNode::size(ra_); // too many variables; just compute it 1631 // the hard way 1632 } 1633 1634 1635 //============================================================================= 1636 1637 int Matcher::regnum_to_fpu_offset(int regnum) 1638 { 1639 return regnum - 32; // The FP registers are in the second chunk 1640 } 1641 1642 // This is UltraSparc specific, true just means we have fast l2f conversion 1643 const bool Matcher::convL2FSupported(void) { 1644 return true; 1645 } 1646 1647 // Is this branch offset short enough that a short branch can be used? 1648 // 1649 // NOTE: If the platform does not provide any short branch variants, then 1650 // this method should return false for offset 0. 1651 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1652 // The passed offset is relative to address of the branch. 1653 // On 86 a branch displacement is calculated relative to address 1654 // of a next instruction. 1655 offset -= br_size; 1656 1657 // the short version of jmpConUCF2 contains multiple branches, 1658 // making the reach slightly less 1659 if (rule == jmpConUCF2_rule) 1660 return (-126 <= offset && offset <= 125); 1661 return (-128 <= offset && offset <= 127); 1662 } 1663 1664 const bool Matcher::isSimpleConstant64(jlong value) { 1665 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1666 //return value == (int) value; // Cf. storeImmL and immL32. 1667 1668 // Probably always true, even if a temp register is required. 1669 return true; 1670 } 1671 1672 // The ecx parameter to rep stosq for the ClearArray node is in words. 1673 const bool Matcher::init_array_count_is_in_bytes = false; 1674 1675 // No additional cost for CMOVL. 1676 const int Matcher::long_cmove_cost() { return 0; } 1677 1678 // No CMOVF/CMOVD with SSE2 1679 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1680 1681 // Does the CPU require late expand (see block.cpp for description of late expand)? 1682 const bool Matcher::require_postalloc_expand = false; 1683 1684 // Do we need to mask the count passed to shift instructions or does 1685 // the cpu only look at the lower 5/6 bits anyway? 1686 const bool Matcher::need_masked_shift_count = false; 1687 1688 bool Matcher::narrow_oop_use_complex_address() { 1689 assert(UseCompressedOops, "only for compressed oops code"); 1690 return (LogMinObjAlignmentInBytes <= 3); 1691 } 1692 1693 bool Matcher::narrow_klass_use_complex_address() { 1694 assert(UseCompressedClassPointers, "only for compressed klass code"); 1695 return (LogKlassAlignmentInBytes <= 3); 1696 } 1697 1698 bool Matcher::const_oop_prefer_decode() { 1699 // Prefer ConN+DecodeN over ConP. 1700 return true; 1701 } 1702 1703 bool Matcher::const_klass_prefer_decode() { 1704 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1705 // or condisider the following: 1706 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1707 //return Universe::narrow_klass_base() == NULL; 1708 return true; 1709 } 1710 1711 // Is it better to copy float constants, or load them directly from 1712 // memory? Intel can load a float constant from a direct address, 1713 // requiring no extra registers. Most RISCs will have to materialize 1714 // an address into a register first, so they would do better to copy 1715 // the constant from stack. 1716 const bool Matcher::rematerialize_float_constants = true; // XXX 1717 1718 // If CPU can load and store mis-aligned doubles directly then no 1719 // fixup is needed. Else we split the double into 2 integer pieces 1720 // and move it piece-by-piece. Only happens when passing doubles into 1721 // C code as the Java calling convention forces doubles to be aligned. 1722 const bool Matcher::misaligned_doubles_ok = true; 1723 1724 // No-op on amd64 1725 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1726 1727 // Advertise here if the CPU requires explicit rounding operations to 1728 // implement the UseStrictFP mode. 1729 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1730 1731 // Are floats conerted to double when stored to stack during deoptimization? 1732 // On x64 it is stored without convertion so we can use normal access. 1733 bool Matcher::float_in_double() { return false; } 1734 1735 // Do ints take an entire long register or just half? 1736 const bool Matcher::int_in_long = true; 1737 1738 // Return whether or not this register is ever used as an argument. 1739 // This function is used on startup to build the trampoline stubs in 1740 // generateOptoStub. Registers not mentioned will be killed by the VM 1741 // call in the trampoline, and arguments in those registers not be 1742 // available to the callee. 1743 bool Matcher::can_be_java_arg(int reg) 1744 { 1745 return 1746 reg == RDI_num || reg == RDI_H_num || 1747 reg == RSI_num || reg == RSI_H_num || 1748 reg == RDX_num || reg == RDX_H_num || 1749 reg == RCX_num || reg == RCX_H_num || 1750 reg == R8_num || reg == R8_H_num || 1751 reg == R9_num || reg == R9_H_num || 1752 reg == R12_num || reg == R12_H_num || 1753 reg == XMM0_num || reg == XMM0b_num || 1754 reg == XMM1_num || reg == XMM1b_num || 1755 reg == XMM2_num || reg == XMM2b_num || 1756 reg == XMM3_num || reg == XMM3b_num || 1757 reg == XMM4_num || reg == XMM4b_num || 1758 reg == XMM5_num || reg == XMM5b_num || 1759 reg == XMM6_num || reg == XMM6b_num || 1760 reg == XMM7_num || reg == XMM7b_num; 1761 } 1762 1763 bool Matcher::is_spillable_arg(int reg) 1764 { 1765 return can_be_java_arg(reg); 1766 } 1767 1768 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1769 // In 64 bit mode a code which use multiply when 1770 // devisor is constant is faster than hardware 1771 // DIV instruction (it uses MulHiL). 1772 return false; 1773 } 1774 1775 // Register for DIVI projection of divmodI 1776 RegMask Matcher::divI_proj_mask() { 1777 return INT_RAX_REG_mask(); 1778 } 1779 1780 // Register for MODI projection of divmodI 1781 RegMask Matcher::modI_proj_mask() { 1782 return INT_RDX_REG_mask(); 1783 } 1784 1785 // Register for DIVL projection of divmodL 1786 RegMask Matcher::divL_proj_mask() { 1787 return LONG_RAX_REG_mask(); 1788 } 1789 1790 // Register for MODL projection of divmodL 1791 RegMask Matcher::modL_proj_mask() { 1792 return LONG_RDX_REG_mask(); 1793 } 1794 1795 // Register for saving SP into on method handle invokes. Not used on x86_64. 1796 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1797 return NO_REG_mask(); 1798 } 1799 1800 %} 1801 1802 //----------ENCODING BLOCK----------------------------------------------------- 1803 // This block specifies the encoding classes used by the compiler to 1804 // output byte streams. Encoding classes are parameterized macros 1805 // used by Machine Instruction Nodes in order to generate the bit 1806 // encoding of the instruction. Operands specify their base encoding 1807 // interface with the interface keyword. There are currently 1808 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1809 // COND_INTER. REG_INTER causes an operand to generate a function 1810 // which returns its register number when queried. CONST_INTER causes 1811 // an operand to generate a function which returns the value of the 1812 // constant when queried. MEMORY_INTER causes an operand to generate 1813 // four functions which return the Base Register, the Index Register, 1814 // the Scale Value, and the Offset Value of the operand when queried. 1815 // COND_INTER causes an operand to generate six functions which return 1816 // the encoding code (ie - encoding bits for the instruction) 1817 // associated with each basic boolean condition for a conditional 1818 // instruction. 1819 // 1820 // Instructions specify two basic values for encoding. Again, a 1821 // function is available to check if the constant displacement is an 1822 // oop. They use the ins_encode keyword to specify their encoding 1823 // classes (which must be a sequence of enc_class names, and their 1824 // parameters, specified in the encoding block), and they use the 1825 // opcode keyword to specify, in order, their primary, secondary, and 1826 // tertiary opcode. Only the opcode sections which a particular 1827 // instruction needs for encoding need to be specified. 1828 encode %{ 1829 // Build emit functions for each basic byte or larger field in the 1830 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1831 // from C++ code in the enc_class source block. Emit functions will 1832 // live in the main source block for now. In future, we can 1833 // generalize this by adding a syntax that specifies the sizes of 1834 // fields in an order, so that the adlc can build the emit functions 1835 // automagically 1836 1837 // Emit primary opcode 1838 enc_class OpcP 1839 %{ 1840 emit_opcode(cbuf, $primary); 1841 %} 1842 1843 // Emit secondary opcode 1844 enc_class OpcS 1845 %{ 1846 emit_opcode(cbuf, $secondary); 1847 %} 1848 1849 // Emit tertiary opcode 1850 enc_class OpcT 1851 %{ 1852 emit_opcode(cbuf, $tertiary); 1853 %} 1854 1855 // Emit opcode directly 1856 enc_class Opcode(immI d8) 1857 %{ 1858 emit_opcode(cbuf, $d8$$constant); 1859 %} 1860 1861 // Emit size prefix 1862 enc_class SizePrefix 1863 %{ 1864 emit_opcode(cbuf, 0x66); 1865 %} 1866 1867 enc_class reg(rRegI reg) 1868 %{ 1869 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1870 %} 1871 1872 enc_class reg_reg(rRegI dst, rRegI src) 1873 %{ 1874 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1875 %} 1876 1877 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1878 %{ 1879 emit_opcode(cbuf, $opcode$$constant); 1880 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1881 %} 1882 1883 enc_class cdql_enc(no_rax_rdx_RegI div) 1884 %{ 1885 // Full implementation of Java idiv and irem; checks for 1886 // special case as described in JVM spec., p.243 & p.271. 1887 // 1888 // normal case special case 1889 // 1890 // input : rax: dividend min_int 1891 // reg: divisor -1 1892 // 1893 // output: rax: quotient (= rax idiv reg) min_int 1894 // rdx: remainder (= rax irem reg) 0 1895 // 1896 // Code sequnce: 1897 // 1898 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1899 // 5: 75 07/08 jne e <normal> 1900 // 7: 33 d2 xor %edx,%edx 1901 // [div >= 8 -> offset + 1] 1902 // [REX_B] 1903 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1904 // c: 74 03/04 je 11 <done> 1905 // 000000000000000e <normal>: 1906 // e: 99 cltd 1907 // [div >= 8 -> offset + 1] 1908 // [REX_B] 1909 // f: f7 f9 idiv $div 1910 // 0000000000000011 <done>: 1911 1912 // cmp $0x80000000,%eax 1913 emit_opcode(cbuf, 0x3d); 1914 emit_d8(cbuf, 0x00); 1915 emit_d8(cbuf, 0x00); 1916 emit_d8(cbuf, 0x00); 1917 emit_d8(cbuf, 0x80); 1918 1919 // jne e <normal> 1920 emit_opcode(cbuf, 0x75); 1921 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1922 1923 // xor %edx,%edx 1924 emit_opcode(cbuf, 0x33); 1925 emit_d8(cbuf, 0xD2); 1926 1927 // cmp $0xffffffffffffffff,%ecx 1928 if ($div$$reg >= 8) { 1929 emit_opcode(cbuf, Assembler::REX_B); 1930 } 1931 emit_opcode(cbuf, 0x83); 1932 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1933 emit_d8(cbuf, 0xFF); 1934 1935 // je 11 <done> 1936 emit_opcode(cbuf, 0x74); 1937 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1938 1939 // <normal> 1940 // cltd 1941 emit_opcode(cbuf, 0x99); 1942 1943 // idivl (note: must be emitted by the user of this rule) 1944 // <done> 1945 %} 1946 1947 enc_class cdqq_enc(no_rax_rdx_RegL div) 1948 %{ 1949 // Full implementation of Java ldiv and lrem; checks for 1950 // special case as described in JVM spec., p.243 & p.271. 1951 // 1952 // normal case special case 1953 // 1954 // input : rax: dividend min_long 1955 // reg: divisor -1 1956 // 1957 // output: rax: quotient (= rax idiv reg) min_long 1958 // rdx: remainder (= rax irem reg) 0 1959 // 1960 // Code sequnce: 1961 // 1962 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1963 // 7: 00 00 80 1964 // a: 48 39 d0 cmp %rdx,%rax 1965 // d: 75 08 jne 17 <normal> 1966 // f: 33 d2 xor %edx,%edx 1967 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1968 // 15: 74 05 je 1c <done> 1969 // 0000000000000017 <normal>: 1970 // 17: 48 99 cqto 1971 // 19: 48 f7 f9 idiv $div 1972 // 000000000000001c <done>: 1973 1974 // mov $0x8000000000000000,%rdx 1975 emit_opcode(cbuf, Assembler::REX_W); 1976 emit_opcode(cbuf, 0xBA); 1977 emit_d8(cbuf, 0x00); 1978 emit_d8(cbuf, 0x00); 1979 emit_d8(cbuf, 0x00); 1980 emit_d8(cbuf, 0x00); 1981 emit_d8(cbuf, 0x00); 1982 emit_d8(cbuf, 0x00); 1983 emit_d8(cbuf, 0x00); 1984 emit_d8(cbuf, 0x80); 1985 1986 // cmp %rdx,%rax 1987 emit_opcode(cbuf, Assembler::REX_W); 1988 emit_opcode(cbuf, 0x39); 1989 emit_d8(cbuf, 0xD0); 1990 1991 // jne 17 <normal> 1992 emit_opcode(cbuf, 0x75); 1993 emit_d8(cbuf, 0x08); 1994 1995 // xor %edx,%edx 1996 emit_opcode(cbuf, 0x33); 1997 emit_d8(cbuf, 0xD2); 1998 1999 // cmp $0xffffffffffffffff,$div 2000 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 2001 emit_opcode(cbuf, 0x83); 2002 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2003 emit_d8(cbuf, 0xFF); 2004 2005 // je 1e <done> 2006 emit_opcode(cbuf, 0x74); 2007 emit_d8(cbuf, 0x05); 2008 2009 // <normal> 2010 // cqto 2011 emit_opcode(cbuf, Assembler::REX_W); 2012 emit_opcode(cbuf, 0x99); 2013 2014 // idivq (note: must be emitted by the user of this rule) 2015 // <done> 2016 %} 2017 2018 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2019 enc_class OpcSE(immI imm) 2020 %{ 2021 // Emit primary opcode and set sign-extend bit 2022 // Check for 8-bit immediate, and set sign extend bit in opcode 2023 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2024 emit_opcode(cbuf, $primary | 0x02); 2025 } else { 2026 // 32-bit immediate 2027 emit_opcode(cbuf, $primary); 2028 } 2029 %} 2030 2031 enc_class OpcSErm(rRegI dst, immI imm) 2032 %{ 2033 // OpcSEr/m 2034 int dstenc = $dst$$reg; 2035 if (dstenc >= 8) { 2036 emit_opcode(cbuf, Assembler::REX_B); 2037 dstenc -= 8; 2038 } 2039 // Emit primary opcode and set sign-extend bit 2040 // Check for 8-bit immediate, and set sign extend bit in opcode 2041 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2042 emit_opcode(cbuf, $primary | 0x02); 2043 } else { 2044 // 32-bit immediate 2045 emit_opcode(cbuf, $primary); 2046 } 2047 // Emit r/m byte with secondary opcode, after primary opcode. 2048 emit_rm(cbuf, 0x3, $secondary, dstenc); 2049 %} 2050 2051 enc_class OpcSErm_wide(rRegL dst, immI imm) 2052 %{ 2053 // OpcSEr/m 2054 int dstenc = $dst$$reg; 2055 if (dstenc < 8) { 2056 emit_opcode(cbuf, Assembler::REX_W); 2057 } else { 2058 emit_opcode(cbuf, Assembler::REX_WB); 2059 dstenc -= 8; 2060 } 2061 // Emit primary opcode and set sign-extend bit 2062 // Check for 8-bit immediate, and set sign extend bit in opcode 2063 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2064 emit_opcode(cbuf, $primary | 0x02); 2065 } else { 2066 // 32-bit immediate 2067 emit_opcode(cbuf, $primary); 2068 } 2069 // Emit r/m byte with secondary opcode, after primary opcode. 2070 emit_rm(cbuf, 0x3, $secondary, dstenc); 2071 %} 2072 2073 enc_class Con8or32(immI imm) 2074 %{ 2075 // Check for 8-bit immediate, and set sign extend bit in opcode 2076 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2077 $$$emit8$imm$$constant; 2078 } else { 2079 // 32-bit immediate 2080 $$$emit32$imm$$constant; 2081 } 2082 %} 2083 2084 enc_class opc2_reg(rRegI dst) 2085 %{ 2086 // BSWAP 2087 emit_cc(cbuf, $secondary, $dst$$reg); 2088 %} 2089 2090 enc_class opc3_reg(rRegI dst) 2091 %{ 2092 // BSWAP 2093 emit_cc(cbuf, $tertiary, $dst$$reg); 2094 %} 2095 2096 enc_class reg_opc(rRegI div) 2097 %{ 2098 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2099 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2100 %} 2101 2102 enc_class enc_cmov(cmpOp cop) 2103 %{ 2104 // CMOV 2105 $$$emit8$primary; 2106 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2107 %} 2108 2109 enc_class enc_PartialSubtypeCheck() 2110 %{ 2111 Register Rrdi = as_Register(RDI_enc); // result register 2112 Register Rrax = as_Register(RAX_enc); // super class 2113 Register Rrcx = as_Register(RCX_enc); // killed 2114 Register Rrsi = as_Register(RSI_enc); // sub class 2115 Label miss; 2116 const bool set_cond_codes = true; 2117 2118 MacroAssembler _masm(&cbuf); 2119 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2120 NULL, &miss, 2121 /*set_cond_codes:*/ true); 2122 if ($primary) { 2123 __ xorptr(Rrdi, Rrdi); 2124 } 2125 __ bind(miss); 2126 %} 2127 2128 enc_class clear_avx %{ 2129 debug_only(int off0 = cbuf.insts_size()); 2130 if (generate_vzeroupper(Compile::current())) { 2131 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2132 // Clear upper bits of YMM registers when current compiled code uses 2133 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2134 MacroAssembler _masm(&cbuf); 2135 __ vzeroupper(); 2136 } 2137 debug_only(int off1 = cbuf.insts_size()); 2138 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2139 %} 2140 2141 enc_class Java_To_Runtime(method meth) %{ 2142 // No relocation needed 2143 MacroAssembler _masm(&cbuf); 2144 __ mov64(r10, (int64_t) $meth$$method); 2145 __ call(r10); 2146 %} 2147 2148 enc_class Java_To_Interpreter(method meth) 2149 %{ 2150 // CALL Java_To_Interpreter 2151 // This is the instruction starting address for relocation info. 2152 cbuf.set_insts_mark(); 2153 $$$emit8$primary; 2154 // CALL directly to the runtime 2155 emit_d32_reloc(cbuf, 2156 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2157 runtime_call_Relocation::spec(), 2158 RELOC_DISP32); 2159 %} 2160 2161 enc_class Java_Static_Call(method meth) 2162 %{ 2163 // JAVA STATIC CALL 2164 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2165 // determine who we intended to call. 2166 cbuf.set_insts_mark(); 2167 $$$emit8$primary; 2168 2169 if (!_method) { 2170 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2171 runtime_call_Relocation::spec(), 2172 RELOC_DISP32); 2173 } else { 2174 int method_index = resolved_method_index(cbuf); 2175 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2176 : static_call_Relocation::spec(method_index); 2177 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2178 rspec, RELOC_DISP32); 2179 // Emit stubs for static call. 2180 address mark = cbuf.insts_mark(); 2181 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2182 if (stub == NULL) { 2183 ciEnv::current()->record_failure("CodeCache is full"); 2184 return; 2185 } 2186 #if INCLUDE_AOT 2187 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2188 #endif 2189 } 2190 %} 2191 2192 enc_class Java_Dynamic_Call(method meth) %{ 2193 MacroAssembler _masm(&cbuf); 2194 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2195 %} 2196 2197 enc_class Java_Compiled_Call(method meth) 2198 %{ 2199 // JAVA COMPILED CALL 2200 int disp = in_bytes(Method:: from_compiled_offset()); 2201 2202 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2203 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2204 2205 // callq *disp(%rax) 2206 cbuf.set_insts_mark(); 2207 $$$emit8$primary; 2208 if (disp < 0x80) { 2209 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2210 emit_d8(cbuf, disp); // Displacement 2211 } else { 2212 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2213 emit_d32(cbuf, disp); // Displacement 2214 } 2215 %} 2216 2217 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2218 %{ 2219 // SAL, SAR, SHR 2220 int dstenc = $dst$$reg; 2221 if (dstenc >= 8) { 2222 emit_opcode(cbuf, Assembler::REX_B); 2223 dstenc -= 8; 2224 } 2225 $$$emit8$primary; 2226 emit_rm(cbuf, 0x3, $secondary, dstenc); 2227 $$$emit8$shift$$constant; 2228 %} 2229 2230 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2231 %{ 2232 // SAL, SAR, SHR 2233 int dstenc = $dst$$reg; 2234 if (dstenc < 8) { 2235 emit_opcode(cbuf, Assembler::REX_W); 2236 } else { 2237 emit_opcode(cbuf, Assembler::REX_WB); 2238 dstenc -= 8; 2239 } 2240 $$$emit8$primary; 2241 emit_rm(cbuf, 0x3, $secondary, dstenc); 2242 $$$emit8$shift$$constant; 2243 %} 2244 2245 enc_class load_immI(rRegI dst, immI src) 2246 %{ 2247 int dstenc = $dst$$reg; 2248 if (dstenc >= 8) { 2249 emit_opcode(cbuf, Assembler::REX_B); 2250 dstenc -= 8; 2251 } 2252 emit_opcode(cbuf, 0xB8 | dstenc); 2253 $$$emit32$src$$constant; 2254 %} 2255 2256 enc_class load_immL(rRegL dst, immL src) 2257 %{ 2258 int dstenc = $dst$$reg; 2259 if (dstenc < 8) { 2260 emit_opcode(cbuf, Assembler::REX_W); 2261 } else { 2262 emit_opcode(cbuf, Assembler::REX_WB); 2263 dstenc -= 8; 2264 } 2265 emit_opcode(cbuf, 0xB8 | dstenc); 2266 emit_d64(cbuf, $src$$constant); 2267 %} 2268 2269 enc_class load_immUL32(rRegL dst, immUL32 src) 2270 %{ 2271 // same as load_immI, but this time we care about zeroes in the high word 2272 int dstenc = $dst$$reg; 2273 if (dstenc >= 8) { 2274 emit_opcode(cbuf, Assembler::REX_B); 2275 dstenc -= 8; 2276 } 2277 emit_opcode(cbuf, 0xB8 | dstenc); 2278 $$$emit32$src$$constant; 2279 %} 2280 2281 enc_class load_immL32(rRegL dst, immL32 src) 2282 %{ 2283 int dstenc = $dst$$reg; 2284 if (dstenc < 8) { 2285 emit_opcode(cbuf, Assembler::REX_W); 2286 } else { 2287 emit_opcode(cbuf, Assembler::REX_WB); 2288 dstenc -= 8; 2289 } 2290 emit_opcode(cbuf, 0xC7); 2291 emit_rm(cbuf, 0x03, 0x00, dstenc); 2292 $$$emit32$src$$constant; 2293 %} 2294 2295 enc_class load_immP31(rRegP dst, immP32 src) 2296 %{ 2297 // same as load_immI, but this time we care about zeroes in the high word 2298 int dstenc = $dst$$reg; 2299 if (dstenc >= 8) { 2300 emit_opcode(cbuf, Assembler::REX_B); 2301 dstenc -= 8; 2302 } 2303 emit_opcode(cbuf, 0xB8 | dstenc); 2304 $$$emit32$src$$constant; 2305 %} 2306 2307 enc_class load_immP(rRegP dst, immP src) 2308 %{ 2309 int dstenc = $dst$$reg; 2310 if (dstenc < 8) { 2311 emit_opcode(cbuf, Assembler::REX_W); 2312 } else { 2313 emit_opcode(cbuf, Assembler::REX_WB); 2314 dstenc -= 8; 2315 } 2316 emit_opcode(cbuf, 0xB8 | dstenc); 2317 // This next line should be generated from ADLC 2318 if ($src->constant_reloc() != relocInfo::none) { 2319 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2320 } else { 2321 emit_d64(cbuf, $src$$constant); 2322 } 2323 %} 2324 2325 enc_class Con32(immI src) 2326 %{ 2327 // Output immediate 2328 $$$emit32$src$$constant; 2329 %} 2330 2331 enc_class Con32F_as_bits(immF src) 2332 %{ 2333 // Output Float immediate bits 2334 jfloat jf = $src$$constant; 2335 jint jf_as_bits = jint_cast(jf); 2336 emit_d32(cbuf, jf_as_bits); 2337 %} 2338 2339 enc_class Con16(immI src) 2340 %{ 2341 // Output immediate 2342 $$$emit16$src$$constant; 2343 %} 2344 2345 // How is this different from Con32??? XXX 2346 enc_class Con_d32(immI src) 2347 %{ 2348 emit_d32(cbuf,$src$$constant); 2349 %} 2350 2351 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2352 // Output immediate memory reference 2353 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2354 emit_d32(cbuf, 0x00); 2355 %} 2356 2357 enc_class lock_prefix() 2358 %{ 2359 if (os::is_MP()) { 2360 emit_opcode(cbuf, 0xF0); // lock 2361 } 2362 %} 2363 2364 enc_class REX_mem(memory mem) 2365 %{ 2366 if ($mem$$base >= 8) { 2367 if ($mem$$index < 8) { 2368 emit_opcode(cbuf, Assembler::REX_B); 2369 } else { 2370 emit_opcode(cbuf, Assembler::REX_XB); 2371 } 2372 } else { 2373 if ($mem$$index >= 8) { 2374 emit_opcode(cbuf, Assembler::REX_X); 2375 } 2376 } 2377 %} 2378 2379 enc_class REX_mem_wide(memory mem) 2380 %{ 2381 if ($mem$$base >= 8) { 2382 if ($mem$$index < 8) { 2383 emit_opcode(cbuf, Assembler::REX_WB); 2384 } else { 2385 emit_opcode(cbuf, Assembler::REX_WXB); 2386 } 2387 } else { 2388 if ($mem$$index < 8) { 2389 emit_opcode(cbuf, Assembler::REX_W); 2390 } else { 2391 emit_opcode(cbuf, Assembler::REX_WX); 2392 } 2393 } 2394 %} 2395 2396 // for byte regs 2397 enc_class REX_breg(rRegI reg) 2398 %{ 2399 if ($reg$$reg >= 4) { 2400 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2401 } 2402 %} 2403 2404 // for byte regs 2405 enc_class REX_reg_breg(rRegI dst, rRegI src) 2406 %{ 2407 if ($dst$$reg < 8) { 2408 if ($src$$reg >= 4) { 2409 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2410 } 2411 } else { 2412 if ($src$$reg < 8) { 2413 emit_opcode(cbuf, Assembler::REX_R); 2414 } else { 2415 emit_opcode(cbuf, Assembler::REX_RB); 2416 } 2417 } 2418 %} 2419 2420 // for byte regs 2421 enc_class REX_breg_mem(rRegI reg, memory mem) 2422 %{ 2423 if ($reg$$reg < 8) { 2424 if ($mem$$base < 8) { 2425 if ($mem$$index >= 8) { 2426 emit_opcode(cbuf, Assembler::REX_X); 2427 } else if ($reg$$reg >= 4) { 2428 emit_opcode(cbuf, Assembler::REX); 2429 } 2430 } else { 2431 if ($mem$$index < 8) { 2432 emit_opcode(cbuf, Assembler::REX_B); 2433 } else { 2434 emit_opcode(cbuf, Assembler::REX_XB); 2435 } 2436 } 2437 } else { 2438 if ($mem$$base < 8) { 2439 if ($mem$$index < 8) { 2440 emit_opcode(cbuf, Assembler::REX_R); 2441 } else { 2442 emit_opcode(cbuf, Assembler::REX_RX); 2443 } 2444 } else { 2445 if ($mem$$index < 8) { 2446 emit_opcode(cbuf, Assembler::REX_RB); 2447 } else { 2448 emit_opcode(cbuf, Assembler::REX_RXB); 2449 } 2450 } 2451 } 2452 %} 2453 2454 enc_class REX_reg(rRegI reg) 2455 %{ 2456 if ($reg$$reg >= 8) { 2457 emit_opcode(cbuf, Assembler::REX_B); 2458 } 2459 %} 2460 2461 enc_class REX_reg_wide(rRegI reg) 2462 %{ 2463 if ($reg$$reg < 8) { 2464 emit_opcode(cbuf, Assembler::REX_W); 2465 } else { 2466 emit_opcode(cbuf, Assembler::REX_WB); 2467 } 2468 %} 2469 2470 enc_class REX_reg_reg(rRegI dst, rRegI src) 2471 %{ 2472 if ($dst$$reg < 8) { 2473 if ($src$$reg >= 8) { 2474 emit_opcode(cbuf, Assembler::REX_B); 2475 } 2476 } else { 2477 if ($src$$reg < 8) { 2478 emit_opcode(cbuf, Assembler::REX_R); 2479 } else { 2480 emit_opcode(cbuf, Assembler::REX_RB); 2481 } 2482 } 2483 %} 2484 2485 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2486 %{ 2487 if ($dst$$reg < 8) { 2488 if ($src$$reg < 8) { 2489 emit_opcode(cbuf, Assembler::REX_W); 2490 } else { 2491 emit_opcode(cbuf, Assembler::REX_WB); 2492 } 2493 } else { 2494 if ($src$$reg < 8) { 2495 emit_opcode(cbuf, Assembler::REX_WR); 2496 } else { 2497 emit_opcode(cbuf, Assembler::REX_WRB); 2498 } 2499 } 2500 %} 2501 2502 enc_class REX_reg_mem(rRegI reg, memory mem) 2503 %{ 2504 if ($reg$$reg < 8) { 2505 if ($mem$$base < 8) { 2506 if ($mem$$index >= 8) { 2507 emit_opcode(cbuf, Assembler::REX_X); 2508 } 2509 } else { 2510 if ($mem$$index < 8) { 2511 emit_opcode(cbuf, Assembler::REX_B); 2512 } else { 2513 emit_opcode(cbuf, Assembler::REX_XB); 2514 } 2515 } 2516 } else { 2517 if ($mem$$base < 8) { 2518 if ($mem$$index < 8) { 2519 emit_opcode(cbuf, Assembler::REX_R); 2520 } else { 2521 emit_opcode(cbuf, Assembler::REX_RX); 2522 } 2523 } else { 2524 if ($mem$$index < 8) { 2525 emit_opcode(cbuf, Assembler::REX_RB); 2526 } else { 2527 emit_opcode(cbuf, Assembler::REX_RXB); 2528 } 2529 } 2530 } 2531 %} 2532 2533 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2534 %{ 2535 if ($reg$$reg < 8) { 2536 if ($mem$$base < 8) { 2537 if ($mem$$index < 8) { 2538 emit_opcode(cbuf, Assembler::REX_W); 2539 } else { 2540 emit_opcode(cbuf, Assembler::REX_WX); 2541 } 2542 } else { 2543 if ($mem$$index < 8) { 2544 emit_opcode(cbuf, Assembler::REX_WB); 2545 } else { 2546 emit_opcode(cbuf, Assembler::REX_WXB); 2547 } 2548 } 2549 } else { 2550 if ($mem$$base < 8) { 2551 if ($mem$$index < 8) { 2552 emit_opcode(cbuf, Assembler::REX_WR); 2553 } else { 2554 emit_opcode(cbuf, Assembler::REX_WRX); 2555 } 2556 } else { 2557 if ($mem$$index < 8) { 2558 emit_opcode(cbuf, Assembler::REX_WRB); 2559 } else { 2560 emit_opcode(cbuf, Assembler::REX_WRXB); 2561 } 2562 } 2563 } 2564 %} 2565 2566 enc_class reg_mem(rRegI ereg, memory mem) 2567 %{ 2568 // High registers handle in encode_RegMem 2569 int reg = $ereg$$reg; 2570 int base = $mem$$base; 2571 int index = $mem$$index; 2572 int scale = $mem$$scale; 2573 int disp = $mem$$disp; 2574 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2575 2576 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2577 %} 2578 2579 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2580 %{ 2581 int rm_byte_opcode = $rm_opcode$$constant; 2582 2583 // High registers handle in encode_RegMem 2584 int base = $mem$$base; 2585 int index = $mem$$index; 2586 int scale = $mem$$scale; 2587 int displace = $mem$$disp; 2588 2589 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2590 // working with static 2591 // globals 2592 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2593 disp_reloc); 2594 %} 2595 2596 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2597 %{ 2598 int reg_encoding = $dst$$reg; 2599 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2600 int index = 0x04; // 0x04 indicates no index 2601 int scale = 0x00; // 0x00 indicates no scale 2602 int displace = $src1$$constant; // 0x00 indicates no displacement 2603 relocInfo::relocType disp_reloc = relocInfo::none; 2604 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2605 disp_reloc); 2606 %} 2607 2608 enc_class neg_reg(rRegI dst) 2609 %{ 2610 int dstenc = $dst$$reg; 2611 if (dstenc >= 8) { 2612 emit_opcode(cbuf, Assembler::REX_B); 2613 dstenc -= 8; 2614 } 2615 // NEG $dst 2616 emit_opcode(cbuf, 0xF7); 2617 emit_rm(cbuf, 0x3, 0x03, dstenc); 2618 %} 2619 2620 enc_class neg_reg_wide(rRegI dst) 2621 %{ 2622 int dstenc = $dst$$reg; 2623 if (dstenc < 8) { 2624 emit_opcode(cbuf, Assembler::REX_W); 2625 } else { 2626 emit_opcode(cbuf, Assembler::REX_WB); 2627 dstenc -= 8; 2628 } 2629 // NEG $dst 2630 emit_opcode(cbuf, 0xF7); 2631 emit_rm(cbuf, 0x3, 0x03, dstenc); 2632 %} 2633 2634 enc_class setLT_reg(rRegI dst) 2635 %{ 2636 int dstenc = $dst$$reg; 2637 if (dstenc >= 8) { 2638 emit_opcode(cbuf, Assembler::REX_B); 2639 dstenc -= 8; 2640 } else if (dstenc >= 4) { 2641 emit_opcode(cbuf, Assembler::REX); 2642 } 2643 // SETLT $dst 2644 emit_opcode(cbuf, 0x0F); 2645 emit_opcode(cbuf, 0x9C); 2646 emit_rm(cbuf, 0x3, 0x0, dstenc); 2647 %} 2648 2649 enc_class setNZ_reg(rRegI dst) 2650 %{ 2651 int dstenc = $dst$$reg; 2652 if (dstenc >= 8) { 2653 emit_opcode(cbuf, Assembler::REX_B); 2654 dstenc -= 8; 2655 } else if (dstenc >= 4) { 2656 emit_opcode(cbuf, Assembler::REX); 2657 } 2658 // SETNZ $dst 2659 emit_opcode(cbuf, 0x0F); 2660 emit_opcode(cbuf, 0x95); 2661 emit_rm(cbuf, 0x3, 0x0, dstenc); 2662 %} 2663 2664 2665 // Compare the lonogs and set -1, 0, or 1 into dst 2666 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2667 %{ 2668 int src1enc = $src1$$reg; 2669 int src2enc = $src2$$reg; 2670 int dstenc = $dst$$reg; 2671 2672 // cmpq $src1, $src2 2673 if (src1enc < 8) { 2674 if (src2enc < 8) { 2675 emit_opcode(cbuf, Assembler::REX_W); 2676 } else { 2677 emit_opcode(cbuf, Assembler::REX_WB); 2678 } 2679 } else { 2680 if (src2enc < 8) { 2681 emit_opcode(cbuf, Assembler::REX_WR); 2682 } else { 2683 emit_opcode(cbuf, Assembler::REX_WRB); 2684 } 2685 } 2686 emit_opcode(cbuf, 0x3B); 2687 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2688 2689 // movl $dst, -1 2690 if (dstenc >= 8) { 2691 emit_opcode(cbuf, Assembler::REX_B); 2692 } 2693 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2694 emit_d32(cbuf, -1); 2695 2696 // jl,s done 2697 emit_opcode(cbuf, 0x7C); 2698 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2699 2700 // setne $dst 2701 if (dstenc >= 4) { 2702 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2703 } 2704 emit_opcode(cbuf, 0x0F); 2705 emit_opcode(cbuf, 0x95); 2706 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2707 2708 // movzbl $dst, $dst 2709 if (dstenc >= 4) { 2710 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2711 } 2712 emit_opcode(cbuf, 0x0F); 2713 emit_opcode(cbuf, 0xB6); 2714 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2715 %} 2716 2717 enc_class Push_ResultXD(regD dst) %{ 2718 MacroAssembler _masm(&cbuf); 2719 __ fstp_d(Address(rsp, 0)); 2720 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2721 __ addptr(rsp, 8); 2722 %} 2723 2724 enc_class Push_SrcXD(regD src) %{ 2725 MacroAssembler _masm(&cbuf); 2726 __ subptr(rsp, 8); 2727 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2728 __ fld_d(Address(rsp, 0)); 2729 %} 2730 2731 2732 enc_class enc_rethrow() 2733 %{ 2734 cbuf.set_insts_mark(); 2735 emit_opcode(cbuf, 0xE9); // jmp entry 2736 emit_d32_reloc(cbuf, 2737 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2738 runtime_call_Relocation::spec(), 2739 RELOC_DISP32); 2740 %} 2741 2742 %} 2743 2744 2745 2746 //----------FRAME-------------------------------------------------------------- 2747 // Definition of frame structure and management information. 2748 // 2749 // S T A C K L A Y O U T Allocators stack-slot number 2750 // | (to get allocators register number 2751 // G Owned by | | v add OptoReg::stack0()) 2752 // r CALLER | | 2753 // o | +--------+ pad to even-align allocators stack-slot 2754 // w V | pad0 | numbers; owned by CALLER 2755 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2756 // h ^ | in | 5 2757 // | | args | 4 Holes in incoming args owned by SELF 2758 // | | | | 3 2759 // | | +--------+ 2760 // V | | old out| Empty on Intel, window on Sparc 2761 // | old |preserve| Must be even aligned. 2762 // | SP-+--------+----> Matcher::_old_SP, even aligned 2763 // | | in | 3 area for Intel ret address 2764 // Owned by |preserve| Empty on Sparc. 2765 // SELF +--------+ 2766 // | | pad2 | 2 pad to align old SP 2767 // | +--------+ 1 2768 // | | locks | 0 2769 // | +--------+----> OptoReg::stack0(), even aligned 2770 // | | pad1 | 11 pad to align new SP 2771 // | +--------+ 2772 // | | | 10 2773 // | | spills | 9 spills 2774 // V | | 8 (pad0 slot for callee) 2775 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2776 // ^ | out | 7 2777 // | | args | 6 Holes in outgoing args owned by CALLEE 2778 // Owned by +--------+ 2779 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2780 // | new |preserve| Must be even-aligned. 2781 // | SP-+--------+----> Matcher::_new_SP, even aligned 2782 // | | | 2783 // 2784 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2785 // known from SELF's arguments and the Java calling convention. 2786 // Region 6-7 is determined per call site. 2787 // Note 2: If the calling convention leaves holes in the incoming argument 2788 // area, those holes are owned by SELF. Holes in the outgoing area 2789 // are owned by the CALLEE. Holes should not be nessecary in the 2790 // incoming area, as the Java calling convention is completely under 2791 // the control of the AD file. Doubles can be sorted and packed to 2792 // avoid holes. Holes in the outgoing arguments may be nessecary for 2793 // varargs C calling conventions. 2794 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2795 // even aligned with pad0 as needed. 2796 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2797 // region 6-11 is even aligned; it may be padded out more so that 2798 // the region from SP to FP meets the minimum stack alignment. 2799 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2800 // alignment. Region 11, pad1, may be dynamically extended so that 2801 // SP meets the minimum alignment. 2802 2803 frame 2804 %{ 2805 // What direction does stack grow in (assumed to be same for C & Java) 2806 stack_direction(TOWARDS_LOW); 2807 2808 // These three registers define part of the calling convention 2809 // between compiled code and the interpreter. 2810 inline_cache_reg(RAX); // Inline Cache Register 2811 interpreter_method_oop_reg(RBX); // Method Oop Register when 2812 // calling interpreter 2813 2814 // Optional: name the operand used by cisc-spilling to access 2815 // [stack_pointer + offset] 2816 cisc_spilling_operand_name(indOffset32); 2817 2818 // Number of stack slots consumed by locking an object 2819 sync_stack_slots(2); 2820 2821 // Compiled code's Frame Pointer 2822 frame_pointer(RSP); 2823 2824 // Interpreter stores its frame pointer in a register which is 2825 // stored to the stack by I2CAdaptors. 2826 // I2CAdaptors convert from interpreted java to compiled java. 2827 interpreter_frame_pointer(RBP); 2828 2829 // Stack alignment requirement 2830 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2831 2832 // Number of stack slots between incoming argument block and the start of 2833 // a new frame. The PROLOG must add this many slots to the stack. The 2834 // EPILOG must remove this many slots. amd64 needs two slots for 2835 // return address. 2836 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2837 2838 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2839 // for calls to C. Supports the var-args backing area for register parms. 2840 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2841 2842 // The after-PROLOG location of the return address. Location of 2843 // return address specifies a type (REG or STACK) and a number 2844 // representing the register number (i.e. - use a register name) or 2845 // stack slot. 2846 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2847 // Otherwise, it is above the locks and verification slot and alignment word 2848 return_addr(STACK - 2 + 2849 align_up((Compile::current()->in_preserve_stack_slots() + 2850 Compile::current()->fixed_slots()), 2851 stack_alignment_in_slots())); 2852 2853 // Body of function which returns an integer array locating 2854 // arguments either in registers or in stack slots. Passed an array 2855 // of ideal registers called "sig" and a "length" count. Stack-slot 2856 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2857 // arguments for a CALLEE. Incoming stack arguments are 2858 // automatically biased by the preserve_stack_slots field above. 2859 2860 calling_convention 2861 %{ 2862 // No difference between ingoing/outgoing just pass false 2863 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2864 %} 2865 2866 c_calling_convention 2867 %{ 2868 // This is obviously always outgoing 2869 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2870 %} 2871 2872 // Location of compiled Java return values. Same as C for now. 2873 return_value 2874 %{ 2875 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2876 "only return normal values"); 2877 2878 static const int lo[Op_RegL + 1] = { 2879 0, 2880 0, 2881 RAX_num, // Op_RegN 2882 RAX_num, // Op_RegI 2883 RAX_num, // Op_RegP 2884 XMM0_num, // Op_RegF 2885 XMM0_num, // Op_RegD 2886 RAX_num // Op_RegL 2887 }; 2888 static const int hi[Op_RegL + 1] = { 2889 0, 2890 0, 2891 OptoReg::Bad, // Op_RegN 2892 OptoReg::Bad, // Op_RegI 2893 RAX_H_num, // Op_RegP 2894 OptoReg::Bad, // Op_RegF 2895 XMM0b_num, // Op_RegD 2896 RAX_H_num // Op_RegL 2897 }; 2898 // Excluded flags and vector registers. 2899 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2900 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2901 %} 2902 %} 2903 2904 //----------ATTRIBUTES--------------------------------------------------------- 2905 //----------Operand Attributes------------------------------------------------- 2906 op_attrib op_cost(0); // Required cost attribute 2907 2908 //----------Instruction Attributes--------------------------------------------- 2909 ins_attrib ins_cost(100); // Required cost attribute 2910 ins_attrib ins_size(8); // Required size attribute (in bits) 2911 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2912 // a non-matching short branch variant 2913 // of some long branch? 2914 ins_attrib ins_alignment(1); // Required alignment attribute (must 2915 // be a power of 2) specifies the 2916 // alignment that some part of the 2917 // instruction (not necessarily the 2918 // start) requires. If > 1, a 2919 // compute_padding() function must be 2920 // provided for the instruction 2921 2922 //----------OPERANDS----------------------------------------------------------- 2923 // Operand definitions must precede instruction definitions for correct parsing 2924 // in the ADLC because operands constitute user defined types which are used in 2925 // instruction definitions. 2926 2927 //----------Simple Operands---------------------------------------------------- 2928 // Immediate Operands 2929 // Integer Immediate 2930 operand immI() 2931 %{ 2932 match(ConI); 2933 2934 op_cost(10); 2935 format %{ %} 2936 interface(CONST_INTER); 2937 %} 2938 2939 // Constant for test vs zero 2940 operand immI0() 2941 %{ 2942 predicate(n->get_int() == 0); 2943 match(ConI); 2944 2945 op_cost(0); 2946 format %{ %} 2947 interface(CONST_INTER); 2948 %} 2949 2950 // Constant for increment 2951 operand immI1() 2952 %{ 2953 predicate(n->get_int() == 1); 2954 match(ConI); 2955 2956 op_cost(0); 2957 format %{ %} 2958 interface(CONST_INTER); 2959 %} 2960 2961 // Constant for decrement 2962 operand immI_M1() 2963 %{ 2964 predicate(n->get_int() == -1); 2965 match(ConI); 2966 2967 op_cost(0); 2968 format %{ %} 2969 interface(CONST_INTER); 2970 %} 2971 2972 // Valid scale values for addressing modes 2973 operand immI2() 2974 %{ 2975 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2976 match(ConI); 2977 2978 format %{ %} 2979 interface(CONST_INTER); 2980 %} 2981 2982 operand immI8() 2983 %{ 2984 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2985 match(ConI); 2986 2987 op_cost(5); 2988 format %{ %} 2989 interface(CONST_INTER); 2990 %} 2991 2992 operand immU8() 2993 %{ 2994 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2995 match(ConI); 2996 2997 op_cost(5); 2998 format %{ %} 2999 interface(CONST_INTER); 3000 %} 3001 3002 operand immI16() 3003 %{ 3004 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 3005 match(ConI); 3006 3007 op_cost(10); 3008 format %{ %} 3009 interface(CONST_INTER); 3010 %} 3011 3012 // Int Immediate non-negative 3013 operand immU31() 3014 %{ 3015 predicate(n->get_int() >= 0); 3016 match(ConI); 3017 3018 op_cost(0); 3019 format %{ %} 3020 interface(CONST_INTER); 3021 %} 3022 3023 // Constant for long shifts 3024 operand immI_32() 3025 %{ 3026 predicate( n->get_int() == 32 ); 3027 match(ConI); 3028 3029 op_cost(0); 3030 format %{ %} 3031 interface(CONST_INTER); 3032 %} 3033 3034 // Constant for long shifts 3035 operand immI_64() 3036 %{ 3037 predicate( n->get_int() == 64 ); 3038 match(ConI); 3039 3040 op_cost(0); 3041 format %{ %} 3042 interface(CONST_INTER); 3043 %} 3044 3045 // Pointer Immediate 3046 operand immP() 3047 %{ 3048 match(ConP); 3049 3050 op_cost(10); 3051 format %{ %} 3052 interface(CONST_INTER); 3053 %} 3054 3055 // NULL Pointer Immediate 3056 operand immP0() 3057 %{ 3058 predicate(n->get_ptr() == 0); 3059 match(ConP); 3060 3061 op_cost(5); 3062 format %{ %} 3063 interface(CONST_INTER); 3064 %} 3065 3066 // Pointer Immediate 3067 operand immN() %{ 3068 match(ConN); 3069 3070 op_cost(10); 3071 format %{ %} 3072 interface(CONST_INTER); 3073 %} 3074 3075 operand immNKlass() %{ 3076 match(ConNKlass); 3077 3078 op_cost(10); 3079 format %{ %} 3080 interface(CONST_INTER); 3081 %} 3082 3083 // NULL Pointer Immediate 3084 operand immN0() %{ 3085 predicate(n->get_narrowcon() == 0); 3086 match(ConN); 3087 3088 op_cost(5); 3089 format %{ %} 3090 interface(CONST_INTER); 3091 %} 3092 3093 operand immP31() 3094 %{ 3095 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3096 && (n->get_ptr() >> 31) == 0); 3097 match(ConP); 3098 3099 op_cost(5); 3100 format %{ %} 3101 interface(CONST_INTER); 3102 %} 3103 3104 3105 // Long Immediate 3106 operand immL() 3107 %{ 3108 match(ConL); 3109 3110 op_cost(20); 3111 format %{ %} 3112 interface(CONST_INTER); 3113 %} 3114 3115 // Long Immediate 8-bit 3116 operand immL8() 3117 %{ 3118 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3119 match(ConL); 3120 3121 op_cost(5); 3122 format %{ %} 3123 interface(CONST_INTER); 3124 %} 3125 3126 // Long Immediate 32-bit unsigned 3127 operand immUL32() 3128 %{ 3129 predicate(n->get_long() == (unsigned int) (n->get_long())); 3130 match(ConL); 3131 3132 op_cost(10); 3133 format %{ %} 3134 interface(CONST_INTER); 3135 %} 3136 3137 // Long Immediate 32-bit signed 3138 operand immL32() 3139 %{ 3140 predicate(n->get_long() == (int) (n->get_long())); 3141 match(ConL); 3142 3143 op_cost(15); 3144 format %{ %} 3145 interface(CONST_INTER); 3146 %} 3147 3148 // Long Immediate zero 3149 operand immL0() 3150 %{ 3151 predicate(n->get_long() == 0L); 3152 match(ConL); 3153 3154 op_cost(10); 3155 format %{ %} 3156 interface(CONST_INTER); 3157 %} 3158 3159 // Constant for increment 3160 operand immL1() 3161 %{ 3162 predicate(n->get_long() == 1); 3163 match(ConL); 3164 3165 format %{ %} 3166 interface(CONST_INTER); 3167 %} 3168 3169 // Constant for decrement 3170 operand immL_M1() 3171 %{ 3172 predicate(n->get_long() == -1); 3173 match(ConL); 3174 3175 format %{ %} 3176 interface(CONST_INTER); 3177 %} 3178 3179 // Long Immediate: the value 10 3180 operand immL10() 3181 %{ 3182 predicate(n->get_long() == 10); 3183 match(ConL); 3184 3185 format %{ %} 3186 interface(CONST_INTER); 3187 %} 3188 3189 // Long immediate from 0 to 127. 3190 // Used for a shorter form of long mul by 10. 3191 operand immL_127() 3192 %{ 3193 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3194 match(ConL); 3195 3196 op_cost(10); 3197 format %{ %} 3198 interface(CONST_INTER); 3199 %} 3200 3201 // Long Immediate: low 32-bit mask 3202 operand immL_32bits() 3203 %{ 3204 predicate(n->get_long() == 0xFFFFFFFFL); 3205 match(ConL); 3206 op_cost(20); 3207 3208 format %{ %} 3209 interface(CONST_INTER); 3210 %} 3211 3212 // Float Immediate zero 3213 operand immF0() 3214 %{ 3215 predicate(jint_cast(n->getf()) == 0); 3216 match(ConF); 3217 3218 op_cost(5); 3219 format %{ %} 3220 interface(CONST_INTER); 3221 %} 3222 3223 // Float Immediate 3224 operand immF() 3225 %{ 3226 match(ConF); 3227 3228 op_cost(15); 3229 format %{ %} 3230 interface(CONST_INTER); 3231 %} 3232 3233 // Double Immediate zero 3234 operand immD0() 3235 %{ 3236 predicate(jlong_cast(n->getd()) == 0); 3237 match(ConD); 3238 3239 op_cost(5); 3240 format %{ %} 3241 interface(CONST_INTER); 3242 %} 3243 3244 // Double Immediate 3245 operand immD() 3246 %{ 3247 match(ConD); 3248 3249 op_cost(15); 3250 format %{ %} 3251 interface(CONST_INTER); 3252 %} 3253 3254 // Immediates for special shifts (sign extend) 3255 3256 // Constants for increment 3257 operand immI_16() 3258 %{ 3259 predicate(n->get_int() == 16); 3260 match(ConI); 3261 3262 format %{ %} 3263 interface(CONST_INTER); 3264 %} 3265 3266 operand immI_24() 3267 %{ 3268 predicate(n->get_int() == 24); 3269 match(ConI); 3270 3271 format %{ %} 3272 interface(CONST_INTER); 3273 %} 3274 3275 // Constant for byte-wide masking 3276 operand immI_255() 3277 %{ 3278 predicate(n->get_int() == 255); 3279 match(ConI); 3280 3281 format %{ %} 3282 interface(CONST_INTER); 3283 %} 3284 3285 // Constant for short-wide masking 3286 operand immI_65535() 3287 %{ 3288 predicate(n->get_int() == 65535); 3289 match(ConI); 3290 3291 format %{ %} 3292 interface(CONST_INTER); 3293 %} 3294 3295 // Constant for byte-wide masking 3296 operand immL_255() 3297 %{ 3298 predicate(n->get_long() == 255); 3299 match(ConL); 3300 3301 format %{ %} 3302 interface(CONST_INTER); 3303 %} 3304 3305 // Constant for short-wide masking 3306 operand immL_65535() 3307 %{ 3308 predicate(n->get_long() == 65535); 3309 match(ConL); 3310 3311 format %{ %} 3312 interface(CONST_INTER); 3313 %} 3314 3315 // Register Operands 3316 // Integer Register 3317 operand rRegI() 3318 %{ 3319 constraint(ALLOC_IN_RC(int_reg)); 3320 match(RegI); 3321 3322 match(rax_RegI); 3323 match(rbx_RegI); 3324 match(rcx_RegI); 3325 match(rdx_RegI); 3326 match(rdi_RegI); 3327 3328 format %{ %} 3329 interface(REG_INTER); 3330 %} 3331 3332 // Special Registers 3333 operand rax_RegI() 3334 %{ 3335 constraint(ALLOC_IN_RC(int_rax_reg)); 3336 match(RegI); 3337 match(rRegI); 3338 3339 format %{ "RAX" %} 3340 interface(REG_INTER); 3341 %} 3342 3343 // Special Registers 3344 operand rbx_RegI() 3345 %{ 3346 constraint(ALLOC_IN_RC(int_rbx_reg)); 3347 match(RegI); 3348 match(rRegI); 3349 3350 format %{ "RBX" %} 3351 interface(REG_INTER); 3352 %} 3353 3354 operand rcx_RegI() 3355 %{ 3356 constraint(ALLOC_IN_RC(int_rcx_reg)); 3357 match(RegI); 3358 match(rRegI); 3359 3360 format %{ "RCX" %} 3361 interface(REG_INTER); 3362 %} 3363 3364 operand rdx_RegI() 3365 %{ 3366 constraint(ALLOC_IN_RC(int_rdx_reg)); 3367 match(RegI); 3368 match(rRegI); 3369 3370 format %{ "RDX" %} 3371 interface(REG_INTER); 3372 %} 3373 3374 operand rdi_RegI() 3375 %{ 3376 constraint(ALLOC_IN_RC(int_rdi_reg)); 3377 match(RegI); 3378 match(rRegI); 3379 3380 format %{ "RDI" %} 3381 interface(REG_INTER); 3382 %} 3383 3384 operand no_rcx_RegI() 3385 %{ 3386 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3387 match(RegI); 3388 match(rax_RegI); 3389 match(rbx_RegI); 3390 match(rdx_RegI); 3391 match(rdi_RegI); 3392 3393 format %{ %} 3394 interface(REG_INTER); 3395 %} 3396 3397 operand no_rax_rdx_RegI() 3398 %{ 3399 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3400 match(RegI); 3401 match(rbx_RegI); 3402 match(rcx_RegI); 3403 match(rdi_RegI); 3404 3405 format %{ %} 3406 interface(REG_INTER); 3407 %} 3408 3409 // Pointer Register 3410 operand any_RegP() 3411 %{ 3412 constraint(ALLOC_IN_RC(any_reg)); 3413 match(RegP); 3414 match(rax_RegP); 3415 match(rbx_RegP); 3416 match(rdi_RegP); 3417 match(rsi_RegP); 3418 match(rbp_RegP); 3419 match(r15_RegP); 3420 match(rRegP); 3421 3422 format %{ %} 3423 interface(REG_INTER); 3424 %} 3425 3426 operand rRegP() 3427 %{ 3428 constraint(ALLOC_IN_RC(ptr_reg)); 3429 match(RegP); 3430 match(rax_RegP); 3431 match(rbx_RegP); 3432 match(rdi_RegP); 3433 match(rsi_RegP); 3434 match(rbp_RegP); // See Q&A below about 3435 match(r15_RegP); // r15_RegP and rbp_RegP. 3436 3437 format %{ %} 3438 interface(REG_INTER); 3439 %} 3440 3441 operand rRegN() %{ 3442 constraint(ALLOC_IN_RC(int_reg)); 3443 match(RegN); 3444 3445 format %{ %} 3446 interface(REG_INTER); 3447 %} 3448 3449 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3450 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3451 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3452 // The output of an instruction is controlled by the allocator, which respects 3453 // register class masks, not match rules. Unless an instruction mentions 3454 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3455 // by the allocator as an input. 3456 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3457 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3458 // result, RBP is not included in the output of the instruction either. 3459 3460 operand no_rax_RegP() 3461 %{ 3462 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3463 match(RegP); 3464 match(rbx_RegP); 3465 match(rsi_RegP); 3466 match(rdi_RegP); 3467 3468 format %{ %} 3469 interface(REG_INTER); 3470 %} 3471 3472 // This operand is not allowed to use RBP even if 3473 // RBP is not used to hold the frame pointer. 3474 operand no_rbp_RegP() 3475 %{ 3476 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3477 match(RegP); 3478 match(rbx_RegP); 3479 match(rsi_RegP); 3480 match(rdi_RegP); 3481 3482 format %{ %} 3483 interface(REG_INTER); 3484 %} 3485 3486 operand no_rax_rbx_RegP() 3487 %{ 3488 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3489 match(RegP); 3490 match(rsi_RegP); 3491 match(rdi_RegP); 3492 3493 format %{ %} 3494 interface(REG_INTER); 3495 %} 3496 3497 // Special Registers 3498 // Return a pointer value 3499 operand rax_RegP() 3500 %{ 3501 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3502 match(RegP); 3503 match(rRegP); 3504 3505 format %{ %} 3506 interface(REG_INTER); 3507 %} 3508 3509 // Special Registers 3510 // Return a compressed pointer value 3511 operand rax_RegN() 3512 %{ 3513 constraint(ALLOC_IN_RC(int_rax_reg)); 3514 match(RegN); 3515 match(rRegN); 3516 3517 format %{ %} 3518 interface(REG_INTER); 3519 %} 3520 3521 // Used in AtomicAdd 3522 operand rbx_RegP() 3523 %{ 3524 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3525 match(RegP); 3526 match(rRegP); 3527 3528 format %{ %} 3529 interface(REG_INTER); 3530 %} 3531 3532 operand rsi_RegP() 3533 %{ 3534 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3535 match(RegP); 3536 match(rRegP); 3537 3538 format %{ %} 3539 interface(REG_INTER); 3540 %} 3541 3542 // Used in rep stosq 3543 operand rdi_RegP() 3544 %{ 3545 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3546 match(RegP); 3547 match(rRegP); 3548 3549 format %{ %} 3550 interface(REG_INTER); 3551 %} 3552 3553 operand r15_RegP() 3554 %{ 3555 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3556 match(RegP); 3557 match(rRegP); 3558 3559 format %{ %} 3560 interface(REG_INTER); 3561 %} 3562 3563 operand rex_RegP() 3564 %{ 3565 constraint(ALLOC_IN_RC(ptr_rex_reg)); 3566 match(RegP); 3567 match(rRegP); 3568 3569 format %{ %} 3570 interface(REG_INTER); 3571 %} 3572 3573 operand rRegL() 3574 %{ 3575 constraint(ALLOC_IN_RC(long_reg)); 3576 match(RegL); 3577 match(rax_RegL); 3578 match(rdx_RegL); 3579 3580 format %{ %} 3581 interface(REG_INTER); 3582 %} 3583 3584 // Special Registers 3585 operand no_rax_rdx_RegL() 3586 %{ 3587 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3588 match(RegL); 3589 match(rRegL); 3590 3591 format %{ %} 3592 interface(REG_INTER); 3593 %} 3594 3595 operand no_rax_RegL() 3596 %{ 3597 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3598 match(RegL); 3599 match(rRegL); 3600 match(rdx_RegL); 3601 3602 format %{ %} 3603 interface(REG_INTER); 3604 %} 3605 3606 operand no_rcx_RegL() 3607 %{ 3608 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3609 match(RegL); 3610 match(rRegL); 3611 3612 format %{ %} 3613 interface(REG_INTER); 3614 %} 3615 3616 operand rax_RegL() 3617 %{ 3618 constraint(ALLOC_IN_RC(long_rax_reg)); 3619 match(RegL); 3620 match(rRegL); 3621 3622 format %{ "RAX" %} 3623 interface(REG_INTER); 3624 %} 3625 3626 operand rcx_RegL() 3627 %{ 3628 constraint(ALLOC_IN_RC(long_rcx_reg)); 3629 match(RegL); 3630 match(rRegL); 3631 3632 format %{ %} 3633 interface(REG_INTER); 3634 %} 3635 3636 operand rdx_RegL() 3637 %{ 3638 constraint(ALLOC_IN_RC(long_rdx_reg)); 3639 match(RegL); 3640 match(rRegL); 3641 3642 format %{ %} 3643 interface(REG_INTER); 3644 %} 3645 3646 // Flags register, used as output of compare instructions 3647 operand rFlagsReg() 3648 %{ 3649 constraint(ALLOC_IN_RC(int_flags)); 3650 match(RegFlags); 3651 3652 format %{ "RFLAGS" %} 3653 interface(REG_INTER); 3654 %} 3655 3656 // Flags register, used as output of FLOATING POINT compare instructions 3657 operand rFlagsRegU() 3658 %{ 3659 constraint(ALLOC_IN_RC(int_flags)); 3660 match(RegFlags); 3661 3662 format %{ "RFLAGS_U" %} 3663 interface(REG_INTER); 3664 %} 3665 3666 operand rFlagsRegUCF() %{ 3667 constraint(ALLOC_IN_RC(int_flags)); 3668 match(RegFlags); 3669 predicate(false); 3670 3671 format %{ "RFLAGS_U_CF" %} 3672 interface(REG_INTER); 3673 %} 3674 3675 // Float register operands 3676 operand regF() %{ 3677 constraint(ALLOC_IN_RC(float_reg)); 3678 match(RegF); 3679 3680 format %{ %} 3681 interface(REG_INTER); 3682 %} 3683 3684 // Double register operands 3685 operand regD() %{ 3686 constraint(ALLOC_IN_RC(double_reg)); 3687 match(RegD); 3688 3689 format %{ %} 3690 interface(REG_INTER); 3691 %} 3692 3693 // Vectors 3694 operand vecS() %{ 3695 constraint(ALLOC_IN_RC(vectors_reg)); 3696 match(VecS); 3697 3698 format %{ %} 3699 interface(REG_INTER); 3700 %} 3701 3702 operand vecD() %{ 3703 constraint(ALLOC_IN_RC(vectord_reg)); 3704 match(VecD); 3705 3706 format %{ %} 3707 interface(REG_INTER); 3708 %} 3709 3710 operand vecX() %{ 3711 constraint(ALLOC_IN_RC(vectorx_reg)); 3712 match(VecX); 3713 3714 format %{ %} 3715 interface(REG_INTER); 3716 %} 3717 3718 operand vecY() %{ 3719 constraint(ALLOC_IN_RC(vectory_reg)); 3720 match(VecY); 3721 3722 format %{ %} 3723 interface(REG_INTER); 3724 %} 3725 3726 //----------Memory Operands---------------------------------------------------- 3727 // Direct Memory Operand 3728 // operand direct(immP addr) 3729 // %{ 3730 // match(addr); 3731 3732 // format %{ "[$addr]" %} 3733 // interface(MEMORY_INTER) %{ 3734 // base(0xFFFFFFFF); 3735 // index(0x4); 3736 // scale(0x0); 3737 // disp($addr); 3738 // %} 3739 // %} 3740 3741 // Indirect Memory Operand 3742 operand indirect(any_RegP reg) 3743 %{ 3744 constraint(ALLOC_IN_RC(ptr_reg)); 3745 match(reg); 3746 3747 format %{ "[$reg]" %} 3748 interface(MEMORY_INTER) %{ 3749 base($reg); 3750 index(0x4); 3751 scale(0x0); 3752 disp(0x0); 3753 %} 3754 %} 3755 3756 // Indirect Memory Plus Short Offset Operand 3757 operand indOffset8(any_RegP reg, immL8 off) 3758 %{ 3759 constraint(ALLOC_IN_RC(ptr_reg)); 3760 match(AddP reg off); 3761 3762 format %{ "[$reg + $off (8-bit)]" %} 3763 interface(MEMORY_INTER) %{ 3764 base($reg); 3765 index(0x4); 3766 scale(0x0); 3767 disp($off); 3768 %} 3769 %} 3770 3771 // Indirect Memory Plus Long Offset Operand 3772 operand indOffset32(any_RegP reg, immL32 off) 3773 %{ 3774 constraint(ALLOC_IN_RC(ptr_reg)); 3775 match(AddP reg off); 3776 3777 format %{ "[$reg + $off (32-bit)]" %} 3778 interface(MEMORY_INTER) %{ 3779 base($reg); 3780 index(0x4); 3781 scale(0x0); 3782 disp($off); 3783 %} 3784 %} 3785 3786 // Indirect Memory Plus Index Register Plus Offset Operand 3787 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3788 %{ 3789 constraint(ALLOC_IN_RC(ptr_reg)); 3790 match(AddP (AddP reg lreg) off); 3791 3792 op_cost(10); 3793 format %{"[$reg + $off + $lreg]" %} 3794 interface(MEMORY_INTER) %{ 3795 base($reg); 3796 index($lreg); 3797 scale(0x0); 3798 disp($off); 3799 %} 3800 %} 3801 3802 // Indirect Memory Plus Index Register Plus Offset Operand 3803 operand indIndex(any_RegP reg, rRegL lreg) 3804 %{ 3805 constraint(ALLOC_IN_RC(ptr_reg)); 3806 match(AddP reg lreg); 3807 3808 op_cost(10); 3809 format %{"[$reg + $lreg]" %} 3810 interface(MEMORY_INTER) %{ 3811 base($reg); 3812 index($lreg); 3813 scale(0x0); 3814 disp(0x0); 3815 %} 3816 %} 3817 3818 // Indirect Memory Times Scale Plus Index Register 3819 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3820 %{ 3821 constraint(ALLOC_IN_RC(ptr_reg)); 3822 match(AddP reg (LShiftL lreg scale)); 3823 3824 op_cost(10); 3825 format %{"[$reg + $lreg << $scale]" %} 3826 interface(MEMORY_INTER) %{ 3827 base($reg); 3828 index($lreg); 3829 scale($scale); 3830 disp(0x0); 3831 %} 3832 %} 3833 3834 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3835 %{ 3836 constraint(ALLOC_IN_RC(ptr_reg)); 3837 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3838 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3839 3840 op_cost(10); 3841 format %{"[$reg + pos $idx << $scale]" %} 3842 interface(MEMORY_INTER) %{ 3843 base($reg); 3844 index($idx); 3845 scale($scale); 3846 disp(0x0); 3847 %} 3848 %} 3849 3850 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3851 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3852 %{ 3853 constraint(ALLOC_IN_RC(ptr_reg)); 3854 match(AddP (AddP reg (LShiftL lreg scale)) off); 3855 3856 op_cost(10); 3857 format %{"[$reg + $off + $lreg << $scale]" %} 3858 interface(MEMORY_INTER) %{ 3859 base($reg); 3860 index($lreg); 3861 scale($scale); 3862 disp($off); 3863 %} 3864 %} 3865 3866 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3867 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3868 %{ 3869 constraint(ALLOC_IN_RC(ptr_reg)); 3870 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3871 match(AddP (AddP reg (ConvI2L idx)) off); 3872 3873 op_cost(10); 3874 format %{"[$reg + $off + $idx]" %} 3875 interface(MEMORY_INTER) %{ 3876 base($reg); 3877 index($idx); 3878 scale(0x0); 3879 disp($off); 3880 %} 3881 %} 3882 3883 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3884 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3885 %{ 3886 constraint(ALLOC_IN_RC(ptr_reg)); 3887 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3888 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3889 3890 op_cost(10); 3891 format %{"[$reg + $off + $idx << $scale]" %} 3892 interface(MEMORY_INTER) %{ 3893 base($reg); 3894 index($idx); 3895 scale($scale); 3896 disp($off); 3897 %} 3898 %} 3899 3900 // Indirect Narrow Oop Plus Offset Operand 3901 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3902 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3903 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3904 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3905 constraint(ALLOC_IN_RC(ptr_reg)); 3906 match(AddP (DecodeN reg) off); 3907 3908 op_cost(10); 3909 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3910 interface(MEMORY_INTER) %{ 3911 base(0xc); // R12 3912 index($reg); 3913 scale(0x3); 3914 disp($off); 3915 %} 3916 %} 3917 3918 // Indirect Memory Operand 3919 operand indirectNarrow(rRegN reg) 3920 %{ 3921 predicate(Universe::narrow_oop_shift() == 0); 3922 constraint(ALLOC_IN_RC(ptr_reg)); 3923 match(DecodeN reg); 3924 3925 format %{ "[$reg]" %} 3926 interface(MEMORY_INTER) %{ 3927 base($reg); 3928 index(0x4); 3929 scale(0x0); 3930 disp(0x0); 3931 %} 3932 %} 3933 3934 // Indirect Memory Plus Short Offset Operand 3935 operand indOffset8Narrow(rRegN reg, immL8 off) 3936 %{ 3937 predicate(Universe::narrow_oop_shift() == 0); 3938 constraint(ALLOC_IN_RC(ptr_reg)); 3939 match(AddP (DecodeN reg) off); 3940 3941 format %{ "[$reg + $off (8-bit)]" %} 3942 interface(MEMORY_INTER) %{ 3943 base($reg); 3944 index(0x4); 3945 scale(0x0); 3946 disp($off); 3947 %} 3948 %} 3949 3950 // Indirect Memory Plus Long Offset Operand 3951 operand indOffset32Narrow(rRegN reg, immL32 off) 3952 %{ 3953 predicate(Universe::narrow_oop_shift() == 0); 3954 constraint(ALLOC_IN_RC(ptr_reg)); 3955 match(AddP (DecodeN reg) off); 3956 3957 format %{ "[$reg + $off (32-bit)]" %} 3958 interface(MEMORY_INTER) %{ 3959 base($reg); 3960 index(0x4); 3961 scale(0x0); 3962 disp($off); 3963 %} 3964 %} 3965 3966 // Indirect Memory Plus Index Register Plus Offset Operand 3967 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3968 %{ 3969 predicate(Universe::narrow_oop_shift() == 0); 3970 constraint(ALLOC_IN_RC(ptr_reg)); 3971 match(AddP (AddP (DecodeN reg) lreg) off); 3972 3973 op_cost(10); 3974 format %{"[$reg + $off + $lreg]" %} 3975 interface(MEMORY_INTER) %{ 3976 base($reg); 3977 index($lreg); 3978 scale(0x0); 3979 disp($off); 3980 %} 3981 %} 3982 3983 // Indirect Memory Plus Index Register Plus Offset Operand 3984 operand indIndexNarrow(rRegN reg, rRegL lreg) 3985 %{ 3986 predicate(Universe::narrow_oop_shift() == 0); 3987 constraint(ALLOC_IN_RC(ptr_reg)); 3988 match(AddP (DecodeN reg) lreg); 3989 3990 op_cost(10); 3991 format %{"[$reg + $lreg]" %} 3992 interface(MEMORY_INTER) %{ 3993 base($reg); 3994 index($lreg); 3995 scale(0x0); 3996 disp(0x0); 3997 %} 3998 %} 3999 4000 // Indirect Memory Times Scale Plus Index Register 4001 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4002 %{ 4003 predicate(Universe::narrow_oop_shift() == 0); 4004 constraint(ALLOC_IN_RC(ptr_reg)); 4005 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4006 4007 op_cost(10); 4008 format %{"[$reg + $lreg << $scale]" %} 4009 interface(MEMORY_INTER) %{ 4010 base($reg); 4011 index($lreg); 4012 scale($scale); 4013 disp(0x0); 4014 %} 4015 %} 4016 4017 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4018 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4019 %{ 4020 predicate(Universe::narrow_oop_shift() == 0); 4021 constraint(ALLOC_IN_RC(ptr_reg)); 4022 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4023 4024 op_cost(10); 4025 format %{"[$reg + $off + $lreg << $scale]" %} 4026 interface(MEMORY_INTER) %{ 4027 base($reg); 4028 index($lreg); 4029 scale($scale); 4030 disp($off); 4031 %} 4032 %} 4033 4034 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4035 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4036 %{ 4037 constraint(ALLOC_IN_RC(ptr_reg)); 4038 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4039 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4040 4041 op_cost(10); 4042 format %{"[$reg + $off + $idx]" %} 4043 interface(MEMORY_INTER) %{ 4044 base($reg); 4045 index($idx); 4046 scale(0x0); 4047 disp($off); 4048 %} 4049 %} 4050 4051 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4052 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4053 %{ 4054 constraint(ALLOC_IN_RC(ptr_reg)); 4055 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4056 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4057 4058 op_cost(10); 4059 format %{"[$reg + $off + $idx << $scale]" %} 4060 interface(MEMORY_INTER) %{ 4061 base($reg); 4062 index($idx); 4063 scale($scale); 4064 disp($off); 4065 %} 4066 %} 4067 4068 //----------Special Memory Operands-------------------------------------------- 4069 // Stack Slot Operand - This operand is used for loading and storing temporary 4070 // values on the stack where a match requires a value to 4071 // flow through memory. 4072 operand stackSlotP(sRegP reg) 4073 %{ 4074 constraint(ALLOC_IN_RC(stack_slots)); 4075 // No match rule because this operand is only generated in matching 4076 4077 format %{ "[$reg]" %} 4078 interface(MEMORY_INTER) %{ 4079 base(0x4); // RSP 4080 index(0x4); // No Index 4081 scale(0x0); // No Scale 4082 disp($reg); // Stack Offset 4083 %} 4084 %} 4085 4086 operand stackSlotI(sRegI reg) 4087 %{ 4088 constraint(ALLOC_IN_RC(stack_slots)); 4089 // No match rule because this operand is only generated in matching 4090 4091 format %{ "[$reg]" %} 4092 interface(MEMORY_INTER) %{ 4093 base(0x4); // RSP 4094 index(0x4); // No Index 4095 scale(0x0); // No Scale 4096 disp($reg); // Stack Offset 4097 %} 4098 %} 4099 4100 operand stackSlotF(sRegF reg) 4101 %{ 4102 constraint(ALLOC_IN_RC(stack_slots)); 4103 // No match rule because this operand is only generated in matching 4104 4105 format %{ "[$reg]" %} 4106 interface(MEMORY_INTER) %{ 4107 base(0x4); // RSP 4108 index(0x4); // No Index 4109 scale(0x0); // No Scale 4110 disp($reg); // Stack Offset 4111 %} 4112 %} 4113 4114 operand stackSlotD(sRegD reg) 4115 %{ 4116 constraint(ALLOC_IN_RC(stack_slots)); 4117 // No match rule because this operand is only generated in matching 4118 4119 format %{ "[$reg]" %} 4120 interface(MEMORY_INTER) %{ 4121 base(0x4); // RSP 4122 index(0x4); // No Index 4123 scale(0x0); // No Scale 4124 disp($reg); // Stack Offset 4125 %} 4126 %} 4127 operand stackSlotL(sRegL reg) 4128 %{ 4129 constraint(ALLOC_IN_RC(stack_slots)); 4130 // No match rule because this operand is only generated in matching 4131 4132 format %{ "[$reg]" %} 4133 interface(MEMORY_INTER) %{ 4134 base(0x4); // RSP 4135 index(0x4); // No Index 4136 scale(0x0); // No Scale 4137 disp($reg); // Stack Offset 4138 %} 4139 %} 4140 4141 //----------Conditional Branch Operands---------------------------------------- 4142 // Comparison Op - This is the operation of the comparison, and is limited to 4143 // the following set of codes: 4144 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4145 // 4146 // Other attributes of the comparison, such as unsignedness, are specified 4147 // by the comparison instruction that sets a condition code flags register. 4148 // That result is represented by a flags operand whose subtype is appropriate 4149 // to the unsignedness (etc.) of the comparison. 4150 // 4151 // Later, the instruction which matches both the Comparison Op (a Bool) and 4152 // the flags (produced by the Cmp) specifies the coding of the comparison op 4153 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4154 4155 // Comparision Code 4156 operand cmpOp() 4157 %{ 4158 match(Bool); 4159 4160 format %{ "" %} 4161 interface(COND_INTER) %{ 4162 equal(0x4, "e"); 4163 not_equal(0x5, "ne"); 4164 less(0xC, "l"); 4165 greater_equal(0xD, "ge"); 4166 less_equal(0xE, "le"); 4167 greater(0xF, "g"); 4168 overflow(0x0, "o"); 4169 no_overflow(0x1, "no"); 4170 %} 4171 %} 4172 4173 // Comparison Code, unsigned compare. Used by FP also, with 4174 // C2 (unordered) turned into GT or LT already. The other bits 4175 // C0 and C3 are turned into Carry & Zero flags. 4176 operand cmpOpU() 4177 %{ 4178 match(Bool); 4179 4180 format %{ "" %} 4181 interface(COND_INTER) %{ 4182 equal(0x4, "e"); 4183 not_equal(0x5, "ne"); 4184 less(0x2, "b"); 4185 greater_equal(0x3, "nb"); 4186 less_equal(0x6, "be"); 4187 greater(0x7, "nbe"); 4188 overflow(0x0, "o"); 4189 no_overflow(0x1, "no"); 4190 %} 4191 %} 4192 4193 4194 // Floating comparisons that don't require any fixup for the unordered case 4195 operand cmpOpUCF() %{ 4196 match(Bool); 4197 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4198 n->as_Bool()->_test._test == BoolTest::ge || 4199 n->as_Bool()->_test._test == BoolTest::le || 4200 n->as_Bool()->_test._test == BoolTest::gt); 4201 format %{ "" %} 4202 interface(COND_INTER) %{ 4203 equal(0x4, "e"); 4204 not_equal(0x5, "ne"); 4205 less(0x2, "b"); 4206 greater_equal(0x3, "nb"); 4207 less_equal(0x6, "be"); 4208 greater(0x7, "nbe"); 4209 overflow(0x0, "o"); 4210 no_overflow(0x1, "no"); 4211 %} 4212 %} 4213 4214 4215 // Floating comparisons that can be fixed up with extra conditional jumps 4216 operand cmpOpUCF2() %{ 4217 match(Bool); 4218 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4219 n->as_Bool()->_test._test == BoolTest::eq); 4220 format %{ "" %} 4221 interface(COND_INTER) %{ 4222 equal(0x4, "e"); 4223 not_equal(0x5, "ne"); 4224 less(0x2, "b"); 4225 greater_equal(0x3, "nb"); 4226 less_equal(0x6, "be"); 4227 greater(0x7, "nbe"); 4228 overflow(0x0, "o"); 4229 no_overflow(0x1, "no"); 4230 %} 4231 %} 4232 4233 // Operands for bound floating pointer register arguments 4234 operand rxmm0() %{ 4235 constraint(ALLOC_IN_RC(xmm0_reg)); match(VecX); 4236 predicate((UseSSE > 0) && (UseAVX<= 2)); format%{%} interface(REG_INTER); 4237 %} 4238 operand rxmm1() %{ 4239 constraint(ALLOC_IN_RC(xmm1_reg)); match(VecX); 4240 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4241 %} 4242 operand rxmm2() %{ 4243 constraint(ALLOC_IN_RC(xmm2_reg)); match(VecX); 4244 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4245 %} 4246 operand rxmm3() %{ 4247 constraint(ALLOC_IN_RC(xmm3_reg)); match(VecX); 4248 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4249 %} 4250 operand rxmm4() %{ 4251 constraint(ALLOC_IN_RC(xmm4_reg)); match(VecX); 4252 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4253 %} 4254 operand rxmm5() %{ 4255 constraint(ALLOC_IN_RC(xmm5_reg)); match(VecX); 4256 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4257 %} 4258 operand rxmm6() %{ 4259 constraint(ALLOC_IN_RC(xmm6_reg)); match(VecX); 4260 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4261 %} 4262 operand rxmm7() %{ 4263 constraint(ALLOC_IN_RC(xmm7_reg)); match(VecX); 4264 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4265 %} 4266 operand rxmm8() %{ 4267 constraint(ALLOC_IN_RC(xmm8_reg)); match(VecX); 4268 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4269 %} 4270 operand rxmm9() %{ 4271 constraint(ALLOC_IN_RC(xmm9_reg)); match(VecX); 4272 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4273 %} 4274 operand rxmm10() %{ 4275 constraint(ALLOC_IN_RC(xmm10_reg)); match(VecX); 4276 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4277 %} 4278 operand rxmm11() %{ 4279 constraint(ALLOC_IN_RC(xmm11_reg)); match(VecX); 4280 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4281 %} 4282 operand rxmm12() %{ 4283 constraint(ALLOC_IN_RC(xmm12_reg)); match(VecX); 4284 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4285 %} 4286 operand rxmm13() %{ 4287 constraint(ALLOC_IN_RC(xmm13_reg)); match(VecX); 4288 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4289 %} 4290 operand rxmm14() %{ 4291 constraint(ALLOC_IN_RC(xmm14_reg)); match(VecX); 4292 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4293 %} 4294 operand rxmm15() %{ 4295 constraint(ALLOC_IN_RC(xmm15_reg)); match(VecX); 4296 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4297 %} 4298 operand rxmm16() %{ 4299 constraint(ALLOC_IN_RC(xmm16_reg)); match(VecX); 4300 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4301 %} 4302 operand rxmm17() %{ 4303 constraint(ALLOC_IN_RC(xmm17_reg)); match(VecX); 4304 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4305 %} 4306 operand rxmm18() %{ 4307 constraint(ALLOC_IN_RC(xmm18_reg)); match(VecX); 4308 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4309 %} 4310 operand rxmm19() %{ 4311 constraint(ALLOC_IN_RC(xmm19_reg)); match(VecX); 4312 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4313 %} 4314 operand rxmm20() %{ 4315 constraint(ALLOC_IN_RC(xmm20_reg)); match(VecX); 4316 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4317 %} 4318 operand rxmm21() %{ 4319 constraint(ALLOC_IN_RC(xmm21_reg)); match(VecX); 4320 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4321 %} 4322 operand rxmm22() %{ 4323 constraint(ALLOC_IN_RC(xmm22_reg)); match(VecX); 4324 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4325 %} 4326 operand rxmm23() %{ 4327 constraint(ALLOC_IN_RC(xmm23_reg)); match(VecX); 4328 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4329 %} 4330 operand rxmm24() %{ 4331 constraint(ALLOC_IN_RC(xmm24_reg)); match(VecX); 4332 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4333 %} 4334 operand rxmm25() %{ 4335 constraint(ALLOC_IN_RC(xmm25_reg)); match(VecX); 4336 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4337 %} 4338 operand rxmm26() %{ 4339 constraint(ALLOC_IN_RC(xmm26_reg)); match(VecX); 4340 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4341 %} 4342 operand rxmm27() %{ 4343 constraint(ALLOC_IN_RC(xmm27_reg)); match(VecX); 4344 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4345 %} 4346 operand rxmm28() %{ 4347 constraint(ALLOC_IN_RC(xmm28_reg)); match(VecX); 4348 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4349 %} 4350 operand rxmm29() %{ 4351 constraint(ALLOC_IN_RC(xmm29_reg)); match(VecX); 4352 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4353 %} 4354 operand rxmm30() %{ 4355 constraint(ALLOC_IN_RC(xmm30_reg)); match(VecX); 4356 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4357 %} 4358 operand rxmm31() %{ 4359 constraint(ALLOC_IN_RC(xmm31_reg)); match(VecX); 4360 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4361 %} 4362 4363 //----------OPERAND CLASSES---------------------------------------------------- 4364 // Operand Classes are groups of operands that are used as to simplify 4365 // instruction definitions by not requiring the AD writer to specify separate 4366 // instructions for every form of operand when the instruction accepts 4367 // multiple operand types with the same basic encoding and format. The classic 4368 // case of this is memory operands. 4369 4370 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4371 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4372 indCompressedOopOffset, 4373 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4374 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4375 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4376 4377 //----------PIPELINE----------------------------------------------------------- 4378 // Rules which define the behavior of the target architectures pipeline. 4379 pipeline %{ 4380 4381 //----------ATTRIBUTES--------------------------------------------------------- 4382 attributes %{ 4383 variable_size_instructions; // Fixed size instructions 4384 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4385 instruction_unit_size = 1; // An instruction is 1 bytes long 4386 instruction_fetch_unit_size = 16; // The processor fetches one line 4387 instruction_fetch_units = 1; // of 16 bytes 4388 4389 // List of nop instructions 4390 nops( MachNop ); 4391 %} 4392 4393 //----------RESOURCES---------------------------------------------------------- 4394 // Resources are the functional units available to the machine 4395 4396 // Generic P2/P3 pipeline 4397 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4398 // 3 instructions decoded per cycle. 4399 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4400 // 3 ALU op, only ALU0 handles mul instructions. 4401 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4402 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4403 BR, FPU, 4404 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4405 4406 //----------PIPELINE DESCRIPTION----------------------------------------------- 4407 // Pipeline Description specifies the stages in the machine's pipeline 4408 4409 // Generic P2/P3 pipeline 4410 pipe_desc(S0, S1, S2, S3, S4, S5); 4411 4412 //----------PIPELINE CLASSES--------------------------------------------------- 4413 // Pipeline Classes describe the stages in which input and output are 4414 // referenced by the hardware pipeline. 4415 4416 // Naming convention: ialu or fpu 4417 // Then: _reg 4418 // Then: _reg if there is a 2nd register 4419 // Then: _long if it's a pair of instructions implementing a long 4420 // Then: _fat if it requires the big decoder 4421 // Or: _mem if it requires the big decoder and a memory unit. 4422 4423 // Integer ALU reg operation 4424 pipe_class ialu_reg(rRegI dst) 4425 %{ 4426 single_instruction; 4427 dst : S4(write); 4428 dst : S3(read); 4429 DECODE : S0; // any decoder 4430 ALU : S3; // any alu 4431 %} 4432 4433 // Long ALU reg operation 4434 pipe_class ialu_reg_long(rRegL dst) 4435 %{ 4436 instruction_count(2); 4437 dst : S4(write); 4438 dst : S3(read); 4439 DECODE : S0(2); // any 2 decoders 4440 ALU : S3(2); // both alus 4441 %} 4442 4443 // Integer ALU reg operation using big decoder 4444 pipe_class ialu_reg_fat(rRegI dst) 4445 %{ 4446 single_instruction; 4447 dst : S4(write); 4448 dst : S3(read); 4449 D0 : S0; // big decoder only 4450 ALU : S3; // any alu 4451 %} 4452 4453 // Long ALU reg operation using big decoder 4454 pipe_class ialu_reg_long_fat(rRegL dst) 4455 %{ 4456 instruction_count(2); 4457 dst : S4(write); 4458 dst : S3(read); 4459 D0 : S0(2); // big decoder only; twice 4460 ALU : S3(2); // any 2 alus 4461 %} 4462 4463 // Integer ALU reg-reg operation 4464 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4465 %{ 4466 single_instruction; 4467 dst : S4(write); 4468 src : S3(read); 4469 DECODE : S0; // any decoder 4470 ALU : S3; // any alu 4471 %} 4472 4473 // Long ALU reg-reg operation 4474 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4475 %{ 4476 instruction_count(2); 4477 dst : S4(write); 4478 src : S3(read); 4479 DECODE : S0(2); // any 2 decoders 4480 ALU : S3(2); // both alus 4481 %} 4482 4483 // Integer ALU reg-reg operation 4484 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4485 %{ 4486 single_instruction; 4487 dst : S4(write); 4488 src : S3(read); 4489 D0 : S0; // big decoder only 4490 ALU : S3; // any alu 4491 %} 4492 4493 // Long ALU reg-reg operation 4494 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4495 %{ 4496 instruction_count(2); 4497 dst : S4(write); 4498 src : S3(read); 4499 D0 : S0(2); // big decoder only; twice 4500 ALU : S3(2); // both alus 4501 %} 4502 4503 // Integer ALU reg-mem operation 4504 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4505 %{ 4506 single_instruction; 4507 dst : S5(write); 4508 mem : S3(read); 4509 D0 : S0; // big decoder only 4510 ALU : S4; // any alu 4511 MEM : S3; // any mem 4512 %} 4513 4514 // Integer mem operation (prefetch) 4515 pipe_class ialu_mem(memory mem) 4516 %{ 4517 single_instruction; 4518 mem : S3(read); 4519 D0 : S0; // big decoder only 4520 MEM : S3; // any mem 4521 %} 4522 4523 // Integer Store to Memory 4524 pipe_class ialu_mem_reg(memory mem, rRegI src) 4525 %{ 4526 single_instruction; 4527 mem : S3(read); 4528 src : S5(read); 4529 D0 : S0; // big decoder only 4530 ALU : S4; // any alu 4531 MEM : S3; 4532 %} 4533 4534 // // Long Store to Memory 4535 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4536 // %{ 4537 // instruction_count(2); 4538 // mem : S3(read); 4539 // src : S5(read); 4540 // D0 : S0(2); // big decoder only; twice 4541 // ALU : S4(2); // any 2 alus 4542 // MEM : S3(2); // Both mems 4543 // %} 4544 4545 // Integer Store to Memory 4546 pipe_class ialu_mem_imm(memory mem) 4547 %{ 4548 single_instruction; 4549 mem : S3(read); 4550 D0 : S0; // big decoder only 4551 ALU : S4; // any alu 4552 MEM : S3; 4553 %} 4554 4555 // Integer ALU0 reg-reg operation 4556 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4557 %{ 4558 single_instruction; 4559 dst : S4(write); 4560 src : S3(read); 4561 D0 : S0; // Big decoder only 4562 ALU0 : S3; // only alu0 4563 %} 4564 4565 // Integer ALU0 reg-mem operation 4566 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4567 %{ 4568 single_instruction; 4569 dst : S5(write); 4570 mem : S3(read); 4571 D0 : S0; // big decoder only 4572 ALU0 : S4; // ALU0 only 4573 MEM : S3; // any mem 4574 %} 4575 4576 // Integer ALU reg-reg operation 4577 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4578 %{ 4579 single_instruction; 4580 cr : S4(write); 4581 src1 : S3(read); 4582 src2 : S3(read); 4583 DECODE : S0; // any decoder 4584 ALU : S3; // any alu 4585 %} 4586 4587 // Integer ALU reg-imm operation 4588 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4589 %{ 4590 single_instruction; 4591 cr : S4(write); 4592 src1 : S3(read); 4593 DECODE : S0; // any decoder 4594 ALU : S3; // any alu 4595 %} 4596 4597 // Integer ALU reg-mem operation 4598 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4599 %{ 4600 single_instruction; 4601 cr : S4(write); 4602 src1 : S3(read); 4603 src2 : S3(read); 4604 D0 : S0; // big decoder only 4605 ALU : S4; // any alu 4606 MEM : S3; 4607 %} 4608 4609 // Conditional move reg-reg 4610 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4611 %{ 4612 instruction_count(4); 4613 y : S4(read); 4614 q : S3(read); 4615 p : S3(read); 4616 DECODE : S0(4); // any decoder 4617 %} 4618 4619 // Conditional move reg-reg 4620 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4621 %{ 4622 single_instruction; 4623 dst : S4(write); 4624 src : S3(read); 4625 cr : S3(read); 4626 DECODE : S0; // any decoder 4627 %} 4628 4629 // Conditional move reg-mem 4630 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4631 %{ 4632 single_instruction; 4633 dst : S4(write); 4634 src : S3(read); 4635 cr : S3(read); 4636 DECODE : S0; // any decoder 4637 MEM : S3; 4638 %} 4639 4640 // Conditional move reg-reg long 4641 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4642 %{ 4643 single_instruction; 4644 dst : S4(write); 4645 src : S3(read); 4646 cr : S3(read); 4647 DECODE : S0(2); // any 2 decoders 4648 %} 4649 4650 // XXX 4651 // // Conditional move double reg-reg 4652 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4653 // %{ 4654 // single_instruction; 4655 // dst : S4(write); 4656 // src : S3(read); 4657 // cr : S3(read); 4658 // DECODE : S0; // any decoder 4659 // %} 4660 4661 // Float reg-reg operation 4662 pipe_class fpu_reg(regD dst) 4663 %{ 4664 instruction_count(2); 4665 dst : S3(read); 4666 DECODE : S0(2); // any 2 decoders 4667 FPU : S3; 4668 %} 4669 4670 // Float reg-reg operation 4671 pipe_class fpu_reg_reg(regD dst, regD src) 4672 %{ 4673 instruction_count(2); 4674 dst : S4(write); 4675 src : S3(read); 4676 DECODE : S0(2); // any 2 decoders 4677 FPU : S3; 4678 %} 4679 4680 // Float reg-reg operation 4681 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4682 %{ 4683 instruction_count(3); 4684 dst : S4(write); 4685 src1 : S3(read); 4686 src2 : S3(read); 4687 DECODE : S0(3); // any 3 decoders 4688 FPU : S3(2); 4689 %} 4690 4691 // Float reg-reg operation 4692 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4693 %{ 4694 instruction_count(4); 4695 dst : S4(write); 4696 src1 : S3(read); 4697 src2 : S3(read); 4698 src3 : S3(read); 4699 DECODE : S0(4); // any 3 decoders 4700 FPU : S3(2); 4701 %} 4702 4703 // Float reg-reg operation 4704 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4705 %{ 4706 instruction_count(4); 4707 dst : S4(write); 4708 src1 : S3(read); 4709 src2 : S3(read); 4710 src3 : S3(read); 4711 DECODE : S1(3); // any 3 decoders 4712 D0 : S0; // Big decoder only 4713 FPU : S3(2); 4714 MEM : S3; 4715 %} 4716 4717 // Float reg-mem operation 4718 pipe_class fpu_reg_mem(regD dst, memory mem) 4719 %{ 4720 instruction_count(2); 4721 dst : S5(write); 4722 mem : S3(read); 4723 D0 : S0; // big decoder only 4724 DECODE : S1; // any decoder for FPU POP 4725 FPU : S4; 4726 MEM : S3; // any mem 4727 %} 4728 4729 // Float reg-mem operation 4730 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4731 %{ 4732 instruction_count(3); 4733 dst : S5(write); 4734 src1 : S3(read); 4735 mem : S3(read); 4736 D0 : S0; // big decoder only 4737 DECODE : S1(2); // any decoder for FPU POP 4738 FPU : S4; 4739 MEM : S3; // any mem 4740 %} 4741 4742 // Float mem-reg operation 4743 pipe_class fpu_mem_reg(memory mem, regD src) 4744 %{ 4745 instruction_count(2); 4746 src : S5(read); 4747 mem : S3(read); 4748 DECODE : S0; // any decoder for FPU PUSH 4749 D0 : S1; // big decoder only 4750 FPU : S4; 4751 MEM : S3; // any mem 4752 %} 4753 4754 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4755 %{ 4756 instruction_count(3); 4757 src1 : S3(read); 4758 src2 : S3(read); 4759 mem : S3(read); 4760 DECODE : S0(2); // any decoder for FPU PUSH 4761 D0 : S1; // big decoder only 4762 FPU : S4; 4763 MEM : S3; // any mem 4764 %} 4765 4766 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4767 %{ 4768 instruction_count(3); 4769 src1 : S3(read); 4770 src2 : S3(read); 4771 mem : S4(read); 4772 DECODE : S0; // any decoder for FPU PUSH 4773 D0 : S0(2); // big decoder only 4774 FPU : S4; 4775 MEM : S3(2); // any mem 4776 %} 4777 4778 pipe_class fpu_mem_mem(memory dst, memory src1) 4779 %{ 4780 instruction_count(2); 4781 src1 : S3(read); 4782 dst : S4(read); 4783 D0 : S0(2); // big decoder only 4784 MEM : S3(2); // any mem 4785 %} 4786 4787 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4788 %{ 4789 instruction_count(3); 4790 src1 : S3(read); 4791 src2 : S3(read); 4792 dst : S4(read); 4793 D0 : S0(3); // big decoder only 4794 FPU : S4; 4795 MEM : S3(3); // any mem 4796 %} 4797 4798 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4799 %{ 4800 instruction_count(3); 4801 src1 : S4(read); 4802 mem : S4(read); 4803 DECODE : S0; // any decoder for FPU PUSH 4804 D0 : S0(2); // big decoder only 4805 FPU : S4; 4806 MEM : S3(2); // any mem 4807 %} 4808 4809 // Float load constant 4810 pipe_class fpu_reg_con(regD dst) 4811 %{ 4812 instruction_count(2); 4813 dst : S5(write); 4814 D0 : S0; // big decoder only for the load 4815 DECODE : S1; // any decoder for FPU POP 4816 FPU : S4; 4817 MEM : S3; // any mem 4818 %} 4819 4820 // Float load constant 4821 pipe_class fpu_reg_reg_con(regD dst, regD src) 4822 %{ 4823 instruction_count(3); 4824 dst : S5(write); 4825 src : S3(read); 4826 D0 : S0; // big decoder only for the load 4827 DECODE : S1(2); // any decoder for FPU POP 4828 FPU : S4; 4829 MEM : S3; // any mem 4830 %} 4831 4832 // UnConditional branch 4833 pipe_class pipe_jmp(label labl) 4834 %{ 4835 single_instruction; 4836 BR : S3; 4837 %} 4838 4839 // Conditional branch 4840 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4841 %{ 4842 single_instruction; 4843 cr : S1(read); 4844 BR : S3; 4845 %} 4846 4847 // Allocation idiom 4848 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4849 %{ 4850 instruction_count(1); force_serialization; 4851 fixed_latency(6); 4852 heap_ptr : S3(read); 4853 DECODE : S0(3); 4854 D0 : S2; 4855 MEM : S3; 4856 ALU : S3(2); 4857 dst : S5(write); 4858 BR : S5; 4859 %} 4860 4861 // Generic big/slow expanded idiom 4862 pipe_class pipe_slow() 4863 %{ 4864 instruction_count(10); multiple_bundles; force_serialization; 4865 fixed_latency(100); 4866 D0 : S0(2); 4867 MEM : S3(2); 4868 %} 4869 4870 // The real do-nothing guy 4871 pipe_class empty() 4872 %{ 4873 instruction_count(0); 4874 %} 4875 4876 // Define the class for the Nop node 4877 define 4878 %{ 4879 MachNop = empty; 4880 %} 4881 4882 %} 4883 4884 //----------INSTRUCTIONS------------------------------------------------------- 4885 // 4886 // match -- States which machine-independent subtree may be replaced 4887 // by this instruction. 4888 // ins_cost -- The estimated cost of this instruction is used by instruction 4889 // selection to identify a minimum cost tree of machine 4890 // instructions that matches a tree of machine-independent 4891 // instructions. 4892 // format -- A string providing the disassembly for this instruction. 4893 // The value of an instruction's operand may be inserted 4894 // by referring to it with a '$' prefix. 4895 // opcode -- Three instruction opcodes may be provided. These are referred 4896 // to within an encode class as $primary, $secondary, and $tertiary 4897 // rrspectively. The primary opcode is commonly used to 4898 // indicate the type of machine instruction, while secondary 4899 // and tertiary are often used for prefix options or addressing 4900 // modes. 4901 // ins_encode -- A list of encode classes with parameters. The encode class 4902 // name must have been defined in an 'enc_class' specification 4903 // in the encode section of the architecture description. 4904 4905 4906 //----------Load/Store/Move Instructions--------------------------------------- 4907 //----------Load Instructions-------------------------------------------------- 4908 4909 // Load Byte (8 bit signed) 4910 instruct loadB(rRegI dst, memory mem) 4911 %{ 4912 match(Set dst (LoadB mem)); 4913 4914 ins_cost(125); 4915 format %{ "movsbl $dst, $mem\t# byte" %} 4916 4917 ins_encode %{ 4918 __ movsbl($dst$$Register, $mem$$Address); 4919 %} 4920 4921 ins_pipe(ialu_reg_mem); 4922 %} 4923 4924 // Load Byte (8 bit signed) into Long Register 4925 instruct loadB2L(rRegL dst, memory mem) 4926 %{ 4927 match(Set dst (ConvI2L (LoadB mem))); 4928 4929 ins_cost(125); 4930 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4931 4932 ins_encode %{ 4933 __ movsbq($dst$$Register, $mem$$Address); 4934 %} 4935 4936 ins_pipe(ialu_reg_mem); 4937 %} 4938 4939 // Load Unsigned Byte (8 bit UNsigned) 4940 instruct loadUB(rRegI dst, memory mem) 4941 %{ 4942 match(Set dst (LoadUB mem)); 4943 4944 ins_cost(125); 4945 format %{ "movzbl $dst, $mem\t# ubyte" %} 4946 4947 ins_encode %{ 4948 __ movzbl($dst$$Register, $mem$$Address); 4949 %} 4950 4951 ins_pipe(ialu_reg_mem); 4952 %} 4953 4954 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4955 instruct loadUB2L(rRegL dst, memory mem) 4956 %{ 4957 match(Set dst (ConvI2L (LoadUB mem))); 4958 4959 ins_cost(125); 4960 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4961 4962 ins_encode %{ 4963 __ movzbq($dst$$Register, $mem$$Address); 4964 %} 4965 4966 ins_pipe(ialu_reg_mem); 4967 %} 4968 4969 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4970 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4971 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4972 effect(KILL cr); 4973 4974 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4975 "andl $dst, right_n_bits($mask, 8)" %} 4976 ins_encode %{ 4977 Register Rdst = $dst$$Register; 4978 __ movzbq(Rdst, $mem$$Address); 4979 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4980 %} 4981 ins_pipe(ialu_reg_mem); 4982 %} 4983 4984 // Load Short (16 bit signed) 4985 instruct loadS(rRegI dst, memory mem) 4986 %{ 4987 match(Set dst (LoadS mem)); 4988 4989 ins_cost(125); 4990 format %{ "movswl $dst, $mem\t# short" %} 4991 4992 ins_encode %{ 4993 __ movswl($dst$$Register, $mem$$Address); 4994 %} 4995 4996 ins_pipe(ialu_reg_mem); 4997 %} 4998 4999 // Load Short (16 bit signed) to Byte (8 bit signed) 5000 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5001 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5002 5003 ins_cost(125); 5004 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5005 ins_encode %{ 5006 __ movsbl($dst$$Register, $mem$$Address); 5007 %} 5008 ins_pipe(ialu_reg_mem); 5009 %} 5010 5011 // Load Short (16 bit signed) into Long Register 5012 instruct loadS2L(rRegL dst, memory mem) 5013 %{ 5014 match(Set dst (ConvI2L (LoadS mem))); 5015 5016 ins_cost(125); 5017 format %{ "movswq $dst, $mem\t# short -> long" %} 5018 5019 ins_encode %{ 5020 __ movswq($dst$$Register, $mem$$Address); 5021 %} 5022 5023 ins_pipe(ialu_reg_mem); 5024 %} 5025 5026 // Load Unsigned Short/Char (16 bit UNsigned) 5027 instruct loadUS(rRegI dst, memory mem) 5028 %{ 5029 match(Set dst (LoadUS mem)); 5030 5031 ins_cost(125); 5032 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5033 5034 ins_encode %{ 5035 __ movzwl($dst$$Register, $mem$$Address); 5036 %} 5037 5038 ins_pipe(ialu_reg_mem); 5039 %} 5040 5041 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5042 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5043 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5044 5045 ins_cost(125); 5046 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5047 ins_encode %{ 5048 __ movsbl($dst$$Register, $mem$$Address); 5049 %} 5050 ins_pipe(ialu_reg_mem); 5051 %} 5052 5053 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5054 instruct loadUS2L(rRegL dst, memory mem) 5055 %{ 5056 match(Set dst (ConvI2L (LoadUS mem))); 5057 5058 ins_cost(125); 5059 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5060 5061 ins_encode %{ 5062 __ movzwq($dst$$Register, $mem$$Address); 5063 %} 5064 5065 ins_pipe(ialu_reg_mem); 5066 %} 5067 5068 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5069 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5070 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5071 5072 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5073 ins_encode %{ 5074 __ movzbq($dst$$Register, $mem$$Address); 5075 %} 5076 ins_pipe(ialu_reg_mem); 5077 %} 5078 5079 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 5080 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5081 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5082 effect(KILL cr); 5083 5084 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 5085 "andl $dst, right_n_bits($mask, 16)" %} 5086 ins_encode %{ 5087 Register Rdst = $dst$$Register; 5088 __ movzwq(Rdst, $mem$$Address); 5089 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 5090 %} 5091 ins_pipe(ialu_reg_mem); 5092 %} 5093 5094 // Load Integer 5095 instruct loadI(rRegI dst, memory mem) 5096 %{ 5097 match(Set dst (LoadI mem)); 5098 5099 ins_cost(125); 5100 format %{ "movl $dst, $mem\t# int" %} 5101 5102 ins_encode %{ 5103 __ movl($dst$$Register, $mem$$Address); 5104 %} 5105 5106 ins_pipe(ialu_reg_mem); 5107 %} 5108 5109 // Load Integer (32 bit signed) to Byte (8 bit signed) 5110 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5111 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5112 5113 ins_cost(125); 5114 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5115 ins_encode %{ 5116 __ movsbl($dst$$Register, $mem$$Address); 5117 %} 5118 ins_pipe(ialu_reg_mem); 5119 %} 5120 5121 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5122 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5123 match(Set dst (AndI (LoadI mem) mask)); 5124 5125 ins_cost(125); 5126 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5127 ins_encode %{ 5128 __ movzbl($dst$$Register, $mem$$Address); 5129 %} 5130 ins_pipe(ialu_reg_mem); 5131 %} 5132 5133 // Load Integer (32 bit signed) to Short (16 bit signed) 5134 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5135 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5136 5137 ins_cost(125); 5138 format %{ "movswl $dst, $mem\t# int -> short" %} 5139 ins_encode %{ 5140 __ movswl($dst$$Register, $mem$$Address); 5141 %} 5142 ins_pipe(ialu_reg_mem); 5143 %} 5144 5145 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5146 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5147 match(Set dst (AndI (LoadI mem) mask)); 5148 5149 ins_cost(125); 5150 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5151 ins_encode %{ 5152 __ movzwl($dst$$Register, $mem$$Address); 5153 %} 5154 ins_pipe(ialu_reg_mem); 5155 %} 5156 5157 // Load Integer into Long Register 5158 instruct loadI2L(rRegL dst, memory mem) 5159 %{ 5160 match(Set dst (ConvI2L (LoadI mem))); 5161 5162 ins_cost(125); 5163 format %{ "movslq $dst, $mem\t# int -> long" %} 5164 5165 ins_encode %{ 5166 __ movslq($dst$$Register, $mem$$Address); 5167 %} 5168 5169 ins_pipe(ialu_reg_mem); 5170 %} 5171 5172 // Load Integer with mask 0xFF into Long Register 5173 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5174 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5175 5176 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5177 ins_encode %{ 5178 __ movzbq($dst$$Register, $mem$$Address); 5179 %} 5180 ins_pipe(ialu_reg_mem); 5181 %} 5182 5183 // Load Integer with mask 0xFFFF into Long Register 5184 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5185 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5186 5187 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5188 ins_encode %{ 5189 __ movzwq($dst$$Register, $mem$$Address); 5190 %} 5191 ins_pipe(ialu_reg_mem); 5192 %} 5193 5194 // Load Integer with a 31-bit mask into Long Register 5195 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5196 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5197 effect(KILL cr); 5198 5199 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5200 "andl $dst, $mask" %} 5201 ins_encode %{ 5202 Register Rdst = $dst$$Register; 5203 __ movl(Rdst, $mem$$Address); 5204 __ andl(Rdst, $mask$$constant); 5205 %} 5206 ins_pipe(ialu_reg_mem); 5207 %} 5208 5209 // Load Unsigned Integer into Long Register 5210 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5211 %{ 5212 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5213 5214 ins_cost(125); 5215 format %{ "movl $dst, $mem\t# uint -> long" %} 5216 5217 ins_encode %{ 5218 __ movl($dst$$Register, $mem$$Address); 5219 %} 5220 5221 ins_pipe(ialu_reg_mem); 5222 %} 5223 5224 // Load Long 5225 instruct loadL(rRegL dst, memory mem) 5226 %{ 5227 match(Set dst (LoadL mem)); 5228 5229 ins_cost(125); 5230 format %{ "movq $dst, $mem\t# long" %} 5231 5232 ins_encode %{ 5233 __ movq($dst$$Register, $mem$$Address); 5234 %} 5235 5236 ins_pipe(ialu_reg_mem); // XXX 5237 %} 5238 5239 // Load Range 5240 instruct loadRange(rRegI dst, memory mem) 5241 %{ 5242 match(Set dst (LoadRange mem)); 5243 5244 ins_cost(125); // XXX 5245 format %{ "movl $dst, $mem\t# range" %} 5246 opcode(0x8B); 5247 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5248 ins_pipe(ialu_reg_mem); 5249 %} 5250 5251 // Load Pointer 5252 instruct loadP(rRegP dst, memory mem) 5253 %{ 5254 match(Set dst (LoadP mem)); 5255 5256 ins_cost(125); // XXX 5257 format %{ "movq $dst, $mem\t# ptr" %} 5258 opcode(0x8B); 5259 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5260 ins_pipe(ialu_reg_mem); // XXX 5261 %} 5262 5263 // Load Compressed Pointer 5264 instruct loadN(rRegN dst, memory mem) 5265 %{ 5266 match(Set dst (LoadN mem)); 5267 5268 ins_cost(125); // XXX 5269 format %{ "movl $dst, $mem\t# compressed ptr" %} 5270 ins_encode %{ 5271 __ movl($dst$$Register, $mem$$Address); 5272 %} 5273 ins_pipe(ialu_reg_mem); // XXX 5274 %} 5275 5276 5277 // Load Klass Pointer 5278 instruct loadKlass(rRegP dst, memory mem) 5279 %{ 5280 match(Set dst (LoadKlass mem)); 5281 5282 ins_cost(125); // XXX 5283 format %{ "movq $dst, $mem\t# class" %} 5284 opcode(0x8B); 5285 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5286 ins_pipe(ialu_reg_mem); // XXX 5287 %} 5288 5289 // Load narrow Klass Pointer 5290 instruct loadNKlass(rRegN dst, memory mem) 5291 %{ 5292 match(Set dst (LoadNKlass mem)); 5293 5294 ins_cost(125); // XXX 5295 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5296 ins_encode %{ 5297 __ movl($dst$$Register, $mem$$Address); 5298 %} 5299 ins_pipe(ialu_reg_mem); // XXX 5300 %} 5301 5302 // Load Float 5303 instruct loadF(regF dst, memory mem) 5304 %{ 5305 match(Set dst (LoadF mem)); 5306 5307 ins_cost(145); // XXX 5308 format %{ "movss $dst, $mem\t# float" %} 5309 ins_encode %{ 5310 __ movflt($dst$$XMMRegister, $mem$$Address); 5311 %} 5312 ins_pipe(pipe_slow); // XXX 5313 %} 5314 5315 // Load Double 5316 instruct loadD_partial(regD dst, memory mem) 5317 %{ 5318 predicate(!UseXmmLoadAndClearUpper); 5319 match(Set dst (LoadD mem)); 5320 5321 ins_cost(145); // XXX 5322 format %{ "movlpd $dst, $mem\t# double" %} 5323 ins_encode %{ 5324 __ movdbl($dst$$XMMRegister, $mem$$Address); 5325 %} 5326 ins_pipe(pipe_slow); // XXX 5327 %} 5328 5329 instruct loadD(regD dst, memory mem) 5330 %{ 5331 predicate(UseXmmLoadAndClearUpper); 5332 match(Set dst (LoadD mem)); 5333 5334 ins_cost(145); // XXX 5335 format %{ "movsd $dst, $mem\t# double" %} 5336 ins_encode %{ 5337 __ movdbl($dst$$XMMRegister, $mem$$Address); 5338 %} 5339 ins_pipe(pipe_slow); // XXX 5340 %} 5341 5342 // Load Effective Address 5343 instruct leaP8(rRegP dst, indOffset8 mem) 5344 %{ 5345 match(Set dst mem); 5346 5347 ins_cost(110); // XXX 5348 format %{ "leaq $dst, $mem\t# ptr 8" %} 5349 opcode(0x8D); 5350 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5351 ins_pipe(ialu_reg_reg_fat); 5352 %} 5353 5354 instruct leaP32(rRegP dst, indOffset32 mem) 5355 %{ 5356 match(Set dst mem); 5357 5358 ins_cost(110); 5359 format %{ "leaq $dst, $mem\t# ptr 32" %} 5360 opcode(0x8D); 5361 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5362 ins_pipe(ialu_reg_reg_fat); 5363 %} 5364 5365 // instruct leaPIdx(rRegP dst, indIndex mem) 5366 // %{ 5367 // match(Set dst mem); 5368 5369 // ins_cost(110); 5370 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5371 // opcode(0x8D); 5372 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5373 // ins_pipe(ialu_reg_reg_fat); 5374 // %} 5375 5376 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5377 %{ 5378 match(Set dst mem); 5379 5380 ins_cost(110); 5381 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5382 opcode(0x8D); 5383 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5384 ins_pipe(ialu_reg_reg_fat); 5385 %} 5386 5387 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5388 %{ 5389 match(Set dst mem); 5390 5391 ins_cost(110); 5392 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5393 opcode(0x8D); 5394 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5395 ins_pipe(ialu_reg_reg_fat); 5396 %} 5397 5398 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5399 %{ 5400 match(Set dst mem); 5401 5402 ins_cost(110); 5403 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5404 opcode(0x8D); 5405 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5406 ins_pipe(ialu_reg_reg_fat); 5407 %} 5408 5409 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5410 %{ 5411 match(Set dst mem); 5412 5413 ins_cost(110); 5414 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5415 opcode(0x8D); 5416 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5417 ins_pipe(ialu_reg_reg_fat); 5418 %} 5419 5420 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5421 %{ 5422 match(Set dst mem); 5423 5424 ins_cost(110); 5425 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5426 opcode(0x8D); 5427 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5428 ins_pipe(ialu_reg_reg_fat); 5429 %} 5430 5431 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5432 %{ 5433 match(Set dst mem); 5434 5435 ins_cost(110); 5436 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5437 opcode(0x8D); 5438 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5439 ins_pipe(ialu_reg_reg_fat); 5440 %} 5441 5442 // Load Effective Address which uses Narrow (32-bits) oop 5443 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5444 %{ 5445 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5446 match(Set dst mem); 5447 5448 ins_cost(110); 5449 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5450 opcode(0x8D); 5451 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5452 ins_pipe(ialu_reg_reg_fat); 5453 %} 5454 5455 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5456 %{ 5457 predicate(Universe::narrow_oop_shift() == 0); 5458 match(Set dst mem); 5459 5460 ins_cost(110); // XXX 5461 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5462 opcode(0x8D); 5463 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5464 ins_pipe(ialu_reg_reg_fat); 5465 %} 5466 5467 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5468 %{ 5469 predicate(Universe::narrow_oop_shift() == 0); 5470 match(Set dst mem); 5471 5472 ins_cost(110); 5473 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5474 opcode(0x8D); 5475 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5476 ins_pipe(ialu_reg_reg_fat); 5477 %} 5478 5479 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5480 %{ 5481 predicate(Universe::narrow_oop_shift() == 0); 5482 match(Set dst mem); 5483 5484 ins_cost(110); 5485 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5486 opcode(0x8D); 5487 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5488 ins_pipe(ialu_reg_reg_fat); 5489 %} 5490 5491 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5492 %{ 5493 predicate(Universe::narrow_oop_shift() == 0); 5494 match(Set dst mem); 5495 5496 ins_cost(110); 5497 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5498 opcode(0x8D); 5499 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5500 ins_pipe(ialu_reg_reg_fat); 5501 %} 5502 5503 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5504 %{ 5505 predicate(Universe::narrow_oop_shift() == 0); 5506 match(Set dst mem); 5507 5508 ins_cost(110); 5509 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5510 opcode(0x8D); 5511 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5512 ins_pipe(ialu_reg_reg_fat); 5513 %} 5514 5515 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5516 %{ 5517 predicate(Universe::narrow_oop_shift() == 0); 5518 match(Set dst mem); 5519 5520 ins_cost(110); 5521 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5522 opcode(0x8D); 5523 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5524 ins_pipe(ialu_reg_reg_fat); 5525 %} 5526 5527 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5528 %{ 5529 predicate(Universe::narrow_oop_shift() == 0); 5530 match(Set dst mem); 5531 5532 ins_cost(110); 5533 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5534 opcode(0x8D); 5535 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5536 ins_pipe(ialu_reg_reg_fat); 5537 %} 5538 5539 instruct loadConI(rRegI dst, immI src) 5540 %{ 5541 match(Set dst src); 5542 5543 format %{ "movl $dst, $src\t# int" %} 5544 ins_encode(load_immI(dst, src)); 5545 ins_pipe(ialu_reg_fat); // XXX 5546 %} 5547 5548 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5549 %{ 5550 match(Set dst src); 5551 effect(KILL cr); 5552 5553 ins_cost(50); 5554 format %{ "xorl $dst, $dst\t# int" %} 5555 opcode(0x33); /* + rd */ 5556 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5557 ins_pipe(ialu_reg); 5558 %} 5559 5560 instruct loadConL(rRegL dst, immL src) 5561 %{ 5562 match(Set dst src); 5563 5564 ins_cost(150); 5565 format %{ "movq $dst, $src\t# long" %} 5566 ins_encode(load_immL(dst, src)); 5567 ins_pipe(ialu_reg); 5568 %} 5569 5570 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5571 %{ 5572 match(Set dst src); 5573 effect(KILL cr); 5574 5575 ins_cost(50); 5576 format %{ "xorl $dst, $dst\t# long" %} 5577 opcode(0x33); /* + rd */ 5578 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5579 ins_pipe(ialu_reg); // XXX 5580 %} 5581 5582 instruct loadConUL32(rRegL dst, immUL32 src) 5583 %{ 5584 match(Set dst src); 5585 5586 ins_cost(60); 5587 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5588 ins_encode(load_immUL32(dst, src)); 5589 ins_pipe(ialu_reg); 5590 %} 5591 5592 instruct loadConL32(rRegL dst, immL32 src) 5593 %{ 5594 match(Set dst src); 5595 5596 ins_cost(70); 5597 format %{ "movq $dst, $src\t# long (32-bit)" %} 5598 ins_encode(load_immL32(dst, src)); 5599 ins_pipe(ialu_reg); 5600 %} 5601 5602 instruct loadConP(rRegP dst, immP con) %{ 5603 match(Set dst con); 5604 5605 format %{ "movq $dst, $con\t# ptr" %} 5606 ins_encode(load_immP(dst, con)); 5607 ins_pipe(ialu_reg_fat); // XXX 5608 %} 5609 5610 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5611 %{ 5612 match(Set dst src); 5613 effect(KILL cr); 5614 5615 ins_cost(50); 5616 format %{ "xorl $dst, $dst\t# ptr" %} 5617 opcode(0x33); /* + rd */ 5618 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5619 ins_pipe(ialu_reg); 5620 %} 5621 5622 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5623 %{ 5624 match(Set dst src); 5625 effect(KILL cr); 5626 5627 ins_cost(60); 5628 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5629 ins_encode(load_immP31(dst, src)); 5630 ins_pipe(ialu_reg); 5631 %} 5632 5633 instruct loadConF(regF dst, immF con) %{ 5634 match(Set dst con); 5635 ins_cost(125); 5636 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5637 ins_encode %{ 5638 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5639 %} 5640 ins_pipe(pipe_slow); 5641 %} 5642 5643 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5644 match(Set dst src); 5645 effect(KILL cr); 5646 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5647 ins_encode %{ 5648 __ xorq($dst$$Register, $dst$$Register); 5649 %} 5650 ins_pipe(ialu_reg); 5651 %} 5652 5653 instruct loadConN(rRegN dst, immN src) %{ 5654 match(Set dst src); 5655 5656 ins_cost(125); 5657 format %{ "movl $dst, $src\t# compressed ptr" %} 5658 ins_encode %{ 5659 address con = (address)$src$$constant; 5660 if (con == NULL) { 5661 ShouldNotReachHere(); 5662 } else { 5663 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5664 } 5665 %} 5666 ins_pipe(ialu_reg_fat); // XXX 5667 %} 5668 5669 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5670 match(Set dst src); 5671 5672 ins_cost(125); 5673 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5674 ins_encode %{ 5675 address con = (address)$src$$constant; 5676 if (con == NULL) { 5677 ShouldNotReachHere(); 5678 } else { 5679 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5680 } 5681 %} 5682 ins_pipe(ialu_reg_fat); // XXX 5683 %} 5684 5685 instruct loadConF0(regF dst, immF0 src) 5686 %{ 5687 match(Set dst src); 5688 ins_cost(100); 5689 5690 format %{ "xorps $dst, $dst\t# float 0.0" %} 5691 ins_encode %{ 5692 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5693 %} 5694 ins_pipe(pipe_slow); 5695 %} 5696 5697 // Use the same format since predicate() can not be used here. 5698 instruct loadConD(regD dst, immD con) %{ 5699 match(Set dst con); 5700 ins_cost(125); 5701 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5702 ins_encode %{ 5703 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5704 %} 5705 ins_pipe(pipe_slow); 5706 %} 5707 5708 instruct loadConD0(regD dst, immD0 src) 5709 %{ 5710 match(Set dst src); 5711 ins_cost(100); 5712 5713 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5714 ins_encode %{ 5715 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5716 %} 5717 ins_pipe(pipe_slow); 5718 %} 5719 5720 instruct loadSSI(rRegI dst, stackSlotI src) 5721 %{ 5722 match(Set dst src); 5723 5724 ins_cost(125); 5725 format %{ "movl $dst, $src\t# int stk" %} 5726 opcode(0x8B); 5727 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5728 ins_pipe(ialu_reg_mem); 5729 %} 5730 5731 instruct loadSSL(rRegL dst, stackSlotL src) 5732 %{ 5733 match(Set dst src); 5734 5735 ins_cost(125); 5736 format %{ "movq $dst, $src\t# long stk" %} 5737 opcode(0x8B); 5738 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5739 ins_pipe(ialu_reg_mem); 5740 %} 5741 5742 instruct loadSSP(rRegP dst, stackSlotP src) 5743 %{ 5744 match(Set dst src); 5745 5746 ins_cost(125); 5747 format %{ "movq $dst, $src\t# ptr stk" %} 5748 opcode(0x8B); 5749 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5750 ins_pipe(ialu_reg_mem); 5751 %} 5752 5753 instruct loadSSF(regF dst, stackSlotF src) 5754 %{ 5755 match(Set dst src); 5756 5757 ins_cost(125); 5758 format %{ "movss $dst, $src\t# float stk" %} 5759 ins_encode %{ 5760 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5761 %} 5762 ins_pipe(pipe_slow); // XXX 5763 %} 5764 5765 // Use the same format since predicate() can not be used here. 5766 instruct loadSSD(regD dst, stackSlotD src) 5767 %{ 5768 match(Set dst src); 5769 5770 ins_cost(125); 5771 format %{ "movsd $dst, $src\t# double stk" %} 5772 ins_encode %{ 5773 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5774 %} 5775 ins_pipe(pipe_slow); // XXX 5776 %} 5777 5778 // Prefetch instructions for allocation. 5779 // Must be safe to execute with invalid address (cannot fault). 5780 5781 instruct prefetchAlloc( memory mem ) %{ 5782 predicate(AllocatePrefetchInstr==3); 5783 match(PrefetchAllocation mem); 5784 ins_cost(125); 5785 5786 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5787 ins_encode %{ 5788 __ prefetchw($mem$$Address); 5789 %} 5790 ins_pipe(ialu_mem); 5791 %} 5792 5793 instruct prefetchAllocNTA( memory mem ) %{ 5794 predicate(AllocatePrefetchInstr==0); 5795 match(PrefetchAllocation mem); 5796 ins_cost(125); 5797 5798 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5799 ins_encode %{ 5800 __ prefetchnta($mem$$Address); 5801 %} 5802 ins_pipe(ialu_mem); 5803 %} 5804 5805 instruct prefetchAllocT0( memory mem ) %{ 5806 predicate(AllocatePrefetchInstr==1); 5807 match(PrefetchAllocation mem); 5808 ins_cost(125); 5809 5810 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5811 ins_encode %{ 5812 __ prefetcht0($mem$$Address); 5813 %} 5814 ins_pipe(ialu_mem); 5815 %} 5816 5817 instruct prefetchAllocT2( memory mem ) %{ 5818 predicate(AllocatePrefetchInstr==2); 5819 match(PrefetchAllocation mem); 5820 ins_cost(125); 5821 5822 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5823 ins_encode %{ 5824 __ prefetcht2($mem$$Address); 5825 %} 5826 ins_pipe(ialu_mem); 5827 %} 5828 5829 //----------Store Instructions------------------------------------------------- 5830 5831 // Store Byte 5832 instruct storeB(memory mem, rRegI src) 5833 %{ 5834 match(Set mem (StoreB mem src)); 5835 5836 ins_cost(125); // XXX 5837 format %{ "movb $mem, $src\t# byte" %} 5838 opcode(0x88); 5839 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5840 ins_pipe(ialu_mem_reg); 5841 %} 5842 5843 // Store Char/Short 5844 instruct storeC(memory mem, rRegI src) 5845 %{ 5846 match(Set mem (StoreC mem src)); 5847 5848 ins_cost(125); // XXX 5849 format %{ "movw $mem, $src\t# char/short" %} 5850 opcode(0x89); 5851 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5852 ins_pipe(ialu_mem_reg); 5853 %} 5854 5855 // Store Integer 5856 instruct storeI(memory mem, rRegI src) 5857 %{ 5858 match(Set mem (StoreI mem src)); 5859 5860 ins_cost(125); // XXX 5861 format %{ "movl $mem, $src\t# int" %} 5862 opcode(0x89); 5863 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5864 ins_pipe(ialu_mem_reg); 5865 %} 5866 5867 // Store Long 5868 instruct storeL(memory mem, rRegL src) 5869 %{ 5870 match(Set mem (StoreL mem src)); 5871 5872 ins_cost(125); // XXX 5873 format %{ "movq $mem, $src\t# long" %} 5874 opcode(0x89); 5875 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5876 ins_pipe(ialu_mem_reg); // XXX 5877 %} 5878 5879 // Store Pointer 5880 instruct storeP(memory mem, any_RegP src) 5881 %{ 5882 match(Set mem (StoreP mem src)); 5883 5884 ins_cost(125); // XXX 5885 format %{ "movq $mem, $src\t# ptr" %} 5886 opcode(0x89); 5887 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5888 ins_pipe(ialu_mem_reg); 5889 %} 5890 5891 instruct storeImmP0(memory mem, immP0 zero) 5892 %{ 5893 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5894 match(Set mem (StoreP mem zero)); 5895 5896 ins_cost(125); // XXX 5897 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5898 ins_encode %{ 5899 __ movq($mem$$Address, r12); 5900 %} 5901 ins_pipe(ialu_mem_reg); 5902 %} 5903 5904 // Store NULL Pointer, mark word, or other simple pointer constant. 5905 instruct storeImmP(memory mem, immP31 src) 5906 %{ 5907 match(Set mem (StoreP mem src)); 5908 5909 ins_cost(150); // XXX 5910 format %{ "movq $mem, $src\t# ptr" %} 5911 opcode(0xC7); /* C7 /0 */ 5912 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5913 ins_pipe(ialu_mem_imm); 5914 %} 5915 5916 // Store Compressed Pointer 5917 instruct storeN(memory mem, rRegN src) 5918 %{ 5919 match(Set mem (StoreN mem src)); 5920 5921 ins_cost(125); // XXX 5922 format %{ "movl $mem, $src\t# compressed ptr" %} 5923 ins_encode %{ 5924 __ movl($mem$$Address, $src$$Register); 5925 %} 5926 ins_pipe(ialu_mem_reg); 5927 %} 5928 5929 instruct storeNKlass(memory mem, rRegN src) 5930 %{ 5931 match(Set mem (StoreNKlass mem src)); 5932 5933 ins_cost(125); // XXX 5934 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5935 ins_encode %{ 5936 __ movl($mem$$Address, $src$$Register); 5937 %} 5938 ins_pipe(ialu_mem_reg); 5939 %} 5940 5941 instruct storeImmN0(memory mem, immN0 zero) 5942 %{ 5943 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5944 match(Set mem (StoreN mem zero)); 5945 5946 ins_cost(125); // XXX 5947 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5948 ins_encode %{ 5949 __ movl($mem$$Address, r12); 5950 %} 5951 ins_pipe(ialu_mem_reg); 5952 %} 5953 5954 instruct storeImmN(memory mem, immN src) 5955 %{ 5956 match(Set mem (StoreN mem src)); 5957 5958 ins_cost(150); // XXX 5959 format %{ "movl $mem, $src\t# compressed ptr" %} 5960 ins_encode %{ 5961 address con = (address)$src$$constant; 5962 if (con == NULL) { 5963 __ movl($mem$$Address, (int32_t)0); 5964 } else { 5965 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5966 } 5967 %} 5968 ins_pipe(ialu_mem_imm); 5969 %} 5970 5971 instruct storeImmNKlass(memory mem, immNKlass src) 5972 %{ 5973 match(Set mem (StoreNKlass mem src)); 5974 5975 ins_cost(150); // XXX 5976 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5977 ins_encode %{ 5978 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5979 %} 5980 ins_pipe(ialu_mem_imm); 5981 %} 5982 5983 // Store Integer Immediate 5984 instruct storeImmI0(memory mem, immI0 zero) 5985 %{ 5986 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5987 match(Set mem (StoreI mem zero)); 5988 5989 ins_cost(125); // XXX 5990 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5991 ins_encode %{ 5992 __ movl($mem$$Address, r12); 5993 %} 5994 ins_pipe(ialu_mem_reg); 5995 %} 5996 5997 instruct storeImmI(memory mem, immI src) 5998 %{ 5999 match(Set mem (StoreI mem src)); 6000 6001 ins_cost(150); 6002 format %{ "movl $mem, $src\t# int" %} 6003 opcode(0xC7); /* C7 /0 */ 6004 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6005 ins_pipe(ialu_mem_imm); 6006 %} 6007 6008 // Store Long Immediate 6009 instruct storeImmL0(memory mem, immL0 zero) 6010 %{ 6011 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6012 match(Set mem (StoreL mem zero)); 6013 6014 ins_cost(125); // XXX 6015 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6016 ins_encode %{ 6017 __ movq($mem$$Address, r12); 6018 %} 6019 ins_pipe(ialu_mem_reg); 6020 %} 6021 6022 instruct storeImmL(memory mem, immL32 src) 6023 %{ 6024 match(Set mem (StoreL mem src)); 6025 6026 ins_cost(150); 6027 format %{ "movq $mem, $src\t# long" %} 6028 opcode(0xC7); /* C7 /0 */ 6029 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6030 ins_pipe(ialu_mem_imm); 6031 %} 6032 6033 // Store Short/Char Immediate 6034 instruct storeImmC0(memory mem, immI0 zero) 6035 %{ 6036 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6037 match(Set mem (StoreC mem zero)); 6038 6039 ins_cost(125); // XXX 6040 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6041 ins_encode %{ 6042 __ movw($mem$$Address, r12); 6043 %} 6044 ins_pipe(ialu_mem_reg); 6045 %} 6046 6047 instruct storeImmI16(memory mem, immI16 src) 6048 %{ 6049 predicate(UseStoreImmI16); 6050 match(Set mem (StoreC mem src)); 6051 6052 ins_cost(150); 6053 format %{ "movw $mem, $src\t# short/char" %} 6054 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6055 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6056 ins_pipe(ialu_mem_imm); 6057 %} 6058 6059 // Store Byte Immediate 6060 instruct storeImmB0(memory mem, immI0 zero) 6061 %{ 6062 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6063 match(Set mem (StoreB mem zero)); 6064 6065 ins_cost(125); // XXX 6066 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6067 ins_encode %{ 6068 __ movb($mem$$Address, r12); 6069 %} 6070 ins_pipe(ialu_mem_reg); 6071 %} 6072 6073 instruct storeImmB(memory mem, immI8 src) 6074 %{ 6075 match(Set mem (StoreB mem src)); 6076 6077 ins_cost(150); // XXX 6078 format %{ "movb $mem, $src\t# byte" %} 6079 opcode(0xC6); /* C6 /0 */ 6080 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6081 ins_pipe(ialu_mem_imm); 6082 %} 6083 6084 // Store CMS card-mark Immediate 6085 instruct storeImmCM0_reg(memory mem, immI0 zero) 6086 %{ 6087 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6088 match(Set mem (StoreCM mem zero)); 6089 6090 ins_cost(125); // XXX 6091 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6092 ins_encode %{ 6093 __ movb($mem$$Address, r12); 6094 %} 6095 ins_pipe(ialu_mem_reg); 6096 %} 6097 6098 instruct storeImmCM0(memory mem, immI0 src) 6099 %{ 6100 match(Set mem (StoreCM mem src)); 6101 6102 ins_cost(150); // XXX 6103 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6104 opcode(0xC6); /* C6 /0 */ 6105 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6106 ins_pipe(ialu_mem_imm); 6107 %} 6108 6109 // Store Float 6110 instruct storeF(memory mem, regF src) 6111 %{ 6112 match(Set mem (StoreF mem src)); 6113 6114 ins_cost(95); // XXX 6115 format %{ "movss $mem, $src\t# float" %} 6116 ins_encode %{ 6117 __ movflt($mem$$Address, $src$$XMMRegister); 6118 %} 6119 ins_pipe(pipe_slow); // XXX 6120 %} 6121 6122 // Store immediate Float value (it is faster than store from XMM register) 6123 instruct storeF0(memory mem, immF0 zero) 6124 %{ 6125 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6126 match(Set mem (StoreF mem zero)); 6127 6128 ins_cost(25); // XXX 6129 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6130 ins_encode %{ 6131 __ movl($mem$$Address, r12); 6132 %} 6133 ins_pipe(ialu_mem_reg); 6134 %} 6135 6136 instruct storeF_imm(memory mem, immF src) 6137 %{ 6138 match(Set mem (StoreF mem src)); 6139 6140 ins_cost(50); 6141 format %{ "movl $mem, $src\t# float" %} 6142 opcode(0xC7); /* C7 /0 */ 6143 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6144 ins_pipe(ialu_mem_imm); 6145 %} 6146 6147 // Store Double 6148 instruct storeD(memory mem, regD src) 6149 %{ 6150 match(Set mem (StoreD mem src)); 6151 6152 ins_cost(95); // XXX 6153 format %{ "movsd $mem, $src\t# double" %} 6154 ins_encode %{ 6155 __ movdbl($mem$$Address, $src$$XMMRegister); 6156 %} 6157 ins_pipe(pipe_slow); // XXX 6158 %} 6159 6160 // Store immediate double 0.0 (it is faster than store from XMM register) 6161 instruct storeD0_imm(memory mem, immD0 src) 6162 %{ 6163 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6164 match(Set mem (StoreD mem src)); 6165 6166 ins_cost(50); 6167 format %{ "movq $mem, $src\t# double 0." %} 6168 opcode(0xC7); /* C7 /0 */ 6169 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6170 ins_pipe(ialu_mem_imm); 6171 %} 6172 6173 instruct storeD0(memory mem, immD0 zero) 6174 %{ 6175 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6176 match(Set mem (StoreD mem zero)); 6177 6178 ins_cost(25); // XXX 6179 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6180 ins_encode %{ 6181 __ movq($mem$$Address, r12); 6182 %} 6183 ins_pipe(ialu_mem_reg); 6184 %} 6185 6186 instruct storeSSI(stackSlotI dst, rRegI src) 6187 %{ 6188 match(Set dst src); 6189 6190 ins_cost(100); 6191 format %{ "movl $dst, $src\t# int stk" %} 6192 opcode(0x89); 6193 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6194 ins_pipe( ialu_mem_reg ); 6195 %} 6196 6197 instruct storeSSL(stackSlotL dst, rRegL src) 6198 %{ 6199 match(Set dst src); 6200 6201 ins_cost(100); 6202 format %{ "movq $dst, $src\t# long stk" %} 6203 opcode(0x89); 6204 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6205 ins_pipe(ialu_mem_reg); 6206 %} 6207 6208 instruct storeSSP(stackSlotP dst, rRegP src) 6209 %{ 6210 match(Set dst src); 6211 6212 ins_cost(100); 6213 format %{ "movq $dst, $src\t# ptr stk" %} 6214 opcode(0x89); 6215 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6216 ins_pipe(ialu_mem_reg); 6217 %} 6218 6219 instruct storeSSF(stackSlotF dst, regF src) 6220 %{ 6221 match(Set dst src); 6222 6223 ins_cost(95); // XXX 6224 format %{ "movss $dst, $src\t# float stk" %} 6225 ins_encode %{ 6226 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6227 %} 6228 ins_pipe(pipe_slow); // XXX 6229 %} 6230 6231 instruct storeSSD(stackSlotD dst, regD src) 6232 %{ 6233 match(Set dst src); 6234 6235 ins_cost(95); // XXX 6236 format %{ "movsd $dst, $src\t# double stk" %} 6237 ins_encode %{ 6238 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6239 %} 6240 ins_pipe(pipe_slow); // XXX 6241 %} 6242 6243 //----------BSWAP Instructions------------------------------------------------- 6244 instruct bytes_reverse_int(rRegI dst) %{ 6245 match(Set dst (ReverseBytesI dst)); 6246 6247 format %{ "bswapl $dst" %} 6248 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6249 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6250 ins_pipe( ialu_reg ); 6251 %} 6252 6253 instruct bytes_reverse_long(rRegL dst) %{ 6254 match(Set dst (ReverseBytesL dst)); 6255 6256 format %{ "bswapq $dst" %} 6257 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6258 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6259 ins_pipe( ialu_reg); 6260 %} 6261 6262 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6263 match(Set dst (ReverseBytesUS dst)); 6264 effect(KILL cr); 6265 6266 format %{ "bswapl $dst\n\t" 6267 "shrl $dst,16\n\t" %} 6268 ins_encode %{ 6269 __ bswapl($dst$$Register); 6270 __ shrl($dst$$Register, 16); 6271 %} 6272 ins_pipe( ialu_reg ); 6273 %} 6274 6275 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6276 match(Set dst (ReverseBytesS dst)); 6277 effect(KILL cr); 6278 6279 format %{ "bswapl $dst\n\t" 6280 "sar $dst,16\n\t" %} 6281 ins_encode %{ 6282 __ bswapl($dst$$Register); 6283 __ sarl($dst$$Register, 16); 6284 %} 6285 ins_pipe( ialu_reg ); 6286 %} 6287 6288 //---------- Zeros Count Instructions ------------------------------------------ 6289 6290 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6291 predicate(UseCountLeadingZerosInstruction); 6292 match(Set dst (CountLeadingZerosI src)); 6293 effect(KILL cr); 6294 6295 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6296 ins_encode %{ 6297 __ lzcntl($dst$$Register, $src$$Register); 6298 %} 6299 ins_pipe(ialu_reg); 6300 %} 6301 6302 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6303 predicate(!UseCountLeadingZerosInstruction); 6304 match(Set dst (CountLeadingZerosI src)); 6305 effect(KILL cr); 6306 6307 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6308 "jnz skip\n\t" 6309 "movl $dst, -1\n" 6310 "skip:\n\t" 6311 "negl $dst\n\t" 6312 "addl $dst, 31" %} 6313 ins_encode %{ 6314 Register Rdst = $dst$$Register; 6315 Register Rsrc = $src$$Register; 6316 Label skip; 6317 __ bsrl(Rdst, Rsrc); 6318 __ jccb(Assembler::notZero, skip); 6319 __ movl(Rdst, -1); 6320 __ bind(skip); 6321 __ negl(Rdst); 6322 __ addl(Rdst, BitsPerInt - 1); 6323 %} 6324 ins_pipe(ialu_reg); 6325 %} 6326 6327 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6328 predicate(UseCountLeadingZerosInstruction); 6329 match(Set dst (CountLeadingZerosL src)); 6330 effect(KILL cr); 6331 6332 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6333 ins_encode %{ 6334 __ lzcntq($dst$$Register, $src$$Register); 6335 %} 6336 ins_pipe(ialu_reg); 6337 %} 6338 6339 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6340 predicate(!UseCountLeadingZerosInstruction); 6341 match(Set dst (CountLeadingZerosL src)); 6342 effect(KILL cr); 6343 6344 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6345 "jnz skip\n\t" 6346 "movl $dst, -1\n" 6347 "skip:\n\t" 6348 "negl $dst\n\t" 6349 "addl $dst, 63" %} 6350 ins_encode %{ 6351 Register Rdst = $dst$$Register; 6352 Register Rsrc = $src$$Register; 6353 Label skip; 6354 __ bsrq(Rdst, Rsrc); 6355 __ jccb(Assembler::notZero, skip); 6356 __ movl(Rdst, -1); 6357 __ bind(skip); 6358 __ negl(Rdst); 6359 __ addl(Rdst, BitsPerLong - 1); 6360 %} 6361 ins_pipe(ialu_reg); 6362 %} 6363 6364 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6365 predicate(UseCountTrailingZerosInstruction); 6366 match(Set dst (CountTrailingZerosI src)); 6367 effect(KILL cr); 6368 6369 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6370 ins_encode %{ 6371 __ tzcntl($dst$$Register, $src$$Register); 6372 %} 6373 ins_pipe(ialu_reg); 6374 %} 6375 6376 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6377 predicate(!UseCountTrailingZerosInstruction); 6378 match(Set dst (CountTrailingZerosI src)); 6379 effect(KILL cr); 6380 6381 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6382 "jnz done\n\t" 6383 "movl $dst, 32\n" 6384 "done:" %} 6385 ins_encode %{ 6386 Register Rdst = $dst$$Register; 6387 Label done; 6388 __ bsfl(Rdst, $src$$Register); 6389 __ jccb(Assembler::notZero, done); 6390 __ movl(Rdst, BitsPerInt); 6391 __ bind(done); 6392 %} 6393 ins_pipe(ialu_reg); 6394 %} 6395 6396 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6397 predicate(UseCountTrailingZerosInstruction); 6398 match(Set dst (CountTrailingZerosL src)); 6399 effect(KILL cr); 6400 6401 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6402 ins_encode %{ 6403 __ tzcntq($dst$$Register, $src$$Register); 6404 %} 6405 ins_pipe(ialu_reg); 6406 %} 6407 6408 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6409 predicate(!UseCountTrailingZerosInstruction); 6410 match(Set dst (CountTrailingZerosL src)); 6411 effect(KILL cr); 6412 6413 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6414 "jnz done\n\t" 6415 "movl $dst, 64\n" 6416 "done:" %} 6417 ins_encode %{ 6418 Register Rdst = $dst$$Register; 6419 Label done; 6420 __ bsfq(Rdst, $src$$Register); 6421 __ jccb(Assembler::notZero, done); 6422 __ movl(Rdst, BitsPerLong); 6423 __ bind(done); 6424 %} 6425 ins_pipe(ialu_reg); 6426 %} 6427 6428 6429 //---------- Population Count Instructions ------------------------------------- 6430 6431 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6432 predicate(UsePopCountInstruction); 6433 match(Set dst (PopCountI src)); 6434 effect(KILL cr); 6435 6436 format %{ "popcnt $dst, $src" %} 6437 ins_encode %{ 6438 __ popcntl($dst$$Register, $src$$Register); 6439 %} 6440 ins_pipe(ialu_reg); 6441 %} 6442 6443 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6444 predicate(UsePopCountInstruction); 6445 match(Set dst (PopCountI (LoadI mem))); 6446 effect(KILL cr); 6447 6448 format %{ "popcnt $dst, $mem" %} 6449 ins_encode %{ 6450 __ popcntl($dst$$Register, $mem$$Address); 6451 %} 6452 ins_pipe(ialu_reg); 6453 %} 6454 6455 // Note: Long.bitCount(long) returns an int. 6456 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6457 predicate(UsePopCountInstruction); 6458 match(Set dst (PopCountL src)); 6459 effect(KILL cr); 6460 6461 format %{ "popcnt $dst, $src" %} 6462 ins_encode %{ 6463 __ popcntq($dst$$Register, $src$$Register); 6464 %} 6465 ins_pipe(ialu_reg); 6466 %} 6467 6468 // Note: Long.bitCount(long) returns an int. 6469 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6470 predicate(UsePopCountInstruction); 6471 match(Set dst (PopCountL (LoadL mem))); 6472 effect(KILL cr); 6473 6474 format %{ "popcnt $dst, $mem" %} 6475 ins_encode %{ 6476 __ popcntq($dst$$Register, $mem$$Address); 6477 %} 6478 ins_pipe(ialu_reg); 6479 %} 6480 6481 6482 //----------MemBar Instructions----------------------------------------------- 6483 // Memory barrier flavors 6484 6485 instruct membar_acquire() 6486 %{ 6487 match(MemBarAcquire); 6488 match(LoadFence); 6489 ins_cost(0); 6490 6491 size(0); 6492 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6493 ins_encode(); 6494 ins_pipe(empty); 6495 %} 6496 6497 instruct membar_acquire_lock() 6498 %{ 6499 match(MemBarAcquireLock); 6500 ins_cost(0); 6501 6502 size(0); 6503 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6504 ins_encode(); 6505 ins_pipe(empty); 6506 %} 6507 6508 instruct membar_release() 6509 %{ 6510 match(MemBarRelease); 6511 match(StoreFence); 6512 ins_cost(0); 6513 6514 size(0); 6515 format %{ "MEMBAR-release ! (empty encoding)" %} 6516 ins_encode(); 6517 ins_pipe(empty); 6518 %} 6519 6520 instruct membar_release_lock() 6521 %{ 6522 match(MemBarReleaseLock); 6523 ins_cost(0); 6524 6525 size(0); 6526 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6527 ins_encode(); 6528 ins_pipe(empty); 6529 %} 6530 6531 instruct membar_volatile(rFlagsReg cr) %{ 6532 match(MemBarVolatile); 6533 effect(KILL cr); 6534 ins_cost(400); 6535 6536 format %{ 6537 $$template 6538 if (os::is_MP()) { 6539 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6540 } else { 6541 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6542 } 6543 %} 6544 ins_encode %{ 6545 __ membar(Assembler::StoreLoad); 6546 %} 6547 ins_pipe(pipe_slow); 6548 %} 6549 6550 instruct unnecessary_membar_volatile() 6551 %{ 6552 match(MemBarVolatile); 6553 predicate(Matcher::post_store_load_barrier(n)); 6554 ins_cost(0); 6555 6556 size(0); 6557 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6558 ins_encode(); 6559 ins_pipe(empty); 6560 %} 6561 6562 instruct membar_storestore() %{ 6563 match(MemBarStoreStore); 6564 ins_cost(0); 6565 6566 size(0); 6567 format %{ "MEMBAR-storestore (empty encoding)" %} 6568 ins_encode( ); 6569 ins_pipe(empty); 6570 %} 6571 6572 //----------Move Instructions-------------------------------------------------- 6573 6574 instruct castX2P(rRegP dst, rRegL src) 6575 %{ 6576 match(Set dst (CastX2P src)); 6577 6578 format %{ "movq $dst, $src\t# long->ptr" %} 6579 ins_encode %{ 6580 if ($dst$$reg != $src$$reg) { 6581 __ movptr($dst$$Register, $src$$Register); 6582 } 6583 %} 6584 ins_pipe(ialu_reg_reg); // XXX 6585 %} 6586 6587 instruct castP2X(rRegL dst, rRegP src) 6588 %{ 6589 match(Set dst (CastP2X src)); 6590 6591 format %{ "movq $dst, $src\t# ptr -> long" %} 6592 ins_encode %{ 6593 if ($dst$$reg != $src$$reg) { 6594 __ movptr($dst$$Register, $src$$Register); 6595 } 6596 %} 6597 ins_pipe(ialu_reg_reg); // XXX 6598 %} 6599 6600 // Convert oop into int for vectors alignment masking 6601 instruct convP2I(rRegI dst, rRegP src) 6602 %{ 6603 match(Set dst (ConvL2I (CastP2X src))); 6604 6605 format %{ "movl $dst, $src\t# ptr -> int" %} 6606 ins_encode %{ 6607 __ movl($dst$$Register, $src$$Register); 6608 %} 6609 ins_pipe(ialu_reg_reg); // XXX 6610 %} 6611 6612 // Convert compressed oop into int for vectors alignment masking 6613 // in case of 32bit oops (heap < 4Gb). 6614 instruct convN2I(rRegI dst, rRegN src) 6615 %{ 6616 predicate(Universe::narrow_oop_shift() == 0); 6617 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6618 6619 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6620 ins_encode %{ 6621 __ movl($dst$$Register, $src$$Register); 6622 %} 6623 ins_pipe(ialu_reg_reg); // XXX 6624 %} 6625 6626 instruct shenandoahRB(rRegP dst, rRegP src, rFlagsReg cr) %{ 6627 match(Set dst (ShenandoahReadBarrier src)); 6628 effect(DEF dst, USE src); 6629 ins_cost(125); // XXX 6630 format %{ "shenandoah_rb $dst, $src" %} 6631 ins_encode %{ 6632 Register d = $dst$$Register; 6633 Register s = $src$$Register; 6634 __ movptr(d, Address(s, BrooksPointer::byte_offset())); 6635 %} 6636 ins_pipe(ialu_reg_mem); 6637 %} 6638 6639 instruct shenandoahRBNarrow(rRegP dst, rRegN src) %{ 6640 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == 0)); 6641 match(Set dst (ShenandoahReadBarrier (DecodeN src))); 6642 effect(DEF dst, USE src); 6643 ins_cost(125); // XXX 6644 format %{ "shenandoah_rb $dst, $src" %} 6645 ins_encode %{ 6646 Register d = $dst$$Register; 6647 Register s = $src$$Register; 6648 __ movptr(d, Address(r12, s, Address::times_1, BrooksPointer::byte_offset())); 6649 %} 6650 ins_pipe(ialu_reg_mem); 6651 %} 6652 6653 instruct shenandoahRBNarrowShift(rRegP dst, rRegN src) %{ 6654 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 6655 match(Set dst (ShenandoahReadBarrier (DecodeN src))); 6656 effect(DEF dst, USE src); 6657 ins_cost(125); // XXX 6658 format %{ "shenandoah_rb $dst, $src" %} 6659 ins_encode %{ 6660 Register d = $dst$$Register; 6661 Register s = $src$$Register; 6662 __ movptr(d, Address(r12, s, Address::times_8, BrooksPointer::byte_offset())); 6663 %} 6664 ins_pipe(ialu_reg_mem); 6665 %} 6666 6667 instruct shenandoahWB(rRegP dst, rRegP src, rFlagsReg cr) %{ 6668 match(Set dst (ShenandoahWriteBarrier src)); 6669 effect(DEF dst, USE src, KILL cr); 6670 ins_cost(300); // XXX 6671 format %{ "shenandoah_wb $dst,$src" %} 6672 ins_encode %{ 6673 #if INCLUDE_SHENANDOAHGC 6674 Register s = $src$$Register; 6675 Register d = $dst$$Register; 6676 // We need that first read barrier in order to trigger a SEGV/NPE on incoming NULL. 6677 // Also, it brings s into d in preparation for the call to shenandoah_write_barrier(). 6678 __ movptr(d, Address(s, BrooksPointer::byte_offset())); 6679 __ shenandoah_write_barrier(d); 6680 #else 6681 ShouldNotReachHere(); 6682 #endif 6683 %} 6684 ins_pipe(pipe_slow); 6685 %} 6686 6687 // Convert oop pointer into compressed form 6688 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6689 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6690 match(Set dst (EncodeP src)); 6691 effect(KILL cr); 6692 format %{ "encode_heap_oop $dst,$src" %} 6693 ins_encode %{ 6694 Register s = $src$$Register; 6695 Register d = $dst$$Register; 6696 if (s != d) { 6697 __ movq(d, s); 6698 } 6699 __ encode_heap_oop(d); 6700 %} 6701 ins_pipe(ialu_reg_long); 6702 %} 6703 6704 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6705 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6706 match(Set dst (EncodeP src)); 6707 effect(KILL cr); 6708 format %{ "encode_heap_oop_not_null $dst,$src" %} 6709 ins_encode %{ 6710 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6711 %} 6712 ins_pipe(ialu_reg_long); 6713 %} 6714 6715 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6716 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6717 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6718 match(Set dst (DecodeN src)); 6719 effect(KILL cr); 6720 format %{ "decode_heap_oop $dst,$src" %} 6721 ins_encode %{ 6722 Register s = $src$$Register; 6723 Register d = $dst$$Register; 6724 if (s != d) { 6725 __ movq(d, s); 6726 } 6727 __ decode_heap_oop(d); 6728 %} 6729 ins_pipe(ialu_reg_long); 6730 %} 6731 6732 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6733 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6734 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6735 match(Set dst (DecodeN src)); 6736 effect(KILL cr); 6737 format %{ "decode_heap_oop_not_null $dst,$src" %} 6738 ins_encode %{ 6739 Register s = $src$$Register; 6740 Register d = $dst$$Register; 6741 if (s != d) { 6742 __ decode_heap_oop_not_null(d, s); 6743 } else { 6744 __ decode_heap_oop_not_null(d); 6745 } 6746 %} 6747 ins_pipe(ialu_reg_long); 6748 %} 6749 6750 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6751 match(Set dst (EncodePKlass src)); 6752 effect(KILL cr); 6753 format %{ "encode_klass_not_null $dst,$src" %} 6754 ins_encode %{ 6755 __ encode_klass_not_null($dst$$Register, $src$$Register); 6756 %} 6757 ins_pipe(ialu_reg_long); 6758 %} 6759 6760 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6761 match(Set dst (DecodeNKlass src)); 6762 effect(KILL cr); 6763 format %{ "decode_klass_not_null $dst,$src" %} 6764 ins_encode %{ 6765 Register s = $src$$Register; 6766 Register d = $dst$$Register; 6767 if (s != d) { 6768 __ decode_klass_not_null(d, s); 6769 } else { 6770 __ decode_klass_not_null(d); 6771 } 6772 %} 6773 ins_pipe(ialu_reg_long); 6774 %} 6775 6776 6777 //----------Conditional Move--------------------------------------------------- 6778 // Jump 6779 // dummy instruction for generating temp registers 6780 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6781 match(Jump (LShiftL switch_val shift)); 6782 ins_cost(350); 6783 predicate(false); 6784 effect(TEMP dest); 6785 6786 format %{ "leaq $dest, [$constantaddress]\n\t" 6787 "jmp [$dest + $switch_val << $shift]\n\t" %} 6788 ins_encode %{ 6789 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6790 // to do that and the compiler is using that register as one it can allocate. 6791 // So we build it all by hand. 6792 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6793 // ArrayAddress dispatch(table, index); 6794 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6795 __ lea($dest$$Register, $constantaddress); 6796 __ jmp(dispatch); 6797 %} 6798 ins_pipe(pipe_jmp); 6799 %} 6800 6801 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6802 match(Jump (AddL (LShiftL switch_val shift) offset)); 6803 ins_cost(350); 6804 effect(TEMP dest); 6805 6806 format %{ "leaq $dest, [$constantaddress]\n\t" 6807 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6808 ins_encode %{ 6809 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6810 // to do that and the compiler is using that register as one it can allocate. 6811 // So we build it all by hand. 6812 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6813 // ArrayAddress dispatch(table, index); 6814 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6815 __ lea($dest$$Register, $constantaddress); 6816 __ jmp(dispatch); 6817 %} 6818 ins_pipe(pipe_jmp); 6819 %} 6820 6821 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6822 match(Jump switch_val); 6823 ins_cost(350); 6824 effect(TEMP dest); 6825 6826 format %{ "leaq $dest, [$constantaddress]\n\t" 6827 "jmp [$dest + $switch_val]\n\t" %} 6828 ins_encode %{ 6829 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6830 // to do that and the compiler is using that register as one it can allocate. 6831 // So we build it all by hand. 6832 // Address index(noreg, switch_reg, Address::times_1); 6833 // ArrayAddress dispatch(table, index); 6834 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6835 __ lea($dest$$Register, $constantaddress); 6836 __ jmp(dispatch); 6837 %} 6838 ins_pipe(pipe_jmp); 6839 %} 6840 6841 // Conditional move 6842 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6843 %{ 6844 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6845 6846 ins_cost(200); // XXX 6847 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6848 opcode(0x0F, 0x40); 6849 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6850 ins_pipe(pipe_cmov_reg); 6851 %} 6852 6853 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6854 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6855 6856 ins_cost(200); // XXX 6857 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6858 opcode(0x0F, 0x40); 6859 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6860 ins_pipe(pipe_cmov_reg); 6861 %} 6862 6863 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6864 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6865 ins_cost(200); 6866 expand %{ 6867 cmovI_regU(cop, cr, dst, src); 6868 %} 6869 %} 6870 6871 // Conditional move 6872 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6873 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6874 6875 ins_cost(250); // XXX 6876 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6877 opcode(0x0F, 0x40); 6878 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6879 ins_pipe(pipe_cmov_mem); 6880 %} 6881 6882 // Conditional move 6883 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6884 %{ 6885 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6886 6887 ins_cost(250); // XXX 6888 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6889 opcode(0x0F, 0x40); 6890 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6891 ins_pipe(pipe_cmov_mem); 6892 %} 6893 6894 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6895 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6896 ins_cost(250); 6897 expand %{ 6898 cmovI_memU(cop, cr, dst, src); 6899 %} 6900 %} 6901 6902 // Conditional move 6903 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6904 %{ 6905 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6906 6907 ins_cost(200); // XXX 6908 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6909 opcode(0x0F, 0x40); 6910 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6911 ins_pipe(pipe_cmov_reg); 6912 %} 6913 6914 // Conditional move 6915 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6916 %{ 6917 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6918 6919 ins_cost(200); // XXX 6920 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6921 opcode(0x0F, 0x40); 6922 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6923 ins_pipe(pipe_cmov_reg); 6924 %} 6925 6926 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6927 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6928 ins_cost(200); 6929 expand %{ 6930 cmovN_regU(cop, cr, dst, src); 6931 %} 6932 %} 6933 6934 // Conditional move 6935 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6936 %{ 6937 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6938 6939 ins_cost(200); // XXX 6940 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6941 opcode(0x0F, 0x40); 6942 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6943 ins_pipe(pipe_cmov_reg); // XXX 6944 %} 6945 6946 // Conditional move 6947 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6948 %{ 6949 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6950 6951 ins_cost(200); // XXX 6952 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6953 opcode(0x0F, 0x40); 6954 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6955 ins_pipe(pipe_cmov_reg); // XXX 6956 %} 6957 6958 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6959 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6960 ins_cost(200); 6961 expand %{ 6962 cmovP_regU(cop, cr, dst, src); 6963 %} 6964 %} 6965 6966 // DISABLED: Requires the ADLC to emit a bottom_type call that 6967 // correctly meets the two pointer arguments; one is an incoming 6968 // register but the other is a memory operand. ALSO appears to 6969 // be buggy with implicit null checks. 6970 // 6971 //// Conditional move 6972 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6973 //%{ 6974 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6975 // ins_cost(250); 6976 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6977 // opcode(0x0F,0x40); 6978 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6979 // ins_pipe( pipe_cmov_mem ); 6980 //%} 6981 // 6982 //// Conditional move 6983 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6984 //%{ 6985 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6986 // ins_cost(250); 6987 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6988 // opcode(0x0F,0x40); 6989 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6990 // ins_pipe( pipe_cmov_mem ); 6991 //%} 6992 6993 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6994 %{ 6995 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6996 6997 ins_cost(200); // XXX 6998 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6999 opcode(0x0F, 0x40); 7000 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7001 ins_pipe(pipe_cmov_reg); // XXX 7002 %} 7003 7004 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7005 %{ 7006 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7007 7008 ins_cost(200); // XXX 7009 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7010 opcode(0x0F, 0x40); 7011 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7012 ins_pipe(pipe_cmov_mem); // XXX 7013 %} 7014 7015 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7016 %{ 7017 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7018 7019 ins_cost(200); // XXX 7020 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7021 opcode(0x0F, 0x40); 7022 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7023 ins_pipe(pipe_cmov_reg); // XXX 7024 %} 7025 7026 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7027 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7028 ins_cost(200); 7029 expand %{ 7030 cmovL_regU(cop, cr, dst, src); 7031 %} 7032 %} 7033 7034 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7035 %{ 7036 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7037 7038 ins_cost(200); // XXX 7039 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7040 opcode(0x0F, 0x40); 7041 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7042 ins_pipe(pipe_cmov_mem); // XXX 7043 %} 7044 7045 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7046 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7047 ins_cost(200); 7048 expand %{ 7049 cmovL_memU(cop, cr, dst, src); 7050 %} 7051 %} 7052 7053 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7054 %{ 7055 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7056 7057 ins_cost(200); // XXX 7058 format %{ "jn$cop skip\t# signed cmove float\n\t" 7059 "movss $dst, $src\n" 7060 "skip:" %} 7061 ins_encode %{ 7062 Label Lskip; 7063 // Invert sense of branch from sense of CMOV 7064 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7065 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7066 __ bind(Lskip); 7067 %} 7068 ins_pipe(pipe_slow); 7069 %} 7070 7071 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7072 // %{ 7073 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7074 7075 // ins_cost(200); // XXX 7076 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7077 // "movss $dst, $src\n" 7078 // "skip:" %} 7079 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7080 // ins_pipe(pipe_slow); 7081 // %} 7082 7083 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7084 %{ 7085 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7086 7087 ins_cost(200); // XXX 7088 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7089 "movss $dst, $src\n" 7090 "skip:" %} 7091 ins_encode %{ 7092 Label Lskip; 7093 // Invert sense of branch from sense of CMOV 7094 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7095 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7096 __ bind(Lskip); 7097 %} 7098 ins_pipe(pipe_slow); 7099 %} 7100 7101 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7102 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7103 ins_cost(200); 7104 expand %{ 7105 cmovF_regU(cop, cr, dst, src); 7106 %} 7107 %} 7108 7109 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7110 %{ 7111 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7112 7113 ins_cost(200); // XXX 7114 format %{ "jn$cop skip\t# signed cmove double\n\t" 7115 "movsd $dst, $src\n" 7116 "skip:" %} 7117 ins_encode %{ 7118 Label Lskip; 7119 // Invert sense of branch from sense of CMOV 7120 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7121 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7122 __ bind(Lskip); 7123 %} 7124 ins_pipe(pipe_slow); 7125 %} 7126 7127 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7128 %{ 7129 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7130 7131 ins_cost(200); // XXX 7132 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7133 "movsd $dst, $src\n" 7134 "skip:" %} 7135 ins_encode %{ 7136 Label Lskip; 7137 // Invert sense of branch from sense of CMOV 7138 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7139 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7140 __ bind(Lskip); 7141 %} 7142 ins_pipe(pipe_slow); 7143 %} 7144 7145 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7146 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7147 ins_cost(200); 7148 expand %{ 7149 cmovD_regU(cop, cr, dst, src); 7150 %} 7151 %} 7152 7153 //----------Arithmetic Instructions-------------------------------------------- 7154 //----------Addition Instructions---------------------------------------------- 7155 7156 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7157 %{ 7158 match(Set dst (AddI dst src)); 7159 effect(KILL cr); 7160 7161 format %{ "addl $dst, $src\t# int" %} 7162 opcode(0x03); 7163 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7164 ins_pipe(ialu_reg_reg); 7165 %} 7166 7167 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7168 %{ 7169 match(Set dst (AddI dst src)); 7170 effect(KILL cr); 7171 7172 format %{ "addl $dst, $src\t# int" %} 7173 opcode(0x81, 0x00); /* /0 id */ 7174 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7175 ins_pipe( ialu_reg ); 7176 %} 7177 7178 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7179 %{ 7180 match(Set dst (AddI dst (LoadI src))); 7181 effect(KILL cr); 7182 7183 ins_cost(125); // XXX 7184 format %{ "addl $dst, $src\t# int" %} 7185 opcode(0x03); 7186 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7187 ins_pipe(ialu_reg_mem); 7188 %} 7189 7190 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7191 %{ 7192 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7193 effect(KILL cr); 7194 7195 ins_cost(150); // XXX 7196 format %{ "addl $dst, $src\t# int" %} 7197 opcode(0x01); /* Opcode 01 /r */ 7198 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7199 ins_pipe(ialu_mem_reg); 7200 %} 7201 7202 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7203 %{ 7204 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7205 effect(KILL cr); 7206 7207 ins_cost(125); // XXX 7208 format %{ "addl $dst, $src\t# int" %} 7209 opcode(0x81); /* Opcode 81 /0 id */ 7210 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7211 ins_pipe(ialu_mem_imm); 7212 %} 7213 7214 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7215 %{ 7216 predicate(UseIncDec); 7217 match(Set dst (AddI dst src)); 7218 effect(KILL cr); 7219 7220 format %{ "incl $dst\t# int" %} 7221 opcode(0xFF, 0x00); // FF /0 7222 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7223 ins_pipe(ialu_reg); 7224 %} 7225 7226 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7227 %{ 7228 predicate(UseIncDec); 7229 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7230 effect(KILL cr); 7231 7232 ins_cost(125); // XXX 7233 format %{ "incl $dst\t# int" %} 7234 opcode(0xFF); /* Opcode FF /0 */ 7235 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7236 ins_pipe(ialu_mem_imm); 7237 %} 7238 7239 // XXX why does that use AddI 7240 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7241 %{ 7242 predicate(UseIncDec); 7243 match(Set dst (AddI dst src)); 7244 effect(KILL cr); 7245 7246 format %{ "decl $dst\t# int" %} 7247 opcode(0xFF, 0x01); // FF /1 7248 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7249 ins_pipe(ialu_reg); 7250 %} 7251 7252 // XXX why does that use AddI 7253 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7254 %{ 7255 predicate(UseIncDec); 7256 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7257 effect(KILL cr); 7258 7259 ins_cost(125); // XXX 7260 format %{ "decl $dst\t# int" %} 7261 opcode(0xFF); /* Opcode FF /1 */ 7262 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7263 ins_pipe(ialu_mem_imm); 7264 %} 7265 7266 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7267 %{ 7268 match(Set dst (AddI src0 src1)); 7269 7270 ins_cost(110); 7271 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7272 opcode(0x8D); /* 0x8D /r */ 7273 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7274 ins_pipe(ialu_reg_reg); 7275 %} 7276 7277 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7278 %{ 7279 match(Set dst (AddL dst src)); 7280 effect(KILL cr); 7281 7282 format %{ "addq $dst, $src\t# long" %} 7283 opcode(0x03); 7284 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7285 ins_pipe(ialu_reg_reg); 7286 %} 7287 7288 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7289 %{ 7290 match(Set dst (AddL dst src)); 7291 effect(KILL cr); 7292 7293 format %{ "addq $dst, $src\t# long" %} 7294 opcode(0x81, 0x00); /* /0 id */ 7295 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7296 ins_pipe( ialu_reg ); 7297 %} 7298 7299 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7300 %{ 7301 match(Set dst (AddL dst (LoadL src))); 7302 effect(KILL cr); 7303 7304 ins_cost(125); // XXX 7305 format %{ "addq $dst, $src\t# long" %} 7306 opcode(0x03); 7307 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7308 ins_pipe(ialu_reg_mem); 7309 %} 7310 7311 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7312 %{ 7313 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7314 effect(KILL cr); 7315 7316 ins_cost(150); // XXX 7317 format %{ "addq $dst, $src\t# long" %} 7318 opcode(0x01); /* Opcode 01 /r */ 7319 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7320 ins_pipe(ialu_mem_reg); 7321 %} 7322 7323 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7324 %{ 7325 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7326 effect(KILL cr); 7327 7328 ins_cost(125); // XXX 7329 format %{ "addq $dst, $src\t# long" %} 7330 opcode(0x81); /* Opcode 81 /0 id */ 7331 ins_encode(REX_mem_wide(dst), 7332 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7333 ins_pipe(ialu_mem_imm); 7334 %} 7335 7336 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7337 %{ 7338 predicate(UseIncDec); 7339 match(Set dst (AddL dst src)); 7340 effect(KILL cr); 7341 7342 format %{ "incq $dst\t# long" %} 7343 opcode(0xFF, 0x00); // FF /0 7344 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7345 ins_pipe(ialu_reg); 7346 %} 7347 7348 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7349 %{ 7350 predicate(UseIncDec); 7351 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7352 effect(KILL cr); 7353 7354 ins_cost(125); // XXX 7355 format %{ "incq $dst\t# long" %} 7356 opcode(0xFF); /* Opcode FF /0 */ 7357 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7358 ins_pipe(ialu_mem_imm); 7359 %} 7360 7361 // XXX why does that use AddL 7362 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7363 %{ 7364 predicate(UseIncDec); 7365 match(Set dst (AddL dst src)); 7366 effect(KILL cr); 7367 7368 format %{ "decq $dst\t# long" %} 7369 opcode(0xFF, 0x01); // FF /1 7370 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7371 ins_pipe(ialu_reg); 7372 %} 7373 7374 // XXX why does that use AddL 7375 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7376 %{ 7377 predicate(UseIncDec); 7378 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7379 effect(KILL cr); 7380 7381 ins_cost(125); // XXX 7382 format %{ "decq $dst\t# long" %} 7383 opcode(0xFF); /* Opcode FF /1 */ 7384 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7385 ins_pipe(ialu_mem_imm); 7386 %} 7387 7388 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7389 %{ 7390 match(Set dst (AddL src0 src1)); 7391 7392 ins_cost(110); 7393 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7394 opcode(0x8D); /* 0x8D /r */ 7395 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7396 ins_pipe(ialu_reg_reg); 7397 %} 7398 7399 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7400 %{ 7401 match(Set dst (AddP dst src)); 7402 effect(KILL cr); 7403 7404 format %{ "addq $dst, $src\t# ptr" %} 7405 opcode(0x03); 7406 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7407 ins_pipe(ialu_reg_reg); 7408 %} 7409 7410 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7411 %{ 7412 match(Set dst (AddP dst src)); 7413 effect(KILL cr); 7414 7415 format %{ "addq $dst, $src\t# ptr" %} 7416 opcode(0x81, 0x00); /* /0 id */ 7417 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7418 ins_pipe( ialu_reg ); 7419 %} 7420 7421 // XXX addP mem ops ???? 7422 7423 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7424 %{ 7425 match(Set dst (AddP src0 src1)); 7426 7427 ins_cost(110); 7428 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7429 opcode(0x8D); /* 0x8D /r */ 7430 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7431 ins_pipe(ialu_reg_reg); 7432 %} 7433 7434 instruct checkCastPP(rRegP dst) 7435 %{ 7436 match(Set dst (CheckCastPP dst)); 7437 7438 size(0); 7439 format %{ "# checkcastPP of $dst" %} 7440 ins_encode(/* empty encoding */); 7441 ins_pipe(empty); 7442 %} 7443 7444 instruct castPP(rRegP dst) 7445 %{ 7446 match(Set dst (CastPP dst)); 7447 7448 size(0); 7449 format %{ "# castPP of $dst" %} 7450 ins_encode(/* empty encoding */); 7451 ins_pipe(empty); 7452 %} 7453 7454 instruct castII(rRegI dst) 7455 %{ 7456 match(Set dst (CastII dst)); 7457 7458 size(0); 7459 format %{ "# castII of $dst" %} 7460 ins_encode(/* empty encoding */); 7461 ins_cost(0); 7462 ins_pipe(empty); 7463 %} 7464 7465 // LoadP-locked same as a regular LoadP when used with compare-swap 7466 instruct loadPLocked(rRegP dst, memory mem) 7467 %{ 7468 match(Set dst (LoadPLocked mem)); 7469 7470 ins_cost(125); // XXX 7471 format %{ "movq $dst, $mem\t# ptr locked" %} 7472 opcode(0x8B); 7473 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7474 ins_pipe(ialu_reg_mem); // XXX 7475 %} 7476 7477 // Conditional-store of the updated heap-top. 7478 // Used during allocation of the shared heap. 7479 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7480 7481 instruct storePConditional(memory heap_top_ptr, 7482 rax_RegP oldval, rRegP newval, 7483 rFlagsReg cr) 7484 %{ 7485 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7486 7487 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7488 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7489 opcode(0x0F, 0xB1); 7490 ins_encode(lock_prefix, 7491 REX_reg_mem_wide(newval, heap_top_ptr), 7492 OpcP, OpcS, 7493 reg_mem(newval, heap_top_ptr)); 7494 ins_pipe(pipe_cmpxchg); 7495 %} 7496 7497 // Conditional-store of an int value. 7498 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7499 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7500 %{ 7501 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7502 effect(KILL oldval); 7503 7504 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7505 opcode(0x0F, 0xB1); 7506 ins_encode(lock_prefix, 7507 REX_reg_mem(newval, mem), 7508 OpcP, OpcS, 7509 reg_mem(newval, mem)); 7510 ins_pipe(pipe_cmpxchg); 7511 %} 7512 7513 // Conditional-store of a long value. 7514 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7515 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7516 %{ 7517 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7518 effect(KILL oldval); 7519 7520 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7521 opcode(0x0F, 0xB1); 7522 ins_encode(lock_prefix, 7523 REX_reg_mem_wide(newval, mem), 7524 OpcP, OpcS, 7525 reg_mem(newval, mem)); 7526 ins_pipe(pipe_cmpxchg); 7527 %} 7528 7529 7530 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7531 instruct compareAndSwapP(rRegI res, 7532 memory mem_ptr, 7533 rax_RegP oldval, rRegP newval, 7534 rFlagsReg cr) 7535 %{ 7536 predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); 7537 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7538 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7539 effect(KILL cr, KILL oldval); 7540 7541 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7542 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7543 "sete $res\n\t" 7544 "movzbl $res, $res" %} 7545 opcode(0x0F, 0xB1); 7546 ins_encode(lock_prefix, 7547 REX_reg_mem_wide(newval, mem_ptr), 7548 OpcP, OpcS, 7549 reg_mem(newval, mem_ptr), 7550 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7551 REX_reg_breg(res, res), // movzbl 7552 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7553 ins_pipe( pipe_cmpxchg ); 7554 %} 7555 7556 instruct compareAndSwapP_shenandoah(rRegI res, 7557 memory mem_ptr, 7558 rRegP tmp1, rRegP tmp2, 7559 rax_RegP oldval, rRegP newval, 7560 rFlagsReg cr) 7561 %{ 7562 predicate(VM_Version::supports_cx8() && UseShenandoahGC); 7563 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7564 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7565 effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 7566 7567 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7568 7569 ins_encode %{ 7570 __ cmpxchg_oop($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7571 false, // swap 7572 false, $tmp1$$Register, $tmp2$$Register 7573 ); 7574 %} 7575 ins_pipe( pipe_cmpxchg ); 7576 %} 7577 7578 instruct compareAndSwapL(rRegI res, 7579 memory mem_ptr, 7580 rax_RegL oldval, rRegL newval, 7581 rFlagsReg cr) 7582 %{ 7583 predicate(VM_Version::supports_cx8()); 7584 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7585 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7586 effect(KILL cr, KILL oldval); 7587 7588 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7589 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7590 "sete $res\n\t" 7591 "movzbl $res, $res" %} 7592 opcode(0x0F, 0xB1); 7593 ins_encode(lock_prefix, 7594 REX_reg_mem_wide(newval, mem_ptr), 7595 OpcP, OpcS, 7596 reg_mem(newval, mem_ptr), 7597 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7598 REX_reg_breg(res, res), // movzbl 7599 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7600 ins_pipe( pipe_cmpxchg ); 7601 %} 7602 7603 instruct compareAndSwapI(rRegI res, 7604 memory mem_ptr, 7605 rax_RegI oldval, rRegI newval, 7606 rFlagsReg cr) 7607 %{ 7608 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7609 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7610 effect(KILL cr, KILL oldval); 7611 7612 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7613 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7614 "sete $res\n\t" 7615 "movzbl $res, $res" %} 7616 opcode(0x0F, 0xB1); 7617 ins_encode(lock_prefix, 7618 REX_reg_mem(newval, mem_ptr), 7619 OpcP, OpcS, 7620 reg_mem(newval, mem_ptr), 7621 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7622 REX_reg_breg(res, res), // movzbl 7623 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7624 ins_pipe( pipe_cmpxchg ); 7625 %} 7626 7627 instruct compareAndSwapB(rRegI res, 7628 memory mem_ptr, 7629 rax_RegI oldval, rRegI newval, 7630 rFlagsReg cr) 7631 %{ 7632 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7633 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7634 effect(KILL cr, KILL oldval); 7635 7636 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7637 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7638 "sete $res\n\t" 7639 "movzbl $res, $res" %} 7640 opcode(0x0F, 0xB0); 7641 ins_encode(lock_prefix, 7642 REX_breg_mem(newval, mem_ptr), 7643 OpcP, OpcS, 7644 reg_mem(newval, mem_ptr), 7645 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7646 REX_reg_breg(res, res), // movzbl 7647 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7648 ins_pipe( pipe_cmpxchg ); 7649 %} 7650 7651 instruct compareAndSwapS(rRegI res, 7652 memory mem_ptr, 7653 rax_RegI oldval, rRegI newval, 7654 rFlagsReg cr) 7655 %{ 7656 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7657 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7658 effect(KILL cr, KILL oldval); 7659 7660 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7661 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7662 "sete $res\n\t" 7663 "movzbl $res, $res" %} 7664 opcode(0x0F, 0xB1); 7665 ins_encode(lock_prefix, 7666 SizePrefix, 7667 REX_reg_mem(newval, mem_ptr), 7668 OpcP, OpcS, 7669 reg_mem(newval, mem_ptr), 7670 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7671 REX_reg_breg(res, res), // movzbl 7672 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7673 ins_pipe( pipe_cmpxchg ); 7674 %} 7675 7676 instruct compareAndSwapN(rRegI res, 7677 memory mem_ptr, 7678 rax_RegN oldval, rRegN newval, 7679 rFlagsReg cr) %{ 7680 predicate(!UseShenandoahGC); 7681 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7682 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7683 effect(KILL cr, KILL oldval); 7684 7685 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7686 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7687 "sete $res\n\t" 7688 "movzbl $res, $res" %} 7689 opcode(0x0F, 0xB1); 7690 ins_encode(lock_prefix, 7691 REX_reg_mem(newval, mem_ptr), 7692 OpcP, OpcS, 7693 reg_mem(newval, mem_ptr), 7694 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7695 REX_reg_breg(res, res), // movzbl 7696 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7697 ins_pipe( pipe_cmpxchg ); 7698 %} 7699 7700 instruct compareAndSwapN_shenandoah(rRegI res, 7701 memory mem_ptr, 7702 rRegP tmp1, rRegP tmp2, 7703 rax_RegN oldval, rRegN newval, 7704 rFlagsReg cr) %{ 7705 predicate(UseShenandoahGC); 7706 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7707 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7708 effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 7709 7710 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7711 7712 ins_encode %{ 7713 __ cmpxchg_oop($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7714 false, // swap 7715 false, $tmp1$$Register, $tmp2$$Register 7716 ); 7717 %} 7718 ins_pipe( pipe_cmpxchg ); 7719 %} 7720 7721 instruct compareAndExchangeB( 7722 memory mem_ptr, 7723 rax_RegI oldval, rRegI newval, 7724 rFlagsReg cr) 7725 %{ 7726 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7727 effect(KILL cr); 7728 7729 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7730 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7731 opcode(0x0F, 0xB0); 7732 ins_encode(lock_prefix, 7733 REX_breg_mem(newval, mem_ptr), 7734 OpcP, OpcS, 7735 reg_mem(newval, mem_ptr) // lock cmpxchg 7736 ); 7737 ins_pipe( pipe_cmpxchg ); 7738 %} 7739 7740 instruct compareAndExchangeS( 7741 memory mem_ptr, 7742 rax_RegI oldval, rRegI newval, 7743 rFlagsReg cr) 7744 %{ 7745 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7746 effect(KILL cr); 7747 7748 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7749 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7750 opcode(0x0F, 0xB1); 7751 ins_encode(lock_prefix, 7752 SizePrefix, 7753 REX_reg_mem(newval, mem_ptr), 7754 OpcP, OpcS, 7755 reg_mem(newval, mem_ptr) // lock cmpxchg 7756 ); 7757 ins_pipe( pipe_cmpxchg ); 7758 %} 7759 7760 instruct compareAndExchangeI( 7761 memory mem_ptr, 7762 rax_RegI oldval, rRegI newval, 7763 rFlagsReg cr) 7764 %{ 7765 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7766 effect(KILL cr); 7767 7768 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7769 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7770 opcode(0x0F, 0xB1); 7771 ins_encode(lock_prefix, 7772 REX_reg_mem(newval, mem_ptr), 7773 OpcP, OpcS, 7774 reg_mem(newval, mem_ptr) // lock cmpxchg 7775 ); 7776 ins_pipe( pipe_cmpxchg ); 7777 %} 7778 7779 instruct compareAndExchangeL( 7780 memory mem_ptr, 7781 rax_RegL oldval, rRegL newval, 7782 rFlagsReg cr) 7783 %{ 7784 predicate(VM_Version::supports_cx8()); 7785 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7786 effect(KILL cr); 7787 7788 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7789 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7790 opcode(0x0F, 0xB1); 7791 ins_encode(lock_prefix, 7792 REX_reg_mem_wide(newval, mem_ptr), 7793 OpcP, OpcS, 7794 reg_mem(newval, mem_ptr) // lock cmpxchg 7795 ); 7796 ins_pipe( pipe_cmpxchg ); 7797 %} 7798 7799 instruct compareAndExchangeN( 7800 memory mem_ptr, 7801 rax_RegN oldval, rRegN newval, 7802 rFlagsReg cr) %{ 7803 predicate(!UseShenandoahGC); 7804 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7805 effect(KILL cr); 7806 7807 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7808 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7809 opcode(0x0F, 0xB1); 7810 ins_encode(lock_prefix, 7811 REX_reg_mem(newval, mem_ptr), 7812 OpcP, OpcS, 7813 reg_mem(newval, mem_ptr) // lock cmpxchg 7814 ); 7815 ins_pipe( pipe_cmpxchg ); 7816 %} 7817 7818 instruct compareAndExchangeN_shenandoah(memory mem_ptr, 7819 rax_RegN oldval, rRegN newval, 7820 rRegP tmp1, rRegP tmp2, 7821 rFlagsReg cr) %{ 7822 predicate(UseShenandoahGC); 7823 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7824 effect(TEMP tmp1, TEMP tmp2, KILL cr); 7825 7826 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7827 7828 ins_encode %{ 7829 __ cmpxchg_oop(NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7830 true, // exchange 7831 false, $tmp1$$Register, $tmp2$$Register 7832 ); 7833 %} 7834 ins_pipe( pipe_cmpxchg ); 7835 %} 7836 7837 instruct compareAndExchangeP( 7838 memory mem_ptr, 7839 rax_RegP oldval, rRegP newval, 7840 rFlagsReg cr) 7841 %{ 7842 predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); 7843 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7844 effect(KILL cr); 7845 7846 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7847 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7848 opcode(0x0F, 0xB1); 7849 ins_encode(lock_prefix, 7850 REX_reg_mem_wide(newval, mem_ptr), 7851 OpcP, OpcS, 7852 reg_mem(newval, mem_ptr) // lock cmpxchg 7853 ); 7854 ins_pipe( pipe_cmpxchg ); 7855 %} 7856 7857 instruct compareAndExchangeP_shenandoah(memory mem_ptr, 7858 rax_RegP oldval, rRegP newval, 7859 rRegP tmp1, rRegP tmp2, 7860 rFlagsReg cr) 7861 %{ 7862 predicate(VM_Version::supports_cx8() && UseShenandoahGC); 7863 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7864 effect(KILL cr, TEMP tmp1, TEMP tmp2); 7865 ins_cost(1000); 7866 7867 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7868 7869 ins_encode %{ 7870 __ cmpxchg_oop(NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7871 true, // exchange 7872 false, $tmp1$$Register, $tmp2$$Register 7873 ); 7874 %} 7875 ins_pipe( pipe_cmpxchg ); 7876 %} 7877 7878 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7879 predicate(n->as_LoadStore()->result_not_used()); 7880 match(Set dummy (GetAndAddB mem add)); 7881 effect(KILL cr); 7882 format %{ "ADDB [$mem],$add" %} 7883 ins_encode %{ 7884 if (os::is_MP()) { __ lock(); } 7885 __ addb($mem$$Address, $add$$constant); 7886 %} 7887 ins_pipe( pipe_cmpxchg ); 7888 %} 7889 7890 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7891 match(Set newval (GetAndAddB mem newval)); 7892 effect(KILL cr); 7893 format %{ "XADDB [$mem],$newval" %} 7894 ins_encode %{ 7895 if (os::is_MP()) { __ lock(); } 7896 __ xaddb($mem$$Address, $newval$$Register); 7897 %} 7898 ins_pipe( pipe_cmpxchg ); 7899 %} 7900 7901 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7902 predicate(n->as_LoadStore()->result_not_used()); 7903 match(Set dummy (GetAndAddS mem add)); 7904 effect(KILL cr); 7905 format %{ "ADDW [$mem],$add" %} 7906 ins_encode %{ 7907 if (os::is_MP()) { __ lock(); } 7908 __ addw($mem$$Address, $add$$constant); 7909 %} 7910 ins_pipe( pipe_cmpxchg ); 7911 %} 7912 7913 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7914 match(Set newval (GetAndAddS mem newval)); 7915 effect(KILL cr); 7916 format %{ "XADDW [$mem],$newval" %} 7917 ins_encode %{ 7918 if (os::is_MP()) { __ lock(); } 7919 __ xaddw($mem$$Address, $newval$$Register); 7920 %} 7921 ins_pipe( pipe_cmpxchg ); 7922 %} 7923 7924 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7925 predicate(n->as_LoadStore()->result_not_used()); 7926 match(Set dummy (GetAndAddI mem add)); 7927 effect(KILL cr); 7928 format %{ "ADDL [$mem],$add" %} 7929 ins_encode %{ 7930 if (os::is_MP()) { __ lock(); } 7931 __ addl($mem$$Address, $add$$constant); 7932 %} 7933 ins_pipe( pipe_cmpxchg ); 7934 %} 7935 7936 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7937 match(Set newval (GetAndAddI mem newval)); 7938 effect(KILL cr); 7939 format %{ "XADDL [$mem],$newval" %} 7940 ins_encode %{ 7941 if (os::is_MP()) { __ lock(); } 7942 __ xaddl($mem$$Address, $newval$$Register); 7943 %} 7944 ins_pipe( pipe_cmpxchg ); 7945 %} 7946 7947 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7948 predicate(n->as_LoadStore()->result_not_used()); 7949 match(Set dummy (GetAndAddL mem add)); 7950 effect(KILL cr); 7951 format %{ "ADDQ [$mem],$add" %} 7952 ins_encode %{ 7953 if (os::is_MP()) { __ lock(); } 7954 __ addq($mem$$Address, $add$$constant); 7955 %} 7956 ins_pipe( pipe_cmpxchg ); 7957 %} 7958 7959 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7960 match(Set newval (GetAndAddL mem newval)); 7961 effect(KILL cr); 7962 format %{ "XADDQ [$mem],$newval" %} 7963 ins_encode %{ 7964 if (os::is_MP()) { __ lock(); } 7965 __ xaddq($mem$$Address, $newval$$Register); 7966 %} 7967 ins_pipe( pipe_cmpxchg ); 7968 %} 7969 7970 instruct xchgB( memory mem, rRegI newval) %{ 7971 match(Set newval (GetAndSetB mem newval)); 7972 format %{ "XCHGB $newval,[$mem]" %} 7973 ins_encode %{ 7974 __ xchgb($newval$$Register, $mem$$Address); 7975 %} 7976 ins_pipe( pipe_cmpxchg ); 7977 %} 7978 7979 instruct xchgS( memory mem, rRegI newval) %{ 7980 match(Set newval (GetAndSetS mem newval)); 7981 format %{ "XCHGW $newval,[$mem]" %} 7982 ins_encode %{ 7983 __ xchgw($newval$$Register, $mem$$Address); 7984 %} 7985 ins_pipe( pipe_cmpxchg ); 7986 %} 7987 7988 instruct xchgI( memory mem, rRegI newval) %{ 7989 match(Set newval (GetAndSetI mem newval)); 7990 format %{ "XCHGL $newval,[$mem]" %} 7991 ins_encode %{ 7992 __ xchgl($newval$$Register, $mem$$Address); 7993 %} 7994 ins_pipe( pipe_cmpxchg ); 7995 %} 7996 7997 instruct xchgL( memory mem, rRegL newval) %{ 7998 match(Set newval (GetAndSetL mem newval)); 7999 format %{ "XCHGL $newval,[$mem]" %} 8000 ins_encode %{ 8001 __ xchgq($newval$$Register, $mem$$Address); 8002 %} 8003 ins_pipe( pipe_cmpxchg ); 8004 %} 8005 8006 instruct xchgP( memory mem, rRegP newval) %{ 8007 match(Set newval (GetAndSetP mem newval)); 8008 format %{ "XCHGQ $newval,[$mem]" %} 8009 ins_encode %{ 8010 __ xchgq($newval$$Register, $mem$$Address); 8011 %} 8012 ins_pipe( pipe_cmpxchg ); 8013 %} 8014 8015 instruct xchgN( memory mem, rRegN newval) %{ 8016 match(Set newval (GetAndSetN mem newval)); 8017 format %{ "XCHGL $newval,$mem]" %} 8018 ins_encode %{ 8019 __ xchgl($newval$$Register, $mem$$Address); 8020 %} 8021 ins_pipe( pipe_cmpxchg ); 8022 %} 8023 8024 //----------Subtraction Instructions------------------------------------------- 8025 8026 // Integer Subtraction Instructions 8027 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8028 %{ 8029 match(Set dst (SubI dst src)); 8030 effect(KILL cr); 8031 8032 format %{ "subl $dst, $src\t# int" %} 8033 opcode(0x2B); 8034 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8035 ins_pipe(ialu_reg_reg); 8036 %} 8037 8038 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8039 %{ 8040 match(Set dst (SubI dst src)); 8041 effect(KILL cr); 8042 8043 format %{ "subl $dst, $src\t# int" %} 8044 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8045 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8046 ins_pipe(ialu_reg); 8047 %} 8048 8049 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8050 %{ 8051 match(Set dst (SubI dst (LoadI src))); 8052 effect(KILL cr); 8053 8054 ins_cost(125); 8055 format %{ "subl $dst, $src\t# int" %} 8056 opcode(0x2B); 8057 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8058 ins_pipe(ialu_reg_mem); 8059 %} 8060 8061 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8062 %{ 8063 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8064 effect(KILL cr); 8065 8066 ins_cost(150); 8067 format %{ "subl $dst, $src\t# int" %} 8068 opcode(0x29); /* Opcode 29 /r */ 8069 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8070 ins_pipe(ialu_mem_reg); 8071 %} 8072 8073 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8074 %{ 8075 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8076 effect(KILL cr); 8077 8078 ins_cost(125); // XXX 8079 format %{ "subl $dst, $src\t# int" %} 8080 opcode(0x81); /* Opcode 81 /5 id */ 8081 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8082 ins_pipe(ialu_mem_imm); 8083 %} 8084 8085 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8086 %{ 8087 match(Set dst (SubL dst src)); 8088 effect(KILL cr); 8089 8090 format %{ "subq $dst, $src\t# long" %} 8091 opcode(0x2B); 8092 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8093 ins_pipe(ialu_reg_reg); 8094 %} 8095 8096 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8097 %{ 8098 match(Set dst (SubL dst src)); 8099 effect(KILL cr); 8100 8101 format %{ "subq $dst, $src\t# long" %} 8102 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8103 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8104 ins_pipe(ialu_reg); 8105 %} 8106 8107 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8108 %{ 8109 match(Set dst (SubL dst (LoadL src))); 8110 effect(KILL cr); 8111 8112 ins_cost(125); 8113 format %{ "subq $dst, $src\t# long" %} 8114 opcode(0x2B); 8115 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8116 ins_pipe(ialu_reg_mem); 8117 %} 8118 8119 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8120 %{ 8121 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8122 effect(KILL cr); 8123 8124 ins_cost(150); 8125 format %{ "subq $dst, $src\t# long" %} 8126 opcode(0x29); /* Opcode 29 /r */ 8127 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8128 ins_pipe(ialu_mem_reg); 8129 %} 8130 8131 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8132 %{ 8133 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8134 effect(KILL cr); 8135 8136 ins_cost(125); // XXX 8137 format %{ "subq $dst, $src\t# long" %} 8138 opcode(0x81); /* Opcode 81 /5 id */ 8139 ins_encode(REX_mem_wide(dst), 8140 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8141 ins_pipe(ialu_mem_imm); 8142 %} 8143 8144 // Subtract from a pointer 8145 // XXX hmpf??? 8146 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8147 %{ 8148 match(Set dst (AddP dst (SubI zero src))); 8149 effect(KILL cr); 8150 8151 format %{ "subq $dst, $src\t# ptr - int" %} 8152 opcode(0x2B); 8153 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8154 ins_pipe(ialu_reg_reg); 8155 %} 8156 8157 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8158 %{ 8159 match(Set dst (SubI zero dst)); 8160 effect(KILL cr); 8161 8162 format %{ "negl $dst\t# int" %} 8163 opcode(0xF7, 0x03); // Opcode F7 /3 8164 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8165 ins_pipe(ialu_reg); 8166 %} 8167 8168 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8169 %{ 8170 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8171 effect(KILL cr); 8172 8173 format %{ "negl $dst\t# int" %} 8174 opcode(0xF7, 0x03); // Opcode F7 /3 8175 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8176 ins_pipe(ialu_reg); 8177 %} 8178 8179 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8180 %{ 8181 match(Set dst (SubL zero dst)); 8182 effect(KILL cr); 8183 8184 format %{ "negq $dst\t# long" %} 8185 opcode(0xF7, 0x03); // Opcode F7 /3 8186 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8187 ins_pipe(ialu_reg); 8188 %} 8189 8190 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8191 %{ 8192 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8193 effect(KILL cr); 8194 8195 format %{ "negq $dst\t# long" %} 8196 opcode(0xF7, 0x03); // Opcode F7 /3 8197 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8198 ins_pipe(ialu_reg); 8199 %} 8200 8201 //----------Multiplication/Division Instructions------------------------------- 8202 // Integer Multiplication Instructions 8203 // Multiply Register 8204 8205 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8206 %{ 8207 match(Set dst (MulI dst src)); 8208 effect(KILL cr); 8209 8210 ins_cost(300); 8211 format %{ "imull $dst, $src\t# int" %} 8212 opcode(0x0F, 0xAF); 8213 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8214 ins_pipe(ialu_reg_reg_alu0); 8215 %} 8216 8217 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8218 %{ 8219 match(Set dst (MulI src imm)); 8220 effect(KILL cr); 8221 8222 ins_cost(300); 8223 format %{ "imull $dst, $src, $imm\t# int" %} 8224 opcode(0x69); /* 69 /r id */ 8225 ins_encode(REX_reg_reg(dst, src), 8226 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8227 ins_pipe(ialu_reg_reg_alu0); 8228 %} 8229 8230 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8231 %{ 8232 match(Set dst (MulI dst (LoadI src))); 8233 effect(KILL cr); 8234 8235 ins_cost(350); 8236 format %{ "imull $dst, $src\t# int" %} 8237 opcode(0x0F, 0xAF); 8238 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8239 ins_pipe(ialu_reg_mem_alu0); 8240 %} 8241 8242 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8243 %{ 8244 match(Set dst (MulI (LoadI src) imm)); 8245 effect(KILL cr); 8246 8247 ins_cost(300); 8248 format %{ "imull $dst, $src, $imm\t# int" %} 8249 opcode(0x69); /* 69 /r id */ 8250 ins_encode(REX_reg_mem(dst, src), 8251 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8252 ins_pipe(ialu_reg_mem_alu0); 8253 %} 8254 8255 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8256 %{ 8257 match(Set dst (MulL dst src)); 8258 effect(KILL cr); 8259 8260 ins_cost(300); 8261 format %{ "imulq $dst, $src\t# long" %} 8262 opcode(0x0F, 0xAF); 8263 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8264 ins_pipe(ialu_reg_reg_alu0); 8265 %} 8266 8267 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8268 %{ 8269 match(Set dst (MulL src imm)); 8270 effect(KILL cr); 8271 8272 ins_cost(300); 8273 format %{ "imulq $dst, $src, $imm\t# long" %} 8274 opcode(0x69); /* 69 /r id */ 8275 ins_encode(REX_reg_reg_wide(dst, src), 8276 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8277 ins_pipe(ialu_reg_reg_alu0); 8278 %} 8279 8280 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8281 %{ 8282 match(Set dst (MulL dst (LoadL src))); 8283 effect(KILL cr); 8284 8285 ins_cost(350); 8286 format %{ "imulq $dst, $src\t# long" %} 8287 opcode(0x0F, 0xAF); 8288 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8289 ins_pipe(ialu_reg_mem_alu0); 8290 %} 8291 8292 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8293 %{ 8294 match(Set dst (MulL (LoadL src) imm)); 8295 effect(KILL cr); 8296 8297 ins_cost(300); 8298 format %{ "imulq $dst, $src, $imm\t# long" %} 8299 opcode(0x69); /* 69 /r id */ 8300 ins_encode(REX_reg_mem_wide(dst, src), 8301 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8302 ins_pipe(ialu_reg_mem_alu0); 8303 %} 8304 8305 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8306 %{ 8307 match(Set dst (MulHiL src rax)); 8308 effect(USE_KILL rax, KILL cr); 8309 8310 ins_cost(300); 8311 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8312 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8313 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8314 ins_pipe(ialu_reg_reg_alu0); 8315 %} 8316 8317 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8318 rFlagsReg cr) 8319 %{ 8320 match(Set rax (DivI rax div)); 8321 effect(KILL rdx, KILL cr); 8322 8323 ins_cost(30*100+10*100); // XXX 8324 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8325 "jne,s normal\n\t" 8326 "xorl rdx, rdx\n\t" 8327 "cmpl $div, -1\n\t" 8328 "je,s done\n" 8329 "normal: cdql\n\t" 8330 "idivl $div\n" 8331 "done:" %} 8332 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8333 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8334 ins_pipe(ialu_reg_reg_alu0); 8335 %} 8336 8337 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8338 rFlagsReg cr) 8339 %{ 8340 match(Set rax (DivL rax div)); 8341 effect(KILL rdx, KILL cr); 8342 8343 ins_cost(30*100+10*100); // XXX 8344 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8345 "cmpq rax, rdx\n\t" 8346 "jne,s normal\n\t" 8347 "xorl rdx, rdx\n\t" 8348 "cmpq $div, -1\n\t" 8349 "je,s done\n" 8350 "normal: cdqq\n\t" 8351 "idivq $div\n" 8352 "done:" %} 8353 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8354 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8355 ins_pipe(ialu_reg_reg_alu0); 8356 %} 8357 8358 // Integer DIVMOD with Register, both quotient and mod results 8359 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8360 rFlagsReg cr) 8361 %{ 8362 match(DivModI rax div); 8363 effect(KILL cr); 8364 8365 ins_cost(30*100+10*100); // XXX 8366 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8367 "jne,s normal\n\t" 8368 "xorl rdx, rdx\n\t" 8369 "cmpl $div, -1\n\t" 8370 "je,s done\n" 8371 "normal: cdql\n\t" 8372 "idivl $div\n" 8373 "done:" %} 8374 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8375 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8376 ins_pipe(pipe_slow); 8377 %} 8378 8379 // Long DIVMOD with Register, both quotient and mod results 8380 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8381 rFlagsReg cr) 8382 %{ 8383 match(DivModL rax div); 8384 effect(KILL cr); 8385 8386 ins_cost(30*100+10*100); // XXX 8387 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8388 "cmpq rax, rdx\n\t" 8389 "jne,s normal\n\t" 8390 "xorl rdx, rdx\n\t" 8391 "cmpq $div, -1\n\t" 8392 "je,s done\n" 8393 "normal: cdqq\n\t" 8394 "idivq $div\n" 8395 "done:" %} 8396 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8397 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8398 ins_pipe(pipe_slow); 8399 %} 8400 8401 //----------- DivL-By-Constant-Expansions-------------------------------------- 8402 // DivI cases are handled by the compiler 8403 8404 // Magic constant, reciprocal of 10 8405 instruct loadConL_0x6666666666666667(rRegL dst) 8406 %{ 8407 effect(DEF dst); 8408 8409 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8410 ins_encode(load_immL(dst, 0x6666666666666667)); 8411 ins_pipe(ialu_reg); 8412 %} 8413 8414 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8415 %{ 8416 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8417 8418 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8419 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8420 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8421 ins_pipe(ialu_reg_reg_alu0); 8422 %} 8423 8424 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8425 %{ 8426 effect(USE_DEF dst, KILL cr); 8427 8428 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8429 opcode(0xC1, 0x7); /* C1 /7 ib */ 8430 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8431 ins_pipe(ialu_reg); 8432 %} 8433 8434 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8435 %{ 8436 effect(USE_DEF dst, KILL cr); 8437 8438 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8439 opcode(0xC1, 0x7); /* C1 /7 ib */ 8440 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8441 ins_pipe(ialu_reg); 8442 %} 8443 8444 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8445 %{ 8446 match(Set dst (DivL src div)); 8447 8448 ins_cost((5+8)*100); 8449 expand %{ 8450 rax_RegL rax; // Killed temp 8451 rFlagsReg cr; // Killed 8452 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8453 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8454 sarL_rReg_63(src, cr); // sarq src, 63 8455 sarL_rReg_2(dst, cr); // sarq rdx, 2 8456 subL_rReg(dst, src, cr); // subl rdx, src 8457 %} 8458 %} 8459 8460 //----------------------------------------------------------------------------- 8461 8462 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8463 rFlagsReg cr) 8464 %{ 8465 match(Set rdx (ModI rax div)); 8466 effect(KILL rax, KILL cr); 8467 8468 ins_cost(300); // XXX 8469 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8470 "jne,s normal\n\t" 8471 "xorl rdx, rdx\n\t" 8472 "cmpl $div, -1\n\t" 8473 "je,s done\n" 8474 "normal: cdql\n\t" 8475 "idivl $div\n" 8476 "done:" %} 8477 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8478 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8479 ins_pipe(ialu_reg_reg_alu0); 8480 %} 8481 8482 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8483 rFlagsReg cr) 8484 %{ 8485 match(Set rdx (ModL rax div)); 8486 effect(KILL rax, KILL cr); 8487 8488 ins_cost(300); // XXX 8489 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8490 "cmpq rax, rdx\n\t" 8491 "jne,s normal\n\t" 8492 "xorl rdx, rdx\n\t" 8493 "cmpq $div, -1\n\t" 8494 "je,s done\n" 8495 "normal: cdqq\n\t" 8496 "idivq $div\n" 8497 "done:" %} 8498 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8499 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8500 ins_pipe(ialu_reg_reg_alu0); 8501 %} 8502 8503 // Integer Shift Instructions 8504 // Shift Left by one 8505 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8506 %{ 8507 match(Set dst (LShiftI dst shift)); 8508 effect(KILL cr); 8509 8510 format %{ "sall $dst, $shift" %} 8511 opcode(0xD1, 0x4); /* D1 /4 */ 8512 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8513 ins_pipe(ialu_reg); 8514 %} 8515 8516 // Shift Left by one 8517 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8518 %{ 8519 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8520 effect(KILL cr); 8521 8522 format %{ "sall $dst, $shift\t" %} 8523 opcode(0xD1, 0x4); /* D1 /4 */ 8524 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8525 ins_pipe(ialu_mem_imm); 8526 %} 8527 8528 // Shift Left by 8-bit immediate 8529 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8530 %{ 8531 match(Set dst (LShiftI dst shift)); 8532 effect(KILL cr); 8533 8534 format %{ "sall $dst, $shift" %} 8535 opcode(0xC1, 0x4); /* C1 /4 ib */ 8536 ins_encode(reg_opc_imm(dst, shift)); 8537 ins_pipe(ialu_reg); 8538 %} 8539 8540 // Shift Left by 8-bit immediate 8541 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8542 %{ 8543 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8544 effect(KILL cr); 8545 8546 format %{ "sall $dst, $shift" %} 8547 opcode(0xC1, 0x4); /* C1 /4 ib */ 8548 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8549 ins_pipe(ialu_mem_imm); 8550 %} 8551 8552 // Shift Left by variable 8553 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8554 %{ 8555 match(Set dst (LShiftI dst shift)); 8556 effect(KILL cr); 8557 8558 format %{ "sall $dst, $shift" %} 8559 opcode(0xD3, 0x4); /* D3 /4 */ 8560 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8561 ins_pipe(ialu_reg_reg); 8562 %} 8563 8564 // Shift Left by variable 8565 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8566 %{ 8567 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8568 effect(KILL cr); 8569 8570 format %{ "sall $dst, $shift" %} 8571 opcode(0xD3, 0x4); /* D3 /4 */ 8572 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8573 ins_pipe(ialu_mem_reg); 8574 %} 8575 8576 // Arithmetic shift right by one 8577 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8578 %{ 8579 match(Set dst (RShiftI dst shift)); 8580 effect(KILL cr); 8581 8582 format %{ "sarl $dst, $shift" %} 8583 opcode(0xD1, 0x7); /* D1 /7 */ 8584 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8585 ins_pipe(ialu_reg); 8586 %} 8587 8588 // Arithmetic shift right by one 8589 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8590 %{ 8591 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8592 effect(KILL cr); 8593 8594 format %{ "sarl $dst, $shift" %} 8595 opcode(0xD1, 0x7); /* D1 /7 */ 8596 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8597 ins_pipe(ialu_mem_imm); 8598 %} 8599 8600 // Arithmetic Shift Right by 8-bit immediate 8601 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8602 %{ 8603 match(Set dst (RShiftI dst shift)); 8604 effect(KILL cr); 8605 8606 format %{ "sarl $dst, $shift" %} 8607 opcode(0xC1, 0x7); /* C1 /7 ib */ 8608 ins_encode(reg_opc_imm(dst, shift)); 8609 ins_pipe(ialu_mem_imm); 8610 %} 8611 8612 // Arithmetic Shift Right by 8-bit immediate 8613 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8614 %{ 8615 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8616 effect(KILL cr); 8617 8618 format %{ "sarl $dst, $shift" %} 8619 opcode(0xC1, 0x7); /* C1 /7 ib */ 8620 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8621 ins_pipe(ialu_mem_imm); 8622 %} 8623 8624 // Arithmetic Shift Right by variable 8625 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8626 %{ 8627 match(Set dst (RShiftI dst shift)); 8628 effect(KILL cr); 8629 8630 format %{ "sarl $dst, $shift" %} 8631 opcode(0xD3, 0x7); /* D3 /7 */ 8632 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8633 ins_pipe(ialu_reg_reg); 8634 %} 8635 8636 // Arithmetic Shift Right by variable 8637 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8638 %{ 8639 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8640 effect(KILL cr); 8641 8642 format %{ "sarl $dst, $shift" %} 8643 opcode(0xD3, 0x7); /* D3 /7 */ 8644 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8645 ins_pipe(ialu_mem_reg); 8646 %} 8647 8648 // Logical shift right by one 8649 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8650 %{ 8651 match(Set dst (URShiftI dst shift)); 8652 effect(KILL cr); 8653 8654 format %{ "shrl $dst, $shift" %} 8655 opcode(0xD1, 0x5); /* D1 /5 */ 8656 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8657 ins_pipe(ialu_reg); 8658 %} 8659 8660 // Logical shift right by one 8661 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8662 %{ 8663 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8664 effect(KILL cr); 8665 8666 format %{ "shrl $dst, $shift" %} 8667 opcode(0xD1, 0x5); /* D1 /5 */ 8668 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8669 ins_pipe(ialu_mem_imm); 8670 %} 8671 8672 // Logical Shift Right by 8-bit immediate 8673 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8674 %{ 8675 match(Set dst (URShiftI dst shift)); 8676 effect(KILL cr); 8677 8678 format %{ "shrl $dst, $shift" %} 8679 opcode(0xC1, 0x5); /* C1 /5 ib */ 8680 ins_encode(reg_opc_imm(dst, shift)); 8681 ins_pipe(ialu_reg); 8682 %} 8683 8684 // Logical Shift Right by 8-bit immediate 8685 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8686 %{ 8687 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8688 effect(KILL cr); 8689 8690 format %{ "shrl $dst, $shift" %} 8691 opcode(0xC1, 0x5); /* C1 /5 ib */ 8692 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8693 ins_pipe(ialu_mem_imm); 8694 %} 8695 8696 // Logical Shift Right by variable 8697 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8698 %{ 8699 match(Set dst (URShiftI dst shift)); 8700 effect(KILL cr); 8701 8702 format %{ "shrl $dst, $shift" %} 8703 opcode(0xD3, 0x5); /* D3 /5 */ 8704 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8705 ins_pipe(ialu_reg_reg); 8706 %} 8707 8708 // Logical Shift Right by variable 8709 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8710 %{ 8711 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8712 effect(KILL cr); 8713 8714 format %{ "shrl $dst, $shift" %} 8715 opcode(0xD3, 0x5); /* D3 /5 */ 8716 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8717 ins_pipe(ialu_mem_reg); 8718 %} 8719 8720 // Long Shift Instructions 8721 // Shift Left by one 8722 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8723 %{ 8724 match(Set dst (LShiftL dst shift)); 8725 effect(KILL cr); 8726 8727 format %{ "salq $dst, $shift" %} 8728 opcode(0xD1, 0x4); /* D1 /4 */ 8729 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8730 ins_pipe(ialu_reg); 8731 %} 8732 8733 // Shift Left by one 8734 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8735 %{ 8736 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8737 effect(KILL cr); 8738 8739 format %{ "salq $dst, $shift" %} 8740 opcode(0xD1, 0x4); /* D1 /4 */ 8741 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8742 ins_pipe(ialu_mem_imm); 8743 %} 8744 8745 // Shift Left by 8-bit immediate 8746 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8747 %{ 8748 match(Set dst (LShiftL dst shift)); 8749 effect(KILL cr); 8750 8751 format %{ "salq $dst, $shift" %} 8752 opcode(0xC1, 0x4); /* C1 /4 ib */ 8753 ins_encode(reg_opc_imm_wide(dst, shift)); 8754 ins_pipe(ialu_reg); 8755 %} 8756 8757 // Shift Left by 8-bit immediate 8758 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8759 %{ 8760 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8761 effect(KILL cr); 8762 8763 format %{ "salq $dst, $shift" %} 8764 opcode(0xC1, 0x4); /* C1 /4 ib */ 8765 ins_encode(REX_mem_wide(dst), OpcP, 8766 RM_opc_mem(secondary, dst), Con8or32(shift)); 8767 ins_pipe(ialu_mem_imm); 8768 %} 8769 8770 // Shift Left by variable 8771 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8772 %{ 8773 match(Set dst (LShiftL dst shift)); 8774 effect(KILL cr); 8775 8776 format %{ "salq $dst, $shift" %} 8777 opcode(0xD3, 0x4); /* D3 /4 */ 8778 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8779 ins_pipe(ialu_reg_reg); 8780 %} 8781 8782 // Shift Left by variable 8783 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8784 %{ 8785 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8786 effect(KILL cr); 8787 8788 format %{ "salq $dst, $shift" %} 8789 opcode(0xD3, 0x4); /* D3 /4 */ 8790 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8791 ins_pipe(ialu_mem_reg); 8792 %} 8793 8794 // Arithmetic shift right by one 8795 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8796 %{ 8797 match(Set dst (RShiftL dst shift)); 8798 effect(KILL cr); 8799 8800 format %{ "sarq $dst, $shift" %} 8801 opcode(0xD1, 0x7); /* D1 /7 */ 8802 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8803 ins_pipe(ialu_reg); 8804 %} 8805 8806 // Arithmetic shift right by one 8807 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8808 %{ 8809 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8810 effect(KILL cr); 8811 8812 format %{ "sarq $dst, $shift" %} 8813 opcode(0xD1, 0x7); /* D1 /7 */ 8814 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8815 ins_pipe(ialu_mem_imm); 8816 %} 8817 8818 // Arithmetic Shift Right by 8-bit immediate 8819 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8820 %{ 8821 match(Set dst (RShiftL dst shift)); 8822 effect(KILL cr); 8823 8824 format %{ "sarq $dst, $shift" %} 8825 opcode(0xC1, 0x7); /* C1 /7 ib */ 8826 ins_encode(reg_opc_imm_wide(dst, shift)); 8827 ins_pipe(ialu_mem_imm); 8828 %} 8829 8830 // Arithmetic Shift Right by 8-bit immediate 8831 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8832 %{ 8833 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8834 effect(KILL cr); 8835 8836 format %{ "sarq $dst, $shift" %} 8837 opcode(0xC1, 0x7); /* C1 /7 ib */ 8838 ins_encode(REX_mem_wide(dst), OpcP, 8839 RM_opc_mem(secondary, dst), Con8or32(shift)); 8840 ins_pipe(ialu_mem_imm); 8841 %} 8842 8843 // Arithmetic Shift Right by variable 8844 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8845 %{ 8846 match(Set dst (RShiftL dst shift)); 8847 effect(KILL cr); 8848 8849 format %{ "sarq $dst, $shift" %} 8850 opcode(0xD3, 0x7); /* D3 /7 */ 8851 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8852 ins_pipe(ialu_reg_reg); 8853 %} 8854 8855 // Arithmetic Shift Right by variable 8856 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8857 %{ 8858 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8859 effect(KILL cr); 8860 8861 format %{ "sarq $dst, $shift" %} 8862 opcode(0xD3, 0x7); /* D3 /7 */ 8863 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8864 ins_pipe(ialu_mem_reg); 8865 %} 8866 8867 // Logical shift right by one 8868 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8869 %{ 8870 match(Set dst (URShiftL dst shift)); 8871 effect(KILL cr); 8872 8873 format %{ "shrq $dst, $shift" %} 8874 opcode(0xD1, 0x5); /* D1 /5 */ 8875 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8876 ins_pipe(ialu_reg); 8877 %} 8878 8879 // Logical shift right by one 8880 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8881 %{ 8882 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8883 effect(KILL cr); 8884 8885 format %{ "shrq $dst, $shift" %} 8886 opcode(0xD1, 0x5); /* D1 /5 */ 8887 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8888 ins_pipe(ialu_mem_imm); 8889 %} 8890 8891 // Logical Shift Right by 8-bit immediate 8892 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8893 %{ 8894 match(Set dst (URShiftL dst shift)); 8895 effect(KILL cr); 8896 8897 format %{ "shrq $dst, $shift" %} 8898 opcode(0xC1, 0x5); /* C1 /5 ib */ 8899 ins_encode(reg_opc_imm_wide(dst, shift)); 8900 ins_pipe(ialu_reg); 8901 %} 8902 8903 8904 // Logical Shift Right by 8-bit immediate 8905 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8906 %{ 8907 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8908 effect(KILL cr); 8909 8910 format %{ "shrq $dst, $shift" %} 8911 opcode(0xC1, 0x5); /* C1 /5 ib */ 8912 ins_encode(REX_mem_wide(dst), OpcP, 8913 RM_opc_mem(secondary, dst), Con8or32(shift)); 8914 ins_pipe(ialu_mem_imm); 8915 %} 8916 8917 // Logical Shift Right by variable 8918 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8919 %{ 8920 match(Set dst (URShiftL dst shift)); 8921 effect(KILL cr); 8922 8923 format %{ "shrq $dst, $shift" %} 8924 opcode(0xD3, 0x5); /* D3 /5 */ 8925 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8926 ins_pipe(ialu_reg_reg); 8927 %} 8928 8929 // Logical Shift Right by variable 8930 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8931 %{ 8932 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8933 effect(KILL cr); 8934 8935 format %{ "shrq $dst, $shift" %} 8936 opcode(0xD3, 0x5); /* D3 /5 */ 8937 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8938 ins_pipe(ialu_mem_reg); 8939 %} 8940 8941 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8942 // This idiom is used by the compiler for the i2b bytecode. 8943 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8944 %{ 8945 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8946 8947 format %{ "movsbl $dst, $src\t# i2b" %} 8948 opcode(0x0F, 0xBE); 8949 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8950 ins_pipe(ialu_reg_reg); 8951 %} 8952 8953 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8954 // This idiom is used by the compiler the i2s bytecode. 8955 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8956 %{ 8957 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8958 8959 format %{ "movswl $dst, $src\t# i2s" %} 8960 opcode(0x0F, 0xBF); 8961 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8962 ins_pipe(ialu_reg_reg); 8963 %} 8964 8965 // ROL/ROR instructions 8966 8967 // ROL expand 8968 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8969 effect(KILL cr, USE_DEF dst); 8970 8971 format %{ "roll $dst" %} 8972 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8973 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8974 ins_pipe(ialu_reg); 8975 %} 8976 8977 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8978 effect(USE_DEF dst, USE shift, KILL cr); 8979 8980 format %{ "roll $dst, $shift" %} 8981 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8982 ins_encode( reg_opc_imm(dst, shift) ); 8983 ins_pipe(ialu_reg); 8984 %} 8985 8986 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8987 %{ 8988 effect(USE_DEF dst, USE shift, KILL cr); 8989 8990 format %{ "roll $dst, $shift" %} 8991 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8992 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8993 ins_pipe(ialu_reg_reg); 8994 %} 8995 // end of ROL expand 8996 8997 // Rotate Left by one 8998 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8999 %{ 9000 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9001 9002 expand %{ 9003 rolI_rReg_imm1(dst, cr); 9004 %} 9005 %} 9006 9007 // Rotate Left by 8-bit immediate 9008 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9009 %{ 9010 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9011 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9012 9013 expand %{ 9014 rolI_rReg_imm8(dst, lshift, cr); 9015 %} 9016 %} 9017 9018 // Rotate Left by variable 9019 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9020 %{ 9021 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9022 9023 expand %{ 9024 rolI_rReg_CL(dst, shift, cr); 9025 %} 9026 %} 9027 9028 // Rotate Left by variable 9029 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9030 %{ 9031 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9032 9033 expand %{ 9034 rolI_rReg_CL(dst, shift, cr); 9035 %} 9036 %} 9037 9038 // ROR expand 9039 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9040 %{ 9041 effect(USE_DEF dst, KILL cr); 9042 9043 format %{ "rorl $dst" %} 9044 opcode(0xD1, 0x1); /* D1 /1 */ 9045 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9046 ins_pipe(ialu_reg); 9047 %} 9048 9049 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9050 %{ 9051 effect(USE_DEF dst, USE shift, KILL cr); 9052 9053 format %{ "rorl $dst, $shift" %} 9054 opcode(0xC1, 0x1); /* C1 /1 ib */ 9055 ins_encode(reg_opc_imm(dst, shift)); 9056 ins_pipe(ialu_reg); 9057 %} 9058 9059 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9060 %{ 9061 effect(USE_DEF dst, USE shift, KILL cr); 9062 9063 format %{ "rorl $dst, $shift" %} 9064 opcode(0xD3, 0x1); /* D3 /1 */ 9065 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9066 ins_pipe(ialu_reg_reg); 9067 %} 9068 // end of ROR expand 9069 9070 // Rotate Right by one 9071 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9072 %{ 9073 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9074 9075 expand %{ 9076 rorI_rReg_imm1(dst, cr); 9077 %} 9078 %} 9079 9080 // Rotate Right by 8-bit immediate 9081 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9082 %{ 9083 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9084 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9085 9086 expand %{ 9087 rorI_rReg_imm8(dst, rshift, cr); 9088 %} 9089 %} 9090 9091 // Rotate Right by variable 9092 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9093 %{ 9094 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9095 9096 expand %{ 9097 rorI_rReg_CL(dst, shift, cr); 9098 %} 9099 %} 9100 9101 // Rotate Right by variable 9102 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9103 %{ 9104 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9105 9106 expand %{ 9107 rorI_rReg_CL(dst, shift, cr); 9108 %} 9109 %} 9110 9111 // for long rotate 9112 // ROL expand 9113 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9114 effect(USE_DEF dst, KILL cr); 9115 9116 format %{ "rolq $dst" %} 9117 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9118 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9119 ins_pipe(ialu_reg); 9120 %} 9121 9122 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9123 effect(USE_DEF dst, USE shift, KILL cr); 9124 9125 format %{ "rolq $dst, $shift" %} 9126 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9127 ins_encode( reg_opc_imm_wide(dst, shift) ); 9128 ins_pipe(ialu_reg); 9129 %} 9130 9131 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9132 %{ 9133 effect(USE_DEF dst, USE shift, KILL cr); 9134 9135 format %{ "rolq $dst, $shift" %} 9136 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9137 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9138 ins_pipe(ialu_reg_reg); 9139 %} 9140 // end of ROL expand 9141 9142 // Rotate Left by one 9143 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9144 %{ 9145 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9146 9147 expand %{ 9148 rolL_rReg_imm1(dst, cr); 9149 %} 9150 %} 9151 9152 // Rotate Left by 8-bit immediate 9153 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9154 %{ 9155 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9156 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9157 9158 expand %{ 9159 rolL_rReg_imm8(dst, lshift, cr); 9160 %} 9161 %} 9162 9163 // Rotate Left by variable 9164 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9165 %{ 9166 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9167 9168 expand %{ 9169 rolL_rReg_CL(dst, shift, cr); 9170 %} 9171 %} 9172 9173 // Rotate Left by variable 9174 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9175 %{ 9176 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9177 9178 expand %{ 9179 rolL_rReg_CL(dst, shift, cr); 9180 %} 9181 %} 9182 9183 // ROR expand 9184 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9185 %{ 9186 effect(USE_DEF dst, KILL cr); 9187 9188 format %{ "rorq $dst" %} 9189 opcode(0xD1, 0x1); /* D1 /1 */ 9190 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9191 ins_pipe(ialu_reg); 9192 %} 9193 9194 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9195 %{ 9196 effect(USE_DEF dst, USE shift, KILL cr); 9197 9198 format %{ "rorq $dst, $shift" %} 9199 opcode(0xC1, 0x1); /* C1 /1 ib */ 9200 ins_encode(reg_opc_imm_wide(dst, shift)); 9201 ins_pipe(ialu_reg); 9202 %} 9203 9204 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9205 %{ 9206 effect(USE_DEF dst, USE shift, KILL cr); 9207 9208 format %{ "rorq $dst, $shift" %} 9209 opcode(0xD3, 0x1); /* D3 /1 */ 9210 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9211 ins_pipe(ialu_reg_reg); 9212 %} 9213 // end of ROR expand 9214 9215 // Rotate Right by one 9216 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9217 %{ 9218 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9219 9220 expand %{ 9221 rorL_rReg_imm1(dst, cr); 9222 %} 9223 %} 9224 9225 // Rotate Right by 8-bit immediate 9226 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9227 %{ 9228 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9229 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9230 9231 expand %{ 9232 rorL_rReg_imm8(dst, rshift, cr); 9233 %} 9234 %} 9235 9236 // Rotate Right by variable 9237 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9238 %{ 9239 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9240 9241 expand %{ 9242 rorL_rReg_CL(dst, shift, cr); 9243 %} 9244 %} 9245 9246 // Rotate Right by variable 9247 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9248 %{ 9249 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9250 9251 expand %{ 9252 rorL_rReg_CL(dst, shift, cr); 9253 %} 9254 %} 9255 9256 // Logical Instructions 9257 9258 // Integer Logical Instructions 9259 9260 // And Instructions 9261 // And Register with Register 9262 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9263 %{ 9264 match(Set dst (AndI dst src)); 9265 effect(KILL cr); 9266 9267 format %{ "andl $dst, $src\t# int" %} 9268 opcode(0x23); 9269 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9270 ins_pipe(ialu_reg_reg); 9271 %} 9272 9273 // And Register with Immediate 255 9274 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9275 %{ 9276 match(Set dst (AndI dst src)); 9277 9278 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9279 opcode(0x0F, 0xB6); 9280 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9281 ins_pipe(ialu_reg); 9282 %} 9283 9284 // And Register with Immediate 255 and promote to long 9285 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9286 %{ 9287 match(Set dst (ConvI2L (AndI src mask))); 9288 9289 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9290 opcode(0x0F, 0xB6); 9291 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9292 ins_pipe(ialu_reg); 9293 %} 9294 9295 // And Register with Immediate 65535 9296 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9297 %{ 9298 match(Set dst (AndI dst src)); 9299 9300 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9301 opcode(0x0F, 0xB7); 9302 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9303 ins_pipe(ialu_reg); 9304 %} 9305 9306 // And Register with Immediate 65535 and promote to long 9307 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9308 %{ 9309 match(Set dst (ConvI2L (AndI src mask))); 9310 9311 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9312 opcode(0x0F, 0xB7); 9313 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9314 ins_pipe(ialu_reg); 9315 %} 9316 9317 // And Register with Immediate 9318 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9319 %{ 9320 match(Set dst (AndI dst src)); 9321 effect(KILL cr); 9322 9323 format %{ "andl $dst, $src\t# int" %} 9324 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9325 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9326 ins_pipe(ialu_reg); 9327 %} 9328 9329 // And Register with Memory 9330 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9331 %{ 9332 match(Set dst (AndI dst (LoadI src))); 9333 effect(KILL cr); 9334 9335 ins_cost(125); 9336 format %{ "andl $dst, $src\t# int" %} 9337 opcode(0x23); 9338 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9339 ins_pipe(ialu_reg_mem); 9340 %} 9341 9342 // And Memory with Register 9343 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9344 %{ 9345 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9346 effect(KILL cr); 9347 9348 ins_cost(150); 9349 format %{ "andl $dst, $src\t# int" %} 9350 opcode(0x21); /* Opcode 21 /r */ 9351 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9352 ins_pipe(ialu_mem_reg); 9353 %} 9354 9355 // And Memory with Immediate 9356 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9357 %{ 9358 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9359 effect(KILL cr); 9360 9361 ins_cost(125); 9362 format %{ "andl $dst, $src\t# int" %} 9363 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9364 ins_encode(REX_mem(dst), OpcSE(src), 9365 RM_opc_mem(secondary, dst), Con8or32(src)); 9366 ins_pipe(ialu_mem_imm); 9367 %} 9368 9369 // BMI1 instructions 9370 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9371 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9372 predicate(UseBMI1Instructions); 9373 effect(KILL cr); 9374 9375 ins_cost(125); 9376 format %{ "andnl $dst, $src1, $src2" %} 9377 9378 ins_encode %{ 9379 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9380 %} 9381 ins_pipe(ialu_reg_mem); 9382 %} 9383 9384 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9385 match(Set dst (AndI (XorI src1 minus_1) src2)); 9386 predicate(UseBMI1Instructions); 9387 effect(KILL cr); 9388 9389 format %{ "andnl $dst, $src1, $src2" %} 9390 9391 ins_encode %{ 9392 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9393 %} 9394 ins_pipe(ialu_reg); 9395 %} 9396 9397 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9398 match(Set dst (AndI (SubI imm_zero src) src)); 9399 predicate(UseBMI1Instructions); 9400 effect(KILL cr); 9401 9402 format %{ "blsil $dst, $src" %} 9403 9404 ins_encode %{ 9405 __ blsil($dst$$Register, $src$$Register); 9406 %} 9407 ins_pipe(ialu_reg); 9408 %} 9409 9410 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9411 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9412 predicate(UseBMI1Instructions); 9413 effect(KILL cr); 9414 9415 ins_cost(125); 9416 format %{ "blsil $dst, $src" %} 9417 9418 ins_encode %{ 9419 __ blsil($dst$$Register, $src$$Address); 9420 %} 9421 ins_pipe(ialu_reg_mem); 9422 %} 9423 9424 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9425 %{ 9426 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9427 predicate(UseBMI1Instructions); 9428 effect(KILL cr); 9429 9430 ins_cost(125); 9431 format %{ "blsmskl $dst, $src" %} 9432 9433 ins_encode %{ 9434 __ blsmskl($dst$$Register, $src$$Address); 9435 %} 9436 ins_pipe(ialu_reg_mem); 9437 %} 9438 9439 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9440 %{ 9441 match(Set dst (XorI (AddI src minus_1) src)); 9442 predicate(UseBMI1Instructions); 9443 effect(KILL cr); 9444 9445 format %{ "blsmskl $dst, $src" %} 9446 9447 ins_encode %{ 9448 __ blsmskl($dst$$Register, $src$$Register); 9449 %} 9450 9451 ins_pipe(ialu_reg); 9452 %} 9453 9454 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9455 %{ 9456 match(Set dst (AndI (AddI src minus_1) src) ); 9457 predicate(UseBMI1Instructions); 9458 effect(KILL cr); 9459 9460 format %{ "blsrl $dst, $src" %} 9461 9462 ins_encode %{ 9463 __ blsrl($dst$$Register, $src$$Register); 9464 %} 9465 9466 ins_pipe(ialu_reg_mem); 9467 %} 9468 9469 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9470 %{ 9471 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9472 predicate(UseBMI1Instructions); 9473 effect(KILL cr); 9474 9475 ins_cost(125); 9476 format %{ "blsrl $dst, $src" %} 9477 9478 ins_encode %{ 9479 __ blsrl($dst$$Register, $src$$Address); 9480 %} 9481 9482 ins_pipe(ialu_reg); 9483 %} 9484 9485 // Or Instructions 9486 // Or Register with Register 9487 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9488 %{ 9489 match(Set dst (OrI dst src)); 9490 effect(KILL cr); 9491 9492 format %{ "orl $dst, $src\t# int" %} 9493 opcode(0x0B); 9494 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9495 ins_pipe(ialu_reg_reg); 9496 %} 9497 9498 // Or Register with Immediate 9499 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9500 %{ 9501 match(Set dst (OrI dst src)); 9502 effect(KILL cr); 9503 9504 format %{ "orl $dst, $src\t# int" %} 9505 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9506 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9507 ins_pipe(ialu_reg); 9508 %} 9509 9510 // Or Register with Memory 9511 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9512 %{ 9513 match(Set dst (OrI dst (LoadI src))); 9514 effect(KILL cr); 9515 9516 ins_cost(125); 9517 format %{ "orl $dst, $src\t# int" %} 9518 opcode(0x0B); 9519 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9520 ins_pipe(ialu_reg_mem); 9521 %} 9522 9523 // Or Memory with Register 9524 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9525 %{ 9526 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9527 effect(KILL cr); 9528 9529 ins_cost(150); 9530 format %{ "orl $dst, $src\t# int" %} 9531 opcode(0x09); /* Opcode 09 /r */ 9532 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9533 ins_pipe(ialu_mem_reg); 9534 %} 9535 9536 // Or Memory with Immediate 9537 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9538 %{ 9539 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9540 effect(KILL cr); 9541 9542 ins_cost(125); 9543 format %{ "orl $dst, $src\t# int" %} 9544 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9545 ins_encode(REX_mem(dst), OpcSE(src), 9546 RM_opc_mem(secondary, dst), Con8or32(src)); 9547 ins_pipe(ialu_mem_imm); 9548 %} 9549 9550 // Xor Instructions 9551 // Xor Register with Register 9552 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9553 %{ 9554 match(Set dst (XorI dst src)); 9555 effect(KILL cr); 9556 9557 format %{ "xorl $dst, $src\t# int" %} 9558 opcode(0x33); 9559 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9560 ins_pipe(ialu_reg_reg); 9561 %} 9562 9563 // Xor Register with Immediate -1 9564 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9565 match(Set dst (XorI dst imm)); 9566 9567 format %{ "not $dst" %} 9568 ins_encode %{ 9569 __ notl($dst$$Register); 9570 %} 9571 ins_pipe(ialu_reg); 9572 %} 9573 9574 // Xor Register with Immediate 9575 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9576 %{ 9577 match(Set dst (XorI dst src)); 9578 effect(KILL cr); 9579 9580 format %{ "xorl $dst, $src\t# int" %} 9581 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9582 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9583 ins_pipe(ialu_reg); 9584 %} 9585 9586 // Xor Register with Memory 9587 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9588 %{ 9589 match(Set dst (XorI dst (LoadI src))); 9590 effect(KILL cr); 9591 9592 ins_cost(125); 9593 format %{ "xorl $dst, $src\t# int" %} 9594 opcode(0x33); 9595 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9596 ins_pipe(ialu_reg_mem); 9597 %} 9598 9599 // Xor Memory with Register 9600 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9601 %{ 9602 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9603 effect(KILL cr); 9604 9605 ins_cost(150); 9606 format %{ "xorl $dst, $src\t# int" %} 9607 opcode(0x31); /* Opcode 31 /r */ 9608 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9609 ins_pipe(ialu_mem_reg); 9610 %} 9611 9612 // Xor Memory with Immediate 9613 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9614 %{ 9615 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9616 effect(KILL cr); 9617 9618 ins_cost(125); 9619 format %{ "xorl $dst, $src\t# int" %} 9620 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9621 ins_encode(REX_mem(dst), OpcSE(src), 9622 RM_opc_mem(secondary, dst), Con8or32(src)); 9623 ins_pipe(ialu_mem_imm); 9624 %} 9625 9626 9627 // Long Logical Instructions 9628 9629 // And Instructions 9630 // And Register with Register 9631 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9632 %{ 9633 match(Set dst (AndL dst src)); 9634 effect(KILL cr); 9635 9636 format %{ "andq $dst, $src\t# long" %} 9637 opcode(0x23); 9638 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9639 ins_pipe(ialu_reg_reg); 9640 %} 9641 9642 // And Register with Immediate 255 9643 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9644 %{ 9645 match(Set dst (AndL dst src)); 9646 9647 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9648 opcode(0x0F, 0xB6); 9649 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9650 ins_pipe(ialu_reg); 9651 %} 9652 9653 // And Register with Immediate 65535 9654 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9655 %{ 9656 match(Set dst (AndL dst src)); 9657 9658 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9659 opcode(0x0F, 0xB7); 9660 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9661 ins_pipe(ialu_reg); 9662 %} 9663 9664 // And Register with Immediate 9665 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9666 %{ 9667 match(Set dst (AndL dst src)); 9668 effect(KILL cr); 9669 9670 format %{ "andq $dst, $src\t# long" %} 9671 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9672 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9673 ins_pipe(ialu_reg); 9674 %} 9675 9676 // And Register with Memory 9677 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9678 %{ 9679 match(Set dst (AndL dst (LoadL src))); 9680 effect(KILL cr); 9681 9682 ins_cost(125); 9683 format %{ "andq $dst, $src\t# long" %} 9684 opcode(0x23); 9685 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9686 ins_pipe(ialu_reg_mem); 9687 %} 9688 9689 // And Memory with Register 9690 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9691 %{ 9692 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9693 effect(KILL cr); 9694 9695 ins_cost(150); 9696 format %{ "andq $dst, $src\t# long" %} 9697 opcode(0x21); /* Opcode 21 /r */ 9698 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9699 ins_pipe(ialu_mem_reg); 9700 %} 9701 9702 // And Memory with Immediate 9703 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9704 %{ 9705 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9706 effect(KILL cr); 9707 9708 ins_cost(125); 9709 format %{ "andq $dst, $src\t# long" %} 9710 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9711 ins_encode(REX_mem_wide(dst), OpcSE(src), 9712 RM_opc_mem(secondary, dst), Con8or32(src)); 9713 ins_pipe(ialu_mem_imm); 9714 %} 9715 9716 // BMI1 instructions 9717 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9718 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9719 predicate(UseBMI1Instructions); 9720 effect(KILL cr); 9721 9722 ins_cost(125); 9723 format %{ "andnq $dst, $src1, $src2" %} 9724 9725 ins_encode %{ 9726 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9727 %} 9728 ins_pipe(ialu_reg_mem); 9729 %} 9730 9731 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9732 match(Set dst (AndL (XorL src1 minus_1) src2)); 9733 predicate(UseBMI1Instructions); 9734 effect(KILL cr); 9735 9736 format %{ "andnq $dst, $src1, $src2" %} 9737 9738 ins_encode %{ 9739 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9740 %} 9741 ins_pipe(ialu_reg_mem); 9742 %} 9743 9744 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9745 match(Set dst (AndL (SubL imm_zero src) src)); 9746 predicate(UseBMI1Instructions); 9747 effect(KILL cr); 9748 9749 format %{ "blsiq $dst, $src" %} 9750 9751 ins_encode %{ 9752 __ blsiq($dst$$Register, $src$$Register); 9753 %} 9754 ins_pipe(ialu_reg); 9755 %} 9756 9757 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9758 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9759 predicate(UseBMI1Instructions); 9760 effect(KILL cr); 9761 9762 ins_cost(125); 9763 format %{ "blsiq $dst, $src" %} 9764 9765 ins_encode %{ 9766 __ blsiq($dst$$Register, $src$$Address); 9767 %} 9768 ins_pipe(ialu_reg_mem); 9769 %} 9770 9771 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9772 %{ 9773 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9774 predicate(UseBMI1Instructions); 9775 effect(KILL cr); 9776 9777 ins_cost(125); 9778 format %{ "blsmskq $dst, $src" %} 9779 9780 ins_encode %{ 9781 __ blsmskq($dst$$Register, $src$$Address); 9782 %} 9783 ins_pipe(ialu_reg_mem); 9784 %} 9785 9786 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9787 %{ 9788 match(Set dst (XorL (AddL src minus_1) src)); 9789 predicate(UseBMI1Instructions); 9790 effect(KILL cr); 9791 9792 format %{ "blsmskq $dst, $src" %} 9793 9794 ins_encode %{ 9795 __ blsmskq($dst$$Register, $src$$Register); 9796 %} 9797 9798 ins_pipe(ialu_reg); 9799 %} 9800 9801 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9802 %{ 9803 match(Set dst (AndL (AddL src minus_1) src) ); 9804 predicate(UseBMI1Instructions); 9805 effect(KILL cr); 9806 9807 format %{ "blsrq $dst, $src" %} 9808 9809 ins_encode %{ 9810 __ blsrq($dst$$Register, $src$$Register); 9811 %} 9812 9813 ins_pipe(ialu_reg); 9814 %} 9815 9816 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9817 %{ 9818 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9819 predicate(UseBMI1Instructions); 9820 effect(KILL cr); 9821 9822 ins_cost(125); 9823 format %{ "blsrq $dst, $src" %} 9824 9825 ins_encode %{ 9826 __ blsrq($dst$$Register, $src$$Address); 9827 %} 9828 9829 ins_pipe(ialu_reg); 9830 %} 9831 9832 // Or Instructions 9833 // Or Register with Register 9834 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9835 %{ 9836 match(Set dst (OrL dst src)); 9837 effect(KILL cr); 9838 9839 format %{ "orq $dst, $src\t# long" %} 9840 opcode(0x0B); 9841 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9842 ins_pipe(ialu_reg_reg); 9843 %} 9844 9845 // Use any_RegP to match R15 (TLS register) without spilling. 9846 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9847 match(Set dst (OrL dst (CastP2X src))); 9848 effect(KILL cr); 9849 9850 format %{ "orq $dst, $src\t# long" %} 9851 opcode(0x0B); 9852 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9853 ins_pipe(ialu_reg_reg); 9854 %} 9855 9856 9857 // Or Register with Immediate 9858 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9859 %{ 9860 match(Set dst (OrL dst src)); 9861 effect(KILL cr); 9862 9863 format %{ "orq $dst, $src\t# long" %} 9864 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9865 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9866 ins_pipe(ialu_reg); 9867 %} 9868 9869 // Or Register with Memory 9870 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9871 %{ 9872 match(Set dst (OrL dst (LoadL src))); 9873 effect(KILL cr); 9874 9875 ins_cost(125); 9876 format %{ "orq $dst, $src\t# long" %} 9877 opcode(0x0B); 9878 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9879 ins_pipe(ialu_reg_mem); 9880 %} 9881 9882 // Or Memory with Register 9883 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9884 %{ 9885 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9886 effect(KILL cr); 9887 9888 ins_cost(150); 9889 format %{ "orq $dst, $src\t# long" %} 9890 opcode(0x09); /* Opcode 09 /r */ 9891 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9892 ins_pipe(ialu_mem_reg); 9893 %} 9894 9895 // Or Memory with Immediate 9896 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9897 %{ 9898 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9899 effect(KILL cr); 9900 9901 ins_cost(125); 9902 format %{ "orq $dst, $src\t# long" %} 9903 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9904 ins_encode(REX_mem_wide(dst), OpcSE(src), 9905 RM_opc_mem(secondary, dst), Con8or32(src)); 9906 ins_pipe(ialu_mem_imm); 9907 %} 9908 9909 // Xor Instructions 9910 // Xor Register with Register 9911 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9912 %{ 9913 match(Set dst (XorL dst src)); 9914 effect(KILL cr); 9915 9916 format %{ "xorq $dst, $src\t# long" %} 9917 opcode(0x33); 9918 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9919 ins_pipe(ialu_reg_reg); 9920 %} 9921 9922 // Xor Register with Immediate -1 9923 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9924 match(Set dst (XorL dst imm)); 9925 9926 format %{ "notq $dst" %} 9927 ins_encode %{ 9928 __ notq($dst$$Register); 9929 %} 9930 ins_pipe(ialu_reg); 9931 %} 9932 9933 // Xor Register with Immediate 9934 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9935 %{ 9936 match(Set dst (XorL dst src)); 9937 effect(KILL cr); 9938 9939 format %{ "xorq $dst, $src\t# long" %} 9940 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9941 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9942 ins_pipe(ialu_reg); 9943 %} 9944 9945 // Xor Register with Memory 9946 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9947 %{ 9948 match(Set dst (XorL dst (LoadL src))); 9949 effect(KILL cr); 9950 9951 ins_cost(125); 9952 format %{ "xorq $dst, $src\t# long" %} 9953 opcode(0x33); 9954 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9955 ins_pipe(ialu_reg_mem); 9956 %} 9957 9958 // Xor Memory with Register 9959 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9960 %{ 9961 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9962 effect(KILL cr); 9963 9964 ins_cost(150); 9965 format %{ "xorq $dst, $src\t# long" %} 9966 opcode(0x31); /* Opcode 31 /r */ 9967 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9968 ins_pipe(ialu_mem_reg); 9969 %} 9970 9971 // Xor Memory with Immediate 9972 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9973 %{ 9974 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9975 effect(KILL cr); 9976 9977 ins_cost(125); 9978 format %{ "xorq $dst, $src\t# long" %} 9979 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9980 ins_encode(REX_mem_wide(dst), OpcSE(src), 9981 RM_opc_mem(secondary, dst), Con8or32(src)); 9982 ins_pipe(ialu_mem_imm); 9983 %} 9984 9985 // Convert Int to Boolean 9986 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9987 %{ 9988 match(Set dst (Conv2B src)); 9989 effect(KILL cr); 9990 9991 format %{ "testl $src, $src\t# ci2b\n\t" 9992 "setnz $dst\n\t" 9993 "movzbl $dst, $dst" %} 9994 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9995 setNZ_reg(dst), 9996 REX_reg_breg(dst, dst), // movzbl 9997 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9998 ins_pipe(pipe_slow); // XXX 9999 %} 10000 10001 // Convert Pointer to Boolean 10002 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10003 %{ 10004 match(Set dst (Conv2B src)); 10005 effect(KILL cr); 10006 10007 format %{ "testq $src, $src\t# cp2b\n\t" 10008 "setnz $dst\n\t" 10009 "movzbl $dst, $dst" %} 10010 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10011 setNZ_reg(dst), 10012 REX_reg_breg(dst, dst), // movzbl 10013 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10014 ins_pipe(pipe_slow); // XXX 10015 %} 10016 10017 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10018 %{ 10019 match(Set dst (CmpLTMask p q)); 10020 effect(KILL cr); 10021 10022 ins_cost(400); 10023 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10024 "setlt $dst\n\t" 10025 "movzbl $dst, $dst\n\t" 10026 "negl $dst" %} 10027 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10028 setLT_reg(dst), 10029 REX_reg_breg(dst, dst), // movzbl 10030 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10031 neg_reg(dst)); 10032 ins_pipe(pipe_slow); 10033 %} 10034 10035 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10036 %{ 10037 match(Set dst (CmpLTMask dst zero)); 10038 effect(KILL cr); 10039 10040 ins_cost(100); 10041 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10042 ins_encode %{ 10043 __ sarl($dst$$Register, 31); 10044 %} 10045 ins_pipe(ialu_reg); 10046 %} 10047 10048 /* Better to save a register than avoid a branch */ 10049 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10050 %{ 10051 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10052 effect(KILL cr); 10053 ins_cost(300); 10054 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10055 "jge done\n\t" 10056 "addl $p,$y\n" 10057 "done: " %} 10058 ins_encode %{ 10059 Register Rp = $p$$Register; 10060 Register Rq = $q$$Register; 10061 Register Ry = $y$$Register; 10062 Label done; 10063 __ subl(Rp, Rq); 10064 __ jccb(Assembler::greaterEqual, done); 10065 __ addl(Rp, Ry); 10066 __ bind(done); 10067 %} 10068 ins_pipe(pipe_cmplt); 10069 %} 10070 10071 /* Better to save a register than avoid a branch */ 10072 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10073 %{ 10074 match(Set y (AndI (CmpLTMask p q) y)); 10075 effect(KILL cr); 10076 10077 ins_cost(300); 10078 10079 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10080 "jlt done\n\t" 10081 "xorl $y, $y\n" 10082 "done: " %} 10083 ins_encode %{ 10084 Register Rp = $p$$Register; 10085 Register Rq = $q$$Register; 10086 Register Ry = $y$$Register; 10087 Label done; 10088 __ cmpl(Rp, Rq); 10089 __ jccb(Assembler::less, done); 10090 __ xorl(Ry, Ry); 10091 __ bind(done); 10092 %} 10093 ins_pipe(pipe_cmplt); 10094 %} 10095 10096 10097 //---------- FP Instructions------------------------------------------------ 10098 10099 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10100 %{ 10101 match(Set cr (CmpF src1 src2)); 10102 10103 ins_cost(145); 10104 format %{ "ucomiss $src1, $src2\n\t" 10105 "jnp,s exit\n\t" 10106 "pushfq\t# saw NaN, set CF\n\t" 10107 "andq [rsp], #0xffffff2b\n\t" 10108 "popfq\n" 10109 "exit:" %} 10110 ins_encode %{ 10111 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10112 emit_cmpfp_fixup(_masm); 10113 %} 10114 ins_pipe(pipe_slow); 10115 %} 10116 10117 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10118 match(Set cr (CmpF src1 src2)); 10119 10120 ins_cost(100); 10121 format %{ "ucomiss $src1, $src2" %} 10122 ins_encode %{ 10123 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10124 %} 10125 ins_pipe(pipe_slow); 10126 %} 10127 10128 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10129 %{ 10130 match(Set cr (CmpF src1 (LoadF src2))); 10131 10132 ins_cost(145); 10133 format %{ "ucomiss $src1, $src2\n\t" 10134 "jnp,s exit\n\t" 10135 "pushfq\t# saw NaN, set CF\n\t" 10136 "andq [rsp], #0xffffff2b\n\t" 10137 "popfq\n" 10138 "exit:" %} 10139 ins_encode %{ 10140 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10141 emit_cmpfp_fixup(_masm); 10142 %} 10143 ins_pipe(pipe_slow); 10144 %} 10145 10146 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10147 match(Set cr (CmpF src1 (LoadF src2))); 10148 10149 ins_cost(100); 10150 format %{ "ucomiss $src1, $src2" %} 10151 ins_encode %{ 10152 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10153 %} 10154 ins_pipe(pipe_slow); 10155 %} 10156 10157 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10158 match(Set cr (CmpF src con)); 10159 10160 ins_cost(145); 10161 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10162 "jnp,s exit\n\t" 10163 "pushfq\t# saw NaN, set CF\n\t" 10164 "andq [rsp], #0xffffff2b\n\t" 10165 "popfq\n" 10166 "exit:" %} 10167 ins_encode %{ 10168 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10169 emit_cmpfp_fixup(_masm); 10170 %} 10171 ins_pipe(pipe_slow); 10172 %} 10173 10174 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10175 match(Set cr (CmpF src con)); 10176 ins_cost(100); 10177 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10178 ins_encode %{ 10179 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10180 %} 10181 ins_pipe(pipe_slow); 10182 %} 10183 10184 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10185 %{ 10186 match(Set cr (CmpD src1 src2)); 10187 10188 ins_cost(145); 10189 format %{ "ucomisd $src1, $src2\n\t" 10190 "jnp,s exit\n\t" 10191 "pushfq\t# saw NaN, set CF\n\t" 10192 "andq [rsp], #0xffffff2b\n\t" 10193 "popfq\n" 10194 "exit:" %} 10195 ins_encode %{ 10196 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10197 emit_cmpfp_fixup(_masm); 10198 %} 10199 ins_pipe(pipe_slow); 10200 %} 10201 10202 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10203 match(Set cr (CmpD src1 src2)); 10204 10205 ins_cost(100); 10206 format %{ "ucomisd $src1, $src2 test" %} 10207 ins_encode %{ 10208 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10209 %} 10210 ins_pipe(pipe_slow); 10211 %} 10212 10213 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10214 %{ 10215 match(Set cr (CmpD src1 (LoadD src2))); 10216 10217 ins_cost(145); 10218 format %{ "ucomisd $src1, $src2\n\t" 10219 "jnp,s exit\n\t" 10220 "pushfq\t# saw NaN, set CF\n\t" 10221 "andq [rsp], #0xffffff2b\n\t" 10222 "popfq\n" 10223 "exit:" %} 10224 ins_encode %{ 10225 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10226 emit_cmpfp_fixup(_masm); 10227 %} 10228 ins_pipe(pipe_slow); 10229 %} 10230 10231 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10232 match(Set cr (CmpD src1 (LoadD src2))); 10233 10234 ins_cost(100); 10235 format %{ "ucomisd $src1, $src2" %} 10236 ins_encode %{ 10237 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10238 %} 10239 ins_pipe(pipe_slow); 10240 %} 10241 10242 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10243 match(Set cr (CmpD src con)); 10244 10245 ins_cost(145); 10246 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10247 "jnp,s exit\n\t" 10248 "pushfq\t# saw NaN, set CF\n\t" 10249 "andq [rsp], #0xffffff2b\n\t" 10250 "popfq\n" 10251 "exit:" %} 10252 ins_encode %{ 10253 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10254 emit_cmpfp_fixup(_masm); 10255 %} 10256 ins_pipe(pipe_slow); 10257 %} 10258 10259 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10260 match(Set cr (CmpD src con)); 10261 ins_cost(100); 10262 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10263 ins_encode %{ 10264 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10265 %} 10266 ins_pipe(pipe_slow); 10267 %} 10268 10269 // Compare into -1,0,1 10270 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10271 %{ 10272 match(Set dst (CmpF3 src1 src2)); 10273 effect(KILL cr); 10274 10275 ins_cost(275); 10276 format %{ "ucomiss $src1, $src2\n\t" 10277 "movl $dst, #-1\n\t" 10278 "jp,s done\n\t" 10279 "jb,s done\n\t" 10280 "setne $dst\n\t" 10281 "movzbl $dst, $dst\n" 10282 "done:" %} 10283 ins_encode %{ 10284 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10285 emit_cmpfp3(_masm, $dst$$Register); 10286 %} 10287 ins_pipe(pipe_slow); 10288 %} 10289 10290 // Compare into -1,0,1 10291 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10292 %{ 10293 match(Set dst (CmpF3 src1 (LoadF src2))); 10294 effect(KILL cr); 10295 10296 ins_cost(275); 10297 format %{ "ucomiss $src1, $src2\n\t" 10298 "movl $dst, #-1\n\t" 10299 "jp,s done\n\t" 10300 "jb,s done\n\t" 10301 "setne $dst\n\t" 10302 "movzbl $dst, $dst\n" 10303 "done:" %} 10304 ins_encode %{ 10305 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10306 emit_cmpfp3(_masm, $dst$$Register); 10307 %} 10308 ins_pipe(pipe_slow); 10309 %} 10310 10311 // Compare into -1,0,1 10312 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10313 match(Set dst (CmpF3 src con)); 10314 effect(KILL cr); 10315 10316 ins_cost(275); 10317 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10318 "movl $dst, #-1\n\t" 10319 "jp,s done\n\t" 10320 "jb,s done\n\t" 10321 "setne $dst\n\t" 10322 "movzbl $dst, $dst\n" 10323 "done:" %} 10324 ins_encode %{ 10325 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10326 emit_cmpfp3(_masm, $dst$$Register); 10327 %} 10328 ins_pipe(pipe_slow); 10329 %} 10330 10331 // Compare into -1,0,1 10332 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10333 %{ 10334 match(Set dst (CmpD3 src1 src2)); 10335 effect(KILL cr); 10336 10337 ins_cost(275); 10338 format %{ "ucomisd $src1, $src2\n\t" 10339 "movl $dst, #-1\n\t" 10340 "jp,s done\n\t" 10341 "jb,s done\n\t" 10342 "setne $dst\n\t" 10343 "movzbl $dst, $dst\n" 10344 "done:" %} 10345 ins_encode %{ 10346 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10347 emit_cmpfp3(_masm, $dst$$Register); 10348 %} 10349 ins_pipe(pipe_slow); 10350 %} 10351 10352 // Compare into -1,0,1 10353 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10354 %{ 10355 match(Set dst (CmpD3 src1 (LoadD src2))); 10356 effect(KILL cr); 10357 10358 ins_cost(275); 10359 format %{ "ucomisd $src1, $src2\n\t" 10360 "movl $dst, #-1\n\t" 10361 "jp,s done\n\t" 10362 "jb,s done\n\t" 10363 "setne $dst\n\t" 10364 "movzbl $dst, $dst\n" 10365 "done:" %} 10366 ins_encode %{ 10367 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10368 emit_cmpfp3(_masm, $dst$$Register); 10369 %} 10370 ins_pipe(pipe_slow); 10371 %} 10372 10373 // Compare into -1,0,1 10374 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10375 match(Set dst (CmpD3 src con)); 10376 effect(KILL cr); 10377 10378 ins_cost(275); 10379 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10380 "movl $dst, #-1\n\t" 10381 "jp,s done\n\t" 10382 "jb,s done\n\t" 10383 "setne $dst\n\t" 10384 "movzbl $dst, $dst\n" 10385 "done:" %} 10386 ins_encode %{ 10387 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10388 emit_cmpfp3(_masm, $dst$$Register); 10389 %} 10390 ins_pipe(pipe_slow); 10391 %} 10392 10393 //----------Arithmetic Conversion Instructions--------------------------------- 10394 10395 instruct roundFloat_nop(regF dst) 10396 %{ 10397 match(Set dst (RoundFloat dst)); 10398 10399 ins_cost(0); 10400 ins_encode(); 10401 ins_pipe(empty); 10402 %} 10403 10404 instruct roundDouble_nop(regD dst) 10405 %{ 10406 match(Set dst (RoundDouble dst)); 10407 10408 ins_cost(0); 10409 ins_encode(); 10410 ins_pipe(empty); 10411 %} 10412 10413 instruct convF2D_reg_reg(regD dst, regF src) 10414 %{ 10415 match(Set dst (ConvF2D src)); 10416 10417 format %{ "cvtss2sd $dst, $src" %} 10418 ins_encode %{ 10419 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10420 %} 10421 ins_pipe(pipe_slow); // XXX 10422 %} 10423 10424 instruct convF2D_reg_mem(regD dst, memory src) 10425 %{ 10426 match(Set dst (ConvF2D (LoadF src))); 10427 10428 format %{ "cvtss2sd $dst, $src" %} 10429 ins_encode %{ 10430 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10431 %} 10432 ins_pipe(pipe_slow); // XXX 10433 %} 10434 10435 instruct convD2F_reg_reg(regF dst, regD src) 10436 %{ 10437 match(Set dst (ConvD2F src)); 10438 10439 format %{ "cvtsd2ss $dst, $src" %} 10440 ins_encode %{ 10441 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10442 %} 10443 ins_pipe(pipe_slow); // XXX 10444 %} 10445 10446 instruct convD2F_reg_mem(regF dst, memory src) 10447 %{ 10448 match(Set dst (ConvD2F (LoadD src))); 10449 10450 format %{ "cvtsd2ss $dst, $src" %} 10451 ins_encode %{ 10452 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10453 %} 10454 ins_pipe(pipe_slow); // XXX 10455 %} 10456 10457 // XXX do mem variants 10458 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10459 %{ 10460 match(Set dst (ConvF2I src)); 10461 effect(KILL cr); 10462 10463 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10464 "cmpl $dst, #0x80000000\n\t" 10465 "jne,s done\n\t" 10466 "subq rsp, #8\n\t" 10467 "movss [rsp], $src\n\t" 10468 "call f2i_fixup\n\t" 10469 "popq $dst\n" 10470 "done: "%} 10471 ins_encode %{ 10472 Label done; 10473 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10474 __ cmpl($dst$$Register, 0x80000000); 10475 __ jccb(Assembler::notEqual, done); 10476 __ subptr(rsp, 8); 10477 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10478 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10479 __ pop($dst$$Register); 10480 __ bind(done); 10481 %} 10482 ins_pipe(pipe_slow); 10483 %} 10484 10485 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10486 %{ 10487 match(Set dst (ConvF2L src)); 10488 effect(KILL cr); 10489 10490 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10491 "cmpq $dst, [0x8000000000000000]\n\t" 10492 "jne,s done\n\t" 10493 "subq rsp, #8\n\t" 10494 "movss [rsp], $src\n\t" 10495 "call f2l_fixup\n\t" 10496 "popq $dst\n" 10497 "done: "%} 10498 ins_encode %{ 10499 Label done; 10500 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10501 __ cmp64($dst$$Register, 10502 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10503 __ jccb(Assembler::notEqual, done); 10504 __ subptr(rsp, 8); 10505 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10506 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10507 __ pop($dst$$Register); 10508 __ bind(done); 10509 %} 10510 ins_pipe(pipe_slow); 10511 %} 10512 10513 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10514 %{ 10515 match(Set dst (ConvD2I src)); 10516 effect(KILL cr); 10517 10518 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10519 "cmpl $dst, #0x80000000\n\t" 10520 "jne,s done\n\t" 10521 "subq rsp, #8\n\t" 10522 "movsd [rsp], $src\n\t" 10523 "call d2i_fixup\n\t" 10524 "popq $dst\n" 10525 "done: "%} 10526 ins_encode %{ 10527 Label done; 10528 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10529 __ cmpl($dst$$Register, 0x80000000); 10530 __ jccb(Assembler::notEqual, done); 10531 __ subptr(rsp, 8); 10532 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10533 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10534 __ pop($dst$$Register); 10535 __ bind(done); 10536 %} 10537 ins_pipe(pipe_slow); 10538 %} 10539 10540 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10541 %{ 10542 match(Set dst (ConvD2L src)); 10543 effect(KILL cr); 10544 10545 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10546 "cmpq $dst, [0x8000000000000000]\n\t" 10547 "jne,s done\n\t" 10548 "subq rsp, #8\n\t" 10549 "movsd [rsp], $src\n\t" 10550 "call d2l_fixup\n\t" 10551 "popq $dst\n" 10552 "done: "%} 10553 ins_encode %{ 10554 Label done; 10555 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10556 __ cmp64($dst$$Register, 10557 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10558 __ jccb(Assembler::notEqual, done); 10559 __ subptr(rsp, 8); 10560 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10561 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10562 __ pop($dst$$Register); 10563 __ bind(done); 10564 %} 10565 ins_pipe(pipe_slow); 10566 %} 10567 10568 instruct convI2F_reg_reg(regF dst, rRegI src) 10569 %{ 10570 predicate(!UseXmmI2F); 10571 match(Set dst (ConvI2F src)); 10572 10573 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10574 ins_encode %{ 10575 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10576 %} 10577 ins_pipe(pipe_slow); // XXX 10578 %} 10579 10580 instruct convI2F_reg_mem(regF dst, memory src) 10581 %{ 10582 match(Set dst (ConvI2F (LoadI src))); 10583 10584 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10585 ins_encode %{ 10586 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10587 %} 10588 ins_pipe(pipe_slow); // XXX 10589 %} 10590 10591 instruct convI2D_reg_reg(regD dst, rRegI src) 10592 %{ 10593 predicate(!UseXmmI2D); 10594 match(Set dst (ConvI2D src)); 10595 10596 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10597 ins_encode %{ 10598 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10599 %} 10600 ins_pipe(pipe_slow); // XXX 10601 %} 10602 10603 instruct convI2D_reg_mem(regD dst, memory src) 10604 %{ 10605 match(Set dst (ConvI2D (LoadI src))); 10606 10607 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10608 ins_encode %{ 10609 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10610 %} 10611 ins_pipe(pipe_slow); // XXX 10612 %} 10613 10614 instruct convXI2F_reg(regF dst, rRegI src) 10615 %{ 10616 predicate(UseXmmI2F); 10617 match(Set dst (ConvI2F src)); 10618 10619 format %{ "movdl $dst, $src\n\t" 10620 "cvtdq2psl $dst, $dst\t# i2f" %} 10621 ins_encode %{ 10622 __ movdl($dst$$XMMRegister, $src$$Register); 10623 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10624 %} 10625 ins_pipe(pipe_slow); // XXX 10626 %} 10627 10628 instruct convXI2D_reg(regD dst, rRegI src) 10629 %{ 10630 predicate(UseXmmI2D); 10631 match(Set dst (ConvI2D src)); 10632 10633 format %{ "movdl $dst, $src\n\t" 10634 "cvtdq2pdl $dst, $dst\t# i2d" %} 10635 ins_encode %{ 10636 __ movdl($dst$$XMMRegister, $src$$Register); 10637 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10638 %} 10639 ins_pipe(pipe_slow); // XXX 10640 %} 10641 10642 instruct convL2F_reg_reg(regF dst, rRegL src) 10643 %{ 10644 match(Set dst (ConvL2F src)); 10645 10646 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10647 ins_encode %{ 10648 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10649 %} 10650 ins_pipe(pipe_slow); // XXX 10651 %} 10652 10653 instruct convL2F_reg_mem(regF dst, memory src) 10654 %{ 10655 match(Set dst (ConvL2F (LoadL src))); 10656 10657 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10658 ins_encode %{ 10659 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10660 %} 10661 ins_pipe(pipe_slow); // XXX 10662 %} 10663 10664 instruct convL2D_reg_reg(regD dst, rRegL src) 10665 %{ 10666 match(Set dst (ConvL2D src)); 10667 10668 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10669 ins_encode %{ 10670 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10671 %} 10672 ins_pipe(pipe_slow); // XXX 10673 %} 10674 10675 instruct convL2D_reg_mem(regD dst, memory src) 10676 %{ 10677 match(Set dst (ConvL2D (LoadL src))); 10678 10679 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10680 ins_encode %{ 10681 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10682 %} 10683 ins_pipe(pipe_slow); // XXX 10684 %} 10685 10686 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10687 %{ 10688 match(Set dst (ConvI2L src)); 10689 10690 ins_cost(125); 10691 format %{ "movslq $dst, $src\t# i2l" %} 10692 ins_encode %{ 10693 __ movslq($dst$$Register, $src$$Register); 10694 %} 10695 ins_pipe(ialu_reg_reg); 10696 %} 10697 10698 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10699 // %{ 10700 // match(Set dst (ConvI2L src)); 10701 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10702 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10703 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10704 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10705 // ((const TypeNode*) n)->type()->is_long()->_lo == 10706 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10707 10708 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10709 // ins_encode(enc_copy(dst, src)); 10710 // // opcode(0x63); // needs REX.W 10711 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10712 // ins_pipe(ialu_reg_reg); 10713 // %} 10714 10715 // Zero-extend convert int to long 10716 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10717 %{ 10718 match(Set dst (AndL (ConvI2L src) mask)); 10719 10720 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10721 ins_encode %{ 10722 if ($dst$$reg != $src$$reg) { 10723 __ movl($dst$$Register, $src$$Register); 10724 } 10725 %} 10726 ins_pipe(ialu_reg_reg); 10727 %} 10728 10729 // Zero-extend convert int to long 10730 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10731 %{ 10732 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10733 10734 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10735 ins_encode %{ 10736 __ movl($dst$$Register, $src$$Address); 10737 %} 10738 ins_pipe(ialu_reg_mem); 10739 %} 10740 10741 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10742 %{ 10743 match(Set dst (AndL src mask)); 10744 10745 format %{ "movl $dst, $src\t# zero-extend long" %} 10746 ins_encode %{ 10747 __ movl($dst$$Register, $src$$Register); 10748 %} 10749 ins_pipe(ialu_reg_reg); 10750 %} 10751 10752 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10753 %{ 10754 match(Set dst (ConvL2I src)); 10755 10756 format %{ "movl $dst, $src\t# l2i" %} 10757 ins_encode %{ 10758 __ movl($dst$$Register, $src$$Register); 10759 %} 10760 ins_pipe(ialu_reg_reg); 10761 %} 10762 10763 10764 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10765 match(Set dst (MoveF2I src)); 10766 effect(DEF dst, USE src); 10767 10768 ins_cost(125); 10769 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10770 ins_encode %{ 10771 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10772 %} 10773 ins_pipe(ialu_reg_mem); 10774 %} 10775 10776 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10777 match(Set dst (MoveI2F src)); 10778 effect(DEF dst, USE src); 10779 10780 ins_cost(125); 10781 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10782 ins_encode %{ 10783 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10784 %} 10785 ins_pipe(pipe_slow); 10786 %} 10787 10788 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10789 match(Set dst (MoveD2L src)); 10790 effect(DEF dst, USE src); 10791 10792 ins_cost(125); 10793 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10794 ins_encode %{ 10795 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10796 %} 10797 ins_pipe(ialu_reg_mem); 10798 %} 10799 10800 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10801 predicate(!UseXmmLoadAndClearUpper); 10802 match(Set dst (MoveL2D src)); 10803 effect(DEF dst, USE src); 10804 10805 ins_cost(125); 10806 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10807 ins_encode %{ 10808 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10809 %} 10810 ins_pipe(pipe_slow); 10811 %} 10812 10813 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10814 predicate(UseXmmLoadAndClearUpper); 10815 match(Set dst (MoveL2D src)); 10816 effect(DEF dst, USE src); 10817 10818 ins_cost(125); 10819 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10820 ins_encode %{ 10821 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10822 %} 10823 ins_pipe(pipe_slow); 10824 %} 10825 10826 10827 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10828 match(Set dst (MoveF2I src)); 10829 effect(DEF dst, USE src); 10830 10831 ins_cost(95); // XXX 10832 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10833 ins_encode %{ 10834 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10835 %} 10836 ins_pipe(pipe_slow); 10837 %} 10838 10839 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10840 match(Set dst (MoveI2F src)); 10841 effect(DEF dst, USE src); 10842 10843 ins_cost(100); 10844 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10845 ins_encode %{ 10846 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10847 %} 10848 ins_pipe( ialu_mem_reg ); 10849 %} 10850 10851 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10852 match(Set dst (MoveD2L src)); 10853 effect(DEF dst, USE src); 10854 10855 ins_cost(95); // XXX 10856 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10857 ins_encode %{ 10858 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10859 %} 10860 ins_pipe(pipe_slow); 10861 %} 10862 10863 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10864 match(Set dst (MoveL2D src)); 10865 effect(DEF dst, USE src); 10866 10867 ins_cost(100); 10868 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10869 ins_encode %{ 10870 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10871 %} 10872 ins_pipe(ialu_mem_reg); 10873 %} 10874 10875 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10876 match(Set dst (MoveF2I src)); 10877 effect(DEF dst, USE src); 10878 ins_cost(85); 10879 format %{ "movd $dst,$src\t# MoveF2I" %} 10880 ins_encode %{ 10881 __ movdl($dst$$Register, $src$$XMMRegister); 10882 %} 10883 ins_pipe( pipe_slow ); 10884 %} 10885 10886 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10887 match(Set dst (MoveD2L src)); 10888 effect(DEF dst, USE src); 10889 ins_cost(85); 10890 format %{ "movd $dst,$src\t# MoveD2L" %} 10891 ins_encode %{ 10892 __ movdq($dst$$Register, $src$$XMMRegister); 10893 %} 10894 ins_pipe( pipe_slow ); 10895 %} 10896 10897 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10898 match(Set dst (MoveI2F src)); 10899 effect(DEF dst, USE src); 10900 ins_cost(100); 10901 format %{ "movd $dst,$src\t# MoveI2F" %} 10902 ins_encode %{ 10903 __ movdl($dst$$XMMRegister, $src$$Register); 10904 %} 10905 ins_pipe( pipe_slow ); 10906 %} 10907 10908 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10909 match(Set dst (MoveL2D src)); 10910 effect(DEF dst, USE src); 10911 ins_cost(100); 10912 format %{ "movd $dst,$src\t# MoveL2D" %} 10913 ins_encode %{ 10914 __ movdq($dst$$XMMRegister, $src$$Register); 10915 %} 10916 ins_pipe( pipe_slow ); 10917 %} 10918 10919 10920 // ======================================================================= 10921 // fast clearing of an array 10922 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10923 Universe dummy, rFlagsReg cr) 10924 %{ 10925 predicate(!((ClearArrayNode*)n)->is_large()); 10926 match(Set dummy (ClearArray cnt base)); 10927 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10928 10929 format %{ $$template 10930 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10931 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10932 $$emit$$"jg LARGE\n\t" 10933 $$emit$$"dec rcx\n\t" 10934 $$emit$$"js DONE\t# Zero length\n\t" 10935 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10936 $$emit$$"dec rcx\n\t" 10937 $$emit$$"jge LOOP\n\t" 10938 $$emit$$"jmp DONE\n\t" 10939 $$emit$$"# LARGE:\n\t" 10940 if (UseFastStosb) { 10941 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10942 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10943 } else if (UseXMMForObjInit) { 10944 $$emit$$"mov rdi,rax\n\t" 10945 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10946 $$emit$$"jmpq L_zero_64_bytes\n\t" 10947 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10948 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10949 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10950 $$emit$$"add 0x40,rax\n\t" 10951 $$emit$$"# L_zero_64_bytes:\n\t" 10952 $$emit$$"sub 0x8,rcx\n\t" 10953 $$emit$$"jge L_loop\n\t" 10954 $$emit$$"add 0x4,rcx\n\t" 10955 $$emit$$"jl L_tail\n\t" 10956 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10957 $$emit$$"add 0x20,rax\n\t" 10958 $$emit$$"sub 0x4,rcx\n\t" 10959 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10960 $$emit$$"add 0x4,rcx\n\t" 10961 $$emit$$"jle L_end\n\t" 10962 $$emit$$"dec rcx\n\t" 10963 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10964 $$emit$$"vmovq xmm0,(rax)\n\t" 10965 $$emit$$"add 0x8,rax\n\t" 10966 $$emit$$"dec rcx\n\t" 10967 $$emit$$"jge L_sloop\n\t" 10968 $$emit$$"# L_end:\n\t" 10969 } else { 10970 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10971 } 10972 $$emit$$"# DONE" 10973 %} 10974 ins_encode %{ 10975 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10976 $tmp$$XMMRegister, false); 10977 %} 10978 ins_pipe(pipe_slow); 10979 %} 10980 10981 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10982 Universe dummy, rFlagsReg cr) 10983 %{ 10984 predicate(((ClearArrayNode*)n)->is_large()); 10985 match(Set dummy (ClearArray cnt base)); 10986 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10987 10988 format %{ $$template 10989 if (UseFastStosb) { 10990 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10991 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10992 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10993 } else if (UseXMMForObjInit) { 10994 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10995 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10996 $$emit$$"jmpq L_zero_64_bytes\n\t" 10997 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10998 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10999 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11000 $$emit$$"add 0x40,rax\n\t" 11001 $$emit$$"# L_zero_64_bytes:\n\t" 11002 $$emit$$"sub 0x8,rcx\n\t" 11003 $$emit$$"jge L_loop\n\t" 11004 $$emit$$"add 0x4,rcx\n\t" 11005 $$emit$$"jl L_tail\n\t" 11006 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11007 $$emit$$"add 0x20,rax\n\t" 11008 $$emit$$"sub 0x4,rcx\n\t" 11009 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11010 $$emit$$"add 0x4,rcx\n\t" 11011 $$emit$$"jle L_end\n\t" 11012 $$emit$$"dec rcx\n\t" 11013 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11014 $$emit$$"vmovq xmm0,(rax)\n\t" 11015 $$emit$$"add 0x8,rax\n\t" 11016 $$emit$$"dec rcx\n\t" 11017 $$emit$$"jge L_sloop\n\t" 11018 $$emit$$"# L_end:\n\t" 11019 } else { 11020 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11021 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11022 } 11023 %} 11024 ins_encode %{ 11025 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11026 $tmp$$XMMRegister, true); 11027 %} 11028 ins_pipe(pipe_slow); 11029 %} 11030 11031 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11032 rax_RegI result, regD tmp1, rFlagsReg cr) 11033 %{ 11034 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11035 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11036 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11037 11038 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11039 ins_encode %{ 11040 __ string_compare($str1$$Register, $str2$$Register, 11041 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11042 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11043 %} 11044 ins_pipe( pipe_slow ); 11045 %} 11046 11047 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11048 rax_RegI result, regD tmp1, rFlagsReg cr) 11049 %{ 11050 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11051 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11052 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11053 11054 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11055 ins_encode %{ 11056 __ string_compare($str1$$Register, $str2$$Register, 11057 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11058 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11059 %} 11060 ins_pipe( pipe_slow ); 11061 %} 11062 11063 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11064 rax_RegI result, regD tmp1, rFlagsReg cr) 11065 %{ 11066 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11067 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11068 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11069 11070 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11071 ins_encode %{ 11072 __ string_compare($str1$$Register, $str2$$Register, 11073 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11074 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11075 %} 11076 ins_pipe( pipe_slow ); 11077 %} 11078 11079 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11080 rax_RegI result, regD tmp1, rFlagsReg cr) 11081 %{ 11082 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11083 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11084 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11085 11086 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11087 ins_encode %{ 11088 __ string_compare($str2$$Register, $str1$$Register, 11089 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11090 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11091 %} 11092 ins_pipe( pipe_slow ); 11093 %} 11094 11095 // fast search of substring with known size. 11096 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11097 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11098 %{ 11099 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11100 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11101 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11102 11103 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11104 ins_encode %{ 11105 int icnt2 = (int)$int_cnt2$$constant; 11106 if (icnt2 >= 16) { 11107 // IndexOf for constant substrings with size >= 16 elements 11108 // which don't need to be loaded through stack. 11109 __ string_indexofC8($str1$$Register, $str2$$Register, 11110 $cnt1$$Register, $cnt2$$Register, 11111 icnt2, $result$$Register, 11112 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11113 } else { 11114 // Small strings are loaded through stack if they cross page boundary. 11115 __ string_indexof($str1$$Register, $str2$$Register, 11116 $cnt1$$Register, $cnt2$$Register, 11117 icnt2, $result$$Register, 11118 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11119 } 11120 %} 11121 ins_pipe( pipe_slow ); 11122 %} 11123 11124 // fast search of substring with known size. 11125 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11126 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11127 %{ 11128 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11129 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11130 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11131 11132 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11133 ins_encode %{ 11134 int icnt2 = (int)$int_cnt2$$constant; 11135 if (icnt2 >= 8) { 11136 // IndexOf for constant substrings with size >= 8 elements 11137 // which don't need to be loaded through stack. 11138 __ string_indexofC8($str1$$Register, $str2$$Register, 11139 $cnt1$$Register, $cnt2$$Register, 11140 icnt2, $result$$Register, 11141 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11142 } else { 11143 // Small strings are loaded through stack if they cross page boundary. 11144 __ string_indexof($str1$$Register, $str2$$Register, 11145 $cnt1$$Register, $cnt2$$Register, 11146 icnt2, $result$$Register, 11147 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11148 } 11149 %} 11150 ins_pipe( pipe_slow ); 11151 %} 11152 11153 // fast search of substring with known size. 11154 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11155 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11156 %{ 11157 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11158 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11159 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11160 11161 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11162 ins_encode %{ 11163 int icnt2 = (int)$int_cnt2$$constant; 11164 if (icnt2 >= 8) { 11165 // IndexOf for constant substrings with size >= 8 elements 11166 // which don't need to be loaded through stack. 11167 __ string_indexofC8($str1$$Register, $str2$$Register, 11168 $cnt1$$Register, $cnt2$$Register, 11169 icnt2, $result$$Register, 11170 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11171 } else { 11172 // Small strings are loaded through stack if they cross page boundary. 11173 __ string_indexof($str1$$Register, $str2$$Register, 11174 $cnt1$$Register, $cnt2$$Register, 11175 icnt2, $result$$Register, 11176 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11177 } 11178 %} 11179 ins_pipe( pipe_slow ); 11180 %} 11181 11182 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11183 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11184 %{ 11185 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11186 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11187 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11188 11189 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11190 ins_encode %{ 11191 __ string_indexof($str1$$Register, $str2$$Register, 11192 $cnt1$$Register, $cnt2$$Register, 11193 (-1), $result$$Register, 11194 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11195 %} 11196 ins_pipe( pipe_slow ); 11197 %} 11198 11199 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11200 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11201 %{ 11202 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11203 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11204 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11205 11206 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11207 ins_encode %{ 11208 __ string_indexof($str1$$Register, $str2$$Register, 11209 $cnt1$$Register, $cnt2$$Register, 11210 (-1), $result$$Register, 11211 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11212 %} 11213 ins_pipe( pipe_slow ); 11214 %} 11215 11216 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11217 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11218 %{ 11219 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11220 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11221 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11222 11223 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11224 ins_encode %{ 11225 __ string_indexof($str1$$Register, $str2$$Register, 11226 $cnt1$$Register, $cnt2$$Register, 11227 (-1), $result$$Register, 11228 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11229 %} 11230 ins_pipe( pipe_slow ); 11231 %} 11232 11233 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11234 rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr) 11235 %{ 11236 predicate(UseSSE42Intrinsics); 11237 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11238 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11239 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11240 ins_encode %{ 11241 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11242 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11243 %} 11244 ins_pipe( pipe_slow ); 11245 %} 11246 11247 // fast string equals 11248 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11249 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11250 %{ 11251 match(Set result (StrEquals (Binary str1 str2) cnt)); 11252 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11253 11254 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11255 ins_encode %{ 11256 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11257 $cnt$$Register, $result$$Register, $tmp3$$Register, 11258 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11259 %} 11260 ins_pipe( pipe_slow ); 11261 %} 11262 11263 // fast array equals 11264 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11265 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11266 %{ 11267 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11268 match(Set result (AryEq ary1 ary2)); 11269 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11270 11271 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11272 ins_encode %{ 11273 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11274 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11275 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11276 %} 11277 ins_pipe( pipe_slow ); 11278 %} 11279 11280 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11281 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11282 %{ 11283 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11284 match(Set result (AryEq ary1 ary2)); 11285 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11286 11287 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11288 ins_encode %{ 11289 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11290 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11291 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11292 %} 11293 ins_pipe( pipe_slow ); 11294 %} 11295 11296 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11297 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11298 %{ 11299 match(Set result (HasNegatives ary1 len)); 11300 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11301 11302 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11303 ins_encode %{ 11304 __ has_negatives($ary1$$Register, $len$$Register, 11305 $result$$Register, $tmp3$$Register, 11306 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11307 %} 11308 ins_pipe( pipe_slow ); 11309 %} 11310 11311 // fast char[] to byte[] compression 11312 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11313 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11314 match(Set result (StrCompressedCopy src (Binary dst len))); 11315 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11316 11317 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11318 ins_encode %{ 11319 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11320 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11321 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11322 %} 11323 ins_pipe( pipe_slow ); 11324 %} 11325 11326 // fast byte[] to char[] inflation 11327 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11328 regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11329 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11330 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11331 11332 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11333 ins_encode %{ 11334 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11335 $tmp1$$XMMRegister, $tmp2$$Register); 11336 %} 11337 ins_pipe( pipe_slow ); 11338 %} 11339 11340 // encode char[] to byte[] in ISO_8859_1 11341 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11342 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11343 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11344 match(Set result (EncodeISOArray src (Binary dst len))); 11345 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11346 11347 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11348 ins_encode %{ 11349 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11350 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11351 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11352 %} 11353 ins_pipe( pipe_slow ); 11354 %} 11355 11356 //----------Overflow Math Instructions----------------------------------------- 11357 11358 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11359 %{ 11360 match(Set cr (OverflowAddI op1 op2)); 11361 effect(DEF cr, USE_KILL op1, USE op2); 11362 11363 format %{ "addl $op1, $op2\t# overflow check int" %} 11364 11365 ins_encode %{ 11366 __ addl($op1$$Register, $op2$$Register); 11367 %} 11368 ins_pipe(ialu_reg_reg); 11369 %} 11370 11371 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11372 %{ 11373 match(Set cr (OverflowAddI op1 op2)); 11374 effect(DEF cr, USE_KILL op1, USE op2); 11375 11376 format %{ "addl $op1, $op2\t# overflow check int" %} 11377 11378 ins_encode %{ 11379 __ addl($op1$$Register, $op2$$constant); 11380 %} 11381 ins_pipe(ialu_reg_reg); 11382 %} 11383 11384 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11385 %{ 11386 match(Set cr (OverflowAddL op1 op2)); 11387 effect(DEF cr, USE_KILL op1, USE op2); 11388 11389 format %{ "addq $op1, $op2\t# overflow check long" %} 11390 ins_encode %{ 11391 __ addq($op1$$Register, $op2$$Register); 11392 %} 11393 ins_pipe(ialu_reg_reg); 11394 %} 11395 11396 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11397 %{ 11398 match(Set cr (OverflowAddL op1 op2)); 11399 effect(DEF cr, USE_KILL op1, USE op2); 11400 11401 format %{ "addq $op1, $op2\t# overflow check long" %} 11402 ins_encode %{ 11403 __ addq($op1$$Register, $op2$$constant); 11404 %} 11405 ins_pipe(ialu_reg_reg); 11406 %} 11407 11408 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11409 %{ 11410 match(Set cr (OverflowSubI op1 op2)); 11411 11412 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11413 ins_encode %{ 11414 __ cmpl($op1$$Register, $op2$$Register); 11415 %} 11416 ins_pipe(ialu_reg_reg); 11417 %} 11418 11419 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11420 %{ 11421 match(Set cr (OverflowSubI op1 op2)); 11422 11423 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11424 ins_encode %{ 11425 __ cmpl($op1$$Register, $op2$$constant); 11426 %} 11427 ins_pipe(ialu_reg_reg); 11428 %} 11429 11430 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11431 %{ 11432 match(Set cr (OverflowSubL op1 op2)); 11433 11434 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11435 ins_encode %{ 11436 __ cmpq($op1$$Register, $op2$$Register); 11437 %} 11438 ins_pipe(ialu_reg_reg); 11439 %} 11440 11441 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11442 %{ 11443 match(Set cr (OverflowSubL op1 op2)); 11444 11445 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11446 ins_encode %{ 11447 __ cmpq($op1$$Register, $op2$$constant); 11448 %} 11449 ins_pipe(ialu_reg_reg); 11450 %} 11451 11452 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11453 %{ 11454 match(Set cr (OverflowSubI zero op2)); 11455 effect(DEF cr, USE_KILL op2); 11456 11457 format %{ "negl $op2\t# overflow check int" %} 11458 ins_encode %{ 11459 __ negl($op2$$Register); 11460 %} 11461 ins_pipe(ialu_reg_reg); 11462 %} 11463 11464 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11465 %{ 11466 match(Set cr (OverflowSubL zero op2)); 11467 effect(DEF cr, USE_KILL op2); 11468 11469 format %{ "negq $op2\t# overflow check long" %} 11470 ins_encode %{ 11471 __ negq($op2$$Register); 11472 %} 11473 ins_pipe(ialu_reg_reg); 11474 %} 11475 11476 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11477 %{ 11478 match(Set cr (OverflowMulI op1 op2)); 11479 effect(DEF cr, USE_KILL op1, USE op2); 11480 11481 format %{ "imull $op1, $op2\t# overflow check int" %} 11482 ins_encode %{ 11483 __ imull($op1$$Register, $op2$$Register); 11484 %} 11485 ins_pipe(ialu_reg_reg_alu0); 11486 %} 11487 11488 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11489 %{ 11490 match(Set cr (OverflowMulI op1 op2)); 11491 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11492 11493 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11494 ins_encode %{ 11495 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11496 %} 11497 ins_pipe(ialu_reg_reg_alu0); 11498 %} 11499 11500 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11501 %{ 11502 match(Set cr (OverflowMulL op1 op2)); 11503 effect(DEF cr, USE_KILL op1, USE op2); 11504 11505 format %{ "imulq $op1, $op2\t# overflow check long" %} 11506 ins_encode %{ 11507 __ imulq($op1$$Register, $op2$$Register); 11508 %} 11509 ins_pipe(ialu_reg_reg_alu0); 11510 %} 11511 11512 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11513 %{ 11514 match(Set cr (OverflowMulL op1 op2)); 11515 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11516 11517 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11518 ins_encode %{ 11519 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11520 %} 11521 ins_pipe(ialu_reg_reg_alu0); 11522 %} 11523 11524 11525 //----------Control Flow Instructions------------------------------------------ 11526 // Signed compare Instructions 11527 11528 // XXX more variants!! 11529 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11530 %{ 11531 match(Set cr (CmpI op1 op2)); 11532 effect(DEF cr, USE op1, USE op2); 11533 11534 format %{ "cmpl $op1, $op2" %} 11535 opcode(0x3B); /* Opcode 3B /r */ 11536 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11537 ins_pipe(ialu_cr_reg_reg); 11538 %} 11539 11540 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11541 %{ 11542 match(Set cr (CmpI op1 op2)); 11543 11544 format %{ "cmpl $op1, $op2" %} 11545 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11546 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11547 ins_pipe(ialu_cr_reg_imm); 11548 %} 11549 11550 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11551 %{ 11552 match(Set cr (CmpI op1 (LoadI op2))); 11553 11554 ins_cost(500); // XXX 11555 format %{ "cmpl $op1, $op2" %} 11556 opcode(0x3B); /* Opcode 3B /r */ 11557 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11558 ins_pipe(ialu_cr_reg_mem); 11559 %} 11560 11561 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11562 %{ 11563 match(Set cr (CmpI src zero)); 11564 11565 format %{ "testl $src, $src" %} 11566 opcode(0x85); 11567 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11568 ins_pipe(ialu_cr_reg_imm); 11569 %} 11570 11571 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11572 %{ 11573 match(Set cr (CmpI (AndI src con) zero)); 11574 11575 format %{ "testl $src, $con" %} 11576 opcode(0xF7, 0x00); 11577 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11578 ins_pipe(ialu_cr_reg_imm); 11579 %} 11580 11581 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11582 %{ 11583 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11584 11585 format %{ "testl $src, $mem" %} 11586 opcode(0x85); 11587 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11588 ins_pipe(ialu_cr_reg_mem); 11589 %} 11590 11591 // Unsigned compare Instructions; really, same as signed except they 11592 // produce an rFlagsRegU instead of rFlagsReg. 11593 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11594 %{ 11595 match(Set cr (CmpU op1 op2)); 11596 11597 format %{ "cmpl $op1, $op2\t# unsigned" %} 11598 opcode(0x3B); /* Opcode 3B /r */ 11599 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11600 ins_pipe(ialu_cr_reg_reg); 11601 %} 11602 11603 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11604 %{ 11605 match(Set cr (CmpU op1 op2)); 11606 11607 format %{ "cmpl $op1, $op2\t# unsigned" %} 11608 opcode(0x81,0x07); /* Opcode 81 /7 */ 11609 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11610 ins_pipe(ialu_cr_reg_imm); 11611 %} 11612 11613 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11614 %{ 11615 match(Set cr (CmpU op1 (LoadI op2))); 11616 11617 ins_cost(500); // XXX 11618 format %{ "cmpl $op1, $op2\t# unsigned" %} 11619 opcode(0x3B); /* Opcode 3B /r */ 11620 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11621 ins_pipe(ialu_cr_reg_mem); 11622 %} 11623 11624 // // // Cisc-spilled version of cmpU_rReg 11625 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11626 // //%{ 11627 // // match(Set cr (CmpU (LoadI op1) op2)); 11628 // // 11629 // // format %{ "CMPu $op1,$op2" %} 11630 // // ins_cost(500); 11631 // // opcode(0x39); /* Opcode 39 /r */ 11632 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11633 // //%} 11634 11635 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11636 %{ 11637 match(Set cr (CmpU src zero)); 11638 11639 format %{ "testl $src, $src\t# unsigned" %} 11640 opcode(0x85); 11641 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11642 ins_pipe(ialu_cr_reg_imm); 11643 %} 11644 11645 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11646 %{ 11647 match(Set cr (CmpP op1 op2)); 11648 11649 format %{ "cmpq $op1, $op2\t# ptr" %} 11650 opcode(0x3B); /* Opcode 3B /r */ 11651 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11652 ins_pipe(ialu_cr_reg_reg); 11653 %} 11654 11655 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11656 %{ 11657 match(Set cr (CmpP op1 (LoadP op2))); 11658 11659 ins_cost(500); // XXX 11660 format %{ "cmpq $op1, $op2\t# ptr" %} 11661 opcode(0x3B); /* Opcode 3B /r */ 11662 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11663 ins_pipe(ialu_cr_reg_mem); 11664 %} 11665 11666 // // // Cisc-spilled version of cmpP_rReg 11667 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11668 // //%{ 11669 // // match(Set cr (CmpP (LoadP op1) op2)); 11670 // // 11671 // // format %{ "CMPu $op1,$op2" %} 11672 // // ins_cost(500); 11673 // // opcode(0x39); /* Opcode 39 /r */ 11674 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11675 // //%} 11676 11677 // XXX this is generalized by compP_rReg_mem??? 11678 // Compare raw pointer (used in out-of-heap check). 11679 // Only works because non-oop pointers must be raw pointers 11680 // and raw pointers have no anti-dependencies. 11681 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11682 %{ 11683 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11684 match(Set cr (CmpP op1 (LoadP op2))); 11685 11686 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11687 opcode(0x3B); /* Opcode 3B /r */ 11688 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11689 ins_pipe(ialu_cr_reg_mem); 11690 %} 11691 11692 // This will generate a signed flags result. This should be OK since 11693 // any compare to a zero should be eq/neq. 11694 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11695 %{ 11696 match(Set cr (CmpP src zero)); 11697 11698 format %{ "testq $src, $src\t# ptr" %} 11699 opcode(0x85); 11700 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11701 ins_pipe(ialu_cr_reg_imm); 11702 %} 11703 11704 // This will generate a signed flags result. This should be OK since 11705 // any compare to a zero should be eq/neq. 11706 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11707 %{ 11708 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11709 match(Set cr (CmpP (LoadP op) zero)); 11710 11711 ins_cost(500); // XXX 11712 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11713 opcode(0xF7); /* Opcode F7 /0 */ 11714 ins_encode(REX_mem_wide(op), 11715 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11716 ins_pipe(ialu_cr_reg_imm); 11717 %} 11718 11719 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11720 %{ 11721 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11722 match(Set cr (CmpP (LoadP mem) zero)); 11723 11724 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11725 ins_encode %{ 11726 __ cmpq(r12, $mem$$Address); 11727 %} 11728 ins_pipe(ialu_cr_reg_mem); 11729 %} 11730 11731 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11732 %{ 11733 match(Set cr (CmpN op1 op2)); 11734 11735 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11736 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11737 ins_pipe(ialu_cr_reg_reg); 11738 %} 11739 11740 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11741 %{ 11742 match(Set cr (CmpN src (LoadN mem))); 11743 11744 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11745 ins_encode %{ 11746 __ cmpl($src$$Register, $mem$$Address); 11747 %} 11748 ins_pipe(ialu_cr_reg_mem); 11749 %} 11750 11751 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11752 match(Set cr (CmpN op1 op2)); 11753 11754 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11755 ins_encode %{ 11756 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11757 %} 11758 ins_pipe(ialu_cr_reg_imm); 11759 %} 11760 11761 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11762 %{ 11763 match(Set cr (CmpN src (LoadN mem))); 11764 11765 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11766 ins_encode %{ 11767 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11768 %} 11769 ins_pipe(ialu_cr_reg_mem); 11770 %} 11771 11772 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11773 match(Set cr (CmpN op1 op2)); 11774 11775 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11776 ins_encode %{ 11777 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11778 %} 11779 ins_pipe(ialu_cr_reg_imm); 11780 %} 11781 11782 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11783 %{ 11784 match(Set cr (CmpN src (LoadNKlass mem))); 11785 11786 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11787 ins_encode %{ 11788 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11789 %} 11790 ins_pipe(ialu_cr_reg_mem); 11791 %} 11792 11793 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11794 match(Set cr (CmpN src zero)); 11795 11796 format %{ "testl $src, $src\t# compressed ptr" %} 11797 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11798 ins_pipe(ialu_cr_reg_imm); 11799 %} 11800 11801 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11802 %{ 11803 predicate(Universe::narrow_oop_base() != NULL); 11804 match(Set cr (CmpN (LoadN mem) zero)); 11805 11806 ins_cost(500); // XXX 11807 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11808 ins_encode %{ 11809 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11810 %} 11811 ins_pipe(ialu_cr_reg_mem); 11812 %} 11813 11814 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11815 %{ 11816 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11817 match(Set cr (CmpN (LoadN mem) zero)); 11818 11819 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11820 ins_encode %{ 11821 __ cmpl(r12, $mem$$Address); 11822 %} 11823 ins_pipe(ialu_cr_reg_mem); 11824 %} 11825 11826 // Yanked all unsigned pointer compare operations. 11827 // Pointer compares are done with CmpP which is already unsigned. 11828 11829 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11830 %{ 11831 match(Set cr (CmpL op1 op2)); 11832 11833 format %{ "cmpq $op1, $op2" %} 11834 opcode(0x3B); /* Opcode 3B /r */ 11835 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11836 ins_pipe(ialu_cr_reg_reg); 11837 %} 11838 11839 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11840 %{ 11841 match(Set cr (CmpL op1 op2)); 11842 11843 format %{ "cmpq $op1, $op2" %} 11844 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11845 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11846 ins_pipe(ialu_cr_reg_imm); 11847 %} 11848 11849 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11850 %{ 11851 match(Set cr (CmpL op1 (LoadL op2))); 11852 11853 format %{ "cmpq $op1, $op2" %} 11854 opcode(0x3B); /* Opcode 3B /r */ 11855 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11856 ins_pipe(ialu_cr_reg_mem); 11857 %} 11858 11859 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11860 %{ 11861 match(Set cr (CmpL src zero)); 11862 11863 format %{ "testq $src, $src" %} 11864 opcode(0x85); 11865 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11866 ins_pipe(ialu_cr_reg_imm); 11867 %} 11868 11869 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11870 %{ 11871 match(Set cr (CmpL (AndL src con) zero)); 11872 11873 format %{ "testq $src, $con\t# long" %} 11874 opcode(0xF7, 0x00); 11875 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11876 ins_pipe(ialu_cr_reg_imm); 11877 %} 11878 11879 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11880 %{ 11881 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11882 11883 format %{ "testq $src, $mem" %} 11884 opcode(0x85); 11885 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11886 ins_pipe(ialu_cr_reg_mem); 11887 %} 11888 11889 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11890 %{ 11891 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11892 11893 format %{ "testq $src, $mem" %} 11894 opcode(0x85); 11895 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11896 ins_pipe(ialu_cr_reg_mem); 11897 %} 11898 11899 // Manifest a CmpL result in an integer register. Very painful. 11900 // This is the test to avoid. 11901 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11902 %{ 11903 match(Set dst (CmpL3 src1 src2)); 11904 effect(KILL flags); 11905 11906 ins_cost(275); // XXX 11907 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11908 "movl $dst, -1\n\t" 11909 "jl,s done\n\t" 11910 "setne $dst\n\t" 11911 "movzbl $dst, $dst\n\t" 11912 "done:" %} 11913 ins_encode(cmpl3_flag(src1, src2, dst)); 11914 ins_pipe(pipe_slow); 11915 %} 11916 11917 // Unsigned long compare Instructions; really, same as signed long except they 11918 // produce an rFlagsRegU instead of rFlagsReg. 11919 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11920 %{ 11921 match(Set cr (CmpUL op1 op2)); 11922 11923 format %{ "cmpq $op1, $op2\t# unsigned" %} 11924 opcode(0x3B); /* Opcode 3B /r */ 11925 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11926 ins_pipe(ialu_cr_reg_reg); 11927 %} 11928 11929 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11930 %{ 11931 match(Set cr (CmpUL op1 op2)); 11932 11933 format %{ "cmpq $op1, $op2\t# unsigned" %} 11934 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11935 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11936 ins_pipe(ialu_cr_reg_imm); 11937 %} 11938 11939 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11940 %{ 11941 match(Set cr (CmpUL op1 (LoadL op2))); 11942 11943 format %{ "cmpq $op1, $op2\t# unsigned" %} 11944 opcode(0x3B); /* Opcode 3B /r */ 11945 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11946 ins_pipe(ialu_cr_reg_mem); 11947 %} 11948 11949 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11950 %{ 11951 match(Set cr (CmpUL src zero)); 11952 11953 format %{ "testq $src, $src\t# unsigned" %} 11954 opcode(0x85); 11955 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11956 ins_pipe(ialu_cr_reg_imm); 11957 %} 11958 11959 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11960 %{ 11961 match(Set cr (CmpI (LoadB mem) imm)); 11962 11963 ins_cost(125); 11964 format %{ "cmpb $mem, $imm" %} 11965 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11966 ins_pipe(ialu_cr_reg_mem); 11967 %} 11968 11969 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 11970 %{ 11971 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11972 11973 ins_cost(125); 11974 format %{ "testb $mem, $imm" %} 11975 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11976 ins_pipe(ialu_cr_reg_mem); 11977 %} 11978 11979 //----------Max and Min-------------------------------------------------------- 11980 // Min Instructions 11981 11982 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11983 %{ 11984 effect(USE_DEF dst, USE src, USE cr); 11985 11986 format %{ "cmovlgt $dst, $src\t# min" %} 11987 opcode(0x0F, 0x4F); 11988 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11989 ins_pipe(pipe_cmov_reg); 11990 %} 11991 11992 11993 instruct minI_rReg(rRegI dst, rRegI src) 11994 %{ 11995 match(Set dst (MinI dst src)); 11996 11997 ins_cost(200); 11998 expand %{ 11999 rFlagsReg cr; 12000 compI_rReg(cr, dst, src); 12001 cmovI_reg_g(dst, src, cr); 12002 %} 12003 %} 12004 12005 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12006 %{ 12007 effect(USE_DEF dst, USE src, USE cr); 12008 12009 format %{ "cmovllt $dst, $src\t# max" %} 12010 opcode(0x0F, 0x4C); 12011 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12012 ins_pipe(pipe_cmov_reg); 12013 %} 12014 12015 12016 instruct maxI_rReg(rRegI dst, rRegI src) 12017 %{ 12018 match(Set dst (MaxI dst src)); 12019 12020 ins_cost(200); 12021 expand %{ 12022 rFlagsReg cr; 12023 compI_rReg(cr, dst, src); 12024 cmovI_reg_l(dst, src, cr); 12025 %} 12026 %} 12027 12028 // ============================================================================ 12029 // Branch Instructions 12030 12031 // Jump Direct - Label defines a relative address from JMP+1 12032 instruct jmpDir(label labl) 12033 %{ 12034 match(Goto); 12035 effect(USE labl); 12036 12037 ins_cost(300); 12038 format %{ "jmp $labl" %} 12039 size(5); 12040 ins_encode %{ 12041 Label* L = $labl$$label; 12042 __ jmp(*L, false); // Always long jump 12043 %} 12044 ins_pipe(pipe_jmp); 12045 %} 12046 12047 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12048 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12049 %{ 12050 match(If cop cr); 12051 effect(USE labl); 12052 12053 ins_cost(300); 12054 format %{ "j$cop $labl" %} 12055 size(6); 12056 ins_encode %{ 12057 Label* L = $labl$$label; 12058 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12059 %} 12060 ins_pipe(pipe_jcc); 12061 %} 12062 12063 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12064 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12065 %{ 12066 predicate(!n->has_vector_mask_set()); 12067 match(CountedLoopEnd cop cr); 12068 effect(USE labl); 12069 12070 ins_cost(300); 12071 format %{ "j$cop $labl\t# loop end" %} 12072 size(6); 12073 ins_encode %{ 12074 Label* L = $labl$$label; 12075 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12076 %} 12077 ins_pipe(pipe_jcc); 12078 %} 12079 12080 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12081 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12082 predicate(!n->has_vector_mask_set()); 12083 match(CountedLoopEnd cop cmp); 12084 effect(USE labl); 12085 12086 ins_cost(300); 12087 format %{ "j$cop,u $labl\t# loop end" %} 12088 size(6); 12089 ins_encode %{ 12090 Label* L = $labl$$label; 12091 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12092 %} 12093 ins_pipe(pipe_jcc); 12094 %} 12095 12096 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12097 predicate(!n->has_vector_mask_set()); 12098 match(CountedLoopEnd cop cmp); 12099 effect(USE labl); 12100 12101 ins_cost(200); 12102 format %{ "j$cop,u $labl\t# loop end" %} 12103 size(6); 12104 ins_encode %{ 12105 Label* L = $labl$$label; 12106 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12107 %} 12108 ins_pipe(pipe_jcc); 12109 %} 12110 12111 // mask version 12112 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12113 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12114 %{ 12115 predicate(n->has_vector_mask_set()); 12116 match(CountedLoopEnd cop cr); 12117 effect(USE labl); 12118 12119 ins_cost(400); 12120 format %{ "j$cop $labl\t# loop end\n\t" 12121 "restorevectmask \t# vector mask restore for loops" %} 12122 size(10); 12123 ins_encode %{ 12124 Label* L = $labl$$label; 12125 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12126 __ restorevectmask(); 12127 %} 12128 ins_pipe(pipe_jcc); 12129 %} 12130 12131 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12132 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12133 predicate(n->has_vector_mask_set()); 12134 match(CountedLoopEnd cop cmp); 12135 effect(USE labl); 12136 12137 ins_cost(400); 12138 format %{ "j$cop,u $labl\t# loop end\n\t" 12139 "restorevectmask \t# vector mask restore for loops" %} 12140 size(10); 12141 ins_encode %{ 12142 Label* L = $labl$$label; 12143 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12144 __ restorevectmask(); 12145 %} 12146 ins_pipe(pipe_jcc); 12147 %} 12148 12149 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12150 predicate(n->has_vector_mask_set()); 12151 match(CountedLoopEnd cop cmp); 12152 effect(USE labl); 12153 12154 ins_cost(300); 12155 format %{ "j$cop,u $labl\t# loop end\n\t" 12156 "restorevectmask \t# vector mask restore for loops" %} 12157 size(10); 12158 ins_encode %{ 12159 Label* L = $labl$$label; 12160 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12161 __ restorevectmask(); 12162 %} 12163 ins_pipe(pipe_jcc); 12164 %} 12165 12166 // Jump Direct Conditional - using unsigned comparison 12167 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12168 match(If cop cmp); 12169 effect(USE labl); 12170 12171 ins_cost(300); 12172 format %{ "j$cop,u $labl" %} 12173 size(6); 12174 ins_encode %{ 12175 Label* L = $labl$$label; 12176 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12177 %} 12178 ins_pipe(pipe_jcc); 12179 %} 12180 12181 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12182 match(If cop cmp); 12183 effect(USE labl); 12184 12185 ins_cost(200); 12186 format %{ "j$cop,u $labl" %} 12187 size(6); 12188 ins_encode %{ 12189 Label* L = $labl$$label; 12190 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12191 %} 12192 ins_pipe(pipe_jcc); 12193 %} 12194 12195 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12196 match(If cop cmp); 12197 effect(USE labl); 12198 12199 ins_cost(200); 12200 format %{ $$template 12201 if ($cop$$cmpcode == Assembler::notEqual) { 12202 $$emit$$"jp,u $labl\n\t" 12203 $$emit$$"j$cop,u $labl" 12204 } else { 12205 $$emit$$"jp,u done\n\t" 12206 $$emit$$"j$cop,u $labl\n\t" 12207 $$emit$$"done:" 12208 } 12209 %} 12210 ins_encode %{ 12211 Label* l = $labl$$label; 12212 if ($cop$$cmpcode == Assembler::notEqual) { 12213 __ jcc(Assembler::parity, *l, false); 12214 __ jcc(Assembler::notEqual, *l, false); 12215 } else if ($cop$$cmpcode == Assembler::equal) { 12216 Label done; 12217 __ jccb(Assembler::parity, done); 12218 __ jcc(Assembler::equal, *l, false); 12219 __ bind(done); 12220 } else { 12221 ShouldNotReachHere(); 12222 } 12223 %} 12224 ins_pipe(pipe_jcc); 12225 %} 12226 12227 // ============================================================================ 12228 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12229 // superklass array for an instance of the superklass. Set a hidden 12230 // internal cache on a hit (cache is checked with exposed code in 12231 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12232 // encoding ALSO sets flags. 12233 12234 instruct partialSubtypeCheck(rdi_RegP result, 12235 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12236 rFlagsReg cr) 12237 %{ 12238 match(Set result (PartialSubtypeCheck sub super)); 12239 effect(KILL rcx, KILL cr); 12240 12241 ins_cost(1100); // slightly larger than the next version 12242 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12243 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12244 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12245 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12246 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12247 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12248 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12249 "miss:\t" %} 12250 12251 opcode(0x1); // Force a XOR of RDI 12252 ins_encode(enc_PartialSubtypeCheck()); 12253 ins_pipe(pipe_slow); 12254 %} 12255 12256 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12257 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12258 immP0 zero, 12259 rdi_RegP result) 12260 %{ 12261 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12262 effect(KILL rcx, KILL result); 12263 12264 ins_cost(1000); 12265 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12266 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12267 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12268 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12269 "jne,s miss\t\t# Missed: flags nz\n\t" 12270 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12271 "miss:\t" %} 12272 12273 opcode(0x0); // No need to XOR RDI 12274 ins_encode(enc_PartialSubtypeCheck()); 12275 ins_pipe(pipe_slow); 12276 %} 12277 12278 // ============================================================================ 12279 // Branch Instructions -- short offset versions 12280 // 12281 // These instructions are used to replace jumps of a long offset (the default 12282 // match) with jumps of a shorter offset. These instructions are all tagged 12283 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12284 // match rules in general matching. Instead, the ADLC generates a conversion 12285 // method in the MachNode which can be used to do in-place replacement of the 12286 // long variant with the shorter variant. The compiler will determine if a 12287 // branch can be taken by the is_short_branch_offset() predicate in the machine 12288 // specific code section of the file. 12289 12290 // Jump Direct - Label defines a relative address from JMP+1 12291 instruct jmpDir_short(label labl) %{ 12292 match(Goto); 12293 effect(USE labl); 12294 12295 ins_cost(300); 12296 format %{ "jmp,s $labl" %} 12297 size(2); 12298 ins_encode %{ 12299 Label* L = $labl$$label; 12300 __ jmpb(*L); 12301 %} 12302 ins_pipe(pipe_jmp); 12303 ins_short_branch(1); 12304 %} 12305 12306 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12307 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12308 match(If cop cr); 12309 effect(USE labl); 12310 12311 ins_cost(300); 12312 format %{ "j$cop,s $labl" %} 12313 size(2); 12314 ins_encode %{ 12315 Label* L = $labl$$label; 12316 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12317 %} 12318 ins_pipe(pipe_jcc); 12319 ins_short_branch(1); 12320 %} 12321 12322 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12323 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12324 match(CountedLoopEnd cop cr); 12325 effect(USE labl); 12326 12327 ins_cost(300); 12328 format %{ "j$cop,s $labl\t# loop end" %} 12329 size(2); 12330 ins_encode %{ 12331 Label* L = $labl$$label; 12332 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12333 %} 12334 ins_pipe(pipe_jcc); 12335 ins_short_branch(1); 12336 %} 12337 12338 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12339 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12340 match(CountedLoopEnd cop cmp); 12341 effect(USE labl); 12342 12343 ins_cost(300); 12344 format %{ "j$cop,us $labl\t# loop end" %} 12345 size(2); 12346 ins_encode %{ 12347 Label* L = $labl$$label; 12348 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12349 %} 12350 ins_pipe(pipe_jcc); 12351 ins_short_branch(1); 12352 %} 12353 12354 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12355 match(CountedLoopEnd cop cmp); 12356 effect(USE labl); 12357 12358 ins_cost(300); 12359 format %{ "j$cop,us $labl\t# loop end" %} 12360 size(2); 12361 ins_encode %{ 12362 Label* L = $labl$$label; 12363 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12364 %} 12365 ins_pipe(pipe_jcc); 12366 ins_short_branch(1); 12367 %} 12368 12369 // Jump Direct Conditional - using unsigned comparison 12370 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12371 match(If cop cmp); 12372 effect(USE labl); 12373 12374 ins_cost(300); 12375 format %{ "j$cop,us $labl" %} 12376 size(2); 12377 ins_encode %{ 12378 Label* L = $labl$$label; 12379 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12380 %} 12381 ins_pipe(pipe_jcc); 12382 ins_short_branch(1); 12383 %} 12384 12385 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12386 match(If cop cmp); 12387 effect(USE labl); 12388 12389 ins_cost(300); 12390 format %{ "j$cop,us $labl" %} 12391 size(2); 12392 ins_encode %{ 12393 Label* L = $labl$$label; 12394 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12395 %} 12396 ins_pipe(pipe_jcc); 12397 ins_short_branch(1); 12398 %} 12399 12400 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12401 match(If cop cmp); 12402 effect(USE labl); 12403 12404 ins_cost(300); 12405 format %{ $$template 12406 if ($cop$$cmpcode == Assembler::notEqual) { 12407 $$emit$$"jp,u,s $labl\n\t" 12408 $$emit$$"j$cop,u,s $labl" 12409 } else { 12410 $$emit$$"jp,u,s done\n\t" 12411 $$emit$$"j$cop,u,s $labl\n\t" 12412 $$emit$$"done:" 12413 } 12414 %} 12415 size(4); 12416 ins_encode %{ 12417 Label* l = $labl$$label; 12418 if ($cop$$cmpcode == Assembler::notEqual) { 12419 __ jccb(Assembler::parity, *l); 12420 __ jccb(Assembler::notEqual, *l); 12421 } else if ($cop$$cmpcode == Assembler::equal) { 12422 Label done; 12423 __ jccb(Assembler::parity, done); 12424 __ jccb(Assembler::equal, *l); 12425 __ bind(done); 12426 } else { 12427 ShouldNotReachHere(); 12428 } 12429 %} 12430 ins_pipe(pipe_jcc); 12431 ins_short_branch(1); 12432 %} 12433 12434 // ============================================================================ 12435 // inlined locking and unlocking 12436 12437 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12438 predicate(Compile::current()->use_rtm()); 12439 match(Set cr (FastLock object box)); 12440 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12441 ins_cost(300); 12442 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12443 ins_encode %{ 12444 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12445 $scr$$Register, $cx1$$Register, $cx2$$Register, 12446 _counters, _rtm_counters, _stack_rtm_counters, 12447 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12448 true, ra_->C->profile_rtm()); 12449 %} 12450 ins_pipe(pipe_slow); 12451 %} 12452 12453 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12454 predicate(!Compile::current()->use_rtm()); 12455 match(Set cr (FastLock object box)); 12456 effect(TEMP tmp, TEMP scr, USE_KILL box); 12457 ins_cost(300); 12458 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12459 ins_encode %{ 12460 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12461 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12462 %} 12463 ins_pipe(pipe_slow); 12464 %} 12465 12466 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12467 match(Set cr (FastUnlock object box)); 12468 effect(TEMP tmp, USE_KILL box); 12469 ins_cost(300); 12470 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12471 ins_encode %{ 12472 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12473 %} 12474 ins_pipe(pipe_slow); 12475 %} 12476 12477 12478 // ============================================================================ 12479 // Safepoint Instructions 12480 instruct safePoint_poll(rFlagsReg cr) 12481 %{ 12482 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12483 match(SafePoint); 12484 effect(KILL cr); 12485 12486 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12487 "# Safepoint: poll for GC" %} 12488 ins_cost(125); 12489 ins_encode %{ 12490 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12491 __ testl(rax, addr); 12492 %} 12493 ins_pipe(ialu_reg_mem); 12494 %} 12495 12496 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12497 %{ 12498 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12499 match(SafePoint poll); 12500 effect(KILL cr, USE poll); 12501 12502 format %{ "testl rax, [$poll]\t" 12503 "# Safepoint: poll for GC" %} 12504 ins_cost(125); 12505 ins_encode %{ 12506 __ relocate(relocInfo::poll_type); 12507 __ testl(rax, Address($poll$$Register, 0)); 12508 %} 12509 ins_pipe(ialu_reg_mem); 12510 %} 12511 12512 instruct safePoint_poll_tls(rFlagsReg cr, rex_RegP poll) 12513 %{ 12514 predicate(SafepointMechanism::uses_thread_local_poll()); 12515 match(SafePoint poll); 12516 effect(KILL cr, USE poll); 12517 12518 format %{ "testl rax, [$poll]\t" 12519 "# Safepoint: poll for GC" %} 12520 ins_cost(125); 12521 size(3); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12522 ins_encode %{ 12523 __ relocate(relocInfo::poll_type); 12524 address pre_pc = __ pc(); 12525 __ testl(rax, Address($poll$$Register, 0)); 12526 address post_pc = __ pc(); 12527 guarantee(pre_pc[0] == 0x41 && pre_pc[1] == 0x85, "must emit #rex test-ax [reg]"); 12528 %} 12529 ins_pipe(ialu_reg_mem); 12530 %} 12531 12532 // ============================================================================ 12533 // Procedure Call/Return Instructions 12534 // Call Java Static Instruction 12535 // Note: If this code changes, the corresponding ret_addr_offset() and 12536 // compute_padding() functions will have to be adjusted. 12537 instruct CallStaticJavaDirect(method meth) %{ 12538 match(CallStaticJava); 12539 effect(USE meth); 12540 12541 ins_cost(300); 12542 format %{ "call,static " %} 12543 opcode(0xE8); /* E8 cd */ 12544 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12545 ins_pipe(pipe_slow); 12546 ins_alignment(4); 12547 %} 12548 12549 // Call Java Dynamic Instruction 12550 // Note: If this code changes, the corresponding ret_addr_offset() and 12551 // compute_padding() functions will have to be adjusted. 12552 instruct CallDynamicJavaDirect(method meth) 12553 %{ 12554 match(CallDynamicJava); 12555 effect(USE meth); 12556 12557 ins_cost(300); 12558 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12559 "call,dynamic " %} 12560 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12561 ins_pipe(pipe_slow); 12562 ins_alignment(4); 12563 %} 12564 12565 // Call Runtime Instruction 12566 instruct CallRuntimeDirect(method meth) 12567 %{ 12568 match(CallRuntime); 12569 effect(USE meth); 12570 12571 ins_cost(300); 12572 format %{ "call,runtime " %} 12573 ins_encode(clear_avx, Java_To_Runtime(meth)); 12574 ins_pipe(pipe_slow); 12575 %} 12576 12577 // Call runtime without safepoint 12578 instruct CallLeafDirect(method meth) 12579 %{ 12580 match(CallLeaf); 12581 effect(USE meth); 12582 12583 ins_cost(300); 12584 format %{ "call_leaf,runtime " %} 12585 ins_encode(clear_avx, Java_To_Runtime(meth)); 12586 ins_pipe(pipe_slow); 12587 %} 12588 12589 // Call runtime without safepoint 12590 instruct CallLeafNoFPDirect(method meth) 12591 %{ 12592 match(CallLeafNoFP); 12593 effect(USE meth); 12594 12595 ins_cost(300); 12596 format %{ "call_leaf_nofp,runtime " %} 12597 ins_encode(clear_avx, Java_To_Runtime(meth)); 12598 ins_pipe(pipe_slow); 12599 %} 12600 12601 // Return Instruction 12602 // Remove the return address & jump to it. 12603 // Notice: We always emit a nop after a ret to make sure there is room 12604 // for safepoint patching 12605 instruct Ret() 12606 %{ 12607 match(Return); 12608 12609 format %{ "ret" %} 12610 opcode(0xC3); 12611 ins_encode(OpcP); 12612 ins_pipe(pipe_jmp); 12613 %} 12614 12615 // Tail Call; Jump from runtime stub to Java code. 12616 // Also known as an 'interprocedural jump'. 12617 // Target of jump will eventually return to caller. 12618 // TailJump below removes the return address. 12619 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12620 %{ 12621 match(TailCall jump_target method_oop); 12622 12623 ins_cost(300); 12624 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12625 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12626 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12627 ins_pipe(pipe_jmp); 12628 %} 12629 12630 // Tail Jump; remove the return address; jump to target. 12631 // TailCall above leaves the return address around. 12632 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12633 %{ 12634 match(TailJump jump_target ex_oop); 12635 12636 ins_cost(300); 12637 format %{ "popq rdx\t# pop return address\n\t" 12638 "jmp $jump_target" %} 12639 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12640 ins_encode(Opcode(0x5a), // popq rdx 12641 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12642 ins_pipe(pipe_jmp); 12643 %} 12644 12645 // Create exception oop: created by stack-crawling runtime code. 12646 // Created exception is now available to this handler, and is setup 12647 // just prior to jumping to this handler. No code emitted. 12648 instruct CreateException(rax_RegP ex_oop) 12649 %{ 12650 match(Set ex_oop (CreateEx)); 12651 12652 size(0); 12653 // use the following format syntax 12654 format %{ "# exception oop is in rax; no code emitted" %} 12655 ins_encode(); 12656 ins_pipe(empty); 12657 %} 12658 12659 // Rethrow exception: 12660 // The exception oop will come in the first argument position. 12661 // Then JUMP (not call) to the rethrow stub code. 12662 instruct RethrowException() 12663 %{ 12664 match(Rethrow); 12665 12666 // use the following format syntax 12667 format %{ "jmp rethrow_stub" %} 12668 ins_encode(enc_rethrow); 12669 ins_pipe(pipe_jmp); 12670 %} 12671 12672 // 12673 // Execute ZGC load barrier (strong) slow path 12674 // 12675 12676 // When running without XMM regs 12677 instruct loadBarrierSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12678 12679 match(Set dst (LoadBarrierSlowReg mem)); 12680 predicate(MaxVectorSize < 16); 12681 12682 effect(DEF dst, KILL cr); 12683 12684 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12685 ins_encode %{ 12686 #if INCLUDE_ZGC 12687 Register d = $dst$$Register; 12688 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12689 12690 assert(d != r12, "Can't be R12!"); 12691 assert(d != r15, "Can't be R15!"); 12692 assert(d != rsp, "Can't be RSP!"); 12693 12694 __ lea(d, $mem$$Address); 12695 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12696 #else 12697 ShouldNotReachHere(); 12698 #endif 12699 %} 12700 ins_pipe(pipe_slow); 12701 %} 12702 12703 // For XMM and YMM enabled processors 12704 instruct loadBarrierSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12705 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12706 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12707 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12708 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12709 12710 match(Set dst (LoadBarrierSlowReg mem)); 12711 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12712 12713 effect(DEF dst, KILL cr, 12714 KILL x0, KILL x1, KILL x2, KILL x3, 12715 KILL x4, KILL x5, KILL x6, KILL x7, 12716 KILL x8, KILL x9, KILL x10, KILL x11, 12717 KILL x12, KILL x13, KILL x14, KILL x15); 12718 12719 format %{"LoadBarrierSlowRegXmm $dst, $mem" %} 12720 ins_encode %{ 12721 #if INCLUDE_ZGC 12722 Register d = $dst$$Register; 12723 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12724 12725 assert(d != r12, "Can't be R12!"); 12726 assert(d != r15, "Can't be R15!"); 12727 assert(d != rsp, "Can't be RSP!"); 12728 12729 __ lea(d, $mem$$Address); 12730 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12731 #else 12732 ShouldNotReachHere(); 12733 #endif 12734 %} 12735 ins_pipe(pipe_slow); 12736 %} 12737 12738 // For ZMM enabled processors 12739 instruct loadBarrierSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12740 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12741 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12742 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12743 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12744 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12745 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12746 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12747 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12748 12749 match(Set dst (LoadBarrierSlowReg mem)); 12750 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12751 12752 effect(DEF dst, KILL cr, 12753 KILL x0, KILL x1, KILL x2, KILL x3, 12754 KILL x4, KILL x5, KILL x6, KILL x7, 12755 KILL x8, KILL x9, KILL x10, KILL x11, 12756 KILL x12, KILL x13, KILL x14, KILL x15, 12757 KILL x16, KILL x17, KILL x18, KILL x19, 12758 KILL x20, KILL x21, KILL x22, KILL x23, 12759 KILL x24, KILL x25, KILL x26, KILL x27, 12760 KILL x28, KILL x29, KILL x30, KILL x31); 12761 12762 format %{"LoadBarrierSlowRegZmm $dst, $mem" %} 12763 ins_encode %{ 12764 #if INCLUDE_ZGC 12765 Register d = $dst$$Register; 12766 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12767 12768 assert(d != r12, "Can't be R12!"); 12769 assert(d != r15, "Can't be R15!"); 12770 assert(d != rsp, "Can't be RSP!"); 12771 12772 __ lea(d, $mem$$Address); 12773 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12774 #else 12775 ShouldNotReachHere(); 12776 #endif 12777 %} 12778 ins_pipe(pipe_slow); 12779 %} 12780 12781 // 12782 // Execute ZGC load barrier (weak) slow path 12783 // 12784 12785 // When running without XMM regs 12786 instruct loadBarrierWeakSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12787 12788 match(Set dst (LoadBarrierSlowReg mem)); 12789 predicate(MaxVectorSize < 16); 12790 12791 effect(DEF dst, KILL cr); 12792 12793 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12794 ins_encode %{ 12795 #if INCLUDE_ZGC 12796 Register d = $dst$$Register; 12797 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12798 12799 assert(d != r12, "Can't be R12!"); 12800 assert(d != r15, "Can't be R15!"); 12801 assert(d != rsp, "Can't be RSP!"); 12802 12803 __ lea(d, $mem$$Address); 12804 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12805 #else 12806 ShouldNotReachHere(); 12807 #endif 12808 %} 12809 ins_pipe(pipe_slow); 12810 %} 12811 12812 // For XMM and YMM enabled processors 12813 instruct loadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12814 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12815 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12816 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12817 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12818 12819 match(Set dst (LoadBarrierWeakSlowReg mem)); 12820 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12821 12822 effect(DEF dst, KILL cr, 12823 KILL x0, KILL x1, KILL x2, KILL x3, 12824 KILL x4, KILL x5, KILL x6, KILL x7, 12825 KILL x8, KILL x9, KILL x10, KILL x11, 12826 KILL x12, KILL x13, KILL x14, KILL x15); 12827 12828 format %{"LoadBarrierWeakSlowRegXmm $dst, $mem" %} 12829 ins_encode %{ 12830 #if INCLUDE_ZGC 12831 Register d = $dst$$Register; 12832 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12833 12834 assert(d != r12, "Can't be R12!"); 12835 assert(d != r15, "Can't be R15!"); 12836 assert(d != rsp, "Can't be RSP!"); 12837 12838 __ lea(d,$mem$$Address); 12839 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12840 #else 12841 ShouldNotReachHere(); 12842 #endif 12843 %} 12844 ins_pipe(pipe_slow); 12845 %} 12846 12847 // For ZMM enabled processors 12848 instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12849 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12850 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12851 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12852 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12853 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12854 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12855 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12856 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12857 12858 match(Set dst (LoadBarrierWeakSlowReg mem)); 12859 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12860 12861 effect(DEF dst, KILL cr, 12862 KILL x0, KILL x1, KILL x2, KILL x3, 12863 KILL x4, KILL x5, KILL x6, KILL x7, 12864 KILL x8, KILL x9, KILL x10, KILL x11, 12865 KILL x12, KILL x13, KILL x14, KILL x15, 12866 KILL x16, KILL x17, KILL x18, KILL x19, 12867 KILL x20, KILL x21, KILL x22, KILL x23, 12868 KILL x24, KILL x25, KILL x26, KILL x27, 12869 KILL x28, KILL x29, KILL x30, KILL x31); 12870 12871 format %{"LoadBarrierWeakSlowRegZmm $dst, $mem" %} 12872 ins_encode %{ 12873 #if INCLUDE_ZGC 12874 Register d = $dst$$Register; 12875 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12876 12877 assert(d != r12, "Can't be R12!"); 12878 assert(d != r15, "Can't be R15!"); 12879 assert(d != rsp, "Can't be RSP!"); 12880 12881 __ lea(d,$mem$$Address); 12882 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12883 #else 12884 ShouldNotReachHere(); 12885 #endif 12886 %} 12887 ins_pipe(pipe_slow); 12888 %} 12889 12890 // ============================================================================ 12891 // This name is KNOWN by the ADLC and cannot be changed. 12892 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12893 // for this guy. 12894 instruct tlsLoadP(r15_RegP dst) %{ 12895 match(Set dst (ThreadLocal)); 12896 effect(DEF dst); 12897 12898 size(0); 12899 format %{ "# TLS is in R15" %} 12900 ins_encode( /*empty encoding*/ ); 12901 ins_pipe(ialu_reg_reg); 12902 %} 12903 12904 12905 //----------PEEPHOLE RULES----------------------------------------------------- 12906 // These must follow all instruction definitions as they use the names 12907 // defined in the instructions definitions. 12908 // 12909 // peepmatch ( root_instr_name [preceding_instruction]* ); 12910 // 12911 // peepconstraint %{ 12912 // (instruction_number.operand_name relational_op instruction_number.operand_name 12913 // [, ...] ); 12914 // // instruction numbers are zero-based using left to right order in peepmatch 12915 // 12916 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12917 // // provide an instruction_number.operand_name for each operand that appears 12918 // // in the replacement instruction's match rule 12919 // 12920 // ---------VM FLAGS--------------------------------------------------------- 12921 // 12922 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12923 // 12924 // Each peephole rule is given an identifying number starting with zero and 12925 // increasing by one in the order seen by the parser. An individual peephole 12926 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12927 // on the command-line. 12928 // 12929 // ---------CURRENT LIMITATIONS---------------------------------------------- 12930 // 12931 // Only match adjacent instructions in same basic block 12932 // Only equality constraints 12933 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12934 // Only one replacement instruction 12935 // 12936 // ---------EXAMPLE---------------------------------------------------------- 12937 // 12938 // // pertinent parts of existing instructions in architecture description 12939 // instruct movI(rRegI dst, rRegI src) 12940 // %{ 12941 // match(Set dst (CopyI src)); 12942 // %} 12943 // 12944 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12945 // %{ 12946 // match(Set dst (AddI dst src)); 12947 // effect(KILL cr); 12948 // %} 12949 // 12950 // // Change (inc mov) to lea 12951 // peephole %{ 12952 // // increment preceeded by register-register move 12953 // peepmatch ( incI_rReg movI ); 12954 // // require that the destination register of the increment 12955 // // match the destination register of the move 12956 // peepconstraint ( 0.dst == 1.dst ); 12957 // // construct a replacement instruction that sets 12958 // // the destination to ( move's source register + one ) 12959 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12960 // %} 12961 // 12962 12963 // Implementation no longer uses movX instructions since 12964 // machine-independent system no longer uses CopyX nodes. 12965 // 12966 // peephole 12967 // %{ 12968 // peepmatch (incI_rReg movI); 12969 // peepconstraint (0.dst == 1.dst); 12970 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12971 // %} 12972 12973 // peephole 12974 // %{ 12975 // peepmatch (decI_rReg movI); 12976 // peepconstraint (0.dst == 1.dst); 12977 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12978 // %} 12979 12980 // peephole 12981 // %{ 12982 // peepmatch (addI_rReg_imm movI); 12983 // peepconstraint (0.dst == 1.dst); 12984 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12985 // %} 12986 12987 // peephole 12988 // %{ 12989 // peepmatch (incL_rReg movL); 12990 // peepconstraint (0.dst == 1.dst); 12991 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12992 // %} 12993 12994 // peephole 12995 // %{ 12996 // peepmatch (decL_rReg movL); 12997 // peepconstraint (0.dst == 1.dst); 12998 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12999 // %} 13000 13001 // peephole 13002 // %{ 13003 // peepmatch (addL_rReg_imm movL); 13004 // peepconstraint (0.dst == 1.dst); 13005 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13006 // %} 13007 13008 // peephole 13009 // %{ 13010 // peepmatch (addP_rReg_imm movP); 13011 // peepconstraint (0.dst == 1.dst); 13012 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 13013 // %} 13014 13015 // // Change load of spilled value to only a spill 13016 // instruct storeI(memory mem, rRegI src) 13017 // %{ 13018 // match(Set mem (StoreI mem src)); 13019 // %} 13020 // 13021 // instruct loadI(rRegI dst, memory mem) 13022 // %{ 13023 // match(Set dst (LoadI mem)); 13024 // %} 13025 // 13026 13027 peephole 13028 %{ 13029 peepmatch (loadI storeI); 13030 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13031 peepreplace (storeI(1.mem 1.mem 1.src)); 13032 %} 13033 13034 peephole 13035 %{ 13036 peepmatch (loadL storeL); 13037 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13038 peepreplace (storeL(1.mem 1.mem 1.src)); 13039 %} 13040 13041 //----------SMARTSPILL RULES--------------------------------------------------- 13042 // These must follow all instruction definitions as they use the names 13043 // defined in the instructions definitions.