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 // Convert oop pointer into compressed form 6668 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6669 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6670 match(Set dst (EncodeP src)); 6671 effect(KILL cr); 6672 format %{ "encode_heap_oop $dst,$src" %} 6673 ins_encode %{ 6674 Register s = $src$$Register; 6675 Register d = $dst$$Register; 6676 if (s != d) { 6677 __ movq(d, s); 6678 } 6679 __ encode_heap_oop(d); 6680 %} 6681 ins_pipe(ialu_reg_long); 6682 %} 6683 6684 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6685 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6686 match(Set dst (EncodeP src)); 6687 effect(KILL cr); 6688 format %{ "encode_heap_oop_not_null $dst,$src" %} 6689 ins_encode %{ 6690 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6691 %} 6692 ins_pipe(ialu_reg_long); 6693 %} 6694 6695 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6696 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6697 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6698 match(Set dst (DecodeN src)); 6699 effect(KILL cr); 6700 format %{ "decode_heap_oop $dst,$src" %} 6701 ins_encode %{ 6702 Register s = $src$$Register; 6703 Register d = $dst$$Register; 6704 if (s != d) { 6705 __ movq(d, s); 6706 } 6707 __ decode_heap_oop(d); 6708 %} 6709 ins_pipe(ialu_reg_long); 6710 %} 6711 6712 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6713 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6714 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6715 match(Set dst (DecodeN src)); 6716 effect(KILL cr); 6717 format %{ "decode_heap_oop_not_null $dst,$src" %} 6718 ins_encode %{ 6719 Register s = $src$$Register; 6720 Register d = $dst$$Register; 6721 if (s != d) { 6722 __ decode_heap_oop_not_null(d, s); 6723 } else { 6724 __ decode_heap_oop_not_null(d); 6725 } 6726 %} 6727 ins_pipe(ialu_reg_long); 6728 %} 6729 6730 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6731 match(Set dst (EncodePKlass src)); 6732 effect(KILL cr); 6733 format %{ "encode_klass_not_null $dst,$src" %} 6734 ins_encode %{ 6735 __ encode_klass_not_null($dst$$Register, $src$$Register); 6736 %} 6737 ins_pipe(ialu_reg_long); 6738 %} 6739 6740 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6741 match(Set dst (DecodeNKlass src)); 6742 effect(KILL cr); 6743 format %{ "decode_klass_not_null $dst,$src" %} 6744 ins_encode %{ 6745 Register s = $src$$Register; 6746 Register d = $dst$$Register; 6747 if (s != d) { 6748 __ decode_klass_not_null(d, s); 6749 } else { 6750 __ decode_klass_not_null(d); 6751 } 6752 %} 6753 ins_pipe(ialu_reg_long); 6754 %} 6755 6756 6757 //----------Conditional Move--------------------------------------------------- 6758 // Jump 6759 // dummy instruction for generating temp registers 6760 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6761 match(Jump (LShiftL switch_val shift)); 6762 ins_cost(350); 6763 predicate(false); 6764 effect(TEMP dest); 6765 6766 format %{ "leaq $dest, [$constantaddress]\n\t" 6767 "jmp [$dest + $switch_val << $shift]\n\t" %} 6768 ins_encode %{ 6769 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6770 // to do that and the compiler is using that register as one it can allocate. 6771 // So we build it all by hand. 6772 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6773 // ArrayAddress dispatch(table, index); 6774 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6775 __ lea($dest$$Register, $constantaddress); 6776 __ jmp(dispatch); 6777 %} 6778 ins_pipe(pipe_jmp); 6779 %} 6780 6781 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6782 match(Jump (AddL (LShiftL switch_val shift) offset)); 6783 ins_cost(350); 6784 effect(TEMP dest); 6785 6786 format %{ "leaq $dest, [$constantaddress]\n\t" 6787 "jmp [$dest + $switch_val << $shift + $offset]\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, (int) $offset$$constant); 6793 // ArrayAddress dispatch(table, index); 6794 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6795 __ lea($dest$$Register, $constantaddress); 6796 __ jmp(dispatch); 6797 %} 6798 ins_pipe(pipe_jmp); 6799 %} 6800 6801 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6802 match(Jump switch_val); 6803 ins_cost(350); 6804 effect(TEMP dest); 6805 6806 format %{ "leaq $dest, [$constantaddress]\n\t" 6807 "jmp [$dest + $switch_val]\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::times_1); 6813 // ArrayAddress dispatch(table, index); 6814 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6815 __ lea($dest$$Register, $constantaddress); 6816 __ jmp(dispatch); 6817 %} 6818 ins_pipe(pipe_jmp); 6819 %} 6820 6821 // Conditional move 6822 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6823 %{ 6824 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6825 6826 ins_cost(200); // XXX 6827 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6828 opcode(0x0F, 0x40); 6829 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6830 ins_pipe(pipe_cmov_reg); 6831 %} 6832 6833 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6834 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6835 6836 ins_cost(200); // XXX 6837 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6838 opcode(0x0F, 0x40); 6839 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6840 ins_pipe(pipe_cmov_reg); 6841 %} 6842 6843 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6844 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6845 ins_cost(200); 6846 expand %{ 6847 cmovI_regU(cop, cr, dst, src); 6848 %} 6849 %} 6850 6851 // Conditional move 6852 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6853 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6854 6855 ins_cost(250); // XXX 6856 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6857 opcode(0x0F, 0x40); 6858 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6859 ins_pipe(pipe_cmov_mem); 6860 %} 6861 6862 // Conditional move 6863 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6864 %{ 6865 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6866 6867 ins_cost(250); // XXX 6868 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6869 opcode(0x0F, 0x40); 6870 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6871 ins_pipe(pipe_cmov_mem); 6872 %} 6873 6874 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6875 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6876 ins_cost(250); 6877 expand %{ 6878 cmovI_memU(cop, cr, dst, src); 6879 %} 6880 %} 6881 6882 // Conditional move 6883 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6884 %{ 6885 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6886 6887 ins_cost(200); // XXX 6888 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6889 opcode(0x0F, 0x40); 6890 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6891 ins_pipe(pipe_cmov_reg); 6892 %} 6893 6894 // Conditional move 6895 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6896 %{ 6897 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6898 6899 ins_cost(200); // XXX 6900 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6901 opcode(0x0F, 0x40); 6902 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6903 ins_pipe(pipe_cmov_reg); 6904 %} 6905 6906 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6907 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6908 ins_cost(200); 6909 expand %{ 6910 cmovN_regU(cop, cr, dst, src); 6911 %} 6912 %} 6913 6914 // Conditional move 6915 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6916 %{ 6917 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6918 6919 ins_cost(200); // XXX 6920 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6921 opcode(0x0F, 0x40); 6922 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6923 ins_pipe(pipe_cmov_reg); // XXX 6924 %} 6925 6926 // Conditional move 6927 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6928 %{ 6929 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6930 6931 ins_cost(200); // XXX 6932 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6933 opcode(0x0F, 0x40); 6934 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6935 ins_pipe(pipe_cmov_reg); // XXX 6936 %} 6937 6938 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6939 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6940 ins_cost(200); 6941 expand %{ 6942 cmovP_regU(cop, cr, dst, src); 6943 %} 6944 %} 6945 6946 // DISABLED: Requires the ADLC to emit a bottom_type call that 6947 // correctly meets the two pointer arguments; one is an incoming 6948 // register but the other is a memory operand. ALSO appears to 6949 // be buggy with implicit null checks. 6950 // 6951 //// Conditional move 6952 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6953 //%{ 6954 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6955 // ins_cost(250); 6956 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6957 // opcode(0x0F,0x40); 6958 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6959 // ins_pipe( pipe_cmov_mem ); 6960 //%} 6961 // 6962 //// Conditional move 6963 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6964 //%{ 6965 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6966 // ins_cost(250); 6967 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6968 // opcode(0x0F,0x40); 6969 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6970 // ins_pipe( pipe_cmov_mem ); 6971 //%} 6972 6973 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6974 %{ 6975 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6976 6977 ins_cost(200); // XXX 6978 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6979 opcode(0x0F, 0x40); 6980 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6981 ins_pipe(pipe_cmov_reg); // XXX 6982 %} 6983 6984 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6985 %{ 6986 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6987 6988 ins_cost(200); // XXX 6989 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6990 opcode(0x0F, 0x40); 6991 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6992 ins_pipe(pipe_cmov_mem); // XXX 6993 %} 6994 6995 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6996 %{ 6997 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6998 6999 ins_cost(200); // XXX 7000 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7001 opcode(0x0F, 0x40); 7002 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7003 ins_pipe(pipe_cmov_reg); // XXX 7004 %} 7005 7006 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7007 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7008 ins_cost(200); 7009 expand %{ 7010 cmovL_regU(cop, cr, dst, src); 7011 %} 7012 %} 7013 7014 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7015 %{ 7016 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7017 7018 ins_cost(200); // XXX 7019 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7020 opcode(0x0F, 0x40); 7021 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7022 ins_pipe(pipe_cmov_mem); // XXX 7023 %} 7024 7025 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7026 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7027 ins_cost(200); 7028 expand %{ 7029 cmovL_memU(cop, cr, dst, src); 7030 %} 7031 %} 7032 7033 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7034 %{ 7035 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7036 7037 ins_cost(200); // XXX 7038 format %{ "jn$cop skip\t# signed cmove float\n\t" 7039 "movss $dst, $src\n" 7040 "skip:" %} 7041 ins_encode %{ 7042 Label Lskip; 7043 // Invert sense of branch from sense of CMOV 7044 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7045 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7046 __ bind(Lskip); 7047 %} 7048 ins_pipe(pipe_slow); 7049 %} 7050 7051 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7052 // %{ 7053 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7054 7055 // ins_cost(200); // XXX 7056 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7057 // "movss $dst, $src\n" 7058 // "skip:" %} 7059 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7060 // ins_pipe(pipe_slow); 7061 // %} 7062 7063 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7064 %{ 7065 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7066 7067 ins_cost(200); // XXX 7068 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7069 "movss $dst, $src\n" 7070 "skip:" %} 7071 ins_encode %{ 7072 Label Lskip; 7073 // Invert sense of branch from sense of CMOV 7074 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7075 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7076 __ bind(Lskip); 7077 %} 7078 ins_pipe(pipe_slow); 7079 %} 7080 7081 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7082 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7083 ins_cost(200); 7084 expand %{ 7085 cmovF_regU(cop, cr, dst, src); 7086 %} 7087 %} 7088 7089 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7090 %{ 7091 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7092 7093 ins_cost(200); // XXX 7094 format %{ "jn$cop skip\t# signed cmove double\n\t" 7095 "movsd $dst, $src\n" 7096 "skip:" %} 7097 ins_encode %{ 7098 Label Lskip; 7099 // Invert sense of branch from sense of CMOV 7100 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7101 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7102 __ bind(Lskip); 7103 %} 7104 ins_pipe(pipe_slow); 7105 %} 7106 7107 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7108 %{ 7109 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7110 7111 ins_cost(200); // XXX 7112 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7113 "movsd $dst, $src\n" 7114 "skip:" %} 7115 ins_encode %{ 7116 Label Lskip; 7117 // Invert sense of branch from sense of CMOV 7118 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7119 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7120 __ bind(Lskip); 7121 %} 7122 ins_pipe(pipe_slow); 7123 %} 7124 7125 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7126 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7127 ins_cost(200); 7128 expand %{ 7129 cmovD_regU(cop, cr, dst, src); 7130 %} 7131 %} 7132 7133 //----------Arithmetic Instructions-------------------------------------------- 7134 //----------Addition Instructions---------------------------------------------- 7135 7136 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7137 %{ 7138 match(Set dst (AddI dst src)); 7139 effect(KILL cr); 7140 7141 format %{ "addl $dst, $src\t# int" %} 7142 opcode(0x03); 7143 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7144 ins_pipe(ialu_reg_reg); 7145 %} 7146 7147 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7148 %{ 7149 match(Set dst (AddI dst src)); 7150 effect(KILL cr); 7151 7152 format %{ "addl $dst, $src\t# int" %} 7153 opcode(0x81, 0x00); /* /0 id */ 7154 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7155 ins_pipe( ialu_reg ); 7156 %} 7157 7158 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7159 %{ 7160 match(Set dst (AddI dst (LoadI src))); 7161 effect(KILL cr); 7162 7163 ins_cost(125); // XXX 7164 format %{ "addl $dst, $src\t# int" %} 7165 opcode(0x03); 7166 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7167 ins_pipe(ialu_reg_mem); 7168 %} 7169 7170 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7171 %{ 7172 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7173 effect(KILL cr); 7174 7175 ins_cost(150); // XXX 7176 format %{ "addl $dst, $src\t# int" %} 7177 opcode(0x01); /* Opcode 01 /r */ 7178 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7179 ins_pipe(ialu_mem_reg); 7180 %} 7181 7182 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7183 %{ 7184 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7185 effect(KILL cr); 7186 7187 ins_cost(125); // XXX 7188 format %{ "addl $dst, $src\t# int" %} 7189 opcode(0x81); /* Opcode 81 /0 id */ 7190 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7191 ins_pipe(ialu_mem_imm); 7192 %} 7193 7194 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7195 %{ 7196 predicate(UseIncDec); 7197 match(Set dst (AddI dst src)); 7198 effect(KILL cr); 7199 7200 format %{ "incl $dst\t# int" %} 7201 opcode(0xFF, 0x00); // FF /0 7202 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7203 ins_pipe(ialu_reg); 7204 %} 7205 7206 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7207 %{ 7208 predicate(UseIncDec); 7209 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7210 effect(KILL cr); 7211 7212 ins_cost(125); // XXX 7213 format %{ "incl $dst\t# int" %} 7214 opcode(0xFF); /* Opcode FF /0 */ 7215 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7216 ins_pipe(ialu_mem_imm); 7217 %} 7218 7219 // XXX why does that use AddI 7220 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7221 %{ 7222 predicate(UseIncDec); 7223 match(Set dst (AddI dst src)); 7224 effect(KILL cr); 7225 7226 format %{ "decl $dst\t# int" %} 7227 opcode(0xFF, 0x01); // FF /1 7228 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7229 ins_pipe(ialu_reg); 7230 %} 7231 7232 // XXX why does that use AddI 7233 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7234 %{ 7235 predicate(UseIncDec); 7236 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7237 effect(KILL cr); 7238 7239 ins_cost(125); // XXX 7240 format %{ "decl $dst\t# int" %} 7241 opcode(0xFF); /* Opcode FF /1 */ 7242 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7243 ins_pipe(ialu_mem_imm); 7244 %} 7245 7246 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7247 %{ 7248 match(Set dst (AddI src0 src1)); 7249 7250 ins_cost(110); 7251 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7252 opcode(0x8D); /* 0x8D /r */ 7253 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7254 ins_pipe(ialu_reg_reg); 7255 %} 7256 7257 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7258 %{ 7259 match(Set dst (AddL dst src)); 7260 effect(KILL cr); 7261 7262 format %{ "addq $dst, $src\t# long" %} 7263 opcode(0x03); 7264 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7265 ins_pipe(ialu_reg_reg); 7266 %} 7267 7268 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7269 %{ 7270 match(Set dst (AddL dst src)); 7271 effect(KILL cr); 7272 7273 format %{ "addq $dst, $src\t# long" %} 7274 opcode(0x81, 0x00); /* /0 id */ 7275 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7276 ins_pipe( ialu_reg ); 7277 %} 7278 7279 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7280 %{ 7281 match(Set dst (AddL dst (LoadL src))); 7282 effect(KILL cr); 7283 7284 ins_cost(125); // XXX 7285 format %{ "addq $dst, $src\t# long" %} 7286 opcode(0x03); 7287 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7288 ins_pipe(ialu_reg_mem); 7289 %} 7290 7291 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7292 %{ 7293 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7294 effect(KILL cr); 7295 7296 ins_cost(150); // XXX 7297 format %{ "addq $dst, $src\t# long" %} 7298 opcode(0x01); /* Opcode 01 /r */ 7299 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7300 ins_pipe(ialu_mem_reg); 7301 %} 7302 7303 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7304 %{ 7305 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7306 effect(KILL cr); 7307 7308 ins_cost(125); // XXX 7309 format %{ "addq $dst, $src\t# long" %} 7310 opcode(0x81); /* Opcode 81 /0 id */ 7311 ins_encode(REX_mem_wide(dst), 7312 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7313 ins_pipe(ialu_mem_imm); 7314 %} 7315 7316 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7317 %{ 7318 predicate(UseIncDec); 7319 match(Set dst (AddL dst src)); 7320 effect(KILL cr); 7321 7322 format %{ "incq $dst\t# long" %} 7323 opcode(0xFF, 0x00); // FF /0 7324 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7325 ins_pipe(ialu_reg); 7326 %} 7327 7328 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7329 %{ 7330 predicate(UseIncDec); 7331 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7332 effect(KILL cr); 7333 7334 ins_cost(125); // XXX 7335 format %{ "incq $dst\t# long" %} 7336 opcode(0xFF); /* Opcode FF /0 */ 7337 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7338 ins_pipe(ialu_mem_imm); 7339 %} 7340 7341 // XXX why does that use AddL 7342 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7343 %{ 7344 predicate(UseIncDec); 7345 match(Set dst (AddL dst src)); 7346 effect(KILL cr); 7347 7348 format %{ "decq $dst\t# long" %} 7349 opcode(0xFF, 0x01); // FF /1 7350 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7351 ins_pipe(ialu_reg); 7352 %} 7353 7354 // XXX why does that use AddL 7355 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7356 %{ 7357 predicate(UseIncDec); 7358 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7359 effect(KILL cr); 7360 7361 ins_cost(125); // XXX 7362 format %{ "decq $dst\t# long" %} 7363 opcode(0xFF); /* Opcode FF /1 */ 7364 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7365 ins_pipe(ialu_mem_imm); 7366 %} 7367 7368 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7369 %{ 7370 match(Set dst (AddL src0 src1)); 7371 7372 ins_cost(110); 7373 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7374 opcode(0x8D); /* 0x8D /r */ 7375 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7376 ins_pipe(ialu_reg_reg); 7377 %} 7378 7379 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7380 %{ 7381 match(Set dst (AddP dst src)); 7382 effect(KILL cr); 7383 7384 format %{ "addq $dst, $src\t# ptr" %} 7385 opcode(0x03); 7386 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7387 ins_pipe(ialu_reg_reg); 7388 %} 7389 7390 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7391 %{ 7392 match(Set dst (AddP dst src)); 7393 effect(KILL cr); 7394 7395 format %{ "addq $dst, $src\t# ptr" %} 7396 opcode(0x81, 0x00); /* /0 id */ 7397 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7398 ins_pipe( ialu_reg ); 7399 %} 7400 7401 // XXX addP mem ops ???? 7402 7403 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7404 %{ 7405 match(Set dst (AddP src0 src1)); 7406 7407 ins_cost(110); 7408 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7409 opcode(0x8D); /* 0x8D /r */ 7410 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7411 ins_pipe(ialu_reg_reg); 7412 %} 7413 7414 instruct checkCastPP(rRegP dst) 7415 %{ 7416 match(Set dst (CheckCastPP dst)); 7417 7418 size(0); 7419 format %{ "# checkcastPP of $dst" %} 7420 ins_encode(/* empty encoding */); 7421 ins_pipe(empty); 7422 %} 7423 7424 instruct castPP(rRegP dst) 7425 %{ 7426 match(Set dst (CastPP dst)); 7427 7428 size(0); 7429 format %{ "# castPP of $dst" %} 7430 ins_encode(/* empty encoding */); 7431 ins_pipe(empty); 7432 %} 7433 7434 instruct castII(rRegI dst) 7435 %{ 7436 match(Set dst (CastII dst)); 7437 7438 size(0); 7439 format %{ "# castII of $dst" %} 7440 ins_encode(/* empty encoding */); 7441 ins_cost(0); 7442 ins_pipe(empty); 7443 %} 7444 7445 // LoadP-locked same as a regular LoadP when used with compare-swap 7446 instruct loadPLocked(rRegP dst, memory mem) 7447 %{ 7448 match(Set dst (LoadPLocked mem)); 7449 7450 ins_cost(125); // XXX 7451 format %{ "movq $dst, $mem\t# ptr locked" %} 7452 opcode(0x8B); 7453 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7454 ins_pipe(ialu_reg_mem); // XXX 7455 %} 7456 7457 // Conditional-store of the updated heap-top. 7458 // Used during allocation of the shared heap. 7459 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7460 7461 instruct storePConditional(memory heap_top_ptr, 7462 rax_RegP oldval, rRegP newval, 7463 rFlagsReg cr) 7464 %{ 7465 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7466 7467 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7468 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7469 opcode(0x0F, 0xB1); 7470 ins_encode(lock_prefix, 7471 REX_reg_mem_wide(newval, heap_top_ptr), 7472 OpcP, OpcS, 7473 reg_mem(newval, heap_top_ptr)); 7474 ins_pipe(pipe_cmpxchg); 7475 %} 7476 7477 // Conditional-store of an int value. 7478 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7479 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7480 %{ 7481 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7482 effect(KILL oldval); 7483 7484 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7485 opcode(0x0F, 0xB1); 7486 ins_encode(lock_prefix, 7487 REX_reg_mem(newval, mem), 7488 OpcP, OpcS, 7489 reg_mem(newval, mem)); 7490 ins_pipe(pipe_cmpxchg); 7491 %} 7492 7493 // Conditional-store of a long value. 7494 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7495 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7496 %{ 7497 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7498 effect(KILL oldval); 7499 7500 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7501 opcode(0x0F, 0xB1); 7502 ins_encode(lock_prefix, 7503 REX_reg_mem_wide(newval, mem), 7504 OpcP, OpcS, 7505 reg_mem(newval, mem)); 7506 ins_pipe(pipe_cmpxchg); 7507 %} 7508 7509 7510 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7511 instruct compareAndSwapP(rRegI res, 7512 memory mem_ptr, 7513 rax_RegP oldval, rRegP newval, 7514 rFlagsReg cr) 7515 %{ 7516 predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); 7517 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7518 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7519 effect(KILL cr, KILL oldval); 7520 7521 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7522 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7523 "sete $res\n\t" 7524 "movzbl $res, $res" %} 7525 opcode(0x0F, 0xB1); 7526 ins_encode(lock_prefix, 7527 REX_reg_mem_wide(newval, mem_ptr), 7528 OpcP, OpcS, 7529 reg_mem(newval, mem_ptr), 7530 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7531 REX_reg_breg(res, res), // movzbl 7532 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7533 ins_pipe( pipe_cmpxchg ); 7534 %} 7535 7536 instruct compareAndSwapP_shenandoah(rRegI res, 7537 memory mem_ptr, 7538 rRegP tmp1, rRegP tmp2, 7539 rax_RegP oldval, rRegP newval, 7540 rFlagsReg cr) 7541 %{ 7542 predicate(VM_Version::supports_cx8() && UseShenandoahGC); 7543 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7544 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7545 effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 7546 7547 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7548 7549 ins_encode %{ 7550 __ cmpxchg_oop($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7551 false, // swap 7552 false, $tmp1$$Register, $tmp2$$Register 7553 ); 7554 %} 7555 ins_pipe( pipe_cmpxchg ); 7556 %} 7557 7558 instruct compareAndSwapL(rRegI res, 7559 memory mem_ptr, 7560 rax_RegL oldval, rRegL newval, 7561 rFlagsReg cr) 7562 %{ 7563 predicate(VM_Version::supports_cx8()); 7564 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7565 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7566 effect(KILL cr, KILL oldval); 7567 7568 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7569 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7570 "sete $res\n\t" 7571 "movzbl $res, $res" %} 7572 opcode(0x0F, 0xB1); 7573 ins_encode(lock_prefix, 7574 REX_reg_mem_wide(newval, mem_ptr), 7575 OpcP, OpcS, 7576 reg_mem(newval, mem_ptr), 7577 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7578 REX_reg_breg(res, res), // movzbl 7579 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7580 ins_pipe( pipe_cmpxchg ); 7581 %} 7582 7583 instruct compareAndSwapI(rRegI res, 7584 memory mem_ptr, 7585 rax_RegI oldval, rRegI newval, 7586 rFlagsReg cr) 7587 %{ 7588 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7589 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7590 effect(KILL cr, KILL oldval); 7591 7592 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7593 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7594 "sete $res\n\t" 7595 "movzbl $res, $res" %} 7596 opcode(0x0F, 0xB1); 7597 ins_encode(lock_prefix, 7598 REX_reg_mem(newval, mem_ptr), 7599 OpcP, OpcS, 7600 reg_mem(newval, mem_ptr), 7601 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7602 REX_reg_breg(res, res), // movzbl 7603 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7604 ins_pipe( pipe_cmpxchg ); 7605 %} 7606 7607 instruct compareAndSwapB(rRegI res, 7608 memory mem_ptr, 7609 rax_RegI oldval, rRegI newval, 7610 rFlagsReg cr) 7611 %{ 7612 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7613 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7614 effect(KILL cr, KILL oldval); 7615 7616 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7617 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7618 "sete $res\n\t" 7619 "movzbl $res, $res" %} 7620 opcode(0x0F, 0xB0); 7621 ins_encode(lock_prefix, 7622 REX_breg_mem(newval, mem_ptr), 7623 OpcP, OpcS, 7624 reg_mem(newval, mem_ptr), 7625 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7626 REX_reg_breg(res, res), // movzbl 7627 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7628 ins_pipe( pipe_cmpxchg ); 7629 %} 7630 7631 instruct compareAndSwapS(rRegI res, 7632 memory mem_ptr, 7633 rax_RegI oldval, rRegI newval, 7634 rFlagsReg cr) 7635 %{ 7636 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7637 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7638 effect(KILL cr, KILL oldval); 7639 7640 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7641 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7642 "sete $res\n\t" 7643 "movzbl $res, $res" %} 7644 opcode(0x0F, 0xB1); 7645 ins_encode(lock_prefix, 7646 SizePrefix, 7647 REX_reg_mem(newval, mem_ptr), 7648 OpcP, OpcS, 7649 reg_mem(newval, mem_ptr), 7650 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7651 REX_reg_breg(res, res), // movzbl 7652 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7653 ins_pipe( pipe_cmpxchg ); 7654 %} 7655 7656 instruct compareAndSwapN(rRegI res, 7657 memory mem_ptr, 7658 rax_RegN oldval, rRegN newval, 7659 rFlagsReg cr) %{ 7660 predicate(!UseShenandoahGC); 7661 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7662 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7663 effect(KILL cr, KILL oldval); 7664 7665 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7666 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7667 "sete $res\n\t" 7668 "movzbl $res, $res" %} 7669 opcode(0x0F, 0xB1); 7670 ins_encode(lock_prefix, 7671 REX_reg_mem(newval, mem_ptr), 7672 OpcP, OpcS, 7673 reg_mem(newval, mem_ptr), 7674 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7675 REX_reg_breg(res, res), // movzbl 7676 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7677 ins_pipe( pipe_cmpxchg ); 7678 %} 7679 7680 instruct compareAndSwapN_shenandoah(rRegI res, 7681 memory mem_ptr, 7682 rRegP tmp1, rRegP tmp2, 7683 rax_RegN oldval, rRegN newval, 7684 rFlagsReg cr) %{ 7685 predicate(UseShenandoahGC); 7686 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7687 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7688 effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 7689 7690 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7691 7692 ins_encode %{ 7693 __ cmpxchg_oop($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7694 false, // swap 7695 false, $tmp1$$Register, $tmp2$$Register 7696 ); 7697 %} 7698 ins_pipe( pipe_cmpxchg ); 7699 %} 7700 7701 instruct compareAndExchangeB( 7702 memory mem_ptr, 7703 rax_RegI oldval, rRegI newval, 7704 rFlagsReg cr) 7705 %{ 7706 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7707 effect(KILL cr); 7708 7709 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7710 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7711 opcode(0x0F, 0xB0); 7712 ins_encode(lock_prefix, 7713 REX_breg_mem(newval, mem_ptr), 7714 OpcP, OpcS, 7715 reg_mem(newval, mem_ptr) // lock cmpxchg 7716 ); 7717 ins_pipe( pipe_cmpxchg ); 7718 %} 7719 7720 instruct compareAndExchangeS( 7721 memory mem_ptr, 7722 rax_RegI oldval, rRegI newval, 7723 rFlagsReg cr) 7724 %{ 7725 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7726 effect(KILL cr); 7727 7728 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7729 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7730 opcode(0x0F, 0xB1); 7731 ins_encode(lock_prefix, 7732 SizePrefix, 7733 REX_reg_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 compareAndExchangeI( 7741 memory mem_ptr, 7742 rax_RegI oldval, rRegI newval, 7743 rFlagsReg cr) 7744 %{ 7745 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7746 effect(KILL cr); 7747 7748 format %{ "cmpxchgl $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 REX_reg_mem(newval, mem_ptr), 7753 OpcP, OpcS, 7754 reg_mem(newval, mem_ptr) // lock cmpxchg 7755 ); 7756 ins_pipe( pipe_cmpxchg ); 7757 %} 7758 7759 instruct compareAndExchangeL( 7760 memory mem_ptr, 7761 rax_RegL oldval, rRegL newval, 7762 rFlagsReg cr) 7763 %{ 7764 predicate(VM_Version::supports_cx8()); 7765 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7766 effect(KILL cr); 7767 7768 format %{ "cmpxchgq $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_wide(newval, mem_ptr), 7773 OpcP, OpcS, 7774 reg_mem(newval, mem_ptr) // lock cmpxchg 7775 ); 7776 ins_pipe( pipe_cmpxchg ); 7777 %} 7778 7779 instruct compareAndExchangeN( 7780 memory mem_ptr, 7781 rax_RegN oldval, rRegN newval, 7782 rFlagsReg cr) %{ 7783 predicate(!UseShenandoahGC); 7784 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7785 effect(KILL cr); 7786 7787 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7788 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7789 opcode(0x0F, 0xB1); 7790 ins_encode(lock_prefix, 7791 REX_reg_mem(newval, mem_ptr), 7792 OpcP, OpcS, 7793 reg_mem(newval, mem_ptr) // lock cmpxchg 7794 ); 7795 ins_pipe( pipe_cmpxchg ); 7796 %} 7797 7798 instruct compareAndExchangeN_shenandoah(memory mem_ptr, 7799 rax_RegN oldval, rRegN newval, 7800 rRegP tmp1, rRegP tmp2, 7801 rFlagsReg cr) %{ 7802 predicate(UseShenandoahGC); 7803 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7804 effect(TEMP tmp1, TEMP tmp2, KILL cr); 7805 7806 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7807 7808 ins_encode %{ 7809 __ cmpxchg_oop(NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7810 true, // exchange 7811 false, $tmp1$$Register, $tmp2$$Register 7812 ); 7813 %} 7814 ins_pipe( pipe_cmpxchg ); 7815 %} 7816 7817 instruct compareAndExchangeP( 7818 memory mem_ptr, 7819 rax_RegP oldval, rRegP newval, 7820 rFlagsReg cr) 7821 %{ 7822 predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); 7823 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7824 effect(KILL cr); 7825 7826 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7827 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7828 opcode(0x0F, 0xB1); 7829 ins_encode(lock_prefix, 7830 REX_reg_mem_wide(newval, mem_ptr), 7831 OpcP, OpcS, 7832 reg_mem(newval, mem_ptr) // lock cmpxchg 7833 ); 7834 ins_pipe( pipe_cmpxchg ); 7835 %} 7836 7837 instruct compareAndExchangeP_shenandoah(memory mem_ptr, 7838 rax_RegP oldval, rRegP newval, 7839 rRegP tmp1, rRegP tmp2, 7840 rFlagsReg cr) 7841 %{ 7842 predicate(VM_Version::supports_cx8() && UseShenandoahGC); 7843 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7844 effect(KILL cr, TEMP tmp1, TEMP tmp2); 7845 ins_cost(1000); 7846 7847 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7848 7849 ins_encode %{ 7850 __ cmpxchg_oop(NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7851 true, // exchange 7852 false, $tmp1$$Register, $tmp2$$Register 7853 ); 7854 %} 7855 ins_pipe( pipe_cmpxchg ); 7856 %} 7857 7858 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7859 predicate(n->as_LoadStore()->result_not_used()); 7860 match(Set dummy (GetAndAddB mem add)); 7861 effect(KILL cr); 7862 format %{ "ADDB [$mem],$add" %} 7863 ins_encode %{ 7864 if (os::is_MP()) { __ lock(); } 7865 __ addb($mem$$Address, $add$$constant); 7866 %} 7867 ins_pipe( pipe_cmpxchg ); 7868 %} 7869 7870 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7871 match(Set newval (GetAndAddB mem newval)); 7872 effect(KILL cr); 7873 format %{ "XADDB [$mem],$newval" %} 7874 ins_encode %{ 7875 if (os::is_MP()) { __ lock(); } 7876 __ xaddb($mem$$Address, $newval$$Register); 7877 %} 7878 ins_pipe( pipe_cmpxchg ); 7879 %} 7880 7881 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7882 predicate(n->as_LoadStore()->result_not_used()); 7883 match(Set dummy (GetAndAddS mem add)); 7884 effect(KILL cr); 7885 format %{ "ADDW [$mem],$add" %} 7886 ins_encode %{ 7887 if (os::is_MP()) { __ lock(); } 7888 __ addw($mem$$Address, $add$$constant); 7889 %} 7890 ins_pipe( pipe_cmpxchg ); 7891 %} 7892 7893 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7894 match(Set newval (GetAndAddS mem newval)); 7895 effect(KILL cr); 7896 format %{ "XADDW [$mem],$newval" %} 7897 ins_encode %{ 7898 if (os::is_MP()) { __ lock(); } 7899 __ xaddw($mem$$Address, $newval$$Register); 7900 %} 7901 ins_pipe( pipe_cmpxchg ); 7902 %} 7903 7904 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7905 predicate(n->as_LoadStore()->result_not_used()); 7906 match(Set dummy (GetAndAddI mem add)); 7907 effect(KILL cr); 7908 format %{ "ADDL [$mem],$add" %} 7909 ins_encode %{ 7910 if (os::is_MP()) { __ lock(); } 7911 __ addl($mem$$Address, $add$$constant); 7912 %} 7913 ins_pipe( pipe_cmpxchg ); 7914 %} 7915 7916 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7917 match(Set newval (GetAndAddI mem newval)); 7918 effect(KILL cr); 7919 format %{ "XADDL [$mem],$newval" %} 7920 ins_encode %{ 7921 if (os::is_MP()) { __ lock(); } 7922 __ xaddl($mem$$Address, $newval$$Register); 7923 %} 7924 ins_pipe( pipe_cmpxchg ); 7925 %} 7926 7927 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7928 predicate(n->as_LoadStore()->result_not_used()); 7929 match(Set dummy (GetAndAddL mem add)); 7930 effect(KILL cr); 7931 format %{ "ADDQ [$mem],$add" %} 7932 ins_encode %{ 7933 if (os::is_MP()) { __ lock(); } 7934 __ addq($mem$$Address, $add$$constant); 7935 %} 7936 ins_pipe( pipe_cmpxchg ); 7937 %} 7938 7939 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7940 match(Set newval (GetAndAddL mem newval)); 7941 effect(KILL cr); 7942 format %{ "XADDQ [$mem],$newval" %} 7943 ins_encode %{ 7944 if (os::is_MP()) { __ lock(); } 7945 __ xaddq($mem$$Address, $newval$$Register); 7946 %} 7947 ins_pipe( pipe_cmpxchg ); 7948 %} 7949 7950 instruct xchgB( memory mem, rRegI newval) %{ 7951 match(Set newval (GetAndSetB mem newval)); 7952 format %{ "XCHGB $newval,[$mem]" %} 7953 ins_encode %{ 7954 __ xchgb($newval$$Register, $mem$$Address); 7955 %} 7956 ins_pipe( pipe_cmpxchg ); 7957 %} 7958 7959 instruct xchgS( memory mem, rRegI newval) %{ 7960 match(Set newval (GetAndSetS mem newval)); 7961 format %{ "XCHGW $newval,[$mem]" %} 7962 ins_encode %{ 7963 __ xchgw($newval$$Register, $mem$$Address); 7964 %} 7965 ins_pipe( pipe_cmpxchg ); 7966 %} 7967 7968 instruct xchgI( memory mem, rRegI newval) %{ 7969 match(Set newval (GetAndSetI mem newval)); 7970 format %{ "XCHGL $newval,[$mem]" %} 7971 ins_encode %{ 7972 __ xchgl($newval$$Register, $mem$$Address); 7973 %} 7974 ins_pipe( pipe_cmpxchg ); 7975 %} 7976 7977 instruct xchgL( memory mem, rRegL newval) %{ 7978 match(Set newval (GetAndSetL mem newval)); 7979 format %{ "XCHGL $newval,[$mem]" %} 7980 ins_encode %{ 7981 __ xchgq($newval$$Register, $mem$$Address); 7982 %} 7983 ins_pipe( pipe_cmpxchg ); 7984 %} 7985 7986 instruct xchgP( memory mem, rRegP newval) %{ 7987 match(Set newval (GetAndSetP mem newval)); 7988 format %{ "XCHGQ $newval,[$mem]" %} 7989 ins_encode %{ 7990 __ xchgq($newval$$Register, $mem$$Address); 7991 %} 7992 ins_pipe( pipe_cmpxchg ); 7993 %} 7994 7995 instruct xchgN( memory mem, rRegN newval) %{ 7996 match(Set newval (GetAndSetN mem newval)); 7997 format %{ "XCHGL $newval,$mem]" %} 7998 ins_encode %{ 7999 __ xchgl($newval$$Register, $mem$$Address); 8000 %} 8001 ins_pipe( pipe_cmpxchg ); 8002 %} 8003 8004 //----------Subtraction Instructions------------------------------------------- 8005 8006 // Integer Subtraction Instructions 8007 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8008 %{ 8009 match(Set dst (SubI dst src)); 8010 effect(KILL cr); 8011 8012 format %{ "subl $dst, $src\t# int" %} 8013 opcode(0x2B); 8014 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8015 ins_pipe(ialu_reg_reg); 8016 %} 8017 8018 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8019 %{ 8020 match(Set dst (SubI dst src)); 8021 effect(KILL cr); 8022 8023 format %{ "subl $dst, $src\t# int" %} 8024 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8025 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8026 ins_pipe(ialu_reg); 8027 %} 8028 8029 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8030 %{ 8031 match(Set dst (SubI dst (LoadI src))); 8032 effect(KILL cr); 8033 8034 ins_cost(125); 8035 format %{ "subl $dst, $src\t# int" %} 8036 opcode(0x2B); 8037 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8038 ins_pipe(ialu_reg_mem); 8039 %} 8040 8041 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8042 %{ 8043 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8044 effect(KILL cr); 8045 8046 ins_cost(150); 8047 format %{ "subl $dst, $src\t# int" %} 8048 opcode(0x29); /* Opcode 29 /r */ 8049 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8050 ins_pipe(ialu_mem_reg); 8051 %} 8052 8053 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8054 %{ 8055 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8056 effect(KILL cr); 8057 8058 ins_cost(125); // XXX 8059 format %{ "subl $dst, $src\t# int" %} 8060 opcode(0x81); /* Opcode 81 /5 id */ 8061 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8062 ins_pipe(ialu_mem_imm); 8063 %} 8064 8065 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8066 %{ 8067 match(Set dst (SubL dst src)); 8068 effect(KILL cr); 8069 8070 format %{ "subq $dst, $src\t# long" %} 8071 opcode(0x2B); 8072 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8073 ins_pipe(ialu_reg_reg); 8074 %} 8075 8076 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8077 %{ 8078 match(Set dst (SubL dst src)); 8079 effect(KILL cr); 8080 8081 format %{ "subq $dst, $src\t# long" %} 8082 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8083 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8084 ins_pipe(ialu_reg); 8085 %} 8086 8087 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8088 %{ 8089 match(Set dst (SubL dst (LoadL src))); 8090 effect(KILL cr); 8091 8092 ins_cost(125); 8093 format %{ "subq $dst, $src\t# long" %} 8094 opcode(0x2B); 8095 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8096 ins_pipe(ialu_reg_mem); 8097 %} 8098 8099 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8100 %{ 8101 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8102 effect(KILL cr); 8103 8104 ins_cost(150); 8105 format %{ "subq $dst, $src\t# long" %} 8106 opcode(0x29); /* Opcode 29 /r */ 8107 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8108 ins_pipe(ialu_mem_reg); 8109 %} 8110 8111 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8112 %{ 8113 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8114 effect(KILL cr); 8115 8116 ins_cost(125); // XXX 8117 format %{ "subq $dst, $src\t# long" %} 8118 opcode(0x81); /* Opcode 81 /5 id */ 8119 ins_encode(REX_mem_wide(dst), 8120 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8121 ins_pipe(ialu_mem_imm); 8122 %} 8123 8124 // Subtract from a pointer 8125 // XXX hmpf??? 8126 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8127 %{ 8128 match(Set dst (AddP dst (SubI zero src))); 8129 effect(KILL cr); 8130 8131 format %{ "subq $dst, $src\t# ptr - int" %} 8132 opcode(0x2B); 8133 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8134 ins_pipe(ialu_reg_reg); 8135 %} 8136 8137 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8138 %{ 8139 match(Set dst (SubI zero dst)); 8140 effect(KILL cr); 8141 8142 format %{ "negl $dst\t# int" %} 8143 opcode(0xF7, 0x03); // Opcode F7 /3 8144 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8145 ins_pipe(ialu_reg); 8146 %} 8147 8148 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8149 %{ 8150 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8151 effect(KILL cr); 8152 8153 format %{ "negl $dst\t# int" %} 8154 opcode(0xF7, 0x03); // Opcode F7 /3 8155 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8156 ins_pipe(ialu_reg); 8157 %} 8158 8159 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8160 %{ 8161 match(Set dst (SubL zero dst)); 8162 effect(KILL cr); 8163 8164 format %{ "negq $dst\t# long" %} 8165 opcode(0xF7, 0x03); // Opcode F7 /3 8166 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8167 ins_pipe(ialu_reg); 8168 %} 8169 8170 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8171 %{ 8172 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8173 effect(KILL cr); 8174 8175 format %{ "negq $dst\t# long" %} 8176 opcode(0xF7, 0x03); // Opcode F7 /3 8177 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8178 ins_pipe(ialu_reg); 8179 %} 8180 8181 //----------Multiplication/Division Instructions------------------------------- 8182 // Integer Multiplication Instructions 8183 // Multiply Register 8184 8185 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8186 %{ 8187 match(Set dst (MulI dst src)); 8188 effect(KILL cr); 8189 8190 ins_cost(300); 8191 format %{ "imull $dst, $src\t# int" %} 8192 opcode(0x0F, 0xAF); 8193 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8194 ins_pipe(ialu_reg_reg_alu0); 8195 %} 8196 8197 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8198 %{ 8199 match(Set dst (MulI src imm)); 8200 effect(KILL cr); 8201 8202 ins_cost(300); 8203 format %{ "imull $dst, $src, $imm\t# int" %} 8204 opcode(0x69); /* 69 /r id */ 8205 ins_encode(REX_reg_reg(dst, src), 8206 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8207 ins_pipe(ialu_reg_reg_alu0); 8208 %} 8209 8210 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8211 %{ 8212 match(Set dst (MulI dst (LoadI src))); 8213 effect(KILL cr); 8214 8215 ins_cost(350); 8216 format %{ "imull $dst, $src\t# int" %} 8217 opcode(0x0F, 0xAF); 8218 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8219 ins_pipe(ialu_reg_mem_alu0); 8220 %} 8221 8222 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8223 %{ 8224 match(Set dst (MulI (LoadI src) imm)); 8225 effect(KILL cr); 8226 8227 ins_cost(300); 8228 format %{ "imull $dst, $src, $imm\t# int" %} 8229 opcode(0x69); /* 69 /r id */ 8230 ins_encode(REX_reg_mem(dst, src), 8231 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8232 ins_pipe(ialu_reg_mem_alu0); 8233 %} 8234 8235 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8236 %{ 8237 match(Set dst (MulL dst src)); 8238 effect(KILL cr); 8239 8240 ins_cost(300); 8241 format %{ "imulq $dst, $src\t# long" %} 8242 opcode(0x0F, 0xAF); 8243 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8244 ins_pipe(ialu_reg_reg_alu0); 8245 %} 8246 8247 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8248 %{ 8249 match(Set dst (MulL src imm)); 8250 effect(KILL cr); 8251 8252 ins_cost(300); 8253 format %{ "imulq $dst, $src, $imm\t# long" %} 8254 opcode(0x69); /* 69 /r id */ 8255 ins_encode(REX_reg_reg_wide(dst, src), 8256 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8257 ins_pipe(ialu_reg_reg_alu0); 8258 %} 8259 8260 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8261 %{ 8262 match(Set dst (MulL dst (LoadL src))); 8263 effect(KILL cr); 8264 8265 ins_cost(350); 8266 format %{ "imulq $dst, $src\t# long" %} 8267 opcode(0x0F, 0xAF); 8268 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8269 ins_pipe(ialu_reg_mem_alu0); 8270 %} 8271 8272 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8273 %{ 8274 match(Set dst (MulL (LoadL src) imm)); 8275 effect(KILL cr); 8276 8277 ins_cost(300); 8278 format %{ "imulq $dst, $src, $imm\t# long" %} 8279 opcode(0x69); /* 69 /r id */ 8280 ins_encode(REX_reg_mem_wide(dst, src), 8281 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8282 ins_pipe(ialu_reg_mem_alu0); 8283 %} 8284 8285 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8286 %{ 8287 match(Set dst (MulHiL src rax)); 8288 effect(USE_KILL rax, KILL cr); 8289 8290 ins_cost(300); 8291 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8292 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8293 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8294 ins_pipe(ialu_reg_reg_alu0); 8295 %} 8296 8297 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8298 rFlagsReg cr) 8299 %{ 8300 match(Set rax (DivI rax div)); 8301 effect(KILL rdx, KILL cr); 8302 8303 ins_cost(30*100+10*100); // XXX 8304 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8305 "jne,s normal\n\t" 8306 "xorl rdx, rdx\n\t" 8307 "cmpl $div, -1\n\t" 8308 "je,s done\n" 8309 "normal: cdql\n\t" 8310 "idivl $div\n" 8311 "done:" %} 8312 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8313 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8314 ins_pipe(ialu_reg_reg_alu0); 8315 %} 8316 8317 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8318 rFlagsReg cr) 8319 %{ 8320 match(Set rax (DivL rax div)); 8321 effect(KILL rdx, KILL cr); 8322 8323 ins_cost(30*100+10*100); // XXX 8324 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8325 "cmpq rax, rdx\n\t" 8326 "jne,s normal\n\t" 8327 "xorl rdx, rdx\n\t" 8328 "cmpq $div, -1\n\t" 8329 "je,s done\n" 8330 "normal: cdqq\n\t" 8331 "idivq $div\n" 8332 "done:" %} 8333 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8334 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8335 ins_pipe(ialu_reg_reg_alu0); 8336 %} 8337 8338 // Integer DIVMOD with Register, both quotient and mod results 8339 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8340 rFlagsReg cr) 8341 %{ 8342 match(DivModI rax div); 8343 effect(KILL cr); 8344 8345 ins_cost(30*100+10*100); // XXX 8346 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8347 "jne,s normal\n\t" 8348 "xorl rdx, rdx\n\t" 8349 "cmpl $div, -1\n\t" 8350 "je,s done\n" 8351 "normal: cdql\n\t" 8352 "idivl $div\n" 8353 "done:" %} 8354 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8355 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8356 ins_pipe(pipe_slow); 8357 %} 8358 8359 // Long DIVMOD with Register, both quotient and mod results 8360 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8361 rFlagsReg cr) 8362 %{ 8363 match(DivModL rax div); 8364 effect(KILL cr); 8365 8366 ins_cost(30*100+10*100); // XXX 8367 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8368 "cmpq rax, rdx\n\t" 8369 "jne,s normal\n\t" 8370 "xorl rdx, rdx\n\t" 8371 "cmpq $div, -1\n\t" 8372 "je,s done\n" 8373 "normal: cdqq\n\t" 8374 "idivq $div\n" 8375 "done:" %} 8376 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8377 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8378 ins_pipe(pipe_slow); 8379 %} 8380 8381 //----------- DivL-By-Constant-Expansions-------------------------------------- 8382 // DivI cases are handled by the compiler 8383 8384 // Magic constant, reciprocal of 10 8385 instruct loadConL_0x6666666666666667(rRegL dst) 8386 %{ 8387 effect(DEF dst); 8388 8389 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8390 ins_encode(load_immL(dst, 0x6666666666666667)); 8391 ins_pipe(ialu_reg); 8392 %} 8393 8394 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8395 %{ 8396 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8397 8398 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8399 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8400 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8401 ins_pipe(ialu_reg_reg_alu0); 8402 %} 8403 8404 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8405 %{ 8406 effect(USE_DEF dst, KILL cr); 8407 8408 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8409 opcode(0xC1, 0x7); /* C1 /7 ib */ 8410 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8411 ins_pipe(ialu_reg); 8412 %} 8413 8414 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8415 %{ 8416 effect(USE_DEF dst, KILL cr); 8417 8418 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8419 opcode(0xC1, 0x7); /* C1 /7 ib */ 8420 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8421 ins_pipe(ialu_reg); 8422 %} 8423 8424 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8425 %{ 8426 match(Set dst (DivL src div)); 8427 8428 ins_cost((5+8)*100); 8429 expand %{ 8430 rax_RegL rax; // Killed temp 8431 rFlagsReg cr; // Killed 8432 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8433 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8434 sarL_rReg_63(src, cr); // sarq src, 63 8435 sarL_rReg_2(dst, cr); // sarq rdx, 2 8436 subL_rReg(dst, src, cr); // subl rdx, src 8437 %} 8438 %} 8439 8440 //----------------------------------------------------------------------------- 8441 8442 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8443 rFlagsReg cr) 8444 %{ 8445 match(Set rdx (ModI rax div)); 8446 effect(KILL rax, KILL cr); 8447 8448 ins_cost(300); // XXX 8449 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8450 "jne,s normal\n\t" 8451 "xorl rdx, rdx\n\t" 8452 "cmpl $div, -1\n\t" 8453 "je,s done\n" 8454 "normal: cdql\n\t" 8455 "idivl $div\n" 8456 "done:" %} 8457 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8458 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8459 ins_pipe(ialu_reg_reg_alu0); 8460 %} 8461 8462 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8463 rFlagsReg cr) 8464 %{ 8465 match(Set rdx (ModL rax div)); 8466 effect(KILL rax, KILL cr); 8467 8468 ins_cost(300); // XXX 8469 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8470 "cmpq rax, rdx\n\t" 8471 "jne,s normal\n\t" 8472 "xorl rdx, rdx\n\t" 8473 "cmpq $div, -1\n\t" 8474 "je,s done\n" 8475 "normal: cdqq\n\t" 8476 "idivq $div\n" 8477 "done:" %} 8478 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8479 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8480 ins_pipe(ialu_reg_reg_alu0); 8481 %} 8482 8483 // Integer Shift Instructions 8484 // Shift Left by one 8485 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8486 %{ 8487 match(Set dst (LShiftI dst shift)); 8488 effect(KILL cr); 8489 8490 format %{ "sall $dst, $shift" %} 8491 opcode(0xD1, 0x4); /* D1 /4 */ 8492 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8493 ins_pipe(ialu_reg); 8494 %} 8495 8496 // Shift Left by one 8497 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8498 %{ 8499 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8500 effect(KILL cr); 8501 8502 format %{ "sall $dst, $shift\t" %} 8503 opcode(0xD1, 0x4); /* D1 /4 */ 8504 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8505 ins_pipe(ialu_mem_imm); 8506 %} 8507 8508 // Shift Left by 8-bit immediate 8509 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8510 %{ 8511 match(Set dst (LShiftI dst shift)); 8512 effect(KILL cr); 8513 8514 format %{ "sall $dst, $shift" %} 8515 opcode(0xC1, 0x4); /* C1 /4 ib */ 8516 ins_encode(reg_opc_imm(dst, shift)); 8517 ins_pipe(ialu_reg); 8518 %} 8519 8520 // Shift Left by 8-bit immediate 8521 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8522 %{ 8523 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8524 effect(KILL cr); 8525 8526 format %{ "sall $dst, $shift" %} 8527 opcode(0xC1, 0x4); /* C1 /4 ib */ 8528 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8529 ins_pipe(ialu_mem_imm); 8530 %} 8531 8532 // Shift Left by variable 8533 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8534 %{ 8535 match(Set dst (LShiftI dst shift)); 8536 effect(KILL cr); 8537 8538 format %{ "sall $dst, $shift" %} 8539 opcode(0xD3, 0x4); /* D3 /4 */ 8540 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8541 ins_pipe(ialu_reg_reg); 8542 %} 8543 8544 // Shift Left by variable 8545 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8546 %{ 8547 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8548 effect(KILL cr); 8549 8550 format %{ "sall $dst, $shift" %} 8551 opcode(0xD3, 0x4); /* D3 /4 */ 8552 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8553 ins_pipe(ialu_mem_reg); 8554 %} 8555 8556 // Arithmetic shift right by one 8557 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8558 %{ 8559 match(Set dst (RShiftI dst shift)); 8560 effect(KILL cr); 8561 8562 format %{ "sarl $dst, $shift" %} 8563 opcode(0xD1, 0x7); /* D1 /7 */ 8564 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8565 ins_pipe(ialu_reg); 8566 %} 8567 8568 // Arithmetic shift right by one 8569 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8570 %{ 8571 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8572 effect(KILL cr); 8573 8574 format %{ "sarl $dst, $shift" %} 8575 opcode(0xD1, 0x7); /* D1 /7 */ 8576 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8577 ins_pipe(ialu_mem_imm); 8578 %} 8579 8580 // Arithmetic Shift Right by 8-bit immediate 8581 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8582 %{ 8583 match(Set dst (RShiftI dst shift)); 8584 effect(KILL cr); 8585 8586 format %{ "sarl $dst, $shift" %} 8587 opcode(0xC1, 0x7); /* C1 /7 ib */ 8588 ins_encode(reg_opc_imm(dst, shift)); 8589 ins_pipe(ialu_mem_imm); 8590 %} 8591 8592 // Arithmetic Shift Right by 8-bit immediate 8593 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8594 %{ 8595 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8596 effect(KILL cr); 8597 8598 format %{ "sarl $dst, $shift" %} 8599 opcode(0xC1, 0x7); /* C1 /7 ib */ 8600 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8601 ins_pipe(ialu_mem_imm); 8602 %} 8603 8604 // Arithmetic Shift Right by variable 8605 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8606 %{ 8607 match(Set dst (RShiftI dst shift)); 8608 effect(KILL cr); 8609 8610 format %{ "sarl $dst, $shift" %} 8611 opcode(0xD3, 0x7); /* D3 /7 */ 8612 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8613 ins_pipe(ialu_reg_reg); 8614 %} 8615 8616 // Arithmetic Shift Right by variable 8617 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8618 %{ 8619 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8620 effect(KILL cr); 8621 8622 format %{ "sarl $dst, $shift" %} 8623 opcode(0xD3, 0x7); /* D3 /7 */ 8624 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8625 ins_pipe(ialu_mem_reg); 8626 %} 8627 8628 // Logical shift right by one 8629 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8630 %{ 8631 match(Set dst (URShiftI dst shift)); 8632 effect(KILL cr); 8633 8634 format %{ "shrl $dst, $shift" %} 8635 opcode(0xD1, 0x5); /* D1 /5 */ 8636 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8637 ins_pipe(ialu_reg); 8638 %} 8639 8640 // Logical shift right by one 8641 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8642 %{ 8643 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8644 effect(KILL cr); 8645 8646 format %{ "shrl $dst, $shift" %} 8647 opcode(0xD1, 0x5); /* D1 /5 */ 8648 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8649 ins_pipe(ialu_mem_imm); 8650 %} 8651 8652 // Logical Shift Right by 8-bit immediate 8653 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8654 %{ 8655 match(Set dst (URShiftI dst shift)); 8656 effect(KILL cr); 8657 8658 format %{ "shrl $dst, $shift" %} 8659 opcode(0xC1, 0x5); /* C1 /5 ib */ 8660 ins_encode(reg_opc_imm(dst, shift)); 8661 ins_pipe(ialu_reg); 8662 %} 8663 8664 // Logical Shift Right by 8-bit immediate 8665 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8666 %{ 8667 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8668 effect(KILL cr); 8669 8670 format %{ "shrl $dst, $shift" %} 8671 opcode(0xC1, 0x5); /* C1 /5 ib */ 8672 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8673 ins_pipe(ialu_mem_imm); 8674 %} 8675 8676 // Logical Shift Right by variable 8677 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8678 %{ 8679 match(Set dst (URShiftI dst shift)); 8680 effect(KILL cr); 8681 8682 format %{ "shrl $dst, $shift" %} 8683 opcode(0xD3, 0x5); /* D3 /5 */ 8684 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8685 ins_pipe(ialu_reg_reg); 8686 %} 8687 8688 // Logical Shift Right by variable 8689 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8690 %{ 8691 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8692 effect(KILL cr); 8693 8694 format %{ "shrl $dst, $shift" %} 8695 opcode(0xD3, 0x5); /* D3 /5 */ 8696 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8697 ins_pipe(ialu_mem_reg); 8698 %} 8699 8700 // Long Shift Instructions 8701 // Shift Left by one 8702 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8703 %{ 8704 match(Set dst (LShiftL dst shift)); 8705 effect(KILL cr); 8706 8707 format %{ "salq $dst, $shift" %} 8708 opcode(0xD1, 0x4); /* D1 /4 */ 8709 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8710 ins_pipe(ialu_reg); 8711 %} 8712 8713 // Shift Left by one 8714 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8715 %{ 8716 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8717 effect(KILL cr); 8718 8719 format %{ "salq $dst, $shift" %} 8720 opcode(0xD1, 0x4); /* D1 /4 */ 8721 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8722 ins_pipe(ialu_mem_imm); 8723 %} 8724 8725 // Shift Left by 8-bit immediate 8726 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8727 %{ 8728 match(Set dst (LShiftL dst shift)); 8729 effect(KILL cr); 8730 8731 format %{ "salq $dst, $shift" %} 8732 opcode(0xC1, 0x4); /* C1 /4 ib */ 8733 ins_encode(reg_opc_imm_wide(dst, shift)); 8734 ins_pipe(ialu_reg); 8735 %} 8736 8737 // Shift Left by 8-bit immediate 8738 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8739 %{ 8740 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8741 effect(KILL cr); 8742 8743 format %{ "salq $dst, $shift" %} 8744 opcode(0xC1, 0x4); /* C1 /4 ib */ 8745 ins_encode(REX_mem_wide(dst), OpcP, 8746 RM_opc_mem(secondary, dst), Con8or32(shift)); 8747 ins_pipe(ialu_mem_imm); 8748 %} 8749 8750 // Shift Left by variable 8751 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8752 %{ 8753 match(Set dst (LShiftL dst shift)); 8754 effect(KILL cr); 8755 8756 format %{ "salq $dst, $shift" %} 8757 opcode(0xD3, 0x4); /* D3 /4 */ 8758 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8759 ins_pipe(ialu_reg_reg); 8760 %} 8761 8762 // Shift Left by variable 8763 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8764 %{ 8765 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8766 effect(KILL cr); 8767 8768 format %{ "salq $dst, $shift" %} 8769 opcode(0xD3, 0x4); /* D3 /4 */ 8770 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8771 ins_pipe(ialu_mem_reg); 8772 %} 8773 8774 // Arithmetic shift right by one 8775 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8776 %{ 8777 match(Set dst (RShiftL dst shift)); 8778 effect(KILL cr); 8779 8780 format %{ "sarq $dst, $shift" %} 8781 opcode(0xD1, 0x7); /* D1 /7 */ 8782 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8783 ins_pipe(ialu_reg); 8784 %} 8785 8786 // Arithmetic shift right by one 8787 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8788 %{ 8789 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8790 effect(KILL cr); 8791 8792 format %{ "sarq $dst, $shift" %} 8793 opcode(0xD1, 0x7); /* D1 /7 */ 8794 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8795 ins_pipe(ialu_mem_imm); 8796 %} 8797 8798 // Arithmetic Shift Right by 8-bit immediate 8799 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8800 %{ 8801 match(Set dst (RShiftL dst shift)); 8802 effect(KILL cr); 8803 8804 format %{ "sarq $dst, $shift" %} 8805 opcode(0xC1, 0x7); /* C1 /7 ib */ 8806 ins_encode(reg_opc_imm_wide(dst, shift)); 8807 ins_pipe(ialu_mem_imm); 8808 %} 8809 8810 // Arithmetic Shift Right by 8-bit immediate 8811 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8812 %{ 8813 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8814 effect(KILL cr); 8815 8816 format %{ "sarq $dst, $shift" %} 8817 opcode(0xC1, 0x7); /* C1 /7 ib */ 8818 ins_encode(REX_mem_wide(dst), OpcP, 8819 RM_opc_mem(secondary, dst), Con8or32(shift)); 8820 ins_pipe(ialu_mem_imm); 8821 %} 8822 8823 // Arithmetic Shift Right by variable 8824 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8825 %{ 8826 match(Set dst (RShiftL dst shift)); 8827 effect(KILL cr); 8828 8829 format %{ "sarq $dst, $shift" %} 8830 opcode(0xD3, 0x7); /* D3 /7 */ 8831 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8832 ins_pipe(ialu_reg_reg); 8833 %} 8834 8835 // Arithmetic Shift Right by variable 8836 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8837 %{ 8838 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8839 effect(KILL cr); 8840 8841 format %{ "sarq $dst, $shift" %} 8842 opcode(0xD3, 0x7); /* D3 /7 */ 8843 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8844 ins_pipe(ialu_mem_reg); 8845 %} 8846 8847 // Logical shift right by one 8848 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8849 %{ 8850 match(Set dst (URShiftL dst shift)); 8851 effect(KILL cr); 8852 8853 format %{ "shrq $dst, $shift" %} 8854 opcode(0xD1, 0x5); /* D1 /5 */ 8855 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8856 ins_pipe(ialu_reg); 8857 %} 8858 8859 // Logical shift right by one 8860 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8861 %{ 8862 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8863 effect(KILL cr); 8864 8865 format %{ "shrq $dst, $shift" %} 8866 opcode(0xD1, 0x5); /* D1 /5 */ 8867 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8868 ins_pipe(ialu_mem_imm); 8869 %} 8870 8871 // Logical Shift Right by 8-bit immediate 8872 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8873 %{ 8874 match(Set dst (URShiftL dst shift)); 8875 effect(KILL cr); 8876 8877 format %{ "shrq $dst, $shift" %} 8878 opcode(0xC1, 0x5); /* C1 /5 ib */ 8879 ins_encode(reg_opc_imm_wide(dst, shift)); 8880 ins_pipe(ialu_reg); 8881 %} 8882 8883 8884 // Logical Shift Right by 8-bit immediate 8885 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8886 %{ 8887 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8888 effect(KILL cr); 8889 8890 format %{ "shrq $dst, $shift" %} 8891 opcode(0xC1, 0x5); /* C1 /5 ib */ 8892 ins_encode(REX_mem_wide(dst), OpcP, 8893 RM_opc_mem(secondary, dst), Con8or32(shift)); 8894 ins_pipe(ialu_mem_imm); 8895 %} 8896 8897 // Logical Shift Right by variable 8898 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8899 %{ 8900 match(Set dst (URShiftL dst shift)); 8901 effect(KILL cr); 8902 8903 format %{ "shrq $dst, $shift" %} 8904 opcode(0xD3, 0x5); /* D3 /5 */ 8905 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8906 ins_pipe(ialu_reg_reg); 8907 %} 8908 8909 // Logical Shift Right by variable 8910 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8911 %{ 8912 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8913 effect(KILL cr); 8914 8915 format %{ "shrq $dst, $shift" %} 8916 opcode(0xD3, 0x5); /* D3 /5 */ 8917 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8918 ins_pipe(ialu_mem_reg); 8919 %} 8920 8921 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8922 // This idiom is used by the compiler for the i2b bytecode. 8923 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8924 %{ 8925 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8926 8927 format %{ "movsbl $dst, $src\t# i2b" %} 8928 opcode(0x0F, 0xBE); 8929 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8930 ins_pipe(ialu_reg_reg); 8931 %} 8932 8933 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8934 // This idiom is used by the compiler the i2s bytecode. 8935 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8936 %{ 8937 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8938 8939 format %{ "movswl $dst, $src\t# i2s" %} 8940 opcode(0x0F, 0xBF); 8941 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8942 ins_pipe(ialu_reg_reg); 8943 %} 8944 8945 // ROL/ROR instructions 8946 8947 // ROL expand 8948 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8949 effect(KILL cr, USE_DEF dst); 8950 8951 format %{ "roll $dst" %} 8952 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8953 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8954 ins_pipe(ialu_reg); 8955 %} 8956 8957 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8958 effect(USE_DEF dst, USE shift, KILL cr); 8959 8960 format %{ "roll $dst, $shift" %} 8961 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8962 ins_encode( reg_opc_imm(dst, shift) ); 8963 ins_pipe(ialu_reg); 8964 %} 8965 8966 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8967 %{ 8968 effect(USE_DEF dst, USE shift, KILL cr); 8969 8970 format %{ "roll $dst, $shift" %} 8971 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8972 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8973 ins_pipe(ialu_reg_reg); 8974 %} 8975 // end of ROL expand 8976 8977 // Rotate Left by one 8978 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8979 %{ 8980 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8981 8982 expand %{ 8983 rolI_rReg_imm1(dst, cr); 8984 %} 8985 %} 8986 8987 // Rotate Left by 8-bit immediate 8988 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8989 %{ 8990 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8991 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8992 8993 expand %{ 8994 rolI_rReg_imm8(dst, lshift, cr); 8995 %} 8996 %} 8997 8998 // Rotate Left by variable 8999 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9000 %{ 9001 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9002 9003 expand %{ 9004 rolI_rReg_CL(dst, shift, cr); 9005 %} 9006 %} 9007 9008 // Rotate Left by variable 9009 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9010 %{ 9011 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9012 9013 expand %{ 9014 rolI_rReg_CL(dst, shift, cr); 9015 %} 9016 %} 9017 9018 // ROR expand 9019 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9020 %{ 9021 effect(USE_DEF dst, KILL cr); 9022 9023 format %{ "rorl $dst" %} 9024 opcode(0xD1, 0x1); /* D1 /1 */ 9025 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9026 ins_pipe(ialu_reg); 9027 %} 9028 9029 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9030 %{ 9031 effect(USE_DEF dst, USE shift, KILL cr); 9032 9033 format %{ "rorl $dst, $shift" %} 9034 opcode(0xC1, 0x1); /* C1 /1 ib */ 9035 ins_encode(reg_opc_imm(dst, shift)); 9036 ins_pipe(ialu_reg); 9037 %} 9038 9039 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9040 %{ 9041 effect(USE_DEF dst, USE shift, KILL cr); 9042 9043 format %{ "rorl $dst, $shift" %} 9044 opcode(0xD3, 0x1); /* D3 /1 */ 9045 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9046 ins_pipe(ialu_reg_reg); 9047 %} 9048 // end of ROR expand 9049 9050 // Rotate Right by one 9051 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9052 %{ 9053 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9054 9055 expand %{ 9056 rorI_rReg_imm1(dst, cr); 9057 %} 9058 %} 9059 9060 // Rotate Right by 8-bit immediate 9061 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9062 %{ 9063 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9064 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9065 9066 expand %{ 9067 rorI_rReg_imm8(dst, rshift, cr); 9068 %} 9069 %} 9070 9071 // Rotate Right by variable 9072 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9073 %{ 9074 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9075 9076 expand %{ 9077 rorI_rReg_CL(dst, shift, cr); 9078 %} 9079 %} 9080 9081 // Rotate Right by variable 9082 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9083 %{ 9084 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9085 9086 expand %{ 9087 rorI_rReg_CL(dst, shift, cr); 9088 %} 9089 %} 9090 9091 // for long rotate 9092 // ROL expand 9093 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9094 effect(USE_DEF dst, KILL cr); 9095 9096 format %{ "rolq $dst" %} 9097 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9098 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9099 ins_pipe(ialu_reg); 9100 %} 9101 9102 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9103 effect(USE_DEF dst, USE shift, KILL cr); 9104 9105 format %{ "rolq $dst, $shift" %} 9106 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9107 ins_encode( reg_opc_imm_wide(dst, shift) ); 9108 ins_pipe(ialu_reg); 9109 %} 9110 9111 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9112 %{ 9113 effect(USE_DEF dst, USE shift, KILL cr); 9114 9115 format %{ "rolq $dst, $shift" %} 9116 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9117 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9118 ins_pipe(ialu_reg_reg); 9119 %} 9120 // end of ROL expand 9121 9122 // Rotate Left by one 9123 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9124 %{ 9125 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9126 9127 expand %{ 9128 rolL_rReg_imm1(dst, cr); 9129 %} 9130 %} 9131 9132 // Rotate Left by 8-bit immediate 9133 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9134 %{ 9135 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9136 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9137 9138 expand %{ 9139 rolL_rReg_imm8(dst, lshift, cr); 9140 %} 9141 %} 9142 9143 // Rotate Left by variable 9144 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9145 %{ 9146 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9147 9148 expand %{ 9149 rolL_rReg_CL(dst, shift, cr); 9150 %} 9151 %} 9152 9153 // Rotate Left by variable 9154 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9155 %{ 9156 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9157 9158 expand %{ 9159 rolL_rReg_CL(dst, shift, cr); 9160 %} 9161 %} 9162 9163 // ROR expand 9164 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9165 %{ 9166 effect(USE_DEF dst, KILL cr); 9167 9168 format %{ "rorq $dst" %} 9169 opcode(0xD1, 0x1); /* D1 /1 */ 9170 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9171 ins_pipe(ialu_reg); 9172 %} 9173 9174 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9175 %{ 9176 effect(USE_DEF dst, USE shift, KILL cr); 9177 9178 format %{ "rorq $dst, $shift" %} 9179 opcode(0xC1, 0x1); /* C1 /1 ib */ 9180 ins_encode(reg_opc_imm_wide(dst, shift)); 9181 ins_pipe(ialu_reg); 9182 %} 9183 9184 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9185 %{ 9186 effect(USE_DEF dst, USE shift, KILL cr); 9187 9188 format %{ "rorq $dst, $shift" %} 9189 opcode(0xD3, 0x1); /* D3 /1 */ 9190 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9191 ins_pipe(ialu_reg_reg); 9192 %} 9193 // end of ROR expand 9194 9195 // Rotate Right by one 9196 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9197 %{ 9198 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9199 9200 expand %{ 9201 rorL_rReg_imm1(dst, cr); 9202 %} 9203 %} 9204 9205 // Rotate Right by 8-bit immediate 9206 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9207 %{ 9208 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9209 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9210 9211 expand %{ 9212 rorL_rReg_imm8(dst, rshift, cr); 9213 %} 9214 %} 9215 9216 // Rotate Right by variable 9217 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9218 %{ 9219 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9220 9221 expand %{ 9222 rorL_rReg_CL(dst, shift, cr); 9223 %} 9224 %} 9225 9226 // Rotate Right by variable 9227 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9228 %{ 9229 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9230 9231 expand %{ 9232 rorL_rReg_CL(dst, shift, cr); 9233 %} 9234 %} 9235 9236 // Logical Instructions 9237 9238 // Integer Logical Instructions 9239 9240 // And Instructions 9241 // And Register with Register 9242 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9243 %{ 9244 match(Set dst (AndI dst src)); 9245 effect(KILL cr); 9246 9247 format %{ "andl $dst, $src\t# int" %} 9248 opcode(0x23); 9249 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9250 ins_pipe(ialu_reg_reg); 9251 %} 9252 9253 // And Register with Immediate 255 9254 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9255 %{ 9256 match(Set dst (AndI dst src)); 9257 9258 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9259 opcode(0x0F, 0xB6); 9260 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9261 ins_pipe(ialu_reg); 9262 %} 9263 9264 // And Register with Immediate 255 and promote to long 9265 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9266 %{ 9267 match(Set dst (ConvI2L (AndI src mask))); 9268 9269 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9270 opcode(0x0F, 0xB6); 9271 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9272 ins_pipe(ialu_reg); 9273 %} 9274 9275 // And Register with Immediate 65535 9276 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9277 %{ 9278 match(Set dst (AndI dst src)); 9279 9280 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9281 opcode(0x0F, 0xB7); 9282 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9283 ins_pipe(ialu_reg); 9284 %} 9285 9286 // And Register with Immediate 65535 and promote to long 9287 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9288 %{ 9289 match(Set dst (ConvI2L (AndI src mask))); 9290 9291 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9292 opcode(0x0F, 0xB7); 9293 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9294 ins_pipe(ialu_reg); 9295 %} 9296 9297 // And Register with Immediate 9298 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9299 %{ 9300 match(Set dst (AndI dst src)); 9301 effect(KILL cr); 9302 9303 format %{ "andl $dst, $src\t# int" %} 9304 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9305 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9306 ins_pipe(ialu_reg); 9307 %} 9308 9309 // And Register with Memory 9310 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9311 %{ 9312 match(Set dst (AndI dst (LoadI src))); 9313 effect(KILL cr); 9314 9315 ins_cost(125); 9316 format %{ "andl $dst, $src\t# int" %} 9317 opcode(0x23); 9318 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9319 ins_pipe(ialu_reg_mem); 9320 %} 9321 9322 // And Memory with Register 9323 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9324 %{ 9325 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9326 effect(KILL cr); 9327 9328 ins_cost(150); 9329 format %{ "andl $dst, $src\t# int" %} 9330 opcode(0x21); /* Opcode 21 /r */ 9331 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9332 ins_pipe(ialu_mem_reg); 9333 %} 9334 9335 // And Memory with Immediate 9336 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9337 %{ 9338 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9339 effect(KILL cr); 9340 9341 ins_cost(125); 9342 format %{ "andl $dst, $src\t# int" %} 9343 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9344 ins_encode(REX_mem(dst), OpcSE(src), 9345 RM_opc_mem(secondary, dst), Con8or32(src)); 9346 ins_pipe(ialu_mem_imm); 9347 %} 9348 9349 // BMI1 instructions 9350 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9351 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9352 predicate(UseBMI1Instructions); 9353 effect(KILL cr); 9354 9355 ins_cost(125); 9356 format %{ "andnl $dst, $src1, $src2" %} 9357 9358 ins_encode %{ 9359 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9360 %} 9361 ins_pipe(ialu_reg_mem); 9362 %} 9363 9364 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9365 match(Set dst (AndI (XorI src1 minus_1) src2)); 9366 predicate(UseBMI1Instructions); 9367 effect(KILL cr); 9368 9369 format %{ "andnl $dst, $src1, $src2" %} 9370 9371 ins_encode %{ 9372 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9373 %} 9374 ins_pipe(ialu_reg); 9375 %} 9376 9377 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9378 match(Set dst (AndI (SubI imm_zero src) src)); 9379 predicate(UseBMI1Instructions); 9380 effect(KILL cr); 9381 9382 format %{ "blsil $dst, $src" %} 9383 9384 ins_encode %{ 9385 __ blsil($dst$$Register, $src$$Register); 9386 %} 9387 ins_pipe(ialu_reg); 9388 %} 9389 9390 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9391 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9392 predicate(UseBMI1Instructions); 9393 effect(KILL cr); 9394 9395 ins_cost(125); 9396 format %{ "blsil $dst, $src" %} 9397 9398 ins_encode %{ 9399 __ blsil($dst$$Register, $src$$Address); 9400 %} 9401 ins_pipe(ialu_reg_mem); 9402 %} 9403 9404 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9405 %{ 9406 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9407 predicate(UseBMI1Instructions); 9408 effect(KILL cr); 9409 9410 ins_cost(125); 9411 format %{ "blsmskl $dst, $src" %} 9412 9413 ins_encode %{ 9414 __ blsmskl($dst$$Register, $src$$Address); 9415 %} 9416 ins_pipe(ialu_reg_mem); 9417 %} 9418 9419 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9420 %{ 9421 match(Set dst (XorI (AddI src minus_1) src)); 9422 predicate(UseBMI1Instructions); 9423 effect(KILL cr); 9424 9425 format %{ "blsmskl $dst, $src" %} 9426 9427 ins_encode %{ 9428 __ blsmskl($dst$$Register, $src$$Register); 9429 %} 9430 9431 ins_pipe(ialu_reg); 9432 %} 9433 9434 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9435 %{ 9436 match(Set dst (AndI (AddI src minus_1) src) ); 9437 predicate(UseBMI1Instructions); 9438 effect(KILL cr); 9439 9440 format %{ "blsrl $dst, $src" %} 9441 9442 ins_encode %{ 9443 __ blsrl($dst$$Register, $src$$Register); 9444 %} 9445 9446 ins_pipe(ialu_reg_mem); 9447 %} 9448 9449 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9450 %{ 9451 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9452 predicate(UseBMI1Instructions); 9453 effect(KILL cr); 9454 9455 ins_cost(125); 9456 format %{ "blsrl $dst, $src" %} 9457 9458 ins_encode %{ 9459 __ blsrl($dst$$Register, $src$$Address); 9460 %} 9461 9462 ins_pipe(ialu_reg); 9463 %} 9464 9465 // Or Instructions 9466 // Or Register with Register 9467 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9468 %{ 9469 match(Set dst (OrI dst src)); 9470 effect(KILL cr); 9471 9472 format %{ "orl $dst, $src\t# int" %} 9473 opcode(0x0B); 9474 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9475 ins_pipe(ialu_reg_reg); 9476 %} 9477 9478 // Or Register with Immediate 9479 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9480 %{ 9481 match(Set dst (OrI dst src)); 9482 effect(KILL cr); 9483 9484 format %{ "orl $dst, $src\t# int" %} 9485 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9486 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9487 ins_pipe(ialu_reg); 9488 %} 9489 9490 // Or Register with Memory 9491 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9492 %{ 9493 match(Set dst (OrI dst (LoadI src))); 9494 effect(KILL cr); 9495 9496 ins_cost(125); 9497 format %{ "orl $dst, $src\t# int" %} 9498 opcode(0x0B); 9499 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9500 ins_pipe(ialu_reg_mem); 9501 %} 9502 9503 // Or Memory with Register 9504 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9505 %{ 9506 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9507 effect(KILL cr); 9508 9509 ins_cost(150); 9510 format %{ "orl $dst, $src\t# int" %} 9511 opcode(0x09); /* Opcode 09 /r */ 9512 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9513 ins_pipe(ialu_mem_reg); 9514 %} 9515 9516 // Or Memory with Immediate 9517 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9518 %{ 9519 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9520 effect(KILL cr); 9521 9522 ins_cost(125); 9523 format %{ "orl $dst, $src\t# int" %} 9524 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9525 ins_encode(REX_mem(dst), OpcSE(src), 9526 RM_opc_mem(secondary, dst), Con8or32(src)); 9527 ins_pipe(ialu_mem_imm); 9528 %} 9529 9530 // Xor Instructions 9531 // Xor Register with Register 9532 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9533 %{ 9534 match(Set dst (XorI dst src)); 9535 effect(KILL cr); 9536 9537 format %{ "xorl $dst, $src\t# int" %} 9538 opcode(0x33); 9539 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9540 ins_pipe(ialu_reg_reg); 9541 %} 9542 9543 // Xor Register with Immediate -1 9544 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9545 match(Set dst (XorI dst imm)); 9546 9547 format %{ "not $dst" %} 9548 ins_encode %{ 9549 __ notl($dst$$Register); 9550 %} 9551 ins_pipe(ialu_reg); 9552 %} 9553 9554 // Xor Register with Immediate 9555 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9556 %{ 9557 match(Set dst (XorI dst src)); 9558 effect(KILL cr); 9559 9560 format %{ "xorl $dst, $src\t# int" %} 9561 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9562 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9563 ins_pipe(ialu_reg); 9564 %} 9565 9566 // Xor Register with Memory 9567 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9568 %{ 9569 match(Set dst (XorI dst (LoadI src))); 9570 effect(KILL cr); 9571 9572 ins_cost(125); 9573 format %{ "xorl $dst, $src\t# int" %} 9574 opcode(0x33); 9575 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9576 ins_pipe(ialu_reg_mem); 9577 %} 9578 9579 // Xor Memory with Register 9580 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9581 %{ 9582 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9583 effect(KILL cr); 9584 9585 ins_cost(150); 9586 format %{ "xorl $dst, $src\t# int" %} 9587 opcode(0x31); /* Opcode 31 /r */ 9588 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9589 ins_pipe(ialu_mem_reg); 9590 %} 9591 9592 // Xor Memory with Immediate 9593 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9594 %{ 9595 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9596 effect(KILL cr); 9597 9598 ins_cost(125); 9599 format %{ "xorl $dst, $src\t# int" %} 9600 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9601 ins_encode(REX_mem(dst), OpcSE(src), 9602 RM_opc_mem(secondary, dst), Con8or32(src)); 9603 ins_pipe(ialu_mem_imm); 9604 %} 9605 9606 9607 // Long Logical Instructions 9608 9609 // And Instructions 9610 // And Register with Register 9611 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9612 %{ 9613 match(Set dst (AndL dst src)); 9614 effect(KILL cr); 9615 9616 format %{ "andq $dst, $src\t# long" %} 9617 opcode(0x23); 9618 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9619 ins_pipe(ialu_reg_reg); 9620 %} 9621 9622 // And Register with Immediate 255 9623 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9624 %{ 9625 match(Set dst (AndL dst src)); 9626 9627 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9628 opcode(0x0F, 0xB6); 9629 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9630 ins_pipe(ialu_reg); 9631 %} 9632 9633 // And Register with Immediate 65535 9634 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9635 %{ 9636 match(Set dst (AndL dst src)); 9637 9638 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9639 opcode(0x0F, 0xB7); 9640 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9641 ins_pipe(ialu_reg); 9642 %} 9643 9644 // And Register with Immediate 9645 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9646 %{ 9647 match(Set dst (AndL dst src)); 9648 effect(KILL cr); 9649 9650 format %{ "andq $dst, $src\t# long" %} 9651 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9652 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9653 ins_pipe(ialu_reg); 9654 %} 9655 9656 // And Register with Memory 9657 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9658 %{ 9659 match(Set dst (AndL dst (LoadL src))); 9660 effect(KILL cr); 9661 9662 ins_cost(125); 9663 format %{ "andq $dst, $src\t# long" %} 9664 opcode(0x23); 9665 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9666 ins_pipe(ialu_reg_mem); 9667 %} 9668 9669 // And Memory with Register 9670 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9671 %{ 9672 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9673 effect(KILL cr); 9674 9675 ins_cost(150); 9676 format %{ "andq $dst, $src\t# long" %} 9677 opcode(0x21); /* Opcode 21 /r */ 9678 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9679 ins_pipe(ialu_mem_reg); 9680 %} 9681 9682 // And Memory with Immediate 9683 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9684 %{ 9685 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9686 effect(KILL cr); 9687 9688 ins_cost(125); 9689 format %{ "andq $dst, $src\t# long" %} 9690 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9691 ins_encode(REX_mem_wide(dst), OpcSE(src), 9692 RM_opc_mem(secondary, dst), Con8or32(src)); 9693 ins_pipe(ialu_mem_imm); 9694 %} 9695 9696 // BMI1 instructions 9697 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9698 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9699 predicate(UseBMI1Instructions); 9700 effect(KILL cr); 9701 9702 ins_cost(125); 9703 format %{ "andnq $dst, $src1, $src2" %} 9704 9705 ins_encode %{ 9706 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9707 %} 9708 ins_pipe(ialu_reg_mem); 9709 %} 9710 9711 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9712 match(Set dst (AndL (XorL src1 minus_1) src2)); 9713 predicate(UseBMI1Instructions); 9714 effect(KILL cr); 9715 9716 format %{ "andnq $dst, $src1, $src2" %} 9717 9718 ins_encode %{ 9719 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9720 %} 9721 ins_pipe(ialu_reg_mem); 9722 %} 9723 9724 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9725 match(Set dst (AndL (SubL imm_zero src) src)); 9726 predicate(UseBMI1Instructions); 9727 effect(KILL cr); 9728 9729 format %{ "blsiq $dst, $src" %} 9730 9731 ins_encode %{ 9732 __ blsiq($dst$$Register, $src$$Register); 9733 %} 9734 ins_pipe(ialu_reg); 9735 %} 9736 9737 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9738 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9739 predicate(UseBMI1Instructions); 9740 effect(KILL cr); 9741 9742 ins_cost(125); 9743 format %{ "blsiq $dst, $src" %} 9744 9745 ins_encode %{ 9746 __ blsiq($dst$$Register, $src$$Address); 9747 %} 9748 ins_pipe(ialu_reg_mem); 9749 %} 9750 9751 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9752 %{ 9753 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9754 predicate(UseBMI1Instructions); 9755 effect(KILL cr); 9756 9757 ins_cost(125); 9758 format %{ "blsmskq $dst, $src" %} 9759 9760 ins_encode %{ 9761 __ blsmskq($dst$$Register, $src$$Address); 9762 %} 9763 ins_pipe(ialu_reg_mem); 9764 %} 9765 9766 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9767 %{ 9768 match(Set dst (XorL (AddL src minus_1) src)); 9769 predicate(UseBMI1Instructions); 9770 effect(KILL cr); 9771 9772 format %{ "blsmskq $dst, $src" %} 9773 9774 ins_encode %{ 9775 __ blsmskq($dst$$Register, $src$$Register); 9776 %} 9777 9778 ins_pipe(ialu_reg); 9779 %} 9780 9781 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9782 %{ 9783 match(Set dst (AndL (AddL src minus_1) src) ); 9784 predicate(UseBMI1Instructions); 9785 effect(KILL cr); 9786 9787 format %{ "blsrq $dst, $src" %} 9788 9789 ins_encode %{ 9790 __ blsrq($dst$$Register, $src$$Register); 9791 %} 9792 9793 ins_pipe(ialu_reg); 9794 %} 9795 9796 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9797 %{ 9798 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9799 predicate(UseBMI1Instructions); 9800 effect(KILL cr); 9801 9802 ins_cost(125); 9803 format %{ "blsrq $dst, $src" %} 9804 9805 ins_encode %{ 9806 __ blsrq($dst$$Register, $src$$Address); 9807 %} 9808 9809 ins_pipe(ialu_reg); 9810 %} 9811 9812 // Or Instructions 9813 // Or Register with Register 9814 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9815 %{ 9816 match(Set dst (OrL dst src)); 9817 effect(KILL cr); 9818 9819 format %{ "orq $dst, $src\t# long" %} 9820 opcode(0x0B); 9821 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9822 ins_pipe(ialu_reg_reg); 9823 %} 9824 9825 // Use any_RegP to match R15 (TLS register) without spilling. 9826 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9827 match(Set dst (OrL dst (CastP2X src))); 9828 effect(KILL cr); 9829 9830 format %{ "orq $dst, $src\t# long" %} 9831 opcode(0x0B); 9832 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9833 ins_pipe(ialu_reg_reg); 9834 %} 9835 9836 9837 // Or Register with Immediate 9838 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9839 %{ 9840 match(Set dst (OrL dst src)); 9841 effect(KILL cr); 9842 9843 format %{ "orq $dst, $src\t# long" %} 9844 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9845 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9846 ins_pipe(ialu_reg); 9847 %} 9848 9849 // Or Register with Memory 9850 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9851 %{ 9852 match(Set dst (OrL dst (LoadL src))); 9853 effect(KILL cr); 9854 9855 ins_cost(125); 9856 format %{ "orq $dst, $src\t# long" %} 9857 opcode(0x0B); 9858 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9859 ins_pipe(ialu_reg_mem); 9860 %} 9861 9862 // Or Memory with Register 9863 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9864 %{ 9865 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9866 effect(KILL cr); 9867 9868 ins_cost(150); 9869 format %{ "orq $dst, $src\t# long" %} 9870 opcode(0x09); /* Opcode 09 /r */ 9871 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9872 ins_pipe(ialu_mem_reg); 9873 %} 9874 9875 // Or Memory with Immediate 9876 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9877 %{ 9878 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9879 effect(KILL cr); 9880 9881 ins_cost(125); 9882 format %{ "orq $dst, $src\t# long" %} 9883 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9884 ins_encode(REX_mem_wide(dst), OpcSE(src), 9885 RM_opc_mem(secondary, dst), Con8or32(src)); 9886 ins_pipe(ialu_mem_imm); 9887 %} 9888 9889 // Xor Instructions 9890 // Xor Register with Register 9891 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9892 %{ 9893 match(Set dst (XorL dst src)); 9894 effect(KILL cr); 9895 9896 format %{ "xorq $dst, $src\t# long" %} 9897 opcode(0x33); 9898 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9899 ins_pipe(ialu_reg_reg); 9900 %} 9901 9902 // Xor Register with Immediate -1 9903 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9904 match(Set dst (XorL dst imm)); 9905 9906 format %{ "notq $dst" %} 9907 ins_encode %{ 9908 __ notq($dst$$Register); 9909 %} 9910 ins_pipe(ialu_reg); 9911 %} 9912 9913 // Xor Register with Immediate 9914 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9915 %{ 9916 match(Set dst (XorL dst src)); 9917 effect(KILL cr); 9918 9919 format %{ "xorq $dst, $src\t# long" %} 9920 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9921 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9922 ins_pipe(ialu_reg); 9923 %} 9924 9925 // Xor Register with Memory 9926 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9927 %{ 9928 match(Set dst (XorL dst (LoadL src))); 9929 effect(KILL cr); 9930 9931 ins_cost(125); 9932 format %{ "xorq $dst, $src\t# long" %} 9933 opcode(0x33); 9934 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9935 ins_pipe(ialu_reg_mem); 9936 %} 9937 9938 // Xor Memory with Register 9939 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9940 %{ 9941 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9942 effect(KILL cr); 9943 9944 ins_cost(150); 9945 format %{ "xorq $dst, $src\t# long" %} 9946 opcode(0x31); /* Opcode 31 /r */ 9947 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9948 ins_pipe(ialu_mem_reg); 9949 %} 9950 9951 // Xor Memory with Immediate 9952 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9953 %{ 9954 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9955 effect(KILL cr); 9956 9957 ins_cost(125); 9958 format %{ "xorq $dst, $src\t# long" %} 9959 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9960 ins_encode(REX_mem_wide(dst), OpcSE(src), 9961 RM_opc_mem(secondary, dst), Con8or32(src)); 9962 ins_pipe(ialu_mem_imm); 9963 %} 9964 9965 // Convert Int to Boolean 9966 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9967 %{ 9968 match(Set dst (Conv2B src)); 9969 effect(KILL cr); 9970 9971 format %{ "testl $src, $src\t# ci2b\n\t" 9972 "setnz $dst\n\t" 9973 "movzbl $dst, $dst" %} 9974 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9975 setNZ_reg(dst), 9976 REX_reg_breg(dst, dst), // movzbl 9977 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9978 ins_pipe(pipe_slow); // XXX 9979 %} 9980 9981 // Convert Pointer to Boolean 9982 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9983 %{ 9984 match(Set dst (Conv2B src)); 9985 effect(KILL cr); 9986 9987 format %{ "testq $src, $src\t# cp2b\n\t" 9988 "setnz $dst\n\t" 9989 "movzbl $dst, $dst" %} 9990 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9991 setNZ_reg(dst), 9992 REX_reg_breg(dst, dst), // movzbl 9993 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9994 ins_pipe(pipe_slow); // XXX 9995 %} 9996 9997 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9998 %{ 9999 match(Set dst (CmpLTMask p q)); 10000 effect(KILL cr); 10001 10002 ins_cost(400); 10003 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10004 "setlt $dst\n\t" 10005 "movzbl $dst, $dst\n\t" 10006 "negl $dst" %} 10007 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10008 setLT_reg(dst), 10009 REX_reg_breg(dst, dst), // movzbl 10010 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10011 neg_reg(dst)); 10012 ins_pipe(pipe_slow); 10013 %} 10014 10015 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10016 %{ 10017 match(Set dst (CmpLTMask dst zero)); 10018 effect(KILL cr); 10019 10020 ins_cost(100); 10021 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10022 ins_encode %{ 10023 __ sarl($dst$$Register, 31); 10024 %} 10025 ins_pipe(ialu_reg); 10026 %} 10027 10028 /* Better to save a register than avoid a branch */ 10029 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10030 %{ 10031 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10032 effect(KILL cr); 10033 ins_cost(300); 10034 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10035 "jge done\n\t" 10036 "addl $p,$y\n" 10037 "done: " %} 10038 ins_encode %{ 10039 Register Rp = $p$$Register; 10040 Register Rq = $q$$Register; 10041 Register Ry = $y$$Register; 10042 Label done; 10043 __ subl(Rp, Rq); 10044 __ jccb(Assembler::greaterEqual, done); 10045 __ addl(Rp, Ry); 10046 __ bind(done); 10047 %} 10048 ins_pipe(pipe_cmplt); 10049 %} 10050 10051 /* Better to save a register than avoid a branch */ 10052 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10053 %{ 10054 match(Set y (AndI (CmpLTMask p q) y)); 10055 effect(KILL cr); 10056 10057 ins_cost(300); 10058 10059 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10060 "jlt done\n\t" 10061 "xorl $y, $y\n" 10062 "done: " %} 10063 ins_encode %{ 10064 Register Rp = $p$$Register; 10065 Register Rq = $q$$Register; 10066 Register Ry = $y$$Register; 10067 Label done; 10068 __ cmpl(Rp, Rq); 10069 __ jccb(Assembler::less, done); 10070 __ xorl(Ry, Ry); 10071 __ bind(done); 10072 %} 10073 ins_pipe(pipe_cmplt); 10074 %} 10075 10076 10077 //---------- FP Instructions------------------------------------------------ 10078 10079 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10080 %{ 10081 match(Set cr (CmpF src1 src2)); 10082 10083 ins_cost(145); 10084 format %{ "ucomiss $src1, $src2\n\t" 10085 "jnp,s exit\n\t" 10086 "pushfq\t# saw NaN, set CF\n\t" 10087 "andq [rsp], #0xffffff2b\n\t" 10088 "popfq\n" 10089 "exit:" %} 10090 ins_encode %{ 10091 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10092 emit_cmpfp_fixup(_masm); 10093 %} 10094 ins_pipe(pipe_slow); 10095 %} 10096 10097 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10098 match(Set cr (CmpF src1 src2)); 10099 10100 ins_cost(100); 10101 format %{ "ucomiss $src1, $src2" %} 10102 ins_encode %{ 10103 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10104 %} 10105 ins_pipe(pipe_slow); 10106 %} 10107 10108 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10109 %{ 10110 match(Set cr (CmpF src1 (LoadF src2))); 10111 10112 ins_cost(145); 10113 format %{ "ucomiss $src1, $src2\n\t" 10114 "jnp,s exit\n\t" 10115 "pushfq\t# saw NaN, set CF\n\t" 10116 "andq [rsp], #0xffffff2b\n\t" 10117 "popfq\n" 10118 "exit:" %} 10119 ins_encode %{ 10120 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10121 emit_cmpfp_fixup(_masm); 10122 %} 10123 ins_pipe(pipe_slow); 10124 %} 10125 10126 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10127 match(Set cr (CmpF src1 (LoadF src2))); 10128 10129 ins_cost(100); 10130 format %{ "ucomiss $src1, $src2" %} 10131 ins_encode %{ 10132 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10133 %} 10134 ins_pipe(pipe_slow); 10135 %} 10136 10137 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10138 match(Set cr (CmpF src con)); 10139 10140 ins_cost(145); 10141 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10142 "jnp,s exit\n\t" 10143 "pushfq\t# saw NaN, set CF\n\t" 10144 "andq [rsp], #0xffffff2b\n\t" 10145 "popfq\n" 10146 "exit:" %} 10147 ins_encode %{ 10148 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10149 emit_cmpfp_fixup(_masm); 10150 %} 10151 ins_pipe(pipe_slow); 10152 %} 10153 10154 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10155 match(Set cr (CmpF src con)); 10156 ins_cost(100); 10157 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10158 ins_encode %{ 10159 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10160 %} 10161 ins_pipe(pipe_slow); 10162 %} 10163 10164 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10165 %{ 10166 match(Set cr (CmpD src1 src2)); 10167 10168 ins_cost(145); 10169 format %{ "ucomisd $src1, $src2\n\t" 10170 "jnp,s exit\n\t" 10171 "pushfq\t# saw NaN, set CF\n\t" 10172 "andq [rsp], #0xffffff2b\n\t" 10173 "popfq\n" 10174 "exit:" %} 10175 ins_encode %{ 10176 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10177 emit_cmpfp_fixup(_masm); 10178 %} 10179 ins_pipe(pipe_slow); 10180 %} 10181 10182 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10183 match(Set cr (CmpD src1 src2)); 10184 10185 ins_cost(100); 10186 format %{ "ucomisd $src1, $src2 test" %} 10187 ins_encode %{ 10188 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10189 %} 10190 ins_pipe(pipe_slow); 10191 %} 10192 10193 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10194 %{ 10195 match(Set cr (CmpD src1 (LoadD src2))); 10196 10197 ins_cost(145); 10198 format %{ "ucomisd $src1, $src2\n\t" 10199 "jnp,s exit\n\t" 10200 "pushfq\t# saw NaN, set CF\n\t" 10201 "andq [rsp], #0xffffff2b\n\t" 10202 "popfq\n" 10203 "exit:" %} 10204 ins_encode %{ 10205 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10206 emit_cmpfp_fixup(_masm); 10207 %} 10208 ins_pipe(pipe_slow); 10209 %} 10210 10211 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10212 match(Set cr (CmpD src1 (LoadD src2))); 10213 10214 ins_cost(100); 10215 format %{ "ucomisd $src1, $src2" %} 10216 ins_encode %{ 10217 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10218 %} 10219 ins_pipe(pipe_slow); 10220 %} 10221 10222 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10223 match(Set cr (CmpD src con)); 10224 10225 ins_cost(145); 10226 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10227 "jnp,s exit\n\t" 10228 "pushfq\t# saw NaN, set CF\n\t" 10229 "andq [rsp], #0xffffff2b\n\t" 10230 "popfq\n" 10231 "exit:" %} 10232 ins_encode %{ 10233 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10234 emit_cmpfp_fixup(_masm); 10235 %} 10236 ins_pipe(pipe_slow); 10237 %} 10238 10239 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10240 match(Set cr (CmpD src con)); 10241 ins_cost(100); 10242 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10243 ins_encode %{ 10244 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10245 %} 10246 ins_pipe(pipe_slow); 10247 %} 10248 10249 // Compare into -1,0,1 10250 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10251 %{ 10252 match(Set dst (CmpF3 src1 src2)); 10253 effect(KILL cr); 10254 10255 ins_cost(275); 10256 format %{ "ucomiss $src1, $src2\n\t" 10257 "movl $dst, #-1\n\t" 10258 "jp,s done\n\t" 10259 "jb,s done\n\t" 10260 "setne $dst\n\t" 10261 "movzbl $dst, $dst\n" 10262 "done:" %} 10263 ins_encode %{ 10264 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10265 emit_cmpfp3(_masm, $dst$$Register); 10266 %} 10267 ins_pipe(pipe_slow); 10268 %} 10269 10270 // Compare into -1,0,1 10271 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10272 %{ 10273 match(Set dst (CmpF3 src1 (LoadF src2))); 10274 effect(KILL cr); 10275 10276 ins_cost(275); 10277 format %{ "ucomiss $src1, $src2\n\t" 10278 "movl $dst, #-1\n\t" 10279 "jp,s done\n\t" 10280 "jb,s done\n\t" 10281 "setne $dst\n\t" 10282 "movzbl $dst, $dst\n" 10283 "done:" %} 10284 ins_encode %{ 10285 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10286 emit_cmpfp3(_masm, $dst$$Register); 10287 %} 10288 ins_pipe(pipe_slow); 10289 %} 10290 10291 // Compare into -1,0,1 10292 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10293 match(Set dst (CmpF3 src con)); 10294 effect(KILL cr); 10295 10296 ins_cost(275); 10297 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\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($src$$XMMRegister, $constantaddress($con)); 10306 emit_cmpfp3(_masm, $dst$$Register); 10307 %} 10308 ins_pipe(pipe_slow); 10309 %} 10310 10311 // Compare into -1,0,1 10312 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10313 %{ 10314 match(Set dst (CmpD3 src1 src2)); 10315 effect(KILL cr); 10316 10317 ins_cost(275); 10318 format %{ "ucomisd $src1, $src2\n\t" 10319 "movl $dst, #-1\n\t" 10320 "jp,s done\n\t" 10321 "jb,s done\n\t" 10322 "setne $dst\n\t" 10323 "movzbl $dst, $dst\n" 10324 "done:" %} 10325 ins_encode %{ 10326 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10327 emit_cmpfp3(_masm, $dst$$Register); 10328 %} 10329 ins_pipe(pipe_slow); 10330 %} 10331 10332 // Compare into -1,0,1 10333 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10334 %{ 10335 match(Set dst (CmpD3 src1 (LoadD src2))); 10336 effect(KILL cr); 10337 10338 ins_cost(275); 10339 format %{ "ucomisd $src1, $src2\n\t" 10340 "movl $dst, #-1\n\t" 10341 "jp,s done\n\t" 10342 "jb,s done\n\t" 10343 "setne $dst\n\t" 10344 "movzbl $dst, $dst\n" 10345 "done:" %} 10346 ins_encode %{ 10347 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10348 emit_cmpfp3(_masm, $dst$$Register); 10349 %} 10350 ins_pipe(pipe_slow); 10351 %} 10352 10353 // Compare into -1,0,1 10354 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10355 match(Set dst (CmpD3 src con)); 10356 effect(KILL cr); 10357 10358 ins_cost(275); 10359 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\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($src$$XMMRegister, $constantaddress($con)); 10368 emit_cmpfp3(_masm, $dst$$Register); 10369 %} 10370 ins_pipe(pipe_slow); 10371 %} 10372 10373 //----------Arithmetic Conversion Instructions--------------------------------- 10374 10375 instruct roundFloat_nop(regF dst) 10376 %{ 10377 match(Set dst (RoundFloat dst)); 10378 10379 ins_cost(0); 10380 ins_encode(); 10381 ins_pipe(empty); 10382 %} 10383 10384 instruct roundDouble_nop(regD dst) 10385 %{ 10386 match(Set dst (RoundDouble dst)); 10387 10388 ins_cost(0); 10389 ins_encode(); 10390 ins_pipe(empty); 10391 %} 10392 10393 instruct convF2D_reg_reg(regD dst, regF src) 10394 %{ 10395 match(Set dst (ConvF2D src)); 10396 10397 format %{ "cvtss2sd $dst, $src" %} 10398 ins_encode %{ 10399 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10400 %} 10401 ins_pipe(pipe_slow); // XXX 10402 %} 10403 10404 instruct convF2D_reg_mem(regD dst, memory src) 10405 %{ 10406 match(Set dst (ConvF2D (LoadF src))); 10407 10408 format %{ "cvtss2sd $dst, $src" %} 10409 ins_encode %{ 10410 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10411 %} 10412 ins_pipe(pipe_slow); // XXX 10413 %} 10414 10415 instruct convD2F_reg_reg(regF dst, regD src) 10416 %{ 10417 match(Set dst (ConvD2F src)); 10418 10419 format %{ "cvtsd2ss $dst, $src" %} 10420 ins_encode %{ 10421 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10422 %} 10423 ins_pipe(pipe_slow); // XXX 10424 %} 10425 10426 instruct convD2F_reg_mem(regF dst, memory src) 10427 %{ 10428 match(Set dst (ConvD2F (LoadD src))); 10429 10430 format %{ "cvtsd2ss $dst, $src" %} 10431 ins_encode %{ 10432 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10433 %} 10434 ins_pipe(pipe_slow); // XXX 10435 %} 10436 10437 // XXX do mem variants 10438 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10439 %{ 10440 match(Set dst (ConvF2I src)); 10441 effect(KILL cr); 10442 10443 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10444 "cmpl $dst, #0x80000000\n\t" 10445 "jne,s done\n\t" 10446 "subq rsp, #8\n\t" 10447 "movss [rsp], $src\n\t" 10448 "call f2i_fixup\n\t" 10449 "popq $dst\n" 10450 "done: "%} 10451 ins_encode %{ 10452 Label done; 10453 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10454 __ cmpl($dst$$Register, 0x80000000); 10455 __ jccb(Assembler::notEqual, done); 10456 __ subptr(rsp, 8); 10457 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10458 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10459 __ pop($dst$$Register); 10460 __ bind(done); 10461 %} 10462 ins_pipe(pipe_slow); 10463 %} 10464 10465 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10466 %{ 10467 match(Set dst (ConvF2L src)); 10468 effect(KILL cr); 10469 10470 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10471 "cmpq $dst, [0x8000000000000000]\n\t" 10472 "jne,s done\n\t" 10473 "subq rsp, #8\n\t" 10474 "movss [rsp], $src\n\t" 10475 "call f2l_fixup\n\t" 10476 "popq $dst\n" 10477 "done: "%} 10478 ins_encode %{ 10479 Label done; 10480 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10481 __ cmp64($dst$$Register, 10482 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10483 __ jccb(Assembler::notEqual, done); 10484 __ subptr(rsp, 8); 10485 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10486 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10487 __ pop($dst$$Register); 10488 __ bind(done); 10489 %} 10490 ins_pipe(pipe_slow); 10491 %} 10492 10493 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10494 %{ 10495 match(Set dst (ConvD2I src)); 10496 effect(KILL cr); 10497 10498 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10499 "cmpl $dst, #0x80000000\n\t" 10500 "jne,s done\n\t" 10501 "subq rsp, #8\n\t" 10502 "movsd [rsp], $src\n\t" 10503 "call d2i_fixup\n\t" 10504 "popq $dst\n" 10505 "done: "%} 10506 ins_encode %{ 10507 Label done; 10508 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10509 __ cmpl($dst$$Register, 0x80000000); 10510 __ jccb(Assembler::notEqual, done); 10511 __ subptr(rsp, 8); 10512 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10513 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10514 __ pop($dst$$Register); 10515 __ bind(done); 10516 %} 10517 ins_pipe(pipe_slow); 10518 %} 10519 10520 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10521 %{ 10522 match(Set dst (ConvD2L src)); 10523 effect(KILL cr); 10524 10525 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10526 "cmpq $dst, [0x8000000000000000]\n\t" 10527 "jne,s done\n\t" 10528 "subq rsp, #8\n\t" 10529 "movsd [rsp], $src\n\t" 10530 "call d2l_fixup\n\t" 10531 "popq $dst\n" 10532 "done: "%} 10533 ins_encode %{ 10534 Label done; 10535 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10536 __ cmp64($dst$$Register, 10537 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10538 __ jccb(Assembler::notEqual, done); 10539 __ subptr(rsp, 8); 10540 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10541 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10542 __ pop($dst$$Register); 10543 __ bind(done); 10544 %} 10545 ins_pipe(pipe_slow); 10546 %} 10547 10548 instruct convI2F_reg_reg(regF dst, rRegI src) 10549 %{ 10550 predicate(!UseXmmI2F); 10551 match(Set dst (ConvI2F src)); 10552 10553 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10554 ins_encode %{ 10555 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10556 %} 10557 ins_pipe(pipe_slow); // XXX 10558 %} 10559 10560 instruct convI2F_reg_mem(regF dst, memory src) 10561 %{ 10562 match(Set dst (ConvI2F (LoadI src))); 10563 10564 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10565 ins_encode %{ 10566 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10567 %} 10568 ins_pipe(pipe_slow); // XXX 10569 %} 10570 10571 instruct convI2D_reg_reg(regD dst, rRegI src) 10572 %{ 10573 predicate(!UseXmmI2D); 10574 match(Set dst (ConvI2D src)); 10575 10576 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10577 ins_encode %{ 10578 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10579 %} 10580 ins_pipe(pipe_slow); // XXX 10581 %} 10582 10583 instruct convI2D_reg_mem(regD dst, memory src) 10584 %{ 10585 match(Set dst (ConvI2D (LoadI src))); 10586 10587 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10588 ins_encode %{ 10589 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10590 %} 10591 ins_pipe(pipe_slow); // XXX 10592 %} 10593 10594 instruct convXI2F_reg(regF dst, rRegI src) 10595 %{ 10596 predicate(UseXmmI2F); 10597 match(Set dst (ConvI2F src)); 10598 10599 format %{ "movdl $dst, $src\n\t" 10600 "cvtdq2psl $dst, $dst\t# i2f" %} 10601 ins_encode %{ 10602 __ movdl($dst$$XMMRegister, $src$$Register); 10603 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10604 %} 10605 ins_pipe(pipe_slow); // XXX 10606 %} 10607 10608 instruct convXI2D_reg(regD dst, rRegI src) 10609 %{ 10610 predicate(UseXmmI2D); 10611 match(Set dst (ConvI2D src)); 10612 10613 format %{ "movdl $dst, $src\n\t" 10614 "cvtdq2pdl $dst, $dst\t# i2d" %} 10615 ins_encode %{ 10616 __ movdl($dst$$XMMRegister, $src$$Register); 10617 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10618 %} 10619 ins_pipe(pipe_slow); // XXX 10620 %} 10621 10622 instruct convL2F_reg_reg(regF dst, rRegL src) 10623 %{ 10624 match(Set dst (ConvL2F src)); 10625 10626 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10627 ins_encode %{ 10628 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10629 %} 10630 ins_pipe(pipe_slow); // XXX 10631 %} 10632 10633 instruct convL2F_reg_mem(regF dst, memory src) 10634 %{ 10635 match(Set dst (ConvL2F (LoadL src))); 10636 10637 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10638 ins_encode %{ 10639 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10640 %} 10641 ins_pipe(pipe_slow); // XXX 10642 %} 10643 10644 instruct convL2D_reg_reg(regD dst, rRegL src) 10645 %{ 10646 match(Set dst (ConvL2D src)); 10647 10648 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10649 ins_encode %{ 10650 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10651 %} 10652 ins_pipe(pipe_slow); // XXX 10653 %} 10654 10655 instruct convL2D_reg_mem(regD dst, memory src) 10656 %{ 10657 match(Set dst (ConvL2D (LoadL src))); 10658 10659 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10660 ins_encode %{ 10661 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10662 %} 10663 ins_pipe(pipe_slow); // XXX 10664 %} 10665 10666 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10667 %{ 10668 match(Set dst (ConvI2L src)); 10669 10670 ins_cost(125); 10671 format %{ "movslq $dst, $src\t# i2l" %} 10672 ins_encode %{ 10673 __ movslq($dst$$Register, $src$$Register); 10674 %} 10675 ins_pipe(ialu_reg_reg); 10676 %} 10677 10678 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10679 // %{ 10680 // match(Set dst (ConvI2L src)); 10681 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10682 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10683 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10684 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10685 // ((const TypeNode*) n)->type()->is_long()->_lo == 10686 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10687 10688 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10689 // ins_encode(enc_copy(dst, src)); 10690 // // opcode(0x63); // needs REX.W 10691 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10692 // ins_pipe(ialu_reg_reg); 10693 // %} 10694 10695 // Zero-extend convert int to long 10696 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10697 %{ 10698 match(Set dst (AndL (ConvI2L src) mask)); 10699 10700 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10701 ins_encode %{ 10702 if ($dst$$reg != $src$$reg) { 10703 __ movl($dst$$Register, $src$$Register); 10704 } 10705 %} 10706 ins_pipe(ialu_reg_reg); 10707 %} 10708 10709 // Zero-extend convert int to long 10710 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10711 %{ 10712 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10713 10714 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10715 ins_encode %{ 10716 __ movl($dst$$Register, $src$$Address); 10717 %} 10718 ins_pipe(ialu_reg_mem); 10719 %} 10720 10721 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10722 %{ 10723 match(Set dst (AndL src mask)); 10724 10725 format %{ "movl $dst, $src\t# zero-extend long" %} 10726 ins_encode %{ 10727 __ movl($dst$$Register, $src$$Register); 10728 %} 10729 ins_pipe(ialu_reg_reg); 10730 %} 10731 10732 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10733 %{ 10734 match(Set dst (ConvL2I src)); 10735 10736 format %{ "movl $dst, $src\t# l2i" %} 10737 ins_encode %{ 10738 __ movl($dst$$Register, $src$$Register); 10739 %} 10740 ins_pipe(ialu_reg_reg); 10741 %} 10742 10743 10744 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10745 match(Set dst (MoveF2I src)); 10746 effect(DEF dst, USE src); 10747 10748 ins_cost(125); 10749 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10750 ins_encode %{ 10751 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10752 %} 10753 ins_pipe(ialu_reg_mem); 10754 %} 10755 10756 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10757 match(Set dst (MoveI2F src)); 10758 effect(DEF dst, USE src); 10759 10760 ins_cost(125); 10761 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10762 ins_encode %{ 10763 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10764 %} 10765 ins_pipe(pipe_slow); 10766 %} 10767 10768 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10769 match(Set dst (MoveD2L src)); 10770 effect(DEF dst, USE src); 10771 10772 ins_cost(125); 10773 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10774 ins_encode %{ 10775 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10776 %} 10777 ins_pipe(ialu_reg_mem); 10778 %} 10779 10780 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10781 predicate(!UseXmmLoadAndClearUpper); 10782 match(Set dst (MoveL2D src)); 10783 effect(DEF dst, USE src); 10784 10785 ins_cost(125); 10786 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10787 ins_encode %{ 10788 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10789 %} 10790 ins_pipe(pipe_slow); 10791 %} 10792 10793 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10794 predicate(UseXmmLoadAndClearUpper); 10795 match(Set dst (MoveL2D src)); 10796 effect(DEF dst, USE src); 10797 10798 ins_cost(125); 10799 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10800 ins_encode %{ 10801 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10802 %} 10803 ins_pipe(pipe_slow); 10804 %} 10805 10806 10807 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10808 match(Set dst (MoveF2I src)); 10809 effect(DEF dst, USE src); 10810 10811 ins_cost(95); // XXX 10812 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10813 ins_encode %{ 10814 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10815 %} 10816 ins_pipe(pipe_slow); 10817 %} 10818 10819 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10820 match(Set dst (MoveI2F src)); 10821 effect(DEF dst, USE src); 10822 10823 ins_cost(100); 10824 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10825 ins_encode %{ 10826 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10827 %} 10828 ins_pipe( ialu_mem_reg ); 10829 %} 10830 10831 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10832 match(Set dst (MoveD2L src)); 10833 effect(DEF dst, USE src); 10834 10835 ins_cost(95); // XXX 10836 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10837 ins_encode %{ 10838 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10839 %} 10840 ins_pipe(pipe_slow); 10841 %} 10842 10843 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10844 match(Set dst (MoveL2D src)); 10845 effect(DEF dst, USE src); 10846 10847 ins_cost(100); 10848 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10849 ins_encode %{ 10850 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10851 %} 10852 ins_pipe(ialu_mem_reg); 10853 %} 10854 10855 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10856 match(Set dst (MoveF2I src)); 10857 effect(DEF dst, USE src); 10858 ins_cost(85); 10859 format %{ "movd $dst,$src\t# MoveF2I" %} 10860 ins_encode %{ 10861 __ movdl($dst$$Register, $src$$XMMRegister); 10862 %} 10863 ins_pipe( pipe_slow ); 10864 %} 10865 10866 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10867 match(Set dst (MoveD2L src)); 10868 effect(DEF dst, USE src); 10869 ins_cost(85); 10870 format %{ "movd $dst,$src\t# MoveD2L" %} 10871 ins_encode %{ 10872 __ movdq($dst$$Register, $src$$XMMRegister); 10873 %} 10874 ins_pipe( pipe_slow ); 10875 %} 10876 10877 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10878 match(Set dst (MoveI2F src)); 10879 effect(DEF dst, USE src); 10880 ins_cost(100); 10881 format %{ "movd $dst,$src\t# MoveI2F" %} 10882 ins_encode %{ 10883 __ movdl($dst$$XMMRegister, $src$$Register); 10884 %} 10885 ins_pipe( pipe_slow ); 10886 %} 10887 10888 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10889 match(Set dst (MoveL2D src)); 10890 effect(DEF dst, USE src); 10891 ins_cost(100); 10892 format %{ "movd $dst,$src\t# MoveL2D" %} 10893 ins_encode %{ 10894 __ movdq($dst$$XMMRegister, $src$$Register); 10895 %} 10896 ins_pipe( pipe_slow ); 10897 %} 10898 10899 10900 // ======================================================================= 10901 // fast clearing of an array 10902 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10903 Universe dummy, rFlagsReg cr) 10904 %{ 10905 predicate(!((ClearArrayNode*)n)->is_large()); 10906 match(Set dummy (ClearArray cnt base)); 10907 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10908 10909 format %{ $$template 10910 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10911 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10912 $$emit$$"jg LARGE\n\t" 10913 $$emit$$"dec rcx\n\t" 10914 $$emit$$"js DONE\t# Zero length\n\t" 10915 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10916 $$emit$$"dec rcx\n\t" 10917 $$emit$$"jge LOOP\n\t" 10918 $$emit$$"jmp DONE\n\t" 10919 $$emit$$"# LARGE:\n\t" 10920 if (UseFastStosb) { 10921 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10922 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10923 } else if (UseXMMForObjInit) { 10924 $$emit$$"mov rdi,rax\n\t" 10925 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10926 $$emit$$"jmpq L_zero_64_bytes\n\t" 10927 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10928 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10929 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10930 $$emit$$"add 0x40,rax\n\t" 10931 $$emit$$"# L_zero_64_bytes:\n\t" 10932 $$emit$$"sub 0x8,rcx\n\t" 10933 $$emit$$"jge L_loop\n\t" 10934 $$emit$$"add 0x4,rcx\n\t" 10935 $$emit$$"jl L_tail\n\t" 10936 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10937 $$emit$$"add 0x20,rax\n\t" 10938 $$emit$$"sub 0x4,rcx\n\t" 10939 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10940 $$emit$$"add 0x4,rcx\n\t" 10941 $$emit$$"jle L_end\n\t" 10942 $$emit$$"dec rcx\n\t" 10943 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10944 $$emit$$"vmovq xmm0,(rax)\n\t" 10945 $$emit$$"add 0x8,rax\n\t" 10946 $$emit$$"dec rcx\n\t" 10947 $$emit$$"jge L_sloop\n\t" 10948 $$emit$$"# L_end:\n\t" 10949 } else { 10950 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10951 } 10952 $$emit$$"# DONE" 10953 %} 10954 ins_encode %{ 10955 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 10956 $tmp$$XMMRegister, false); 10957 %} 10958 ins_pipe(pipe_slow); 10959 %} 10960 10961 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10962 Universe dummy, rFlagsReg cr) 10963 %{ 10964 predicate(((ClearArrayNode*)n)->is_large()); 10965 match(Set dummy (ClearArray cnt base)); 10966 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10967 10968 format %{ $$template 10969 if (UseFastStosb) { 10970 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10971 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10972 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10973 } else if (UseXMMForObjInit) { 10974 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10975 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10976 $$emit$$"jmpq L_zero_64_bytes\n\t" 10977 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10978 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10979 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10980 $$emit$$"add 0x40,rax\n\t" 10981 $$emit$$"# L_zero_64_bytes:\n\t" 10982 $$emit$$"sub 0x8,rcx\n\t" 10983 $$emit$$"jge L_loop\n\t" 10984 $$emit$$"add 0x4,rcx\n\t" 10985 $$emit$$"jl L_tail\n\t" 10986 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10987 $$emit$$"add 0x20,rax\n\t" 10988 $$emit$$"sub 0x4,rcx\n\t" 10989 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10990 $$emit$$"add 0x4,rcx\n\t" 10991 $$emit$$"jle L_end\n\t" 10992 $$emit$$"dec rcx\n\t" 10993 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10994 $$emit$$"vmovq xmm0,(rax)\n\t" 10995 $$emit$$"add 0x8,rax\n\t" 10996 $$emit$$"dec rcx\n\t" 10997 $$emit$$"jge L_sloop\n\t" 10998 $$emit$$"# L_end:\n\t" 10999 } else { 11000 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11001 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11002 } 11003 %} 11004 ins_encode %{ 11005 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11006 $tmp$$XMMRegister, true); 11007 %} 11008 ins_pipe(pipe_slow); 11009 %} 11010 11011 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11012 rax_RegI result, regD tmp1, rFlagsReg cr) 11013 %{ 11014 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11015 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11016 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11017 11018 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11019 ins_encode %{ 11020 __ string_compare($str1$$Register, $str2$$Register, 11021 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11022 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11023 %} 11024 ins_pipe( pipe_slow ); 11025 %} 11026 11027 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11028 rax_RegI result, regD tmp1, rFlagsReg cr) 11029 %{ 11030 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11031 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11032 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11033 11034 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11035 ins_encode %{ 11036 __ string_compare($str1$$Register, $str2$$Register, 11037 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11038 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11039 %} 11040 ins_pipe( pipe_slow ); 11041 %} 11042 11043 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11044 rax_RegI result, regD tmp1, rFlagsReg cr) 11045 %{ 11046 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11047 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11048 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11049 11050 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11051 ins_encode %{ 11052 __ string_compare($str1$$Register, $str2$$Register, 11053 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11054 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11055 %} 11056 ins_pipe( pipe_slow ); 11057 %} 11058 11059 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11060 rax_RegI result, regD tmp1, rFlagsReg cr) 11061 %{ 11062 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11063 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11064 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11065 11066 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11067 ins_encode %{ 11068 __ string_compare($str2$$Register, $str1$$Register, 11069 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11070 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11071 %} 11072 ins_pipe( pipe_slow ); 11073 %} 11074 11075 // fast search of substring with known size. 11076 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11077 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11078 %{ 11079 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11080 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11081 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11082 11083 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11084 ins_encode %{ 11085 int icnt2 = (int)$int_cnt2$$constant; 11086 if (icnt2 >= 16) { 11087 // IndexOf for constant substrings with size >= 16 elements 11088 // which don't need to be loaded through stack. 11089 __ string_indexofC8($str1$$Register, $str2$$Register, 11090 $cnt1$$Register, $cnt2$$Register, 11091 icnt2, $result$$Register, 11092 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11093 } else { 11094 // Small strings are loaded through stack if they cross page boundary. 11095 __ string_indexof($str1$$Register, $str2$$Register, 11096 $cnt1$$Register, $cnt2$$Register, 11097 icnt2, $result$$Register, 11098 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11099 } 11100 %} 11101 ins_pipe( pipe_slow ); 11102 %} 11103 11104 // fast search of substring with known size. 11105 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11106 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11107 %{ 11108 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11109 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11110 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11111 11112 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11113 ins_encode %{ 11114 int icnt2 = (int)$int_cnt2$$constant; 11115 if (icnt2 >= 8) { 11116 // IndexOf for constant substrings with size >= 8 elements 11117 // which don't need to be loaded through stack. 11118 __ string_indexofC8($str1$$Register, $str2$$Register, 11119 $cnt1$$Register, $cnt2$$Register, 11120 icnt2, $result$$Register, 11121 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11122 } else { 11123 // Small strings are loaded through stack if they cross page boundary. 11124 __ string_indexof($str1$$Register, $str2$$Register, 11125 $cnt1$$Register, $cnt2$$Register, 11126 icnt2, $result$$Register, 11127 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11128 } 11129 %} 11130 ins_pipe( pipe_slow ); 11131 %} 11132 11133 // fast search of substring with known size. 11134 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11135 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11136 %{ 11137 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11138 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11139 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11140 11141 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11142 ins_encode %{ 11143 int icnt2 = (int)$int_cnt2$$constant; 11144 if (icnt2 >= 8) { 11145 // IndexOf for constant substrings with size >= 8 elements 11146 // which don't need to be loaded through stack. 11147 __ string_indexofC8($str1$$Register, $str2$$Register, 11148 $cnt1$$Register, $cnt2$$Register, 11149 icnt2, $result$$Register, 11150 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11151 } else { 11152 // Small strings are loaded through stack if they cross page boundary. 11153 __ string_indexof($str1$$Register, $str2$$Register, 11154 $cnt1$$Register, $cnt2$$Register, 11155 icnt2, $result$$Register, 11156 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11157 } 11158 %} 11159 ins_pipe( pipe_slow ); 11160 %} 11161 11162 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11163 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11164 %{ 11165 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11166 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11167 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11168 11169 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11170 ins_encode %{ 11171 __ string_indexof($str1$$Register, $str2$$Register, 11172 $cnt1$$Register, $cnt2$$Register, 11173 (-1), $result$$Register, 11174 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11175 %} 11176 ins_pipe( pipe_slow ); 11177 %} 11178 11179 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11180 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11181 %{ 11182 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11183 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11184 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11185 11186 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11187 ins_encode %{ 11188 __ string_indexof($str1$$Register, $str2$$Register, 11189 $cnt1$$Register, $cnt2$$Register, 11190 (-1), $result$$Register, 11191 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11192 %} 11193 ins_pipe( pipe_slow ); 11194 %} 11195 11196 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11197 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11198 %{ 11199 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11200 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11201 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11202 11203 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11204 ins_encode %{ 11205 __ string_indexof($str1$$Register, $str2$$Register, 11206 $cnt1$$Register, $cnt2$$Register, 11207 (-1), $result$$Register, 11208 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11209 %} 11210 ins_pipe( pipe_slow ); 11211 %} 11212 11213 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11214 rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr) 11215 %{ 11216 predicate(UseSSE42Intrinsics); 11217 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11218 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11219 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11220 ins_encode %{ 11221 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11222 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11223 %} 11224 ins_pipe( pipe_slow ); 11225 %} 11226 11227 // fast string equals 11228 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11229 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11230 %{ 11231 match(Set result (StrEquals (Binary str1 str2) cnt)); 11232 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11233 11234 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11235 ins_encode %{ 11236 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11237 $cnt$$Register, $result$$Register, $tmp3$$Register, 11238 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11239 %} 11240 ins_pipe( pipe_slow ); 11241 %} 11242 11243 // fast array equals 11244 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11245 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11246 %{ 11247 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11248 match(Set result (AryEq ary1 ary2)); 11249 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11250 11251 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11252 ins_encode %{ 11253 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11254 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11255 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11256 %} 11257 ins_pipe( pipe_slow ); 11258 %} 11259 11260 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11261 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11262 %{ 11263 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11264 match(Set result (AryEq ary1 ary2)); 11265 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11266 11267 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11268 ins_encode %{ 11269 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11270 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11271 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11272 %} 11273 ins_pipe( pipe_slow ); 11274 %} 11275 11276 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11277 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11278 %{ 11279 match(Set result (HasNegatives ary1 len)); 11280 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11281 11282 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11283 ins_encode %{ 11284 __ has_negatives($ary1$$Register, $len$$Register, 11285 $result$$Register, $tmp3$$Register, 11286 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11287 %} 11288 ins_pipe( pipe_slow ); 11289 %} 11290 11291 // fast char[] to byte[] compression 11292 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11293 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11294 match(Set result (StrCompressedCopy src (Binary dst len))); 11295 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11296 11297 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11298 ins_encode %{ 11299 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11300 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11301 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11302 %} 11303 ins_pipe( pipe_slow ); 11304 %} 11305 11306 // fast byte[] to char[] inflation 11307 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11308 regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11309 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11310 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11311 11312 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11313 ins_encode %{ 11314 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11315 $tmp1$$XMMRegister, $tmp2$$Register); 11316 %} 11317 ins_pipe( pipe_slow ); 11318 %} 11319 11320 // encode char[] to byte[] in ISO_8859_1 11321 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11322 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11323 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11324 match(Set result (EncodeISOArray src (Binary dst len))); 11325 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11326 11327 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11328 ins_encode %{ 11329 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11330 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11331 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11332 %} 11333 ins_pipe( pipe_slow ); 11334 %} 11335 11336 //----------Overflow Math Instructions----------------------------------------- 11337 11338 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11339 %{ 11340 match(Set cr (OverflowAddI op1 op2)); 11341 effect(DEF cr, USE_KILL op1, USE op2); 11342 11343 format %{ "addl $op1, $op2\t# overflow check int" %} 11344 11345 ins_encode %{ 11346 __ addl($op1$$Register, $op2$$Register); 11347 %} 11348 ins_pipe(ialu_reg_reg); 11349 %} 11350 11351 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11352 %{ 11353 match(Set cr (OverflowAddI op1 op2)); 11354 effect(DEF cr, USE_KILL op1, USE op2); 11355 11356 format %{ "addl $op1, $op2\t# overflow check int" %} 11357 11358 ins_encode %{ 11359 __ addl($op1$$Register, $op2$$constant); 11360 %} 11361 ins_pipe(ialu_reg_reg); 11362 %} 11363 11364 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11365 %{ 11366 match(Set cr (OverflowAddL op1 op2)); 11367 effect(DEF cr, USE_KILL op1, USE op2); 11368 11369 format %{ "addq $op1, $op2\t# overflow check long" %} 11370 ins_encode %{ 11371 __ addq($op1$$Register, $op2$$Register); 11372 %} 11373 ins_pipe(ialu_reg_reg); 11374 %} 11375 11376 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11377 %{ 11378 match(Set cr (OverflowAddL op1 op2)); 11379 effect(DEF cr, USE_KILL op1, USE op2); 11380 11381 format %{ "addq $op1, $op2\t# overflow check long" %} 11382 ins_encode %{ 11383 __ addq($op1$$Register, $op2$$constant); 11384 %} 11385 ins_pipe(ialu_reg_reg); 11386 %} 11387 11388 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11389 %{ 11390 match(Set cr (OverflowSubI op1 op2)); 11391 11392 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11393 ins_encode %{ 11394 __ cmpl($op1$$Register, $op2$$Register); 11395 %} 11396 ins_pipe(ialu_reg_reg); 11397 %} 11398 11399 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11400 %{ 11401 match(Set cr (OverflowSubI op1 op2)); 11402 11403 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11404 ins_encode %{ 11405 __ cmpl($op1$$Register, $op2$$constant); 11406 %} 11407 ins_pipe(ialu_reg_reg); 11408 %} 11409 11410 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11411 %{ 11412 match(Set cr (OverflowSubL op1 op2)); 11413 11414 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11415 ins_encode %{ 11416 __ cmpq($op1$$Register, $op2$$Register); 11417 %} 11418 ins_pipe(ialu_reg_reg); 11419 %} 11420 11421 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11422 %{ 11423 match(Set cr (OverflowSubL op1 op2)); 11424 11425 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11426 ins_encode %{ 11427 __ cmpq($op1$$Register, $op2$$constant); 11428 %} 11429 ins_pipe(ialu_reg_reg); 11430 %} 11431 11432 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11433 %{ 11434 match(Set cr (OverflowSubI zero op2)); 11435 effect(DEF cr, USE_KILL op2); 11436 11437 format %{ "negl $op2\t# overflow check int" %} 11438 ins_encode %{ 11439 __ negl($op2$$Register); 11440 %} 11441 ins_pipe(ialu_reg_reg); 11442 %} 11443 11444 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11445 %{ 11446 match(Set cr (OverflowSubL zero op2)); 11447 effect(DEF cr, USE_KILL op2); 11448 11449 format %{ "negq $op2\t# overflow check long" %} 11450 ins_encode %{ 11451 __ negq($op2$$Register); 11452 %} 11453 ins_pipe(ialu_reg_reg); 11454 %} 11455 11456 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11457 %{ 11458 match(Set cr (OverflowMulI op1 op2)); 11459 effect(DEF cr, USE_KILL op1, USE op2); 11460 11461 format %{ "imull $op1, $op2\t# overflow check int" %} 11462 ins_encode %{ 11463 __ imull($op1$$Register, $op2$$Register); 11464 %} 11465 ins_pipe(ialu_reg_reg_alu0); 11466 %} 11467 11468 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11469 %{ 11470 match(Set cr (OverflowMulI op1 op2)); 11471 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11472 11473 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11474 ins_encode %{ 11475 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11476 %} 11477 ins_pipe(ialu_reg_reg_alu0); 11478 %} 11479 11480 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11481 %{ 11482 match(Set cr (OverflowMulL op1 op2)); 11483 effect(DEF cr, USE_KILL op1, USE op2); 11484 11485 format %{ "imulq $op1, $op2\t# overflow check long" %} 11486 ins_encode %{ 11487 __ imulq($op1$$Register, $op2$$Register); 11488 %} 11489 ins_pipe(ialu_reg_reg_alu0); 11490 %} 11491 11492 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11493 %{ 11494 match(Set cr (OverflowMulL op1 op2)); 11495 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11496 11497 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11498 ins_encode %{ 11499 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11500 %} 11501 ins_pipe(ialu_reg_reg_alu0); 11502 %} 11503 11504 11505 //----------Control Flow Instructions------------------------------------------ 11506 // Signed compare Instructions 11507 11508 // XXX more variants!! 11509 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11510 %{ 11511 match(Set cr (CmpI op1 op2)); 11512 effect(DEF cr, USE op1, USE op2); 11513 11514 format %{ "cmpl $op1, $op2" %} 11515 opcode(0x3B); /* Opcode 3B /r */ 11516 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11517 ins_pipe(ialu_cr_reg_reg); 11518 %} 11519 11520 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11521 %{ 11522 match(Set cr (CmpI op1 op2)); 11523 11524 format %{ "cmpl $op1, $op2" %} 11525 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11526 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11527 ins_pipe(ialu_cr_reg_imm); 11528 %} 11529 11530 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11531 %{ 11532 match(Set cr (CmpI op1 (LoadI op2))); 11533 11534 ins_cost(500); // XXX 11535 format %{ "cmpl $op1, $op2" %} 11536 opcode(0x3B); /* Opcode 3B /r */ 11537 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11538 ins_pipe(ialu_cr_reg_mem); 11539 %} 11540 11541 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11542 %{ 11543 match(Set cr (CmpI src zero)); 11544 11545 format %{ "testl $src, $src" %} 11546 opcode(0x85); 11547 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11548 ins_pipe(ialu_cr_reg_imm); 11549 %} 11550 11551 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11552 %{ 11553 match(Set cr (CmpI (AndI src con) zero)); 11554 11555 format %{ "testl $src, $con" %} 11556 opcode(0xF7, 0x00); 11557 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11558 ins_pipe(ialu_cr_reg_imm); 11559 %} 11560 11561 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11562 %{ 11563 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11564 11565 format %{ "testl $src, $mem" %} 11566 opcode(0x85); 11567 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11568 ins_pipe(ialu_cr_reg_mem); 11569 %} 11570 11571 // Unsigned compare Instructions; really, same as signed except they 11572 // produce an rFlagsRegU instead of rFlagsReg. 11573 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11574 %{ 11575 match(Set cr (CmpU op1 op2)); 11576 11577 format %{ "cmpl $op1, $op2\t# unsigned" %} 11578 opcode(0x3B); /* Opcode 3B /r */ 11579 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11580 ins_pipe(ialu_cr_reg_reg); 11581 %} 11582 11583 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11584 %{ 11585 match(Set cr (CmpU op1 op2)); 11586 11587 format %{ "cmpl $op1, $op2\t# unsigned" %} 11588 opcode(0x81,0x07); /* Opcode 81 /7 */ 11589 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11590 ins_pipe(ialu_cr_reg_imm); 11591 %} 11592 11593 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11594 %{ 11595 match(Set cr (CmpU op1 (LoadI op2))); 11596 11597 ins_cost(500); // XXX 11598 format %{ "cmpl $op1, $op2\t# unsigned" %} 11599 opcode(0x3B); /* Opcode 3B /r */ 11600 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11601 ins_pipe(ialu_cr_reg_mem); 11602 %} 11603 11604 // // // Cisc-spilled version of cmpU_rReg 11605 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11606 // //%{ 11607 // // match(Set cr (CmpU (LoadI op1) op2)); 11608 // // 11609 // // format %{ "CMPu $op1,$op2" %} 11610 // // ins_cost(500); 11611 // // opcode(0x39); /* Opcode 39 /r */ 11612 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11613 // //%} 11614 11615 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11616 %{ 11617 match(Set cr (CmpU src zero)); 11618 11619 format %{ "testl $src, $src\t# unsigned" %} 11620 opcode(0x85); 11621 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11622 ins_pipe(ialu_cr_reg_imm); 11623 %} 11624 11625 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11626 %{ 11627 match(Set cr (CmpP op1 op2)); 11628 11629 format %{ "cmpq $op1, $op2\t# ptr" %} 11630 opcode(0x3B); /* Opcode 3B /r */ 11631 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11632 ins_pipe(ialu_cr_reg_reg); 11633 %} 11634 11635 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11636 %{ 11637 match(Set cr (CmpP op1 (LoadP op2))); 11638 11639 ins_cost(500); // XXX 11640 format %{ "cmpq $op1, $op2\t# ptr" %} 11641 opcode(0x3B); /* Opcode 3B /r */ 11642 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11643 ins_pipe(ialu_cr_reg_mem); 11644 %} 11645 11646 // // // Cisc-spilled version of cmpP_rReg 11647 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11648 // //%{ 11649 // // match(Set cr (CmpP (LoadP op1) op2)); 11650 // // 11651 // // format %{ "CMPu $op1,$op2" %} 11652 // // ins_cost(500); 11653 // // opcode(0x39); /* Opcode 39 /r */ 11654 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11655 // //%} 11656 11657 // XXX this is generalized by compP_rReg_mem??? 11658 // Compare raw pointer (used in out-of-heap check). 11659 // Only works because non-oop pointers must be raw pointers 11660 // and raw pointers have no anti-dependencies. 11661 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11662 %{ 11663 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11664 match(Set cr (CmpP op1 (LoadP op2))); 11665 11666 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11667 opcode(0x3B); /* Opcode 3B /r */ 11668 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11669 ins_pipe(ialu_cr_reg_mem); 11670 %} 11671 11672 // This will generate a signed flags result. This should be OK since 11673 // any compare to a zero should be eq/neq. 11674 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11675 %{ 11676 match(Set cr (CmpP src zero)); 11677 11678 format %{ "testq $src, $src\t# ptr" %} 11679 opcode(0x85); 11680 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11681 ins_pipe(ialu_cr_reg_imm); 11682 %} 11683 11684 // This will generate a signed flags result. This should be OK since 11685 // any compare to a zero should be eq/neq. 11686 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11687 %{ 11688 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11689 match(Set cr (CmpP (LoadP op) zero)); 11690 11691 ins_cost(500); // XXX 11692 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11693 opcode(0xF7); /* Opcode F7 /0 */ 11694 ins_encode(REX_mem_wide(op), 11695 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11696 ins_pipe(ialu_cr_reg_imm); 11697 %} 11698 11699 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11700 %{ 11701 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11702 match(Set cr (CmpP (LoadP mem) zero)); 11703 11704 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11705 ins_encode %{ 11706 __ cmpq(r12, $mem$$Address); 11707 %} 11708 ins_pipe(ialu_cr_reg_mem); 11709 %} 11710 11711 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11712 %{ 11713 match(Set cr (CmpN op1 op2)); 11714 11715 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11716 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11717 ins_pipe(ialu_cr_reg_reg); 11718 %} 11719 11720 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11721 %{ 11722 match(Set cr (CmpN src (LoadN mem))); 11723 11724 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11725 ins_encode %{ 11726 __ cmpl($src$$Register, $mem$$Address); 11727 %} 11728 ins_pipe(ialu_cr_reg_mem); 11729 %} 11730 11731 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11732 match(Set cr (CmpN op1 op2)); 11733 11734 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11735 ins_encode %{ 11736 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11737 %} 11738 ins_pipe(ialu_cr_reg_imm); 11739 %} 11740 11741 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11742 %{ 11743 match(Set cr (CmpN src (LoadN mem))); 11744 11745 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11746 ins_encode %{ 11747 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11748 %} 11749 ins_pipe(ialu_cr_reg_mem); 11750 %} 11751 11752 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11753 match(Set cr (CmpN op1 op2)); 11754 11755 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11756 ins_encode %{ 11757 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11758 %} 11759 ins_pipe(ialu_cr_reg_imm); 11760 %} 11761 11762 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11763 %{ 11764 match(Set cr (CmpN src (LoadNKlass mem))); 11765 11766 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11767 ins_encode %{ 11768 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11769 %} 11770 ins_pipe(ialu_cr_reg_mem); 11771 %} 11772 11773 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11774 match(Set cr (CmpN src zero)); 11775 11776 format %{ "testl $src, $src\t# compressed ptr" %} 11777 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11778 ins_pipe(ialu_cr_reg_imm); 11779 %} 11780 11781 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11782 %{ 11783 predicate(Universe::narrow_oop_base() != NULL); 11784 match(Set cr (CmpN (LoadN mem) zero)); 11785 11786 ins_cost(500); // XXX 11787 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11788 ins_encode %{ 11789 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11790 %} 11791 ins_pipe(ialu_cr_reg_mem); 11792 %} 11793 11794 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11795 %{ 11796 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11797 match(Set cr (CmpN (LoadN mem) zero)); 11798 11799 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11800 ins_encode %{ 11801 __ cmpl(r12, $mem$$Address); 11802 %} 11803 ins_pipe(ialu_cr_reg_mem); 11804 %} 11805 11806 // Yanked all unsigned pointer compare operations. 11807 // Pointer compares are done with CmpP which is already unsigned. 11808 11809 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11810 %{ 11811 match(Set cr (CmpL op1 op2)); 11812 11813 format %{ "cmpq $op1, $op2" %} 11814 opcode(0x3B); /* Opcode 3B /r */ 11815 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11816 ins_pipe(ialu_cr_reg_reg); 11817 %} 11818 11819 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11820 %{ 11821 match(Set cr (CmpL op1 op2)); 11822 11823 format %{ "cmpq $op1, $op2" %} 11824 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11825 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11826 ins_pipe(ialu_cr_reg_imm); 11827 %} 11828 11829 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11830 %{ 11831 match(Set cr (CmpL op1 (LoadL op2))); 11832 11833 format %{ "cmpq $op1, $op2" %} 11834 opcode(0x3B); /* Opcode 3B /r */ 11835 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11836 ins_pipe(ialu_cr_reg_mem); 11837 %} 11838 11839 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11840 %{ 11841 match(Set cr (CmpL src zero)); 11842 11843 format %{ "testq $src, $src" %} 11844 opcode(0x85); 11845 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11846 ins_pipe(ialu_cr_reg_imm); 11847 %} 11848 11849 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11850 %{ 11851 match(Set cr (CmpL (AndL src con) zero)); 11852 11853 format %{ "testq $src, $con\t# long" %} 11854 opcode(0xF7, 0x00); 11855 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11856 ins_pipe(ialu_cr_reg_imm); 11857 %} 11858 11859 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11860 %{ 11861 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11862 11863 format %{ "testq $src, $mem" %} 11864 opcode(0x85); 11865 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11866 ins_pipe(ialu_cr_reg_mem); 11867 %} 11868 11869 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11870 %{ 11871 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11872 11873 format %{ "testq $src, $mem" %} 11874 opcode(0x85); 11875 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11876 ins_pipe(ialu_cr_reg_mem); 11877 %} 11878 11879 // Manifest a CmpL result in an integer register. Very painful. 11880 // This is the test to avoid. 11881 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11882 %{ 11883 match(Set dst (CmpL3 src1 src2)); 11884 effect(KILL flags); 11885 11886 ins_cost(275); // XXX 11887 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11888 "movl $dst, -1\n\t" 11889 "jl,s done\n\t" 11890 "setne $dst\n\t" 11891 "movzbl $dst, $dst\n\t" 11892 "done:" %} 11893 ins_encode(cmpl3_flag(src1, src2, dst)); 11894 ins_pipe(pipe_slow); 11895 %} 11896 11897 // Unsigned long compare Instructions; really, same as signed long except they 11898 // produce an rFlagsRegU instead of rFlagsReg. 11899 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11900 %{ 11901 match(Set cr (CmpUL op1 op2)); 11902 11903 format %{ "cmpq $op1, $op2\t# unsigned" %} 11904 opcode(0x3B); /* Opcode 3B /r */ 11905 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11906 ins_pipe(ialu_cr_reg_reg); 11907 %} 11908 11909 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11910 %{ 11911 match(Set cr (CmpUL op1 op2)); 11912 11913 format %{ "cmpq $op1, $op2\t# unsigned" %} 11914 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11915 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11916 ins_pipe(ialu_cr_reg_imm); 11917 %} 11918 11919 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11920 %{ 11921 match(Set cr (CmpUL op1 (LoadL op2))); 11922 11923 format %{ "cmpq $op1, $op2\t# unsigned" %} 11924 opcode(0x3B); /* Opcode 3B /r */ 11925 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11926 ins_pipe(ialu_cr_reg_mem); 11927 %} 11928 11929 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11930 %{ 11931 match(Set cr (CmpUL src zero)); 11932 11933 format %{ "testq $src, $src\t# unsigned" %} 11934 opcode(0x85); 11935 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11936 ins_pipe(ialu_cr_reg_imm); 11937 %} 11938 11939 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11940 %{ 11941 match(Set cr (CmpI (LoadB mem) imm)); 11942 11943 ins_cost(125); 11944 format %{ "cmpb $mem, $imm" %} 11945 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11946 ins_pipe(ialu_cr_reg_mem); 11947 %} 11948 11949 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 11950 %{ 11951 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 11952 11953 ins_cost(125); 11954 format %{ "testb $mem, $imm" %} 11955 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 11956 ins_pipe(ialu_cr_reg_mem); 11957 %} 11958 11959 //----------Max and Min-------------------------------------------------------- 11960 // Min Instructions 11961 11962 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11963 %{ 11964 effect(USE_DEF dst, USE src, USE cr); 11965 11966 format %{ "cmovlgt $dst, $src\t# min" %} 11967 opcode(0x0F, 0x4F); 11968 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11969 ins_pipe(pipe_cmov_reg); 11970 %} 11971 11972 11973 instruct minI_rReg(rRegI dst, rRegI src) 11974 %{ 11975 match(Set dst (MinI dst src)); 11976 11977 ins_cost(200); 11978 expand %{ 11979 rFlagsReg cr; 11980 compI_rReg(cr, dst, src); 11981 cmovI_reg_g(dst, src, cr); 11982 %} 11983 %} 11984 11985 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11986 %{ 11987 effect(USE_DEF dst, USE src, USE cr); 11988 11989 format %{ "cmovllt $dst, $src\t# max" %} 11990 opcode(0x0F, 0x4C); 11991 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11992 ins_pipe(pipe_cmov_reg); 11993 %} 11994 11995 11996 instruct maxI_rReg(rRegI dst, rRegI src) 11997 %{ 11998 match(Set dst (MaxI dst src)); 11999 12000 ins_cost(200); 12001 expand %{ 12002 rFlagsReg cr; 12003 compI_rReg(cr, dst, src); 12004 cmovI_reg_l(dst, src, cr); 12005 %} 12006 %} 12007 12008 // ============================================================================ 12009 // Branch Instructions 12010 12011 // Jump Direct - Label defines a relative address from JMP+1 12012 instruct jmpDir(label labl) 12013 %{ 12014 match(Goto); 12015 effect(USE labl); 12016 12017 ins_cost(300); 12018 format %{ "jmp $labl" %} 12019 size(5); 12020 ins_encode %{ 12021 Label* L = $labl$$label; 12022 __ jmp(*L, false); // Always long jump 12023 %} 12024 ins_pipe(pipe_jmp); 12025 %} 12026 12027 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12028 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12029 %{ 12030 match(If cop cr); 12031 effect(USE labl); 12032 12033 ins_cost(300); 12034 format %{ "j$cop $labl" %} 12035 size(6); 12036 ins_encode %{ 12037 Label* L = $labl$$label; 12038 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12039 %} 12040 ins_pipe(pipe_jcc); 12041 %} 12042 12043 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12044 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12045 %{ 12046 predicate(!n->has_vector_mask_set()); 12047 match(CountedLoopEnd cop cr); 12048 effect(USE labl); 12049 12050 ins_cost(300); 12051 format %{ "j$cop $labl\t# loop end" %} 12052 size(6); 12053 ins_encode %{ 12054 Label* L = $labl$$label; 12055 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12056 %} 12057 ins_pipe(pipe_jcc); 12058 %} 12059 12060 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12061 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12062 predicate(!n->has_vector_mask_set()); 12063 match(CountedLoopEnd cop cmp); 12064 effect(USE labl); 12065 12066 ins_cost(300); 12067 format %{ "j$cop,u $labl\t# loop end" %} 12068 size(6); 12069 ins_encode %{ 12070 Label* L = $labl$$label; 12071 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12072 %} 12073 ins_pipe(pipe_jcc); 12074 %} 12075 12076 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12077 predicate(!n->has_vector_mask_set()); 12078 match(CountedLoopEnd cop cmp); 12079 effect(USE labl); 12080 12081 ins_cost(200); 12082 format %{ "j$cop,u $labl\t# loop end" %} 12083 size(6); 12084 ins_encode %{ 12085 Label* L = $labl$$label; 12086 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12087 %} 12088 ins_pipe(pipe_jcc); 12089 %} 12090 12091 // mask version 12092 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12093 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12094 %{ 12095 predicate(n->has_vector_mask_set()); 12096 match(CountedLoopEnd cop cr); 12097 effect(USE labl); 12098 12099 ins_cost(400); 12100 format %{ "j$cop $labl\t# loop end\n\t" 12101 "restorevectmask \t# vector mask restore for loops" %} 12102 size(10); 12103 ins_encode %{ 12104 Label* L = $labl$$label; 12105 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12106 __ restorevectmask(); 12107 %} 12108 ins_pipe(pipe_jcc); 12109 %} 12110 12111 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12112 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12113 predicate(n->has_vector_mask_set()); 12114 match(CountedLoopEnd cop cmp); 12115 effect(USE labl); 12116 12117 ins_cost(400); 12118 format %{ "j$cop,u $labl\t# loop end\n\t" 12119 "restorevectmask \t# vector mask restore for loops" %} 12120 size(10); 12121 ins_encode %{ 12122 Label* L = $labl$$label; 12123 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12124 __ restorevectmask(); 12125 %} 12126 ins_pipe(pipe_jcc); 12127 %} 12128 12129 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12130 predicate(n->has_vector_mask_set()); 12131 match(CountedLoopEnd cop cmp); 12132 effect(USE labl); 12133 12134 ins_cost(300); 12135 format %{ "j$cop,u $labl\t# loop end\n\t" 12136 "restorevectmask \t# vector mask restore for loops" %} 12137 size(10); 12138 ins_encode %{ 12139 Label* L = $labl$$label; 12140 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12141 __ restorevectmask(); 12142 %} 12143 ins_pipe(pipe_jcc); 12144 %} 12145 12146 // Jump Direct Conditional - using unsigned comparison 12147 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12148 match(If cop cmp); 12149 effect(USE labl); 12150 12151 ins_cost(300); 12152 format %{ "j$cop,u $labl" %} 12153 size(6); 12154 ins_encode %{ 12155 Label* L = $labl$$label; 12156 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12157 %} 12158 ins_pipe(pipe_jcc); 12159 %} 12160 12161 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12162 match(If cop cmp); 12163 effect(USE labl); 12164 12165 ins_cost(200); 12166 format %{ "j$cop,u $labl" %} 12167 size(6); 12168 ins_encode %{ 12169 Label* L = $labl$$label; 12170 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12171 %} 12172 ins_pipe(pipe_jcc); 12173 %} 12174 12175 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12176 match(If cop cmp); 12177 effect(USE labl); 12178 12179 ins_cost(200); 12180 format %{ $$template 12181 if ($cop$$cmpcode == Assembler::notEqual) { 12182 $$emit$$"jp,u $labl\n\t" 12183 $$emit$$"j$cop,u $labl" 12184 } else { 12185 $$emit$$"jp,u done\n\t" 12186 $$emit$$"j$cop,u $labl\n\t" 12187 $$emit$$"done:" 12188 } 12189 %} 12190 ins_encode %{ 12191 Label* l = $labl$$label; 12192 if ($cop$$cmpcode == Assembler::notEqual) { 12193 __ jcc(Assembler::parity, *l, false); 12194 __ jcc(Assembler::notEqual, *l, false); 12195 } else if ($cop$$cmpcode == Assembler::equal) { 12196 Label done; 12197 __ jccb(Assembler::parity, done); 12198 __ jcc(Assembler::equal, *l, false); 12199 __ bind(done); 12200 } else { 12201 ShouldNotReachHere(); 12202 } 12203 %} 12204 ins_pipe(pipe_jcc); 12205 %} 12206 12207 // ============================================================================ 12208 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12209 // superklass array for an instance of the superklass. Set a hidden 12210 // internal cache on a hit (cache is checked with exposed code in 12211 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12212 // encoding ALSO sets flags. 12213 12214 instruct partialSubtypeCheck(rdi_RegP result, 12215 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12216 rFlagsReg cr) 12217 %{ 12218 match(Set result (PartialSubtypeCheck sub super)); 12219 effect(KILL rcx, KILL cr); 12220 12221 ins_cost(1100); // slightly larger than the next version 12222 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12223 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12224 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12225 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12226 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12227 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12228 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12229 "miss:\t" %} 12230 12231 opcode(0x1); // Force a XOR of RDI 12232 ins_encode(enc_PartialSubtypeCheck()); 12233 ins_pipe(pipe_slow); 12234 %} 12235 12236 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12237 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12238 immP0 zero, 12239 rdi_RegP result) 12240 %{ 12241 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12242 effect(KILL rcx, KILL result); 12243 12244 ins_cost(1000); 12245 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12246 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12247 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12248 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12249 "jne,s miss\t\t# Missed: flags nz\n\t" 12250 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12251 "miss:\t" %} 12252 12253 opcode(0x0); // No need to XOR RDI 12254 ins_encode(enc_PartialSubtypeCheck()); 12255 ins_pipe(pipe_slow); 12256 %} 12257 12258 // ============================================================================ 12259 // Branch Instructions -- short offset versions 12260 // 12261 // These instructions are used to replace jumps of a long offset (the default 12262 // match) with jumps of a shorter offset. These instructions are all tagged 12263 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12264 // match rules in general matching. Instead, the ADLC generates a conversion 12265 // method in the MachNode which can be used to do in-place replacement of the 12266 // long variant with the shorter variant. The compiler will determine if a 12267 // branch can be taken by the is_short_branch_offset() predicate in the machine 12268 // specific code section of the file. 12269 12270 // Jump Direct - Label defines a relative address from JMP+1 12271 instruct jmpDir_short(label labl) %{ 12272 match(Goto); 12273 effect(USE labl); 12274 12275 ins_cost(300); 12276 format %{ "jmp,s $labl" %} 12277 size(2); 12278 ins_encode %{ 12279 Label* L = $labl$$label; 12280 __ jmpb(*L); 12281 %} 12282 ins_pipe(pipe_jmp); 12283 ins_short_branch(1); 12284 %} 12285 12286 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12287 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12288 match(If cop cr); 12289 effect(USE labl); 12290 12291 ins_cost(300); 12292 format %{ "j$cop,s $labl" %} 12293 size(2); 12294 ins_encode %{ 12295 Label* L = $labl$$label; 12296 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12297 %} 12298 ins_pipe(pipe_jcc); 12299 ins_short_branch(1); 12300 %} 12301 12302 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12303 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12304 match(CountedLoopEnd cop cr); 12305 effect(USE labl); 12306 12307 ins_cost(300); 12308 format %{ "j$cop,s $labl\t# loop end" %} 12309 size(2); 12310 ins_encode %{ 12311 Label* L = $labl$$label; 12312 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12313 %} 12314 ins_pipe(pipe_jcc); 12315 ins_short_branch(1); 12316 %} 12317 12318 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12319 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12320 match(CountedLoopEnd cop cmp); 12321 effect(USE labl); 12322 12323 ins_cost(300); 12324 format %{ "j$cop,us $labl\t# loop end" %} 12325 size(2); 12326 ins_encode %{ 12327 Label* L = $labl$$label; 12328 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12329 %} 12330 ins_pipe(pipe_jcc); 12331 ins_short_branch(1); 12332 %} 12333 12334 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12335 match(CountedLoopEnd cop cmp); 12336 effect(USE labl); 12337 12338 ins_cost(300); 12339 format %{ "j$cop,us $labl\t# loop end" %} 12340 size(2); 12341 ins_encode %{ 12342 Label* L = $labl$$label; 12343 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12344 %} 12345 ins_pipe(pipe_jcc); 12346 ins_short_branch(1); 12347 %} 12348 12349 // Jump Direct Conditional - using unsigned comparison 12350 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12351 match(If cop cmp); 12352 effect(USE labl); 12353 12354 ins_cost(300); 12355 format %{ "j$cop,us $labl" %} 12356 size(2); 12357 ins_encode %{ 12358 Label* L = $labl$$label; 12359 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12360 %} 12361 ins_pipe(pipe_jcc); 12362 ins_short_branch(1); 12363 %} 12364 12365 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12366 match(If cop cmp); 12367 effect(USE labl); 12368 12369 ins_cost(300); 12370 format %{ "j$cop,us $labl" %} 12371 size(2); 12372 ins_encode %{ 12373 Label* L = $labl$$label; 12374 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12375 %} 12376 ins_pipe(pipe_jcc); 12377 ins_short_branch(1); 12378 %} 12379 12380 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12381 match(If cop cmp); 12382 effect(USE labl); 12383 12384 ins_cost(300); 12385 format %{ $$template 12386 if ($cop$$cmpcode == Assembler::notEqual) { 12387 $$emit$$"jp,u,s $labl\n\t" 12388 $$emit$$"j$cop,u,s $labl" 12389 } else { 12390 $$emit$$"jp,u,s done\n\t" 12391 $$emit$$"j$cop,u,s $labl\n\t" 12392 $$emit$$"done:" 12393 } 12394 %} 12395 size(4); 12396 ins_encode %{ 12397 Label* l = $labl$$label; 12398 if ($cop$$cmpcode == Assembler::notEqual) { 12399 __ jccb(Assembler::parity, *l); 12400 __ jccb(Assembler::notEqual, *l); 12401 } else if ($cop$$cmpcode == Assembler::equal) { 12402 Label done; 12403 __ jccb(Assembler::parity, done); 12404 __ jccb(Assembler::equal, *l); 12405 __ bind(done); 12406 } else { 12407 ShouldNotReachHere(); 12408 } 12409 %} 12410 ins_pipe(pipe_jcc); 12411 ins_short_branch(1); 12412 %} 12413 12414 // ============================================================================ 12415 // inlined locking and unlocking 12416 12417 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12418 predicate(Compile::current()->use_rtm()); 12419 match(Set cr (FastLock object box)); 12420 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12421 ins_cost(300); 12422 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12423 ins_encode %{ 12424 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12425 $scr$$Register, $cx1$$Register, $cx2$$Register, 12426 _counters, _rtm_counters, _stack_rtm_counters, 12427 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12428 true, ra_->C->profile_rtm()); 12429 %} 12430 ins_pipe(pipe_slow); 12431 %} 12432 12433 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12434 predicate(!Compile::current()->use_rtm()); 12435 match(Set cr (FastLock object box)); 12436 effect(TEMP tmp, TEMP scr, USE_KILL box); 12437 ins_cost(300); 12438 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12439 ins_encode %{ 12440 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12441 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12442 %} 12443 ins_pipe(pipe_slow); 12444 %} 12445 12446 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12447 match(Set cr (FastUnlock object box)); 12448 effect(TEMP tmp, USE_KILL box); 12449 ins_cost(300); 12450 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12451 ins_encode %{ 12452 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12453 %} 12454 ins_pipe(pipe_slow); 12455 %} 12456 12457 12458 // ============================================================================ 12459 // Safepoint Instructions 12460 instruct safePoint_poll(rFlagsReg cr) 12461 %{ 12462 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12463 match(SafePoint); 12464 effect(KILL cr); 12465 12466 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12467 "# Safepoint: poll for GC" %} 12468 ins_cost(125); 12469 ins_encode %{ 12470 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12471 __ testl(rax, addr); 12472 %} 12473 ins_pipe(ialu_reg_mem); 12474 %} 12475 12476 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12477 %{ 12478 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12479 match(SafePoint poll); 12480 effect(KILL cr, USE poll); 12481 12482 format %{ "testl rax, [$poll]\t" 12483 "# Safepoint: poll for GC" %} 12484 ins_cost(125); 12485 ins_encode %{ 12486 __ relocate(relocInfo::poll_type); 12487 __ testl(rax, Address($poll$$Register, 0)); 12488 %} 12489 ins_pipe(ialu_reg_mem); 12490 %} 12491 12492 instruct safePoint_poll_tls(rFlagsReg cr, rex_RegP poll) 12493 %{ 12494 predicate(SafepointMechanism::uses_thread_local_poll()); 12495 match(SafePoint poll); 12496 effect(KILL cr, USE poll); 12497 12498 format %{ "testl rax, [$poll]\t" 12499 "# Safepoint: poll for GC" %} 12500 ins_cost(125); 12501 size(3); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12502 ins_encode %{ 12503 __ relocate(relocInfo::poll_type); 12504 address pre_pc = __ pc(); 12505 __ testl(rax, Address($poll$$Register, 0)); 12506 address post_pc = __ pc(); 12507 guarantee(pre_pc[0] == 0x41 && pre_pc[1] == 0x85, "must emit #rex test-ax [reg]"); 12508 %} 12509 ins_pipe(ialu_reg_mem); 12510 %} 12511 12512 // ============================================================================ 12513 // Procedure Call/Return Instructions 12514 // Call Java Static Instruction 12515 // Note: If this code changes, the corresponding ret_addr_offset() and 12516 // compute_padding() functions will have to be adjusted. 12517 instruct CallStaticJavaDirect(method meth) %{ 12518 match(CallStaticJava); 12519 effect(USE meth); 12520 12521 ins_cost(300); 12522 format %{ "call,static " %} 12523 opcode(0xE8); /* E8 cd */ 12524 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12525 ins_pipe(pipe_slow); 12526 ins_alignment(4); 12527 %} 12528 12529 // Call Java Dynamic Instruction 12530 // Note: If this code changes, the corresponding ret_addr_offset() and 12531 // compute_padding() functions will have to be adjusted. 12532 instruct CallDynamicJavaDirect(method meth) 12533 %{ 12534 match(CallDynamicJava); 12535 effect(USE meth); 12536 12537 ins_cost(300); 12538 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12539 "call,dynamic " %} 12540 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12541 ins_pipe(pipe_slow); 12542 ins_alignment(4); 12543 %} 12544 12545 // Call Runtime Instruction 12546 instruct CallRuntimeDirect(method meth) 12547 %{ 12548 match(CallRuntime); 12549 effect(USE meth); 12550 12551 ins_cost(300); 12552 format %{ "call,runtime " %} 12553 ins_encode(clear_avx, Java_To_Runtime(meth)); 12554 ins_pipe(pipe_slow); 12555 %} 12556 12557 // Call runtime without safepoint 12558 instruct CallLeafDirect(method meth) 12559 %{ 12560 match(CallLeaf); 12561 effect(USE meth); 12562 12563 ins_cost(300); 12564 format %{ "call_leaf,runtime " %} 12565 ins_encode(clear_avx, Java_To_Runtime(meth)); 12566 ins_pipe(pipe_slow); 12567 %} 12568 12569 // Call runtime without safepoint 12570 instruct CallLeafNoFPDirect(method meth) 12571 %{ 12572 match(CallLeafNoFP); 12573 effect(USE meth); 12574 12575 ins_cost(300); 12576 format %{ "call_leaf_nofp,runtime " %} 12577 ins_encode(clear_avx, Java_To_Runtime(meth)); 12578 ins_pipe(pipe_slow); 12579 %} 12580 12581 // Return Instruction 12582 // Remove the return address & jump to it. 12583 // Notice: We always emit a nop after a ret to make sure there is room 12584 // for safepoint patching 12585 instruct Ret() 12586 %{ 12587 match(Return); 12588 12589 format %{ "ret" %} 12590 opcode(0xC3); 12591 ins_encode(OpcP); 12592 ins_pipe(pipe_jmp); 12593 %} 12594 12595 // Tail Call; Jump from runtime stub to Java code. 12596 // Also known as an 'interprocedural jump'. 12597 // Target of jump will eventually return to caller. 12598 // TailJump below removes the return address. 12599 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12600 %{ 12601 match(TailCall jump_target method_oop); 12602 12603 ins_cost(300); 12604 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12605 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12606 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12607 ins_pipe(pipe_jmp); 12608 %} 12609 12610 // Tail Jump; remove the return address; jump to target. 12611 // TailCall above leaves the return address around. 12612 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12613 %{ 12614 match(TailJump jump_target ex_oop); 12615 12616 ins_cost(300); 12617 format %{ "popq rdx\t# pop return address\n\t" 12618 "jmp $jump_target" %} 12619 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12620 ins_encode(Opcode(0x5a), // popq rdx 12621 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12622 ins_pipe(pipe_jmp); 12623 %} 12624 12625 // Create exception oop: created by stack-crawling runtime code. 12626 // Created exception is now available to this handler, and is setup 12627 // just prior to jumping to this handler. No code emitted. 12628 instruct CreateException(rax_RegP ex_oop) 12629 %{ 12630 match(Set ex_oop (CreateEx)); 12631 12632 size(0); 12633 // use the following format syntax 12634 format %{ "# exception oop is in rax; no code emitted" %} 12635 ins_encode(); 12636 ins_pipe(empty); 12637 %} 12638 12639 // Rethrow exception: 12640 // The exception oop will come in the first argument position. 12641 // Then JUMP (not call) to the rethrow stub code. 12642 instruct RethrowException() 12643 %{ 12644 match(Rethrow); 12645 12646 // use the following format syntax 12647 format %{ "jmp rethrow_stub" %} 12648 ins_encode(enc_rethrow); 12649 ins_pipe(pipe_jmp); 12650 %} 12651 12652 // 12653 // Execute ZGC load barrier (strong) slow path 12654 // 12655 12656 // When running without XMM regs 12657 instruct loadBarrierSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12658 12659 match(Set dst (LoadBarrierSlowReg mem)); 12660 predicate(MaxVectorSize < 16); 12661 12662 effect(DEF dst, KILL cr); 12663 12664 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12665 ins_encode %{ 12666 #if INCLUDE_ZGC 12667 Register d = $dst$$Register; 12668 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12669 12670 assert(d != r12, "Can't be R12!"); 12671 assert(d != r15, "Can't be R15!"); 12672 assert(d != rsp, "Can't be RSP!"); 12673 12674 __ lea(d, $mem$$Address); 12675 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12676 #else 12677 ShouldNotReachHere(); 12678 #endif 12679 %} 12680 ins_pipe(pipe_slow); 12681 %} 12682 12683 // For XMM and YMM enabled processors 12684 instruct loadBarrierSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12685 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12686 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12687 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12688 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12689 12690 match(Set dst (LoadBarrierSlowReg mem)); 12691 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12692 12693 effect(DEF dst, KILL cr, 12694 KILL x0, KILL x1, KILL x2, KILL x3, 12695 KILL x4, KILL x5, KILL x6, KILL x7, 12696 KILL x8, KILL x9, KILL x10, KILL x11, 12697 KILL x12, KILL x13, KILL x14, KILL x15); 12698 12699 format %{"LoadBarrierSlowRegXmm $dst, $mem" %} 12700 ins_encode %{ 12701 #if INCLUDE_ZGC 12702 Register d = $dst$$Register; 12703 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12704 12705 assert(d != r12, "Can't be R12!"); 12706 assert(d != r15, "Can't be R15!"); 12707 assert(d != rsp, "Can't be RSP!"); 12708 12709 __ lea(d, $mem$$Address); 12710 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12711 #else 12712 ShouldNotReachHere(); 12713 #endif 12714 %} 12715 ins_pipe(pipe_slow); 12716 %} 12717 12718 // For ZMM enabled processors 12719 instruct loadBarrierSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12720 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12721 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12722 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12723 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12724 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12725 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12726 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12727 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12728 12729 match(Set dst (LoadBarrierSlowReg mem)); 12730 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12731 12732 effect(DEF dst, KILL cr, 12733 KILL x0, KILL x1, KILL x2, KILL x3, 12734 KILL x4, KILL x5, KILL x6, KILL x7, 12735 KILL x8, KILL x9, KILL x10, KILL x11, 12736 KILL x12, KILL x13, KILL x14, KILL x15, 12737 KILL x16, KILL x17, KILL x18, KILL x19, 12738 KILL x20, KILL x21, KILL x22, KILL x23, 12739 KILL x24, KILL x25, KILL x26, KILL x27, 12740 KILL x28, KILL x29, KILL x30, KILL x31); 12741 12742 format %{"LoadBarrierSlowRegZmm $dst, $mem" %} 12743 ins_encode %{ 12744 #if INCLUDE_ZGC 12745 Register d = $dst$$Register; 12746 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12747 12748 assert(d != r12, "Can't be R12!"); 12749 assert(d != r15, "Can't be R15!"); 12750 assert(d != rsp, "Can't be RSP!"); 12751 12752 __ lea(d, $mem$$Address); 12753 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12754 #else 12755 ShouldNotReachHere(); 12756 #endif 12757 %} 12758 ins_pipe(pipe_slow); 12759 %} 12760 12761 // 12762 // Execute ZGC load barrier (weak) slow path 12763 // 12764 12765 // When running without XMM regs 12766 instruct loadBarrierWeakSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12767 12768 match(Set dst (LoadBarrierSlowReg mem)); 12769 predicate(MaxVectorSize < 16); 12770 12771 effect(DEF dst, KILL cr); 12772 12773 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12774 ins_encode %{ 12775 #if INCLUDE_ZGC 12776 Register d = $dst$$Register; 12777 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12778 12779 assert(d != r12, "Can't be R12!"); 12780 assert(d != r15, "Can't be R15!"); 12781 assert(d != rsp, "Can't be RSP!"); 12782 12783 __ lea(d, $mem$$Address); 12784 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12785 #else 12786 ShouldNotReachHere(); 12787 #endif 12788 %} 12789 ins_pipe(pipe_slow); 12790 %} 12791 12792 // For XMM and YMM enabled processors 12793 instruct loadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12794 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12795 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12796 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12797 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12798 12799 match(Set dst (LoadBarrierWeakSlowReg mem)); 12800 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12801 12802 effect(DEF dst, KILL cr, 12803 KILL x0, KILL x1, KILL x2, KILL x3, 12804 KILL x4, KILL x5, KILL x6, KILL x7, 12805 KILL x8, KILL x9, KILL x10, KILL x11, 12806 KILL x12, KILL x13, KILL x14, KILL x15); 12807 12808 format %{"LoadBarrierWeakSlowRegXmm $dst, $mem" %} 12809 ins_encode %{ 12810 #if INCLUDE_ZGC 12811 Register d = $dst$$Register; 12812 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12813 12814 assert(d != r12, "Can't be R12!"); 12815 assert(d != r15, "Can't be R15!"); 12816 assert(d != rsp, "Can't be RSP!"); 12817 12818 __ lea(d,$mem$$Address); 12819 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12820 #else 12821 ShouldNotReachHere(); 12822 #endif 12823 %} 12824 ins_pipe(pipe_slow); 12825 %} 12826 12827 // For ZMM enabled processors 12828 instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12829 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12830 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12831 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12832 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12833 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12834 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12835 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12836 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12837 12838 match(Set dst (LoadBarrierWeakSlowReg mem)); 12839 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 12840 12841 effect(DEF dst, KILL cr, 12842 KILL x0, KILL x1, KILL x2, KILL x3, 12843 KILL x4, KILL x5, KILL x6, KILL x7, 12844 KILL x8, KILL x9, KILL x10, KILL x11, 12845 KILL x12, KILL x13, KILL x14, KILL x15, 12846 KILL x16, KILL x17, KILL x18, KILL x19, 12847 KILL x20, KILL x21, KILL x22, KILL x23, 12848 KILL x24, KILL x25, KILL x26, KILL x27, 12849 KILL x28, KILL x29, KILL x30, KILL x31); 12850 12851 format %{"LoadBarrierWeakSlowRegZmm $dst, $mem" %} 12852 ins_encode %{ 12853 #if INCLUDE_ZGC 12854 Register d = $dst$$Register; 12855 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12856 12857 assert(d != r12, "Can't be R12!"); 12858 assert(d != r15, "Can't be R15!"); 12859 assert(d != rsp, "Can't be RSP!"); 12860 12861 __ lea(d,$mem$$Address); 12862 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12863 #else 12864 ShouldNotReachHere(); 12865 #endif 12866 %} 12867 ins_pipe(pipe_slow); 12868 %} 12869 12870 // ============================================================================ 12871 // This name is KNOWN by the ADLC and cannot be changed. 12872 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12873 // for this guy. 12874 instruct tlsLoadP(r15_RegP dst) %{ 12875 match(Set dst (ThreadLocal)); 12876 effect(DEF dst); 12877 12878 size(0); 12879 format %{ "# TLS is in R15" %} 12880 ins_encode( /*empty encoding*/ ); 12881 ins_pipe(ialu_reg_reg); 12882 %} 12883 12884 12885 //----------PEEPHOLE RULES----------------------------------------------------- 12886 // These must follow all instruction definitions as they use the names 12887 // defined in the instructions definitions. 12888 // 12889 // peepmatch ( root_instr_name [preceding_instruction]* ); 12890 // 12891 // peepconstraint %{ 12892 // (instruction_number.operand_name relational_op instruction_number.operand_name 12893 // [, ...] ); 12894 // // instruction numbers are zero-based using left to right order in peepmatch 12895 // 12896 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12897 // // provide an instruction_number.operand_name for each operand that appears 12898 // // in the replacement instruction's match rule 12899 // 12900 // ---------VM FLAGS--------------------------------------------------------- 12901 // 12902 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12903 // 12904 // Each peephole rule is given an identifying number starting with zero and 12905 // increasing by one in the order seen by the parser. An individual peephole 12906 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12907 // on the command-line. 12908 // 12909 // ---------CURRENT LIMITATIONS---------------------------------------------- 12910 // 12911 // Only match adjacent instructions in same basic block 12912 // Only equality constraints 12913 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12914 // Only one replacement instruction 12915 // 12916 // ---------EXAMPLE---------------------------------------------------------- 12917 // 12918 // // pertinent parts of existing instructions in architecture description 12919 // instruct movI(rRegI dst, rRegI src) 12920 // %{ 12921 // match(Set dst (CopyI src)); 12922 // %} 12923 // 12924 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12925 // %{ 12926 // match(Set dst (AddI dst src)); 12927 // effect(KILL cr); 12928 // %} 12929 // 12930 // // Change (inc mov) to lea 12931 // peephole %{ 12932 // // increment preceeded by register-register move 12933 // peepmatch ( incI_rReg movI ); 12934 // // require that the destination register of the increment 12935 // // match the destination register of the move 12936 // peepconstraint ( 0.dst == 1.dst ); 12937 // // construct a replacement instruction that sets 12938 // // the destination to ( move's source register + one ) 12939 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12940 // %} 12941 // 12942 12943 // Implementation no longer uses movX instructions since 12944 // machine-independent system no longer uses CopyX nodes. 12945 // 12946 // peephole 12947 // %{ 12948 // peepmatch (incI_rReg movI); 12949 // peepconstraint (0.dst == 1.dst); 12950 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12951 // %} 12952 12953 // peephole 12954 // %{ 12955 // peepmatch (decI_rReg movI); 12956 // peepconstraint (0.dst == 1.dst); 12957 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12958 // %} 12959 12960 // peephole 12961 // %{ 12962 // peepmatch (addI_rReg_imm movI); 12963 // peepconstraint (0.dst == 1.dst); 12964 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12965 // %} 12966 12967 // peephole 12968 // %{ 12969 // peepmatch (incL_rReg movL); 12970 // peepconstraint (0.dst == 1.dst); 12971 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12972 // %} 12973 12974 // peephole 12975 // %{ 12976 // peepmatch (decL_rReg movL); 12977 // peepconstraint (0.dst == 1.dst); 12978 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12979 // %} 12980 12981 // peephole 12982 // %{ 12983 // peepmatch (addL_rReg_imm movL); 12984 // peepconstraint (0.dst == 1.dst); 12985 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12986 // %} 12987 12988 // peephole 12989 // %{ 12990 // peepmatch (addP_rReg_imm movP); 12991 // peepconstraint (0.dst == 1.dst); 12992 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12993 // %} 12994 12995 // // Change load of spilled value to only a spill 12996 // instruct storeI(memory mem, rRegI src) 12997 // %{ 12998 // match(Set mem (StoreI mem src)); 12999 // %} 13000 // 13001 // instruct loadI(rRegI dst, memory mem) 13002 // %{ 13003 // match(Set dst (LoadI mem)); 13004 // %} 13005 // 13006 13007 peephole 13008 %{ 13009 peepmatch (loadI storeI); 13010 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13011 peepreplace (storeI(1.mem 1.mem 1.src)); 13012 %} 13013 13014 peephole 13015 %{ 13016 peepmatch (loadL storeL); 13017 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13018 peepreplace (storeL(1.mem 1.mem 1.src)); 13019 %} 13020 13021 //----------SMARTSPILL RULES--------------------------------------------------- 13022 // These must follow all instruction definitions as they use the names 13023 // defined in the instructions definitions.