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 BLOCK------------------------------------------------------- 542 // This is a block of C++ code which provides values, functions, and 543 // definitions necessary in the rest of the architecture description 544 source %{ 545 #define RELOC_IMM64 Assembler::imm_operand 546 #define RELOC_DISP32 Assembler::disp32_operand 547 548 #define __ _masm. 549 550 static bool generate_vzeroupper(Compile* C) { 551 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 552 } 553 554 static int clear_avx_size() { 555 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 556 } 557 558 // !!!!! Special hack to get all types of calls to specify the byte offset 559 // from the start of the call to the point where the return address 560 // will point. 561 int MachCallStaticJavaNode::ret_addr_offset() 562 { 563 int offset = 5; // 5 bytes from start of call to where return address points 564 offset += clear_avx_size(); 565 return offset; 566 } 567 568 int MachCallDynamicJavaNode::ret_addr_offset() 569 { 570 int offset = 15; // 15 bytes from start of call to where return address points 571 offset += clear_avx_size(); 572 return offset; 573 } 574 575 int MachCallRuntimeNode::ret_addr_offset() { 576 int offset = 13; // movq r10,#addr; callq (r10) 577 offset += clear_avx_size(); 578 return offset; 579 } 580 581 // Indicate if the safepoint node needs the polling page as an input, 582 // it does if the polling page is more than disp32 away. 583 bool SafePointNode::needs_polling_address_input() 584 { 585 return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far(); 586 } 587 588 // 589 // Compute padding required for nodes which need alignment 590 // 591 592 // The address of the call instruction needs to be 4-byte aligned to 593 // ensure that it does not span a cache line so that it can be patched. 594 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 595 { 596 current_offset += clear_avx_size(); // skip vzeroupper 597 current_offset += 1; // skip call opcode byte 598 return align_up(current_offset, alignment_required()) - current_offset; 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 CallDynamicJavaDirectNode::compute_padding(int current_offset) const 604 { 605 current_offset += clear_avx_size(); // skip vzeroupper 606 current_offset += 11; // skip movq instruction + call opcode byte 607 return align_up(current_offset, alignment_required()) - current_offset; 608 } 609 610 // EMIT_RM() 611 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 612 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 613 cbuf.insts()->emit_int8(c); 614 } 615 616 // EMIT_CC() 617 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 618 unsigned char c = (unsigned char) (f1 | f2); 619 cbuf.insts()->emit_int8(c); 620 } 621 622 // EMIT_OPCODE() 623 void emit_opcode(CodeBuffer &cbuf, int code) { 624 cbuf.insts()->emit_int8((unsigned char) code); 625 } 626 627 // EMIT_OPCODE() w/ relocation information 628 void emit_opcode(CodeBuffer &cbuf, 629 int code, relocInfo::relocType reloc, int offset, int format) 630 { 631 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 632 emit_opcode(cbuf, code); 633 } 634 635 // EMIT_D8() 636 void emit_d8(CodeBuffer &cbuf, int d8) { 637 cbuf.insts()->emit_int8((unsigned char) d8); 638 } 639 640 // EMIT_D16() 641 void emit_d16(CodeBuffer &cbuf, int d16) { 642 cbuf.insts()->emit_int16(d16); 643 } 644 645 // EMIT_D32() 646 void emit_d32(CodeBuffer &cbuf, int d32) { 647 cbuf.insts()->emit_int32(d32); 648 } 649 650 // EMIT_D64() 651 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 652 cbuf.insts()->emit_int64(d64); 653 } 654 655 // emit 32 bit value and construct relocation entry from relocInfo::relocType 656 void emit_d32_reloc(CodeBuffer& cbuf, 657 int d32, 658 relocInfo::relocType reloc, 659 int format) 660 { 661 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 662 cbuf.relocate(cbuf.insts_mark(), reloc, format); 663 cbuf.insts()->emit_int32(d32); 664 } 665 666 // emit 32 bit value and construct relocation entry from RelocationHolder 667 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 668 #ifdef ASSERT 669 if (rspec.reloc()->type() == relocInfo::oop_type && 670 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 671 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 672 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)) && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 673 } 674 #endif 675 cbuf.relocate(cbuf.insts_mark(), rspec, format); 676 cbuf.insts()->emit_int32(d32); 677 } 678 679 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 680 address next_ip = cbuf.insts_end() + 4; 681 emit_d32_reloc(cbuf, (int) (addr - next_ip), 682 external_word_Relocation::spec(addr), 683 RELOC_DISP32); 684 } 685 686 687 // emit 64 bit value and construct relocation entry from relocInfo::relocType 688 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 689 cbuf.relocate(cbuf.insts_mark(), reloc, format); 690 cbuf.insts()->emit_int64(d64); 691 } 692 693 // emit 64 bit value and construct relocation entry from RelocationHolder 694 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 695 #ifdef ASSERT 696 if (rspec.reloc()->type() == relocInfo::oop_type && 697 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 698 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 699 assert(oopDesc::is_oop(cast_to_oop(d64)) && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()), 700 "cannot embed scavengable oops in code"); 701 } 702 #endif 703 cbuf.relocate(cbuf.insts_mark(), rspec, format); 704 cbuf.insts()->emit_int64(d64); 705 } 706 707 // Access stack slot for load or store 708 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 709 { 710 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 711 if (-0x80 <= disp && disp < 0x80) { 712 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 713 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 714 emit_d8(cbuf, disp); // Displacement // R/M byte 715 } else { 716 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 717 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 718 emit_d32(cbuf, disp); // Displacement // R/M byte 719 } 720 } 721 722 // rRegI ereg, memory mem) %{ // emit_reg_mem 723 void encode_RegMem(CodeBuffer &cbuf, 724 int reg, 725 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 726 { 727 assert(disp_reloc == relocInfo::none, "cannot have disp"); 728 int regenc = reg & 7; 729 int baseenc = base & 7; 730 int indexenc = index & 7; 731 732 // There is no index & no scale, use form without SIB byte 733 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 734 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 735 if (disp == 0 && base != RBP_enc && base != R13_enc) { 736 emit_rm(cbuf, 0x0, regenc, baseenc); // * 737 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 738 // If 8-bit displacement, mode 0x1 739 emit_rm(cbuf, 0x1, regenc, baseenc); // * 740 emit_d8(cbuf, disp); 741 } else { 742 // If 32-bit displacement 743 if (base == -1) { // Special flag for absolute address 744 emit_rm(cbuf, 0x0, regenc, 0x5); // * 745 if (disp_reloc != relocInfo::none) { 746 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 747 } else { 748 emit_d32(cbuf, disp); 749 } 750 } else { 751 // Normal base + offset 752 emit_rm(cbuf, 0x2, regenc, baseenc); // * 753 if (disp_reloc != relocInfo::none) { 754 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 755 } else { 756 emit_d32(cbuf, disp); 757 } 758 } 759 } 760 } else { 761 // Else, encode with the SIB byte 762 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 763 if (disp == 0 && base != RBP_enc && base != R13_enc) { 764 // If no displacement 765 emit_rm(cbuf, 0x0, regenc, 0x4); // * 766 emit_rm(cbuf, scale, indexenc, baseenc); 767 } else { 768 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 769 // If 8-bit displacement, mode 0x1 770 emit_rm(cbuf, 0x1, regenc, 0x4); // * 771 emit_rm(cbuf, scale, indexenc, baseenc); 772 emit_d8(cbuf, disp); 773 } else { 774 // If 32-bit displacement 775 if (base == 0x04 ) { 776 emit_rm(cbuf, 0x2, regenc, 0x4); 777 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 778 } else { 779 emit_rm(cbuf, 0x2, regenc, 0x4); 780 emit_rm(cbuf, scale, indexenc, baseenc); // * 781 } 782 if (disp_reloc != relocInfo::none) { 783 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 784 } else { 785 emit_d32(cbuf, disp); 786 } 787 } 788 } 789 } 790 } 791 792 // This could be in MacroAssembler but it's fairly C2 specific 793 void emit_cmpfp_fixup(MacroAssembler& _masm) { 794 Label exit; 795 __ jccb(Assembler::noParity, exit); 796 __ pushf(); 797 // 798 // comiss/ucomiss instructions set ZF,PF,CF flags and 799 // zero OF,AF,SF for NaN values. 800 // Fixup flags by zeroing ZF,PF so that compare of NaN 801 // values returns 'less than' result (CF is set). 802 // Leave the rest of flags unchanged. 803 // 804 // 7 6 5 4 3 2 1 0 805 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 806 // 0 0 1 0 1 0 1 1 (0x2B) 807 // 808 __ andq(Address(rsp, 0), 0xffffff2b); 809 __ popf(); 810 __ bind(exit); 811 } 812 813 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 814 Label done; 815 __ movl(dst, -1); 816 __ jcc(Assembler::parity, done); 817 __ jcc(Assembler::below, done); 818 __ setb(Assembler::notEqual, dst); 819 __ movzbl(dst, dst); 820 __ bind(done); 821 } 822 823 824 //============================================================================= 825 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 826 827 int Compile::ConstantTable::calculate_table_base_offset() const { 828 return 0; // absolute addressing, no offset 829 } 830 831 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 832 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 833 ShouldNotReachHere(); 834 } 835 836 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 837 // Empty encoding 838 } 839 840 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 841 return 0; 842 } 843 844 #ifndef PRODUCT 845 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 846 st->print("# MachConstantBaseNode (empty encoding)"); 847 } 848 #endif 849 850 851 //============================================================================= 852 #ifndef PRODUCT 853 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 854 Compile* C = ra_->C; 855 856 int framesize = C->frame_size_in_bytes(); 857 int bangsize = C->bang_size_in_bytes(); 858 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 859 // Remove wordSize for return addr which is already pushed. 860 framesize -= wordSize; 861 862 if (C->need_stack_bang(bangsize)) { 863 framesize -= wordSize; 864 st->print("# stack bang (%d bytes)", bangsize); 865 st->print("\n\t"); 866 st->print("pushq rbp\t# Save rbp"); 867 if (PreserveFramePointer) { 868 st->print("\n\t"); 869 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 870 } 871 if (framesize) { 872 st->print("\n\t"); 873 st->print("subq rsp, #%d\t# Create frame",framesize); 874 } 875 } else { 876 st->print("subq rsp, #%d\t# Create frame",framesize); 877 st->print("\n\t"); 878 framesize -= wordSize; 879 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 880 if (PreserveFramePointer) { 881 st->print("\n\t"); 882 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 883 if (framesize > 0) { 884 st->print("\n\t"); 885 st->print("addq rbp, #%d", framesize); 886 } 887 } 888 } 889 890 if (VerifyStackAtCalls) { 891 st->print("\n\t"); 892 framesize -= wordSize; 893 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 894 #ifdef ASSERT 895 st->print("\n\t"); 896 st->print("# stack alignment check"); 897 #endif 898 } 899 st->cr(); 900 } 901 #endif 902 903 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 904 Compile* C = ra_->C; 905 MacroAssembler _masm(&cbuf); 906 907 int framesize = C->frame_size_in_bytes(); 908 int bangsize = C->bang_size_in_bytes(); 909 910 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); 911 912 C->set_frame_complete(cbuf.insts_size()); 913 914 if (C->has_mach_constant_base_node()) { 915 // NOTE: We set the table base offset here because users might be 916 // emitted before MachConstantBaseNode. 917 Compile::ConstantTable& constant_table = C->constant_table(); 918 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 919 } 920 } 921 922 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 923 { 924 return MachNode::size(ra_); // too many variables; just compute it 925 // the hard way 926 } 927 928 int MachPrologNode::reloc() const 929 { 930 return 0; // a large enough number 931 } 932 933 //============================================================================= 934 #ifndef PRODUCT 935 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 936 { 937 Compile* C = ra_->C; 938 if (generate_vzeroupper(C)) { 939 st->print("vzeroupper"); 940 st->cr(); st->print("\t"); 941 } 942 943 int framesize = C->frame_size_in_bytes(); 944 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 945 // Remove word for return adr already pushed 946 // and RBP 947 framesize -= 2*wordSize; 948 949 if (framesize) { 950 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 951 st->print("\t"); 952 } 953 954 st->print_cr("popq rbp"); 955 if (do_polling() && C->is_method_compilation()) { 956 st->print("\t"); 957 if (SafepointMechanism::uses_thread_local_poll()) { 958 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 959 "testl rax, [rscratch1]\t" 960 "# Safepoint: poll for GC"); 961 } else if (Assembler::is_polling_page_far()) { 962 st->print_cr("movq rscratch1, #polling_page_address\n\t" 963 "testl rax, [rscratch1]\t" 964 "# Safepoint: poll for GC"); 965 } else { 966 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 967 "# Safepoint: poll for GC"); 968 } 969 } 970 } 971 #endif 972 973 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 974 { 975 Compile* C = ra_->C; 976 MacroAssembler _masm(&cbuf); 977 978 if (generate_vzeroupper(C)) { 979 // Clear upper bits of YMM registers when current compiled code uses 980 // wide vectors to avoid AVX <-> SSE transition penalty during call. 981 __ vzeroupper(); 982 } 983 984 int framesize = C->frame_size_in_bytes(); 985 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 986 // Remove word for return adr already pushed 987 // and RBP 988 framesize -= 2*wordSize; 989 990 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 991 992 if (framesize) { 993 emit_opcode(cbuf, Assembler::REX_W); 994 if (framesize < 0x80) { 995 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 996 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 997 emit_d8(cbuf, framesize); 998 } else { 999 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 1000 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1001 emit_d32(cbuf, framesize); 1002 } 1003 } 1004 1005 // popq rbp 1006 emit_opcode(cbuf, 0x58 | RBP_enc); 1007 1008 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1009 __ reserved_stack_check(); 1010 } 1011 1012 if (do_polling() && C->is_method_compilation()) { 1013 MacroAssembler _masm(&cbuf); 1014 if (SafepointMechanism::uses_thread_local_poll()) { 1015 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 1016 __ relocate(relocInfo::poll_return_type); 1017 __ testl(rax, Address(rscratch1, 0)); 1018 } else { 1019 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1020 if (Assembler::is_polling_page_far()) { 1021 __ lea(rscratch1, polling_page); 1022 __ relocate(relocInfo::poll_return_type); 1023 __ testl(rax, Address(rscratch1, 0)); 1024 } else { 1025 __ testl(rax, polling_page); 1026 } 1027 } 1028 } 1029 } 1030 1031 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1032 { 1033 return MachNode::size(ra_); // too many variables; just compute it 1034 // the hard way 1035 } 1036 1037 int MachEpilogNode::reloc() const 1038 { 1039 return 2; // a large enough number 1040 } 1041 1042 const Pipeline* MachEpilogNode::pipeline() const 1043 { 1044 return MachNode::pipeline_class(); 1045 } 1046 1047 int MachEpilogNode::safepoint_offset() const 1048 { 1049 return 0; 1050 } 1051 1052 //============================================================================= 1053 1054 enum RC { 1055 rc_bad, 1056 rc_int, 1057 rc_float, 1058 rc_stack 1059 }; 1060 1061 static enum RC rc_class(OptoReg::Name reg) 1062 { 1063 if( !OptoReg::is_valid(reg) ) return rc_bad; 1064 1065 if (OptoReg::is_stack(reg)) return rc_stack; 1066 1067 VMReg r = OptoReg::as_VMReg(reg); 1068 1069 if (r->is_Register()) return rc_int; 1070 1071 assert(r->is_XMMRegister(), "must be"); 1072 return rc_float; 1073 } 1074 1075 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1076 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1077 int src_hi, int dst_hi, uint ireg, outputStream* st); 1078 1079 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1080 int stack_offset, int reg, uint ireg, outputStream* st); 1081 1082 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1083 int dst_offset, uint ireg, outputStream* st) { 1084 if (cbuf) { 1085 MacroAssembler _masm(cbuf); 1086 switch (ireg) { 1087 case Op_VecS: 1088 __ movq(Address(rsp, -8), rax); 1089 __ movl(rax, Address(rsp, src_offset)); 1090 __ movl(Address(rsp, dst_offset), rax); 1091 __ movq(rax, Address(rsp, -8)); 1092 break; 1093 case Op_VecD: 1094 __ pushq(Address(rsp, src_offset)); 1095 __ popq (Address(rsp, dst_offset)); 1096 break; 1097 case Op_VecX: 1098 __ pushq(Address(rsp, src_offset)); 1099 __ popq (Address(rsp, dst_offset)); 1100 __ pushq(Address(rsp, src_offset+8)); 1101 __ popq (Address(rsp, dst_offset+8)); 1102 break; 1103 case Op_VecY: 1104 __ vmovdqu(Address(rsp, -32), xmm0); 1105 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1106 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1107 __ vmovdqu(xmm0, Address(rsp, -32)); 1108 break; 1109 case Op_VecZ: 1110 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1111 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1112 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1113 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1114 break; 1115 default: 1116 ShouldNotReachHere(); 1117 } 1118 #ifndef PRODUCT 1119 } else { 1120 switch (ireg) { 1121 case Op_VecS: 1122 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1123 "movl rax, [rsp + #%d]\n\t" 1124 "movl [rsp + #%d], rax\n\t" 1125 "movq rax, [rsp - #8]", 1126 src_offset, dst_offset); 1127 break; 1128 case Op_VecD: 1129 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1130 "popq [rsp + #%d]", 1131 src_offset, dst_offset); 1132 break; 1133 case Op_VecX: 1134 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1135 "popq [rsp + #%d]\n\t" 1136 "pushq [rsp + #%d]\n\t" 1137 "popq [rsp + #%d]", 1138 src_offset, dst_offset, src_offset+8, dst_offset+8); 1139 break; 1140 case Op_VecY: 1141 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1142 "vmovdqu xmm0, [rsp + #%d]\n\t" 1143 "vmovdqu [rsp + #%d], xmm0\n\t" 1144 "vmovdqu xmm0, [rsp - #32]", 1145 src_offset, dst_offset); 1146 break; 1147 case Op_VecZ: 1148 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1149 "vmovdqu xmm0, [rsp + #%d]\n\t" 1150 "vmovdqu [rsp + #%d], xmm0\n\t" 1151 "vmovdqu xmm0, [rsp - #64]", 1152 src_offset, dst_offset); 1153 break; 1154 default: 1155 ShouldNotReachHere(); 1156 } 1157 #endif 1158 } 1159 } 1160 1161 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1162 PhaseRegAlloc* ra_, 1163 bool do_size, 1164 outputStream* st) const { 1165 assert(cbuf != NULL || st != NULL, "sanity"); 1166 // Get registers to move 1167 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1168 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1169 OptoReg::Name dst_second = ra_->get_reg_second(this); 1170 OptoReg::Name dst_first = ra_->get_reg_first(this); 1171 1172 enum RC src_second_rc = rc_class(src_second); 1173 enum RC src_first_rc = rc_class(src_first); 1174 enum RC dst_second_rc = rc_class(dst_second); 1175 enum RC dst_first_rc = rc_class(dst_first); 1176 1177 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1178 "must move at least 1 register" ); 1179 1180 if (src_first == dst_first && src_second == dst_second) { 1181 // Self copy, no move 1182 return 0; 1183 } 1184 if (bottom_type()->isa_vect() != NULL) { 1185 uint ireg = ideal_reg(); 1186 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1187 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1188 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1189 // mem -> mem 1190 int src_offset = ra_->reg2offset(src_first); 1191 int dst_offset = ra_->reg2offset(dst_first); 1192 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1193 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1194 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1195 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1196 int stack_offset = ra_->reg2offset(dst_first); 1197 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1198 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1199 int stack_offset = ra_->reg2offset(src_first); 1200 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1201 } else { 1202 ShouldNotReachHere(); 1203 } 1204 return 0; 1205 } 1206 if (src_first_rc == rc_stack) { 1207 // mem -> 1208 if (dst_first_rc == rc_stack) { 1209 // mem -> mem 1210 assert(src_second != dst_first, "overlap"); 1211 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1212 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1213 // 64-bit 1214 int src_offset = ra_->reg2offset(src_first); 1215 int dst_offset = ra_->reg2offset(dst_first); 1216 if (cbuf) { 1217 MacroAssembler _masm(cbuf); 1218 __ pushq(Address(rsp, src_offset)); 1219 __ popq (Address(rsp, dst_offset)); 1220 #ifndef PRODUCT 1221 } else { 1222 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1223 "popq [rsp + #%d]", 1224 src_offset, dst_offset); 1225 #endif 1226 } 1227 } else { 1228 // 32-bit 1229 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1230 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1231 // No pushl/popl, so: 1232 int src_offset = ra_->reg2offset(src_first); 1233 int dst_offset = ra_->reg2offset(dst_first); 1234 if (cbuf) { 1235 MacroAssembler _masm(cbuf); 1236 __ movq(Address(rsp, -8), rax); 1237 __ movl(rax, Address(rsp, src_offset)); 1238 __ movl(Address(rsp, dst_offset), rax); 1239 __ movq(rax, Address(rsp, -8)); 1240 #ifndef PRODUCT 1241 } else { 1242 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1243 "movl rax, [rsp + #%d]\n\t" 1244 "movl [rsp + #%d], rax\n\t" 1245 "movq rax, [rsp - #8]", 1246 src_offset, dst_offset); 1247 #endif 1248 } 1249 } 1250 return 0; 1251 } else if (dst_first_rc == rc_int) { 1252 // mem -> gpr 1253 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1254 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1255 // 64-bit 1256 int offset = ra_->reg2offset(src_first); 1257 if (cbuf) { 1258 MacroAssembler _masm(cbuf); 1259 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1260 #ifndef PRODUCT 1261 } else { 1262 st->print("movq %s, [rsp + #%d]\t# spill", 1263 Matcher::regName[dst_first], 1264 offset); 1265 #endif 1266 } 1267 } else { 1268 // 32-bit 1269 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1270 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1271 int offset = ra_->reg2offset(src_first); 1272 if (cbuf) { 1273 MacroAssembler _masm(cbuf); 1274 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1275 #ifndef PRODUCT 1276 } else { 1277 st->print("movl %s, [rsp + #%d]\t# spill", 1278 Matcher::regName[dst_first], 1279 offset); 1280 #endif 1281 } 1282 } 1283 return 0; 1284 } else if (dst_first_rc == rc_float) { 1285 // mem-> xmm 1286 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1287 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1288 // 64-bit 1289 int offset = ra_->reg2offset(src_first); 1290 if (cbuf) { 1291 MacroAssembler _masm(cbuf); 1292 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1293 #ifndef PRODUCT 1294 } else { 1295 st->print("%s %s, [rsp + #%d]\t# spill", 1296 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1297 Matcher::regName[dst_first], 1298 offset); 1299 #endif 1300 } 1301 } else { 1302 // 32-bit 1303 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1304 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1305 int offset = ra_->reg2offset(src_first); 1306 if (cbuf) { 1307 MacroAssembler _masm(cbuf); 1308 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1309 #ifndef PRODUCT 1310 } else { 1311 st->print("movss %s, [rsp + #%d]\t# spill", 1312 Matcher::regName[dst_first], 1313 offset); 1314 #endif 1315 } 1316 } 1317 return 0; 1318 } 1319 } else if (src_first_rc == rc_int) { 1320 // gpr -> 1321 if (dst_first_rc == rc_stack) { 1322 // gpr -> mem 1323 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1324 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1325 // 64-bit 1326 int offset = ra_->reg2offset(dst_first); 1327 if (cbuf) { 1328 MacroAssembler _masm(cbuf); 1329 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1330 #ifndef PRODUCT 1331 } else { 1332 st->print("movq [rsp + #%d], %s\t# spill", 1333 offset, 1334 Matcher::regName[src_first]); 1335 #endif 1336 } 1337 } else { 1338 // 32-bit 1339 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1340 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1341 int offset = ra_->reg2offset(dst_first); 1342 if (cbuf) { 1343 MacroAssembler _masm(cbuf); 1344 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1345 #ifndef PRODUCT 1346 } else { 1347 st->print("movl [rsp + #%d], %s\t# spill", 1348 offset, 1349 Matcher::regName[src_first]); 1350 #endif 1351 } 1352 } 1353 return 0; 1354 } else if (dst_first_rc == rc_int) { 1355 // gpr -> gpr 1356 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1357 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1358 // 64-bit 1359 if (cbuf) { 1360 MacroAssembler _masm(cbuf); 1361 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1362 as_Register(Matcher::_regEncode[src_first])); 1363 #ifndef PRODUCT 1364 } else { 1365 st->print("movq %s, %s\t# spill", 1366 Matcher::regName[dst_first], 1367 Matcher::regName[src_first]); 1368 #endif 1369 } 1370 return 0; 1371 } else { 1372 // 32-bit 1373 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1374 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1375 if (cbuf) { 1376 MacroAssembler _masm(cbuf); 1377 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1378 as_Register(Matcher::_regEncode[src_first])); 1379 #ifndef PRODUCT 1380 } else { 1381 st->print("movl %s, %s\t# spill", 1382 Matcher::regName[dst_first], 1383 Matcher::regName[src_first]); 1384 #endif 1385 } 1386 return 0; 1387 } 1388 } else if (dst_first_rc == rc_float) { 1389 // gpr -> xmm 1390 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1391 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1392 // 64-bit 1393 if (cbuf) { 1394 MacroAssembler _masm(cbuf); 1395 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1396 #ifndef PRODUCT 1397 } else { 1398 st->print("movdq %s, %s\t# spill", 1399 Matcher::regName[dst_first], 1400 Matcher::regName[src_first]); 1401 #endif 1402 } 1403 } else { 1404 // 32-bit 1405 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1406 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1407 if (cbuf) { 1408 MacroAssembler _masm(cbuf); 1409 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1410 #ifndef PRODUCT 1411 } else { 1412 st->print("movdl %s, %s\t# spill", 1413 Matcher::regName[dst_first], 1414 Matcher::regName[src_first]); 1415 #endif 1416 } 1417 } 1418 return 0; 1419 } 1420 } else if (src_first_rc == rc_float) { 1421 // xmm -> 1422 if (dst_first_rc == rc_stack) { 1423 // xmm -> mem 1424 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1425 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1426 // 64-bit 1427 int offset = ra_->reg2offset(dst_first); 1428 if (cbuf) { 1429 MacroAssembler _masm(cbuf); 1430 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1431 #ifndef PRODUCT 1432 } else { 1433 st->print("movsd [rsp + #%d], %s\t# spill", 1434 offset, 1435 Matcher::regName[src_first]); 1436 #endif 1437 } 1438 } else { 1439 // 32-bit 1440 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1441 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1442 int offset = ra_->reg2offset(dst_first); 1443 if (cbuf) { 1444 MacroAssembler _masm(cbuf); 1445 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1446 #ifndef PRODUCT 1447 } else { 1448 st->print("movss [rsp + #%d], %s\t# spill", 1449 offset, 1450 Matcher::regName[src_first]); 1451 #endif 1452 } 1453 } 1454 return 0; 1455 } else if (dst_first_rc == rc_int) { 1456 // xmm -> gpr 1457 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1458 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1459 // 64-bit 1460 if (cbuf) { 1461 MacroAssembler _masm(cbuf); 1462 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1463 #ifndef PRODUCT 1464 } else { 1465 st->print("movdq %s, %s\t# spill", 1466 Matcher::regName[dst_first], 1467 Matcher::regName[src_first]); 1468 #endif 1469 } 1470 } else { 1471 // 32-bit 1472 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1473 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1474 if (cbuf) { 1475 MacroAssembler _masm(cbuf); 1476 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1477 #ifndef PRODUCT 1478 } else { 1479 st->print("movdl %s, %s\t# spill", 1480 Matcher::regName[dst_first], 1481 Matcher::regName[src_first]); 1482 #endif 1483 } 1484 } 1485 return 0; 1486 } else if (dst_first_rc == rc_float) { 1487 // xmm -> xmm 1488 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1489 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1490 // 64-bit 1491 if (cbuf) { 1492 MacroAssembler _masm(cbuf); 1493 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1494 #ifndef PRODUCT 1495 } else { 1496 st->print("%s %s, %s\t# spill", 1497 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1498 Matcher::regName[dst_first], 1499 Matcher::regName[src_first]); 1500 #endif 1501 } 1502 } else { 1503 // 32-bit 1504 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1505 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1506 if (cbuf) { 1507 MacroAssembler _masm(cbuf); 1508 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1509 #ifndef PRODUCT 1510 } else { 1511 st->print("%s %s, %s\t# spill", 1512 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1513 Matcher::regName[dst_first], 1514 Matcher::regName[src_first]); 1515 #endif 1516 } 1517 } 1518 return 0; 1519 } 1520 } 1521 1522 assert(0," foo "); 1523 Unimplemented(); 1524 return 0; 1525 } 1526 1527 #ifndef PRODUCT 1528 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1529 implementation(NULL, ra_, false, st); 1530 } 1531 #endif 1532 1533 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1534 implementation(&cbuf, ra_, false, NULL); 1535 } 1536 1537 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1538 return MachNode::size(ra_); 1539 } 1540 1541 //============================================================================= 1542 #ifndef PRODUCT 1543 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1544 { 1545 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1546 int reg = ra_->get_reg_first(this); 1547 st->print("leaq %s, [rsp + #%d]\t# box lock", 1548 Matcher::regName[reg], offset); 1549 } 1550 #endif 1551 1552 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1553 { 1554 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1555 int reg = ra_->get_encode(this); 1556 if (offset >= 0x80) { 1557 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1558 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1559 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1560 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1561 emit_d32(cbuf, offset); 1562 } else { 1563 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1564 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1565 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1566 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1567 emit_d8(cbuf, offset); 1568 } 1569 } 1570 1571 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1572 { 1573 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1574 return (offset < 0x80) ? 5 : 8; // REX 1575 } 1576 1577 //============================================================================= 1578 #ifndef PRODUCT 1579 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1580 { 1581 if (UseCompressedClassPointers) { 1582 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1583 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1584 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1585 } else { 1586 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1587 "# Inline cache check"); 1588 } 1589 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1590 st->print_cr("\tnop\t# nops to align entry point"); 1591 } 1592 #endif 1593 1594 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1595 { 1596 MacroAssembler masm(&cbuf); 1597 uint insts_size = cbuf.insts_size(); 1598 if (UseCompressedClassPointers) { 1599 masm.load_klass(rscratch1, j_rarg0); 1600 masm.cmpptr(rax, rscratch1); 1601 } else { 1602 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1603 } 1604 1605 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1606 1607 /* WARNING these NOPs are critical so that verified entry point is properly 1608 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1609 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1610 if (OptoBreakpoint) { 1611 // Leave space for int3 1612 nops_cnt -= 1; 1613 } 1614 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1615 if (nops_cnt > 0) 1616 masm.nop(nops_cnt); 1617 } 1618 1619 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1620 { 1621 return MachNode::size(ra_); // too many variables; just compute it 1622 // the hard way 1623 } 1624 1625 1626 //============================================================================= 1627 1628 int Matcher::regnum_to_fpu_offset(int regnum) 1629 { 1630 return regnum - 32; // The FP registers are in the second chunk 1631 } 1632 1633 // This is UltraSparc specific, true just means we have fast l2f conversion 1634 const bool Matcher::convL2FSupported(void) { 1635 return true; 1636 } 1637 1638 // Is this branch offset short enough that a short branch can be used? 1639 // 1640 // NOTE: If the platform does not provide any short branch variants, then 1641 // this method should return false for offset 0. 1642 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1643 // The passed offset is relative to address of the branch. 1644 // On 86 a branch displacement is calculated relative to address 1645 // of a next instruction. 1646 offset -= br_size; 1647 1648 // the short version of jmpConUCF2 contains multiple branches, 1649 // making the reach slightly less 1650 if (rule == jmpConUCF2_rule) 1651 return (-126 <= offset && offset <= 125); 1652 return (-128 <= offset && offset <= 127); 1653 } 1654 1655 const bool Matcher::isSimpleConstant64(jlong value) { 1656 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1657 //return value == (int) value; // Cf. storeImmL and immL32. 1658 1659 // Probably always true, even if a temp register is required. 1660 return true; 1661 } 1662 1663 // The ecx parameter to rep stosq for the ClearArray node is in words. 1664 const bool Matcher::init_array_count_is_in_bytes = false; 1665 1666 // No additional cost for CMOVL. 1667 const int Matcher::long_cmove_cost() { return 0; } 1668 1669 // No CMOVF/CMOVD with SSE2 1670 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1671 1672 // Does the CPU require late expand (see block.cpp for description of late expand)? 1673 const bool Matcher::require_postalloc_expand = false; 1674 1675 // Do we need to mask the count passed to shift instructions or does 1676 // the cpu only look at the lower 5/6 bits anyway? 1677 const bool Matcher::need_masked_shift_count = false; 1678 1679 bool Matcher::narrow_oop_use_complex_address() { 1680 assert(UseCompressedOops, "only for compressed oops code"); 1681 return (LogMinObjAlignmentInBytes <= 3); 1682 } 1683 1684 bool Matcher::narrow_klass_use_complex_address() { 1685 assert(UseCompressedClassPointers, "only for compressed klass code"); 1686 return (LogKlassAlignmentInBytes <= 3); 1687 } 1688 1689 bool Matcher::const_oop_prefer_decode() { 1690 // Prefer ConN+DecodeN over ConP. 1691 return true; 1692 } 1693 1694 bool Matcher::const_klass_prefer_decode() { 1695 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1696 // or condisider the following: 1697 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1698 //return Universe::narrow_klass_base() == NULL; 1699 return true; 1700 } 1701 1702 // Is it better to copy float constants, or load them directly from 1703 // memory? Intel can load a float constant from a direct address, 1704 // requiring no extra registers. Most RISCs will have to materialize 1705 // an address into a register first, so they would do better to copy 1706 // the constant from stack. 1707 const bool Matcher::rematerialize_float_constants = true; // XXX 1708 1709 // If CPU can load and store mis-aligned doubles directly then no 1710 // fixup is needed. Else we split the double into 2 integer pieces 1711 // and move it piece-by-piece. Only happens when passing doubles into 1712 // C code as the Java calling convention forces doubles to be aligned. 1713 const bool Matcher::misaligned_doubles_ok = true; 1714 1715 // No-op on amd64 1716 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1717 1718 // Advertise here if the CPU requires explicit rounding operations to 1719 // implement the UseStrictFP mode. 1720 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1721 1722 // Are floats conerted to double when stored to stack during deoptimization? 1723 // On x64 it is stored without convertion so we can use normal access. 1724 bool Matcher::float_in_double() { return false; } 1725 1726 // Do ints take an entire long register or just half? 1727 const bool Matcher::int_in_long = true; 1728 1729 // Return whether or not this register is ever used as an argument. 1730 // This function is used on startup to build the trampoline stubs in 1731 // generateOptoStub. Registers not mentioned will be killed by the VM 1732 // call in the trampoline, and arguments in those registers not be 1733 // available to the callee. 1734 bool Matcher::can_be_java_arg(int reg) 1735 { 1736 return 1737 reg == RDI_num || reg == RDI_H_num || 1738 reg == RSI_num || reg == RSI_H_num || 1739 reg == RDX_num || reg == RDX_H_num || 1740 reg == RCX_num || reg == RCX_H_num || 1741 reg == R8_num || reg == R8_H_num || 1742 reg == R9_num || reg == R9_H_num || 1743 reg == R12_num || reg == R12_H_num || 1744 reg == XMM0_num || reg == XMM0b_num || 1745 reg == XMM1_num || reg == XMM1b_num || 1746 reg == XMM2_num || reg == XMM2b_num || 1747 reg == XMM3_num || reg == XMM3b_num || 1748 reg == XMM4_num || reg == XMM4b_num || 1749 reg == XMM5_num || reg == XMM5b_num || 1750 reg == XMM6_num || reg == XMM6b_num || 1751 reg == XMM7_num || reg == XMM7b_num; 1752 } 1753 1754 bool Matcher::is_spillable_arg(int reg) 1755 { 1756 return can_be_java_arg(reg); 1757 } 1758 1759 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1760 // In 64 bit mode a code which use multiply when 1761 // devisor is constant is faster than hardware 1762 // DIV instruction (it uses MulHiL). 1763 return false; 1764 } 1765 1766 // Register for DIVI projection of divmodI 1767 RegMask Matcher::divI_proj_mask() { 1768 return INT_RAX_REG_mask(); 1769 } 1770 1771 // Register for MODI projection of divmodI 1772 RegMask Matcher::modI_proj_mask() { 1773 return INT_RDX_REG_mask(); 1774 } 1775 1776 // Register for DIVL projection of divmodL 1777 RegMask Matcher::divL_proj_mask() { 1778 return LONG_RAX_REG_mask(); 1779 } 1780 1781 // Register for MODL projection of divmodL 1782 RegMask Matcher::modL_proj_mask() { 1783 return LONG_RDX_REG_mask(); 1784 } 1785 1786 // Register for saving SP into on method handle invokes. Not used on x86_64. 1787 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1788 return NO_REG_mask(); 1789 } 1790 1791 %} 1792 1793 //----------ENCODING BLOCK----------------------------------------------------- 1794 // This block specifies the encoding classes used by the compiler to 1795 // output byte streams. Encoding classes are parameterized macros 1796 // used by Machine Instruction Nodes in order to generate the bit 1797 // encoding of the instruction. Operands specify their base encoding 1798 // interface with the interface keyword. There are currently 1799 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1800 // COND_INTER. REG_INTER causes an operand to generate a function 1801 // which returns its register number when queried. CONST_INTER causes 1802 // an operand to generate a function which returns the value of the 1803 // constant when queried. MEMORY_INTER causes an operand to generate 1804 // four functions which return the Base Register, the Index Register, 1805 // the Scale Value, and the Offset Value of the operand when queried. 1806 // COND_INTER causes an operand to generate six functions which return 1807 // the encoding code (ie - encoding bits for the instruction) 1808 // associated with each basic boolean condition for a conditional 1809 // instruction. 1810 // 1811 // Instructions specify two basic values for encoding. Again, a 1812 // function is available to check if the constant displacement is an 1813 // oop. They use the ins_encode keyword to specify their encoding 1814 // classes (which must be a sequence of enc_class names, and their 1815 // parameters, specified in the encoding block), and they use the 1816 // opcode keyword to specify, in order, their primary, secondary, and 1817 // tertiary opcode. Only the opcode sections which a particular 1818 // instruction needs for encoding need to be specified. 1819 encode %{ 1820 // Build emit functions for each basic byte or larger field in the 1821 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1822 // from C++ code in the enc_class source block. Emit functions will 1823 // live in the main source block for now. In future, we can 1824 // generalize this by adding a syntax that specifies the sizes of 1825 // fields in an order, so that the adlc can build the emit functions 1826 // automagically 1827 1828 // Emit primary opcode 1829 enc_class OpcP 1830 %{ 1831 emit_opcode(cbuf, $primary); 1832 %} 1833 1834 // Emit secondary opcode 1835 enc_class OpcS 1836 %{ 1837 emit_opcode(cbuf, $secondary); 1838 %} 1839 1840 // Emit tertiary opcode 1841 enc_class OpcT 1842 %{ 1843 emit_opcode(cbuf, $tertiary); 1844 %} 1845 1846 // Emit opcode directly 1847 enc_class Opcode(immI d8) 1848 %{ 1849 emit_opcode(cbuf, $d8$$constant); 1850 %} 1851 1852 // Emit size prefix 1853 enc_class SizePrefix 1854 %{ 1855 emit_opcode(cbuf, 0x66); 1856 %} 1857 1858 enc_class reg(rRegI reg) 1859 %{ 1860 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1861 %} 1862 1863 enc_class reg_reg(rRegI dst, rRegI src) 1864 %{ 1865 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1866 %} 1867 1868 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1869 %{ 1870 emit_opcode(cbuf, $opcode$$constant); 1871 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1872 %} 1873 1874 enc_class cdql_enc(no_rax_rdx_RegI div) 1875 %{ 1876 // Full implementation of Java idiv and irem; checks for 1877 // special case as described in JVM spec., p.243 & p.271. 1878 // 1879 // normal case special case 1880 // 1881 // input : rax: dividend min_int 1882 // reg: divisor -1 1883 // 1884 // output: rax: quotient (= rax idiv reg) min_int 1885 // rdx: remainder (= rax irem reg) 0 1886 // 1887 // Code sequnce: 1888 // 1889 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1890 // 5: 75 07/08 jne e <normal> 1891 // 7: 33 d2 xor %edx,%edx 1892 // [div >= 8 -> offset + 1] 1893 // [REX_B] 1894 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1895 // c: 74 03/04 je 11 <done> 1896 // 000000000000000e <normal>: 1897 // e: 99 cltd 1898 // [div >= 8 -> offset + 1] 1899 // [REX_B] 1900 // f: f7 f9 idiv $div 1901 // 0000000000000011 <done>: 1902 1903 // cmp $0x80000000,%eax 1904 emit_opcode(cbuf, 0x3d); 1905 emit_d8(cbuf, 0x00); 1906 emit_d8(cbuf, 0x00); 1907 emit_d8(cbuf, 0x00); 1908 emit_d8(cbuf, 0x80); 1909 1910 // jne e <normal> 1911 emit_opcode(cbuf, 0x75); 1912 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1913 1914 // xor %edx,%edx 1915 emit_opcode(cbuf, 0x33); 1916 emit_d8(cbuf, 0xD2); 1917 1918 // cmp $0xffffffffffffffff,%ecx 1919 if ($div$$reg >= 8) { 1920 emit_opcode(cbuf, Assembler::REX_B); 1921 } 1922 emit_opcode(cbuf, 0x83); 1923 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1924 emit_d8(cbuf, 0xFF); 1925 1926 // je 11 <done> 1927 emit_opcode(cbuf, 0x74); 1928 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1929 1930 // <normal> 1931 // cltd 1932 emit_opcode(cbuf, 0x99); 1933 1934 // idivl (note: must be emitted by the user of this rule) 1935 // <done> 1936 %} 1937 1938 enc_class cdqq_enc(no_rax_rdx_RegL div) 1939 %{ 1940 // Full implementation of Java ldiv and lrem; checks for 1941 // special case as described in JVM spec., p.243 & p.271. 1942 // 1943 // normal case special case 1944 // 1945 // input : rax: dividend min_long 1946 // reg: divisor -1 1947 // 1948 // output: rax: quotient (= rax idiv reg) min_long 1949 // rdx: remainder (= rax irem reg) 0 1950 // 1951 // Code sequnce: 1952 // 1953 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1954 // 7: 00 00 80 1955 // a: 48 39 d0 cmp %rdx,%rax 1956 // d: 75 08 jne 17 <normal> 1957 // f: 33 d2 xor %edx,%edx 1958 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1959 // 15: 74 05 je 1c <done> 1960 // 0000000000000017 <normal>: 1961 // 17: 48 99 cqto 1962 // 19: 48 f7 f9 idiv $div 1963 // 000000000000001c <done>: 1964 1965 // mov $0x8000000000000000,%rdx 1966 emit_opcode(cbuf, Assembler::REX_W); 1967 emit_opcode(cbuf, 0xBA); 1968 emit_d8(cbuf, 0x00); 1969 emit_d8(cbuf, 0x00); 1970 emit_d8(cbuf, 0x00); 1971 emit_d8(cbuf, 0x00); 1972 emit_d8(cbuf, 0x00); 1973 emit_d8(cbuf, 0x00); 1974 emit_d8(cbuf, 0x00); 1975 emit_d8(cbuf, 0x80); 1976 1977 // cmp %rdx,%rax 1978 emit_opcode(cbuf, Assembler::REX_W); 1979 emit_opcode(cbuf, 0x39); 1980 emit_d8(cbuf, 0xD0); 1981 1982 // jne 17 <normal> 1983 emit_opcode(cbuf, 0x75); 1984 emit_d8(cbuf, 0x08); 1985 1986 // xor %edx,%edx 1987 emit_opcode(cbuf, 0x33); 1988 emit_d8(cbuf, 0xD2); 1989 1990 // cmp $0xffffffffffffffff,$div 1991 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1992 emit_opcode(cbuf, 0x83); 1993 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1994 emit_d8(cbuf, 0xFF); 1995 1996 // je 1e <done> 1997 emit_opcode(cbuf, 0x74); 1998 emit_d8(cbuf, 0x05); 1999 2000 // <normal> 2001 // cqto 2002 emit_opcode(cbuf, Assembler::REX_W); 2003 emit_opcode(cbuf, 0x99); 2004 2005 // idivq (note: must be emitted by the user of this rule) 2006 // <done> 2007 %} 2008 2009 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2010 enc_class OpcSE(immI imm) 2011 %{ 2012 // Emit primary opcode and set sign-extend bit 2013 // Check for 8-bit immediate, and set sign extend bit in opcode 2014 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2015 emit_opcode(cbuf, $primary | 0x02); 2016 } else { 2017 // 32-bit immediate 2018 emit_opcode(cbuf, $primary); 2019 } 2020 %} 2021 2022 enc_class OpcSErm(rRegI dst, immI imm) 2023 %{ 2024 // OpcSEr/m 2025 int dstenc = $dst$$reg; 2026 if (dstenc >= 8) { 2027 emit_opcode(cbuf, Assembler::REX_B); 2028 dstenc -= 8; 2029 } 2030 // Emit primary opcode and set sign-extend bit 2031 // Check for 8-bit immediate, and set sign extend bit in opcode 2032 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2033 emit_opcode(cbuf, $primary | 0x02); 2034 } else { 2035 // 32-bit immediate 2036 emit_opcode(cbuf, $primary); 2037 } 2038 // Emit r/m byte with secondary opcode, after primary opcode. 2039 emit_rm(cbuf, 0x3, $secondary, dstenc); 2040 %} 2041 2042 enc_class OpcSErm_wide(rRegL dst, immI imm) 2043 %{ 2044 // OpcSEr/m 2045 int dstenc = $dst$$reg; 2046 if (dstenc < 8) { 2047 emit_opcode(cbuf, Assembler::REX_W); 2048 } else { 2049 emit_opcode(cbuf, Assembler::REX_WB); 2050 dstenc -= 8; 2051 } 2052 // Emit primary opcode and set sign-extend bit 2053 // Check for 8-bit immediate, and set sign extend bit in opcode 2054 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2055 emit_opcode(cbuf, $primary | 0x02); 2056 } else { 2057 // 32-bit immediate 2058 emit_opcode(cbuf, $primary); 2059 } 2060 // Emit r/m byte with secondary opcode, after primary opcode. 2061 emit_rm(cbuf, 0x3, $secondary, dstenc); 2062 %} 2063 2064 enc_class Con8or32(immI imm) 2065 %{ 2066 // Check for 8-bit immediate, and set sign extend bit in opcode 2067 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2068 $$$emit8$imm$$constant; 2069 } else { 2070 // 32-bit immediate 2071 $$$emit32$imm$$constant; 2072 } 2073 %} 2074 2075 enc_class opc2_reg(rRegI dst) 2076 %{ 2077 // BSWAP 2078 emit_cc(cbuf, $secondary, $dst$$reg); 2079 %} 2080 2081 enc_class opc3_reg(rRegI dst) 2082 %{ 2083 // BSWAP 2084 emit_cc(cbuf, $tertiary, $dst$$reg); 2085 %} 2086 2087 enc_class reg_opc(rRegI div) 2088 %{ 2089 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2090 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2091 %} 2092 2093 enc_class enc_cmov(cmpOp cop) 2094 %{ 2095 // CMOV 2096 $$$emit8$primary; 2097 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2098 %} 2099 2100 enc_class enc_PartialSubtypeCheck() 2101 %{ 2102 Register Rrdi = as_Register(RDI_enc); // result register 2103 Register Rrax = as_Register(RAX_enc); // super class 2104 Register Rrcx = as_Register(RCX_enc); // killed 2105 Register Rrsi = as_Register(RSI_enc); // sub class 2106 Label miss; 2107 const bool set_cond_codes = true; 2108 2109 MacroAssembler _masm(&cbuf); 2110 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2111 NULL, &miss, 2112 /*set_cond_codes:*/ true); 2113 if ($primary) { 2114 __ xorptr(Rrdi, Rrdi); 2115 } 2116 __ bind(miss); 2117 %} 2118 2119 enc_class clear_avx %{ 2120 debug_only(int off0 = cbuf.insts_size()); 2121 if (generate_vzeroupper(Compile::current())) { 2122 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2123 // Clear upper bits of YMM registers when current compiled code uses 2124 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2125 MacroAssembler _masm(&cbuf); 2126 __ vzeroupper(); 2127 } 2128 debug_only(int off1 = cbuf.insts_size()); 2129 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2130 %} 2131 2132 enc_class Java_To_Runtime(method meth) %{ 2133 // No relocation needed 2134 MacroAssembler _masm(&cbuf); 2135 __ mov64(r10, (int64_t) $meth$$method); 2136 __ call(r10); 2137 %} 2138 2139 enc_class Java_To_Interpreter(method meth) 2140 %{ 2141 // CALL Java_To_Interpreter 2142 // This is the instruction starting address for relocation info. 2143 cbuf.set_insts_mark(); 2144 $$$emit8$primary; 2145 // CALL directly to the runtime 2146 emit_d32_reloc(cbuf, 2147 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2148 runtime_call_Relocation::spec(), 2149 RELOC_DISP32); 2150 %} 2151 2152 enc_class Java_Static_Call(method meth) 2153 %{ 2154 // JAVA STATIC CALL 2155 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2156 // determine who we intended to call. 2157 cbuf.set_insts_mark(); 2158 $$$emit8$primary; 2159 2160 if (!_method) { 2161 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2162 runtime_call_Relocation::spec(), 2163 RELOC_DISP32); 2164 } else { 2165 int method_index = resolved_method_index(cbuf); 2166 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2167 : static_call_Relocation::spec(method_index); 2168 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2169 rspec, RELOC_DISP32); 2170 // Emit stubs for static call. 2171 address mark = cbuf.insts_mark(); 2172 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2173 if (stub == NULL) { 2174 ciEnv::current()->record_failure("CodeCache is full"); 2175 return; 2176 } 2177 #if INCLUDE_AOT 2178 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2179 #endif 2180 } 2181 %} 2182 2183 enc_class Java_Dynamic_Call(method meth) %{ 2184 MacroAssembler _masm(&cbuf); 2185 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2186 %} 2187 2188 enc_class Java_Compiled_Call(method meth) 2189 %{ 2190 // JAVA COMPILED CALL 2191 int disp = in_bytes(Method:: from_compiled_offset()); 2192 2193 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2194 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2195 2196 // callq *disp(%rax) 2197 cbuf.set_insts_mark(); 2198 $$$emit8$primary; 2199 if (disp < 0x80) { 2200 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2201 emit_d8(cbuf, disp); // Displacement 2202 } else { 2203 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2204 emit_d32(cbuf, disp); // Displacement 2205 } 2206 %} 2207 2208 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2209 %{ 2210 // SAL, SAR, SHR 2211 int dstenc = $dst$$reg; 2212 if (dstenc >= 8) { 2213 emit_opcode(cbuf, Assembler::REX_B); 2214 dstenc -= 8; 2215 } 2216 $$$emit8$primary; 2217 emit_rm(cbuf, 0x3, $secondary, dstenc); 2218 $$$emit8$shift$$constant; 2219 %} 2220 2221 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2222 %{ 2223 // SAL, SAR, SHR 2224 int dstenc = $dst$$reg; 2225 if (dstenc < 8) { 2226 emit_opcode(cbuf, Assembler::REX_W); 2227 } else { 2228 emit_opcode(cbuf, Assembler::REX_WB); 2229 dstenc -= 8; 2230 } 2231 $$$emit8$primary; 2232 emit_rm(cbuf, 0x3, $secondary, dstenc); 2233 $$$emit8$shift$$constant; 2234 %} 2235 2236 enc_class load_immI(rRegI dst, immI src) 2237 %{ 2238 int dstenc = $dst$$reg; 2239 if (dstenc >= 8) { 2240 emit_opcode(cbuf, Assembler::REX_B); 2241 dstenc -= 8; 2242 } 2243 emit_opcode(cbuf, 0xB8 | dstenc); 2244 $$$emit32$src$$constant; 2245 %} 2246 2247 enc_class load_immL(rRegL dst, immL src) 2248 %{ 2249 int dstenc = $dst$$reg; 2250 if (dstenc < 8) { 2251 emit_opcode(cbuf, Assembler::REX_W); 2252 } else { 2253 emit_opcode(cbuf, Assembler::REX_WB); 2254 dstenc -= 8; 2255 } 2256 emit_opcode(cbuf, 0xB8 | dstenc); 2257 emit_d64(cbuf, $src$$constant); 2258 %} 2259 2260 enc_class load_immUL32(rRegL dst, immUL32 src) 2261 %{ 2262 // same as load_immI, but this time we care about zeroes in the high word 2263 int dstenc = $dst$$reg; 2264 if (dstenc >= 8) { 2265 emit_opcode(cbuf, Assembler::REX_B); 2266 dstenc -= 8; 2267 } 2268 emit_opcode(cbuf, 0xB8 | dstenc); 2269 $$$emit32$src$$constant; 2270 %} 2271 2272 enc_class load_immL32(rRegL dst, immL32 src) 2273 %{ 2274 int dstenc = $dst$$reg; 2275 if (dstenc < 8) { 2276 emit_opcode(cbuf, Assembler::REX_W); 2277 } else { 2278 emit_opcode(cbuf, Assembler::REX_WB); 2279 dstenc -= 8; 2280 } 2281 emit_opcode(cbuf, 0xC7); 2282 emit_rm(cbuf, 0x03, 0x00, dstenc); 2283 $$$emit32$src$$constant; 2284 %} 2285 2286 enc_class load_immP31(rRegP dst, immP32 src) 2287 %{ 2288 // same as load_immI, but this time we care about zeroes in the high word 2289 int dstenc = $dst$$reg; 2290 if (dstenc >= 8) { 2291 emit_opcode(cbuf, Assembler::REX_B); 2292 dstenc -= 8; 2293 } 2294 emit_opcode(cbuf, 0xB8 | dstenc); 2295 $$$emit32$src$$constant; 2296 %} 2297 2298 enc_class load_immP(rRegP dst, immP src) 2299 %{ 2300 int dstenc = $dst$$reg; 2301 if (dstenc < 8) { 2302 emit_opcode(cbuf, Assembler::REX_W); 2303 } else { 2304 emit_opcode(cbuf, Assembler::REX_WB); 2305 dstenc -= 8; 2306 } 2307 emit_opcode(cbuf, 0xB8 | dstenc); 2308 // This next line should be generated from ADLC 2309 if ($src->constant_reloc() != relocInfo::none) { 2310 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2311 } else { 2312 emit_d64(cbuf, $src$$constant); 2313 } 2314 %} 2315 2316 enc_class Con32(immI src) 2317 %{ 2318 // Output immediate 2319 $$$emit32$src$$constant; 2320 %} 2321 2322 enc_class Con32F_as_bits(immF src) 2323 %{ 2324 // Output Float immediate bits 2325 jfloat jf = $src$$constant; 2326 jint jf_as_bits = jint_cast(jf); 2327 emit_d32(cbuf, jf_as_bits); 2328 %} 2329 2330 enc_class Con16(immI src) 2331 %{ 2332 // Output immediate 2333 $$$emit16$src$$constant; 2334 %} 2335 2336 // How is this different from Con32??? XXX 2337 enc_class Con_d32(immI src) 2338 %{ 2339 emit_d32(cbuf,$src$$constant); 2340 %} 2341 2342 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2343 // Output immediate memory reference 2344 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2345 emit_d32(cbuf, 0x00); 2346 %} 2347 2348 enc_class lock_prefix() 2349 %{ 2350 if (os::is_MP()) { 2351 emit_opcode(cbuf, 0xF0); // lock 2352 } 2353 %} 2354 2355 enc_class REX_mem(memory mem) 2356 %{ 2357 if ($mem$$base >= 8) { 2358 if ($mem$$index < 8) { 2359 emit_opcode(cbuf, Assembler::REX_B); 2360 } else { 2361 emit_opcode(cbuf, Assembler::REX_XB); 2362 } 2363 } else { 2364 if ($mem$$index >= 8) { 2365 emit_opcode(cbuf, Assembler::REX_X); 2366 } 2367 } 2368 %} 2369 2370 enc_class REX_mem_wide(memory mem) 2371 %{ 2372 if ($mem$$base >= 8) { 2373 if ($mem$$index < 8) { 2374 emit_opcode(cbuf, Assembler::REX_WB); 2375 } else { 2376 emit_opcode(cbuf, Assembler::REX_WXB); 2377 } 2378 } else { 2379 if ($mem$$index < 8) { 2380 emit_opcode(cbuf, Assembler::REX_W); 2381 } else { 2382 emit_opcode(cbuf, Assembler::REX_WX); 2383 } 2384 } 2385 %} 2386 2387 // for byte regs 2388 enc_class REX_breg(rRegI reg) 2389 %{ 2390 if ($reg$$reg >= 4) { 2391 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2392 } 2393 %} 2394 2395 // for byte regs 2396 enc_class REX_reg_breg(rRegI dst, rRegI src) 2397 %{ 2398 if ($dst$$reg < 8) { 2399 if ($src$$reg >= 4) { 2400 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2401 } 2402 } else { 2403 if ($src$$reg < 8) { 2404 emit_opcode(cbuf, Assembler::REX_R); 2405 } else { 2406 emit_opcode(cbuf, Assembler::REX_RB); 2407 } 2408 } 2409 %} 2410 2411 // for byte regs 2412 enc_class REX_breg_mem(rRegI reg, memory mem) 2413 %{ 2414 if ($reg$$reg < 8) { 2415 if ($mem$$base < 8) { 2416 if ($mem$$index >= 8) { 2417 emit_opcode(cbuf, Assembler::REX_X); 2418 } else if ($reg$$reg >= 4) { 2419 emit_opcode(cbuf, Assembler::REX); 2420 } 2421 } else { 2422 if ($mem$$index < 8) { 2423 emit_opcode(cbuf, Assembler::REX_B); 2424 } else { 2425 emit_opcode(cbuf, Assembler::REX_XB); 2426 } 2427 } 2428 } else { 2429 if ($mem$$base < 8) { 2430 if ($mem$$index < 8) { 2431 emit_opcode(cbuf, Assembler::REX_R); 2432 } else { 2433 emit_opcode(cbuf, Assembler::REX_RX); 2434 } 2435 } else { 2436 if ($mem$$index < 8) { 2437 emit_opcode(cbuf, Assembler::REX_RB); 2438 } else { 2439 emit_opcode(cbuf, Assembler::REX_RXB); 2440 } 2441 } 2442 } 2443 %} 2444 2445 enc_class REX_reg(rRegI reg) 2446 %{ 2447 if ($reg$$reg >= 8) { 2448 emit_opcode(cbuf, Assembler::REX_B); 2449 } 2450 %} 2451 2452 enc_class REX_reg_wide(rRegI reg) 2453 %{ 2454 if ($reg$$reg < 8) { 2455 emit_opcode(cbuf, Assembler::REX_W); 2456 } else { 2457 emit_opcode(cbuf, Assembler::REX_WB); 2458 } 2459 %} 2460 2461 enc_class REX_reg_reg(rRegI dst, rRegI src) 2462 %{ 2463 if ($dst$$reg < 8) { 2464 if ($src$$reg >= 8) { 2465 emit_opcode(cbuf, Assembler::REX_B); 2466 } 2467 } else { 2468 if ($src$$reg < 8) { 2469 emit_opcode(cbuf, Assembler::REX_R); 2470 } else { 2471 emit_opcode(cbuf, Assembler::REX_RB); 2472 } 2473 } 2474 %} 2475 2476 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2477 %{ 2478 if ($dst$$reg < 8) { 2479 if ($src$$reg < 8) { 2480 emit_opcode(cbuf, Assembler::REX_W); 2481 } else { 2482 emit_opcode(cbuf, Assembler::REX_WB); 2483 } 2484 } else { 2485 if ($src$$reg < 8) { 2486 emit_opcode(cbuf, Assembler::REX_WR); 2487 } else { 2488 emit_opcode(cbuf, Assembler::REX_WRB); 2489 } 2490 } 2491 %} 2492 2493 enc_class REX_reg_mem(rRegI reg, memory mem) 2494 %{ 2495 if ($reg$$reg < 8) { 2496 if ($mem$$base < 8) { 2497 if ($mem$$index >= 8) { 2498 emit_opcode(cbuf, Assembler::REX_X); 2499 } 2500 } else { 2501 if ($mem$$index < 8) { 2502 emit_opcode(cbuf, Assembler::REX_B); 2503 } else { 2504 emit_opcode(cbuf, Assembler::REX_XB); 2505 } 2506 } 2507 } else { 2508 if ($mem$$base < 8) { 2509 if ($mem$$index < 8) { 2510 emit_opcode(cbuf, Assembler::REX_R); 2511 } else { 2512 emit_opcode(cbuf, Assembler::REX_RX); 2513 } 2514 } else { 2515 if ($mem$$index < 8) { 2516 emit_opcode(cbuf, Assembler::REX_RB); 2517 } else { 2518 emit_opcode(cbuf, Assembler::REX_RXB); 2519 } 2520 } 2521 } 2522 %} 2523 2524 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2525 %{ 2526 if ($reg$$reg < 8) { 2527 if ($mem$$base < 8) { 2528 if ($mem$$index < 8) { 2529 emit_opcode(cbuf, Assembler::REX_W); 2530 } else { 2531 emit_opcode(cbuf, Assembler::REX_WX); 2532 } 2533 } else { 2534 if ($mem$$index < 8) { 2535 emit_opcode(cbuf, Assembler::REX_WB); 2536 } else { 2537 emit_opcode(cbuf, Assembler::REX_WXB); 2538 } 2539 } 2540 } else { 2541 if ($mem$$base < 8) { 2542 if ($mem$$index < 8) { 2543 emit_opcode(cbuf, Assembler::REX_WR); 2544 } else { 2545 emit_opcode(cbuf, Assembler::REX_WRX); 2546 } 2547 } else { 2548 if ($mem$$index < 8) { 2549 emit_opcode(cbuf, Assembler::REX_WRB); 2550 } else { 2551 emit_opcode(cbuf, Assembler::REX_WRXB); 2552 } 2553 } 2554 } 2555 %} 2556 2557 enc_class reg_mem(rRegI ereg, memory mem) 2558 %{ 2559 // High registers handle in encode_RegMem 2560 int reg = $ereg$$reg; 2561 int base = $mem$$base; 2562 int index = $mem$$index; 2563 int scale = $mem$$scale; 2564 int disp = $mem$$disp; 2565 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2566 2567 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2568 %} 2569 2570 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2571 %{ 2572 int rm_byte_opcode = $rm_opcode$$constant; 2573 2574 // High registers handle in encode_RegMem 2575 int base = $mem$$base; 2576 int index = $mem$$index; 2577 int scale = $mem$$scale; 2578 int displace = $mem$$disp; 2579 2580 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2581 // working with static 2582 // globals 2583 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2584 disp_reloc); 2585 %} 2586 2587 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2588 %{ 2589 int reg_encoding = $dst$$reg; 2590 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2591 int index = 0x04; // 0x04 indicates no index 2592 int scale = 0x00; // 0x00 indicates no scale 2593 int displace = $src1$$constant; // 0x00 indicates no displacement 2594 relocInfo::relocType disp_reloc = relocInfo::none; 2595 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2596 disp_reloc); 2597 %} 2598 2599 enc_class neg_reg(rRegI dst) 2600 %{ 2601 int dstenc = $dst$$reg; 2602 if (dstenc >= 8) { 2603 emit_opcode(cbuf, Assembler::REX_B); 2604 dstenc -= 8; 2605 } 2606 // NEG $dst 2607 emit_opcode(cbuf, 0xF7); 2608 emit_rm(cbuf, 0x3, 0x03, dstenc); 2609 %} 2610 2611 enc_class neg_reg_wide(rRegI dst) 2612 %{ 2613 int dstenc = $dst$$reg; 2614 if (dstenc < 8) { 2615 emit_opcode(cbuf, Assembler::REX_W); 2616 } else { 2617 emit_opcode(cbuf, Assembler::REX_WB); 2618 dstenc -= 8; 2619 } 2620 // NEG $dst 2621 emit_opcode(cbuf, 0xF7); 2622 emit_rm(cbuf, 0x3, 0x03, dstenc); 2623 %} 2624 2625 enc_class setLT_reg(rRegI dst) 2626 %{ 2627 int dstenc = $dst$$reg; 2628 if (dstenc >= 8) { 2629 emit_opcode(cbuf, Assembler::REX_B); 2630 dstenc -= 8; 2631 } else if (dstenc >= 4) { 2632 emit_opcode(cbuf, Assembler::REX); 2633 } 2634 // SETLT $dst 2635 emit_opcode(cbuf, 0x0F); 2636 emit_opcode(cbuf, 0x9C); 2637 emit_rm(cbuf, 0x3, 0x0, dstenc); 2638 %} 2639 2640 enc_class setNZ_reg(rRegI dst) 2641 %{ 2642 int dstenc = $dst$$reg; 2643 if (dstenc >= 8) { 2644 emit_opcode(cbuf, Assembler::REX_B); 2645 dstenc -= 8; 2646 } else if (dstenc >= 4) { 2647 emit_opcode(cbuf, Assembler::REX); 2648 } 2649 // SETNZ $dst 2650 emit_opcode(cbuf, 0x0F); 2651 emit_opcode(cbuf, 0x95); 2652 emit_rm(cbuf, 0x3, 0x0, dstenc); 2653 %} 2654 2655 2656 // Compare the lonogs and set -1, 0, or 1 into dst 2657 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2658 %{ 2659 int src1enc = $src1$$reg; 2660 int src2enc = $src2$$reg; 2661 int dstenc = $dst$$reg; 2662 2663 // cmpq $src1, $src2 2664 if (src1enc < 8) { 2665 if (src2enc < 8) { 2666 emit_opcode(cbuf, Assembler::REX_W); 2667 } else { 2668 emit_opcode(cbuf, Assembler::REX_WB); 2669 } 2670 } else { 2671 if (src2enc < 8) { 2672 emit_opcode(cbuf, Assembler::REX_WR); 2673 } else { 2674 emit_opcode(cbuf, Assembler::REX_WRB); 2675 } 2676 } 2677 emit_opcode(cbuf, 0x3B); 2678 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2679 2680 // movl $dst, -1 2681 if (dstenc >= 8) { 2682 emit_opcode(cbuf, Assembler::REX_B); 2683 } 2684 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2685 emit_d32(cbuf, -1); 2686 2687 // jl,s done 2688 emit_opcode(cbuf, 0x7C); 2689 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2690 2691 // setne $dst 2692 if (dstenc >= 4) { 2693 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2694 } 2695 emit_opcode(cbuf, 0x0F); 2696 emit_opcode(cbuf, 0x95); 2697 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2698 2699 // movzbl $dst, $dst 2700 if (dstenc >= 4) { 2701 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2702 } 2703 emit_opcode(cbuf, 0x0F); 2704 emit_opcode(cbuf, 0xB6); 2705 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2706 %} 2707 2708 enc_class Push_ResultXD(regD dst) %{ 2709 MacroAssembler _masm(&cbuf); 2710 __ fstp_d(Address(rsp, 0)); 2711 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2712 __ addptr(rsp, 8); 2713 %} 2714 2715 enc_class Push_SrcXD(regD src) %{ 2716 MacroAssembler _masm(&cbuf); 2717 __ subptr(rsp, 8); 2718 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2719 __ fld_d(Address(rsp, 0)); 2720 %} 2721 2722 2723 enc_class enc_rethrow() 2724 %{ 2725 cbuf.set_insts_mark(); 2726 emit_opcode(cbuf, 0xE9); // jmp entry 2727 emit_d32_reloc(cbuf, 2728 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2729 runtime_call_Relocation::spec(), 2730 RELOC_DISP32); 2731 %} 2732 2733 %} 2734 2735 2736 2737 //----------FRAME-------------------------------------------------------------- 2738 // Definition of frame structure and management information. 2739 // 2740 // S T A C K L A Y O U T Allocators stack-slot number 2741 // | (to get allocators register number 2742 // G Owned by | | v add OptoReg::stack0()) 2743 // r CALLER | | 2744 // o | +--------+ pad to even-align allocators stack-slot 2745 // w V | pad0 | numbers; owned by CALLER 2746 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2747 // h ^ | in | 5 2748 // | | args | 4 Holes in incoming args owned by SELF 2749 // | | | | 3 2750 // | | +--------+ 2751 // V | | old out| Empty on Intel, window on Sparc 2752 // | old |preserve| Must be even aligned. 2753 // | SP-+--------+----> Matcher::_old_SP, even aligned 2754 // | | in | 3 area for Intel ret address 2755 // Owned by |preserve| Empty on Sparc. 2756 // SELF +--------+ 2757 // | | pad2 | 2 pad to align old SP 2758 // | +--------+ 1 2759 // | | locks | 0 2760 // | +--------+----> OptoReg::stack0(), even aligned 2761 // | | pad1 | 11 pad to align new SP 2762 // | +--------+ 2763 // | | | 10 2764 // | | spills | 9 spills 2765 // V | | 8 (pad0 slot for callee) 2766 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2767 // ^ | out | 7 2768 // | | args | 6 Holes in outgoing args owned by CALLEE 2769 // Owned by +--------+ 2770 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2771 // | new |preserve| Must be even-aligned. 2772 // | SP-+--------+----> Matcher::_new_SP, even aligned 2773 // | | | 2774 // 2775 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2776 // known from SELF's arguments and the Java calling convention. 2777 // Region 6-7 is determined per call site. 2778 // Note 2: If the calling convention leaves holes in the incoming argument 2779 // area, those holes are owned by SELF. Holes in the outgoing area 2780 // are owned by the CALLEE. Holes should not be nessecary in the 2781 // incoming area, as the Java calling convention is completely under 2782 // the control of the AD file. Doubles can be sorted and packed to 2783 // avoid holes. Holes in the outgoing arguments may be nessecary for 2784 // varargs C calling conventions. 2785 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2786 // even aligned with pad0 as needed. 2787 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2788 // region 6-11 is even aligned; it may be padded out more so that 2789 // the region from SP to FP meets the minimum stack alignment. 2790 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2791 // alignment. Region 11, pad1, may be dynamically extended so that 2792 // SP meets the minimum alignment. 2793 2794 frame 2795 %{ 2796 // What direction does stack grow in (assumed to be same for C & Java) 2797 stack_direction(TOWARDS_LOW); 2798 2799 // These three registers define part of the calling convention 2800 // between compiled code and the interpreter. 2801 inline_cache_reg(RAX); // Inline Cache Register 2802 interpreter_method_oop_reg(RBX); // Method Oop Register when 2803 // calling interpreter 2804 2805 // Optional: name the operand used by cisc-spilling to access 2806 // [stack_pointer + offset] 2807 cisc_spilling_operand_name(indOffset32); 2808 2809 // Number of stack slots consumed by locking an object 2810 sync_stack_slots(2); 2811 2812 // Compiled code's Frame Pointer 2813 frame_pointer(RSP); 2814 2815 // Interpreter stores its frame pointer in a register which is 2816 // stored to the stack by I2CAdaptors. 2817 // I2CAdaptors convert from interpreted java to compiled java. 2818 interpreter_frame_pointer(RBP); 2819 2820 // Stack alignment requirement 2821 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2822 2823 // Number of stack slots between incoming argument block and the start of 2824 // a new frame. The PROLOG must add this many slots to the stack. The 2825 // EPILOG must remove this many slots. amd64 needs two slots for 2826 // return address. 2827 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2828 2829 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2830 // for calls to C. Supports the var-args backing area for register parms. 2831 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2832 2833 // The after-PROLOG location of the return address. Location of 2834 // return address specifies a type (REG or STACK) and a number 2835 // representing the register number (i.e. - use a register name) or 2836 // stack slot. 2837 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2838 // Otherwise, it is above the locks and verification slot and alignment word 2839 return_addr(STACK - 2 + 2840 align_up((Compile::current()->in_preserve_stack_slots() + 2841 Compile::current()->fixed_slots()), 2842 stack_alignment_in_slots())); 2843 2844 // Body of function which returns an integer array locating 2845 // arguments either in registers or in stack slots. Passed an array 2846 // of ideal registers called "sig" and a "length" count. Stack-slot 2847 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2848 // arguments for a CALLEE. Incoming stack arguments are 2849 // automatically biased by the preserve_stack_slots field above. 2850 2851 calling_convention 2852 %{ 2853 // No difference between ingoing/outgoing just pass false 2854 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2855 %} 2856 2857 c_calling_convention 2858 %{ 2859 // This is obviously always outgoing 2860 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2861 %} 2862 2863 // Location of compiled Java return values. Same as C for now. 2864 return_value 2865 %{ 2866 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2867 "only return normal values"); 2868 2869 static const int lo[Op_RegL + 1] = { 2870 0, 2871 0, 2872 RAX_num, // Op_RegN 2873 RAX_num, // Op_RegI 2874 RAX_num, // Op_RegP 2875 XMM0_num, // Op_RegF 2876 XMM0_num, // Op_RegD 2877 RAX_num // Op_RegL 2878 }; 2879 static const int hi[Op_RegL + 1] = { 2880 0, 2881 0, 2882 OptoReg::Bad, // Op_RegN 2883 OptoReg::Bad, // Op_RegI 2884 RAX_H_num, // Op_RegP 2885 OptoReg::Bad, // Op_RegF 2886 XMM0b_num, // Op_RegD 2887 RAX_H_num // Op_RegL 2888 }; 2889 // Excluded flags and vector registers. 2890 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2891 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2892 %} 2893 %} 2894 2895 //----------ATTRIBUTES--------------------------------------------------------- 2896 //----------Operand Attributes------------------------------------------------- 2897 op_attrib op_cost(0); // Required cost attribute 2898 2899 //----------Instruction Attributes--------------------------------------------- 2900 ins_attrib ins_cost(100); // Required cost attribute 2901 ins_attrib ins_size(8); // Required size attribute (in bits) 2902 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2903 // a non-matching short branch variant 2904 // of some long branch? 2905 ins_attrib ins_alignment(1); // Required alignment attribute (must 2906 // be a power of 2) specifies the 2907 // alignment that some part of the 2908 // instruction (not necessarily the 2909 // start) requires. If > 1, a 2910 // compute_padding() function must be 2911 // provided for the instruction 2912 2913 //----------OPERANDS----------------------------------------------------------- 2914 // Operand definitions must precede instruction definitions for correct parsing 2915 // in the ADLC because operands constitute user defined types which are used in 2916 // instruction definitions. 2917 2918 //----------Simple Operands---------------------------------------------------- 2919 // Immediate Operands 2920 // Integer Immediate 2921 operand immI() 2922 %{ 2923 match(ConI); 2924 2925 op_cost(10); 2926 format %{ %} 2927 interface(CONST_INTER); 2928 %} 2929 2930 // Constant for test vs zero 2931 operand immI0() 2932 %{ 2933 predicate(n->get_int() == 0); 2934 match(ConI); 2935 2936 op_cost(0); 2937 format %{ %} 2938 interface(CONST_INTER); 2939 %} 2940 2941 // Constant for increment 2942 operand immI1() 2943 %{ 2944 predicate(n->get_int() == 1); 2945 match(ConI); 2946 2947 op_cost(0); 2948 format %{ %} 2949 interface(CONST_INTER); 2950 %} 2951 2952 // Constant for decrement 2953 operand immI_M1() 2954 %{ 2955 predicate(n->get_int() == -1); 2956 match(ConI); 2957 2958 op_cost(0); 2959 format %{ %} 2960 interface(CONST_INTER); 2961 %} 2962 2963 // Valid scale values for addressing modes 2964 operand immI2() 2965 %{ 2966 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2967 match(ConI); 2968 2969 format %{ %} 2970 interface(CONST_INTER); 2971 %} 2972 2973 operand immI8() 2974 %{ 2975 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2976 match(ConI); 2977 2978 op_cost(5); 2979 format %{ %} 2980 interface(CONST_INTER); 2981 %} 2982 2983 operand immI16() 2984 %{ 2985 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2986 match(ConI); 2987 2988 op_cost(10); 2989 format %{ %} 2990 interface(CONST_INTER); 2991 %} 2992 2993 // Int Immediate non-negative 2994 operand immU31() 2995 %{ 2996 predicate(n->get_int() >= 0); 2997 match(ConI); 2998 2999 op_cost(0); 3000 format %{ %} 3001 interface(CONST_INTER); 3002 %} 3003 3004 // Constant for long shifts 3005 operand immI_32() 3006 %{ 3007 predicate( n->get_int() == 32 ); 3008 match(ConI); 3009 3010 op_cost(0); 3011 format %{ %} 3012 interface(CONST_INTER); 3013 %} 3014 3015 // Constant for long shifts 3016 operand immI_64() 3017 %{ 3018 predicate( n->get_int() == 64 ); 3019 match(ConI); 3020 3021 op_cost(0); 3022 format %{ %} 3023 interface(CONST_INTER); 3024 %} 3025 3026 // Pointer Immediate 3027 operand immP() 3028 %{ 3029 match(ConP); 3030 3031 op_cost(10); 3032 format %{ %} 3033 interface(CONST_INTER); 3034 %} 3035 3036 // NULL Pointer Immediate 3037 operand immP0() 3038 %{ 3039 predicate(n->get_ptr() == 0); 3040 match(ConP); 3041 3042 op_cost(5); 3043 format %{ %} 3044 interface(CONST_INTER); 3045 %} 3046 3047 // Pointer Immediate 3048 operand immN() %{ 3049 match(ConN); 3050 3051 op_cost(10); 3052 format %{ %} 3053 interface(CONST_INTER); 3054 %} 3055 3056 operand immNKlass() %{ 3057 match(ConNKlass); 3058 3059 op_cost(10); 3060 format %{ %} 3061 interface(CONST_INTER); 3062 %} 3063 3064 // NULL Pointer Immediate 3065 operand immN0() %{ 3066 predicate(n->get_narrowcon() == 0); 3067 match(ConN); 3068 3069 op_cost(5); 3070 format %{ %} 3071 interface(CONST_INTER); 3072 %} 3073 3074 operand immP31() 3075 %{ 3076 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3077 && (n->get_ptr() >> 31) == 0); 3078 match(ConP); 3079 3080 op_cost(5); 3081 format %{ %} 3082 interface(CONST_INTER); 3083 %} 3084 3085 3086 // Long Immediate 3087 operand immL() 3088 %{ 3089 match(ConL); 3090 3091 op_cost(20); 3092 format %{ %} 3093 interface(CONST_INTER); 3094 %} 3095 3096 // Long Immediate 8-bit 3097 operand immL8() 3098 %{ 3099 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3100 match(ConL); 3101 3102 op_cost(5); 3103 format %{ %} 3104 interface(CONST_INTER); 3105 %} 3106 3107 // Long Immediate 32-bit unsigned 3108 operand immUL32() 3109 %{ 3110 predicate(n->get_long() == (unsigned int) (n->get_long())); 3111 match(ConL); 3112 3113 op_cost(10); 3114 format %{ %} 3115 interface(CONST_INTER); 3116 %} 3117 3118 // Long Immediate 32-bit signed 3119 operand immL32() 3120 %{ 3121 predicate(n->get_long() == (int) (n->get_long())); 3122 match(ConL); 3123 3124 op_cost(15); 3125 format %{ %} 3126 interface(CONST_INTER); 3127 %} 3128 3129 // Long Immediate zero 3130 operand immL0() 3131 %{ 3132 predicate(n->get_long() == 0L); 3133 match(ConL); 3134 3135 op_cost(10); 3136 format %{ %} 3137 interface(CONST_INTER); 3138 %} 3139 3140 // Constant for increment 3141 operand immL1() 3142 %{ 3143 predicate(n->get_long() == 1); 3144 match(ConL); 3145 3146 format %{ %} 3147 interface(CONST_INTER); 3148 %} 3149 3150 // Constant for decrement 3151 operand immL_M1() 3152 %{ 3153 predicate(n->get_long() == -1); 3154 match(ConL); 3155 3156 format %{ %} 3157 interface(CONST_INTER); 3158 %} 3159 3160 // Long Immediate: the value 10 3161 operand immL10() 3162 %{ 3163 predicate(n->get_long() == 10); 3164 match(ConL); 3165 3166 format %{ %} 3167 interface(CONST_INTER); 3168 %} 3169 3170 // Long immediate from 0 to 127. 3171 // Used for a shorter form of long mul by 10. 3172 operand immL_127() 3173 %{ 3174 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3175 match(ConL); 3176 3177 op_cost(10); 3178 format %{ %} 3179 interface(CONST_INTER); 3180 %} 3181 3182 // Long Immediate: low 32-bit mask 3183 operand immL_32bits() 3184 %{ 3185 predicate(n->get_long() == 0xFFFFFFFFL); 3186 match(ConL); 3187 op_cost(20); 3188 3189 format %{ %} 3190 interface(CONST_INTER); 3191 %} 3192 3193 // Float Immediate zero 3194 operand immF0() 3195 %{ 3196 predicate(jint_cast(n->getf()) == 0); 3197 match(ConF); 3198 3199 op_cost(5); 3200 format %{ %} 3201 interface(CONST_INTER); 3202 %} 3203 3204 // Float Immediate 3205 operand immF() 3206 %{ 3207 match(ConF); 3208 3209 op_cost(15); 3210 format %{ %} 3211 interface(CONST_INTER); 3212 %} 3213 3214 // Double Immediate zero 3215 operand immD0() 3216 %{ 3217 predicate(jlong_cast(n->getd()) == 0); 3218 match(ConD); 3219 3220 op_cost(5); 3221 format %{ %} 3222 interface(CONST_INTER); 3223 %} 3224 3225 // Double Immediate 3226 operand immD() 3227 %{ 3228 match(ConD); 3229 3230 op_cost(15); 3231 format %{ %} 3232 interface(CONST_INTER); 3233 %} 3234 3235 // Immediates for special shifts (sign extend) 3236 3237 // Constants for increment 3238 operand immI_16() 3239 %{ 3240 predicate(n->get_int() == 16); 3241 match(ConI); 3242 3243 format %{ %} 3244 interface(CONST_INTER); 3245 %} 3246 3247 operand immI_24() 3248 %{ 3249 predicate(n->get_int() == 24); 3250 match(ConI); 3251 3252 format %{ %} 3253 interface(CONST_INTER); 3254 %} 3255 3256 // Constant for byte-wide masking 3257 operand immI_255() 3258 %{ 3259 predicate(n->get_int() == 255); 3260 match(ConI); 3261 3262 format %{ %} 3263 interface(CONST_INTER); 3264 %} 3265 3266 // Constant for short-wide masking 3267 operand immI_65535() 3268 %{ 3269 predicate(n->get_int() == 65535); 3270 match(ConI); 3271 3272 format %{ %} 3273 interface(CONST_INTER); 3274 %} 3275 3276 // Constant for byte-wide masking 3277 operand immL_255() 3278 %{ 3279 predicate(n->get_long() == 255); 3280 match(ConL); 3281 3282 format %{ %} 3283 interface(CONST_INTER); 3284 %} 3285 3286 // Constant for short-wide masking 3287 operand immL_65535() 3288 %{ 3289 predicate(n->get_long() == 65535); 3290 match(ConL); 3291 3292 format %{ %} 3293 interface(CONST_INTER); 3294 %} 3295 3296 // Register Operands 3297 // Integer Register 3298 operand rRegI() 3299 %{ 3300 constraint(ALLOC_IN_RC(int_reg)); 3301 match(RegI); 3302 3303 match(rax_RegI); 3304 match(rbx_RegI); 3305 match(rcx_RegI); 3306 match(rdx_RegI); 3307 match(rdi_RegI); 3308 3309 format %{ %} 3310 interface(REG_INTER); 3311 %} 3312 3313 // Special Registers 3314 operand rax_RegI() 3315 %{ 3316 constraint(ALLOC_IN_RC(int_rax_reg)); 3317 match(RegI); 3318 match(rRegI); 3319 3320 format %{ "RAX" %} 3321 interface(REG_INTER); 3322 %} 3323 3324 // Special Registers 3325 operand rbx_RegI() 3326 %{ 3327 constraint(ALLOC_IN_RC(int_rbx_reg)); 3328 match(RegI); 3329 match(rRegI); 3330 3331 format %{ "RBX" %} 3332 interface(REG_INTER); 3333 %} 3334 3335 operand rcx_RegI() 3336 %{ 3337 constraint(ALLOC_IN_RC(int_rcx_reg)); 3338 match(RegI); 3339 match(rRegI); 3340 3341 format %{ "RCX" %} 3342 interface(REG_INTER); 3343 %} 3344 3345 operand rdx_RegI() 3346 %{ 3347 constraint(ALLOC_IN_RC(int_rdx_reg)); 3348 match(RegI); 3349 match(rRegI); 3350 3351 format %{ "RDX" %} 3352 interface(REG_INTER); 3353 %} 3354 3355 operand rdi_RegI() 3356 %{ 3357 constraint(ALLOC_IN_RC(int_rdi_reg)); 3358 match(RegI); 3359 match(rRegI); 3360 3361 format %{ "RDI" %} 3362 interface(REG_INTER); 3363 %} 3364 3365 operand no_rcx_RegI() 3366 %{ 3367 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3368 match(RegI); 3369 match(rax_RegI); 3370 match(rbx_RegI); 3371 match(rdx_RegI); 3372 match(rdi_RegI); 3373 3374 format %{ %} 3375 interface(REG_INTER); 3376 %} 3377 3378 operand no_rax_rdx_RegI() 3379 %{ 3380 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3381 match(RegI); 3382 match(rbx_RegI); 3383 match(rcx_RegI); 3384 match(rdi_RegI); 3385 3386 format %{ %} 3387 interface(REG_INTER); 3388 %} 3389 3390 // Pointer Register 3391 operand any_RegP() 3392 %{ 3393 constraint(ALLOC_IN_RC(any_reg)); 3394 match(RegP); 3395 match(rax_RegP); 3396 match(rbx_RegP); 3397 match(rdi_RegP); 3398 match(rsi_RegP); 3399 match(rbp_RegP); 3400 match(r15_RegP); 3401 match(rRegP); 3402 3403 format %{ %} 3404 interface(REG_INTER); 3405 %} 3406 3407 operand rRegP() 3408 %{ 3409 constraint(ALLOC_IN_RC(ptr_reg)); 3410 match(RegP); 3411 match(rax_RegP); 3412 match(rbx_RegP); 3413 match(rdi_RegP); 3414 match(rsi_RegP); 3415 match(rbp_RegP); // See Q&A below about 3416 match(r15_RegP); // r15_RegP and rbp_RegP. 3417 3418 format %{ %} 3419 interface(REG_INTER); 3420 %} 3421 3422 operand rRegN() %{ 3423 constraint(ALLOC_IN_RC(int_reg)); 3424 match(RegN); 3425 3426 format %{ %} 3427 interface(REG_INTER); 3428 %} 3429 3430 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3431 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3432 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3433 // The output of an instruction is controlled by the allocator, which respects 3434 // register class masks, not match rules. Unless an instruction mentions 3435 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3436 // by the allocator as an input. 3437 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3438 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3439 // result, RBP is not included in the output of the instruction either. 3440 3441 operand no_rax_RegP() 3442 %{ 3443 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3444 match(RegP); 3445 match(rbx_RegP); 3446 match(rsi_RegP); 3447 match(rdi_RegP); 3448 3449 format %{ %} 3450 interface(REG_INTER); 3451 %} 3452 3453 // This operand is not allowed to use RBP even if 3454 // RBP is not used to hold the frame pointer. 3455 operand no_rbp_RegP() 3456 %{ 3457 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3458 match(RegP); 3459 match(rbx_RegP); 3460 match(rsi_RegP); 3461 match(rdi_RegP); 3462 3463 format %{ %} 3464 interface(REG_INTER); 3465 %} 3466 3467 operand no_rax_rbx_RegP() 3468 %{ 3469 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3470 match(RegP); 3471 match(rsi_RegP); 3472 match(rdi_RegP); 3473 3474 format %{ %} 3475 interface(REG_INTER); 3476 %} 3477 3478 // Special Registers 3479 // Return a pointer value 3480 operand rax_RegP() 3481 %{ 3482 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3483 match(RegP); 3484 match(rRegP); 3485 3486 format %{ %} 3487 interface(REG_INTER); 3488 %} 3489 3490 // Special Registers 3491 // Return a compressed pointer value 3492 operand rax_RegN() 3493 %{ 3494 constraint(ALLOC_IN_RC(int_rax_reg)); 3495 match(RegN); 3496 match(rRegN); 3497 3498 format %{ %} 3499 interface(REG_INTER); 3500 %} 3501 3502 // Used in AtomicAdd 3503 operand rbx_RegP() 3504 %{ 3505 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3506 match(RegP); 3507 match(rRegP); 3508 3509 format %{ %} 3510 interface(REG_INTER); 3511 %} 3512 3513 operand rsi_RegP() 3514 %{ 3515 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3516 match(RegP); 3517 match(rRegP); 3518 3519 format %{ %} 3520 interface(REG_INTER); 3521 %} 3522 3523 // Used in rep stosq 3524 operand rdi_RegP() 3525 %{ 3526 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3527 match(RegP); 3528 match(rRegP); 3529 3530 format %{ %} 3531 interface(REG_INTER); 3532 %} 3533 3534 operand r15_RegP() 3535 %{ 3536 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3537 match(RegP); 3538 match(rRegP); 3539 3540 format %{ %} 3541 interface(REG_INTER); 3542 %} 3543 3544 operand rex_RegP() 3545 %{ 3546 constraint(ALLOC_IN_RC(ptr_rex_reg)); 3547 match(RegP); 3548 match(rRegP); 3549 3550 format %{ %} 3551 interface(REG_INTER); 3552 %} 3553 3554 operand rRegL() 3555 %{ 3556 constraint(ALLOC_IN_RC(long_reg)); 3557 match(RegL); 3558 match(rax_RegL); 3559 match(rdx_RegL); 3560 3561 format %{ %} 3562 interface(REG_INTER); 3563 %} 3564 3565 // Special Registers 3566 operand no_rax_rdx_RegL() 3567 %{ 3568 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3569 match(RegL); 3570 match(rRegL); 3571 3572 format %{ %} 3573 interface(REG_INTER); 3574 %} 3575 3576 operand no_rax_RegL() 3577 %{ 3578 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3579 match(RegL); 3580 match(rRegL); 3581 match(rdx_RegL); 3582 3583 format %{ %} 3584 interface(REG_INTER); 3585 %} 3586 3587 operand no_rcx_RegL() 3588 %{ 3589 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3590 match(RegL); 3591 match(rRegL); 3592 3593 format %{ %} 3594 interface(REG_INTER); 3595 %} 3596 3597 operand rax_RegL() 3598 %{ 3599 constraint(ALLOC_IN_RC(long_rax_reg)); 3600 match(RegL); 3601 match(rRegL); 3602 3603 format %{ "RAX" %} 3604 interface(REG_INTER); 3605 %} 3606 3607 operand rcx_RegL() 3608 %{ 3609 constraint(ALLOC_IN_RC(long_rcx_reg)); 3610 match(RegL); 3611 match(rRegL); 3612 3613 format %{ %} 3614 interface(REG_INTER); 3615 %} 3616 3617 operand rdx_RegL() 3618 %{ 3619 constraint(ALLOC_IN_RC(long_rdx_reg)); 3620 match(RegL); 3621 match(rRegL); 3622 3623 format %{ %} 3624 interface(REG_INTER); 3625 %} 3626 3627 // Flags register, used as output of compare instructions 3628 operand rFlagsReg() 3629 %{ 3630 constraint(ALLOC_IN_RC(int_flags)); 3631 match(RegFlags); 3632 3633 format %{ "RFLAGS" %} 3634 interface(REG_INTER); 3635 %} 3636 3637 // Flags register, used as output of FLOATING POINT compare instructions 3638 operand rFlagsRegU() 3639 %{ 3640 constraint(ALLOC_IN_RC(int_flags)); 3641 match(RegFlags); 3642 3643 format %{ "RFLAGS_U" %} 3644 interface(REG_INTER); 3645 %} 3646 3647 operand rFlagsRegUCF() %{ 3648 constraint(ALLOC_IN_RC(int_flags)); 3649 match(RegFlags); 3650 predicate(false); 3651 3652 format %{ "RFLAGS_U_CF" %} 3653 interface(REG_INTER); 3654 %} 3655 3656 // Float register operands 3657 operand regF() %{ 3658 constraint(ALLOC_IN_RC(float_reg)); 3659 match(RegF); 3660 3661 format %{ %} 3662 interface(REG_INTER); 3663 %} 3664 3665 // Double register operands 3666 operand regD() %{ 3667 constraint(ALLOC_IN_RC(double_reg)); 3668 match(RegD); 3669 3670 format %{ %} 3671 interface(REG_INTER); 3672 %} 3673 3674 // Vectors 3675 operand vecS() %{ 3676 constraint(ALLOC_IN_RC(vectors_reg)); 3677 match(VecS); 3678 3679 format %{ %} 3680 interface(REG_INTER); 3681 %} 3682 3683 operand vecD() %{ 3684 constraint(ALLOC_IN_RC(vectord_reg)); 3685 match(VecD); 3686 3687 format %{ %} 3688 interface(REG_INTER); 3689 %} 3690 3691 operand vecX() %{ 3692 constraint(ALLOC_IN_RC(vectorx_reg)); 3693 match(VecX); 3694 3695 format %{ %} 3696 interface(REG_INTER); 3697 %} 3698 3699 operand vecY() %{ 3700 constraint(ALLOC_IN_RC(vectory_reg)); 3701 match(VecY); 3702 3703 format %{ %} 3704 interface(REG_INTER); 3705 %} 3706 3707 //----------Memory Operands---------------------------------------------------- 3708 // Direct Memory Operand 3709 // operand direct(immP addr) 3710 // %{ 3711 // match(addr); 3712 3713 // format %{ "[$addr]" %} 3714 // interface(MEMORY_INTER) %{ 3715 // base(0xFFFFFFFF); 3716 // index(0x4); 3717 // scale(0x0); 3718 // disp($addr); 3719 // %} 3720 // %} 3721 3722 // Indirect Memory Operand 3723 operand indirect(any_RegP reg) 3724 %{ 3725 constraint(ALLOC_IN_RC(ptr_reg)); 3726 match(reg); 3727 3728 format %{ "[$reg]" %} 3729 interface(MEMORY_INTER) %{ 3730 base($reg); 3731 index(0x4); 3732 scale(0x0); 3733 disp(0x0); 3734 %} 3735 %} 3736 3737 // Indirect Memory Plus Short Offset Operand 3738 operand indOffset8(any_RegP reg, immL8 off) 3739 %{ 3740 constraint(ALLOC_IN_RC(ptr_reg)); 3741 match(AddP reg off); 3742 3743 format %{ "[$reg + $off (8-bit)]" %} 3744 interface(MEMORY_INTER) %{ 3745 base($reg); 3746 index(0x4); 3747 scale(0x0); 3748 disp($off); 3749 %} 3750 %} 3751 3752 // Indirect Memory Plus Long Offset Operand 3753 operand indOffset32(any_RegP reg, immL32 off) 3754 %{ 3755 constraint(ALLOC_IN_RC(ptr_reg)); 3756 match(AddP reg off); 3757 3758 format %{ "[$reg + $off (32-bit)]" %} 3759 interface(MEMORY_INTER) %{ 3760 base($reg); 3761 index(0x4); 3762 scale(0x0); 3763 disp($off); 3764 %} 3765 %} 3766 3767 // Indirect Memory Plus Index Register Plus Offset Operand 3768 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3769 %{ 3770 constraint(ALLOC_IN_RC(ptr_reg)); 3771 match(AddP (AddP reg lreg) off); 3772 3773 op_cost(10); 3774 format %{"[$reg + $off + $lreg]" %} 3775 interface(MEMORY_INTER) %{ 3776 base($reg); 3777 index($lreg); 3778 scale(0x0); 3779 disp($off); 3780 %} 3781 %} 3782 3783 // Indirect Memory Plus Index Register Plus Offset Operand 3784 operand indIndex(any_RegP reg, rRegL lreg) 3785 %{ 3786 constraint(ALLOC_IN_RC(ptr_reg)); 3787 match(AddP reg lreg); 3788 3789 op_cost(10); 3790 format %{"[$reg + $lreg]" %} 3791 interface(MEMORY_INTER) %{ 3792 base($reg); 3793 index($lreg); 3794 scale(0x0); 3795 disp(0x0); 3796 %} 3797 %} 3798 3799 // Indirect Memory Times Scale Plus Index Register 3800 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3801 %{ 3802 constraint(ALLOC_IN_RC(ptr_reg)); 3803 match(AddP reg (LShiftL lreg scale)); 3804 3805 op_cost(10); 3806 format %{"[$reg + $lreg << $scale]" %} 3807 interface(MEMORY_INTER) %{ 3808 base($reg); 3809 index($lreg); 3810 scale($scale); 3811 disp(0x0); 3812 %} 3813 %} 3814 3815 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3816 %{ 3817 constraint(ALLOC_IN_RC(ptr_reg)); 3818 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3819 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3820 3821 op_cost(10); 3822 format %{"[$reg + pos $idx << $scale]" %} 3823 interface(MEMORY_INTER) %{ 3824 base($reg); 3825 index($idx); 3826 scale($scale); 3827 disp(0x0); 3828 %} 3829 %} 3830 3831 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3832 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3833 %{ 3834 constraint(ALLOC_IN_RC(ptr_reg)); 3835 match(AddP (AddP reg (LShiftL lreg scale)) off); 3836 3837 op_cost(10); 3838 format %{"[$reg + $off + $lreg << $scale]" %} 3839 interface(MEMORY_INTER) %{ 3840 base($reg); 3841 index($lreg); 3842 scale($scale); 3843 disp($off); 3844 %} 3845 %} 3846 3847 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3848 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3849 %{ 3850 constraint(ALLOC_IN_RC(ptr_reg)); 3851 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3852 match(AddP (AddP reg (ConvI2L idx)) off); 3853 3854 op_cost(10); 3855 format %{"[$reg + $off + $idx]" %} 3856 interface(MEMORY_INTER) %{ 3857 base($reg); 3858 index($idx); 3859 scale(0x0); 3860 disp($off); 3861 %} 3862 %} 3863 3864 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3865 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3866 %{ 3867 constraint(ALLOC_IN_RC(ptr_reg)); 3868 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3869 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3870 3871 op_cost(10); 3872 format %{"[$reg + $off + $idx << $scale]" %} 3873 interface(MEMORY_INTER) %{ 3874 base($reg); 3875 index($idx); 3876 scale($scale); 3877 disp($off); 3878 %} 3879 %} 3880 3881 // Indirect Narrow Oop Plus Offset Operand 3882 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3883 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3884 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3885 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3886 constraint(ALLOC_IN_RC(ptr_reg)); 3887 match(AddP (DecodeN reg) off); 3888 3889 op_cost(10); 3890 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3891 interface(MEMORY_INTER) %{ 3892 base(0xc); // R12 3893 index($reg); 3894 scale(0x3); 3895 disp($off); 3896 %} 3897 %} 3898 3899 // Indirect Memory Operand 3900 operand indirectNarrow(rRegN reg) 3901 %{ 3902 predicate(Universe::narrow_oop_shift() == 0); 3903 constraint(ALLOC_IN_RC(ptr_reg)); 3904 match(DecodeN reg); 3905 3906 format %{ "[$reg]" %} 3907 interface(MEMORY_INTER) %{ 3908 base($reg); 3909 index(0x4); 3910 scale(0x0); 3911 disp(0x0); 3912 %} 3913 %} 3914 3915 // Indirect Memory Plus Short Offset Operand 3916 operand indOffset8Narrow(rRegN reg, immL8 off) 3917 %{ 3918 predicate(Universe::narrow_oop_shift() == 0); 3919 constraint(ALLOC_IN_RC(ptr_reg)); 3920 match(AddP (DecodeN reg) off); 3921 3922 format %{ "[$reg + $off (8-bit)]" %} 3923 interface(MEMORY_INTER) %{ 3924 base($reg); 3925 index(0x4); 3926 scale(0x0); 3927 disp($off); 3928 %} 3929 %} 3930 3931 // Indirect Memory Plus Long Offset Operand 3932 operand indOffset32Narrow(rRegN reg, immL32 off) 3933 %{ 3934 predicate(Universe::narrow_oop_shift() == 0); 3935 constraint(ALLOC_IN_RC(ptr_reg)); 3936 match(AddP (DecodeN reg) off); 3937 3938 format %{ "[$reg + $off (32-bit)]" %} 3939 interface(MEMORY_INTER) %{ 3940 base($reg); 3941 index(0x4); 3942 scale(0x0); 3943 disp($off); 3944 %} 3945 %} 3946 3947 // Indirect Memory Plus Index Register Plus Offset Operand 3948 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3949 %{ 3950 predicate(Universe::narrow_oop_shift() == 0); 3951 constraint(ALLOC_IN_RC(ptr_reg)); 3952 match(AddP (AddP (DecodeN reg) lreg) off); 3953 3954 op_cost(10); 3955 format %{"[$reg + $off + $lreg]" %} 3956 interface(MEMORY_INTER) %{ 3957 base($reg); 3958 index($lreg); 3959 scale(0x0); 3960 disp($off); 3961 %} 3962 %} 3963 3964 // Indirect Memory Plus Index Register Plus Offset Operand 3965 operand indIndexNarrow(rRegN reg, rRegL lreg) 3966 %{ 3967 predicate(Universe::narrow_oop_shift() == 0); 3968 constraint(ALLOC_IN_RC(ptr_reg)); 3969 match(AddP (DecodeN reg) lreg); 3970 3971 op_cost(10); 3972 format %{"[$reg + $lreg]" %} 3973 interface(MEMORY_INTER) %{ 3974 base($reg); 3975 index($lreg); 3976 scale(0x0); 3977 disp(0x0); 3978 %} 3979 %} 3980 3981 // Indirect Memory Times Scale Plus Index Register 3982 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3983 %{ 3984 predicate(Universe::narrow_oop_shift() == 0); 3985 constraint(ALLOC_IN_RC(ptr_reg)); 3986 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3987 3988 op_cost(10); 3989 format %{"[$reg + $lreg << $scale]" %} 3990 interface(MEMORY_INTER) %{ 3991 base($reg); 3992 index($lreg); 3993 scale($scale); 3994 disp(0x0); 3995 %} 3996 %} 3997 3998 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3999 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4000 %{ 4001 predicate(Universe::narrow_oop_shift() == 0); 4002 constraint(ALLOC_IN_RC(ptr_reg)); 4003 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4004 4005 op_cost(10); 4006 format %{"[$reg + $off + $lreg << $scale]" %} 4007 interface(MEMORY_INTER) %{ 4008 base($reg); 4009 index($lreg); 4010 scale($scale); 4011 disp($off); 4012 %} 4013 %} 4014 4015 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4016 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4017 %{ 4018 constraint(ALLOC_IN_RC(ptr_reg)); 4019 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4020 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4021 4022 op_cost(10); 4023 format %{"[$reg + $off + $idx]" %} 4024 interface(MEMORY_INTER) %{ 4025 base($reg); 4026 index($idx); 4027 scale(0x0); 4028 disp($off); 4029 %} 4030 %} 4031 4032 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4033 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4034 %{ 4035 constraint(ALLOC_IN_RC(ptr_reg)); 4036 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4037 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4038 4039 op_cost(10); 4040 format %{"[$reg + $off + $idx << $scale]" %} 4041 interface(MEMORY_INTER) %{ 4042 base($reg); 4043 index($idx); 4044 scale($scale); 4045 disp($off); 4046 %} 4047 %} 4048 4049 //----------Special Memory Operands-------------------------------------------- 4050 // Stack Slot Operand - This operand is used for loading and storing temporary 4051 // values on the stack where a match requires a value to 4052 // flow through memory. 4053 operand stackSlotP(sRegP reg) 4054 %{ 4055 constraint(ALLOC_IN_RC(stack_slots)); 4056 // No match rule because this operand is only generated in matching 4057 4058 format %{ "[$reg]" %} 4059 interface(MEMORY_INTER) %{ 4060 base(0x4); // RSP 4061 index(0x4); // No Index 4062 scale(0x0); // No Scale 4063 disp($reg); // Stack Offset 4064 %} 4065 %} 4066 4067 operand stackSlotI(sRegI reg) 4068 %{ 4069 constraint(ALLOC_IN_RC(stack_slots)); 4070 // No match rule because this operand is only generated in matching 4071 4072 format %{ "[$reg]" %} 4073 interface(MEMORY_INTER) %{ 4074 base(0x4); // RSP 4075 index(0x4); // No Index 4076 scale(0x0); // No Scale 4077 disp($reg); // Stack Offset 4078 %} 4079 %} 4080 4081 operand stackSlotF(sRegF reg) 4082 %{ 4083 constraint(ALLOC_IN_RC(stack_slots)); 4084 // No match rule because this operand is only generated in matching 4085 4086 format %{ "[$reg]" %} 4087 interface(MEMORY_INTER) %{ 4088 base(0x4); // RSP 4089 index(0x4); // No Index 4090 scale(0x0); // No Scale 4091 disp($reg); // Stack Offset 4092 %} 4093 %} 4094 4095 operand stackSlotD(sRegD reg) 4096 %{ 4097 constraint(ALLOC_IN_RC(stack_slots)); 4098 // No match rule because this operand is only generated in matching 4099 4100 format %{ "[$reg]" %} 4101 interface(MEMORY_INTER) %{ 4102 base(0x4); // RSP 4103 index(0x4); // No Index 4104 scale(0x0); // No Scale 4105 disp($reg); // Stack Offset 4106 %} 4107 %} 4108 operand stackSlotL(sRegL reg) 4109 %{ 4110 constraint(ALLOC_IN_RC(stack_slots)); 4111 // No match rule because this operand is only generated in matching 4112 4113 format %{ "[$reg]" %} 4114 interface(MEMORY_INTER) %{ 4115 base(0x4); // RSP 4116 index(0x4); // No Index 4117 scale(0x0); // No Scale 4118 disp($reg); // Stack Offset 4119 %} 4120 %} 4121 4122 //----------Conditional Branch Operands---------------------------------------- 4123 // Comparison Op - This is the operation of the comparison, and is limited to 4124 // the following set of codes: 4125 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4126 // 4127 // Other attributes of the comparison, such as unsignedness, are specified 4128 // by the comparison instruction that sets a condition code flags register. 4129 // That result is represented by a flags operand whose subtype is appropriate 4130 // to the unsignedness (etc.) of the comparison. 4131 // 4132 // Later, the instruction which matches both the Comparison Op (a Bool) and 4133 // the flags (produced by the Cmp) specifies the coding of the comparison op 4134 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4135 4136 // Comparision Code 4137 operand cmpOp() 4138 %{ 4139 match(Bool); 4140 4141 format %{ "" %} 4142 interface(COND_INTER) %{ 4143 equal(0x4, "e"); 4144 not_equal(0x5, "ne"); 4145 less(0xC, "l"); 4146 greater_equal(0xD, "ge"); 4147 less_equal(0xE, "le"); 4148 greater(0xF, "g"); 4149 overflow(0x0, "o"); 4150 no_overflow(0x1, "no"); 4151 %} 4152 %} 4153 4154 // Comparison Code, unsigned compare. Used by FP also, with 4155 // C2 (unordered) turned into GT or LT already. The other bits 4156 // C0 and C3 are turned into Carry & Zero flags. 4157 operand cmpOpU() 4158 %{ 4159 match(Bool); 4160 4161 format %{ "" %} 4162 interface(COND_INTER) %{ 4163 equal(0x4, "e"); 4164 not_equal(0x5, "ne"); 4165 less(0x2, "b"); 4166 greater_equal(0x3, "nb"); 4167 less_equal(0x6, "be"); 4168 greater(0x7, "nbe"); 4169 overflow(0x0, "o"); 4170 no_overflow(0x1, "no"); 4171 %} 4172 %} 4173 4174 4175 // Floating comparisons that don't require any fixup for the unordered case 4176 operand cmpOpUCF() %{ 4177 match(Bool); 4178 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4179 n->as_Bool()->_test._test == BoolTest::ge || 4180 n->as_Bool()->_test._test == BoolTest::le || 4181 n->as_Bool()->_test._test == BoolTest::gt); 4182 format %{ "" %} 4183 interface(COND_INTER) %{ 4184 equal(0x4, "e"); 4185 not_equal(0x5, "ne"); 4186 less(0x2, "b"); 4187 greater_equal(0x3, "nb"); 4188 less_equal(0x6, "be"); 4189 greater(0x7, "nbe"); 4190 overflow(0x0, "o"); 4191 no_overflow(0x1, "no"); 4192 %} 4193 %} 4194 4195 4196 // Floating comparisons that can be fixed up with extra conditional jumps 4197 operand cmpOpUCF2() %{ 4198 match(Bool); 4199 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4200 n->as_Bool()->_test._test == BoolTest::eq); 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 //----------OPERAND CLASSES---------------------------------------------------- 4216 // Operand Classes are groups of operands that are used as to simplify 4217 // instruction definitions by not requiring the AD writer to specify separate 4218 // instructions for every form of operand when the instruction accepts 4219 // multiple operand types with the same basic encoding and format. The classic 4220 // case of this is memory operands. 4221 4222 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4223 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4224 indCompressedOopOffset, 4225 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4226 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4227 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4228 4229 //----------PIPELINE----------------------------------------------------------- 4230 // Rules which define the behavior of the target architectures pipeline. 4231 pipeline %{ 4232 4233 //----------ATTRIBUTES--------------------------------------------------------- 4234 attributes %{ 4235 variable_size_instructions; // Fixed size instructions 4236 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4237 instruction_unit_size = 1; // An instruction is 1 bytes long 4238 instruction_fetch_unit_size = 16; // The processor fetches one line 4239 instruction_fetch_units = 1; // of 16 bytes 4240 4241 // List of nop instructions 4242 nops( MachNop ); 4243 %} 4244 4245 //----------RESOURCES---------------------------------------------------------- 4246 // Resources are the functional units available to the machine 4247 4248 // Generic P2/P3 pipeline 4249 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4250 // 3 instructions decoded per cycle. 4251 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4252 // 3 ALU op, only ALU0 handles mul instructions. 4253 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4254 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4255 BR, FPU, 4256 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4257 4258 //----------PIPELINE DESCRIPTION----------------------------------------------- 4259 // Pipeline Description specifies the stages in the machine's pipeline 4260 4261 // Generic P2/P3 pipeline 4262 pipe_desc(S0, S1, S2, S3, S4, S5); 4263 4264 //----------PIPELINE CLASSES--------------------------------------------------- 4265 // Pipeline Classes describe the stages in which input and output are 4266 // referenced by the hardware pipeline. 4267 4268 // Naming convention: ialu or fpu 4269 // Then: _reg 4270 // Then: _reg if there is a 2nd register 4271 // Then: _long if it's a pair of instructions implementing a long 4272 // Then: _fat if it requires the big decoder 4273 // Or: _mem if it requires the big decoder and a memory unit. 4274 4275 // Integer ALU reg operation 4276 pipe_class ialu_reg(rRegI dst) 4277 %{ 4278 single_instruction; 4279 dst : S4(write); 4280 dst : S3(read); 4281 DECODE : S0; // any decoder 4282 ALU : S3; // any alu 4283 %} 4284 4285 // Long ALU reg operation 4286 pipe_class ialu_reg_long(rRegL dst) 4287 %{ 4288 instruction_count(2); 4289 dst : S4(write); 4290 dst : S3(read); 4291 DECODE : S0(2); // any 2 decoders 4292 ALU : S3(2); // both alus 4293 %} 4294 4295 // Integer ALU reg operation using big decoder 4296 pipe_class ialu_reg_fat(rRegI dst) 4297 %{ 4298 single_instruction; 4299 dst : S4(write); 4300 dst : S3(read); 4301 D0 : S0; // big decoder only 4302 ALU : S3; // any alu 4303 %} 4304 4305 // Long ALU reg operation using big decoder 4306 pipe_class ialu_reg_long_fat(rRegL dst) 4307 %{ 4308 instruction_count(2); 4309 dst : S4(write); 4310 dst : S3(read); 4311 D0 : S0(2); // big decoder only; twice 4312 ALU : S3(2); // any 2 alus 4313 %} 4314 4315 // Integer ALU reg-reg operation 4316 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4317 %{ 4318 single_instruction; 4319 dst : S4(write); 4320 src : S3(read); 4321 DECODE : S0; // any decoder 4322 ALU : S3; // any alu 4323 %} 4324 4325 // Long ALU reg-reg operation 4326 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4327 %{ 4328 instruction_count(2); 4329 dst : S4(write); 4330 src : S3(read); 4331 DECODE : S0(2); // any 2 decoders 4332 ALU : S3(2); // both alus 4333 %} 4334 4335 // Integer ALU reg-reg operation 4336 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4337 %{ 4338 single_instruction; 4339 dst : S4(write); 4340 src : S3(read); 4341 D0 : S0; // big decoder only 4342 ALU : S3; // any alu 4343 %} 4344 4345 // Long ALU reg-reg operation 4346 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4347 %{ 4348 instruction_count(2); 4349 dst : S4(write); 4350 src : S3(read); 4351 D0 : S0(2); // big decoder only; twice 4352 ALU : S3(2); // both alus 4353 %} 4354 4355 // Integer ALU reg-mem operation 4356 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4357 %{ 4358 single_instruction; 4359 dst : S5(write); 4360 mem : S3(read); 4361 D0 : S0; // big decoder only 4362 ALU : S4; // any alu 4363 MEM : S3; // any mem 4364 %} 4365 4366 // Integer mem operation (prefetch) 4367 pipe_class ialu_mem(memory mem) 4368 %{ 4369 single_instruction; 4370 mem : S3(read); 4371 D0 : S0; // big decoder only 4372 MEM : S3; // any mem 4373 %} 4374 4375 // Integer Store to Memory 4376 pipe_class ialu_mem_reg(memory mem, rRegI src) 4377 %{ 4378 single_instruction; 4379 mem : S3(read); 4380 src : S5(read); 4381 D0 : S0; // big decoder only 4382 ALU : S4; // any alu 4383 MEM : S3; 4384 %} 4385 4386 // // Long Store to Memory 4387 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4388 // %{ 4389 // instruction_count(2); 4390 // mem : S3(read); 4391 // src : S5(read); 4392 // D0 : S0(2); // big decoder only; twice 4393 // ALU : S4(2); // any 2 alus 4394 // MEM : S3(2); // Both mems 4395 // %} 4396 4397 // Integer Store to Memory 4398 pipe_class ialu_mem_imm(memory mem) 4399 %{ 4400 single_instruction; 4401 mem : S3(read); 4402 D0 : S0; // big decoder only 4403 ALU : S4; // any alu 4404 MEM : S3; 4405 %} 4406 4407 // Integer ALU0 reg-reg operation 4408 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4409 %{ 4410 single_instruction; 4411 dst : S4(write); 4412 src : S3(read); 4413 D0 : S0; // Big decoder only 4414 ALU0 : S3; // only alu0 4415 %} 4416 4417 // Integer ALU0 reg-mem operation 4418 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4419 %{ 4420 single_instruction; 4421 dst : S5(write); 4422 mem : S3(read); 4423 D0 : S0; // big decoder only 4424 ALU0 : S4; // ALU0 only 4425 MEM : S3; // any mem 4426 %} 4427 4428 // Integer ALU reg-reg operation 4429 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4430 %{ 4431 single_instruction; 4432 cr : S4(write); 4433 src1 : S3(read); 4434 src2 : S3(read); 4435 DECODE : S0; // any decoder 4436 ALU : S3; // any alu 4437 %} 4438 4439 // Integer ALU reg-imm operation 4440 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4441 %{ 4442 single_instruction; 4443 cr : S4(write); 4444 src1 : S3(read); 4445 DECODE : S0; // any decoder 4446 ALU : S3; // any alu 4447 %} 4448 4449 // Integer ALU reg-mem operation 4450 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4451 %{ 4452 single_instruction; 4453 cr : S4(write); 4454 src1 : S3(read); 4455 src2 : S3(read); 4456 D0 : S0; // big decoder only 4457 ALU : S4; // any alu 4458 MEM : S3; 4459 %} 4460 4461 // Conditional move reg-reg 4462 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4463 %{ 4464 instruction_count(4); 4465 y : S4(read); 4466 q : S3(read); 4467 p : S3(read); 4468 DECODE : S0(4); // any decoder 4469 %} 4470 4471 // Conditional move reg-reg 4472 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4473 %{ 4474 single_instruction; 4475 dst : S4(write); 4476 src : S3(read); 4477 cr : S3(read); 4478 DECODE : S0; // any decoder 4479 %} 4480 4481 // Conditional move reg-mem 4482 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4483 %{ 4484 single_instruction; 4485 dst : S4(write); 4486 src : S3(read); 4487 cr : S3(read); 4488 DECODE : S0; // any decoder 4489 MEM : S3; 4490 %} 4491 4492 // Conditional move reg-reg long 4493 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4494 %{ 4495 single_instruction; 4496 dst : S4(write); 4497 src : S3(read); 4498 cr : S3(read); 4499 DECODE : S0(2); // any 2 decoders 4500 %} 4501 4502 // XXX 4503 // // Conditional move double reg-reg 4504 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4505 // %{ 4506 // single_instruction; 4507 // dst : S4(write); 4508 // src : S3(read); 4509 // cr : S3(read); 4510 // DECODE : S0; // any decoder 4511 // %} 4512 4513 // Float reg-reg operation 4514 pipe_class fpu_reg(regD dst) 4515 %{ 4516 instruction_count(2); 4517 dst : S3(read); 4518 DECODE : S0(2); // any 2 decoders 4519 FPU : S3; 4520 %} 4521 4522 // Float reg-reg operation 4523 pipe_class fpu_reg_reg(regD dst, regD src) 4524 %{ 4525 instruction_count(2); 4526 dst : S4(write); 4527 src : S3(read); 4528 DECODE : S0(2); // any 2 decoders 4529 FPU : S3; 4530 %} 4531 4532 // Float reg-reg operation 4533 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4534 %{ 4535 instruction_count(3); 4536 dst : S4(write); 4537 src1 : S3(read); 4538 src2 : S3(read); 4539 DECODE : S0(3); // any 3 decoders 4540 FPU : S3(2); 4541 %} 4542 4543 // Float reg-reg operation 4544 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4545 %{ 4546 instruction_count(4); 4547 dst : S4(write); 4548 src1 : S3(read); 4549 src2 : S3(read); 4550 src3 : S3(read); 4551 DECODE : S0(4); // any 3 decoders 4552 FPU : S3(2); 4553 %} 4554 4555 // Float reg-reg operation 4556 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4557 %{ 4558 instruction_count(4); 4559 dst : S4(write); 4560 src1 : S3(read); 4561 src2 : S3(read); 4562 src3 : S3(read); 4563 DECODE : S1(3); // any 3 decoders 4564 D0 : S0; // Big decoder only 4565 FPU : S3(2); 4566 MEM : S3; 4567 %} 4568 4569 // Float reg-mem operation 4570 pipe_class fpu_reg_mem(regD dst, memory mem) 4571 %{ 4572 instruction_count(2); 4573 dst : S5(write); 4574 mem : S3(read); 4575 D0 : S0; // big decoder only 4576 DECODE : S1; // any decoder for FPU POP 4577 FPU : S4; 4578 MEM : S3; // any mem 4579 %} 4580 4581 // Float reg-mem operation 4582 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4583 %{ 4584 instruction_count(3); 4585 dst : S5(write); 4586 src1 : S3(read); 4587 mem : S3(read); 4588 D0 : S0; // big decoder only 4589 DECODE : S1(2); // any decoder for FPU POP 4590 FPU : S4; 4591 MEM : S3; // any mem 4592 %} 4593 4594 // Float mem-reg operation 4595 pipe_class fpu_mem_reg(memory mem, regD src) 4596 %{ 4597 instruction_count(2); 4598 src : S5(read); 4599 mem : S3(read); 4600 DECODE : S0; // any decoder for FPU PUSH 4601 D0 : S1; // big decoder only 4602 FPU : S4; 4603 MEM : S3; // any mem 4604 %} 4605 4606 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4607 %{ 4608 instruction_count(3); 4609 src1 : S3(read); 4610 src2 : S3(read); 4611 mem : S3(read); 4612 DECODE : S0(2); // any decoder for FPU PUSH 4613 D0 : S1; // big decoder only 4614 FPU : S4; 4615 MEM : S3; // any mem 4616 %} 4617 4618 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4619 %{ 4620 instruction_count(3); 4621 src1 : S3(read); 4622 src2 : S3(read); 4623 mem : S4(read); 4624 DECODE : S0; // any decoder for FPU PUSH 4625 D0 : S0(2); // big decoder only 4626 FPU : S4; 4627 MEM : S3(2); // any mem 4628 %} 4629 4630 pipe_class fpu_mem_mem(memory dst, memory src1) 4631 %{ 4632 instruction_count(2); 4633 src1 : S3(read); 4634 dst : S4(read); 4635 D0 : S0(2); // big decoder only 4636 MEM : S3(2); // any mem 4637 %} 4638 4639 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4640 %{ 4641 instruction_count(3); 4642 src1 : S3(read); 4643 src2 : S3(read); 4644 dst : S4(read); 4645 D0 : S0(3); // big decoder only 4646 FPU : S4; 4647 MEM : S3(3); // any mem 4648 %} 4649 4650 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4651 %{ 4652 instruction_count(3); 4653 src1 : S4(read); 4654 mem : S4(read); 4655 DECODE : S0; // any decoder for FPU PUSH 4656 D0 : S0(2); // big decoder only 4657 FPU : S4; 4658 MEM : S3(2); // any mem 4659 %} 4660 4661 // Float load constant 4662 pipe_class fpu_reg_con(regD dst) 4663 %{ 4664 instruction_count(2); 4665 dst : S5(write); 4666 D0 : S0; // big decoder only for the load 4667 DECODE : S1; // any decoder for FPU POP 4668 FPU : S4; 4669 MEM : S3; // any mem 4670 %} 4671 4672 // Float load constant 4673 pipe_class fpu_reg_reg_con(regD dst, regD src) 4674 %{ 4675 instruction_count(3); 4676 dst : S5(write); 4677 src : S3(read); 4678 D0 : S0; // big decoder only for the load 4679 DECODE : S1(2); // any decoder for FPU POP 4680 FPU : S4; 4681 MEM : S3; // any mem 4682 %} 4683 4684 // UnConditional branch 4685 pipe_class pipe_jmp(label labl) 4686 %{ 4687 single_instruction; 4688 BR : S3; 4689 %} 4690 4691 // Conditional branch 4692 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4693 %{ 4694 single_instruction; 4695 cr : S1(read); 4696 BR : S3; 4697 %} 4698 4699 // Allocation idiom 4700 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4701 %{ 4702 instruction_count(1); force_serialization; 4703 fixed_latency(6); 4704 heap_ptr : S3(read); 4705 DECODE : S0(3); 4706 D0 : S2; 4707 MEM : S3; 4708 ALU : S3(2); 4709 dst : S5(write); 4710 BR : S5; 4711 %} 4712 4713 // Generic big/slow expanded idiom 4714 pipe_class pipe_slow() 4715 %{ 4716 instruction_count(10); multiple_bundles; force_serialization; 4717 fixed_latency(100); 4718 D0 : S0(2); 4719 MEM : S3(2); 4720 %} 4721 4722 // The real do-nothing guy 4723 pipe_class empty() 4724 %{ 4725 instruction_count(0); 4726 %} 4727 4728 // Define the class for the Nop node 4729 define 4730 %{ 4731 MachNop = empty; 4732 %} 4733 4734 %} 4735 4736 //----------INSTRUCTIONS------------------------------------------------------- 4737 // 4738 // match -- States which machine-independent subtree may be replaced 4739 // by this instruction. 4740 // ins_cost -- The estimated cost of this instruction is used by instruction 4741 // selection to identify a minimum cost tree of machine 4742 // instructions that matches a tree of machine-independent 4743 // instructions. 4744 // format -- A string providing the disassembly for this instruction. 4745 // The value of an instruction's operand may be inserted 4746 // by referring to it with a '$' prefix. 4747 // opcode -- Three instruction opcodes may be provided. These are referred 4748 // to within an encode class as $primary, $secondary, and $tertiary 4749 // rrspectively. The primary opcode is commonly used to 4750 // indicate the type of machine instruction, while secondary 4751 // and tertiary are often used for prefix options or addressing 4752 // modes. 4753 // ins_encode -- A list of encode classes with parameters. The encode class 4754 // name must have been defined in an 'enc_class' specification 4755 // in the encode section of the architecture description. 4756 4757 4758 //----------Load/Store/Move Instructions--------------------------------------- 4759 //----------Load Instructions-------------------------------------------------- 4760 4761 // Load Byte (8 bit signed) 4762 instruct loadB(rRegI dst, memory mem) 4763 %{ 4764 match(Set dst (LoadB mem)); 4765 4766 ins_cost(125); 4767 format %{ "movsbl $dst, $mem\t# byte" %} 4768 4769 ins_encode %{ 4770 __ movsbl($dst$$Register, $mem$$Address); 4771 %} 4772 4773 ins_pipe(ialu_reg_mem); 4774 %} 4775 4776 // Load Byte (8 bit signed) into Long Register 4777 instruct loadB2L(rRegL dst, memory mem) 4778 %{ 4779 match(Set dst (ConvI2L (LoadB mem))); 4780 4781 ins_cost(125); 4782 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4783 4784 ins_encode %{ 4785 __ movsbq($dst$$Register, $mem$$Address); 4786 %} 4787 4788 ins_pipe(ialu_reg_mem); 4789 %} 4790 4791 // Load Unsigned Byte (8 bit UNsigned) 4792 instruct loadUB(rRegI dst, memory mem) 4793 %{ 4794 match(Set dst (LoadUB mem)); 4795 4796 ins_cost(125); 4797 format %{ "movzbl $dst, $mem\t# ubyte" %} 4798 4799 ins_encode %{ 4800 __ movzbl($dst$$Register, $mem$$Address); 4801 %} 4802 4803 ins_pipe(ialu_reg_mem); 4804 %} 4805 4806 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4807 instruct loadUB2L(rRegL dst, memory mem) 4808 %{ 4809 match(Set dst (ConvI2L (LoadUB mem))); 4810 4811 ins_cost(125); 4812 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4813 4814 ins_encode %{ 4815 __ movzbq($dst$$Register, $mem$$Address); 4816 %} 4817 4818 ins_pipe(ialu_reg_mem); 4819 %} 4820 4821 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4822 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4823 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4824 effect(KILL cr); 4825 4826 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4827 "andl $dst, right_n_bits($mask, 8)" %} 4828 ins_encode %{ 4829 Register Rdst = $dst$$Register; 4830 __ movzbq(Rdst, $mem$$Address); 4831 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4832 %} 4833 ins_pipe(ialu_reg_mem); 4834 %} 4835 4836 // Load Short (16 bit signed) 4837 instruct loadS(rRegI dst, memory mem) 4838 %{ 4839 match(Set dst (LoadS mem)); 4840 4841 ins_cost(125); 4842 format %{ "movswl $dst, $mem\t# short" %} 4843 4844 ins_encode %{ 4845 __ movswl($dst$$Register, $mem$$Address); 4846 %} 4847 4848 ins_pipe(ialu_reg_mem); 4849 %} 4850 4851 // Load Short (16 bit signed) to Byte (8 bit signed) 4852 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4853 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4854 4855 ins_cost(125); 4856 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4857 ins_encode %{ 4858 __ movsbl($dst$$Register, $mem$$Address); 4859 %} 4860 ins_pipe(ialu_reg_mem); 4861 %} 4862 4863 // Load Short (16 bit signed) into Long Register 4864 instruct loadS2L(rRegL dst, memory mem) 4865 %{ 4866 match(Set dst (ConvI2L (LoadS mem))); 4867 4868 ins_cost(125); 4869 format %{ "movswq $dst, $mem\t# short -> long" %} 4870 4871 ins_encode %{ 4872 __ movswq($dst$$Register, $mem$$Address); 4873 %} 4874 4875 ins_pipe(ialu_reg_mem); 4876 %} 4877 4878 // Load Unsigned Short/Char (16 bit UNsigned) 4879 instruct loadUS(rRegI dst, memory mem) 4880 %{ 4881 match(Set dst (LoadUS mem)); 4882 4883 ins_cost(125); 4884 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4885 4886 ins_encode %{ 4887 __ movzwl($dst$$Register, $mem$$Address); 4888 %} 4889 4890 ins_pipe(ialu_reg_mem); 4891 %} 4892 4893 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4894 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4895 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4896 4897 ins_cost(125); 4898 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4899 ins_encode %{ 4900 __ movsbl($dst$$Register, $mem$$Address); 4901 %} 4902 ins_pipe(ialu_reg_mem); 4903 %} 4904 4905 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4906 instruct loadUS2L(rRegL dst, memory mem) 4907 %{ 4908 match(Set dst (ConvI2L (LoadUS mem))); 4909 4910 ins_cost(125); 4911 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4912 4913 ins_encode %{ 4914 __ movzwq($dst$$Register, $mem$$Address); 4915 %} 4916 4917 ins_pipe(ialu_reg_mem); 4918 %} 4919 4920 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4921 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4922 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4923 4924 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4925 ins_encode %{ 4926 __ movzbq($dst$$Register, $mem$$Address); 4927 %} 4928 ins_pipe(ialu_reg_mem); 4929 %} 4930 4931 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4932 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4933 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4934 effect(KILL cr); 4935 4936 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4937 "andl $dst, right_n_bits($mask, 16)" %} 4938 ins_encode %{ 4939 Register Rdst = $dst$$Register; 4940 __ movzwq(Rdst, $mem$$Address); 4941 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4942 %} 4943 ins_pipe(ialu_reg_mem); 4944 %} 4945 4946 // Load Integer 4947 instruct loadI(rRegI dst, memory mem) 4948 %{ 4949 match(Set dst (LoadI mem)); 4950 4951 ins_cost(125); 4952 format %{ "movl $dst, $mem\t# int" %} 4953 4954 ins_encode %{ 4955 __ movl($dst$$Register, $mem$$Address); 4956 %} 4957 4958 ins_pipe(ialu_reg_mem); 4959 %} 4960 4961 // Load Integer (32 bit signed) to Byte (8 bit signed) 4962 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4963 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4964 4965 ins_cost(125); 4966 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4967 ins_encode %{ 4968 __ movsbl($dst$$Register, $mem$$Address); 4969 %} 4970 ins_pipe(ialu_reg_mem); 4971 %} 4972 4973 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4974 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4975 match(Set dst (AndI (LoadI mem) mask)); 4976 4977 ins_cost(125); 4978 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4979 ins_encode %{ 4980 __ movzbl($dst$$Register, $mem$$Address); 4981 %} 4982 ins_pipe(ialu_reg_mem); 4983 %} 4984 4985 // Load Integer (32 bit signed) to Short (16 bit signed) 4986 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4987 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4988 4989 ins_cost(125); 4990 format %{ "movswl $dst, $mem\t# int -> short" %} 4991 ins_encode %{ 4992 __ movswl($dst$$Register, $mem$$Address); 4993 %} 4994 ins_pipe(ialu_reg_mem); 4995 %} 4996 4997 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4998 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4999 match(Set dst (AndI (LoadI mem) mask)); 5000 5001 ins_cost(125); 5002 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5003 ins_encode %{ 5004 __ movzwl($dst$$Register, $mem$$Address); 5005 %} 5006 ins_pipe(ialu_reg_mem); 5007 %} 5008 5009 // Load Integer into Long Register 5010 instruct loadI2L(rRegL dst, memory mem) 5011 %{ 5012 match(Set dst (ConvI2L (LoadI mem))); 5013 5014 ins_cost(125); 5015 format %{ "movslq $dst, $mem\t# int -> long" %} 5016 5017 ins_encode %{ 5018 __ movslq($dst$$Register, $mem$$Address); 5019 %} 5020 5021 ins_pipe(ialu_reg_mem); 5022 %} 5023 5024 // Load Integer with mask 0xFF into Long Register 5025 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5026 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5027 5028 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5029 ins_encode %{ 5030 __ movzbq($dst$$Register, $mem$$Address); 5031 %} 5032 ins_pipe(ialu_reg_mem); 5033 %} 5034 5035 // Load Integer with mask 0xFFFF into Long Register 5036 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5037 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5038 5039 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5040 ins_encode %{ 5041 __ movzwq($dst$$Register, $mem$$Address); 5042 %} 5043 ins_pipe(ialu_reg_mem); 5044 %} 5045 5046 // Load Integer with a 31-bit mask into Long Register 5047 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5048 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5049 effect(KILL cr); 5050 5051 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5052 "andl $dst, $mask" %} 5053 ins_encode %{ 5054 Register Rdst = $dst$$Register; 5055 __ movl(Rdst, $mem$$Address); 5056 __ andl(Rdst, $mask$$constant); 5057 %} 5058 ins_pipe(ialu_reg_mem); 5059 %} 5060 5061 // Load Unsigned Integer into Long Register 5062 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5063 %{ 5064 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5065 5066 ins_cost(125); 5067 format %{ "movl $dst, $mem\t# uint -> long" %} 5068 5069 ins_encode %{ 5070 __ movl($dst$$Register, $mem$$Address); 5071 %} 5072 5073 ins_pipe(ialu_reg_mem); 5074 %} 5075 5076 // Load Long 5077 instruct loadL(rRegL dst, memory mem) 5078 %{ 5079 match(Set dst (LoadL mem)); 5080 5081 ins_cost(125); 5082 format %{ "movq $dst, $mem\t# long" %} 5083 5084 ins_encode %{ 5085 __ movq($dst$$Register, $mem$$Address); 5086 %} 5087 5088 ins_pipe(ialu_reg_mem); // XXX 5089 %} 5090 5091 // Load Range 5092 instruct loadRange(rRegI dst, memory mem) 5093 %{ 5094 match(Set dst (LoadRange mem)); 5095 5096 ins_cost(125); // XXX 5097 format %{ "movl $dst, $mem\t# range" %} 5098 opcode(0x8B); 5099 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5100 ins_pipe(ialu_reg_mem); 5101 %} 5102 5103 // Load Pointer 5104 instruct loadP(rRegP dst, memory mem) 5105 %{ 5106 match(Set dst (LoadP mem)); 5107 5108 ins_cost(125); // XXX 5109 format %{ "movq $dst, $mem\t# ptr" %} 5110 opcode(0x8B); 5111 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5112 ins_pipe(ialu_reg_mem); // XXX 5113 %} 5114 5115 // Load Compressed Pointer 5116 instruct loadN(rRegN dst, memory mem) 5117 %{ 5118 match(Set dst (LoadN mem)); 5119 5120 ins_cost(125); // XXX 5121 format %{ "movl $dst, $mem\t# compressed ptr" %} 5122 ins_encode %{ 5123 __ movl($dst$$Register, $mem$$Address); 5124 %} 5125 ins_pipe(ialu_reg_mem); // XXX 5126 %} 5127 5128 5129 // Load Klass Pointer 5130 instruct loadKlass(rRegP dst, memory mem) 5131 %{ 5132 match(Set dst (LoadKlass mem)); 5133 5134 ins_cost(125); // XXX 5135 format %{ "movq $dst, $mem\t# class" %} 5136 opcode(0x8B); 5137 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5138 ins_pipe(ialu_reg_mem); // XXX 5139 %} 5140 5141 // Load narrow Klass Pointer 5142 instruct loadNKlass(rRegN dst, memory mem) 5143 %{ 5144 match(Set dst (LoadNKlass mem)); 5145 5146 ins_cost(125); // XXX 5147 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5148 ins_encode %{ 5149 __ movl($dst$$Register, $mem$$Address); 5150 %} 5151 ins_pipe(ialu_reg_mem); // XXX 5152 %} 5153 5154 // Load Float 5155 instruct loadF(regF dst, memory mem) 5156 %{ 5157 match(Set dst (LoadF mem)); 5158 5159 ins_cost(145); // XXX 5160 format %{ "movss $dst, $mem\t# float" %} 5161 ins_encode %{ 5162 __ movflt($dst$$XMMRegister, $mem$$Address); 5163 %} 5164 ins_pipe(pipe_slow); // XXX 5165 %} 5166 5167 // Load Double 5168 instruct loadD_partial(regD dst, memory mem) 5169 %{ 5170 predicate(!UseXmmLoadAndClearUpper); 5171 match(Set dst (LoadD mem)); 5172 5173 ins_cost(145); // XXX 5174 format %{ "movlpd $dst, $mem\t# double" %} 5175 ins_encode %{ 5176 __ movdbl($dst$$XMMRegister, $mem$$Address); 5177 %} 5178 ins_pipe(pipe_slow); // XXX 5179 %} 5180 5181 instruct loadD(regD dst, memory mem) 5182 %{ 5183 predicate(UseXmmLoadAndClearUpper); 5184 match(Set dst (LoadD mem)); 5185 5186 ins_cost(145); // XXX 5187 format %{ "movsd $dst, $mem\t# double" %} 5188 ins_encode %{ 5189 __ movdbl($dst$$XMMRegister, $mem$$Address); 5190 %} 5191 ins_pipe(pipe_slow); // XXX 5192 %} 5193 5194 // Load Effective Address 5195 instruct leaP8(rRegP dst, indOffset8 mem) 5196 %{ 5197 match(Set dst mem); 5198 5199 ins_cost(110); // XXX 5200 format %{ "leaq $dst, $mem\t# ptr 8" %} 5201 opcode(0x8D); 5202 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5203 ins_pipe(ialu_reg_reg_fat); 5204 %} 5205 5206 instruct leaP32(rRegP dst, indOffset32 mem) 5207 %{ 5208 match(Set dst mem); 5209 5210 ins_cost(110); 5211 format %{ "leaq $dst, $mem\t# ptr 32" %} 5212 opcode(0x8D); 5213 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5214 ins_pipe(ialu_reg_reg_fat); 5215 %} 5216 5217 // instruct leaPIdx(rRegP dst, indIndex mem) 5218 // %{ 5219 // match(Set dst mem); 5220 5221 // ins_cost(110); 5222 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5223 // opcode(0x8D); 5224 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5225 // ins_pipe(ialu_reg_reg_fat); 5226 // %} 5227 5228 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5229 %{ 5230 match(Set dst mem); 5231 5232 ins_cost(110); 5233 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5234 opcode(0x8D); 5235 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5236 ins_pipe(ialu_reg_reg_fat); 5237 %} 5238 5239 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5240 %{ 5241 match(Set dst mem); 5242 5243 ins_cost(110); 5244 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5245 opcode(0x8D); 5246 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5247 ins_pipe(ialu_reg_reg_fat); 5248 %} 5249 5250 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5251 %{ 5252 match(Set dst mem); 5253 5254 ins_cost(110); 5255 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5256 opcode(0x8D); 5257 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5258 ins_pipe(ialu_reg_reg_fat); 5259 %} 5260 5261 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5262 %{ 5263 match(Set dst mem); 5264 5265 ins_cost(110); 5266 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5267 opcode(0x8D); 5268 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5269 ins_pipe(ialu_reg_reg_fat); 5270 %} 5271 5272 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5273 %{ 5274 match(Set dst mem); 5275 5276 ins_cost(110); 5277 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5278 opcode(0x8D); 5279 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5280 ins_pipe(ialu_reg_reg_fat); 5281 %} 5282 5283 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5284 %{ 5285 match(Set dst mem); 5286 5287 ins_cost(110); 5288 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5289 opcode(0x8D); 5290 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5291 ins_pipe(ialu_reg_reg_fat); 5292 %} 5293 5294 // Load Effective Address which uses Narrow (32-bits) oop 5295 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5296 %{ 5297 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5298 match(Set dst mem); 5299 5300 ins_cost(110); 5301 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5302 opcode(0x8D); 5303 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5304 ins_pipe(ialu_reg_reg_fat); 5305 %} 5306 5307 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5308 %{ 5309 predicate(Universe::narrow_oop_shift() == 0); 5310 match(Set dst mem); 5311 5312 ins_cost(110); // XXX 5313 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5314 opcode(0x8D); 5315 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5316 ins_pipe(ialu_reg_reg_fat); 5317 %} 5318 5319 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5320 %{ 5321 predicate(Universe::narrow_oop_shift() == 0); 5322 match(Set dst mem); 5323 5324 ins_cost(110); 5325 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5326 opcode(0x8D); 5327 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5328 ins_pipe(ialu_reg_reg_fat); 5329 %} 5330 5331 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5332 %{ 5333 predicate(Universe::narrow_oop_shift() == 0); 5334 match(Set dst mem); 5335 5336 ins_cost(110); 5337 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5338 opcode(0x8D); 5339 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5340 ins_pipe(ialu_reg_reg_fat); 5341 %} 5342 5343 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5344 %{ 5345 predicate(Universe::narrow_oop_shift() == 0); 5346 match(Set dst mem); 5347 5348 ins_cost(110); 5349 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5350 opcode(0x8D); 5351 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5352 ins_pipe(ialu_reg_reg_fat); 5353 %} 5354 5355 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5356 %{ 5357 predicate(Universe::narrow_oop_shift() == 0); 5358 match(Set dst mem); 5359 5360 ins_cost(110); 5361 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5362 opcode(0x8D); 5363 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5364 ins_pipe(ialu_reg_reg_fat); 5365 %} 5366 5367 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5368 %{ 5369 predicate(Universe::narrow_oop_shift() == 0); 5370 match(Set dst mem); 5371 5372 ins_cost(110); 5373 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5374 opcode(0x8D); 5375 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5376 ins_pipe(ialu_reg_reg_fat); 5377 %} 5378 5379 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5380 %{ 5381 predicate(Universe::narrow_oop_shift() == 0); 5382 match(Set dst mem); 5383 5384 ins_cost(110); 5385 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5386 opcode(0x8D); 5387 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5388 ins_pipe(ialu_reg_reg_fat); 5389 %} 5390 5391 instruct loadConI(rRegI dst, immI src) 5392 %{ 5393 match(Set dst src); 5394 5395 format %{ "movl $dst, $src\t# int" %} 5396 ins_encode(load_immI(dst, src)); 5397 ins_pipe(ialu_reg_fat); // XXX 5398 %} 5399 5400 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5401 %{ 5402 match(Set dst src); 5403 effect(KILL cr); 5404 5405 ins_cost(50); 5406 format %{ "xorl $dst, $dst\t# int" %} 5407 opcode(0x33); /* + rd */ 5408 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5409 ins_pipe(ialu_reg); 5410 %} 5411 5412 instruct loadConL(rRegL dst, immL src) 5413 %{ 5414 match(Set dst src); 5415 5416 ins_cost(150); 5417 format %{ "movq $dst, $src\t# long" %} 5418 ins_encode(load_immL(dst, src)); 5419 ins_pipe(ialu_reg); 5420 %} 5421 5422 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5423 %{ 5424 match(Set dst src); 5425 effect(KILL cr); 5426 5427 ins_cost(50); 5428 format %{ "xorl $dst, $dst\t# long" %} 5429 opcode(0x33); /* + rd */ 5430 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5431 ins_pipe(ialu_reg); // XXX 5432 %} 5433 5434 instruct loadConUL32(rRegL dst, immUL32 src) 5435 %{ 5436 match(Set dst src); 5437 5438 ins_cost(60); 5439 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5440 ins_encode(load_immUL32(dst, src)); 5441 ins_pipe(ialu_reg); 5442 %} 5443 5444 instruct loadConL32(rRegL dst, immL32 src) 5445 %{ 5446 match(Set dst src); 5447 5448 ins_cost(70); 5449 format %{ "movq $dst, $src\t# long (32-bit)" %} 5450 ins_encode(load_immL32(dst, src)); 5451 ins_pipe(ialu_reg); 5452 %} 5453 5454 instruct loadConP(rRegP dst, immP con) %{ 5455 match(Set dst con); 5456 5457 format %{ "movq $dst, $con\t# ptr" %} 5458 ins_encode(load_immP(dst, con)); 5459 ins_pipe(ialu_reg_fat); // XXX 5460 %} 5461 5462 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5463 %{ 5464 match(Set dst src); 5465 effect(KILL cr); 5466 5467 ins_cost(50); 5468 format %{ "xorl $dst, $dst\t# ptr" %} 5469 opcode(0x33); /* + rd */ 5470 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5471 ins_pipe(ialu_reg); 5472 %} 5473 5474 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5475 %{ 5476 match(Set dst src); 5477 effect(KILL cr); 5478 5479 ins_cost(60); 5480 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5481 ins_encode(load_immP31(dst, src)); 5482 ins_pipe(ialu_reg); 5483 %} 5484 5485 instruct loadConF(regF dst, immF con) %{ 5486 match(Set dst con); 5487 ins_cost(125); 5488 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5489 ins_encode %{ 5490 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5491 %} 5492 ins_pipe(pipe_slow); 5493 %} 5494 5495 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5496 match(Set dst src); 5497 effect(KILL cr); 5498 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5499 ins_encode %{ 5500 __ xorq($dst$$Register, $dst$$Register); 5501 %} 5502 ins_pipe(ialu_reg); 5503 %} 5504 5505 instruct loadConN(rRegN dst, immN src) %{ 5506 match(Set dst src); 5507 5508 ins_cost(125); 5509 format %{ "movl $dst, $src\t# compressed ptr" %} 5510 ins_encode %{ 5511 address con = (address)$src$$constant; 5512 if (con == NULL) { 5513 ShouldNotReachHere(); 5514 } else { 5515 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5516 } 5517 %} 5518 ins_pipe(ialu_reg_fat); // XXX 5519 %} 5520 5521 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5522 match(Set dst src); 5523 5524 ins_cost(125); 5525 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5526 ins_encode %{ 5527 address con = (address)$src$$constant; 5528 if (con == NULL) { 5529 ShouldNotReachHere(); 5530 } else { 5531 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5532 } 5533 %} 5534 ins_pipe(ialu_reg_fat); // XXX 5535 %} 5536 5537 instruct loadConF0(regF dst, immF0 src) 5538 %{ 5539 match(Set dst src); 5540 ins_cost(100); 5541 5542 format %{ "xorps $dst, $dst\t# float 0.0" %} 5543 ins_encode %{ 5544 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5545 %} 5546 ins_pipe(pipe_slow); 5547 %} 5548 5549 // Use the same format since predicate() can not be used here. 5550 instruct loadConD(regD dst, immD con) %{ 5551 match(Set dst con); 5552 ins_cost(125); 5553 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5554 ins_encode %{ 5555 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5556 %} 5557 ins_pipe(pipe_slow); 5558 %} 5559 5560 instruct loadConD0(regD dst, immD0 src) 5561 %{ 5562 match(Set dst src); 5563 ins_cost(100); 5564 5565 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5566 ins_encode %{ 5567 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5568 %} 5569 ins_pipe(pipe_slow); 5570 %} 5571 5572 instruct loadSSI(rRegI dst, stackSlotI src) 5573 %{ 5574 match(Set dst src); 5575 5576 ins_cost(125); 5577 format %{ "movl $dst, $src\t# int stk" %} 5578 opcode(0x8B); 5579 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5580 ins_pipe(ialu_reg_mem); 5581 %} 5582 5583 instruct loadSSL(rRegL dst, stackSlotL src) 5584 %{ 5585 match(Set dst src); 5586 5587 ins_cost(125); 5588 format %{ "movq $dst, $src\t# long stk" %} 5589 opcode(0x8B); 5590 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5591 ins_pipe(ialu_reg_mem); 5592 %} 5593 5594 instruct loadSSP(rRegP dst, stackSlotP src) 5595 %{ 5596 match(Set dst src); 5597 5598 ins_cost(125); 5599 format %{ "movq $dst, $src\t# ptr stk" %} 5600 opcode(0x8B); 5601 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5602 ins_pipe(ialu_reg_mem); 5603 %} 5604 5605 instruct loadSSF(regF dst, stackSlotF src) 5606 %{ 5607 match(Set dst src); 5608 5609 ins_cost(125); 5610 format %{ "movss $dst, $src\t# float stk" %} 5611 ins_encode %{ 5612 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5613 %} 5614 ins_pipe(pipe_slow); // XXX 5615 %} 5616 5617 // Use the same format since predicate() can not be used here. 5618 instruct loadSSD(regD dst, stackSlotD src) 5619 %{ 5620 match(Set dst src); 5621 5622 ins_cost(125); 5623 format %{ "movsd $dst, $src\t# double stk" %} 5624 ins_encode %{ 5625 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5626 %} 5627 ins_pipe(pipe_slow); // XXX 5628 %} 5629 5630 // Prefetch instructions for allocation. 5631 // Must be safe to execute with invalid address (cannot fault). 5632 5633 instruct prefetchAlloc( memory mem ) %{ 5634 predicate(AllocatePrefetchInstr==3); 5635 match(PrefetchAllocation mem); 5636 ins_cost(125); 5637 5638 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5639 ins_encode %{ 5640 __ prefetchw($mem$$Address); 5641 %} 5642 ins_pipe(ialu_mem); 5643 %} 5644 5645 instruct prefetchAllocNTA( memory mem ) %{ 5646 predicate(AllocatePrefetchInstr==0); 5647 match(PrefetchAllocation mem); 5648 ins_cost(125); 5649 5650 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5651 ins_encode %{ 5652 __ prefetchnta($mem$$Address); 5653 %} 5654 ins_pipe(ialu_mem); 5655 %} 5656 5657 instruct prefetchAllocT0( memory mem ) %{ 5658 predicate(AllocatePrefetchInstr==1); 5659 match(PrefetchAllocation mem); 5660 ins_cost(125); 5661 5662 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5663 ins_encode %{ 5664 __ prefetcht0($mem$$Address); 5665 %} 5666 ins_pipe(ialu_mem); 5667 %} 5668 5669 instruct prefetchAllocT2( memory mem ) %{ 5670 predicate(AllocatePrefetchInstr==2); 5671 match(PrefetchAllocation mem); 5672 ins_cost(125); 5673 5674 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5675 ins_encode %{ 5676 __ prefetcht2($mem$$Address); 5677 %} 5678 ins_pipe(ialu_mem); 5679 %} 5680 5681 //----------Store Instructions------------------------------------------------- 5682 5683 // Store Byte 5684 instruct storeB(memory mem, rRegI src) 5685 %{ 5686 match(Set mem (StoreB mem src)); 5687 5688 ins_cost(125); // XXX 5689 format %{ "movb $mem, $src\t# byte" %} 5690 opcode(0x88); 5691 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5692 ins_pipe(ialu_mem_reg); 5693 %} 5694 5695 // Store Char/Short 5696 instruct storeC(memory mem, rRegI src) 5697 %{ 5698 match(Set mem (StoreC mem src)); 5699 5700 ins_cost(125); // XXX 5701 format %{ "movw $mem, $src\t# char/short" %} 5702 opcode(0x89); 5703 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5704 ins_pipe(ialu_mem_reg); 5705 %} 5706 5707 // Store Integer 5708 instruct storeI(memory mem, rRegI src) 5709 %{ 5710 match(Set mem (StoreI mem src)); 5711 5712 ins_cost(125); // XXX 5713 format %{ "movl $mem, $src\t# int" %} 5714 opcode(0x89); 5715 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5716 ins_pipe(ialu_mem_reg); 5717 %} 5718 5719 // Store Long 5720 instruct storeL(memory mem, rRegL src) 5721 %{ 5722 match(Set mem (StoreL mem src)); 5723 5724 ins_cost(125); // XXX 5725 format %{ "movq $mem, $src\t# long" %} 5726 opcode(0x89); 5727 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5728 ins_pipe(ialu_mem_reg); // XXX 5729 %} 5730 5731 // Store Pointer 5732 instruct storeP(memory mem, any_RegP src) 5733 %{ 5734 match(Set mem (StoreP mem src)); 5735 5736 ins_cost(125); // XXX 5737 format %{ "movq $mem, $src\t# ptr" %} 5738 opcode(0x89); 5739 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5740 ins_pipe(ialu_mem_reg); 5741 %} 5742 5743 instruct storeImmP0(memory mem, immP0 zero) 5744 %{ 5745 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5746 match(Set mem (StoreP mem zero)); 5747 5748 ins_cost(125); // XXX 5749 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5750 ins_encode %{ 5751 __ movq($mem$$Address, r12); 5752 %} 5753 ins_pipe(ialu_mem_reg); 5754 %} 5755 5756 // Store NULL Pointer, mark word, or other simple pointer constant. 5757 instruct storeImmP(memory mem, immP31 src) 5758 %{ 5759 match(Set mem (StoreP mem src)); 5760 5761 ins_cost(150); // XXX 5762 format %{ "movq $mem, $src\t# ptr" %} 5763 opcode(0xC7); /* C7 /0 */ 5764 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5765 ins_pipe(ialu_mem_imm); 5766 %} 5767 5768 // Store Compressed Pointer 5769 instruct storeN(memory mem, rRegN src) 5770 %{ 5771 match(Set mem (StoreN mem src)); 5772 5773 ins_cost(125); // XXX 5774 format %{ "movl $mem, $src\t# compressed ptr" %} 5775 ins_encode %{ 5776 __ movl($mem$$Address, $src$$Register); 5777 %} 5778 ins_pipe(ialu_mem_reg); 5779 %} 5780 5781 instruct storeNKlass(memory mem, rRegN src) 5782 %{ 5783 match(Set mem (StoreNKlass mem src)); 5784 5785 ins_cost(125); // XXX 5786 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5787 ins_encode %{ 5788 __ movl($mem$$Address, $src$$Register); 5789 %} 5790 ins_pipe(ialu_mem_reg); 5791 %} 5792 5793 instruct storeImmN0(memory mem, immN0 zero) 5794 %{ 5795 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5796 match(Set mem (StoreN mem zero)); 5797 5798 ins_cost(125); // XXX 5799 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5800 ins_encode %{ 5801 __ movl($mem$$Address, r12); 5802 %} 5803 ins_pipe(ialu_mem_reg); 5804 %} 5805 5806 instruct storeImmN(memory mem, immN src) 5807 %{ 5808 match(Set mem (StoreN mem src)); 5809 5810 ins_cost(150); // XXX 5811 format %{ "movl $mem, $src\t# compressed ptr" %} 5812 ins_encode %{ 5813 address con = (address)$src$$constant; 5814 if (con == NULL) { 5815 __ movl($mem$$Address, (int32_t)0); 5816 } else { 5817 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5818 } 5819 %} 5820 ins_pipe(ialu_mem_imm); 5821 %} 5822 5823 instruct storeImmNKlass(memory mem, immNKlass src) 5824 %{ 5825 match(Set mem (StoreNKlass mem src)); 5826 5827 ins_cost(150); // XXX 5828 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5829 ins_encode %{ 5830 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5831 %} 5832 ins_pipe(ialu_mem_imm); 5833 %} 5834 5835 // Store Integer Immediate 5836 instruct storeImmI0(memory mem, immI0 zero) 5837 %{ 5838 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5839 match(Set mem (StoreI mem zero)); 5840 5841 ins_cost(125); // XXX 5842 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5843 ins_encode %{ 5844 __ movl($mem$$Address, r12); 5845 %} 5846 ins_pipe(ialu_mem_reg); 5847 %} 5848 5849 instruct storeImmI(memory mem, immI src) 5850 %{ 5851 match(Set mem (StoreI mem src)); 5852 5853 ins_cost(150); 5854 format %{ "movl $mem, $src\t# int" %} 5855 opcode(0xC7); /* C7 /0 */ 5856 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5857 ins_pipe(ialu_mem_imm); 5858 %} 5859 5860 // Store Long Immediate 5861 instruct storeImmL0(memory mem, immL0 zero) 5862 %{ 5863 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5864 match(Set mem (StoreL mem zero)); 5865 5866 ins_cost(125); // XXX 5867 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5868 ins_encode %{ 5869 __ movq($mem$$Address, r12); 5870 %} 5871 ins_pipe(ialu_mem_reg); 5872 %} 5873 5874 instruct storeImmL(memory mem, immL32 src) 5875 %{ 5876 match(Set mem (StoreL mem src)); 5877 5878 ins_cost(150); 5879 format %{ "movq $mem, $src\t# long" %} 5880 opcode(0xC7); /* C7 /0 */ 5881 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5882 ins_pipe(ialu_mem_imm); 5883 %} 5884 5885 // Store Short/Char Immediate 5886 instruct storeImmC0(memory mem, immI0 zero) 5887 %{ 5888 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5889 match(Set mem (StoreC mem zero)); 5890 5891 ins_cost(125); // XXX 5892 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5893 ins_encode %{ 5894 __ movw($mem$$Address, r12); 5895 %} 5896 ins_pipe(ialu_mem_reg); 5897 %} 5898 5899 instruct storeImmI16(memory mem, immI16 src) 5900 %{ 5901 predicate(UseStoreImmI16); 5902 match(Set mem (StoreC mem src)); 5903 5904 ins_cost(150); 5905 format %{ "movw $mem, $src\t# short/char" %} 5906 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 5907 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 5908 ins_pipe(ialu_mem_imm); 5909 %} 5910 5911 // Store Byte Immediate 5912 instruct storeImmB0(memory mem, immI0 zero) 5913 %{ 5914 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5915 match(Set mem (StoreB mem zero)); 5916 5917 ins_cost(125); // XXX 5918 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5919 ins_encode %{ 5920 __ movb($mem$$Address, r12); 5921 %} 5922 ins_pipe(ialu_mem_reg); 5923 %} 5924 5925 instruct storeImmB(memory mem, immI8 src) 5926 %{ 5927 match(Set mem (StoreB mem src)); 5928 5929 ins_cost(150); // XXX 5930 format %{ "movb $mem, $src\t# byte" %} 5931 opcode(0xC6); /* C6 /0 */ 5932 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5933 ins_pipe(ialu_mem_imm); 5934 %} 5935 5936 // Store CMS card-mark Immediate 5937 instruct storeImmCM0_reg(memory mem, immI0 zero) 5938 %{ 5939 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5940 match(Set mem (StoreCM mem zero)); 5941 5942 ins_cost(125); // XXX 5943 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5944 ins_encode %{ 5945 __ movb($mem$$Address, r12); 5946 %} 5947 ins_pipe(ialu_mem_reg); 5948 %} 5949 5950 instruct storeImmCM0(memory mem, immI0 src) 5951 %{ 5952 match(Set mem (StoreCM mem src)); 5953 5954 ins_cost(150); // XXX 5955 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5956 opcode(0xC6); /* C6 /0 */ 5957 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5958 ins_pipe(ialu_mem_imm); 5959 %} 5960 5961 // Store Float 5962 instruct storeF(memory mem, regF src) 5963 %{ 5964 match(Set mem (StoreF mem src)); 5965 5966 ins_cost(95); // XXX 5967 format %{ "movss $mem, $src\t# float" %} 5968 ins_encode %{ 5969 __ movflt($mem$$Address, $src$$XMMRegister); 5970 %} 5971 ins_pipe(pipe_slow); // XXX 5972 %} 5973 5974 // Store immediate Float value (it is faster than store from XMM register) 5975 instruct storeF0(memory mem, immF0 zero) 5976 %{ 5977 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5978 match(Set mem (StoreF mem zero)); 5979 5980 ins_cost(25); // XXX 5981 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5982 ins_encode %{ 5983 __ movl($mem$$Address, r12); 5984 %} 5985 ins_pipe(ialu_mem_reg); 5986 %} 5987 5988 instruct storeF_imm(memory mem, immF src) 5989 %{ 5990 match(Set mem (StoreF mem src)); 5991 5992 ins_cost(50); 5993 format %{ "movl $mem, $src\t# float" %} 5994 opcode(0xC7); /* C7 /0 */ 5995 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5996 ins_pipe(ialu_mem_imm); 5997 %} 5998 5999 // Store Double 6000 instruct storeD(memory mem, regD src) 6001 %{ 6002 match(Set mem (StoreD mem src)); 6003 6004 ins_cost(95); // XXX 6005 format %{ "movsd $mem, $src\t# double" %} 6006 ins_encode %{ 6007 __ movdbl($mem$$Address, $src$$XMMRegister); 6008 %} 6009 ins_pipe(pipe_slow); // XXX 6010 %} 6011 6012 // Store immediate double 0.0 (it is faster than store from XMM register) 6013 instruct storeD0_imm(memory mem, immD0 src) 6014 %{ 6015 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6016 match(Set mem (StoreD mem src)); 6017 6018 ins_cost(50); 6019 format %{ "movq $mem, $src\t# double 0." %} 6020 opcode(0xC7); /* C7 /0 */ 6021 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6022 ins_pipe(ialu_mem_imm); 6023 %} 6024 6025 instruct storeD0(memory mem, immD0 zero) 6026 %{ 6027 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6028 match(Set mem (StoreD mem zero)); 6029 6030 ins_cost(25); // XXX 6031 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6032 ins_encode %{ 6033 __ movq($mem$$Address, r12); 6034 %} 6035 ins_pipe(ialu_mem_reg); 6036 %} 6037 6038 instruct storeSSI(stackSlotI dst, rRegI src) 6039 %{ 6040 match(Set dst src); 6041 6042 ins_cost(100); 6043 format %{ "movl $dst, $src\t# int stk" %} 6044 opcode(0x89); 6045 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6046 ins_pipe( ialu_mem_reg ); 6047 %} 6048 6049 instruct storeSSL(stackSlotL dst, rRegL src) 6050 %{ 6051 match(Set dst src); 6052 6053 ins_cost(100); 6054 format %{ "movq $dst, $src\t# long stk" %} 6055 opcode(0x89); 6056 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6057 ins_pipe(ialu_mem_reg); 6058 %} 6059 6060 instruct storeSSP(stackSlotP dst, rRegP src) 6061 %{ 6062 match(Set dst src); 6063 6064 ins_cost(100); 6065 format %{ "movq $dst, $src\t# ptr stk" %} 6066 opcode(0x89); 6067 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6068 ins_pipe(ialu_mem_reg); 6069 %} 6070 6071 instruct storeSSF(stackSlotF dst, regF src) 6072 %{ 6073 match(Set dst src); 6074 6075 ins_cost(95); // XXX 6076 format %{ "movss $dst, $src\t# float stk" %} 6077 ins_encode %{ 6078 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6079 %} 6080 ins_pipe(pipe_slow); // XXX 6081 %} 6082 6083 instruct storeSSD(stackSlotD dst, regD src) 6084 %{ 6085 match(Set dst src); 6086 6087 ins_cost(95); // XXX 6088 format %{ "movsd $dst, $src\t# double stk" %} 6089 ins_encode %{ 6090 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6091 %} 6092 ins_pipe(pipe_slow); // XXX 6093 %} 6094 6095 //----------BSWAP Instructions------------------------------------------------- 6096 instruct bytes_reverse_int(rRegI dst) %{ 6097 match(Set dst (ReverseBytesI dst)); 6098 6099 format %{ "bswapl $dst" %} 6100 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6101 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6102 ins_pipe( ialu_reg ); 6103 %} 6104 6105 instruct bytes_reverse_long(rRegL dst) %{ 6106 match(Set dst (ReverseBytesL dst)); 6107 6108 format %{ "bswapq $dst" %} 6109 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6110 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6111 ins_pipe( ialu_reg); 6112 %} 6113 6114 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6115 match(Set dst (ReverseBytesUS dst)); 6116 effect(KILL cr); 6117 6118 format %{ "bswapl $dst\n\t" 6119 "shrl $dst,16\n\t" %} 6120 ins_encode %{ 6121 __ bswapl($dst$$Register); 6122 __ shrl($dst$$Register, 16); 6123 %} 6124 ins_pipe( ialu_reg ); 6125 %} 6126 6127 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6128 match(Set dst (ReverseBytesS dst)); 6129 effect(KILL cr); 6130 6131 format %{ "bswapl $dst\n\t" 6132 "sar $dst,16\n\t" %} 6133 ins_encode %{ 6134 __ bswapl($dst$$Register); 6135 __ sarl($dst$$Register, 16); 6136 %} 6137 ins_pipe( ialu_reg ); 6138 %} 6139 6140 //---------- Zeros Count Instructions ------------------------------------------ 6141 6142 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6143 predicate(UseCountLeadingZerosInstruction); 6144 match(Set dst (CountLeadingZerosI src)); 6145 effect(KILL cr); 6146 6147 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6148 ins_encode %{ 6149 __ lzcntl($dst$$Register, $src$$Register); 6150 %} 6151 ins_pipe(ialu_reg); 6152 %} 6153 6154 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6155 predicate(!UseCountLeadingZerosInstruction); 6156 match(Set dst (CountLeadingZerosI src)); 6157 effect(KILL cr); 6158 6159 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6160 "jnz skip\n\t" 6161 "movl $dst, -1\n" 6162 "skip:\n\t" 6163 "negl $dst\n\t" 6164 "addl $dst, 31" %} 6165 ins_encode %{ 6166 Register Rdst = $dst$$Register; 6167 Register Rsrc = $src$$Register; 6168 Label skip; 6169 __ bsrl(Rdst, Rsrc); 6170 __ jccb(Assembler::notZero, skip); 6171 __ movl(Rdst, -1); 6172 __ bind(skip); 6173 __ negl(Rdst); 6174 __ addl(Rdst, BitsPerInt - 1); 6175 %} 6176 ins_pipe(ialu_reg); 6177 %} 6178 6179 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6180 predicate(UseCountLeadingZerosInstruction); 6181 match(Set dst (CountLeadingZerosL src)); 6182 effect(KILL cr); 6183 6184 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6185 ins_encode %{ 6186 __ lzcntq($dst$$Register, $src$$Register); 6187 %} 6188 ins_pipe(ialu_reg); 6189 %} 6190 6191 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6192 predicate(!UseCountLeadingZerosInstruction); 6193 match(Set dst (CountLeadingZerosL src)); 6194 effect(KILL cr); 6195 6196 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6197 "jnz skip\n\t" 6198 "movl $dst, -1\n" 6199 "skip:\n\t" 6200 "negl $dst\n\t" 6201 "addl $dst, 63" %} 6202 ins_encode %{ 6203 Register Rdst = $dst$$Register; 6204 Register Rsrc = $src$$Register; 6205 Label skip; 6206 __ bsrq(Rdst, Rsrc); 6207 __ jccb(Assembler::notZero, skip); 6208 __ movl(Rdst, -1); 6209 __ bind(skip); 6210 __ negl(Rdst); 6211 __ addl(Rdst, BitsPerLong - 1); 6212 %} 6213 ins_pipe(ialu_reg); 6214 %} 6215 6216 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6217 predicate(UseCountTrailingZerosInstruction); 6218 match(Set dst (CountTrailingZerosI src)); 6219 effect(KILL cr); 6220 6221 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6222 ins_encode %{ 6223 __ tzcntl($dst$$Register, $src$$Register); 6224 %} 6225 ins_pipe(ialu_reg); 6226 %} 6227 6228 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6229 predicate(!UseCountTrailingZerosInstruction); 6230 match(Set dst (CountTrailingZerosI src)); 6231 effect(KILL cr); 6232 6233 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6234 "jnz done\n\t" 6235 "movl $dst, 32\n" 6236 "done:" %} 6237 ins_encode %{ 6238 Register Rdst = $dst$$Register; 6239 Label done; 6240 __ bsfl(Rdst, $src$$Register); 6241 __ jccb(Assembler::notZero, done); 6242 __ movl(Rdst, BitsPerInt); 6243 __ bind(done); 6244 %} 6245 ins_pipe(ialu_reg); 6246 %} 6247 6248 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6249 predicate(UseCountTrailingZerosInstruction); 6250 match(Set dst (CountTrailingZerosL src)); 6251 effect(KILL cr); 6252 6253 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6254 ins_encode %{ 6255 __ tzcntq($dst$$Register, $src$$Register); 6256 %} 6257 ins_pipe(ialu_reg); 6258 %} 6259 6260 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6261 predicate(!UseCountTrailingZerosInstruction); 6262 match(Set dst (CountTrailingZerosL src)); 6263 effect(KILL cr); 6264 6265 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6266 "jnz done\n\t" 6267 "movl $dst, 64\n" 6268 "done:" %} 6269 ins_encode %{ 6270 Register Rdst = $dst$$Register; 6271 Label done; 6272 __ bsfq(Rdst, $src$$Register); 6273 __ jccb(Assembler::notZero, done); 6274 __ movl(Rdst, BitsPerLong); 6275 __ bind(done); 6276 %} 6277 ins_pipe(ialu_reg); 6278 %} 6279 6280 6281 //---------- Population Count Instructions ------------------------------------- 6282 6283 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6284 predicate(UsePopCountInstruction); 6285 match(Set dst (PopCountI src)); 6286 effect(KILL cr); 6287 6288 format %{ "popcnt $dst, $src" %} 6289 ins_encode %{ 6290 __ popcntl($dst$$Register, $src$$Register); 6291 %} 6292 ins_pipe(ialu_reg); 6293 %} 6294 6295 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6296 predicate(UsePopCountInstruction); 6297 match(Set dst (PopCountI (LoadI mem))); 6298 effect(KILL cr); 6299 6300 format %{ "popcnt $dst, $mem" %} 6301 ins_encode %{ 6302 __ popcntl($dst$$Register, $mem$$Address); 6303 %} 6304 ins_pipe(ialu_reg); 6305 %} 6306 6307 // Note: Long.bitCount(long) returns an int. 6308 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6309 predicate(UsePopCountInstruction); 6310 match(Set dst (PopCountL src)); 6311 effect(KILL cr); 6312 6313 format %{ "popcnt $dst, $src" %} 6314 ins_encode %{ 6315 __ popcntq($dst$$Register, $src$$Register); 6316 %} 6317 ins_pipe(ialu_reg); 6318 %} 6319 6320 // Note: Long.bitCount(long) returns an int. 6321 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6322 predicate(UsePopCountInstruction); 6323 match(Set dst (PopCountL (LoadL mem))); 6324 effect(KILL cr); 6325 6326 format %{ "popcnt $dst, $mem" %} 6327 ins_encode %{ 6328 __ popcntq($dst$$Register, $mem$$Address); 6329 %} 6330 ins_pipe(ialu_reg); 6331 %} 6332 6333 6334 //----------MemBar Instructions----------------------------------------------- 6335 // Memory barrier flavors 6336 6337 instruct membar_acquire() 6338 %{ 6339 match(MemBarAcquire); 6340 match(LoadFence); 6341 ins_cost(0); 6342 6343 size(0); 6344 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6345 ins_encode(); 6346 ins_pipe(empty); 6347 %} 6348 6349 instruct membar_acquire_lock() 6350 %{ 6351 match(MemBarAcquireLock); 6352 ins_cost(0); 6353 6354 size(0); 6355 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6356 ins_encode(); 6357 ins_pipe(empty); 6358 %} 6359 6360 instruct membar_release() 6361 %{ 6362 match(MemBarRelease); 6363 match(StoreFence); 6364 ins_cost(0); 6365 6366 size(0); 6367 format %{ "MEMBAR-release ! (empty encoding)" %} 6368 ins_encode(); 6369 ins_pipe(empty); 6370 %} 6371 6372 instruct membar_release_lock() 6373 %{ 6374 match(MemBarReleaseLock); 6375 ins_cost(0); 6376 6377 size(0); 6378 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6379 ins_encode(); 6380 ins_pipe(empty); 6381 %} 6382 6383 instruct membar_volatile(rFlagsReg cr) %{ 6384 match(MemBarVolatile); 6385 effect(KILL cr); 6386 ins_cost(400); 6387 6388 format %{ 6389 $$template 6390 if (os::is_MP()) { 6391 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6392 } else { 6393 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6394 } 6395 %} 6396 ins_encode %{ 6397 __ membar(Assembler::StoreLoad); 6398 %} 6399 ins_pipe(pipe_slow); 6400 %} 6401 6402 instruct unnecessary_membar_volatile() 6403 %{ 6404 match(MemBarVolatile); 6405 predicate(Matcher::post_store_load_barrier(n)); 6406 ins_cost(0); 6407 6408 size(0); 6409 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6410 ins_encode(); 6411 ins_pipe(empty); 6412 %} 6413 6414 instruct membar_storestore() %{ 6415 match(MemBarStoreStore); 6416 ins_cost(0); 6417 6418 size(0); 6419 format %{ "MEMBAR-storestore (empty encoding)" %} 6420 ins_encode( ); 6421 ins_pipe(empty); 6422 %} 6423 6424 //----------Move Instructions-------------------------------------------------- 6425 6426 instruct castX2P(rRegP dst, rRegL src) 6427 %{ 6428 match(Set dst (CastX2P src)); 6429 6430 format %{ "movq $dst, $src\t# long->ptr" %} 6431 ins_encode %{ 6432 if ($dst$$reg != $src$$reg) { 6433 __ movptr($dst$$Register, $src$$Register); 6434 } 6435 %} 6436 ins_pipe(ialu_reg_reg); // XXX 6437 %} 6438 6439 instruct castN2X(rRegL dst, rRegN src) 6440 %{ 6441 match(Set dst (CastP2X src)); 6442 6443 format %{ "movq $dst, $src\t# ptr -> long" %} 6444 ins_encode %{ 6445 if ($dst$$reg != $src$$reg) { 6446 __ movptr($dst$$Register, $src$$Register); 6447 } 6448 %} 6449 ins_pipe(ialu_reg_reg); // XXX 6450 %} 6451 6452 instruct castP2X(rRegL dst, rRegP src) 6453 %{ 6454 match(Set dst (CastP2X src)); 6455 6456 format %{ "movq $dst, $src\t# ptr -> long" %} 6457 ins_encode %{ 6458 if ($dst$$reg != $src$$reg) { 6459 __ movptr($dst$$Register, $src$$Register); 6460 } 6461 %} 6462 ins_pipe(ialu_reg_reg); // XXX 6463 %} 6464 6465 // Convert oop into int for vectors alignment masking 6466 instruct convP2I(rRegI dst, rRegP src) 6467 %{ 6468 match(Set dst (ConvL2I (CastP2X src))); 6469 6470 format %{ "movl $dst, $src\t# ptr -> int" %} 6471 ins_encode %{ 6472 __ movl($dst$$Register, $src$$Register); 6473 %} 6474 ins_pipe(ialu_reg_reg); // XXX 6475 %} 6476 6477 // Convert compressed oop into int for vectors alignment masking 6478 // in case of 32bit oops (heap < 4Gb). 6479 instruct convN2I(rRegI dst, rRegN src) 6480 %{ 6481 predicate(Universe::narrow_oop_shift() == 0); 6482 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6483 6484 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6485 ins_encode %{ 6486 __ movl($dst$$Register, $src$$Register); 6487 %} 6488 ins_pipe(ialu_reg_reg); // XXX 6489 %} 6490 6491 // Convert oop pointer into compressed form 6492 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6493 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6494 match(Set dst (EncodeP src)); 6495 effect(KILL cr); 6496 format %{ "encode_heap_oop $dst,$src" %} 6497 ins_encode %{ 6498 Register s = $src$$Register; 6499 Register d = $dst$$Register; 6500 if (s != d) { 6501 __ movq(d, s); 6502 } 6503 __ encode_heap_oop(d); 6504 %} 6505 ins_pipe(ialu_reg_long); 6506 %} 6507 6508 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6509 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6510 match(Set dst (EncodeP src)); 6511 effect(KILL cr); 6512 format %{ "encode_heap_oop_not_null $dst,$src" %} 6513 ins_encode %{ 6514 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6515 %} 6516 ins_pipe(ialu_reg_long); 6517 %} 6518 6519 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6520 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6521 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6522 match(Set dst (DecodeN src)); 6523 effect(KILL cr); 6524 format %{ "decode_heap_oop $dst,$src" %} 6525 ins_encode %{ 6526 Register s = $src$$Register; 6527 Register d = $dst$$Register; 6528 if (s != d) { 6529 __ movq(d, s); 6530 } 6531 __ decode_heap_oop(d); 6532 %} 6533 ins_pipe(ialu_reg_long); 6534 %} 6535 6536 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6537 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6538 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6539 match(Set dst (DecodeN src)); 6540 effect(KILL cr); 6541 format %{ "decode_heap_oop_not_null $dst,$src" %} 6542 ins_encode %{ 6543 Register s = $src$$Register; 6544 Register d = $dst$$Register; 6545 if (s != d) { 6546 __ decode_heap_oop_not_null(d, s); 6547 } else { 6548 __ decode_heap_oop_not_null(d); 6549 } 6550 %} 6551 ins_pipe(ialu_reg_long); 6552 %} 6553 6554 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6555 match(Set dst (EncodePKlass src)); 6556 effect(KILL cr); 6557 format %{ "encode_klass_not_null $dst,$src" %} 6558 ins_encode %{ 6559 __ encode_klass_not_null($dst$$Register, $src$$Register); 6560 %} 6561 ins_pipe(ialu_reg_long); 6562 %} 6563 6564 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6565 match(Set dst (DecodeNKlass src)); 6566 effect(KILL cr); 6567 format %{ "decode_klass_not_null $dst,$src" %} 6568 ins_encode %{ 6569 Register s = $src$$Register; 6570 Register d = $dst$$Register; 6571 if (s != d) { 6572 __ decode_klass_not_null(d, s); 6573 } else { 6574 __ decode_klass_not_null(d); 6575 } 6576 %} 6577 ins_pipe(ialu_reg_long); 6578 %} 6579 6580 6581 //----------Conditional Move--------------------------------------------------- 6582 // Jump 6583 // dummy instruction for generating temp registers 6584 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6585 match(Jump (LShiftL switch_val shift)); 6586 ins_cost(350); 6587 predicate(false); 6588 effect(TEMP dest); 6589 6590 format %{ "leaq $dest, [$constantaddress]\n\t" 6591 "jmp [$dest + $switch_val << $shift]\n\t" %} 6592 ins_encode %{ 6593 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6594 // to do that and the compiler is using that register as one it can allocate. 6595 // So we build it all by hand. 6596 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6597 // ArrayAddress dispatch(table, index); 6598 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6599 __ lea($dest$$Register, $constantaddress); 6600 __ jmp(dispatch); 6601 %} 6602 ins_pipe(pipe_jmp); 6603 %} 6604 6605 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6606 match(Jump (AddL (LShiftL switch_val shift) offset)); 6607 ins_cost(350); 6608 effect(TEMP dest); 6609 6610 format %{ "leaq $dest, [$constantaddress]\n\t" 6611 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6612 ins_encode %{ 6613 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6614 // to do that and the compiler is using that register as one it can allocate. 6615 // So we build it all by hand. 6616 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6617 // ArrayAddress dispatch(table, index); 6618 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6619 __ lea($dest$$Register, $constantaddress); 6620 __ jmp(dispatch); 6621 %} 6622 ins_pipe(pipe_jmp); 6623 %} 6624 6625 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6626 match(Jump switch_val); 6627 ins_cost(350); 6628 effect(TEMP dest); 6629 6630 format %{ "leaq $dest, [$constantaddress]\n\t" 6631 "jmp [$dest + $switch_val]\n\t" %} 6632 ins_encode %{ 6633 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6634 // to do that and the compiler is using that register as one it can allocate. 6635 // So we build it all by hand. 6636 // Address index(noreg, switch_reg, Address::times_1); 6637 // ArrayAddress dispatch(table, index); 6638 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6639 __ lea($dest$$Register, $constantaddress); 6640 __ jmp(dispatch); 6641 %} 6642 ins_pipe(pipe_jmp); 6643 %} 6644 6645 // Conditional move 6646 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6647 %{ 6648 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6649 6650 ins_cost(200); // XXX 6651 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6652 opcode(0x0F, 0x40); 6653 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6654 ins_pipe(pipe_cmov_reg); 6655 %} 6656 6657 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6658 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6659 6660 ins_cost(200); // XXX 6661 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6662 opcode(0x0F, 0x40); 6663 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6664 ins_pipe(pipe_cmov_reg); 6665 %} 6666 6667 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6668 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6669 ins_cost(200); 6670 expand %{ 6671 cmovI_regU(cop, cr, dst, src); 6672 %} 6673 %} 6674 6675 // Conditional move 6676 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6677 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6678 6679 ins_cost(250); // XXX 6680 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6681 opcode(0x0F, 0x40); 6682 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6683 ins_pipe(pipe_cmov_mem); 6684 %} 6685 6686 // Conditional move 6687 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6688 %{ 6689 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6690 6691 ins_cost(250); // XXX 6692 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6693 opcode(0x0F, 0x40); 6694 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6695 ins_pipe(pipe_cmov_mem); 6696 %} 6697 6698 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6699 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6700 ins_cost(250); 6701 expand %{ 6702 cmovI_memU(cop, cr, dst, src); 6703 %} 6704 %} 6705 6706 // Conditional move 6707 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6708 %{ 6709 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6710 6711 ins_cost(200); // XXX 6712 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6713 opcode(0x0F, 0x40); 6714 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6715 ins_pipe(pipe_cmov_reg); 6716 %} 6717 6718 // Conditional move 6719 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6720 %{ 6721 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6722 6723 ins_cost(200); // XXX 6724 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6725 opcode(0x0F, 0x40); 6726 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6727 ins_pipe(pipe_cmov_reg); 6728 %} 6729 6730 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6731 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6732 ins_cost(200); 6733 expand %{ 6734 cmovN_regU(cop, cr, dst, src); 6735 %} 6736 %} 6737 6738 // Conditional move 6739 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6740 %{ 6741 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6742 6743 ins_cost(200); // XXX 6744 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6745 opcode(0x0F, 0x40); 6746 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6747 ins_pipe(pipe_cmov_reg); // XXX 6748 %} 6749 6750 // Conditional move 6751 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6752 %{ 6753 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6754 6755 ins_cost(200); // XXX 6756 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6757 opcode(0x0F, 0x40); 6758 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6759 ins_pipe(pipe_cmov_reg); // XXX 6760 %} 6761 6762 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6763 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6764 ins_cost(200); 6765 expand %{ 6766 cmovP_regU(cop, cr, dst, src); 6767 %} 6768 %} 6769 6770 // DISABLED: Requires the ADLC to emit a bottom_type call that 6771 // correctly meets the two pointer arguments; one is an incoming 6772 // register but the other is a memory operand. ALSO appears to 6773 // be buggy with implicit null checks. 6774 // 6775 //// Conditional move 6776 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6777 //%{ 6778 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6779 // ins_cost(250); 6780 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6781 // opcode(0x0F,0x40); 6782 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6783 // ins_pipe( pipe_cmov_mem ); 6784 //%} 6785 // 6786 //// Conditional move 6787 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6788 //%{ 6789 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6790 // ins_cost(250); 6791 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6792 // opcode(0x0F,0x40); 6793 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6794 // ins_pipe( pipe_cmov_mem ); 6795 //%} 6796 6797 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6798 %{ 6799 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6800 6801 ins_cost(200); // XXX 6802 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6803 opcode(0x0F, 0x40); 6804 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6805 ins_pipe(pipe_cmov_reg); // XXX 6806 %} 6807 6808 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6809 %{ 6810 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6811 6812 ins_cost(200); // XXX 6813 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6814 opcode(0x0F, 0x40); 6815 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6816 ins_pipe(pipe_cmov_mem); // XXX 6817 %} 6818 6819 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6820 %{ 6821 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6822 6823 ins_cost(200); // XXX 6824 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6825 opcode(0x0F, 0x40); 6826 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6827 ins_pipe(pipe_cmov_reg); // XXX 6828 %} 6829 6830 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6831 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6832 ins_cost(200); 6833 expand %{ 6834 cmovL_regU(cop, cr, dst, src); 6835 %} 6836 %} 6837 6838 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6839 %{ 6840 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6841 6842 ins_cost(200); // XXX 6843 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6844 opcode(0x0F, 0x40); 6845 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6846 ins_pipe(pipe_cmov_mem); // XXX 6847 %} 6848 6849 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6850 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6851 ins_cost(200); 6852 expand %{ 6853 cmovL_memU(cop, cr, dst, src); 6854 %} 6855 %} 6856 6857 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6858 %{ 6859 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6860 6861 ins_cost(200); // XXX 6862 format %{ "jn$cop skip\t# signed cmove float\n\t" 6863 "movss $dst, $src\n" 6864 "skip:" %} 6865 ins_encode %{ 6866 Label Lskip; 6867 // Invert sense of branch from sense of CMOV 6868 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6869 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6870 __ bind(Lskip); 6871 %} 6872 ins_pipe(pipe_slow); 6873 %} 6874 6875 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6876 // %{ 6877 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 6878 6879 // ins_cost(200); // XXX 6880 // format %{ "jn$cop skip\t# signed cmove float\n\t" 6881 // "movss $dst, $src\n" 6882 // "skip:" %} 6883 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 6884 // ins_pipe(pipe_slow); 6885 // %} 6886 6887 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6888 %{ 6889 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6890 6891 ins_cost(200); // XXX 6892 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6893 "movss $dst, $src\n" 6894 "skip:" %} 6895 ins_encode %{ 6896 Label Lskip; 6897 // Invert sense of branch from sense of CMOV 6898 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6899 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6900 __ bind(Lskip); 6901 %} 6902 ins_pipe(pipe_slow); 6903 %} 6904 6905 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6906 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6907 ins_cost(200); 6908 expand %{ 6909 cmovF_regU(cop, cr, dst, src); 6910 %} 6911 %} 6912 6913 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6914 %{ 6915 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6916 6917 ins_cost(200); // XXX 6918 format %{ "jn$cop skip\t# signed cmove double\n\t" 6919 "movsd $dst, $src\n" 6920 "skip:" %} 6921 ins_encode %{ 6922 Label Lskip; 6923 // Invert sense of branch from sense of CMOV 6924 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6925 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6926 __ bind(Lskip); 6927 %} 6928 ins_pipe(pipe_slow); 6929 %} 6930 6931 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6932 %{ 6933 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6934 6935 ins_cost(200); // XXX 6936 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6937 "movsd $dst, $src\n" 6938 "skip:" %} 6939 ins_encode %{ 6940 Label Lskip; 6941 // Invert sense of branch from sense of CMOV 6942 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6943 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6944 __ bind(Lskip); 6945 %} 6946 ins_pipe(pipe_slow); 6947 %} 6948 6949 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6950 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6951 ins_cost(200); 6952 expand %{ 6953 cmovD_regU(cop, cr, dst, src); 6954 %} 6955 %} 6956 6957 //----------Arithmetic Instructions-------------------------------------------- 6958 //----------Addition Instructions---------------------------------------------- 6959 6960 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6961 %{ 6962 match(Set dst (AddI dst src)); 6963 effect(KILL cr); 6964 6965 format %{ "addl $dst, $src\t# int" %} 6966 opcode(0x03); 6967 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 6968 ins_pipe(ialu_reg_reg); 6969 %} 6970 6971 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6972 %{ 6973 match(Set dst (AddI dst src)); 6974 effect(KILL cr); 6975 6976 format %{ "addl $dst, $src\t# int" %} 6977 opcode(0x81, 0x00); /* /0 id */ 6978 ins_encode(OpcSErm(dst, src), Con8or32(src)); 6979 ins_pipe( ialu_reg ); 6980 %} 6981 6982 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6983 %{ 6984 match(Set dst (AddI dst (LoadI src))); 6985 effect(KILL cr); 6986 6987 ins_cost(125); // XXX 6988 format %{ "addl $dst, $src\t# int" %} 6989 opcode(0x03); 6990 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6991 ins_pipe(ialu_reg_mem); 6992 %} 6993 6994 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6995 %{ 6996 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6997 effect(KILL cr); 6998 6999 ins_cost(150); // XXX 7000 format %{ "addl $dst, $src\t# int" %} 7001 opcode(0x01); /* Opcode 01 /r */ 7002 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7003 ins_pipe(ialu_mem_reg); 7004 %} 7005 7006 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7007 %{ 7008 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7009 effect(KILL cr); 7010 7011 ins_cost(125); // XXX 7012 format %{ "addl $dst, $src\t# int" %} 7013 opcode(0x81); /* Opcode 81 /0 id */ 7014 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7015 ins_pipe(ialu_mem_imm); 7016 %} 7017 7018 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7019 %{ 7020 predicate(UseIncDec); 7021 match(Set dst (AddI dst src)); 7022 effect(KILL cr); 7023 7024 format %{ "incl $dst\t# int" %} 7025 opcode(0xFF, 0x00); // FF /0 7026 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7027 ins_pipe(ialu_reg); 7028 %} 7029 7030 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7031 %{ 7032 predicate(UseIncDec); 7033 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7034 effect(KILL cr); 7035 7036 ins_cost(125); // XXX 7037 format %{ "incl $dst\t# int" %} 7038 opcode(0xFF); /* Opcode FF /0 */ 7039 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7040 ins_pipe(ialu_mem_imm); 7041 %} 7042 7043 // XXX why does that use AddI 7044 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7045 %{ 7046 predicate(UseIncDec); 7047 match(Set dst (AddI dst src)); 7048 effect(KILL cr); 7049 7050 format %{ "decl $dst\t# int" %} 7051 opcode(0xFF, 0x01); // FF /1 7052 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7053 ins_pipe(ialu_reg); 7054 %} 7055 7056 // XXX why does that use AddI 7057 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7058 %{ 7059 predicate(UseIncDec); 7060 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7061 effect(KILL cr); 7062 7063 ins_cost(125); // XXX 7064 format %{ "decl $dst\t# int" %} 7065 opcode(0xFF); /* Opcode FF /1 */ 7066 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7067 ins_pipe(ialu_mem_imm); 7068 %} 7069 7070 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7071 %{ 7072 match(Set dst (AddI src0 src1)); 7073 7074 ins_cost(110); 7075 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7076 opcode(0x8D); /* 0x8D /r */ 7077 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7078 ins_pipe(ialu_reg_reg); 7079 %} 7080 7081 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7082 %{ 7083 match(Set dst (AddL dst src)); 7084 effect(KILL cr); 7085 7086 format %{ "addq $dst, $src\t# long" %} 7087 opcode(0x03); 7088 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7089 ins_pipe(ialu_reg_reg); 7090 %} 7091 7092 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7093 %{ 7094 match(Set dst (AddL dst src)); 7095 effect(KILL cr); 7096 7097 format %{ "addq $dst, $src\t# long" %} 7098 opcode(0x81, 0x00); /* /0 id */ 7099 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7100 ins_pipe( ialu_reg ); 7101 %} 7102 7103 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7104 %{ 7105 match(Set dst (AddL dst (LoadL src))); 7106 effect(KILL cr); 7107 7108 ins_cost(125); // XXX 7109 format %{ "addq $dst, $src\t# long" %} 7110 opcode(0x03); 7111 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7112 ins_pipe(ialu_reg_mem); 7113 %} 7114 7115 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7116 %{ 7117 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7118 effect(KILL cr); 7119 7120 ins_cost(150); // XXX 7121 format %{ "addq $dst, $src\t# long" %} 7122 opcode(0x01); /* Opcode 01 /r */ 7123 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7124 ins_pipe(ialu_mem_reg); 7125 %} 7126 7127 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7128 %{ 7129 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7130 effect(KILL cr); 7131 7132 ins_cost(125); // XXX 7133 format %{ "addq $dst, $src\t# long" %} 7134 opcode(0x81); /* Opcode 81 /0 id */ 7135 ins_encode(REX_mem_wide(dst), 7136 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7137 ins_pipe(ialu_mem_imm); 7138 %} 7139 7140 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7141 %{ 7142 predicate(UseIncDec); 7143 match(Set dst (AddL dst src)); 7144 effect(KILL cr); 7145 7146 format %{ "incq $dst\t# long" %} 7147 opcode(0xFF, 0x00); // FF /0 7148 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7149 ins_pipe(ialu_reg); 7150 %} 7151 7152 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7153 %{ 7154 predicate(UseIncDec); 7155 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7156 effect(KILL cr); 7157 7158 ins_cost(125); // XXX 7159 format %{ "incq $dst\t# long" %} 7160 opcode(0xFF); /* Opcode FF /0 */ 7161 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7162 ins_pipe(ialu_mem_imm); 7163 %} 7164 7165 // XXX why does that use AddL 7166 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7167 %{ 7168 predicate(UseIncDec); 7169 match(Set dst (AddL dst src)); 7170 effect(KILL cr); 7171 7172 format %{ "decq $dst\t# long" %} 7173 opcode(0xFF, 0x01); // FF /1 7174 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7175 ins_pipe(ialu_reg); 7176 %} 7177 7178 // XXX why does that use AddL 7179 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7180 %{ 7181 predicate(UseIncDec); 7182 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7183 effect(KILL cr); 7184 7185 ins_cost(125); // XXX 7186 format %{ "decq $dst\t# long" %} 7187 opcode(0xFF); /* Opcode FF /1 */ 7188 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7189 ins_pipe(ialu_mem_imm); 7190 %} 7191 7192 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7193 %{ 7194 match(Set dst (AddL src0 src1)); 7195 7196 ins_cost(110); 7197 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7198 opcode(0x8D); /* 0x8D /r */ 7199 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7200 ins_pipe(ialu_reg_reg); 7201 %} 7202 7203 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7204 %{ 7205 match(Set dst (AddP dst src)); 7206 effect(KILL cr); 7207 7208 format %{ "addq $dst, $src\t# ptr" %} 7209 opcode(0x03); 7210 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7211 ins_pipe(ialu_reg_reg); 7212 %} 7213 7214 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7215 %{ 7216 match(Set dst (AddP dst src)); 7217 effect(KILL cr); 7218 7219 format %{ "addq $dst, $src\t# ptr" %} 7220 opcode(0x81, 0x00); /* /0 id */ 7221 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7222 ins_pipe( ialu_reg ); 7223 %} 7224 7225 // XXX addP mem ops ???? 7226 7227 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7228 %{ 7229 match(Set dst (AddP src0 src1)); 7230 7231 ins_cost(110); 7232 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7233 opcode(0x8D); /* 0x8D /r */ 7234 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7235 ins_pipe(ialu_reg_reg); 7236 %} 7237 7238 instruct checkCastPP(rRegP dst) 7239 %{ 7240 match(Set dst (CheckCastPP dst)); 7241 7242 size(0); 7243 format %{ "# checkcastPP of $dst" %} 7244 ins_encode(/* empty encoding */); 7245 ins_pipe(empty); 7246 %} 7247 7248 instruct castPP(rRegP dst) 7249 %{ 7250 match(Set dst (CastPP dst)); 7251 7252 size(0); 7253 format %{ "# castPP of $dst" %} 7254 ins_encode(/* empty encoding */); 7255 ins_pipe(empty); 7256 %} 7257 7258 instruct castII(rRegI dst) 7259 %{ 7260 match(Set dst (CastII dst)); 7261 7262 size(0); 7263 format %{ "# castII of $dst" %} 7264 ins_encode(/* empty encoding */); 7265 ins_cost(0); 7266 ins_pipe(empty); 7267 %} 7268 7269 // LoadP-locked same as a regular LoadP when used with compare-swap 7270 instruct loadPLocked(rRegP dst, memory mem) 7271 %{ 7272 match(Set dst (LoadPLocked mem)); 7273 7274 ins_cost(125); // XXX 7275 format %{ "movq $dst, $mem\t# ptr locked" %} 7276 opcode(0x8B); 7277 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7278 ins_pipe(ialu_reg_mem); // XXX 7279 %} 7280 7281 // Conditional-store of the updated heap-top. 7282 // Used during allocation of the shared heap. 7283 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7284 7285 instruct storePConditional(memory heap_top_ptr, 7286 rax_RegP oldval, rRegP newval, 7287 rFlagsReg cr) 7288 %{ 7289 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7290 7291 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7292 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7293 opcode(0x0F, 0xB1); 7294 ins_encode(lock_prefix, 7295 REX_reg_mem_wide(newval, heap_top_ptr), 7296 OpcP, OpcS, 7297 reg_mem(newval, heap_top_ptr)); 7298 ins_pipe(pipe_cmpxchg); 7299 %} 7300 7301 // Conditional-store of an int value. 7302 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7303 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7304 %{ 7305 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7306 effect(KILL oldval); 7307 7308 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7309 opcode(0x0F, 0xB1); 7310 ins_encode(lock_prefix, 7311 REX_reg_mem(newval, mem), 7312 OpcP, OpcS, 7313 reg_mem(newval, mem)); 7314 ins_pipe(pipe_cmpxchg); 7315 %} 7316 7317 // Conditional-store of a long value. 7318 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7319 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7320 %{ 7321 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7322 effect(KILL oldval); 7323 7324 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7325 opcode(0x0F, 0xB1); 7326 ins_encode(lock_prefix, 7327 REX_reg_mem_wide(newval, mem), 7328 OpcP, OpcS, 7329 reg_mem(newval, mem)); 7330 ins_pipe(pipe_cmpxchg); 7331 %} 7332 7333 7334 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7335 instruct compareAndSwapP(rRegI res, 7336 memory mem_ptr, 7337 rax_RegP oldval, rRegP newval, 7338 rFlagsReg cr) 7339 %{ 7340 predicate(VM_Version::supports_cx8()); 7341 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7342 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7343 effect(KILL cr, KILL oldval); 7344 7345 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7346 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7347 "sete $res\n\t" 7348 "movzbl $res, $res" %} 7349 opcode(0x0F, 0xB1); 7350 ins_encode(lock_prefix, 7351 REX_reg_mem_wide(newval, mem_ptr), 7352 OpcP, OpcS, 7353 reg_mem(newval, mem_ptr), 7354 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7355 REX_reg_breg(res, res), // movzbl 7356 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7357 ins_pipe( pipe_cmpxchg ); 7358 %} 7359 7360 instruct compareAndSwapL(rRegI res, 7361 memory mem_ptr, 7362 rax_RegL oldval, rRegL newval, 7363 rFlagsReg cr) 7364 %{ 7365 predicate(VM_Version::supports_cx8()); 7366 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7367 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7368 effect(KILL cr, KILL oldval); 7369 7370 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7371 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7372 "sete $res\n\t" 7373 "movzbl $res, $res" %} 7374 opcode(0x0F, 0xB1); 7375 ins_encode(lock_prefix, 7376 REX_reg_mem_wide(newval, mem_ptr), 7377 OpcP, OpcS, 7378 reg_mem(newval, mem_ptr), 7379 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7380 REX_reg_breg(res, res), // movzbl 7381 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7382 ins_pipe( pipe_cmpxchg ); 7383 %} 7384 7385 instruct compareAndSwapI(rRegI res, 7386 memory mem_ptr, 7387 rax_RegI oldval, rRegI newval, 7388 rFlagsReg cr) 7389 %{ 7390 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7391 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7392 effect(KILL cr, KILL oldval); 7393 7394 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7395 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7396 "sete $res\n\t" 7397 "movzbl $res, $res" %} 7398 opcode(0x0F, 0xB1); 7399 ins_encode(lock_prefix, 7400 REX_reg_mem(newval, mem_ptr), 7401 OpcP, OpcS, 7402 reg_mem(newval, mem_ptr), 7403 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7404 REX_reg_breg(res, res), // movzbl 7405 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7406 ins_pipe( pipe_cmpxchg ); 7407 %} 7408 7409 instruct compareAndSwapB(rRegI res, 7410 memory mem_ptr, 7411 rax_RegI oldval, rRegI newval, 7412 rFlagsReg cr) 7413 %{ 7414 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7415 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7416 effect(KILL cr, KILL oldval); 7417 7418 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7419 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7420 "sete $res\n\t" 7421 "movzbl $res, $res" %} 7422 opcode(0x0F, 0xB0); 7423 ins_encode(lock_prefix, 7424 REX_breg_mem(newval, mem_ptr), 7425 OpcP, OpcS, 7426 reg_mem(newval, mem_ptr), 7427 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7428 REX_reg_breg(res, res), // movzbl 7429 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7430 ins_pipe( pipe_cmpxchg ); 7431 %} 7432 7433 instruct compareAndSwapS(rRegI res, 7434 memory mem_ptr, 7435 rax_RegI oldval, rRegI newval, 7436 rFlagsReg cr) 7437 %{ 7438 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7439 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7440 effect(KILL cr, KILL oldval); 7441 7442 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7443 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7444 "sete $res\n\t" 7445 "movzbl $res, $res" %} 7446 opcode(0x0F, 0xB1); 7447 ins_encode(lock_prefix, 7448 SizePrefix, 7449 REX_reg_mem(newval, mem_ptr), 7450 OpcP, OpcS, 7451 reg_mem(newval, mem_ptr), 7452 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7453 REX_reg_breg(res, res), // movzbl 7454 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7455 ins_pipe( pipe_cmpxchg ); 7456 %} 7457 7458 instruct compareAndSwapN(rRegI res, 7459 memory mem_ptr, 7460 rax_RegN oldval, rRegN newval, 7461 rFlagsReg cr) %{ 7462 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7463 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7464 effect(KILL cr, KILL oldval); 7465 7466 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7467 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7468 "sete $res\n\t" 7469 "movzbl $res, $res" %} 7470 opcode(0x0F, 0xB1); 7471 ins_encode(lock_prefix, 7472 REX_reg_mem(newval, mem_ptr), 7473 OpcP, OpcS, 7474 reg_mem(newval, mem_ptr), 7475 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7476 REX_reg_breg(res, res), // movzbl 7477 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7478 ins_pipe( pipe_cmpxchg ); 7479 %} 7480 7481 instruct compareAndExchangeB( 7482 memory mem_ptr, 7483 rax_RegI oldval, rRegI newval, 7484 rFlagsReg cr) 7485 %{ 7486 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7487 effect(KILL cr); 7488 7489 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7490 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7491 opcode(0x0F, 0xB0); 7492 ins_encode(lock_prefix, 7493 REX_breg_mem(newval, mem_ptr), 7494 OpcP, OpcS, 7495 reg_mem(newval, mem_ptr) // lock cmpxchg 7496 ); 7497 ins_pipe( pipe_cmpxchg ); 7498 %} 7499 7500 instruct compareAndExchangeS( 7501 memory mem_ptr, 7502 rax_RegI oldval, rRegI newval, 7503 rFlagsReg cr) 7504 %{ 7505 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7506 effect(KILL cr); 7507 7508 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7509 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7510 opcode(0x0F, 0xB1); 7511 ins_encode(lock_prefix, 7512 SizePrefix, 7513 REX_reg_mem(newval, mem_ptr), 7514 OpcP, OpcS, 7515 reg_mem(newval, mem_ptr) // lock cmpxchg 7516 ); 7517 ins_pipe( pipe_cmpxchg ); 7518 %} 7519 7520 instruct compareAndExchangeI( 7521 memory mem_ptr, 7522 rax_RegI oldval, rRegI newval, 7523 rFlagsReg cr) 7524 %{ 7525 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7526 effect(KILL cr); 7527 7528 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7529 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7530 opcode(0x0F, 0xB1); 7531 ins_encode(lock_prefix, 7532 REX_reg_mem(newval, mem_ptr), 7533 OpcP, OpcS, 7534 reg_mem(newval, mem_ptr) // lock cmpxchg 7535 ); 7536 ins_pipe( pipe_cmpxchg ); 7537 %} 7538 7539 instruct compareAndExchangeL( 7540 memory mem_ptr, 7541 rax_RegL oldval, rRegL newval, 7542 rFlagsReg cr) 7543 %{ 7544 predicate(VM_Version::supports_cx8()); 7545 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7546 effect(KILL cr); 7547 7548 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7549 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7550 opcode(0x0F, 0xB1); 7551 ins_encode(lock_prefix, 7552 REX_reg_mem_wide(newval, mem_ptr), 7553 OpcP, OpcS, 7554 reg_mem(newval, mem_ptr) // lock cmpxchg 7555 ); 7556 ins_pipe( pipe_cmpxchg ); 7557 %} 7558 7559 instruct compareAndExchangeN( 7560 memory mem_ptr, 7561 rax_RegN oldval, rRegN newval, 7562 rFlagsReg cr) %{ 7563 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7564 effect(KILL cr); 7565 7566 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7567 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7568 opcode(0x0F, 0xB1); 7569 ins_encode(lock_prefix, 7570 REX_reg_mem(newval, mem_ptr), 7571 OpcP, OpcS, 7572 reg_mem(newval, mem_ptr) // lock cmpxchg 7573 ); 7574 ins_pipe( pipe_cmpxchg ); 7575 %} 7576 7577 instruct compareAndExchangeP( 7578 memory mem_ptr, 7579 rax_RegP oldval, rRegP newval, 7580 rFlagsReg cr) 7581 %{ 7582 predicate(VM_Version::supports_cx8()); 7583 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7584 effect(KILL cr); 7585 7586 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7587 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7588 opcode(0x0F, 0xB1); 7589 ins_encode(lock_prefix, 7590 REX_reg_mem_wide(newval, mem_ptr), 7591 OpcP, OpcS, 7592 reg_mem(newval, mem_ptr) // lock cmpxchg 7593 ); 7594 ins_pipe( pipe_cmpxchg ); 7595 %} 7596 7597 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7598 predicate(n->as_LoadStore()->result_not_used()); 7599 match(Set dummy (GetAndAddB mem add)); 7600 effect(KILL cr); 7601 format %{ "ADDB [$mem],$add" %} 7602 ins_encode %{ 7603 if (os::is_MP()) { __ lock(); } 7604 __ addb($mem$$Address, $add$$constant); 7605 %} 7606 ins_pipe( pipe_cmpxchg ); 7607 %} 7608 7609 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7610 match(Set newval (GetAndAddB mem newval)); 7611 effect(KILL cr); 7612 format %{ "XADDB [$mem],$newval" %} 7613 ins_encode %{ 7614 if (os::is_MP()) { __ lock(); } 7615 __ xaddb($mem$$Address, $newval$$Register); 7616 %} 7617 ins_pipe( pipe_cmpxchg ); 7618 %} 7619 7620 instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7621 predicate(n->as_LoadStore()->result_not_used()); 7622 match(Set dummy (GetAndAddS mem add)); 7623 effect(KILL cr); 7624 format %{ "ADDW [$mem],$add" %} 7625 ins_encode %{ 7626 if (os::is_MP()) { __ lock(); } 7627 __ addw($mem$$Address, $add$$constant); 7628 %} 7629 ins_pipe( pipe_cmpxchg ); 7630 %} 7631 7632 instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7633 match(Set newval (GetAndAddS mem newval)); 7634 effect(KILL cr); 7635 format %{ "XADDW [$mem],$newval" %} 7636 ins_encode %{ 7637 if (os::is_MP()) { __ lock(); } 7638 __ xaddw($mem$$Address, $newval$$Register); 7639 %} 7640 ins_pipe( pipe_cmpxchg ); 7641 %} 7642 7643 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7644 predicate(n->as_LoadStore()->result_not_used()); 7645 match(Set dummy (GetAndAddI mem add)); 7646 effect(KILL cr); 7647 format %{ "ADDL [$mem],$add" %} 7648 ins_encode %{ 7649 if (os::is_MP()) { __ lock(); } 7650 __ addl($mem$$Address, $add$$constant); 7651 %} 7652 ins_pipe( pipe_cmpxchg ); 7653 %} 7654 7655 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7656 match(Set newval (GetAndAddI mem newval)); 7657 effect(KILL cr); 7658 format %{ "XADDL [$mem],$newval" %} 7659 ins_encode %{ 7660 if (os::is_MP()) { __ lock(); } 7661 __ xaddl($mem$$Address, $newval$$Register); 7662 %} 7663 ins_pipe( pipe_cmpxchg ); 7664 %} 7665 7666 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7667 predicate(n->as_LoadStore()->result_not_used()); 7668 match(Set dummy (GetAndAddL mem add)); 7669 effect(KILL cr); 7670 format %{ "ADDQ [$mem],$add" %} 7671 ins_encode %{ 7672 if (os::is_MP()) { __ lock(); } 7673 __ addq($mem$$Address, $add$$constant); 7674 %} 7675 ins_pipe( pipe_cmpxchg ); 7676 %} 7677 7678 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7679 match(Set newval (GetAndAddL mem newval)); 7680 effect(KILL cr); 7681 format %{ "XADDQ [$mem],$newval" %} 7682 ins_encode %{ 7683 if (os::is_MP()) { __ lock(); } 7684 __ xaddq($mem$$Address, $newval$$Register); 7685 %} 7686 ins_pipe( pipe_cmpxchg ); 7687 %} 7688 7689 instruct xchgB( memory mem, rRegI newval) %{ 7690 match(Set newval (GetAndSetB mem newval)); 7691 format %{ "XCHGB $newval,[$mem]" %} 7692 ins_encode %{ 7693 __ xchgb($newval$$Register, $mem$$Address); 7694 %} 7695 ins_pipe( pipe_cmpxchg ); 7696 %} 7697 7698 instruct xchgS( memory mem, rRegI newval) %{ 7699 match(Set newval (GetAndSetS mem newval)); 7700 format %{ "XCHGW $newval,[$mem]" %} 7701 ins_encode %{ 7702 __ xchgw($newval$$Register, $mem$$Address); 7703 %} 7704 ins_pipe( pipe_cmpxchg ); 7705 %} 7706 7707 instruct xchgI( memory mem, rRegI newval) %{ 7708 match(Set newval (GetAndSetI mem newval)); 7709 format %{ "XCHGL $newval,[$mem]" %} 7710 ins_encode %{ 7711 __ xchgl($newval$$Register, $mem$$Address); 7712 %} 7713 ins_pipe( pipe_cmpxchg ); 7714 %} 7715 7716 instruct xchgL( memory mem, rRegL newval) %{ 7717 match(Set newval (GetAndSetL mem newval)); 7718 format %{ "XCHGL $newval,[$mem]" %} 7719 ins_encode %{ 7720 __ xchgq($newval$$Register, $mem$$Address); 7721 %} 7722 ins_pipe( pipe_cmpxchg ); 7723 %} 7724 7725 instruct xchgP( memory mem, rRegP newval) %{ 7726 match(Set newval (GetAndSetP mem newval)); 7727 format %{ "XCHGQ $newval,[$mem]" %} 7728 ins_encode %{ 7729 __ xchgq($newval$$Register, $mem$$Address); 7730 %} 7731 ins_pipe( pipe_cmpxchg ); 7732 %} 7733 7734 instruct xchgN( memory mem, rRegN newval) %{ 7735 match(Set newval (GetAndSetN mem newval)); 7736 format %{ "XCHGL $newval,$mem]" %} 7737 ins_encode %{ 7738 __ xchgl($newval$$Register, $mem$$Address); 7739 %} 7740 ins_pipe( pipe_cmpxchg ); 7741 %} 7742 7743 //----------Subtraction Instructions------------------------------------------- 7744 7745 // Integer Subtraction Instructions 7746 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7747 %{ 7748 match(Set dst (SubI dst src)); 7749 effect(KILL cr); 7750 7751 format %{ "subl $dst, $src\t# int" %} 7752 opcode(0x2B); 7753 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7754 ins_pipe(ialu_reg_reg); 7755 %} 7756 7757 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7758 %{ 7759 match(Set dst (SubI dst src)); 7760 effect(KILL cr); 7761 7762 format %{ "subl $dst, $src\t# int" %} 7763 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7764 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7765 ins_pipe(ialu_reg); 7766 %} 7767 7768 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7769 %{ 7770 match(Set dst (SubI dst (LoadI src))); 7771 effect(KILL cr); 7772 7773 ins_cost(125); 7774 format %{ "subl $dst, $src\t# int" %} 7775 opcode(0x2B); 7776 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7777 ins_pipe(ialu_reg_mem); 7778 %} 7779 7780 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7781 %{ 7782 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7783 effect(KILL cr); 7784 7785 ins_cost(150); 7786 format %{ "subl $dst, $src\t# int" %} 7787 opcode(0x29); /* Opcode 29 /r */ 7788 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7789 ins_pipe(ialu_mem_reg); 7790 %} 7791 7792 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7793 %{ 7794 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7795 effect(KILL cr); 7796 7797 ins_cost(125); // XXX 7798 format %{ "subl $dst, $src\t# int" %} 7799 opcode(0x81); /* Opcode 81 /5 id */ 7800 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7801 ins_pipe(ialu_mem_imm); 7802 %} 7803 7804 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7805 %{ 7806 match(Set dst (SubL dst src)); 7807 effect(KILL cr); 7808 7809 format %{ "subq $dst, $src\t# long" %} 7810 opcode(0x2B); 7811 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7812 ins_pipe(ialu_reg_reg); 7813 %} 7814 7815 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7816 %{ 7817 match(Set dst (SubL dst src)); 7818 effect(KILL cr); 7819 7820 format %{ "subq $dst, $src\t# long" %} 7821 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7822 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7823 ins_pipe(ialu_reg); 7824 %} 7825 7826 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7827 %{ 7828 match(Set dst (SubL dst (LoadL src))); 7829 effect(KILL cr); 7830 7831 ins_cost(125); 7832 format %{ "subq $dst, $src\t# long" %} 7833 opcode(0x2B); 7834 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7835 ins_pipe(ialu_reg_mem); 7836 %} 7837 7838 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7839 %{ 7840 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7841 effect(KILL cr); 7842 7843 ins_cost(150); 7844 format %{ "subq $dst, $src\t# long" %} 7845 opcode(0x29); /* Opcode 29 /r */ 7846 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7847 ins_pipe(ialu_mem_reg); 7848 %} 7849 7850 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7851 %{ 7852 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7853 effect(KILL cr); 7854 7855 ins_cost(125); // XXX 7856 format %{ "subq $dst, $src\t# long" %} 7857 opcode(0x81); /* Opcode 81 /5 id */ 7858 ins_encode(REX_mem_wide(dst), 7859 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7860 ins_pipe(ialu_mem_imm); 7861 %} 7862 7863 // Subtract from a pointer 7864 // XXX hmpf??? 7865 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7866 %{ 7867 match(Set dst (AddP dst (SubI zero src))); 7868 effect(KILL cr); 7869 7870 format %{ "subq $dst, $src\t# ptr - int" %} 7871 opcode(0x2B); 7872 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7873 ins_pipe(ialu_reg_reg); 7874 %} 7875 7876 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7877 %{ 7878 match(Set dst (SubI zero dst)); 7879 effect(KILL cr); 7880 7881 format %{ "negl $dst\t# int" %} 7882 opcode(0xF7, 0x03); // Opcode F7 /3 7883 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7884 ins_pipe(ialu_reg); 7885 %} 7886 7887 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7888 %{ 7889 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7890 effect(KILL cr); 7891 7892 format %{ "negl $dst\t# int" %} 7893 opcode(0xF7, 0x03); // Opcode F7 /3 7894 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7895 ins_pipe(ialu_reg); 7896 %} 7897 7898 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7899 %{ 7900 match(Set dst (SubL zero dst)); 7901 effect(KILL cr); 7902 7903 format %{ "negq $dst\t# long" %} 7904 opcode(0xF7, 0x03); // Opcode F7 /3 7905 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7906 ins_pipe(ialu_reg); 7907 %} 7908 7909 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7910 %{ 7911 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7912 effect(KILL cr); 7913 7914 format %{ "negq $dst\t# long" %} 7915 opcode(0xF7, 0x03); // Opcode F7 /3 7916 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7917 ins_pipe(ialu_reg); 7918 %} 7919 7920 //----------Multiplication/Division Instructions------------------------------- 7921 // Integer Multiplication Instructions 7922 // Multiply Register 7923 7924 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7925 %{ 7926 match(Set dst (MulI dst src)); 7927 effect(KILL cr); 7928 7929 ins_cost(300); 7930 format %{ "imull $dst, $src\t# int" %} 7931 opcode(0x0F, 0xAF); 7932 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7933 ins_pipe(ialu_reg_reg_alu0); 7934 %} 7935 7936 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7937 %{ 7938 match(Set dst (MulI src imm)); 7939 effect(KILL cr); 7940 7941 ins_cost(300); 7942 format %{ "imull $dst, $src, $imm\t# int" %} 7943 opcode(0x69); /* 69 /r id */ 7944 ins_encode(REX_reg_reg(dst, src), 7945 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7946 ins_pipe(ialu_reg_reg_alu0); 7947 %} 7948 7949 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7950 %{ 7951 match(Set dst (MulI dst (LoadI src))); 7952 effect(KILL cr); 7953 7954 ins_cost(350); 7955 format %{ "imull $dst, $src\t# int" %} 7956 opcode(0x0F, 0xAF); 7957 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7958 ins_pipe(ialu_reg_mem_alu0); 7959 %} 7960 7961 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7962 %{ 7963 match(Set dst (MulI (LoadI src) imm)); 7964 effect(KILL cr); 7965 7966 ins_cost(300); 7967 format %{ "imull $dst, $src, $imm\t# int" %} 7968 opcode(0x69); /* 69 /r id */ 7969 ins_encode(REX_reg_mem(dst, src), 7970 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7971 ins_pipe(ialu_reg_mem_alu0); 7972 %} 7973 7974 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7975 %{ 7976 match(Set dst (MulL dst src)); 7977 effect(KILL cr); 7978 7979 ins_cost(300); 7980 format %{ "imulq $dst, $src\t# long" %} 7981 opcode(0x0F, 0xAF); 7982 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7983 ins_pipe(ialu_reg_reg_alu0); 7984 %} 7985 7986 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7987 %{ 7988 match(Set dst (MulL src imm)); 7989 effect(KILL cr); 7990 7991 ins_cost(300); 7992 format %{ "imulq $dst, $src, $imm\t# long" %} 7993 opcode(0x69); /* 69 /r id */ 7994 ins_encode(REX_reg_reg_wide(dst, src), 7995 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7996 ins_pipe(ialu_reg_reg_alu0); 7997 %} 7998 7999 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8000 %{ 8001 match(Set dst (MulL dst (LoadL src))); 8002 effect(KILL cr); 8003 8004 ins_cost(350); 8005 format %{ "imulq $dst, $src\t# long" %} 8006 opcode(0x0F, 0xAF); 8007 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8008 ins_pipe(ialu_reg_mem_alu0); 8009 %} 8010 8011 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8012 %{ 8013 match(Set dst (MulL (LoadL src) imm)); 8014 effect(KILL cr); 8015 8016 ins_cost(300); 8017 format %{ "imulq $dst, $src, $imm\t# long" %} 8018 opcode(0x69); /* 69 /r id */ 8019 ins_encode(REX_reg_mem_wide(dst, src), 8020 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8021 ins_pipe(ialu_reg_mem_alu0); 8022 %} 8023 8024 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8025 %{ 8026 match(Set dst (MulHiL src rax)); 8027 effect(USE_KILL rax, KILL cr); 8028 8029 ins_cost(300); 8030 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8031 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8032 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8033 ins_pipe(ialu_reg_reg_alu0); 8034 %} 8035 8036 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8037 rFlagsReg cr) 8038 %{ 8039 match(Set rax (DivI rax div)); 8040 effect(KILL rdx, KILL cr); 8041 8042 ins_cost(30*100+10*100); // XXX 8043 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8044 "jne,s normal\n\t" 8045 "xorl rdx, rdx\n\t" 8046 "cmpl $div, -1\n\t" 8047 "je,s done\n" 8048 "normal: cdql\n\t" 8049 "idivl $div\n" 8050 "done:" %} 8051 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8052 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8053 ins_pipe(ialu_reg_reg_alu0); 8054 %} 8055 8056 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8057 rFlagsReg cr) 8058 %{ 8059 match(Set rax (DivL rax div)); 8060 effect(KILL rdx, KILL cr); 8061 8062 ins_cost(30*100+10*100); // XXX 8063 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8064 "cmpq rax, rdx\n\t" 8065 "jne,s normal\n\t" 8066 "xorl rdx, rdx\n\t" 8067 "cmpq $div, -1\n\t" 8068 "je,s done\n" 8069 "normal: cdqq\n\t" 8070 "idivq $div\n" 8071 "done:" %} 8072 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8073 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8074 ins_pipe(ialu_reg_reg_alu0); 8075 %} 8076 8077 // Integer DIVMOD with Register, both quotient and mod results 8078 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8079 rFlagsReg cr) 8080 %{ 8081 match(DivModI rax div); 8082 effect(KILL cr); 8083 8084 ins_cost(30*100+10*100); // XXX 8085 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8086 "jne,s normal\n\t" 8087 "xorl rdx, rdx\n\t" 8088 "cmpl $div, -1\n\t" 8089 "je,s done\n" 8090 "normal: cdql\n\t" 8091 "idivl $div\n" 8092 "done:" %} 8093 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8094 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8095 ins_pipe(pipe_slow); 8096 %} 8097 8098 // Long DIVMOD with Register, both quotient and mod results 8099 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8100 rFlagsReg cr) 8101 %{ 8102 match(DivModL rax div); 8103 effect(KILL cr); 8104 8105 ins_cost(30*100+10*100); // XXX 8106 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8107 "cmpq rax, rdx\n\t" 8108 "jne,s normal\n\t" 8109 "xorl rdx, rdx\n\t" 8110 "cmpq $div, -1\n\t" 8111 "je,s done\n" 8112 "normal: cdqq\n\t" 8113 "idivq $div\n" 8114 "done:" %} 8115 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8116 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8117 ins_pipe(pipe_slow); 8118 %} 8119 8120 //----------- DivL-By-Constant-Expansions-------------------------------------- 8121 // DivI cases are handled by the compiler 8122 8123 // Magic constant, reciprocal of 10 8124 instruct loadConL_0x6666666666666667(rRegL dst) 8125 %{ 8126 effect(DEF dst); 8127 8128 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8129 ins_encode(load_immL(dst, 0x6666666666666667)); 8130 ins_pipe(ialu_reg); 8131 %} 8132 8133 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8134 %{ 8135 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8136 8137 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8138 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8139 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8140 ins_pipe(ialu_reg_reg_alu0); 8141 %} 8142 8143 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8144 %{ 8145 effect(USE_DEF dst, KILL cr); 8146 8147 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8148 opcode(0xC1, 0x7); /* C1 /7 ib */ 8149 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8150 ins_pipe(ialu_reg); 8151 %} 8152 8153 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8154 %{ 8155 effect(USE_DEF dst, KILL cr); 8156 8157 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8158 opcode(0xC1, 0x7); /* C1 /7 ib */ 8159 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8160 ins_pipe(ialu_reg); 8161 %} 8162 8163 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8164 %{ 8165 match(Set dst (DivL src div)); 8166 8167 ins_cost((5+8)*100); 8168 expand %{ 8169 rax_RegL rax; // Killed temp 8170 rFlagsReg cr; // Killed 8171 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8172 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8173 sarL_rReg_63(src, cr); // sarq src, 63 8174 sarL_rReg_2(dst, cr); // sarq rdx, 2 8175 subL_rReg(dst, src, cr); // subl rdx, src 8176 %} 8177 %} 8178 8179 //----------------------------------------------------------------------------- 8180 8181 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8182 rFlagsReg cr) 8183 %{ 8184 match(Set rdx (ModI rax div)); 8185 effect(KILL rax, KILL cr); 8186 8187 ins_cost(300); // XXX 8188 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8189 "jne,s normal\n\t" 8190 "xorl rdx, rdx\n\t" 8191 "cmpl $div, -1\n\t" 8192 "je,s done\n" 8193 "normal: cdql\n\t" 8194 "idivl $div\n" 8195 "done:" %} 8196 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8197 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8198 ins_pipe(ialu_reg_reg_alu0); 8199 %} 8200 8201 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8202 rFlagsReg cr) 8203 %{ 8204 match(Set rdx (ModL rax div)); 8205 effect(KILL rax, KILL cr); 8206 8207 ins_cost(300); // XXX 8208 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8209 "cmpq rax, rdx\n\t" 8210 "jne,s normal\n\t" 8211 "xorl rdx, rdx\n\t" 8212 "cmpq $div, -1\n\t" 8213 "je,s done\n" 8214 "normal: cdqq\n\t" 8215 "idivq $div\n" 8216 "done:" %} 8217 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8218 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8219 ins_pipe(ialu_reg_reg_alu0); 8220 %} 8221 8222 // Integer Shift Instructions 8223 // Shift Left by one 8224 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8225 %{ 8226 match(Set dst (LShiftI dst shift)); 8227 effect(KILL cr); 8228 8229 format %{ "sall $dst, $shift" %} 8230 opcode(0xD1, 0x4); /* D1 /4 */ 8231 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8232 ins_pipe(ialu_reg); 8233 %} 8234 8235 // Shift Left by one 8236 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8237 %{ 8238 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8239 effect(KILL cr); 8240 8241 format %{ "sall $dst, $shift\t" %} 8242 opcode(0xD1, 0x4); /* D1 /4 */ 8243 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8244 ins_pipe(ialu_mem_imm); 8245 %} 8246 8247 // Shift Left by 8-bit immediate 8248 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8249 %{ 8250 match(Set dst (LShiftI dst shift)); 8251 effect(KILL cr); 8252 8253 format %{ "sall $dst, $shift" %} 8254 opcode(0xC1, 0x4); /* C1 /4 ib */ 8255 ins_encode(reg_opc_imm(dst, shift)); 8256 ins_pipe(ialu_reg); 8257 %} 8258 8259 // Shift Left by 8-bit immediate 8260 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8261 %{ 8262 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8263 effect(KILL cr); 8264 8265 format %{ "sall $dst, $shift" %} 8266 opcode(0xC1, 0x4); /* C1 /4 ib */ 8267 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8268 ins_pipe(ialu_mem_imm); 8269 %} 8270 8271 // Shift Left by variable 8272 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8273 %{ 8274 match(Set dst (LShiftI dst shift)); 8275 effect(KILL cr); 8276 8277 format %{ "sall $dst, $shift" %} 8278 opcode(0xD3, 0x4); /* D3 /4 */ 8279 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8280 ins_pipe(ialu_reg_reg); 8281 %} 8282 8283 // Shift Left by variable 8284 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8285 %{ 8286 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8287 effect(KILL cr); 8288 8289 format %{ "sall $dst, $shift" %} 8290 opcode(0xD3, 0x4); /* D3 /4 */ 8291 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8292 ins_pipe(ialu_mem_reg); 8293 %} 8294 8295 // Arithmetic shift right by one 8296 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8297 %{ 8298 match(Set dst (RShiftI dst shift)); 8299 effect(KILL cr); 8300 8301 format %{ "sarl $dst, $shift" %} 8302 opcode(0xD1, 0x7); /* D1 /7 */ 8303 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8304 ins_pipe(ialu_reg); 8305 %} 8306 8307 // Arithmetic shift right by one 8308 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8309 %{ 8310 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8311 effect(KILL cr); 8312 8313 format %{ "sarl $dst, $shift" %} 8314 opcode(0xD1, 0x7); /* D1 /7 */ 8315 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8316 ins_pipe(ialu_mem_imm); 8317 %} 8318 8319 // Arithmetic Shift Right by 8-bit immediate 8320 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8321 %{ 8322 match(Set dst (RShiftI dst shift)); 8323 effect(KILL cr); 8324 8325 format %{ "sarl $dst, $shift" %} 8326 opcode(0xC1, 0x7); /* C1 /7 ib */ 8327 ins_encode(reg_opc_imm(dst, shift)); 8328 ins_pipe(ialu_mem_imm); 8329 %} 8330 8331 // Arithmetic Shift Right by 8-bit immediate 8332 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8333 %{ 8334 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8335 effect(KILL cr); 8336 8337 format %{ "sarl $dst, $shift" %} 8338 opcode(0xC1, 0x7); /* C1 /7 ib */ 8339 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8340 ins_pipe(ialu_mem_imm); 8341 %} 8342 8343 // Arithmetic Shift Right by variable 8344 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8345 %{ 8346 match(Set dst (RShiftI dst shift)); 8347 effect(KILL cr); 8348 8349 format %{ "sarl $dst, $shift" %} 8350 opcode(0xD3, 0x7); /* D3 /7 */ 8351 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8352 ins_pipe(ialu_reg_reg); 8353 %} 8354 8355 // Arithmetic Shift Right by variable 8356 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8357 %{ 8358 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8359 effect(KILL cr); 8360 8361 format %{ "sarl $dst, $shift" %} 8362 opcode(0xD3, 0x7); /* D3 /7 */ 8363 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8364 ins_pipe(ialu_mem_reg); 8365 %} 8366 8367 // Logical shift right by one 8368 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8369 %{ 8370 match(Set dst (URShiftI dst shift)); 8371 effect(KILL cr); 8372 8373 format %{ "shrl $dst, $shift" %} 8374 opcode(0xD1, 0x5); /* D1 /5 */ 8375 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8376 ins_pipe(ialu_reg); 8377 %} 8378 8379 // Logical shift right by one 8380 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8381 %{ 8382 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8383 effect(KILL cr); 8384 8385 format %{ "shrl $dst, $shift" %} 8386 opcode(0xD1, 0x5); /* D1 /5 */ 8387 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8388 ins_pipe(ialu_mem_imm); 8389 %} 8390 8391 // Logical Shift Right by 8-bit immediate 8392 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8393 %{ 8394 match(Set dst (URShiftI dst shift)); 8395 effect(KILL cr); 8396 8397 format %{ "shrl $dst, $shift" %} 8398 opcode(0xC1, 0x5); /* C1 /5 ib */ 8399 ins_encode(reg_opc_imm(dst, shift)); 8400 ins_pipe(ialu_reg); 8401 %} 8402 8403 // Logical Shift Right by 8-bit immediate 8404 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8405 %{ 8406 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8407 effect(KILL cr); 8408 8409 format %{ "shrl $dst, $shift" %} 8410 opcode(0xC1, 0x5); /* C1 /5 ib */ 8411 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8412 ins_pipe(ialu_mem_imm); 8413 %} 8414 8415 // Logical Shift Right by variable 8416 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8417 %{ 8418 match(Set dst (URShiftI dst shift)); 8419 effect(KILL cr); 8420 8421 format %{ "shrl $dst, $shift" %} 8422 opcode(0xD3, 0x5); /* D3 /5 */ 8423 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8424 ins_pipe(ialu_reg_reg); 8425 %} 8426 8427 // Logical Shift Right by variable 8428 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8429 %{ 8430 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8431 effect(KILL cr); 8432 8433 format %{ "shrl $dst, $shift" %} 8434 opcode(0xD3, 0x5); /* D3 /5 */ 8435 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8436 ins_pipe(ialu_mem_reg); 8437 %} 8438 8439 // Long Shift Instructions 8440 // Shift Left by one 8441 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8442 %{ 8443 match(Set dst (LShiftL dst shift)); 8444 effect(KILL cr); 8445 8446 format %{ "salq $dst, $shift" %} 8447 opcode(0xD1, 0x4); /* D1 /4 */ 8448 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8449 ins_pipe(ialu_reg); 8450 %} 8451 8452 // Shift Left by one 8453 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8454 %{ 8455 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8456 effect(KILL cr); 8457 8458 format %{ "salq $dst, $shift" %} 8459 opcode(0xD1, 0x4); /* D1 /4 */ 8460 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8461 ins_pipe(ialu_mem_imm); 8462 %} 8463 8464 // Shift Left by 8-bit immediate 8465 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8466 %{ 8467 match(Set dst (LShiftL dst shift)); 8468 effect(KILL cr); 8469 8470 format %{ "salq $dst, $shift" %} 8471 opcode(0xC1, 0x4); /* C1 /4 ib */ 8472 ins_encode(reg_opc_imm_wide(dst, shift)); 8473 ins_pipe(ialu_reg); 8474 %} 8475 8476 // Shift Left by 8-bit immediate 8477 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8478 %{ 8479 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8480 effect(KILL cr); 8481 8482 format %{ "salq $dst, $shift" %} 8483 opcode(0xC1, 0x4); /* C1 /4 ib */ 8484 ins_encode(REX_mem_wide(dst), OpcP, 8485 RM_opc_mem(secondary, dst), Con8or32(shift)); 8486 ins_pipe(ialu_mem_imm); 8487 %} 8488 8489 // Shift Left by variable 8490 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8491 %{ 8492 match(Set dst (LShiftL dst shift)); 8493 effect(KILL cr); 8494 8495 format %{ "salq $dst, $shift" %} 8496 opcode(0xD3, 0x4); /* D3 /4 */ 8497 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8498 ins_pipe(ialu_reg_reg); 8499 %} 8500 8501 // Shift Left by variable 8502 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8503 %{ 8504 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8505 effect(KILL cr); 8506 8507 format %{ "salq $dst, $shift" %} 8508 opcode(0xD3, 0x4); /* D3 /4 */ 8509 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8510 ins_pipe(ialu_mem_reg); 8511 %} 8512 8513 // Arithmetic shift right by one 8514 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8515 %{ 8516 match(Set dst (RShiftL dst shift)); 8517 effect(KILL cr); 8518 8519 format %{ "sarq $dst, $shift" %} 8520 opcode(0xD1, 0x7); /* D1 /7 */ 8521 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8522 ins_pipe(ialu_reg); 8523 %} 8524 8525 // Arithmetic shift right by one 8526 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8527 %{ 8528 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8529 effect(KILL cr); 8530 8531 format %{ "sarq $dst, $shift" %} 8532 opcode(0xD1, 0x7); /* D1 /7 */ 8533 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8534 ins_pipe(ialu_mem_imm); 8535 %} 8536 8537 // Arithmetic Shift Right by 8-bit immediate 8538 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8539 %{ 8540 match(Set dst (RShiftL dst shift)); 8541 effect(KILL cr); 8542 8543 format %{ "sarq $dst, $shift" %} 8544 opcode(0xC1, 0x7); /* C1 /7 ib */ 8545 ins_encode(reg_opc_imm_wide(dst, shift)); 8546 ins_pipe(ialu_mem_imm); 8547 %} 8548 8549 // Arithmetic Shift Right by 8-bit immediate 8550 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8551 %{ 8552 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8553 effect(KILL cr); 8554 8555 format %{ "sarq $dst, $shift" %} 8556 opcode(0xC1, 0x7); /* C1 /7 ib */ 8557 ins_encode(REX_mem_wide(dst), OpcP, 8558 RM_opc_mem(secondary, dst), Con8or32(shift)); 8559 ins_pipe(ialu_mem_imm); 8560 %} 8561 8562 // Arithmetic Shift Right by variable 8563 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8564 %{ 8565 match(Set dst (RShiftL dst shift)); 8566 effect(KILL cr); 8567 8568 format %{ "sarq $dst, $shift" %} 8569 opcode(0xD3, 0x7); /* D3 /7 */ 8570 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8571 ins_pipe(ialu_reg_reg); 8572 %} 8573 8574 // Arithmetic Shift Right by variable 8575 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8576 %{ 8577 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8578 effect(KILL cr); 8579 8580 format %{ "sarq $dst, $shift" %} 8581 opcode(0xD3, 0x7); /* D3 /7 */ 8582 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8583 ins_pipe(ialu_mem_reg); 8584 %} 8585 8586 // Logical shift right by one 8587 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8588 %{ 8589 match(Set dst (URShiftL dst shift)); 8590 effect(KILL cr); 8591 8592 format %{ "shrq $dst, $shift" %} 8593 opcode(0xD1, 0x5); /* D1 /5 */ 8594 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8595 ins_pipe(ialu_reg); 8596 %} 8597 8598 // Logical shift right by one 8599 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8600 %{ 8601 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8602 effect(KILL cr); 8603 8604 format %{ "shrq $dst, $shift" %} 8605 opcode(0xD1, 0x5); /* D1 /5 */ 8606 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8607 ins_pipe(ialu_mem_imm); 8608 %} 8609 8610 // Logical Shift Right by 8-bit immediate 8611 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8612 %{ 8613 match(Set dst (URShiftL dst shift)); 8614 effect(KILL cr); 8615 8616 format %{ "shrq $dst, $shift" %} 8617 opcode(0xC1, 0x5); /* C1 /5 ib */ 8618 ins_encode(reg_opc_imm_wide(dst, shift)); 8619 ins_pipe(ialu_reg); 8620 %} 8621 8622 8623 // Logical Shift Right by 8-bit immediate 8624 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8625 %{ 8626 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8627 effect(KILL cr); 8628 8629 format %{ "shrq $dst, $shift" %} 8630 opcode(0xC1, 0x5); /* C1 /5 ib */ 8631 ins_encode(REX_mem_wide(dst), OpcP, 8632 RM_opc_mem(secondary, dst), Con8or32(shift)); 8633 ins_pipe(ialu_mem_imm); 8634 %} 8635 8636 // Logical Shift Right by variable 8637 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8638 %{ 8639 match(Set dst (URShiftL dst shift)); 8640 effect(KILL cr); 8641 8642 format %{ "shrq $dst, $shift" %} 8643 opcode(0xD3, 0x5); /* D3 /5 */ 8644 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8645 ins_pipe(ialu_reg_reg); 8646 %} 8647 8648 // Logical Shift Right by variable 8649 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8650 %{ 8651 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8652 effect(KILL cr); 8653 8654 format %{ "shrq $dst, $shift" %} 8655 opcode(0xD3, 0x5); /* D3 /5 */ 8656 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8657 ins_pipe(ialu_mem_reg); 8658 %} 8659 8660 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8661 // This idiom is used by the compiler for the i2b bytecode. 8662 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8663 %{ 8664 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8665 8666 format %{ "movsbl $dst, $src\t# i2b" %} 8667 opcode(0x0F, 0xBE); 8668 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8669 ins_pipe(ialu_reg_reg); 8670 %} 8671 8672 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8673 // This idiom is used by the compiler the i2s bytecode. 8674 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8675 %{ 8676 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8677 8678 format %{ "movswl $dst, $src\t# i2s" %} 8679 opcode(0x0F, 0xBF); 8680 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8681 ins_pipe(ialu_reg_reg); 8682 %} 8683 8684 // ROL/ROR instructions 8685 8686 // ROL expand 8687 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8688 effect(KILL cr, USE_DEF dst); 8689 8690 format %{ "roll $dst" %} 8691 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8692 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8693 ins_pipe(ialu_reg); 8694 %} 8695 8696 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8697 effect(USE_DEF dst, USE shift, KILL cr); 8698 8699 format %{ "roll $dst, $shift" %} 8700 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8701 ins_encode( reg_opc_imm(dst, shift) ); 8702 ins_pipe(ialu_reg); 8703 %} 8704 8705 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8706 %{ 8707 effect(USE_DEF dst, USE shift, KILL cr); 8708 8709 format %{ "roll $dst, $shift" %} 8710 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8711 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8712 ins_pipe(ialu_reg_reg); 8713 %} 8714 // end of ROL expand 8715 8716 // Rotate Left by one 8717 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8718 %{ 8719 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8720 8721 expand %{ 8722 rolI_rReg_imm1(dst, cr); 8723 %} 8724 %} 8725 8726 // Rotate Left by 8-bit immediate 8727 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8728 %{ 8729 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8730 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8731 8732 expand %{ 8733 rolI_rReg_imm8(dst, lshift, cr); 8734 %} 8735 %} 8736 8737 // Rotate Left by variable 8738 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8739 %{ 8740 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8741 8742 expand %{ 8743 rolI_rReg_CL(dst, shift, cr); 8744 %} 8745 %} 8746 8747 // Rotate Left by variable 8748 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8749 %{ 8750 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8751 8752 expand %{ 8753 rolI_rReg_CL(dst, shift, cr); 8754 %} 8755 %} 8756 8757 // ROR expand 8758 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8759 %{ 8760 effect(USE_DEF dst, KILL cr); 8761 8762 format %{ "rorl $dst" %} 8763 opcode(0xD1, 0x1); /* D1 /1 */ 8764 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8765 ins_pipe(ialu_reg); 8766 %} 8767 8768 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8769 %{ 8770 effect(USE_DEF dst, USE shift, KILL cr); 8771 8772 format %{ "rorl $dst, $shift" %} 8773 opcode(0xC1, 0x1); /* C1 /1 ib */ 8774 ins_encode(reg_opc_imm(dst, shift)); 8775 ins_pipe(ialu_reg); 8776 %} 8777 8778 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8779 %{ 8780 effect(USE_DEF dst, USE shift, KILL cr); 8781 8782 format %{ "rorl $dst, $shift" %} 8783 opcode(0xD3, 0x1); /* D3 /1 */ 8784 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8785 ins_pipe(ialu_reg_reg); 8786 %} 8787 // end of ROR expand 8788 8789 // Rotate Right by one 8790 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8791 %{ 8792 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8793 8794 expand %{ 8795 rorI_rReg_imm1(dst, cr); 8796 %} 8797 %} 8798 8799 // Rotate Right by 8-bit immediate 8800 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8801 %{ 8802 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8803 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8804 8805 expand %{ 8806 rorI_rReg_imm8(dst, rshift, cr); 8807 %} 8808 %} 8809 8810 // Rotate Right by variable 8811 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8812 %{ 8813 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8814 8815 expand %{ 8816 rorI_rReg_CL(dst, shift, cr); 8817 %} 8818 %} 8819 8820 // Rotate Right by variable 8821 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8822 %{ 8823 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8824 8825 expand %{ 8826 rorI_rReg_CL(dst, shift, cr); 8827 %} 8828 %} 8829 8830 // for long rotate 8831 // ROL expand 8832 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8833 effect(USE_DEF dst, KILL cr); 8834 8835 format %{ "rolq $dst" %} 8836 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8837 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8838 ins_pipe(ialu_reg); 8839 %} 8840 8841 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8842 effect(USE_DEF dst, USE shift, KILL cr); 8843 8844 format %{ "rolq $dst, $shift" %} 8845 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8846 ins_encode( reg_opc_imm_wide(dst, shift) ); 8847 ins_pipe(ialu_reg); 8848 %} 8849 8850 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8851 %{ 8852 effect(USE_DEF dst, USE shift, KILL cr); 8853 8854 format %{ "rolq $dst, $shift" %} 8855 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8856 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8857 ins_pipe(ialu_reg_reg); 8858 %} 8859 // end of ROL expand 8860 8861 // Rotate Left by one 8862 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8863 %{ 8864 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8865 8866 expand %{ 8867 rolL_rReg_imm1(dst, cr); 8868 %} 8869 %} 8870 8871 // Rotate Left by 8-bit immediate 8872 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8873 %{ 8874 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8875 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8876 8877 expand %{ 8878 rolL_rReg_imm8(dst, lshift, cr); 8879 %} 8880 %} 8881 8882 // Rotate Left by variable 8883 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8884 %{ 8885 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8886 8887 expand %{ 8888 rolL_rReg_CL(dst, shift, cr); 8889 %} 8890 %} 8891 8892 // Rotate Left by variable 8893 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8894 %{ 8895 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8896 8897 expand %{ 8898 rolL_rReg_CL(dst, shift, cr); 8899 %} 8900 %} 8901 8902 // ROR expand 8903 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8904 %{ 8905 effect(USE_DEF dst, KILL cr); 8906 8907 format %{ "rorq $dst" %} 8908 opcode(0xD1, 0x1); /* D1 /1 */ 8909 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8910 ins_pipe(ialu_reg); 8911 %} 8912 8913 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8914 %{ 8915 effect(USE_DEF dst, USE shift, KILL cr); 8916 8917 format %{ "rorq $dst, $shift" %} 8918 opcode(0xC1, 0x1); /* C1 /1 ib */ 8919 ins_encode(reg_opc_imm_wide(dst, shift)); 8920 ins_pipe(ialu_reg); 8921 %} 8922 8923 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8924 %{ 8925 effect(USE_DEF dst, USE shift, KILL cr); 8926 8927 format %{ "rorq $dst, $shift" %} 8928 opcode(0xD3, 0x1); /* D3 /1 */ 8929 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8930 ins_pipe(ialu_reg_reg); 8931 %} 8932 // end of ROR expand 8933 8934 // Rotate Right by one 8935 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8936 %{ 8937 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8938 8939 expand %{ 8940 rorL_rReg_imm1(dst, cr); 8941 %} 8942 %} 8943 8944 // Rotate Right by 8-bit immediate 8945 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8946 %{ 8947 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8948 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8949 8950 expand %{ 8951 rorL_rReg_imm8(dst, rshift, cr); 8952 %} 8953 %} 8954 8955 // Rotate Right by variable 8956 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8957 %{ 8958 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8959 8960 expand %{ 8961 rorL_rReg_CL(dst, shift, cr); 8962 %} 8963 %} 8964 8965 // Rotate Right by variable 8966 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8967 %{ 8968 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8969 8970 expand %{ 8971 rorL_rReg_CL(dst, shift, cr); 8972 %} 8973 %} 8974 8975 // Logical Instructions 8976 8977 // Integer Logical Instructions 8978 8979 // And Instructions 8980 // And Register with Register 8981 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8982 %{ 8983 match(Set dst (AndI dst src)); 8984 effect(KILL cr); 8985 8986 format %{ "andl $dst, $src\t# int" %} 8987 opcode(0x23); 8988 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8989 ins_pipe(ialu_reg_reg); 8990 %} 8991 8992 // And Register with Immediate 255 8993 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 8994 %{ 8995 match(Set dst (AndI dst src)); 8996 8997 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 8998 opcode(0x0F, 0xB6); 8999 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9000 ins_pipe(ialu_reg); 9001 %} 9002 9003 // And Register with Immediate 255 and promote to long 9004 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9005 %{ 9006 match(Set dst (ConvI2L (AndI src mask))); 9007 9008 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9009 opcode(0x0F, 0xB6); 9010 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9011 ins_pipe(ialu_reg); 9012 %} 9013 9014 // And Register with Immediate 65535 9015 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9016 %{ 9017 match(Set dst (AndI dst src)); 9018 9019 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9020 opcode(0x0F, 0xB7); 9021 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9022 ins_pipe(ialu_reg); 9023 %} 9024 9025 // And Register with Immediate 65535 and promote to long 9026 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9027 %{ 9028 match(Set dst (ConvI2L (AndI src mask))); 9029 9030 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9031 opcode(0x0F, 0xB7); 9032 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9033 ins_pipe(ialu_reg); 9034 %} 9035 9036 // And Register with Immediate 9037 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9038 %{ 9039 match(Set dst (AndI dst src)); 9040 effect(KILL cr); 9041 9042 format %{ "andl $dst, $src\t# int" %} 9043 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9044 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9045 ins_pipe(ialu_reg); 9046 %} 9047 9048 // And Register with Memory 9049 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9050 %{ 9051 match(Set dst (AndI dst (LoadI src))); 9052 effect(KILL cr); 9053 9054 ins_cost(125); 9055 format %{ "andl $dst, $src\t# int" %} 9056 opcode(0x23); 9057 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9058 ins_pipe(ialu_reg_mem); 9059 %} 9060 9061 // And Memory with Register 9062 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9063 %{ 9064 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9065 effect(KILL cr); 9066 9067 ins_cost(150); 9068 format %{ "andl $dst, $src\t# int" %} 9069 opcode(0x21); /* Opcode 21 /r */ 9070 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9071 ins_pipe(ialu_mem_reg); 9072 %} 9073 9074 // And Memory with Immediate 9075 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9076 %{ 9077 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9078 effect(KILL cr); 9079 9080 ins_cost(125); 9081 format %{ "andl $dst, $src\t# int" %} 9082 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9083 ins_encode(REX_mem(dst), OpcSE(src), 9084 RM_opc_mem(secondary, dst), Con8or32(src)); 9085 ins_pipe(ialu_mem_imm); 9086 %} 9087 9088 // BMI1 instructions 9089 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9090 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9091 predicate(UseBMI1Instructions); 9092 effect(KILL cr); 9093 9094 ins_cost(125); 9095 format %{ "andnl $dst, $src1, $src2" %} 9096 9097 ins_encode %{ 9098 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9099 %} 9100 ins_pipe(ialu_reg_mem); 9101 %} 9102 9103 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9104 match(Set dst (AndI (XorI src1 minus_1) src2)); 9105 predicate(UseBMI1Instructions); 9106 effect(KILL cr); 9107 9108 format %{ "andnl $dst, $src1, $src2" %} 9109 9110 ins_encode %{ 9111 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9112 %} 9113 ins_pipe(ialu_reg); 9114 %} 9115 9116 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9117 match(Set dst (AndI (SubI imm_zero src) src)); 9118 predicate(UseBMI1Instructions); 9119 effect(KILL cr); 9120 9121 format %{ "blsil $dst, $src" %} 9122 9123 ins_encode %{ 9124 __ blsil($dst$$Register, $src$$Register); 9125 %} 9126 ins_pipe(ialu_reg); 9127 %} 9128 9129 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9130 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9131 predicate(UseBMI1Instructions); 9132 effect(KILL cr); 9133 9134 ins_cost(125); 9135 format %{ "blsil $dst, $src" %} 9136 9137 ins_encode %{ 9138 __ blsil($dst$$Register, $src$$Address); 9139 %} 9140 ins_pipe(ialu_reg_mem); 9141 %} 9142 9143 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9144 %{ 9145 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9146 predicate(UseBMI1Instructions); 9147 effect(KILL cr); 9148 9149 ins_cost(125); 9150 format %{ "blsmskl $dst, $src" %} 9151 9152 ins_encode %{ 9153 __ blsmskl($dst$$Register, $src$$Address); 9154 %} 9155 ins_pipe(ialu_reg_mem); 9156 %} 9157 9158 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9159 %{ 9160 match(Set dst (XorI (AddI src minus_1) src)); 9161 predicate(UseBMI1Instructions); 9162 effect(KILL cr); 9163 9164 format %{ "blsmskl $dst, $src" %} 9165 9166 ins_encode %{ 9167 __ blsmskl($dst$$Register, $src$$Register); 9168 %} 9169 9170 ins_pipe(ialu_reg); 9171 %} 9172 9173 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9174 %{ 9175 match(Set dst (AndI (AddI src minus_1) src) ); 9176 predicate(UseBMI1Instructions); 9177 effect(KILL cr); 9178 9179 format %{ "blsrl $dst, $src" %} 9180 9181 ins_encode %{ 9182 __ blsrl($dst$$Register, $src$$Register); 9183 %} 9184 9185 ins_pipe(ialu_reg_mem); 9186 %} 9187 9188 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9189 %{ 9190 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9191 predicate(UseBMI1Instructions); 9192 effect(KILL cr); 9193 9194 ins_cost(125); 9195 format %{ "blsrl $dst, $src" %} 9196 9197 ins_encode %{ 9198 __ blsrl($dst$$Register, $src$$Address); 9199 %} 9200 9201 ins_pipe(ialu_reg); 9202 %} 9203 9204 // Or Instructions 9205 // Or Register with Register 9206 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9207 %{ 9208 match(Set dst (OrI dst src)); 9209 effect(KILL cr); 9210 9211 format %{ "orl $dst, $src\t# int" %} 9212 opcode(0x0B); 9213 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9214 ins_pipe(ialu_reg_reg); 9215 %} 9216 9217 // Or Register with Immediate 9218 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9219 %{ 9220 match(Set dst (OrI dst src)); 9221 effect(KILL cr); 9222 9223 format %{ "orl $dst, $src\t# int" %} 9224 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9225 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9226 ins_pipe(ialu_reg); 9227 %} 9228 9229 // Or Register with Memory 9230 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9231 %{ 9232 match(Set dst (OrI dst (LoadI src))); 9233 effect(KILL cr); 9234 9235 ins_cost(125); 9236 format %{ "orl $dst, $src\t# int" %} 9237 opcode(0x0B); 9238 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9239 ins_pipe(ialu_reg_mem); 9240 %} 9241 9242 // Or Memory with Register 9243 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9244 %{ 9245 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9246 effect(KILL cr); 9247 9248 ins_cost(150); 9249 format %{ "orl $dst, $src\t# int" %} 9250 opcode(0x09); /* Opcode 09 /r */ 9251 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9252 ins_pipe(ialu_mem_reg); 9253 %} 9254 9255 // Or Memory with Immediate 9256 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9257 %{ 9258 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9259 effect(KILL cr); 9260 9261 ins_cost(125); 9262 format %{ "orl $dst, $src\t# int" %} 9263 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9264 ins_encode(REX_mem(dst), OpcSE(src), 9265 RM_opc_mem(secondary, dst), Con8or32(src)); 9266 ins_pipe(ialu_mem_imm); 9267 %} 9268 9269 // Xor Instructions 9270 // Xor Register with Register 9271 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9272 %{ 9273 match(Set dst (XorI dst src)); 9274 effect(KILL cr); 9275 9276 format %{ "xorl $dst, $src\t# int" %} 9277 opcode(0x33); 9278 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9279 ins_pipe(ialu_reg_reg); 9280 %} 9281 9282 // Xor Register with Immediate -1 9283 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9284 match(Set dst (XorI dst imm)); 9285 9286 format %{ "not $dst" %} 9287 ins_encode %{ 9288 __ notl($dst$$Register); 9289 %} 9290 ins_pipe(ialu_reg); 9291 %} 9292 9293 // Xor Register with Immediate 9294 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9295 %{ 9296 match(Set dst (XorI dst src)); 9297 effect(KILL cr); 9298 9299 format %{ "xorl $dst, $src\t# int" %} 9300 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9301 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9302 ins_pipe(ialu_reg); 9303 %} 9304 9305 // Xor Register with Memory 9306 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9307 %{ 9308 match(Set dst (XorI dst (LoadI src))); 9309 effect(KILL cr); 9310 9311 ins_cost(125); 9312 format %{ "xorl $dst, $src\t# int" %} 9313 opcode(0x33); 9314 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9315 ins_pipe(ialu_reg_mem); 9316 %} 9317 9318 // Xor Memory with Register 9319 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9320 %{ 9321 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9322 effect(KILL cr); 9323 9324 ins_cost(150); 9325 format %{ "xorl $dst, $src\t# int" %} 9326 opcode(0x31); /* Opcode 31 /r */ 9327 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9328 ins_pipe(ialu_mem_reg); 9329 %} 9330 9331 // Xor Memory with Immediate 9332 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9333 %{ 9334 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9335 effect(KILL cr); 9336 9337 ins_cost(125); 9338 format %{ "xorl $dst, $src\t# int" %} 9339 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9340 ins_encode(REX_mem(dst), OpcSE(src), 9341 RM_opc_mem(secondary, dst), Con8or32(src)); 9342 ins_pipe(ialu_mem_imm); 9343 %} 9344 9345 9346 // Long Logical Instructions 9347 9348 // And Instructions 9349 // And Register with Register 9350 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9351 %{ 9352 match(Set dst (AndL dst src)); 9353 effect(KILL cr); 9354 9355 format %{ "andq $dst, $src\t# long" %} 9356 opcode(0x23); 9357 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9358 ins_pipe(ialu_reg_reg); 9359 %} 9360 9361 // And Register with Immediate 255 9362 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9363 %{ 9364 match(Set dst (AndL dst src)); 9365 9366 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9367 opcode(0x0F, 0xB6); 9368 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9369 ins_pipe(ialu_reg); 9370 %} 9371 9372 // And Register with Immediate 65535 9373 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9374 %{ 9375 match(Set dst (AndL dst src)); 9376 9377 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9378 opcode(0x0F, 0xB7); 9379 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9380 ins_pipe(ialu_reg); 9381 %} 9382 9383 // And Register with Immediate 9384 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9385 %{ 9386 match(Set dst (AndL dst src)); 9387 effect(KILL cr); 9388 9389 format %{ "andq $dst, $src\t# long" %} 9390 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9391 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9392 ins_pipe(ialu_reg); 9393 %} 9394 9395 // And Register with Memory 9396 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9397 %{ 9398 match(Set dst (AndL dst (LoadL src))); 9399 effect(KILL cr); 9400 9401 ins_cost(125); 9402 format %{ "andq $dst, $src\t# long" %} 9403 opcode(0x23); 9404 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9405 ins_pipe(ialu_reg_mem); 9406 %} 9407 9408 // And Memory with Register 9409 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9410 %{ 9411 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9412 effect(KILL cr); 9413 9414 ins_cost(150); 9415 format %{ "andq $dst, $src\t# long" %} 9416 opcode(0x21); /* Opcode 21 /r */ 9417 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9418 ins_pipe(ialu_mem_reg); 9419 %} 9420 9421 // And Memory with Immediate 9422 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9423 %{ 9424 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9425 effect(KILL cr); 9426 9427 ins_cost(125); 9428 format %{ "andq $dst, $src\t# long" %} 9429 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9430 ins_encode(REX_mem_wide(dst), OpcSE(src), 9431 RM_opc_mem(secondary, dst), Con8or32(src)); 9432 ins_pipe(ialu_mem_imm); 9433 %} 9434 9435 // BMI1 instructions 9436 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9437 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9438 predicate(UseBMI1Instructions); 9439 effect(KILL cr); 9440 9441 ins_cost(125); 9442 format %{ "andnq $dst, $src1, $src2" %} 9443 9444 ins_encode %{ 9445 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9446 %} 9447 ins_pipe(ialu_reg_mem); 9448 %} 9449 9450 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9451 match(Set dst (AndL (XorL src1 minus_1) src2)); 9452 predicate(UseBMI1Instructions); 9453 effect(KILL cr); 9454 9455 format %{ "andnq $dst, $src1, $src2" %} 9456 9457 ins_encode %{ 9458 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9459 %} 9460 ins_pipe(ialu_reg_mem); 9461 %} 9462 9463 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9464 match(Set dst (AndL (SubL imm_zero src) src)); 9465 predicate(UseBMI1Instructions); 9466 effect(KILL cr); 9467 9468 format %{ "blsiq $dst, $src" %} 9469 9470 ins_encode %{ 9471 __ blsiq($dst$$Register, $src$$Register); 9472 %} 9473 ins_pipe(ialu_reg); 9474 %} 9475 9476 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9477 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9478 predicate(UseBMI1Instructions); 9479 effect(KILL cr); 9480 9481 ins_cost(125); 9482 format %{ "blsiq $dst, $src" %} 9483 9484 ins_encode %{ 9485 __ blsiq($dst$$Register, $src$$Address); 9486 %} 9487 ins_pipe(ialu_reg_mem); 9488 %} 9489 9490 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9491 %{ 9492 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9493 predicate(UseBMI1Instructions); 9494 effect(KILL cr); 9495 9496 ins_cost(125); 9497 format %{ "blsmskq $dst, $src" %} 9498 9499 ins_encode %{ 9500 __ blsmskq($dst$$Register, $src$$Address); 9501 %} 9502 ins_pipe(ialu_reg_mem); 9503 %} 9504 9505 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9506 %{ 9507 match(Set dst (XorL (AddL src minus_1) src)); 9508 predicate(UseBMI1Instructions); 9509 effect(KILL cr); 9510 9511 format %{ "blsmskq $dst, $src" %} 9512 9513 ins_encode %{ 9514 __ blsmskq($dst$$Register, $src$$Register); 9515 %} 9516 9517 ins_pipe(ialu_reg); 9518 %} 9519 9520 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9521 %{ 9522 match(Set dst (AndL (AddL src minus_1) src) ); 9523 predicate(UseBMI1Instructions); 9524 effect(KILL cr); 9525 9526 format %{ "blsrq $dst, $src" %} 9527 9528 ins_encode %{ 9529 __ blsrq($dst$$Register, $src$$Register); 9530 %} 9531 9532 ins_pipe(ialu_reg); 9533 %} 9534 9535 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9536 %{ 9537 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9538 predicate(UseBMI1Instructions); 9539 effect(KILL cr); 9540 9541 ins_cost(125); 9542 format %{ "blsrq $dst, $src" %} 9543 9544 ins_encode %{ 9545 __ blsrq($dst$$Register, $src$$Address); 9546 %} 9547 9548 ins_pipe(ialu_reg); 9549 %} 9550 9551 // Or Instructions 9552 // Or Register with Register 9553 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9554 %{ 9555 match(Set dst (OrL dst src)); 9556 effect(KILL cr); 9557 9558 format %{ "orq $dst, $src\t# long" %} 9559 opcode(0x0B); 9560 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9561 ins_pipe(ialu_reg_reg); 9562 %} 9563 9564 // Use any_RegP to match R15 (TLS register) without spilling. 9565 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9566 match(Set dst (OrL dst (CastP2X src))); 9567 effect(KILL cr); 9568 9569 format %{ "orq $dst, $src\t# long" %} 9570 opcode(0x0B); 9571 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9572 ins_pipe(ialu_reg_reg); 9573 %} 9574 9575 9576 // Or Register with Immediate 9577 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9578 %{ 9579 match(Set dst (OrL dst src)); 9580 effect(KILL cr); 9581 9582 format %{ "orq $dst, $src\t# long" %} 9583 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9584 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9585 ins_pipe(ialu_reg); 9586 %} 9587 9588 // Or Register with Memory 9589 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9590 %{ 9591 match(Set dst (OrL dst (LoadL src))); 9592 effect(KILL cr); 9593 9594 ins_cost(125); 9595 format %{ "orq $dst, $src\t# long" %} 9596 opcode(0x0B); 9597 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9598 ins_pipe(ialu_reg_mem); 9599 %} 9600 9601 // Or Memory with Register 9602 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9603 %{ 9604 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9605 effect(KILL cr); 9606 9607 ins_cost(150); 9608 format %{ "orq $dst, $src\t# long" %} 9609 opcode(0x09); /* Opcode 09 /r */ 9610 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9611 ins_pipe(ialu_mem_reg); 9612 %} 9613 9614 // Or Memory with Immediate 9615 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9616 %{ 9617 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9618 effect(KILL cr); 9619 9620 ins_cost(125); 9621 format %{ "orq $dst, $src\t# long" %} 9622 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9623 ins_encode(REX_mem_wide(dst), OpcSE(src), 9624 RM_opc_mem(secondary, dst), Con8or32(src)); 9625 ins_pipe(ialu_mem_imm); 9626 %} 9627 9628 // Xor Instructions 9629 // Xor Register with Register 9630 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9631 %{ 9632 match(Set dst (XorL dst src)); 9633 effect(KILL cr); 9634 9635 format %{ "xorq $dst, $src\t# long" %} 9636 opcode(0x33); 9637 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9638 ins_pipe(ialu_reg_reg); 9639 %} 9640 9641 // Xor Register with Immediate -1 9642 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9643 match(Set dst (XorL dst imm)); 9644 9645 format %{ "notq $dst" %} 9646 ins_encode %{ 9647 __ notq($dst$$Register); 9648 %} 9649 ins_pipe(ialu_reg); 9650 %} 9651 9652 // Xor Register with Immediate 9653 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9654 %{ 9655 match(Set dst (XorL dst src)); 9656 effect(KILL cr); 9657 9658 format %{ "xorq $dst, $src\t# long" %} 9659 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9660 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9661 ins_pipe(ialu_reg); 9662 %} 9663 9664 // Xor Register with Memory 9665 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9666 %{ 9667 match(Set dst (XorL dst (LoadL src))); 9668 effect(KILL cr); 9669 9670 ins_cost(125); 9671 format %{ "xorq $dst, $src\t# long" %} 9672 opcode(0x33); 9673 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9674 ins_pipe(ialu_reg_mem); 9675 %} 9676 9677 // Xor Memory with Register 9678 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9679 %{ 9680 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9681 effect(KILL cr); 9682 9683 ins_cost(150); 9684 format %{ "xorq $dst, $src\t# long" %} 9685 opcode(0x31); /* Opcode 31 /r */ 9686 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9687 ins_pipe(ialu_mem_reg); 9688 %} 9689 9690 // Xor Memory with Immediate 9691 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9692 %{ 9693 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9694 effect(KILL cr); 9695 9696 ins_cost(125); 9697 format %{ "xorq $dst, $src\t# long" %} 9698 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9699 ins_encode(REX_mem_wide(dst), OpcSE(src), 9700 RM_opc_mem(secondary, dst), Con8or32(src)); 9701 ins_pipe(ialu_mem_imm); 9702 %} 9703 9704 // Convert Int to Boolean 9705 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9706 %{ 9707 match(Set dst (Conv2B src)); 9708 effect(KILL cr); 9709 9710 format %{ "testl $src, $src\t# ci2b\n\t" 9711 "setnz $dst\n\t" 9712 "movzbl $dst, $dst" %} 9713 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9714 setNZ_reg(dst), 9715 REX_reg_breg(dst, dst), // movzbl 9716 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9717 ins_pipe(pipe_slow); // XXX 9718 %} 9719 9720 // Convert Pointer to Boolean 9721 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9722 %{ 9723 match(Set dst (Conv2B src)); 9724 effect(KILL cr); 9725 9726 format %{ "testq $src, $src\t# cp2b\n\t" 9727 "setnz $dst\n\t" 9728 "movzbl $dst, $dst" %} 9729 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9730 setNZ_reg(dst), 9731 REX_reg_breg(dst, dst), // movzbl 9732 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9733 ins_pipe(pipe_slow); // XXX 9734 %} 9735 9736 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9737 %{ 9738 match(Set dst (CmpLTMask p q)); 9739 effect(KILL cr); 9740 9741 ins_cost(400); 9742 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9743 "setlt $dst\n\t" 9744 "movzbl $dst, $dst\n\t" 9745 "negl $dst" %} 9746 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9747 setLT_reg(dst), 9748 REX_reg_breg(dst, dst), // movzbl 9749 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9750 neg_reg(dst)); 9751 ins_pipe(pipe_slow); 9752 %} 9753 9754 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9755 %{ 9756 match(Set dst (CmpLTMask dst zero)); 9757 effect(KILL cr); 9758 9759 ins_cost(100); 9760 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9761 ins_encode %{ 9762 __ sarl($dst$$Register, 31); 9763 %} 9764 ins_pipe(ialu_reg); 9765 %} 9766 9767 /* Better to save a register than avoid a branch */ 9768 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9769 %{ 9770 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9771 effect(KILL cr); 9772 ins_cost(300); 9773 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9774 "jge done\n\t" 9775 "addl $p,$y\n" 9776 "done: " %} 9777 ins_encode %{ 9778 Register Rp = $p$$Register; 9779 Register Rq = $q$$Register; 9780 Register Ry = $y$$Register; 9781 Label done; 9782 __ subl(Rp, Rq); 9783 __ jccb(Assembler::greaterEqual, done); 9784 __ addl(Rp, Ry); 9785 __ bind(done); 9786 %} 9787 ins_pipe(pipe_cmplt); 9788 %} 9789 9790 /* Better to save a register than avoid a branch */ 9791 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9792 %{ 9793 match(Set y (AndI (CmpLTMask p q) y)); 9794 effect(KILL cr); 9795 9796 ins_cost(300); 9797 9798 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9799 "jlt done\n\t" 9800 "xorl $y, $y\n" 9801 "done: " %} 9802 ins_encode %{ 9803 Register Rp = $p$$Register; 9804 Register Rq = $q$$Register; 9805 Register Ry = $y$$Register; 9806 Label done; 9807 __ cmpl(Rp, Rq); 9808 __ jccb(Assembler::less, done); 9809 __ xorl(Ry, Ry); 9810 __ bind(done); 9811 %} 9812 ins_pipe(pipe_cmplt); 9813 %} 9814 9815 9816 //---------- FP Instructions------------------------------------------------ 9817 9818 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9819 %{ 9820 match(Set cr (CmpF src1 src2)); 9821 9822 ins_cost(145); 9823 format %{ "ucomiss $src1, $src2\n\t" 9824 "jnp,s exit\n\t" 9825 "pushfq\t# saw NaN, set CF\n\t" 9826 "andq [rsp], #0xffffff2b\n\t" 9827 "popfq\n" 9828 "exit:" %} 9829 ins_encode %{ 9830 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9831 emit_cmpfp_fixup(_masm); 9832 %} 9833 ins_pipe(pipe_slow); 9834 %} 9835 9836 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9837 match(Set cr (CmpF src1 src2)); 9838 9839 ins_cost(100); 9840 format %{ "ucomiss $src1, $src2" %} 9841 ins_encode %{ 9842 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9843 %} 9844 ins_pipe(pipe_slow); 9845 %} 9846 9847 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9848 %{ 9849 match(Set cr (CmpF src1 (LoadF src2))); 9850 9851 ins_cost(145); 9852 format %{ "ucomiss $src1, $src2\n\t" 9853 "jnp,s exit\n\t" 9854 "pushfq\t# saw NaN, set CF\n\t" 9855 "andq [rsp], #0xffffff2b\n\t" 9856 "popfq\n" 9857 "exit:" %} 9858 ins_encode %{ 9859 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9860 emit_cmpfp_fixup(_masm); 9861 %} 9862 ins_pipe(pipe_slow); 9863 %} 9864 9865 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9866 match(Set cr (CmpF src1 (LoadF src2))); 9867 9868 ins_cost(100); 9869 format %{ "ucomiss $src1, $src2" %} 9870 ins_encode %{ 9871 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9872 %} 9873 ins_pipe(pipe_slow); 9874 %} 9875 9876 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9877 match(Set cr (CmpF src con)); 9878 9879 ins_cost(145); 9880 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9881 "jnp,s exit\n\t" 9882 "pushfq\t# saw NaN, set CF\n\t" 9883 "andq [rsp], #0xffffff2b\n\t" 9884 "popfq\n" 9885 "exit:" %} 9886 ins_encode %{ 9887 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9888 emit_cmpfp_fixup(_masm); 9889 %} 9890 ins_pipe(pipe_slow); 9891 %} 9892 9893 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9894 match(Set cr (CmpF src con)); 9895 ins_cost(100); 9896 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9897 ins_encode %{ 9898 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9899 %} 9900 ins_pipe(pipe_slow); 9901 %} 9902 9903 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9904 %{ 9905 match(Set cr (CmpD src1 src2)); 9906 9907 ins_cost(145); 9908 format %{ "ucomisd $src1, $src2\n\t" 9909 "jnp,s exit\n\t" 9910 "pushfq\t# saw NaN, set CF\n\t" 9911 "andq [rsp], #0xffffff2b\n\t" 9912 "popfq\n" 9913 "exit:" %} 9914 ins_encode %{ 9915 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9916 emit_cmpfp_fixup(_masm); 9917 %} 9918 ins_pipe(pipe_slow); 9919 %} 9920 9921 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9922 match(Set cr (CmpD src1 src2)); 9923 9924 ins_cost(100); 9925 format %{ "ucomisd $src1, $src2 test" %} 9926 ins_encode %{ 9927 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9928 %} 9929 ins_pipe(pipe_slow); 9930 %} 9931 9932 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9933 %{ 9934 match(Set cr (CmpD src1 (LoadD src2))); 9935 9936 ins_cost(145); 9937 format %{ "ucomisd $src1, $src2\n\t" 9938 "jnp,s exit\n\t" 9939 "pushfq\t# saw NaN, set CF\n\t" 9940 "andq [rsp], #0xffffff2b\n\t" 9941 "popfq\n" 9942 "exit:" %} 9943 ins_encode %{ 9944 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9945 emit_cmpfp_fixup(_masm); 9946 %} 9947 ins_pipe(pipe_slow); 9948 %} 9949 9950 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9951 match(Set cr (CmpD src1 (LoadD src2))); 9952 9953 ins_cost(100); 9954 format %{ "ucomisd $src1, $src2" %} 9955 ins_encode %{ 9956 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9957 %} 9958 ins_pipe(pipe_slow); 9959 %} 9960 9961 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9962 match(Set cr (CmpD src con)); 9963 9964 ins_cost(145); 9965 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9966 "jnp,s exit\n\t" 9967 "pushfq\t# saw NaN, set CF\n\t" 9968 "andq [rsp], #0xffffff2b\n\t" 9969 "popfq\n" 9970 "exit:" %} 9971 ins_encode %{ 9972 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9973 emit_cmpfp_fixup(_masm); 9974 %} 9975 ins_pipe(pipe_slow); 9976 %} 9977 9978 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9979 match(Set cr (CmpD src con)); 9980 ins_cost(100); 9981 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9982 ins_encode %{ 9983 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9984 %} 9985 ins_pipe(pipe_slow); 9986 %} 9987 9988 // Compare into -1,0,1 9989 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9990 %{ 9991 match(Set dst (CmpF3 src1 src2)); 9992 effect(KILL cr); 9993 9994 ins_cost(275); 9995 format %{ "ucomiss $src1, $src2\n\t" 9996 "movl $dst, #-1\n\t" 9997 "jp,s done\n\t" 9998 "jb,s done\n\t" 9999 "setne $dst\n\t" 10000 "movzbl $dst, $dst\n" 10001 "done:" %} 10002 ins_encode %{ 10003 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10004 emit_cmpfp3(_masm, $dst$$Register); 10005 %} 10006 ins_pipe(pipe_slow); 10007 %} 10008 10009 // Compare into -1,0,1 10010 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10011 %{ 10012 match(Set dst (CmpF3 src1 (LoadF src2))); 10013 effect(KILL cr); 10014 10015 ins_cost(275); 10016 format %{ "ucomiss $src1, $src2\n\t" 10017 "movl $dst, #-1\n\t" 10018 "jp,s done\n\t" 10019 "jb,s done\n\t" 10020 "setne $dst\n\t" 10021 "movzbl $dst, $dst\n" 10022 "done:" %} 10023 ins_encode %{ 10024 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10025 emit_cmpfp3(_masm, $dst$$Register); 10026 %} 10027 ins_pipe(pipe_slow); 10028 %} 10029 10030 // Compare into -1,0,1 10031 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10032 match(Set dst (CmpF3 src con)); 10033 effect(KILL cr); 10034 10035 ins_cost(275); 10036 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10037 "movl $dst, #-1\n\t" 10038 "jp,s done\n\t" 10039 "jb,s done\n\t" 10040 "setne $dst\n\t" 10041 "movzbl $dst, $dst\n" 10042 "done:" %} 10043 ins_encode %{ 10044 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10045 emit_cmpfp3(_masm, $dst$$Register); 10046 %} 10047 ins_pipe(pipe_slow); 10048 %} 10049 10050 // Compare into -1,0,1 10051 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10052 %{ 10053 match(Set dst (CmpD3 src1 src2)); 10054 effect(KILL cr); 10055 10056 ins_cost(275); 10057 format %{ "ucomisd $src1, $src2\n\t" 10058 "movl $dst, #-1\n\t" 10059 "jp,s done\n\t" 10060 "jb,s done\n\t" 10061 "setne $dst\n\t" 10062 "movzbl $dst, $dst\n" 10063 "done:" %} 10064 ins_encode %{ 10065 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10066 emit_cmpfp3(_masm, $dst$$Register); 10067 %} 10068 ins_pipe(pipe_slow); 10069 %} 10070 10071 // Compare into -1,0,1 10072 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10073 %{ 10074 match(Set dst (CmpD3 src1 (LoadD src2))); 10075 effect(KILL cr); 10076 10077 ins_cost(275); 10078 format %{ "ucomisd $src1, $src2\n\t" 10079 "movl $dst, #-1\n\t" 10080 "jp,s done\n\t" 10081 "jb,s done\n\t" 10082 "setne $dst\n\t" 10083 "movzbl $dst, $dst\n" 10084 "done:" %} 10085 ins_encode %{ 10086 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10087 emit_cmpfp3(_masm, $dst$$Register); 10088 %} 10089 ins_pipe(pipe_slow); 10090 %} 10091 10092 // Compare into -1,0,1 10093 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10094 match(Set dst (CmpD3 src con)); 10095 effect(KILL cr); 10096 10097 ins_cost(275); 10098 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10099 "movl $dst, #-1\n\t" 10100 "jp,s done\n\t" 10101 "jb,s done\n\t" 10102 "setne $dst\n\t" 10103 "movzbl $dst, $dst\n" 10104 "done:" %} 10105 ins_encode %{ 10106 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10107 emit_cmpfp3(_masm, $dst$$Register); 10108 %} 10109 ins_pipe(pipe_slow); 10110 %} 10111 10112 //----------Arithmetic Conversion Instructions--------------------------------- 10113 10114 instruct roundFloat_nop(regF dst) 10115 %{ 10116 match(Set dst (RoundFloat dst)); 10117 10118 ins_cost(0); 10119 ins_encode(); 10120 ins_pipe(empty); 10121 %} 10122 10123 instruct roundDouble_nop(regD dst) 10124 %{ 10125 match(Set dst (RoundDouble dst)); 10126 10127 ins_cost(0); 10128 ins_encode(); 10129 ins_pipe(empty); 10130 %} 10131 10132 instruct convF2D_reg_reg(regD dst, regF src) 10133 %{ 10134 match(Set dst (ConvF2D src)); 10135 10136 format %{ "cvtss2sd $dst, $src" %} 10137 ins_encode %{ 10138 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10139 %} 10140 ins_pipe(pipe_slow); // XXX 10141 %} 10142 10143 instruct convF2D_reg_mem(regD dst, memory src) 10144 %{ 10145 match(Set dst (ConvF2D (LoadF src))); 10146 10147 format %{ "cvtss2sd $dst, $src" %} 10148 ins_encode %{ 10149 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10150 %} 10151 ins_pipe(pipe_slow); // XXX 10152 %} 10153 10154 instruct convD2F_reg_reg(regF dst, regD src) 10155 %{ 10156 match(Set dst (ConvD2F src)); 10157 10158 format %{ "cvtsd2ss $dst, $src" %} 10159 ins_encode %{ 10160 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10161 %} 10162 ins_pipe(pipe_slow); // XXX 10163 %} 10164 10165 instruct convD2F_reg_mem(regF dst, memory src) 10166 %{ 10167 match(Set dst (ConvD2F (LoadD src))); 10168 10169 format %{ "cvtsd2ss $dst, $src" %} 10170 ins_encode %{ 10171 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10172 %} 10173 ins_pipe(pipe_slow); // XXX 10174 %} 10175 10176 // XXX do mem variants 10177 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10178 %{ 10179 match(Set dst (ConvF2I src)); 10180 effect(KILL cr); 10181 10182 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10183 "cmpl $dst, #0x80000000\n\t" 10184 "jne,s done\n\t" 10185 "subq rsp, #8\n\t" 10186 "movss [rsp], $src\n\t" 10187 "call f2i_fixup\n\t" 10188 "popq $dst\n" 10189 "done: "%} 10190 ins_encode %{ 10191 Label done; 10192 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10193 __ cmpl($dst$$Register, 0x80000000); 10194 __ jccb(Assembler::notEqual, done); 10195 __ subptr(rsp, 8); 10196 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10197 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10198 __ pop($dst$$Register); 10199 __ bind(done); 10200 %} 10201 ins_pipe(pipe_slow); 10202 %} 10203 10204 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10205 %{ 10206 match(Set dst (ConvF2L src)); 10207 effect(KILL cr); 10208 10209 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10210 "cmpq $dst, [0x8000000000000000]\n\t" 10211 "jne,s done\n\t" 10212 "subq rsp, #8\n\t" 10213 "movss [rsp], $src\n\t" 10214 "call f2l_fixup\n\t" 10215 "popq $dst\n" 10216 "done: "%} 10217 ins_encode %{ 10218 Label done; 10219 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10220 __ cmp64($dst$$Register, 10221 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10222 __ jccb(Assembler::notEqual, done); 10223 __ subptr(rsp, 8); 10224 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10225 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10226 __ pop($dst$$Register); 10227 __ bind(done); 10228 %} 10229 ins_pipe(pipe_slow); 10230 %} 10231 10232 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10233 %{ 10234 match(Set dst (ConvD2I src)); 10235 effect(KILL cr); 10236 10237 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10238 "cmpl $dst, #0x80000000\n\t" 10239 "jne,s done\n\t" 10240 "subq rsp, #8\n\t" 10241 "movsd [rsp], $src\n\t" 10242 "call d2i_fixup\n\t" 10243 "popq $dst\n" 10244 "done: "%} 10245 ins_encode %{ 10246 Label done; 10247 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10248 __ cmpl($dst$$Register, 0x80000000); 10249 __ jccb(Assembler::notEqual, done); 10250 __ subptr(rsp, 8); 10251 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10252 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10253 __ pop($dst$$Register); 10254 __ bind(done); 10255 %} 10256 ins_pipe(pipe_slow); 10257 %} 10258 10259 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10260 %{ 10261 match(Set dst (ConvD2L src)); 10262 effect(KILL cr); 10263 10264 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10265 "cmpq $dst, [0x8000000000000000]\n\t" 10266 "jne,s done\n\t" 10267 "subq rsp, #8\n\t" 10268 "movsd [rsp], $src\n\t" 10269 "call d2l_fixup\n\t" 10270 "popq $dst\n" 10271 "done: "%} 10272 ins_encode %{ 10273 Label done; 10274 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10275 __ cmp64($dst$$Register, 10276 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10277 __ jccb(Assembler::notEqual, done); 10278 __ subptr(rsp, 8); 10279 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10280 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10281 __ pop($dst$$Register); 10282 __ bind(done); 10283 %} 10284 ins_pipe(pipe_slow); 10285 %} 10286 10287 instruct convI2F_reg_reg(regF dst, rRegI src) 10288 %{ 10289 predicate(!UseXmmI2F); 10290 match(Set dst (ConvI2F src)); 10291 10292 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10293 ins_encode %{ 10294 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10295 %} 10296 ins_pipe(pipe_slow); // XXX 10297 %} 10298 10299 instruct convI2F_reg_mem(regF dst, memory src) 10300 %{ 10301 match(Set dst (ConvI2F (LoadI src))); 10302 10303 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10304 ins_encode %{ 10305 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10306 %} 10307 ins_pipe(pipe_slow); // XXX 10308 %} 10309 10310 instruct convI2D_reg_reg(regD dst, rRegI src) 10311 %{ 10312 predicate(!UseXmmI2D); 10313 match(Set dst (ConvI2D src)); 10314 10315 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10316 ins_encode %{ 10317 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10318 %} 10319 ins_pipe(pipe_slow); // XXX 10320 %} 10321 10322 instruct convI2D_reg_mem(regD dst, memory src) 10323 %{ 10324 match(Set dst (ConvI2D (LoadI src))); 10325 10326 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10327 ins_encode %{ 10328 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10329 %} 10330 ins_pipe(pipe_slow); // XXX 10331 %} 10332 10333 instruct convXI2F_reg(regF dst, rRegI src) 10334 %{ 10335 predicate(UseXmmI2F); 10336 match(Set dst (ConvI2F src)); 10337 10338 format %{ "movdl $dst, $src\n\t" 10339 "cvtdq2psl $dst, $dst\t# i2f" %} 10340 ins_encode %{ 10341 __ movdl($dst$$XMMRegister, $src$$Register); 10342 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10343 %} 10344 ins_pipe(pipe_slow); // XXX 10345 %} 10346 10347 instruct convXI2D_reg(regD dst, rRegI src) 10348 %{ 10349 predicate(UseXmmI2D); 10350 match(Set dst (ConvI2D src)); 10351 10352 format %{ "movdl $dst, $src\n\t" 10353 "cvtdq2pdl $dst, $dst\t# i2d" %} 10354 ins_encode %{ 10355 __ movdl($dst$$XMMRegister, $src$$Register); 10356 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10357 %} 10358 ins_pipe(pipe_slow); // XXX 10359 %} 10360 10361 instruct convL2F_reg_reg(regF dst, rRegL src) 10362 %{ 10363 match(Set dst (ConvL2F src)); 10364 10365 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10366 ins_encode %{ 10367 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10368 %} 10369 ins_pipe(pipe_slow); // XXX 10370 %} 10371 10372 instruct convL2F_reg_mem(regF dst, memory src) 10373 %{ 10374 match(Set dst (ConvL2F (LoadL src))); 10375 10376 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10377 ins_encode %{ 10378 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10379 %} 10380 ins_pipe(pipe_slow); // XXX 10381 %} 10382 10383 instruct convL2D_reg_reg(regD dst, rRegL src) 10384 %{ 10385 match(Set dst (ConvL2D src)); 10386 10387 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10388 ins_encode %{ 10389 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10390 %} 10391 ins_pipe(pipe_slow); // XXX 10392 %} 10393 10394 instruct convL2D_reg_mem(regD dst, memory src) 10395 %{ 10396 match(Set dst (ConvL2D (LoadL src))); 10397 10398 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10399 ins_encode %{ 10400 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10401 %} 10402 ins_pipe(pipe_slow); // XXX 10403 %} 10404 10405 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10406 %{ 10407 match(Set dst (ConvI2L src)); 10408 10409 ins_cost(125); 10410 format %{ "movslq $dst, $src\t# i2l" %} 10411 ins_encode %{ 10412 __ movslq($dst$$Register, $src$$Register); 10413 %} 10414 ins_pipe(ialu_reg_reg); 10415 %} 10416 10417 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10418 // %{ 10419 // match(Set dst (ConvI2L src)); 10420 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10421 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10422 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10423 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10424 // ((const TypeNode*) n)->type()->is_long()->_lo == 10425 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10426 10427 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10428 // ins_encode(enc_copy(dst, src)); 10429 // // opcode(0x63); // needs REX.W 10430 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10431 // ins_pipe(ialu_reg_reg); 10432 // %} 10433 10434 // Zero-extend convert int to long 10435 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10436 %{ 10437 match(Set dst (AndL (ConvI2L src) mask)); 10438 10439 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10440 ins_encode %{ 10441 if ($dst$$reg != $src$$reg) { 10442 __ movl($dst$$Register, $src$$Register); 10443 } 10444 %} 10445 ins_pipe(ialu_reg_reg); 10446 %} 10447 10448 // Zero-extend convert int to long 10449 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10450 %{ 10451 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10452 10453 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10454 ins_encode %{ 10455 __ movl($dst$$Register, $src$$Address); 10456 %} 10457 ins_pipe(ialu_reg_mem); 10458 %} 10459 10460 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10461 %{ 10462 match(Set dst (AndL src mask)); 10463 10464 format %{ "movl $dst, $src\t# zero-extend long" %} 10465 ins_encode %{ 10466 __ movl($dst$$Register, $src$$Register); 10467 %} 10468 ins_pipe(ialu_reg_reg); 10469 %} 10470 10471 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10472 %{ 10473 match(Set dst (ConvL2I src)); 10474 10475 format %{ "movl $dst, $src\t# l2i" %} 10476 ins_encode %{ 10477 __ movl($dst$$Register, $src$$Register); 10478 %} 10479 ins_pipe(ialu_reg_reg); 10480 %} 10481 10482 10483 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10484 match(Set dst (MoveF2I src)); 10485 effect(DEF dst, USE src); 10486 10487 ins_cost(125); 10488 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10489 ins_encode %{ 10490 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10491 %} 10492 ins_pipe(ialu_reg_mem); 10493 %} 10494 10495 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10496 match(Set dst (MoveI2F src)); 10497 effect(DEF dst, USE src); 10498 10499 ins_cost(125); 10500 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10501 ins_encode %{ 10502 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10503 %} 10504 ins_pipe(pipe_slow); 10505 %} 10506 10507 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10508 match(Set dst (MoveD2L src)); 10509 effect(DEF dst, USE src); 10510 10511 ins_cost(125); 10512 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10513 ins_encode %{ 10514 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10515 %} 10516 ins_pipe(ialu_reg_mem); 10517 %} 10518 10519 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10520 predicate(!UseXmmLoadAndClearUpper); 10521 match(Set dst (MoveL2D src)); 10522 effect(DEF dst, USE src); 10523 10524 ins_cost(125); 10525 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10526 ins_encode %{ 10527 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10528 %} 10529 ins_pipe(pipe_slow); 10530 %} 10531 10532 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10533 predicate(UseXmmLoadAndClearUpper); 10534 match(Set dst (MoveL2D src)); 10535 effect(DEF dst, USE src); 10536 10537 ins_cost(125); 10538 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10539 ins_encode %{ 10540 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10541 %} 10542 ins_pipe(pipe_slow); 10543 %} 10544 10545 10546 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10547 match(Set dst (MoveF2I src)); 10548 effect(DEF dst, USE src); 10549 10550 ins_cost(95); // XXX 10551 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10552 ins_encode %{ 10553 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10554 %} 10555 ins_pipe(pipe_slow); 10556 %} 10557 10558 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10559 match(Set dst (MoveI2F src)); 10560 effect(DEF dst, USE src); 10561 10562 ins_cost(100); 10563 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10564 ins_encode %{ 10565 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10566 %} 10567 ins_pipe( ialu_mem_reg ); 10568 %} 10569 10570 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10571 match(Set dst (MoveD2L src)); 10572 effect(DEF dst, USE src); 10573 10574 ins_cost(95); // XXX 10575 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10576 ins_encode %{ 10577 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10578 %} 10579 ins_pipe(pipe_slow); 10580 %} 10581 10582 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10583 match(Set dst (MoveL2D src)); 10584 effect(DEF dst, USE src); 10585 10586 ins_cost(100); 10587 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10588 ins_encode %{ 10589 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10590 %} 10591 ins_pipe(ialu_mem_reg); 10592 %} 10593 10594 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10595 match(Set dst (MoveF2I src)); 10596 effect(DEF dst, USE src); 10597 ins_cost(85); 10598 format %{ "movd $dst,$src\t# MoveF2I" %} 10599 ins_encode %{ 10600 __ movdl($dst$$Register, $src$$XMMRegister); 10601 %} 10602 ins_pipe( pipe_slow ); 10603 %} 10604 10605 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10606 match(Set dst (MoveD2L src)); 10607 effect(DEF dst, USE src); 10608 ins_cost(85); 10609 format %{ "movd $dst,$src\t# MoveD2L" %} 10610 ins_encode %{ 10611 __ movdq($dst$$Register, $src$$XMMRegister); 10612 %} 10613 ins_pipe( pipe_slow ); 10614 %} 10615 10616 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10617 match(Set dst (MoveI2F src)); 10618 effect(DEF dst, USE src); 10619 ins_cost(100); 10620 format %{ "movd $dst,$src\t# MoveI2F" %} 10621 ins_encode %{ 10622 __ movdl($dst$$XMMRegister, $src$$Register); 10623 %} 10624 ins_pipe( pipe_slow ); 10625 %} 10626 10627 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10628 match(Set dst (MoveL2D src)); 10629 effect(DEF dst, USE src); 10630 ins_cost(100); 10631 format %{ "movd $dst,$src\t# MoveL2D" %} 10632 ins_encode %{ 10633 __ movdq($dst$$XMMRegister, $src$$Register); 10634 %} 10635 ins_pipe( pipe_slow ); 10636 %} 10637 10638 10639 // ======================================================================= 10640 // fast clearing of an array 10641 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10642 rFlagsReg cr) 10643 %{ 10644 predicate(!((ClearArrayNode*)n)->is_large()); 10645 match(Set dummy (ClearArray cnt base)); 10646 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10647 10648 format %{ $$template 10649 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10650 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10651 $$emit$$"jg LARGE\n\t" 10652 $$emit$$"dec rcx\n\t" 10653 $$emit$$"js DONE\t# Zero length\n\t" 10654 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10655 $$emit$$"dec rcx\n\t" 10656 $$emit$$"jge LOOP\n\t" 10657 $$emit$$"jmp DONE\n\t" 10658 $$emit$$"# LARGE:\n\t" 10659 if (UseFastStosb) { 10660 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10661 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10662 } else { 10663 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10664 } 10665 $$emit$$"# DONE" 10666 %} 10667 ins_encode %{ 10668 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, false); 10669 %} 10670 ins_pipe(pipe_slow); 10671 %} 10672 10673 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10674 rFlagsReg cr) 10675 %{ 10676 predicate(((ClearArrayNode*)n)->is_large()); 10677 match(Set dummy (ClearArray cnt base)); 10678 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10679 10680 format %{ $$template 10681 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10682 if (UseFastStosb) { 10683 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10684 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10685 } else { 10686 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10687 } 10688 %} 10689 ins_encode %{ 10690 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, true); 10691 %} 10692 ins_pipe(pipe_slow); 10693 %} 10694 10695 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10696 rax_RegI result, regD tmp1, rFlagsReg cr) 10697 %{ 10698 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10699 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10700 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10701 10702 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10703 ins_encode %{ 10704 __ string_compare($str1$$Register, $str2$$Register, 10705 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10706 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 10707 %} 10708 ins_pipe( pipe_slow ); 10709 %} 10710 10711 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10712 rax_RegI result, regD tmp1, rFlagsReg cr) 10713 %{ 10714 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10715 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10716 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10717 10718 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10719 ins_encode %{ 10720 __ string_compare($str1$$Register, $str2$$Register, 10721 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10722 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 10723 %} 10724 ins_pipe( pipe_slow ); 10725 %} 10726 10727 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10728 rax_RegI result, regD tmp1, rFlagsReg cr) 10729 %{ 10730 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10731 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10732 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10733 10734 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10735 ins_encode %{ 10736 __ string_compare($str1$$Register, $str2$$Register, 10737 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10738 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 10739 %} 10740 ins_pipe( pipe_slow ); 10741 %} 10742 10743 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10744 rax_RegI result, regD tmp1, rFlagsReg cr) 10745 %{ 10746 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10747 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10748 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10749 10750 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10751 ins_encode %{ 10752 __ string_compare($str2$$Register, $str1$$Register, 10753 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10754 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 10755 %} 10756 ins_pipe( pipe_slow ); 10757 %} 10758 10759 // fast search of substring with known size. 10760 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10761 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10762 %{ 10763 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10764 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10765 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10766 10767 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10768 ins_encode %{ 10769 int icnt2 = (int)$int_cnt2$$constant; 10770 if (icnt2 >= 16) { 10771 // IndexOf for constant substrings with size >= 16 elements 10772 // which don't need to be loaded through stack. 10773 __ string_indexofC8($str1$$Register, $str2$$Register, 10774 $cnt1$$Register, $cnt2$$Register, 10775 icnt2, $result$$Register, 10776 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10777 } else { 10778 // Small strings are loaded through stack if they cross page boundary. 10779 __ string_indexof($str1$$Register, $str2$$Register, 10780 $cnt1$$Register, $cnt2$$Register, 10781 icnt2, $result$$Register, 10782 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10783 } 10784 %} 10785 ins_pipe( pipe_slow ); 10786 %} 10787 10788 // fast search of substring with known size. 10789 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10790 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10791 %{ 10792 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10793 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10794 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10795 10796 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10797 ins_encode %{ 10798 int icnt2 = (int)$int_cnt2$$constant; 10799 if (icnt2 >= 8) { 10800 // IndexOf for constant substrings with size >= 8 elements 10801 // which don't need to be loaded through stack. 10802 __ string_indexofC8($str1$$Register, $str2$$Register, 10803 $cnt1$$Register, $cnt2$$Register, 10804 icnt2, $result$$Register, 10805 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10806 } else { 10807 // Small strings are loaded through stack if they cross page boundary. 10808 __ string_indexof($str1$$Register, $str2$$Register, 10809 $cnt1$$Register, $cnt2$$Register, 10810 icnt2, $result$$Register, 10811 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10812 } 10813 %} 10814 ins_pipe( pipe_slow ); 10815 %} 10816 10817 // fast search of substring with known size. 10818 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10819 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10820 %{ 10821 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10822 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10823 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10824 10825 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10826 ins_encode %{ 10827 int icnt2 = (int)$int_cnt2$$constant; 10828 if (icnt2 >= 8) { 10829 // IndexOf for constant substrings with size >= 8 elements 10830 // which don't need to be loaded through stack. 10831 __ string_indexofC8($str1$$Register, $str2$$Register, 10832 $cnt1$$Register, $cnt2$$Register, 10833 icnt2, $result$$Register, 10834 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10835 } else { 10836 // Small strings are loaded through stack if they cross page boundary. 10837 __ string_indexof($str1$$Register, $str2$$Register, 10838 $cnt1$$Register, $cnt2$$Register, 10839 icnt2, $result$$Register, 10840 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10841 } 10842 %} 10843 ins_pipe( pipe_slow ); 10844 %} 10845 10846 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10847 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10848 %{ 10849 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10850 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10851 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10852 10853 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10854 ins_encode %{ 10855 __ string_indexof($str1$$Register, $str2$$Register, 10856 $cnt1$$Register, $cnt2$$Register, 10857 (-1), $result$$Register, 10858 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10859 %} 10860 ins_pipe( pipe_slow ); 10861 %} 10862 10863 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10864 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10865 %{ 10866 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10867 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10868 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10869 10870 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10871 ins_encode %{ 10872 __ string_indexof($str1$$Register, $str2$$Register, 10873 $cnt1$$Register, $cnt2$$Register, 10874 (-1), $result$$Register, 10875 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10876 %} 10877 ins_pipe( pipe_slow ); 10878 %} 10879 10880 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10881 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10882 %{ 10883 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10884 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10885 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10886 10887 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10888 ins_encode %{ 10889 __ string_indexof($str1$$Register, $str2$$Register, 10890 $cnt1$$Register, $cnt2$$Register, 10891 (-1), $result$$Register, 10892 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10893 %} 10894 ins_pipe( pipe_slow ); 10895 %} 10896 10897 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10898 rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr) 10899 %{ 10900 predicate(UseSSE42Intrinsics); 10901 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10902 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10903 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10904 ins_encode %{ 10905 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10906 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 10907 %} 10908 ins_pipe( pipe_slow ); 10909 %} 10910 10911 // fast string equals 10912 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10913 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10914 %{ 10915 match(Set result (StrEquals (Binary str1 str2) cnt)); 10916 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10917 10918 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10919 ins_encode %{ 10920 __ arrays_equals(false, $str1$$Register, $str2$$Register, 10921 $cnt$$Register, $result$$Register, $tmp3$$Register, 10922 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 10923 %} 10924 ins_pipe( pipe_slow ); 10925 %} 10926 10927 // fast array equals 10928 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10929 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10930 %{ 10931 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 10932 match(Set result (AryEq ary1 ary2)); 10933 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10934 10935 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10936 ins_encode %{ 10937 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 10938 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10939 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 10940 %} 10941 ins_pipe( pipe_slow ); 10942 %} 10943 10944 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10945 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10946 %{ 10947 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 10948 match(Set result (AryEq ary1 ary2)); 10949 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10950 10951 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10952 ins_encode %{ 10953 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 10954 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10955 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 10956 %} 10957 ins_pipe( pipe_slow ); 10958 %} 10959 10960 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 10961 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10962 %{ 10963 match(Set result (HasNegatives ary1 len)); 10964 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 10965 10966 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10967 ins_encode %{ 10968 __ has_negatives($ary1$$Register, $len$$Register, 10969 $result$$Register, $tmp3$$Register, 10970 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10971 %} 10972 ins_pipe( pipe_slow ); 10973 %} 10974 10975 // fast char[] to byte[] compression 10976 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, 10977 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 10978 match(Set result (StrCompressedCopy src (Binary dst len))); 10979 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 10980 10981 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 10982 ins_encode %{ 10983 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 10984 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 10985 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 10986 %} 10987 ins_pipe( pipe_slow ); 10988 %} 10989 10990 // fast byte[] to char[] inflation 10991 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 10992 regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 10993 match(Set dummy (StrInflatedCopy src (Binary dst len))); 10994 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 10995 10996 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 10997 ins_encode %{ 10998 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 10999 $tmp1$$XMMRegister, $tmp2$$Register); 11000 %} 11001 ins_pipe( pipe_slow ); 11002 %} 11003 11004 // encode char[] to byte[] in ISO_8859_1 11005 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11006 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11007 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11008 match(Set result (EncodeISOArray src (Binary dst len))); 11009 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11010 11011 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11012 ins_encode %{ 11013 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11014 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11015 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11016 %} 11017 ins_pipe( pipe_slow ); 11018 %} 11019 11020 //----------Overflow Math Instructions----------------------------------------- 11021 11022 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11023 %{ 11024 match(Set cr (OverflowAddI op1 op2)); 11025 effect(DEF cr, USE_KILL op1, USE op2); 11026 11027 format %{ "addl $op1, $op2\t# overflow check int" %} 11028 11029 ins_encode %{ 11030 __ addl($op1$$Register, $op2$$Register); 11031 %} 11032 ins_pipe(ialu_reg_reg); 11033 %} 11034 11035 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11036 %{ 11037 match(Set cr (OverflowAddI op1 op2)); 11038 effect(DEF cr, USE_KILL op1, USE op2); 11039 11040 format %{ "addl $op1, $op2\t# overflow check int" %} 11041 11042 ins_encode %{ 11043 __ addl($op1$$Register, $op2$$constant); 11044 %} 11045 ins_pipe(ialu_reg_reg); 11046 %} 11047 11048 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11049 %{ 11050 match(Set cr (OverflowAddL op1 op2)); 11051 effect(DEF cr, USE_KILL op1, USE op2); 11052 11053 format %{ "addq $op1, $op2\t# overflow check long" %} 11054 ins_encode %{ 11055 __ addq($op1$$Register, $op2$$Register); 11056 %} 11057 ins_pipe(ialu_reg_reg); 11058 %} 11059 11060 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11061 %{ 11062 match(Set cr (OverflowAddL op1 op2)); 11063 effect(DEF cr, USE_KILL op1, USE op2); 11064 11065 format %{ "addq $op1, $op2\t# overflow check long" %} 11066 ins_encode %{ 11067 __ addq($op1$$Register, $op2$$constant); 11068 %} 11069 ins_pipe(ialu_reg_reg); 11070 %} 11071 11072 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11073 %{ 11074 match(Set cr (OverflowSubI op1 op2)); 11075 11076 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11077 ins_encode %{ 11078 __ cmpl($op1$$Register, $op2$$Register); 11079 %} 11080 ins_pipe(ialu_reg_reg); 11081 %} 11082 11083 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11084 %{ 11085 match(Set cr (OverflowSubI op1 op2)); 11086 11087 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11088 ins_encode %{ 11089 __ cmpl($op1$$Register, $op2$$constant); 11090 %} 11091 ins_pipe(ialu_reg_reg); 11092 %} 11093 11094 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11095 %{ 11096 match(Set cr (OverflowSubL op1 op2)); 11097 11098 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11099 ins_encode %{ 11100 __ cmpq($op1$$Register, $op2$$Register); 11101 %} 11102 ins_pipe(ialu_reg_reg); 11103 %} 11104 11105 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11106 %{ 11107 match(Set cr (OverflowSubL op1 op2)); 11108 11109 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11110 ins_encode %{ 11111 __ cmpq($op1$$Register, $op2$$constant); 11112 %} 11113 ins_pipe(ialu_reg_reg); 11114 %} 11115 11116 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11117 %{ 11118 match(Set cr (OverflowSubI zero op2)); 11119 effect(DEF cr, USE_KILL op2); 11120 11121 format %{ "negl $op2\t# overflow check int" %} 11122 ins_encode %{ 11123 __ negl($op2$$Register); 11124 %} 11125 ins_pipe(ialu_reg_reg); 11126 %} 11127 11128 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11129 %{ 11130 match(Set cr (OverflowSubL zero op2)); 11131 effect(DEF cr, USE_KILL op2); 11132 11133 format %{ "negq $op2\t# overflow check long" %} 11134 ins_encode %{ 11135 __ negq($op2$$Register); 11136 %} 11137 ins_pipe(ialu_reg_reg); 11138 %} 11139 11140 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11141 %{ 11142 match(Set cr (OverflowMulI op1 op2)); 11143 effect(DEF cr, USE_KILL op1, USE op2); 11144 11145 format %{ "imull $op1, $op2\t# overflow check int" %} 11146 ins_encode %{ 11147 __ imull($op1$$Register, $op2$$Register); 11148 %} 11149 ins_pipe(ialu_reg_reg_alu0); 11150 %} 11151 11152 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11153 %{ 11154 match(Set cr (OverflowMulI op1 op2)); 11155 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11156 11157 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11158 ins_encode %{ 11159 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11160 %} 11161 ins_pipe(ialu_reg_reg_alu0); 11162 %} 11163 11164 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11165 %{ 11166 match(Set cr (OverflowMulL op1 op2)); 11167 effect(DEF cr, USE_KILL op1, USE op2); 11168 11169 format %{ "imulq $op1, $op2\t# overflow check long" %} 11170 ins_encode %{ 11171 __ imulq($op1$$Register, $op2$$Register); 11172 %} 11173 ins_pipe(ialu_reg_reg_alu0); 11174 %} 11175 11176 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11177 %{ 11178 match(Set cr (OverflowMulL op1 op2)); 11179 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11180 11181 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11182 ins_encode %{ 11183 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11184 %} 11185 ins_pipe(ialu_reg_reg_alu0); 11186 %} 11187 11188 11189 //----------Control Flow Instructions------------------------------------------ 11190 // Signed compare Instructions 11191 11192 // XXX more variants!! 11193 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11194 %{ 11195 match(Set cr (CmpI op1 op2)); 11196 effect(DEF cr, USE op1, USE op2); 11197 11198 format %{ "cmpl $op1, $op2" %} 11199 opcode(0x3B); /* Opcode 3B /r */ 11200 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11201 ins_pipe(ialu_cr_reg_reg); 11202 %} 11203 11204 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11205 %{ 11206 match(Set cr (CmpI op1 op2)); 11207 11208 format %{ "cmpl $op1, $op2" %} 11209 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11210 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11211 ins_pipe(ialu_cr_reg_imm); 11212 %} 11213 11214 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11215 %{ 11216 match(Set cr (CmpI op1 (LoadI op2))); 11217 11218 ins_cost(500); // XXX 11219 format %{ "cmpl $op1, $op2" %} 11220 opcode(0x3B); /* Opcode 3B /r */ 11221 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11222 ins_pipe(ialu_cr_reg_mem); 11223 %} 11224 11225 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11226 %{ 11227 match(Set cr (CmpI src zero)); 11228 11229 format %{ "testl $src, $src" %} 11230 opcode(0x85); 11231 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11232 ins_pipe(ialu_cr_reg_imm); 11233 %} 11234 11235 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11236 %{ 11237 match(Set cr (CmpI (AndI src con) zero)); 11238 11239 format %{ "testl $src, $con" %} 11240 opcode(0xF7, 0x00); 11241 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11242 ins_pipe(ialu_cr_reg_imm); 11243 %} 11244 11245 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11246 %{ 11247 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11248 11249 format %{ "testl $src, $mem" %} 11250 opcode(0x85); 11251 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11252 ins_pipe(ialu_cr_reg_mem); 11253 %} 11254 11255 // Unsigned compare Instructions; really, same as signed except they 11256 // produce an rFlagsRegU instead of rFlagsReg. 11257 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11258 %{ 11259 match(Set cr (CmpU op1 op2)); 11260 11261 format %{ "cmpl $op1, $op2\t# unsigned" %} 11262 opcode(0x3B); /* Opcode 3B /r */ 11263 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11264 ins_pipe(ialu_cr_reg_reg); 11265 %} 11266 11267 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11268 %{ 11269 match(Set cr (CmpU op1 op2)); 11270 11271 format %{ "cmpl $op1, $op2\t# unsigned" %} 11272 opcode(0x81,0x07); /* Opcode 81 /7 */ 11273 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11274 ins_pipe(ialu_cr_reg_imm); 11275 %} 11276 11277 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11278 %{ 11279 match(Set cr (CmpU op1 (LoadI op2))); 11280 11281 ins_cost(500); // XXX 11282 format %{ "cmpl $op1, $op2\t# unsigned" %} 11283 opcode(0x3B); /* Opcode 3B /r */ 11284 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11285 ins_pipe(ialu_cr_reg_mem); 11286 %} 11287 11288 // // // Cisc-spilled version of cmpU_rReg 11289 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11290 // //%{ 11291 // // match(Set cr (CmpU (LoadI op1) op2)); 11292 // // 11293 // // format %{ "CMPu $op1,$op2" %} 11294 // // ins_cost(500); 11295 // // opcode(0x39); /* Opcode 39 /r */ 11296 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11297 // //%} 11298 11299 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11300 %{ 11301 match(Set cr (CmpU src zero)); 11302 11303 format %{ "testl $src, $src\t# unsigned" %} 11304 opcode(0x85); 11305 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11306 ins_pipe(ialu_cr_reg_imm); 11307 %} 11308 11309 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11310 %{ 11311 match(Set cr (CmpP op1 op2)); 11312 11313 format %{ "cmpq $op1, $op2\t# ptr" %} 11314 opcode(0x3B); /* Opcode 3B /r */ 11315 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11316 ins_pipe(ialu_cr_reg_reg); 11317 %} 11318 11319 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11320 %{ 11321 match(Set cr (CmpP op1 (LoadP op2))); 11322 11323 ins_cost(500); // XXX 11324 format %{ "cmpq $op1, $op2\t# ptr" %} 11325 opcode(0x3B); /* Opcode 3B /r */ 11326 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11327 ins_pipe(ialu_cr_reg_mem); 11328 %} 11329 11330 // // // Cisc-spilled version of cmpP_rReg 11331 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11332 // //%{ 11333 // // match(Set cr (CmpP (LoadP op1) op2)); 11334 // // 11335 // // format %{ "CMPu $op1,$op2" %} 11336 // // ins_cost(500); 11337 // // opcode(0x39); /* Opcode 39 /r */ 11338 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11339 // //%} 11340 11341 // XXX this is generalized by compP_rReg_mem??? 11342 // Compare raw pointer (used in out-of-heap check). 11343 // Only works because non-oop pointers must be raw pointers 11344 // and raw pointers have no anti-dependencies. 11345 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11346 %{ 11347 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11348 match(Set cr (CmpP op1 (LoadP op2))); 11349 11350 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11351 opcode(0x3B); /* Opcode 3B /r */ 11352 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11353 ins_pipe(ialu_cr_reg_mem); 11354 %} 11355 11356 // This will generate a signed flags result. This should be OK since 11357 // any compare to a zero should be eq/neq. 11358 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11359 %{ 11360 match(Set cr (CmpP src zero)); 11361 11362 format %{ "testq $src, $src\t# ptr" %} 11363 opcode(0x85); 11364 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11365 ins_pipe(ialu_cr_reg_imm); 11366 %} 11367 11368 // This will generate a signed flags result. This should be OK since 11369 // any compare to a zero should be eq/neq. 11370 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11371 %{ 11372 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11373 match(Set cr (CmpP (LoadP op) zero)); 11374 11375 ins_cost(500); // XXX 11376 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11377 opcode(0xF7); /* Opcode F7 /0 */ 11378 ins_encode(REX_mem_wide(op), 11379 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11380 ins_pipe(ialu_cr_reg_imm); 11381 %} 11382 11383 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11384 %{ 11385 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11386 match(Set cr (CmpP (LoadP mem) zero)); 11387 11388 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11389 ins_encode %{ 11390 __ cmpq(r12, $mem$$Address); 11391 %} 11392 ins_pipe(ialu_cr_reg_mem); 11393 %} 11394 11395 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11396 %{ 11397 match(Set cr (CmpN op1 op2)); 11398 11399 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11400 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11401 ins_pipe(ialu_cr_reg_reg); 11402 %} 11403 11404 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11405 %{ 11406 match(Set cr (CmpN src (LoadN mem))); 11407 11408 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11409 ins_encode %{ 11410 __ cmpl($src$$Register, $mem$$Address); 11411 %} 11412 ins_pipe(ialu_cr_reg_mem); 11413 %} 11414 11415 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11416 match(Set cr (CmpN op1 op2)); 11417 11418 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11419 ins_encode %{ 11420 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11421 %} 11422 ins_pipe(ialu_cr_reg_imm); 11423 %} 11424 11425 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11426 %{ 11427 match(Set cr (CmpN src (LoadN mem))); 11428 11429 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11430 ins_encode %{ 11431 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11432 %} 11433 ins_pipe(ialu_cr_reg_mem); 11434 %} 11435 11436 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11437 match(Set cr (CmpN op1 op2)); 11438 11439 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11440 ins_encode %{ 11441 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11442 %} 11443 ins_pipe(ialu_cr_reg_imm); 11444 %} 11445 11446 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11447 %{ 11448 match(Set cr (CmpN src (LoadNKlass mem))); 11449 11450 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11451 ins_encode %{ 11452 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11453 %} 11454 ins_pipe(ialu_cr_reg_mem); 11455 %} 11456 11457 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11458 match(Set cr (CmpN src zero)); 11459 11460 format %{ "testl $src, $src\t# compressed ptr" %} 11461 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11462 ins_pipe(ialu_cr_reg_imm); 11463 %} 11464 11465 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11466 %{ 11467 predicate(Universe::narrow_oop_base() != NULL); 11468 match(Set cr (CmpN (LoadN mem) zero)); 11469 11470 ins_cost(500); // XXX 11471 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11472 ins_encode %{ 11473 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11474 %} 11475 ins_pipe(ialu_cr_reg_mem); 11476 %} 11477 11478 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11479 %{ 11480 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11481 match(Set cr (CmpN (LoadN mem) zero)); 11482 11483 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11484 ins_encode %{ 11485 __ cmpl(r12, $mem$$Address); 11486 %} 11487 ins_pipe(ialu_cr_reg_mem); 11488 %} 11489 11490 // Yanked all unsigned pointer compare operations. 11491 // Pointer compares are done with CmpP which is already unsigned. 11492 11493 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11494 %{ 11495 match(Set cr (CmpL op1 op2)); 11496 11497 format %{ "cmpq $op1, $op2" %} 11498 opcode(0x3B); /* Opcode 3B /r */ 11499 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11500 ins_pipe(ialu_cr_reg_reg); 11501 %} 11502 11503 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11504 %{ 11505 match(Set cr (CmpL op1 op2)); 11506 11507 format %{ "cmpq $op1, $op2" %} 11508 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11509 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11510 ins_pipe(ialu_cr_reg_imm); 11511 %} 11512 11513 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11514 %{ 11515 match(Set cr (CmpL op1 (LoadL op2))); 11516 11517 format %{ "cmpq $op1, $op2" %} 11518 opcode(0x3B); /* Opcode 3B /r */ 11519 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11520 ins_pipe(ialu_cr_reg_mem); 11521 %} 11522 11523 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11524 %{ 11525 match(Set cr (CmpL src zero)); 11526 11527 format %{ "testq $src, $src" %} 11528 opcode(0x85); 11529 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11530 ins_pipe(ialu_cr_reg_imm); 11531 %} 11532 11533 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11534 %{ 11535 match(Set cr (CmpL (AndL src con) zero)); 11536 11537 format %{ "testq $src, $con\t# long" %} 11538 opcode(0xF7, 0x00); 11539 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11540 ins_pipe(ialu_cr_reg_imm); 11541 %} 11542 11543 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11544 %{ 11545 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11546 11547 format %{ "testq $src, $mem" %} 11548 opcode(0x85); 11549 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11550 ins_pipe(ialu_cr_reg_mem); 11551 %} 11552 11553 // Manifest a CmpL result in an integer register. Very painful. 11554 // This is the test to avoid. 11555 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11556 %{ 11557 match(Set dst (CmpL3 src1 src2)); 11558 effect(KILL flags); 11559 11560 ins_cost(275); // XXX 11561 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11562 "movl $dst, -1\n\t" 11563 "jl,s done\n\t" 11564 "setne $dst\n\t" 11565 "movzbl $dst, $dst\n\t" 11566 "done:" %} 11567 ins_encode(cmpl3_flag(src1, src2, dst)); 11568 ins_pipe(pipe_slow); 11569 %} 11570 11571 // Unsigned long compare Instructions; really, same as signed long except they 11572 // produce an rFlagsRegU instead of rFlagsReg. 11573 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11574 %{ 11575 match(Set cr (CmpUL op1 op2)); 11576 11577 format %{ "cmpq $op1, $op2\t# unsigned" %} 11578 opcode(0x3B); /* Opcode 3B /r */ 11579 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11580 ins_pipe(ialu_cr_reg_reg); 11581 %} 11582 11583 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11584 %{ 11585 match(Set cr (CmpUL op1 op2)); 11586 11587 format %{ "cmpq $op1, $op2\t# unsigned" %} 11588 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11589 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11590 ins_pipe(ialu_cr_reg_imm); 11591 %} 11592 11593 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11594 %{ 11595 match(Set cr (CmpUL op1 (LoadL op2))); 11596 11597 format %{ "cmpq $op1, $op2\t# unsigned" %} 11598 opcode(0x3B); /* Opcode 3B /r */ 11599 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11600 ins_pipe(ialu_cr_reg_mem); 11601 %} 11602 11603 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11604 %{ 11605 match(Set cr (CmpUL src zero)); 11606 11607 format %{ "testq $src, $src\t# unsigned" %} 11608 opcode(0x85); 11609 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11610 ins_pipe(ialu_cr_reg_imm); 11611 %} 11612 11613 //----------Max and Min-------------------------------------------------------- 11614 // Min Instructions 11615 11616 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11617 %{ 11618 effect(USE_DEF dst, USE src, USE cr); 11619 11620 format %{ "cmovlgt $dst, $src\t# min" %} 11621 opcode(0x0F, 0x4F); 11622 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11623 ins_pipe(pipe_cmov_reg); 11624 %} 11625 11626 11627 instruct minI_rReg(rRegI dst, rRegI src) 11628 %{ 11629 match(Set dst (MinI dst src)); 11630 11631 ins_cost(200); 11632 expand %{ 11633 rFlagsReg cr; 11634 compI_rReg(cr, dst, src); 11635 cmovI_reg_g(dst, src, cr); 11636 %} 11637 %} 11638 11639 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11640 %{ 11641 effect(USE_DEF dst, USE src, USE cr); 11642 11643 format %{ "cmovllt $dst, $src\t# max" %} 11644 opcode(0x0F, 0x4C); 11645 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11646 ins_pipe(pipe_cmov_reg); 11647 %} 11648 11649 11650 instruct maxI_rReg(rRegI dst, rRegI src) 11651 %{ 11652 match(Set dst (MaxI dst src)); 11653 11654 ins_cost(200); 11655 expand %{ 11656 rFlagsReg cr; 11657 compI_rReg(cr, dst, src); 11658 cmovI_reg_l(dst, src, cr); 11659 %} 11660 %} 11661 11662 // ============================================================================ 11663 // Branch Instructions 11664 11665 // Jump Direct - Label defines a relative address from JMP+1 11666 instruct jmpDir(label labl) 11667 %{ 11668 match(Goto); 11669 effect(USE labl); 11670 11671 ins_cost(300); 11672 format %{ "jmp $labl" %} 11673 size(5); 11674 ins_encode %{ 11675 Label* L = $labl$$label; 11676 __ jmp(*L, false); // Always long jump 11677 %} 11678 ins_pipe(pipe_jmp); 11679 %} 11680 11681 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11682 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11683 %{ 11684 match(If cop cr); 11685 effect(USE labl); 11686 11687 ins_cost(300); 11688 format %{ "j$cop $labl" %} 11689 size(6); 11690 ins_encode %{ 11691 Label* L = $labl$$label; 11692 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11693 %} 11694 ins_pipe(pipe_jcc); 11695 %} 11696 11697 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11698 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11699 %{ 11700 predicate(!n->has_vector_mask_set()); 11701 match(CountedLoopEnd cop cr); 11702 effect(USE labl); 11703 11704 ins_cost(300); 11705 format %{ "j$cop $labl\t# loop end" %} 11706 size(6); 11707 ins_encode %{ 11708 Label* L = $labl$$label; 11709 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11710 %} 11711 ins_pipe(pipe_jcc); 11712 %} 11713 11714 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11715 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11716 predicate(!n->has_vector_mask_set()); 11717 match(CountedLoopEnd cop cmp); 11718 effect(USE labl); 11719 11720 ins_cost(300); 11721 format %{ "j$cop,u $labl\t# loop end" %} 11722 size(6); 11723 ins_encode %{ 11724 Label* L = $labl$$label; 11725 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11726 %} 11727 ins_pipe(pipe_jcc); 11728 %} 11729 11730 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11731 predicate(!n->has_vector_mask_set()); 11732 match(CountedLoopEnd cop cmp); 11733 effect(USE labl); 11734 11735 ins_cost(200); 11736 format %{ "j$cop,u $labl\t# loop end" %} 11737 size(6); 11738 ins_encode %{ 11739 Label* L = $labl$$label; 11740 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11741 %} 11742 ins_pipe(pipe_jcc); 11743 %} 11744 11745 // mask version 11746 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11747 instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 11748 %{ 11749 predicate(n->has_vector_mask_set()); 11750 match(CountedLoopEnd cop cr); 11751 effect(USE labl); 11752 11753 ins_cost(400); 11754 format %{ "j$cop $labl\t# loop end\n\t" 11755 "restorevectmask \t# vector mask restore for loops" %} 11756 size(10); 11757 ins_encode %{ 11758 Label* L = $labl$$label; 11759 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11760 __ restorevectmask(); 11761 %} 11762 ins_pipe(pipe_jcc); 11763 %} 11764 11765 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11766 instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11767 predicate(n->has_vector_mask_set()); 11768 match(CountedLoopEnd cop cmp); 11769 effect(USE labl); 11770 11771 ins_cost(400); 11772 format %{ "j$cop,u $labl\t# loop end\n\t" 11773 "restorevectmask \t# vector mask restore for loops" %} 11774 size(10); 11775 ins_encode %{ 11776 Label* L = $labl$$label; 11777 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11778 __ restorevectmask(); 11779 %} 11780 ins_pipe(pipe_jcc); 11781 %} 11782 11783 instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11784 predicate(n->has_vector_mask_set()); 11785 match(CountedLoopEnd cop cmp); 11786 effect(USE labl); 11787 11788 ins_cost(300); 11789 format %{ "j$cop,u $labl\t# loop end\n\t" 11790 "restorevectmask \t# vector mask restore for loops" %} 11791 size(10); 11792 ins_encode %{ 11793 Label* L = $labl$$label; 11794 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11795 __ restorevectmask(); 11796 %} 11797 ins_pipe(pipe_jcc); 11798 %} 11799 11800 // Jump Direct Conditional - using unsigned comparison 11801 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11802 match(If cop cmp); 11803 effect(USE labl); 11804 11805 ins_cost(300); 11806 format %{ "j$cop,u $labl" %} 11807 size(6); 11808 ins_encode %{ 11809 Label* L = $labl$$label; 11810 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11811 %} 11812 ins_pipe(pipe_jcc); 11813 %} 11814 11815 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11816 match(If cop cmp); 11817 effect(USE labl); 11818 11819 ins_cost(200); 11820 format %{ "j$cop,u $labl" %} 11821 size(6); 11822 ins_encode %{ 11823 Label* L = $labl$$label; 11824 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11825 %} 11826 ins_pipe(pipe_jcc); 11827 %} 11828 11829 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11830 match(If cop cmp); 11831 effect(USE labl); 11832 11833 ins_cost(200); 11834 format %{ $$template 11835 if ($cop$$cmpcode == Assembler::notEqual) { 11836 $$emit$$"jp,u $labl\n\t" 11837 $$emit$$"j$cop,u $labl" 11838 } else { 11839 $$emit$$"jp,u done\n\t" 11840 $$emit$$"j$cop,u $labl\n\t" 11841 $$emit$$"done:" 11842 } 11843 %} 11844 ins_encode %{ 11845 Label* l = $labl$$label; 11846 if ($cop$$cmpcode == Assembler::notEqual) { 11847 __ jcc(Assembler::parity, *l, false); 11848 __ jcc(Assembler::notEqual, *l, false); 11849 } else if ($cop$$cmpcode == Assembler::equal) { 11850 Label done; 11851 __ jccb(Assembler::parity, done); 11852 __ jcc(Assembler::equal, *l, false); 11853 __ bind(done); 11854 } else { 11855 ShouldNotReachHere(); 11856 } 11857 %} 11858 ins_pipe(pipe_jcc); 11859 %} 11860 11861 // ============================================================================ 11862 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11863 // superklass array for an instance of the superklass. Set a hidden 11864 // internal cache on a hit (cache is checked with exposed code in 11865 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11866 // encoding ALSO sets flags. 11867 11868 instruct partialSubtypeCheck(rdi_RegP result, 11869 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11870 rFlagsReg cr) 11871 %{ 11872 match(Set result (PartialSubtypeCheck sub super)); 11873 effect(KILL rcx, KILL cr); 11874 11875 ins_cost(1100); // slightly larger than the next version 11876 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11877 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11878 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11879 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11880 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11881 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11882 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11883 "miss:\t" %} 11884 11885 opcode(0x1); // Force a XOR of RDI 11886 ins_encode(enc_PartialSubtypeCheck()); 11887 ins_pipe(pipe_slow); 11888 %} 11889 11890 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11891 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11892 immP0 zero, 11893 rdi_RegP result) 11894 %{ 11895 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11896 effect(KILL rcx, KILL result); 11897 11898 ins_cost(1000); 11899 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11900 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11901 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11902 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11903 "jne,s miss\t\t# Missed: flags nz\n\t" 11904 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11905 "miss:\t" %} 11906 11907 opcode(0x0); // No need to XOR RDI 11908 ins_encode(enc_PartialSubtypeCheck()); 11909 ins_pipe(pipe_slow); 11910 %} 11911 11912 // ============================================================================ 11913 // Branch Instructions -- short offset versions 11914 // 11915 // These instructions are used to replace jumps of a long offset (the default 11916 // match) with jumps of a shorter offset. These instructions are all tagged 11917 // with the ins_short_branch attribute, which causes the ADLC to suppress the 11918 // match rules in general matching. Instead, the ADLC generates a conversion 11919 // method in the MachNode which can be used to do in-place replacement of the 11920 // long variant with the shorter variant. The compiler will determine if a 11921 // branch can be taken by the is_short_branch_offset() predicate in the machine 11922 // specific code section of the file. 11923 11924 // Jump Direct - Label defines a relative address from JMP+1 11925 instruct jmpDir_short(label labl) %{ 11926 match(Goto); 11927 effect(USE labl); 11928 11929 ins_cost(300); 11930 format %{ "jmp,s $labl" %} 11931 size(2); 11932 ins_encode %{ 11933 Label* L = $labl$$label; 11934 __ jmpb(*L); 11935 %} 11936 ins_pipe(pipe_jmp); 11937 ins_short_branch(1); 11938 %} 11939 11940 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11941 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11942 match(If cop cr); 11943 effect(USE labl); 11944 11945 ins_cost(300); 11946 format %{ "j$cop,s $labl" %} 11947 size(2); 11948 ins_encode %{ 11949 Label* L = $labl$$label; 11950 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11951 %} 11952 ins_pipe(pipe_jcc); 11953 ins_short_branch(1); 11954 %} 11955 11956 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11957 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11958 match(CountedLoopEnd cop cr); 11959 effect(USE labl); 11960 11961 ins_cost(300); 11962 format %{ "j$cop,s $labl\t# loop end" %} 11963 size(2); 11964 ins_encode %{ 11965 Label* L = $labl$$label; 11966 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11967 %} 11968 ins_pipe(pipe_jcc); 11969 ins_short_branch(1); 11970 %} 11971 11972 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11973 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11974 match(CountedLoopEnd cop cmp); 11975 effect(USE labl); 11976 11977 ins_cost(300); 11978 format %{ "j$cop,us $labl\t# loop end" %} 11979 size(2); 11980 ins_encode %{ 11981 Label* L = $labl$$label; 11982 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11983 %} 11984 ins_pipe(pipe_jcc); 11985 ins_short_branch(1); 11986 %} 11987 11988 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11989 match(CountedLoopEnd cop cmp); 11990 effect(USE labl); 11991 11992 ins_cost(300); 11993 format %{ "j$cop,us $labl\t# loop end" %} 11994 size(2); 11995 ins_encode %{ 11996 Label* L = $labl$$label; 11997 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11998 %} 11999 ins_pipe(pipe_jcc); 12000 ins_short_branch(1); 12001 %} 12002 12003 // Jump Direct Conditional - using unsigned comparison 12004 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12005 match(If cop cmp); 12006 effect(USE labl); 12007 12008 ins_cost(300); 12009 format %{ "j$cop,us $labl" %} 12010 size(2); 12011 ins_encode %{ 12012 Label* L = $labl$$label; 12013 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12014 %} 12015 ins_pipe(pipe_jcc); 12016 ins_short_branch(1); 12017 %} 12018 12019 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12020 match(If cop cmp); 12021 effect(USE labl); 12022 12023 ins_cost(300); 12024 format %{ "j$cop,us $labl" %} 12025 size(2); 12026 ins_encode %{ 12027 Label* L = $labl$$label; 12028 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12029 %} 12030 ins_pipe(pipe_jcc); 12031 ins_short_branch(1); 12032 %} 12033 12034 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12035 match(If cop cmp); 12036 effect(USE labl); 12037 12038 ins_cost(300); 12039 format %{ $$template 12040 if ($cop$$cmpcode == Assembler::notEqual) { 12041 $$emit$$"jp,u,s $labl\n\t" 12042 $$emit$$"j$cop,u,s $labl" 12043 } else { 12044 $$emit$$"jp,u,s done\n\t" 12045 $$emit$$"j$cop,u,s $labl\n\t" 12046 $$emit$$"done:" 12047 } 12048 %} 12049 size(4); 12050 ins_encode %{ 12051 Label* l = $labl$$label; 12052 if ($cop$$cmpcode == Assembler::notEqual) { 12053 __ jccb(Assembler::parity, *l); 12054 __ jccb(Assembler::notEqual, *l); 12055 } else if ($cop$$cmpcode == Assembler::equal) { 12056 Label done; 12057 __ jccb(Assembler::parity, done); 12058 __ jccb(Assembler::equal, *l); 12059 __ bind(done); 12060 } else { 12061 ShouldNotReachHere(); 12062 } 12063 %} 12064 ins_pipe(pipe_jcc); 12065 ins_short_branch(1); 12066 %} 12067 12068 // ============================================================================ 12069 // inlined locking and unlocking 12070 12071 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12072 predicate(Compile::current()->use_rtm()); 12073 match(Set cr (FastLock object box)); 12074 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12075 ins_cost(300); 12076 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12077 ins_encode %{ 12078 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12079 $scr$$Register, $cx1$$Register, $cx2$$Register, 12080 _counters, _rtm_counters, _stack_rtm_counters, 12081 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12082 true, ra_->C->profile_rtm()); 12083 %} 12084 ins_pipe(pipe_slow); 12085 %} 12086 12087 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12088 predicate(!Compile::current()->use_rtm()); 12089 match(Set cr (FastLock object box)); 12090 effect(TEMP tmp, TEMP scr, USE_KILL box); 12091 ins_cost(300); 12092 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12093 ins_encode %{ 12094 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12095 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12096 %} 12097 ins_pipe(pipe_slow); 12098 %} 12099 12100 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12101 match(Set cr (FastUnlock object box)); 12102 effect(TEMP tmp, USE_KILL box); 12103 ins_cost(300); 12104 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12105 ins_encode %{ 12106 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12107 %} 12108 ins_pipe(pipe_slow); 12109 %} 12110 12111 12112 // ============================================================================ 12113 // Safepoint Instructions 12114 instruct safePoint_poll(rFlagsReg cr) 12115 %{ 12116 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12117 match(SafePoint); 12118 effect(KILL cr); 12119 12120 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12121 "# Safepoint: poll for GC" %} 12122 ins_cost(125); 12123 ins_encode %{ 12124 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12125 __ testl(rax, addr); 12126 %} 12127 ins_pipe(ialu_reg_mem); 12128 %} 12129 12130 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12131 %{ 12132 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12133 match(SafePoint poll); 12134 effect(KILL cr, USE poll); 12135 12136 format %{ "testl rax, [$poll]\t" 12137 "# Safepoint: poll for GC" %} 12138 ins_cost(125); 12139 ins_encode %{ 12140 __ relocate(relocInfo::poll_type); 12141 __ testl(rax, Address($poll$$Register, 0)); 12142 %} 12143 ins_pipe(ialu_reg_mem); 12144 %} 12145 12146 instruct safePoint_poll_tls(rFlagsReg cr, rex_RegP poll) 12147 %{ 12148 predicate(SafepointMechanism::uses_thread_local_poll()); 12149 match(SafePoint poll); 12150 effect(KILL cr, USE poll); 12151 12152 format %{ "testl rax, [$poll]\t" 12153 "# Safepoint: poll for GC" %} 12154 ins_cost(125); 12155 size(3); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12156 ins_encode %{ 12157 __ relocate(relocInfo::poll_type); 12158 address pre_pc = __ pc(); 12159 __ testl(rax, Address($poll$$Register, 0)); 12160 address post_pc = __ pc(); 12161 guarantee(pre_pc[0] == 0x41 && pre_pc[1] == 0x85, "must emit #rex test-ax [reg]"); 12162 %} 12163 ins_pipe(ialu_reg_mem); 12164 %} 12165 12166 // ============================================================================ 12167 // Procedure Call/Return Instructions 12168 // Call Java Static Instruction 12169 // Note: If this code changes, the corresponding ret_addr_offset() and 12170 // compute_padding() functions will have to be adjusted. 12171 instruct CallStaticJavaDirect(method meth) %{ 12172 match(CallStaticJava); 12173 effect(USE meth); 12174 12175 ins_cost(300); 12176 format %{ "call,static " %} 12177 opcode(0xE8); /* E8 cd */ 12178 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12179 ins_pipe(pipe_slow); 12180 ins_alignment(4); 12181 %} 12182 12183 // Call Java Dynamic Instruction 12184 // Note: If this code changes, the corresponding ret_addr_offset() and 12185 // compute_padding() functions will have to be adjusted. 12186 instruct CallDynamicJavaDirect(method meth) 12187 %{ 12188 match(CallDynamicJava); 12189 effect(USE meth); 12190 12191 ins_cost(300); 12192 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12193 "call,dynamic " %} 12194 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12195 ins_pipe(pipe_slow); 12196 ins_alignment(4); 12197 %} 12198 12199 // Call Runtime Instruction 12200 instruct CallRuntimeDirect(method meth) 12201 %{ 12202 match(CallRuntime); 12203 effect(USE meth); 12204 12205 ins_cost(300); 12206 format %{ "call,runtime " %} 12207 ins_encode(clear_avx, Java_To_Runtime(meth)); 12208 ins_pipe(pipe_slow); 12209 %} 12210 12211 // Call runtime without safepoint 12212 instruct CallLeafDirect(method meth) 12213 %{ 12214 match(CallLeaf); 12215 effect(USE meth); 12216 12217 ins_cost(300); 12218 format %{ "call_leaf,runtime " %} 12219 ins_encode(clear_avx, Java_To_Runtime(meth)); 12220 ins_pipe(pipe_slow); 12221 %} 12222 12223 // Call runtime without safepoint 12224 instruct CallLeafNoFPDirect(method meth) 12225 %{ 12226 match(CallLeafNoFP); 12227 effect(USE meth); 12228 12229 ins_cost(300); 12230 format %{ "call_leaf_nofp,runtime " %} 12231 ins_encode(clear_avx, Java_To_Runtime(meth)); 12232 ins_pipe(pipe_slow); 12233 %} 12234 12235 // Return Instruction 12236 // Remove the return address & jump to it. 12237 // Notice: We always emit a nop after a ret to make sure there is room 12238 // for safepoint patching 12239 instruct Ret() 12240 %{ 12241 match(Return); 12242 12243 format %{ "ret" %} 12244 opcode(0xC3); 12245 ins_encode(OpcP); 12246 ins_pipe(pipe_jmp); 12247 %} 12248 12249 // Tail Call; Jump from runtime stub to Java code. 12250 // Also known as an 'interprocedural jump'. 12251 // Target of jump will eventually return to caller. 12252 // TailJump below removes the return address. 12253 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12254 %{ 12255 match(TailCall jump_target method_oop); 12256 12257 ins_cost(300); 12258 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12259 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12260 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12261 ins_pipe(pipe_jmp); 12262 %} 12263 12264 // Tail Jump; remove the return address; jump to target. 12265 // TailCall above leaves the return address around. 12266 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12267 %{ 12268 match(TailJump jump_target ex_oop); 12269 12270 ins_cost(300); 12271 format %{ "popq rdx\t# pop return address\n\t" 12272 "jmp $jump_target" %} 12273 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12274 ins_encode(Opcode(0x5a), // popq rdx 12275 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12276 ins_pipe(pipe_jmp); 12277 %} 12278 12279 // Create exception oop: created by stack-crawling runtime code. 12280 // Created exception is now available to this handler, and is setup 12281 // just prior to jumping to this handler. No code emitted. 12282 instruct CreateException(rax_RegP ex_oop) 12283 %{ 12284 match(Set ex_oop (CreateEx)); 12285 12286 size(0); 12287 // use the following format syntax 12288 format %{ "# exception oop is in rax; no code emitted" %} 12289 ins_encode(); 12290 ins_pipe(empty); 12291 %} 12292 12293 // Rethrow exception: 12294 // The exception oop will come in the first argument position. 12295 // Then JUMP (not call) to the rethrow stub code. 12296 instruct RethrowException() 12297 %{ 12298 match(Rethrow); 12299 12300 // use the following format syntax 12301 format %{ "jmp rethrow_stub" %} 12302 ins_encode(enc_rethrow); 12303 ins_pipe(pipe_jmp); 12304 %} 12305 12306 12307 // ============================================================================ 12308 // This name is KNOWN by the ADLC and cannot be changed. 12309 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12310 // for this guy. 12311 instruct tlsLoadP(r15_RegP dst) %{ 12312 match(Set dst (ThreadLocal)); 12313 effect(DEF dst); 12314 12315 size(0); 12316 format %{ "# TLS is in R15" %} 12317 ins_encode( /*empty encoding*/ ); 12318 ins_pipe(ialu_reg_reg); 12319 %} 12320 12321 12322 //----------PEEPHOLE RULES----------------------------------------------------- 12323 // These must follow all instruction definitions as they use the names 12324 // defined in the instructions definitions. 12325 // 12326 // peepmatch ( root_instr_name [preceding_instruction]* ); 12327 // 12328 // peepconstraint %{ 12329 // (instruction_number.operand_name relational_op instruction_number.operand_name 12330 // [, ...] ); 12331 // // instruction numbers are zero-based using left to right order in peepmatch 12332 // 12333 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12334 // // provide an instruction_number.operand_name for each operand that appears 12335 // // in the replacement instruction's match rule 12336 // 12337 // ---------VM FLAGS--------------------------------------------------------- 12338 // 12339 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12340 // 12341 // Each peephole rule is given an identifying number starting with zero and 12342 // increasing by one in the order seen by the parser. An individual peephole 12343 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12344 // on the command-line. 12345 // 12346 // ---------CURRENT LIMITATIONS---------------------------------------------- 12347 // 12348 // Only match adjacent instructions in same basic block 12349 // Only equality constraints 12350 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12351 // Only one replacement instruction 12352 // 12353 // ---------EXAMPLE---------------------------------------------------------- 12354 // 12355 // // pertinent parts of existing instructions in architecture description 12356 // instruct movI(rRegI dst, rRegI src) 12357 // %{ 12358 // match(Set dst (CopyI src)); 12359 // %} 12360 // 12361 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12362 // %{ 12363 // match(Set dst (AddI dst src)); 12364 // effect(KILL cr); 12365 // %} 12366 // 12367 // // Change (inc mov) to lea 12368 // peephole %{ 12369 // // increment preceeded by register-register move 12370 // peepmatch ( incI_rReg movI ); 12371 // // require that the destination register of the increment 12372 // // match the destination register of the move 12373 // peepconstraint ( 0.dst == 1.dst ); 12374 // // construct a replacement instruction that sets 12375 // // the destination to ( move's source register + one ) 12376 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12377 // %} 12378 // 12379 12380 // Implementation no longer uses movX instructions since 12381 // machine-independent system no longer uses CopyX nodes. 12382 // 12383 // peephole 12384 // %{ 12385 // peepmatch (incI_rReg movI); 12386 // peepconstraint (0.dst == 1.dst); 12387 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12388 // %} 12389 12390 // peephole 12391 // %{ 12392 // peepmatch (decI_rReg movI); 12393 // peepconstraint (0.dst == 1.dst); 12394 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12395 // %} 12396 12397 // peephole 12398 // %{ 12399 // peepmatch (addI_rReg_imm movI); 12400 // peepconstraint (0.dst == 1.dst); 12401 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12402 // %} 12403 12404 // peephole 12405 // %{ 12406 // peepmatch (incL_rReg movL); 12407 // peepconstraint (0.dst == 1.dst); 12408 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12409 // %} 12410 12411 // peephole 12412 // %{ 12413 // peepmatch (decL_rReg movL); 12414 // peepconstraint (0.dst == 1.dst); 12415 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12416 // %} 12417 12418 // peephole 12419 // %{ 12420 // peepmatch (addL_rReg_imm movL); 12421 // peepconstraint (0.dst == 1.dst); 12422 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12423 // %} 12424 12425 // peephole 12426 // %{ 12427 // peepmatch (addP_rReg_imm movP); 12428 // peepconstraint (0.dst == 1.dst); 12429 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12430 // %} 12431 12432 // // Change load of spilled value to only a spill 12433 // instruct storeI(memory mem, rRegI src) 12434 // %{ 12435 // match(Set mem (StoreI mem src)); 12436 // %} 12437 // 12438 // instruct loadI(rRegI dst, memory mem) 12439 // %{ 12440 // match(Set dst (LoadI mem)); 12441 // %} 12442 // 12443 12444 peephole 12445 %{ 12446 peepmatch (loadI storeI); 12447 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12448 peepreplace (storeI(1.mem 1.mem 1.src)); 12449 %} 12450 12451 peephole 12452 %{ 12453 peepmatch (loadL storeL); 12454 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12455 peepreplace (storeL(1.mem 1.mem 1.src)); 12456 %} 12457 12458 //----------SMARTSPILL RULES--------------------------------------------------- 12459 // These must follow all instruction definitions as they use the names 12460 // defined in the instructions definitions.