1 // 2 // Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // Specify priority of register selection within phases of register 135 // allocation. Highest priority is first. A useful heuristic is to 136 // give registers a low priority when they are required by machine 137 // instructions, like EAX and EDX on I486, and choose no-save registers 138 // before save-on-call, & save-on-call before save-on-entry. Registers 139 // which participate in fixed calling sequences should come last. 140 // Registers which are used as pairs must fall on an even boundary. 141 142 alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160 //----------Architecture Description Register Classes-------------------------- 161 // Several register classes are automatically defined based upon information in 162 // this architecture description. 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167 // 168 169 // Empty register class. 170 reg_class no_reg(); 171 172 // Class for all pointer registers (including RSP and RBP) 173 reg_class any_reg_with_rbp(RAX, RAX_H, 174 RDX, RDX_H, 175 RBP, RBP_H, 176 RDI, RDI_H, 177 RSI, RSI_H, 178 RCX, RCX_H, 179 RBX, RBX_H, 180 RSP, RSP_H, 181 R8, R8_H, 182 R9, R9_H, 183 R10, R10_H, 184 R11, R11_H, 185 R12, R12_H, 186 R13, R13_H, 187 R14, R14_H, 188 R15, R15_H); 189 190 // Class for all pointer registers (including RSP, but excluding RBP) 191 reg_class any_reg_no_rbp(RAX, RAX_H, 192 RDX, RDX_H, 193 RDI, RDI_H, 194 RSI, RSI_H, 195 RCX, RCX_H, 196 RBX, RBX_H, 197 RSP, RSP_H, 198 R8, R8_H, 199 R9, R9_H, 200 R10, R10_H, 201 R11, R11_H, 202 R12, R12_H, 203 R13, R13_H, 204 R14, R14_H, 205 R15, R15_H); 206 207 // Dynamic register class that selects at runtime between register classes 208 // any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer). 209 // Equivalent to: return PreserveFramePointer ? any_reg_no_rbp : any_reg_with_rbp; 210 reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %}); 211 212 // Class for all pointer registers (excluding RSP) 213 reg_class ptr_reg_with_rbp(RAX, RAX_H, 214 RDX, RDX_H, 215 RBP, RBP_H, 216 RDI, RDI_H, 217 RSI, RSI_H, 218 RCX, RCX_H, 219 RBX, RBX_H, 220 R8, R8_H, 221 R9, R9_H, 222 R10, R10_H, 223 R11, R11_H, 224 R13, R13_H, 225 R14, R14_H); 226 227 // Class for all pointer registers (excluding RSP and RBP) 228 reg_class ptr_reg_no_rbp(RAX, RAX_H, 229 RDX, RDX_H, 230 RDI, RDI_H, 231 RSI, RSI_H, 232 RCX, RCX_H, 233 RBX, RBX_H, 234 R8, R8_H, 235 R9, R9_H, 236 R10, R10_H, 237 R11, R11_H, 238 R13, R13_H, 239 R14, R14_H); 240 241 // Dynamic register class that selects between ptr_reg_no_rbp and ptr_reg_with_rbp. 242 reg_class_dynamic ptr_reg(ptr_reg_no_rbp, ptr_reg_with_rbp, %{ PreserveFramePointer %}); 243 244 // Class for all pointer registers (excluding RAX and RSP) 245 reg_class ptr_no_rax_reg_with_rbp(RDX, RDX_H, 246 RBP, RBP_H, 247 RDI, RDI_H, 248 RSI, RSI_H, 249 RCX, RCX_H, 250 RBX, RBX_H, 251 R8, R8_H, 252 R9, R9_H, 253 R10, R10_H, 254 R11, R11_H, 255 R13, R13_H, 256 R14, R14_H); 257 258 // Class for all pointer registers (excluding RAX, RSP, and RBP) 259 reg_class ptr_no_rax_reg_no_rbp(RDX, RDX_H, 260 RDI, RDI_H, 261 RSI, RSI_H, 262 RCX, RCX_H, 263 RBX, RBX_H, 264 R8, R8_H, 265 R9, R9_H, 266 R10, R10_H, 267 R11, R11_H, 268 R13, R13_H, 269 R14, R14_H); 270 271 // Dynamic register class that selects between ptr_no_rax_reg_no_rbp and ptr_no_rax_reg_with_rbp. 272 reg_class_dynamic ptr_no_rax_reg(ptr_no_rax_reg_no_rbp, ptr_no_rax_reg_with_rbp, %{ PreserveFramePointer %}); 273 274 // Class for all pointer registers (excluding RAX, RBX, and RSP) 275 reg_class ptr_no_rax_rbx_reg_with_rbp(RDX, RDX_H, 276 RBP, RBP_H, 277 RDI, RDI_H, 278 RSI, RSI_H, 279 RCX, RCX_H, 280 R8, R8_H, 281 R9, R9_H, 282 R10, R10_H, 283 R11, R11_H, 284 R13, R13_H, 285 R14, R14_H); 286 287 // Class for all pointer registers (excluding RAX, RBX, RSP, and RBP) 288 reg_class ptr_no_rax_rbx_reg_no_rbp(RDX, RDX_H, 289 RDI, RDI_H, 290 RSI, RSI_H, 291 RCX, RCX_H, 292 R8, R8_H, 293 R9, R9_H, 294 R10, R10_H, 295 R11, R11_H, 296 R13, R13_H, 297 R14, R14_H); 298 299 // Dynamic register class that selects between ptr_no_rax_rbx_reg_no_rbp and ptr_no_rax_rbx_reg_with_rbp. 300 reg_class_dynamic ptr_no_rax_rbx_reg(ptr_no_rax_rbx_reg_no_rbp, ptr_no_rax_rbx_reg_with_rbp, %{ PreserveFramePointer %}); 301 302 // Singleton class for RAX pointer register 303 reg_class ptr_rax_reg(RAX, RAX_H); 304 305 // Singleton class for RBX pointer register 306 reg_class ptr_rbx_reg(RBX, RBX_H); 307 308 // Singleton class for RSI pointer register 309 reg_class ptr_rsi_reg(RSI, RSI_H); 310 311 // Singleton class for RDI pointer register 312 reg_class ptr_rdi_reg(RDI, RDI_H); 313 314 // Singleton class for stack pointer 315 reg_class ptr_rsp_reg(RSP, RSP_H); 316 317 // Singleton class for TLS pointer 318 reg_class ptr_r15_reg(R15, R15_H); 319 320 // Class for all long registers (excluding RSP) 321 reg_class long_reg_with_rbp(RAX, RAX_H, 322 RDX, RDX_H, 323 RBP, RBP_H, 324 RDI, RDI_H, 325 RSI, RSI_H, 326 RCX, RCX_H, 327 RBX, RBX_H, 328 R8, R8_H, 329 R9, R9_H, 330 R10, R10_H, 331 R11, R11_H, 332 R13, R13_H, 333 R14, R14_H); 334 335 // Class for all long registers (excluding RSP and RBP) 336 reg_class long_reg_no_rbp(RAX, RAX_H, 337 RDX, RDX_H, 338 RDI, RDI_H, 339 RSI, RSI_H, 340 RCX, RCX_H, 341 RBX, RBX_H, 342 R8, R8_H, 343 R9, R9_H, 344 R10, R10_H, 345 R11, R11_H, 346 R13, R13_H, 347 R14, R14_H); 348 349 // Dynamic register class that selects between long_reg_no_rbp and long_reg_with_rbp. 350 reg_class_dynamic long_reg(long_reg_no_rbp, long_reg_with_rbp, %{ PreserveFramePointer %}); 351 352 // Class for all long registers (excluding RAX, RDX and RSP) 353 reg_class long_no_rax_rdx_reg_with_rbp(RBP, RBP_H, 354 RDI, RDI_H, 355 RSI, RSI_H, 356 RCX, RCX_H, 357 RBX, RBX_H, 358 R8, R8_H, 359 R9, R9_H, 360 R10, R10_H, 361 R11, R11_H, 362 R13, R13_H, 363 R14, R14_H); 364 365 // Class for all long registers (excluding RAX, RDX, RSP, and RBP) 366 reg_class long_no_rax_rdx_reg_no_rbp(RDI, RDI_H, 367 RSI, RSI_H, 368 RCX, RCX_H, 369 RBX, RBX_H, 370 R8, R8_H, 371 R9, R9_H, 372 R10, R10_H, 373 R11, R11_H, 374 R13, R13_H, 375 R14, R14_H); 376 377 // Dynamic register class that selects between long_no_rax_rdx_reg_no_rbp and long_no_rax_rdx_reg_with_rbp. 378 reg_class_dynamic long_no_rax_rdx_reg(long_no_rax_rdx_reg_no_rbp, long_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 379 380 // Class for all long registers (excluding RCX and RSP) 381 reg_class long_no_rcx_reg_with_rbp(RBP, RBP_H, 382 RDI, RDI_H, 383 RSI, RSI_H, 384 RAX, RAX_H, 385 RDX, RDX_H, 386 RBX, RBX_H, 387 R8, R8_H, 388 R9, R9_H, 389 R10, R10_H, 390 R11, R11_H, 391 R13, R13_H, 392 R14, R14_H); 393 394 // Class for all long registers (excluding RCX, RSP, and RBP) 395 reg_class long_no_rcx_reg_no_rbp(RDI, RDI_H, 396 RSI, RSI_H, 397 RAX, RAX_H, 398 RDX, RDX_H, 399 RBX, RBX_H, 400 R8, R8_H, 401 R9, R9_H, 402 R10, R10_H, 403 R11, R11_H, 404 R13, R13_H, 405 R14, R14_H); 406 407 // Dynamic register class that selects between long_no_rcx_reg_no_rbp and long_no_rcx_reg_with_rbp. 408 reg_class_dynamic long_no_rcx_reg(long_no_rcx_reg_no_rbp, long_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 409 410 // Singleton class for RAX long register 411 reg_class long_rax_reg(RAX, RAX_H); 412 413 // Singleton class for RCX long register 414 reg_class long_rcx_reg(RCX, RCX_H); 415 416 // Singleton class for RDX long register 417 reg_class long_rdx_reg(RDX, RDX_H); 418 419 // Class for all int registers (excluding RSP) 420 reg_class int_reg_with_rbp(RAX, 421 RDX, 422 RBP, 423 RDI, 424 RSI, 425 RCX, 426 RBX, 427 R8, 428 R9, 429 R10, 430 R11, 431 R13, 432 R14); 433 434 // Class for all int registers (excluding RSP and RBP) 435 reg_class int_reg_no_rbp(RAX, 436 RDX, 437 RDI, 438 RSI, 439 RCX, 440 RBX, 441 R8, 442 R9, 443 R10, 444 R11, 445 R13, 446 R14); 447 448 // Dynamic register class that selects between int_reg_no_rbp and int_reg_with_rbp. 449 reg_class_dynamic int_reg(int_reg_no_rbp, int_reg_with_rbp, %{ PreserveFramePointer %}); 450 451 // Class for all int registers (excluding RCX and RSP) 452 reg_class int_no_rcx_reg_with_rbp(RAX, 453 RDX, 454 RBP, 455 RDI, 456 RSI, 457 RBX, 458 R8, 459 R9, 460 R10, 461 R11, 462 R13, 463 R14); 464 465 // Class for all int registers (excluding RCX, RSP, and RBP) 466 reg_class int_no_rcx_reg_no_rbp(RAX, 467 RDX, 468 RDI, 469 RSI, 470 RBX, 471 R8, 472 R9, 473 R10, 474 R11, 475 R13, 476 R14); 477 478 // Dynamic register class that selects between int_no_rcx_reg_no_rbp and int_no_rcx_reg_with_rbp. 479 reg_class_dynamic int_no_rcx_reg(int_no_rcx_reg_no_rbp, int_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 480 481 // Class for all int registers (excluding RAX, RDX, and RSP) 482 reg_class int_no_rax_rdx_reg_with_rbp(RBP, 483 RDI, 484 RSI, 485 RCX, 486 RBX, 487 R8, 488 R9, 489 R10, 490 R11, 491 R13, 492 R14); 493 494 // Class for all int registers (excluding RAX, RDX, RSP, and RBP) 495 reg_class int_no_rax_rdx_reg_no_rbp(RDI, 496 RSI, 497 RCX, 498 RBX, 499 R8, 500 R9, 501 R10, 502 R11, 503 R13, 504 R14); 505 506 // Dynamic register class that selects between int_no_rax_rdx_reg_no_rbp and int_no_rax_rdx_reg_with_rbp. 507 reg_class_dynamic int_no_rax_rdx_reg(int_no_rax_rdx_reg_no_rbp, int_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 508 509 // Singleton class for RAX int register 510 reg_class int_rax_reg(RAX); 511 512 // Singleton class for RBX int register 513 reg_class int_rbx_reg(RBX); 514 515 // Singleton class for RCX int register 516 reg_class int_rcx_reg(RCX); 517 518 // Singleton class for RCX int register 519 reg_class int_rdx_reg(RDX); 520 521 // Singleton class for RCX int register 522 reg_class int_rdi_reg(RDI); 523 524 // Singleton class for instruction pointer 525 // reg_class ip_reg(RIP); 526 527 %} 528 529 //----------SOURCE BLOCK------------------------------------------------------- 530 // This is a block of C++ code which provides values, functions, and 531 // definitions necessary in the rest of the architecture description 532 source %{ 533 #define RELOC_IMM64 Assembler::imm_operand 534 #define RELOC_DISP32 Assembler::disp32_operand 535 536 #define __ _masm. 537 538 static int clear_avx_size() { 539 if(UseAVX > 2) { 540 return 0; // vzeroupper is ignored 541 } else { 542 return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper 543 } 544 } 545 546 // !!!!! Special hack to get all types of calls to specify the byte offset 547 // from the start of the call to the point where the return address 548 // will point. 549 int MachCallStaticJavaNode::ret_addr_offset() 550 { 551 int offset = 5; // 5 bytes from start of call to where return address points 552 offset += clear_avx_size(); 553 return offset; 554 } 555 556 int MachCallDynamicJavaNode::ret_addr_offset() 557 { 558 int offset = 15; // 15 bytes from start of call to where return address points 559 offset += clear_avx_size(); 560 return offset; 561 } 562 563 int MachCallRuntimeNode::ret_addr_offset() { 564 int offset = 13; // movq r10,#addr; callq (r10) 565 offset += clear_avx_size(); 566 return offset; 567 } 568 569 // Indicate if the safepoint node needs the polling page as an input, 570 // it does if the polling page is more than disp32 away. 571 bool SafePointNode::needs_polling_address_input() 572 { 573 return Assembler::is_polling_page_far(); 574 } 575 576 // 577 // Compute padding required for nodes which need alignment 578 // 579 580 // The address of the call instruction needs to be 4-byte aligned to 581 // ensure that it does not span a cache line so that it can be patched. 582 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 583 { 584 current_offset += clear_avx_size(); // skip vzeroupper 585 current_offset += 1; // skip call opcode byte 586 return round_to(current_offset, alignment_required()) - current_offset; 587 } 588 589 // The address of the call instruction needs to be 4-byte aligned to 590 // ensure that it does not span a cache line so that it can be patched. 591 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 592 { 593 current_offset += clear_avx_size(); // skip vzeroupper 594 current_offset += 11; // skip movq instruction + call opcode byte 595 return round_to(current_offset, alignment_required()) - current_offset; 596 } 597 598 // EMIT_RM() 599 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 600 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 601 cbuf.insts()->emit_int8(c); 602 } 603 604 // EMIT_CC() 605 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 606 unsigned char c = (unsigned char) (f1 | f2); 607 cbuf.insts()->emit_int8(c); 608 } 609 610 // EMIT_OPCODE() 611 void emit_opcode(CodeBuffer &cbuf, int code) { 612 cbuf.insts()->emit_int8((unsigned char) code); 613 } 614 615 // EMIT_OPCODE() w/ relocation information 616 void emit_opcode(CodeBuffer &cbuf, 617 int code, relocInfo::relocType reloc, int offset, int format) 618 { 619 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 620 emit_opcode(cbuf, code); 621 } 622 623 // EMIT_D8() 624 void emit_d8(CodeBuffer &cbuf, int d8) { 625 cbuf.insts()->emit_int8((unsigned char) d8); 626 } 627 628 // EMIT_D16() 629 void emit_d16(CodeBuffer &cbuf, int d16) { 630 cbuf.insts()->emit_int16(d16); 631 } 632 633 // EMIT_D32() 634 void emit_d32(CodeBuffer &cbuf, int d32) { 635 cbuf.insts()->emit_int32(d32); 636 } 637 638 // EMIT_D64() 639 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 640 cbuf.insts()->emit_int64(d64); 641 } 642 643 // emit 32 bit value and construct relocation entry from relocInfo::relocType 644 void emit_d32_reloc(CodeBuffer& cbuf, 645 int d32, 646 relocInfo::relocType reloc, 647 int format) 648 { 649 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 650 cbuf.relocate(cbuf.insts_mark(), reloc, format); 651 cbuf.insts()->emit_int32(d32); 652 } 653 654 // emit 32 bit value and construct relocation entry from RelocationHolder 655 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 656 #ifdef ASSERT 657 if (rspec.reloc()->type() == relocInfo::oop_type && 658 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 659 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 660 assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 661 } 662 #endif 663 cbuf.relocate(cbuf.insts_mark(), rspec, format); 664 cbuf.insts()->emit_int32(d32); 665 } 666 667 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 668 address next_ip = cbuf.insts_end() + 4; 669 emit_d32_reloc(cbuf, (int) (addr - next_ip), 670 external_word_Relocation::spec(addr), 671 RELOC_DISP32); 672 } 673 674 675 // emit 64 bit value and construct relocation entry from relocInfo::relocType 676 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 677 cbuf.relocate(cbuf.insts_mark(), reloc, format); 678 cbuf.insts()->emit_int64(d64); 679 } 680 681 // emit 64 bit value and construct relocation entry from RelocationHolder 682 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 683 #ifdef ASSERT 684 if (rspec.reloc()->type() == relocInfo::oop_type && 685 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 686 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 687 assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()), 688 "cannot embed scavengable oops in code"); 689 } 690 #endif 691 cbuf.relocate(cbuf.insts_mark(), rspec, format); 692 cbuf.insts()->emit_int64(d64); 693 } 694 695 // Access stack slot for load or store 696 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 697 { 698 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 699 if (-0x80 <= disp && disp < 0x80) { 700 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 701 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 702 emit_d8(cbuf, disp); // Displacement // R/M byte 703 } else { 704 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 705 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 706 emit_d32(cbuf, disp); // Displacement // R/M byte 707 } 708 } 709 710 // rRegI ereg, memory mem) %{ // emit_reg_mem 711 void encode_RegMem(CodeBuffer &cbuf, 712 int reg, 713 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 714 { 715 assert(disp_reloc == relocInfo::none, "cannot have disp"); 716 int regenc = reg & 7; 717 int baseenc = base & 7; 718 int indexenc = index & 7; 719 720 // There is no index & no scale, use form without SIB byte 721 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 722 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 723 if (disp == 0 && base != RBP_enc && base != R13_enc) { 724 emit_rm(cbuf, 0x0, regenc, baseenc); // * 725 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 726 // If 8-bit displacement, mode 0x1 727 emit_rm(cbuf, 0x1, regenc, baseenc); // * 728 emit_d8(cbuf, disp); 729 } else { 730 // If 32-bit displacement 731 if (base == -1) { // Special flag for absolute address 732 emit_rm(cbuf, 0x0, regenc, 0x5); // * 733 if (disp_reloc != relocInfo::none) { 734 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 735 } else { 736 emit_d32(cbuf, disp); 737 } 738 } else { 739 // Normal base + offset 740 emit_rm(cbuf, 0x2, regenc, baseenc); // * 741 if (disp_reloc != relocInfo::none) { 742 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 743 } else { 744 emit_d32(cbuf, disp); 745 } 746 } 747 } 748 } else { 749 // Else, encode with the SIB byte 750 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 751 if (disp == 0 && base != RBP_enc && base != R13_enc) { 752 // If no displacement 753 emit_rm(cbuf, 0x0, regenc, 0x4); // * 754 emit_rm(cbuf, scale, indexenc, baseenc); 755 } else { 756 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 757 // If 8-bit displacement, mode 0x1 758 emit_rm(cbuf, 0x1, regenc, 0x4); // * 759 emit_rm(cbuf, scale, indexenc, baseenc); 760 emit_d8(cbuf, disp); 761 } else { 762 // If 32-bit displacement 763 if (base == 0x04 ) { 764 emit_rm(cbuf, 0x2, regenc, 0x4); 765 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 766 } else { 767 emit_rm(cbuf, 0x2, regenc, 0x4); 768 emit_rm(cbuf, scale, indexenc, baseenc); // * 769 } 770 if (disp_reloc != relocInfo::none) { 771 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 772 } else { 773 emit_d32(cbuf, disp); 774 } 775 } 776 } 777 } 778 } 779 780 // This could be in MacroAssembler but it's fairly C2 specific 781 void emit_cmpfp_fixup(MacroAssembler& _masm) { 782 Label exit; 783 __ jccb(Assembler::noParity, exit); 784 __ pushf(); 785 // 786 // comiss/ucomiss instructions set ZF,PF,CF flags and 787 // zero OF,AF,SF for NaN values. 788 // Fixup flags by zeroing ZF,PF so that compare of NaN 789 // values returns 'less than' result (CF is set). 790 // Leave the rest of flags unchanged. 791 // 792 // 7 6 5 4 3 2 1 0 793 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 794 // 0 0 1 0 1 0 1 1 (0x2B) 795 // 796 __ andq(Address(rsp, 0), 0xffffff2b); 797 __ popf(); 798 __ bind(exit); 799 } 800 801 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 802 Label done; 803 __ movl(dst, -1); 804 __ jcc(Assembler::parity, done); 805 __ jcc(Assembler::below, done); 806 __ setb(Assembler::notEqual, dst); 807 __ movzbl(dst, dst); 808 __ bind(done); 809 } 810 811 812 //============================================================================= 813 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 814 815 int Compile::ConstantTable::calculate_table_base_offset() const { 816 return 0; // absolute addressing, no offset 817 } 818 819 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 820 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 821 ShouldNotReachHere(); 822 } 823 824 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 825 // Empty encoding 826 } 827 828 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 829 return 0; 830 } 831 832 #ifndef PRODUCT 833 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 834 st->print("# MachConstantBaseNode (empty encoding)"); 835 } 836 #endif 837 838 839 //============================================================================= 840 #ifndef PRODUCT 841 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 842 Compile* C = ra_->C; 843 844 int framesize = C->frame_size_in_bytes(); 845 int bangsize = C->bang_size_in_bytes(); 846 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 847 // Remove wordSize for return addr which is already pushed. 848 framesize -= wordSize; 849 850 if (C->need_stack_bang(bangsize)) { 851 framesize -= wordSize; 852 st->print("# stack bang (%d bytes)", bangsize); 853 st->print("\n\t"); 854 st->print("pushq rbp\t# Save rbp"); 855 if (PreserveFramePointer) { 856 st->print("\n\t"); 857 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 858 } 859 if (framesize) { 860 st->print("\n\t"); 861 st->print("subq rsp, #%d\t# Create frame",framesize); 862 } 863 } else { 864 st->print("subq rsp, #%d\t# Create frame",framesize); 865 st->print("\n\t"); 866 framesize -= wordSize; 867 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 868 if (PreserveFramePointer) { 869 st->print("\n\t"); 870 st->print("movq rbp, [rsp + #%d]\t# Save the caller's SP into rbp", (framesize + wordSize)); 871 } 872 } 873 874 if (VerifyStackAtCalls) { 875 st->print("\n\t"); 876 framesize -= wordSize; 877 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 878 #ifdef ASSERT 879 st->print("\n\t"); 880 st->print("# stack alignment check"); 881 #endif 882 } 883 st->cr(); 884 } 885 #endif 886 887 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 888 Compile* C = ra_->C; 889 MacroAssembler _masm(&cbuf); 890 891 int framesize = C->frame_size_in_bytes(); 892 int bangsize = C->bang_size_in_bytes(); 893 894 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); 895 896 C->set_frame_complete(cbuf.insts_size()); 897 898 if (C->has_mach_constant_base_node()) { 899 // NOTE: We set the table base offset here because users might be 900 // emitted before MachConstantBaseNode. 901 Compile::ConstantTable& constant_table = C->constant_table(); 902 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 903 } 904 } 905 906 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 907 { 908 return MachNode::size(ra_); // too many variables; just compute it 909 // the hard way 910 } 911 912 int MachPrologNode::reloc() const 913 { 914 return 0; // a large enough number 915 } 916 917 //============================================================================= 918 #ifndef PRODUCT 919 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 920 { 921 Compile* C = ra_->C; 922 if (C->max_vector_size() > 16) { 923 st->print("vzeroupper"); 924 st->cr(); st->print("\t"); 925 } 926 927 int framesize = C->frame_size_in_bytes(); 928 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 929 // Remove word for return adr already pushed 930 // and RBP 931 framesize -= 2*wordSize; 932 933 if (framesize) { 934 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 935 st->print("\t"); 936 } 937 938 st->print_cr("popq rbp"); 939 if (do_polling() && C->is_method_compilation()) { 940 st->print("\t"); 941 if (Assembler::is_polling_page_far()) { 942 st->print_cr("movq rscratch1, #polling_page_address\n\t" 943 "testl rax, [rscratch1]\t" 944 "# Safepoint: poll for GC"); 945 } else { 946 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 947 "# Safepoint: poll for GC"); 948 } 949 } 950 } 951 #endif 952 953 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 954 { 955 Compile* C = ra_->C; 956 if (C->max_vector_size() > 16) { 957 // Clear upper bits of YMM registers when current compiled code uses 958 // wide vectors to avoid AVX <-> SSE transition penalty during call. 959 MacroAssembler _masm(&cbuf); 960 __ vzeroupper(); 961 } 962 963 int framesize = C->frame_size_in_bytes(); 964 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 965 // Remove word for return adr already pushed 966 // and RBP 967 framesize -= 2*wordSize; 968 969 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 970 971 if (framesize) { 972 emit_opcode(cbuf, Assembler::REX_W); 973 if (framesize < 0x80) { 974 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 975 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 976 emit_d8(cbuf, framesize); 977 } else { 978 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 979 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 980 emit_d32(cbuf, framesize); 981 } 982 } 983 984 // popq rbp 985 emit_opcode(cbuf, 0x58 | RBP_enc); 986 987 if (do_polling() && C->is_method_compilation()) { 988 MacroAssembler _masm(&cbuf); 989 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 990 if (Assembler::is_polling_page_far()) { 991 __ lea(rscratch1, polling_page); 992 __ relocate(relocInfo::poll_return_type); 993 __ testl(rax, Address(rscratch1, 0)); 994 } else { 995 __ testl(rax, polling_page); 996 } 997 } 998 } 999 1000 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1001 { 1002 return MachNode::size(ra_); // too many variables; just compute it 1003 // the hard way 1004 } 1005 1006 int MachEpilogNode::reloc() const 1007 { 1008 return 2; // a large enough number 1009 } 1010 1011 const Pipeline* MachEpilogNode::pipeline() const 1012 { 1013 return MachNode::pipeline_class(); 1014 } 1015 1016 int MachEpilogNode::safepoint_offset() const 1017 { 1018 return 0; 1019 } 1020 1021 //============================================================================= 1022 1023 enum RC { 1024 rc_bad, 1025 rc_int, 1026 rc_float, 1027 rc_stack 1028 }; 1029 1030 static enum RC rc_class(OptoReg::Name reg) 1031 { 1032 if( !OptoReg::is_valid(reg) ) return rc_bad; 1033 1034 if (OptoReg::is_stack(reg)) return rc_stack; 1035 1036 VMReg r = OptoReg::as_VMReg(reg); 1037 1038 if (r->is_Register()) return rc_int; 1039 1040 assert(r->is_XMMRegister(), "must be"); 1041 return rc_float; 1042 } 1043 1044 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1045 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1046 int src_hi, int dst_hi, uint ireg, outputStream* st); 1047 1048 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1049 int stack_offset, int reg, uint ireg, outputStream* st); 1050 1051 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1052 int dst_offset, uint ireg, outputStream* st) { 1053 if (cbuf) { 1054 MacroAssembler _masm(cbuf); 1055 switch (ireg) { 1056 case Op_VecS: 1057 __ movq(Address(rsp, -8), rax); 1058 __ movl(rax, Address(rsp, src_offset)); 1059 __ movl(Address(rsp, dst_offset), rax); 1060 __ movq(rax, Address(rsp, -8)); 1061 break; 1062 case Op_VecD: 1063 __ pushq(Address(rsp, src_offset)); 1064 __ popq (Address(rsp, dst_offset)); 1065 break; 1066 case Op_VecX: 1067 __ pushq(Address(rsp, src_offset)); 1068 __ popq (Address(rsp, dst_offset)); 1069 __ pushq(Address(rsp, src_offset+8)); 1070 __ popq (Address(rsp, dst_offset+8)); 1071 break; 1072 case Op_VecY: 1073 __ vmovdqu(Address(rsp, -32), xmm0); 1074 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1075 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1076 __ vmovdqu(xmm0, Address(rsp, -32)); 1077 case Op_VecZ: 1078 __ evmovdqu(Address(rsp, -64), xmm0, 2); 1079 __ evmovdqu(xmm0, Address(rsp, src_offset), 2); 1080 __ evmovdqu(Address(rsp, dst_offset), xmm0, 2); 1081 __ evmovdqu(xmm0, Address(rsp, -64), 2); 1082 break; 1083 default: 1084 ShouldNotReachHere(); 1085 } 1086 #ifndef PRODUCT 1087 } else { 1088 switch (ireg) { 1089 case Op_VecS: 1090 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1091 "movl rax, [rsp + #%d]\n\t" 1092 "movl [rsp + #%d], rax\n\t" 1093 "movq rax, [rsp - #8]", 1094 src_offset, dst_offset); 1095 break; 1096 case Op_VecD: 1097 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1098 "popq [rsp + #%d]", 1099 src_offset, dst_offset); 1100 break; 1101 case Op_VecX: 1102 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1103 "popq [rsp + #%d]\n\t" 1104 "pushq [rsp + #%d]\n\t" 1105 "popq [rsp + #%d]", 1106 src_offset, dst_offset, src_offset+8, dst_offset+8); 1107 break; 1108 case Op_VecY: 1109 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1110 "vmovdqu xmm0, [rsp + #%d]\n\t" 1111 "vmovdqu [rsp + #%d], xmm0\n\t" 1112 "vmovdqu xmm0, [rsp - #32]", 1113 src_offset, dst_offset); 1114 break; 1115 case Op_VecZ: 1116 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1117 "vmovdqu xmm0, [rsp + #%d]\n\t" 1118 "vmovdqu [rsp + #%d], xmm0\n\t" 1119 "vmovdqu xmm0, [rsp - #64]", 1120 src_offset, dst_offset); 1121 break; 1122 default: 1123 ShouldNotReachHere(); 1124 } 1125 #endif 1126 } 1127 } 1128 1129 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1130 PhaseRegAlloc* ra_, 1131 bool do_size, 1132 outputStream* st) const { 1133 assert(cbuf != NULL || st != NULL, "sanity"); 1134 // Get registers to move 1135 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1136 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1137 OptoReg::Name dst_second = ra_->get_reg_second(this); 1138 OptoReg::Name dst_first = ra_->get_reg_first(this); 1139 1140 enum RC src_second_rc = rc_class(src_second); 1141 enum RC src_first_rc = rc_class(src_first); 1142 enum RC dst_second_rc = rc_class(dst_second); 1143 enum RC dst_first_rc = rc_class(dst_first); 1144 1145 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1146 "must move at least 1 register" ); 1147 1148 if (src_first == dst_first && src_second == dst_second) { 1149 // Self copy, no move 1150 return 0; 1151 } 1152 if (bottom_type()->isa_vect() != NULL) { 1153 uint ireg = ideal_reg(); 1154 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1155 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1156 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1157 // mem -> mem 1158 int src_offset = ra_->reg2offset(src_first); 1159 int dst_offset = ra_->reg2offset(dst_first); 1160 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1161 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1162 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1163 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1164 int stack_offset = ra_->reg2offset(dst_first); 1165 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1166 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1167 int stack_offset = ra_->reg2offset(src_first); 1168 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1169 } else { 1170 ShouldNotReachHere(); 1171 } 1172 return 0; 1173 } 1174 if (src_first_rc == rc_stack) { 1175 // mem -> 1176 if (dst_first_rc == rc_stack) { 1177 // mem -> mem 1178 assert(src_second != dst_first, "overlap"); 1179 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1180 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1181 // 64-bit 1182 int src_offset = ra_->reg2offset(src_first); 1183 int dst_offset = ra_->reg2offset(dst_first); 1184 if (cbuf) { 1185 MacroAssembler _masm(cbuf); 1186 __ pushq(Address(rsp, src_offset)); 1187 __ popq (Address(rsp, dst_offset)); 1188 #ifndef PRODUCT 1189 } else { 1190 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1191 "popq [rsp + #%d]", 1192 src_offset, dst_offset); 1193 #endif 1194 } 1195 } else { 1196 // 32-bit 1197 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1198 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1199 // No pushl/popl, so: 1200 int src_offset = ra_->reg2offset(src_first); 1201 int dst_offset = ra_->reg2offset(dst_first); 1202 if (cbuf) { 1203 MacroAssembler _masm(cbuf); 1204 __ movq(Address(rsp, -8), rax); 1205 __ movl(rax, Address(rsp, src_offset)); 1206 __ movl(Address(rsp, dst_offset), rax); 1207 __ movq(rax, Address(rsp, -8)); 1208 #ifndef PRODUCT 1209 } else { 1210 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1211 "movl rax, [rsp + #%d]\n\t" 1212 "movl [rsp + #%d], rax\n\t" 1213 "movq rax, [rsp - #8]", 1214 src_offset, dst_offset); 1215 #endif 1216 } 1217 } 1218 return 0; 1219 } else if (dst_first_rc == rc_int) { 1220 // mem -> gpr 1221 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1222 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1223 // 64-bit 1224 int offset = ra_->reg2offset(src_first); 1225 if (cbuf) { 1226 MacroAssembler _masm(cbuf); 1227 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1228 #ifndef PRODUCT 1229 } else { 1230 st->print("movq %s, [rsp + #%d]\t# spill", 1231 Matcher::regName[dst_first], 1232 offset); 1233 #endif 1234 } 1235 } else { 1236 // 32-bit 1237 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1238 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1239 int offset = ra_->reg2offset(src_first); 1240 if (cbuf) { 1241 MacroAssembler _masm(cbuf); 1242 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1243 #ifndef PRODUCT 1244 } else { 1245 st->print("movl %s, [rsp + #%d]\t# spill", 1246 Matcher::regName[dst_first], 1247 offset); 1248 #endif 1249 } 1250 } 1251 return 0; 1252 } else if (dst_first_rc == rc_float) { 1253 // mem-> xmm 1254 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1255 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1256 // 64-bit 1257 int offset = ra_->reg2offset(src_first); 1258 if (cbuf) { 1259 MacroAssembler _masm(cbuf); 1260 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1261 #ifndef PRODUCT 1262 } else { 1263 st->print("%s %s, [rsp + #%d]\t# spill", 1264 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1265 Matcher::regName[dst_first], 1266 offset); 1267 #endif 1268 } 1269 } else { 1270 // 32-bit 1271 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1272 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1273 int offset = ra_->reg2offset(src_first); 1274 if (cbuf) { 1275 MacroAssembler _masm(cbuf); 1276 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1277 #ifndef PRODUCT 1278 } else { 1279 st->print("movss %s, [rsp + #%d]\t# spill", 1280 Matcher::regName[dst_first], 1281 offset); 1282 #endif 1283 } 1284 } 1285 return 0; 1286 } 1287 } else if (src_first_rc == rc_int) { 1288 // gpr -> 1289 if (dst_first_rc == rc_stack) { 1290 // gpr -> mem 1291 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1292 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1293 // 64-bit 1294 int offset = ra_->reg2offset(dst_first); 1295 if (cbuf) { 1296 MacroAssembler _masm(cbuf); 1297 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1298 #ifndef PRODUCT 1299 } else { 1300 st->print("movq [rsp + #%d], %s\t# spill", 1301 offset, 1302 Matcher::regName[src_first]); 1303 #endif 1304 } 1305 } else { 1306 // 32-bit 1307 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1308 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1309 int offset = ra_->reg2offset(dst_first); 1310 if (cbuf) { 1311 MacroAssembler _masm(cbuf); 1312 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1313 #ifndef PRODUCT 1314 } else { 1315 st->print("movl [rsp + #%d], %s\t# spill", 1316 offset, 1317 Matcher::regName[src_first]); 1318 #endif 1319 } 1320 } 1321 return 0; 1322 } else if (dst_first_rc == rc_int) { 1323 // gpr -> gpr 1324 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1325 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1326 // 64-bit 1327 if (cbuf) { 1328 MacroAssembler _masm(cbuf); 1329 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1330 as_Register(Matcher::_regEncode[src_first])); 1331 #ifndef PRODUCT 1332 } else { 1333 st->print("movq %s, %s\t# spill", 1334 Matcher::regName[dst_first], 1335 Matcher::regName[src_first]); 1336 #endif 1337 } 1338 return 0; 1339 } else { 1340 // 32-bit 1341 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1342 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1343 if (cbuf) { 1344 MacroAssembler _masm(cbuf); 1345 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1346 as_Register(Matcher::_regEncode[src_first])); 1347 #ifndef PRODUCT 1348 } else { 1349 st->print("movl %s, %s\t# spill", 1350 Matcher::regName[dst_first], 1351 Matcher::regName[src_first]); 1352 #endif 1353 } 1354 return 0; 1355 } 1356 } else if (dst_first_rc == rc_float) { 1357 // gpr -> xmm 1358 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1359 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1360 // 64-bit 1361 if (cbuf) { 1362 MacroAssembler _masm(cbuf); 1363 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1364 #ifndef PRODUCT 1365 } else { 1366 st->print("movdq %s, %s\t# spill", 1367 Matcher::regName[dst_first], 1368 Matcher::regName[src_first]); 1369 #endif 1370 } 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 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1378 #ifndef PRODUCT 1379 } else { 1380 st->print("movdl %s, %s\t# spill", 1381 Matcher::regName[dst_first], 1382 Matcher::regName[src_first]); 1383 #endif 1384 } 1385 } 1386 return 0; 1387 } 1388 } else if (src_first_rc == rc_float) { 1389 // xmm -> 1390 if (dst_first_rc == rc_stack) { 1391 // xmm -> mem 1392 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1393 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1394 // 64-bit 1395 int offset = ra_->reg2offset(dst_first); 1396 if (cbuf) { 1397 MacroAssembler _masm(cbuf); 1398 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1399 #ifndef PRODUCT 1400 } else { 1401 st->print("movsd [rsp + #%d], %s\t# spill", 1402 offset, 1403 Matcher::regName[src_first]); 1404 #endif 1405 } 1406 } else { 1407 // 32-bit 1408 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1409 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1410 int offset = ra_->reg2offset(dst_first); 1411 if (cbuf) { 1412 MacroAssembler _masm(cbuf); 1413 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1414 #ifndef PRODUCT 1415 } else { 1416 st->print("movss [rsp + #%d], %s\t# spill", 1417 offset, 1418 Matcher::regName[src_first]); 1419 #endif 1420 } 1421 } 1422 return 0; 1423 } else if (dst_first_rc == rc_int) { 1424 // xmm -> gpr 1425 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1426 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1427 // 64-bit 1428 if (cbuf) { 1429 MacroAssembler _masm(cbuf); 1430 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1431 #ifndef PRODUCT 1432 } else { 1433 st->print("movdq %s, %s\t# spill", 1434 Matcher::regName[dst_first], 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 if (cbuf) { 1443 MacroAssembler _masm(cbuf); 1444 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1445 #ifndef PRODUCT 1446 } else { 1447 st->print("movdl %s, %s\t# spill", 1448 Matcher::regName[dst_first], 1449 Matcher::regName[src_first]); 1450 #endif 1451 } 1452 } 1453 return 0; 1454 } else if (dst_first_rc == rc_float) { 1455 // xmm -> xmm 1456 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1457 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1458 // 64-bit 1459 if (cbuf) { 1460 MacroAssembler _masm(cbuf); 1461 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1462 #ifndef PRODUCT 1463 } else { 1464 st->print("%s %s, %s\t# spill", 1465 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 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 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1477 #ifndef PRODUCT 1478 } else { 1479 st->print("%s %s, %s\t# spill", 1480 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1481 Matcher::regName[dst_first], 1482 Matcher::regName[src_first]); 1483 #endif 1484 } 1485 } 1486 return 0; 1487 } 1488 } 1489 1490 assert(0," foo "); 1491 Unimplemented(); 1492 return 0; 1493 } 1494 1495 #ifndef PRODUCT 1496 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1497 implementation(NULL, ra_, false, st); 1498 } 1499 #endif 1500 1501 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1502 implementation(&cbuf, ra_, false, NULL); 1503 } 1504 1505 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1506 return MachNode::size(ra_); 1507 } 1508 1509 //============================================================================= 1510 #ifndef PRODUCT 1511 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1512 { 1513 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1514 int reg = ra_->get_reg_first(this); 1515 st->print("leaq %s, [rsp + #%d]\t# box lock", 1516 Matcher::regName[reg], offset); 1517 } 1518 #endif 1519 1520 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1521 { 1522 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1523 int reg = ra_->get_encode(this); 1524 if (offset >= 0x80) { 1525 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1526 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1527 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1528 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1529 emit_d32(cbuf, offset); 1530 } else { 1531 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1532 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1533 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1534 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1535 emit_d8(cbuf, offset); 1536 } 1537 } 1538 1539 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1540 { 1541 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1542 return (offset < 0x80) ? 5 : 8; // REX 1543 } 1544 1545 //============================================================================= 1546 #ifndef PRODUCT 1547 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1548 { 1549 if (UseCompressedClassPointers) { 1550 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1551 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1552 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1553 } else { 1554 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1555 "# Inline cache check"); 1556 } 1557 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1558 st->print_cr("\tnop\t# nops to align entry point"); 1559 } 1560 #endif 1561 1562 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1563 { 1564 MacroAssembler masm(&cbuf); 1565 uint insts_size = cbuf.insts_size(); 1566 if (UseCompressedClassPointers) { 1567 masm.load_klass(rscratch1, j_rarg0); 1568 masm.cmpptr(rax, rscratch1); 1569 } else { 1570 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1571 } 1572 1573 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1574 1575 /* WARNING these NOPs are critical so that verified entry point is properly 1576 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1577 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1578 if (OptoBreakpoint) { 1579 // Leave space for int3 1580 nops_cnt -= 1; 1581 } 1582 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1583 if (nops_cnt > 0) 1584 masm.nop(nops_cnt); 1585 } 1586 1587 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1588 { 1589 return MachNode::size(ra_); // too many variables; just compute it 1590 // the hard way 1591 } 1592 1593 1594 //============================================================================= 1595 1596 int Matcher::regnum_to_fpu_offset(int regnum) 1597 { 1598 return regnum - 32; // The FP registers are in the second chunk 1599 } 1600 1601 // This is UltraSparc specific, true just means we have fast l2f conversion 1602 const bool Matcher::convL2FSupported(void) { 1603 return true; 1604 } 1605 1606 // Is this branch offset short enough that a short branch can be used? 1607 // 1608 // NOTE: If the platform does not provide any short branch variants, then 1609 // this method should return false for offset 0. 1610 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1611 // The passed offset is relative to address of the branch. 1612 // On 86 a branch displacement is calculated relative to address 1613 // of a next instruction. 1614 offset -= br_size; 1615 1616 // the short version of jmpConUCF2 contains multiple branches, 1617 // making the reach slightly less 1618 if (rule == jmpConUCF2_rule) 1619 return (-126 <= offset && offset <= 125); 1620 return (-128 <= offset && offset <= 127); 1621 } 1622 1623 const bool Matcher::isSimpleConstant64(jlong value) { 1624 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1625 //return value == (int) value; // Cf. storeImmL and immL32. 1626 1627 // Probably always true, even if a temp register is required. 1628 return true; 1629 } 1630 1631 // The ecx parameter to rep stosq for the ClearArray node is in words. 1632 const bool Matcher::init_array_count_is_in_bytes = false; 1633 1634 // Threshold size for cleararray. 1635 const int Matcher::init_array_short_size = 8 * BytesPerLong; 1636 1637 // No additional cost for CMOVL. 1638 const int Matcher::long_cmove_cost() { return 0; } 1639 1640 // No CMOVF/CMOVD with SSE2 1641 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1642 1643 // Does the CPU require late expand (see block.cpp for description of late expand)? 1644 const bool Matcher::require_postalloc_expand = false; 1645 1646 // Should the Matcher clone shifts on addressing modes, expecting them 1647 // to be subsumed into complex addressing expressions or compute them 1648 // into registers? True for Intel but false for most RISCs 1649 const bool Matcher::clone_shift_expressions = true; 1650 1651 // Do we need to mask the count passed to shift instructions or does 1652 // the cpu only look at the lower 5/6 bits anyway? 1653 const bool Matcher::need_masked_shift_count = false; 1654 1655 bool Matcher::narrow_oop_use_complex_address() { 1656 assert(UseCompressedOops, "only for compressed oops code"); 1657 return (LogMinObjAlignmentInBytes <= 3); 1658 } 1659 1660 bool Matcher::narrow_klass_use_complex_address() { 1661 assert(UseCompressedClassPointers, "only for compressed klass code"); 1662 return (LogKlassAlignmentInBytes <= 3); 1663 } 1664 1665 // Is it better to copy float constants, or load them directly from 1666 // memory? Intel can load a float constant from a direct address, 1667 // requiring no extra registers. Most RISCs will have to materialize 1668 // an address into a register first, so they would do better to copy 1669 // the constant from stack. 1670 const bool Matcher::rematerialize_float_constants = true; // XXX 1671 1672 // If CPU can load and store mis-aligned doubles directly then no 1673 // fixup is needed. Else we split the double into 2 integer pieces 1674 // and move it piece-by-piece. Only happens when passing doubles into 1675 // C code as the Java calling convention forces doubles to be aligned. 1676 const bool Matcher::misaligned_doubles_ok = true; 1677 1678 // No-op on amd64 1679 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1680 1681 // Advertise here if the CPU requires explicit rounding operations to 1682 // implement the UseStrictFP mode. 1683 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1684 1685 // Are floats conerted to double when stored to stack during deoptimization? 1686 // On x64 it is stored without convertion so we can use normal access. 1687 bool Matcher::float_in_double() { return false; } 1688 1689 // Do ints take an entire long register or just half? 1690 const bool Matcher::int_in_long = true; 1691 1692 // Return whether or not this register is ever used as an argument. 1693 // This function is used on startup to build the trampoline stubs in 1694 // generateOptoStub. Registers not mentioned will be killed by the VM 1695 // call in the trampoline, and arguments in those registers not be 1696 // available to the callee. 1697 bool Matcher::can_be_java_arg(int reg) 1698 { 1699 return 1700 reg == RDI_num || reg == RDI_H_num || 1701 reg == RSI_num || reg == RSI_H_num || 1702 reg == RDX_num || reg == RDX_H_num || 1703 reg == RCX_num || reg == RCX_H_num || 1704 reg == R8_num || reg == R8_H_num || 1705 reg == R9_num || reg == R9_H_num || 1706 reg == R12_num || reg == R12_H_num || 1707 reg == XMM0_num || reg == XMM0b_num || 1708 reg == XMM1_num || reg == XMM1b_num || 1709 reg == XMM2_num || reg == XMM2b_num || 1710 reg == XMM3_num || reg == XMM3b_num || 1711 reg == XMM4_num || reg == XMM4b_num || 1712 reg == XMM5_num || reg == XMM5b_num || 1713 reg == XMM6_num || reg == XMM6b_num || 1714 reg == XMM7_num || reg == XMM7b_num; 1715 } 1716 1717 bool Matcher::is_spillable_arg(int reg) 1718 { 1719 return can_be_java_arg(reg); 1720 } 1721 1722 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1723 // In 64 bit mode a code which use multiply when 1724 // devisor is constant is faster than hardware 1725 // DIV instruction (it uses MulHiL). 1726 return false; 1727 } 1728 1729 // Register for DIVI projection of divmodI 1730 RegMask Matcher::divI_proj_mask() { 1731 return INT_RAX_REG_mask(); 1732 } 1733 1734 // Register for MODI projection of divmodI 1735 RegMask Matcher::modI_proj_mask() { 1736 return INT_RDX_REG_mask(); 1737 } 1738 1739 // Register for DIVL projection of divmodL 1740 RegMask Matcher::divL_proj_mask() { 1741 return LONG_RAX_REG_mask(); 1742 } 1743 1744 // Register for MODL projection of divmodL 1745 RegMask Matcher::modL_proj_mask() { 1746 return LONG_RDX_REG_mask(); 1747 } 1748 1749 // Register for saving SP into on method handle invokes. Not used on x86_64. 1750 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1751 return NO_REG_mask(); 1752 } 1753 1754 %} 1755 1756 //----------ENCODING BLOCK----------------------------------------------------- 1757 // This block specifies the encoding classes used by the compiler to 1758 // output byte streams. Encoding classes are parameterized macros 1759 // used by Machine Instruction Nodes in order to generate the bit 1760 // encoding of the instruction. Operands specify their base encoding 1761 // interface with the interface keyword. There are currently 1762 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1763 // COND_INTER. REG_INTER causes an operand to generate a function 1764 // which returns its register number when queried. CONST_INTER causes 1765 // an operand to generate a function which returns the value of the 1766 // constant when queried. MEMORY_INTER causes an operand to generate 1767 // four functions which return the Base Register, the Index Register, 1768 // the Scale Value, and the Offset Value of the operand when queried. 1769 // COND_INTER causes an operand to generate six functions which return 1770 // the encoding code (ie - encoding bits for the instruction) 1771 // associated with each basic boolean condition for a conditional 1772 // instruction. 1773 // 1774 // Instructions specify two basic values for encoding. Again, a 1775 // function is available to check if the constant displacement is an 1776 // oop. They use the ins_encode keyword to specify their encoding 1777 // classes (which must be a sequence of enc_class names, and their 1778 // parameters, specified in the encoding block), and they use the 1779 // opcode keyword to specify, in order, their primary, secondary, and 1780 // tertiary opcode. Only the opcode sections which a particular 1781 // instruction needs for encoding need to be specified. 1782 encode %{ 1783 // Build emit functions for each basic byte or larger field in the 1784 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1785 // from C++ code in the enc_class source block. Emit functions will 1786 // live in the main source block for now. In future, we can 1787 // generalize this by adding a syntax that specifies the sizes of 1788 // fields in an order, so that the adlc can build the emit functions 1789 // automagically 1790 1791 // Emit primary opcode 1792 enc_class OpcP 1793 %{ 1794 emit_opcode(cbuf, $primary); 1795 %} 1796 1797 // Emit secondary opcode 1798 enc_class OpcS 1799 %{ 1800 emit_opcode(cbuf, $secondary); 1801 %} 1802 1803 // Emit tertiary opcode 1804 enc_class OpcT 1805 %{ 1806 emit_opcode(cbuf, $tertiary); 1807 %} 1808 1809 // Emit opcode directly 1810 enc_class Opcode(immI d8) 1811 %{ 1812 emit_opcode(cbuf, $d8$$constant); 1813 %} 1814 1815 // Emit size prefix 1816 enc_class SizePrefix 1817 %{ 1818 emit_opcode(cbuf, 0x66); 1819 %} 1820 1821 enc_class reg(rRegI reg) 1822 %{ 1823 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1824 %} 1825 1826 enc_class reg_reg(rRegI dst, rRegI src) 1827 %{ 1828 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1829 %} 1830 1831 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1832 %{ 1833 emit_opcode(cbuf, $opcode$$constant); 1834 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1835 %} 1836 1837 enc_class cdql_enc(no_rax_rdx_RegI div) 1838 %{ 1839 // Full implementation of Java idiv and irem; checks for 1840 // special case as described in JVM spec., p.243 & p.271. 1841 // 1842 // normal case special case 1843 // 1844 // input : rax: dividend min_int 1845 // reg: divisor -1 1846 // 1847 // output: rax: quotient (= rax idiv reg) min_int 1848 // rdx: remainder (= rax irem reg) 0 1849 // 1850 // Code sequnce: 1851 // 1852 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1853 // 5: 75 07/08 jne e <normal> 1854 // 7: 33 d2 xor %edx,%edx 1855 // [div >= 8 -> offset + 1] 1856 // [REX_B] 1857 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1858 // c: 74 03/04 je 11 <done> 1859 // 000000000000000e <normal>: 1860 // e: 99 cltd 1861 // [div >= 8 -> offset + 1] 1862 // [REX_B] 1863 // f: f7 f9 idiv $div 1864 // 0000000000000011 <done>: 1865 1866 // cmp $0x80000000,%eax 1867 emit_opcode(cbuf, 0x3d); 1868 emit_d8(cbuf, 0x00); 1869 emit_d8(cbuf, 0x00); 1870 emit_d8(cbuf, 0x00); 1871 emit_d8(cbuf, 0x80); 1872 1873 // jne e <normal> 1874 emit_opcode(cbuf, 0x75); 1875 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1876 1877 // xor %edx,%edx 1878 emit_opcode(cbuf, 0x33); 1879 emit_d8(cbuf, 0xD2); 1880 1881 // cmp $0xffffffffffffffff,%ecx 1882 if ($div$$reg >= 8) { 1883 emit_opcode(cbuf, Assembler::REX_B); 1884 } 1885 emit_opcode(cbuf, 0x83); 1886 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1887 emit_d8(cbuf, 0xFF); 1888 1889 // je 11 <done> 1890 emit_opcode(cbuf, 0x74); 1891 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1892 1893 // <normal> 1894 // cltd 1895 emit_opcode(cbuf, 0x99); 1896 1897 // idivl (note: must be emitted by the user of this rule) 1898 // <done> 1899 %} 1900 1901 enc_class cdqq_enc(no_rax_rdx_RegL div) 1902 %{ 1903 // Full implementation of Java ldiv and lrem; checks for 1904 // special case as described in JVM spec., p.243 & p.271. 1905 // 1906 // normal case special case 1907 // 1908 // input : rax: dividend min_long 1909 // reg: divisor -1 1910 // 1911 // output: rax: quotient (= rax idiv reg) min_long 1912 // rdx: remainder (= rax irem reg) 0 1913 // 1914 // Code sequnce: 1915 // 1916 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1917 // 7: 00 00 80 1918 // a: 48 39 d0 cmp %rdx,%rax 1919 // d: 75 08 jne 17 <normal> 1920 // f: 33 d2 xor %edx,%edx 1921 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1922 // 15: 74 05 je 1c <done> 1923 // 0000000000000017 <normal>: 1924 // 17: 48 99 cqto 1925 // 19: 48 f7 f9 idiv $div 1926 // 000000000000001c <done>: 1927 1928 // mov $0x8000000000000000,%rdx 1929 emit_opcode(cbuf, Assembler::REX_W); 1930 emit_opcode(cbuf, 0xBA); 1931 emit_d8(cbuf, 0x00); 1932 emit_d8(cbuf, 0x00); 1933 emit_d8(cbuf, 0x00); 1934 emit_d8(cbuf, 0x00); 1935 emit_d8(cbuf, 0x00); 1936 emit_d8(cbuf, 0x00); 1937 emit_d8(cbuf, 0x00); 1938 emit_d8(cbuf, 0x80); 1939 1940 // cmp %rdx,%rax 1941 emit_opcode(cbuf, Assembler::REX_W); 1942 emit_opcode(cbuf, 0x39); 1943 emit_d8(cbuf, 0xD0); 1944 1945 // jne 17 <normal> 1946 emit_opcode(cbuf, 0x75); 1947 emit_d8(cbuf, 0x08); 1948 1949 // xor %edx,%edx 1950 emit_opcode(cbuf, 0x33); 1951 emit_d8(cbuf, 0xD2); 1952 1953 // cmp $0xffffffffffffffff,$div 1954 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1955 emit_opcode(cbuf, 0x83); 1956 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1957 emit_d8(cbuf, 0xFF); 1958 1959 // je 1e <done> 1960 emit_opcode(cbuf, 0x74); 1961 emit_d8(cbuf, 0x05); 1962 1963 // <normal> 1964 // cqto 1965 emit_opcode(cbuf, Assembler::REX_W); 1966 emit_opcode(cbuf, 0x99); 1967 1968 // idivq (note: must be emitted by the user of this rule) 1969 // <done> 1970 %} 1971 1972 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1973 enc_class OpcSE(immI imm) 1974 %{ 1975 // Emit primary opcode and set sign-extend bit 1976 // Check for 8-bit immediate, and set sign extend bit in opcode 1977 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1978 emit_opcode(cbuf, $primary | 0x02); 1979 } else { 1980 // 32-bit immediate 1981 emit_opcode(cbuf, $primary); 1982 } 1983 %} 1984 1985 enc_class OpcSErm(rRegI dst, immI imm) 1986 %{ 1987 // OpcSEr/m 1988 int dstenc = $dst$$reg; 1989 if (dstenc >= 8) { 1990 emit_opcode(cbuf, Assembler::REX_B); 1991 dstenc -= 8; 1992 } 1993 // Emit primary opcode and set sign-extend bit 1994 // Check for 8-bit immediate, and set sign extend bit in opcode 1995 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1996 emit_opcode(cbuf, $primary | 0x02); 1997 } else { 1998 // 32-bit immediate 1999 emit_opcode(cbuf, $primary); 2000 } 2001 // Emit r/m byte with secondary opcode, after primary opcode. 2002 emit_rm(cbuf, 0x3, $secondary, dstenc); 2003 %} 2004 2005 enc_class OpcSErm_wide(rRegL dst, immI imm) 2006 %{ 2007 // OpcSEr/m 2008 int dstenc = $dst$$reg; 2009 if (dstenc < 8) { 2010 emit_opcode(cbuf, Assembler::REX_W); 2011 } else { 2012 emit_opcode(cbuf, Assembler::REX_WB); 2013 dstenc -= 8; 2014 } 2015 // Emit primary opcode and set sign-extend bit 2016 // Check for 8-bit immediate, and set sign extend bit in opcode 2017 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2018 emit_opcode(cbuf, $primary | 0x02); 2019 } else { 2020 // 32-bit immediate 2021 emit_opcode(cbuf, $primary); 2022 } 2023 // Emit r/m byte with secondary opcode, after primary opcode. 2024 emit_rm(cbuf, 0x3, $secondary, dstenc); 2025 %} 2026 2027 enc_class Con8or32(immI imm) 2028 %{ 2029 // Check for 8-bit immediate, and set sign extend bit in opcode 2030 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2031 $$$emit8$imm$$constant; 2032 } else { 2033 // 32-bit immediate 2034 $$$emit32$imm$$constant; 2035 } 2036 %} 2037 2038 enc_class opc2_reg(rRegI dst) 2039 %{ 2040 // BSWAP 2041 emit_cc(cbuf, $secondary, $dst$$reg); 2042 %} 2043 2044 enc_class opc3_reg(rRegI dst) 2045 %{ 2046 // BSWAP 2047 emit_cc(cbuf, $tertiary, $dst$$reg); 2048 %} 2049 2050 enc_class reg_opc(rRegI div) 2051 %{ 2052 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2053 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2054 %} 2055 2056 enc_class enc_cmov(cmpOp cop) 2057 %{ 2058 // CMOV 2059 $$$emit8$primary; 2060 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2061 %} 2062 2063 enc_class enc_PartialSubtypeCheck() 2064 %{ 2065 Register Rrdi = as_Register(RDI_enc); // result register 2066 Register Rrax = as_Register(RAX_enc); // super class 2067 Register Rrcx = as_Register(RCX_enc); // killed 2068 Register Rrsi = as_Register(RSI_enc); // sub class 2069 Label miss; 2070 const bool set_cond_codes = true; 2071 2072 MacroAssembler _masm(&cbuf); 2073 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2074 NULL, &miss, 2075 /*set_cond_codes:*/ true); 2076 if ($primary) { 2077 __ xorptr(Rrdi, Rrdi); 2078 } 2079 __ bind(miss); 2080 %} 2081 2082 enc_class clear_avx %{ 2083 debug_only(int off0 = cbuf.insts_size()); 2084 if (ra_->C->max_vector_size() > 16) { 2085 // Clear upper bits of YMM registers when current compiled code uses 2086 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2087 MacroAssembler _masm(&cbuf); 2088 __ vzeroupper(); 2089 } 2090 debug_only(int off1 = cbuf.insts_size()); 2091 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2092 %} 2093 2094 enc_class Java_To_Runtime(method meth) %{ 2095 // No relocation needed 2096 MacroAssembler _masm(&cbuf); 2097 __ mov64(r10, (int64_t) $meth$$method); 2098 __ call(r10); 2099 %} 2100 2101 enc_class Java_To_Interpreter(method meth) 2102 %{ 2103 // CALL Java_To_Interpreter 2104 // This is the instruction starting address for relocation info. 2105 cbuf.set_insts_mark(); 2106 $$$emit8$primary; 2107 // CALL directly to the runtime 2108 emit_d32_reloc(cbuf, 2109 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2110 runtime_call_Relocation::spec(), 2111 RELOC_DISP32); 2112 %} 2113 2114 enc_class Java_Static_Call(method meth) 2115 %{ 2116 // JAVA STATIC CALL 2117 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2118 // determine who we intended to call. 2119 cbuf.set_insts_mark(); 2120 $$$emit8$primary; 2121 2122 if (!_method) { 2123 emit_d32_reloc(cbuf, 2124 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2125 runtime_call_Relocation::spec(), 2126 RELOC_DISP32); 2127 } else if (_optimized_virtual) { 2128 emit_d32_reloc(cbuf, 2129 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2130 opt_virtual_call_Relocation::spec(), 2131 RELOC_DISP32); 2132 } else { 2133 emit_d32_reloc(cbuf, 2134 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2135 static_call_Relocation::spec(), 2136 RELOC_DISP32); 2137 } 2138 if (_method) { 2139 // Emit stub for static call. 2140 CompiledStaticCall::emit_to_interp_stub(cbuf); 2141 } 2142 %} 2143 2144 enc_class Java_Dynamic_Call(method meth) %{ 2145 MacroAssembler _masm(&cbuf); 2146 __ ic_call((address)$meth$$method); 2147 %} 2148 2149 enc_class Java_Compiled_Call(method meth) 2150 %{ 2151 // JAVA COMPILED CALL 2152 int disp = in_bytes(Method:: from_compiled_offset()); 2153 2154 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2155 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2156 2157 // callq *disp(%rax) 2158 cbuf.set_insts_mark(); 2159 $$$emit8$primary; 2160 if (disp < 0x80) { 2161 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2162 emit_d8(cbuf, disp); // Displacement 2163 } else { 2164 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2165 emit_d32(cbuf, disp); // Displacement 2166 } 2167 %} 2168 2169 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2170 %{ 2171 // SAL, SAR, SHR 2172 int dstenc = $dst$$reg; 2173 if (dstenc >= 8) { 2174 emit_opcode(cbuf, Assembler::REX_B); 2175 dstenc -= 8; 2176 } 2177 $$$emit8$primary; 2178 emit_rm(cbuf, 0x3, $secondary, dstenc); 2179 $$$emit8$shift$$constant; 2180 %} 2181 2182 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2183 %{ 2184 // SAL, SAR, SHR 2185 int dstenc = $dst$$reg; 2186 if (dstenc < 8) { 2187 emit_opcode(cbuf, Assembler::REX_W); 2188 } else { 2189 emit_opcode(cbuf, Assembler::REX_WB); 2190 dstenc -= 8; 2191 } 2192 $$$emit8$primary; 2193 emit_rm(cbuf, 0x3, $secondary, dstenc); 2194 $$$emit8$shift$$constant; 2195 %} 2196 2197 enc_class load_immI(rRegI dst, immI src) 2198 %{ 2199 int dstenc = $dst$$reg; 2200 if (dstenc >= 8) { 2201 emit_opcode(cbuf, Assembler::REX_B); 2202 dstenc -= 8; 2203 } 2204 emit_opcode(cbuf, 0xB8 | dstenc); 2205 $$$emit32$src$$constant; 2206 %} 2207 2208 enc_class load_immL(rRegL dst, immL src) 2209 %{ 2210 int dstenc = $dst$$reg; 2211 if (dstenc < 8) { 2212 emit_opcode(cbuf, Assembler::REX_W); 2213 } else { 2214 emit_opcode(cbuf, Assembler::REX_WB); 2215 dstenc -= 8; 2216 } 2217 emit_opcode(cbuf, 0xB8 | dstenc); 2218 emit_d64(cbuf, $src$$constant); 2219 %} 2220 2221 enc_class load_immUL32(rRegL dst, immUL32 src) 2222 %{ 2223 // same as load_immI, but this time we care about zeroes in the high word 2224 int dstenc = $dst$$reg; 2225 if (dstenc >= 8) { 2226 emit_opcode(cbuf, Assembler::REX_B); 2227 dstenc -= 8; 2228 } 2229 emit_opcode(cbuf, 0xB8 | dstenc); 2230 $$$emit32$src$$constant; 2231 %} 2232 2233 enc_class load_immL32(rRegL dst, immL32 src) 2234 %{ 2235 int dstenc = $dst$$reg; 2236 if (dstenc < 8) { 2237 emit_opcode(cbuf, Assembler::REX_W); 2238 } else { 2239 emit_opcode(cbuf, Assembler::REX_WB); 2240 dstenc -= 8; 2241 } 2242 emit_opcode(cbuf, 0xC7); 2243 emit_rm(cbuf, 0x03, 0x00, dstenc); 2244 $$$emit32$src$$constant; 2245 %} 2246 2247 enc_class load_immP31(rRegP dst, immP32 src) 2248 %{ 2249 // same as load_immI, but this time we care about zeroes in the high word 2250 int dstenc = $dst$$reg; 2251 if (dstenc >= 8) { 2252 emit_opcode(cbuf, Assembler::REX_B); 2253 dstenc -= 8; 2254 } 2255 emit_opcode(cbuf, 0xB8 | dstenc); 2256 $$$emit32$src$$constant; 2257 %} 2258 2259 enc_class load_immP(rRegP dst, immP src) 2260 %{ 2261 int dstenc = $dst$$reg; 2262 if (dstenc < 8) { 2263 emit_opcode(cbuf, Assembler::REX_W); 2264 } else { 2265 emit_opcode(cbuf, Assembler::REX_WB); 2266 dstenc -= 8; 2267 } 2268 emit_opcode(cbuf, 0xB8 | dstenc); 2269 // This next line should be generated from ADLC 2270 if ($src->constant_reloc() != relocInfo::none) { 2271 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2272 } else { 2273 emit_d64(cbuf, $src$$constant); 2274 } 2275 %} 2276 2277 enc_class Con32(immI src) 2278 %{ 2279 // Output immediate 2280 $$$emit32$src$$constant; 2281 %} 2282 2283 enc_class Con32F_as_bits(immF src) 2284 %{ 2285 // Output Float immediate bits 2286 jfloat jf = $src$$constant; 2287 jint jf_as_bits = jint_cast(jf); 2288 emit_d32(cbuf, jf_as_bits); 2289 %} 2290 2291 enc_class Con16(immI src) 2292 %{ 2293 // Output immediate 2294 $$$emit16$src$$constant; 2295 %} 2296 2297 // How is this different from Con32??? XXX 2298 enc_class Con_d32(immI src) 2299 %{ 2300 emit_d32(cbuf,$src$$constant); 2301 %} 2302 2303 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2304 // Output immediate memory reference 2305 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2306 emit_d32(cbuf, 0x00); 2307 %} 2308 2309 enc_class lock_prefix() 2310 %{ 2311 if (os::is_MP()) { 2312 emit_opcode(cbuf, 0xF0); // lock 2313 } 2314 %} 2315 2316 enc_class REX_mem(memory mem) 2317 %{ 2318 if ($mem$$base >= 8) { 2319 if ($mem$$index < 8) { 2320 emit_opcode(cbuf, Assembler::REX_B); 2321 } else { 2322 emit_opcode(cbuf, Assembler::REX_XB); 2323 } 2324 } else { 2325 if ($mem$$index >= 8) { 2326 emit_opcode(cbuf, Assembler::REX_X); 2327 } 2328 } 2329 %} 2330 2331 enc_class REX_mem_wide(memory mem) 2332 %{ 2333 if ($mem$$base >= 8) { 2334 if ($mem$$index < 8) { 2335 emit_opcode(cbuf, Assembler::REX_WB); 2336 } else { 2337 emit_opcode(cbuf, Assembler::REX_WXB); 2338 } 2339 } else { 2340 if ($mem$$index < 8) { 2341 emit_opcode(cbuf, Assembler::REX_W); 2342 } else { 2343 emit_opcode(cbuf, Assembler::REX_WX); 2344 } 2345 } 2346 %} 2347 2348 // for byte regs 2349 enc_class REX_breg(rRegI reg) 2350 %{ 2351 if ($reg$$reg >= 4) { 2352 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2353 } 2354 %} 2355 2356 // for byte regs 2357 enc_class REX_reg_breg(rRegI dst, rRegI src) 2358 %{ 2359 if ($dst$$reg < 8) { 2360 if ($src$$reg >= 4) { 2361 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2362 } 2363 } else { 2364 if ($src$$reg < 8) { 2365 emit_opcode(cbuf, Assembler::REX_R); 2366 } else { 2367 emit_opcode(cbuf, Assembler::REX_RB); 2368 } 2369 } 2370 %} 2371 2372 // for byte regs 2373 enc_class REX_breg_mem(rRegI reg, memory mem) 2374 %{ 2375 if ($reg$$reg < 8) { 2376 if ($mem$$base < 8) { 2377 if ($mem$$index >= 8) { 2378 emit_opcode(cbuf, Assembler::REX_X); 2379 } else if ($reg$$reg >= 4) { 2380 emit_opcode(cbuf, Assembler::REX); 2381 } 2382 } else { 2383 if ($mem$$index < 8) { 2384 emit_opcode(cbuf, Assembler::REX_B); 2385 } else { 2386 emit_opcode(cbuf, Assembler::REX_XB); 2387 } 2388 } 2389 } else { 2390 if ($mem$$base < 8) { 2391 if ($mem$$index < 8) { 2392 emit_opcode(cbuf, Assembler::REX_R); 2393 } else { 2394 emit_opcode(cbuf, Assembler::REX_RX); 2395 } 2396 } else { 2397 if ($mem$$index < 8) { 2398 emit_opcode(cbuf, Assembler::REX_RB); 2399 } else { 2400 emit_opcode(cbuf, Assembler::REX_RXB); 2401 } 2402 } 2403 } 2404 %} 2405 2406 enc_class REX_reg(rRegI reg) 2407 %{ 2408 if ($reg$$reg >= 8) { 2409 emit_opcode(cbuf, Assembler::REX_B); 2410 } 2411 %} 2412 2413 enc_class REX_reg_wide(rRegI reg) 2414 %{ 2415 if ($reg$$reg < 8) { 2416 emit_opcode(cbuf, Assembler::REX_W); 2417 } else { 2418 emit_opcode(cbuf, Assembler::REX_WB); 2419 } 2420 %} 2421 2422 enc_class REX_reg_reg(rRegI dst, rRegI src) 2423 %{ 2424 if ($dst$$reg < 8) { 2425 if ($src$$reg >= 8) { 2426 emit_opcode(cbuf, Assembler::REX_B); 2427 } 2428 } else { 2429 if ($src$$reg < 8) { 2430 emit_opcode(cbuf, Assembler::REX_R); 2431 } else { 2432 emit_opcode(cbuf, Assembler::REX_RB); 2433 } 2434 } 2435 %} 2436 2437 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2438 %{ 2439 if ($dst$$reg < 8) { 2440 if ($src$$reg < 8) { 2441 emit_opcode(cbuf, Assembler::REX_W); 2442 } else { 2443 emit_opcode(cbuf, Assembler::REX_WB); 2444 } 2445 } else { 2446 if ($src$$reg < 8) { 2447 emit_opcode(cbuf, Assembler::REX_WR); 2448 } else { 2449 emit_opcode(cbuf, Assembler::REX_WRB); 2450 } 2451 } 2452 %} 2453 2454 enc_class REX_reg_mem(rRegI reg, memory mem) 2455 %{ 2456 if ($reg$$reg < 8) { 2457 if ($mem$$base < 8) { 2458 if ($mem$$index >= 8) { 2459 emit_opcode(cbuf, Assembler::REX_X); 2460 } 2461 } else { 2462 if ($mem$$index < 8) { 2463 emit_opcode(cbuf, Assembler::REX_B); 2464 } else { 2465 emit_opcode(cbuf, Assembler::REX_XB); 2466 } 2467 } 2468 } else { 2469 if ($mem$$base < 8) { 2470 if ($mem$$index < 8) { 2471 emit_opcode(cbuf, Assembler::REX_R); 2472 } else { 2473 emit_opcode(cbuf, Assembler::REX_RX); 2474 } 2475 } else { 2476 if ($mem$$index < 8) { 2477 emit_opcode(cbuf, Assembler::REX_RB); 2478 } else { 2479 emit_opcode(cbuf, Assembler::REX_RXB); 2480 } 2481 } 2482 } 2483 %} 2484 2485 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2486 %{ 2487 if ($reg$$reg < 8) { 2488 if ($mem$$base < 8) { 2489 if ($mem$$index < 8) { 2490 emit_opcode(cbuf, Assembler::REX_W); 2491 } else { 2492 emit_opcode(cbuf, Assembler::REX_WX); 2493 } 2494 } else { 2495 if ($mem$$index < 8) { 2496 emit_opcode(cbuf, Assembler::REX_WB); 2497 } else { 2498 emit_opcode(cbuf, Assembler::REX_WXB); 2499 } 2500 } 2501 } else { 2502 if ($mem$$base < 8) { 2503 if ($mem$$index < 8) { 2504 emit_opcode(cbuf, Assembler::REX_WR); 2505 } else { 2506 emit_opcode(cbuf, Assembler::REX_WRX); 2507 } 2508 } else { 2509 if ($mem$$index < 8) { 2510 emit_opcode(cbuf, Assembler::REX_WRB); 2511 } else { 2512 emit_opcode(cbuf, Assembler::REX_WRXB); 2513 } 2514 } 2515 } 2516 %} 2517 2518 enc_class reg_mem(rRegI ereg, memory mem) 2519 %{ 2520 // High registers handle in encode_RegMem 2521 int reg = $ereg$$reg; 2522 int base = $mem$$base; 2523 int index = $mem$$index; 2524 int scale = $mem$$scale; 2525 int disp = $mem$$disp; 2526 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2527 2528 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2529 %} 2530 2531 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2532 %{ 2533 int rm_byte_opcode = $rm_opcode$$constant; 2534 2535 // High registers handle in encode_RegMem 2536 int base = $mem$$base; 2537 int index = $mem$$index; 2538 int scale = $mem$$scale; 2539 int displace = $mem$$disp; 2540 2541 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2542 // working with static 2543 // globals 2544 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2545 disp_reloc); 2546 %} 2547 2548 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2549 %{ 2550 int reg_encoding = $dst$$reg; 2551 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2552 int index = 0x04; // 0x04 indicates no index 2553 int scale = 0x00; // 0x00 indicates no scale 2554 int displace = $src1$$constant; // 0x00 indicates no displacement 2555 relocInfo::relocType disp_reloc = relocInfo::none; 2556 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2557 disp_reloc); 2558 %} 2559 2560 enc_class neg_reg(rRegI dst) 2561 %{ 2562 int dstenc = $dst$$reg; 2563 if (dstenc >= 8) { 2564 emit_opcode(cbuf, Assembler::REX_B); 2565 dstenc -= 8; 2566 } 2567 // NEG $dst 2568 emit_opcode(cbuf, 0xF7); 2569 emit_rm(cbuf, 0x3, 0x03, dstenc); 2570 %} 2571 2572 enc_class neg_reg_wide(rRegI dst) 2573 %{ 2574 int dstenc = $dst$$reg; 2575 if (dstenc < 8) { 2576 emit_opcode(cbuf, Assembler::REX_W); 2577 } else { 2578 emit_opcode(cbuf, Assembler::REX_WB); 2579 dstenc -= 8; 2580 } 2581 // NEG $dst 2582 emit_opcode(cbuf, 0xF7); 2583 emit_rm(cbuf, 0x3, 0x03, dstenc); 2584 %} 2585 2586 enc_class setLT_reg(rRegI dst) 2587 %{ 2588 int dstenc = $dst$$reg; 2589 if (dstenc >= 8) { 2590 emit_opcode(cbuf, Assembler::REX_B); 2591 dstenc -= 8; 2592 } else if (dstenc >= 4) { 2593 emit_opcode(cbuf, Assembler::REX); 2594 } 2595 // SETLT $dst 2596 emit_opcode(cbuf, 0x0F); 2597 emit_opcode(cbuf, 0x9C); 2598 emit_rm(cbuf, 0x3, 0x0, dstenc); 2599 %} 2600 2601 enc_class setNZ_reg(rRegI dst) 2602 %{ 2603 int dstenc = $dst$$reg; 2604 if (dstenc >= 8) { 2605 emit_opcode(cbuf, Assembler::REX_B); 2606 dstenc -= 8; 2607 } else if (dstenc >= 4) { 2608 emit_opcode(cbuf, Assembler::REX); 2609 } 2610 // SETNZ $dst 2611 emit_opcode(cbuf, 0x0F); 2612 emit_opcode(cbuf, 0x95); 2613 emit_rm(cbuf, 0x3, 0x0, dstenc); 2614 %} 2615 2616 2617 // Compare the lonogs and set -1, 0, or 1 into dst 2618 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2619 %{ 2620 int src1enc = $src1$$reg; 2621 int src2enc = $src2$$reg; 2622 int dstenc = $dst$$reg; 2623 2624 // cmpq $src1, $src2 2625 if (src1enc < 8) { 2626 if (src2enc < 8) { 2627 emit_opcode(cbuf, Assembler::REX_W); 2628 } else { 2629 emit_opcode(cbuf, Assembler::REX_WB); 2630 } 2631 } else { 2632 if (src2enc < 8) { 2633 emit_opcode(cbuf, Assembler::REX_WR); 2634 } else { 2635 emit_opcode(cbuf, Assembler::REX_WRB); 2636 } 2637 } 2638 emit_opcode(cbuf, 0x3B); 2639 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2640 2641 // movl $dst, -1 2642 if (dstenc >= 8) { 2643 emit_opcode(cbuf, Assembler::REX_B); 2644 } 2645 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2646 emit_d32(cbuf, -1); 2647 2648 // jl,s done 2649 emit_opcode(cbuf, 0x7C); 2650 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2651 2652 // setne $dst 2653 if (dstenc >= 4) { 2654 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2655 } 2656 emit_opcode(cbuf, 0x0F); 2657 emit_opcode(cbuf, 0x95); 2658 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2659 2660 // movzbl $dst, $dst 2661 if (dstenc >= 4) { 2662 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2663 } 2664 emit_opcode(cbuf, 0x0F); 2665 emit_opcode(cbuf, 0xB6); 2666 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2667 %} 2668 2669 enc_class Push_ResultXD(regD dst) %{ 2670 MacroAssembler _masm(&cbuf); 2671 __ fstp_d(Address(rsp, 0)); 2672 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2673 __ addptr(rsp, 8); 2674 %} 2675 2676 enc_class Push_SrcXD(regD src) %{ 2677 MacroAssembler _masm(&cbuf); 2678 __ subptr(rsp, 8); 2679 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2680 __ fld_d(Address(rsp, 0)); 2681 %} 2682 2683 2684 enc_class enc_rethrow() 2685 %{ 2686 cbuf.set_insts_mark(); 2687 emit_opcode(cbuf, 0xE9); // jmp entry 2688 emit_d32_reloc(cbuf, 2689 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2690 runtime_call_Relocation::spec(), 2691 RELOC_DISP32); 2692 %} 2693 2694 %} 2695 2696 2697 2698 //----------FRAME-------------------------------------------------------------- 2699 // Definition of frame structure and management information. 2700 // 2701 // S T A C K L A Y O U T Allocators stack-slot number 2702 // | (to get allocators register number 2703 // G Owned by | | v add OptoReg::stack0()) 2704 // r CALLER | | 2705 // o | +--------+ pad to even-align allocators stack-slot 2706 // w V | pad0 | numbers; owned by CALLER 2707 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2708 // h ^ | in | 5 2709 // | | args | 4 Holes in incoming args owned by SELF 2710 // | | | | 3 2711 // | | +--------+ 2712 // V | | old out| Empty on Intel, window on Sparc 2713 // | old |preserve| Must be even aligned. 2714 // | SP-+--------+----> Matcher::_old_SP, even aligned 2715 // | | in | 3 area for Intel ret address 2716 // Owned by |preserve| Empty on Sparc. 2717 // SELF +--------+ 2718 // | | pad2 | 2 pad to align old SP 2719 // | +--------+ 1 2720 // | | locks | 0 2721 // | +--------+----> OptoReg::stack0(), even aligned 2722 // | | pad1 | 11 pad to align new SP 2723 // | +--------+ 2724 // | | | 10 2725 // | | spills | 9 spills 2726 // V | | 8 (pad0 slot for callee) 2727 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2728 // ^ | out | 7 2729 // | | args | 6 Holes in outgoing args owned by CALLEE 2730 // Owned by +--------+ 2731 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2732 // | new |preserve| Must be even-aligned. 2733 // | SP-+--------+----> Matcher::_new_SP, even aligned 2734 // | | | 2735 // 2736 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2737 // known from SELF's arguments and the Java calling convention. 2738 // Region 6-7 is determined per call site. 2739 // Note 2: If the calling convention leaves holes in the incoming argument 2740 // area, those holes are owned by SELF. Holes in the outgoing area 2741 // are owned by the CALLEE. Holes should not be nessecary in the 2742 // incoming area, as the Java calling convention is completely under 2743 // the control of the AD file. Doubles can be sorted and packed to 2744 // avoid holes. Holes in the outgoing arguments may be nessecary for 2745 // varargs C calling conventions. 2746 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2747 // even aligned with pad0 as needed. 2748 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2749 // region 6-11 is even aligned; it may be padded out more so that 2750 // the region from SP to FP meets the minimum stack alignment. 2751 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2752 // alignment. Region 11, pad1, may be dynamically extended so that 2753 // SP meets the minimum alignment. 2754 2755 frame 2756 %{ 2757 // What direction does stack grow in (assumed to be same for C & Java) 2758 stack_direction(TOWARDS_LOW); 2759 2760 // These three registers define part of the calling convention 2761 // between compiled code and the interpreter. 2762 inline_cache_reg(RAX); // Inline Cache Register 2763 interpreter_method_oop_reg(RBX); // Method Oop Register when 2764 // calling interpreter 2765 2766 // Optional: name the operand used by cisc-spilling to access 2767 // [stack_pointer + offset] 2768 cisc_spilling_operand_name(indOffset32); 2769 2770 // Number of stack slots consumed by locking an object 2771 sync_stack_slots(2); 2772 2773 // Compiled code's Frame Pointer 2774 frame_pointer(RSP); 2775 2776 // Interpreter stores its frame pointer in a register which is 2777 // stored to the stack by I2CAdaptors. 2778 // I2CAdaptors convert from interpreted java to compiled java. 2779 interpreter_frame_pointer(RBP); 2780 2781 // Stack alignment requirement 2782 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2783 2784 // Number of stack slots between incoming argument block and the start of 2785 // a new frame. The PROLOG must add this many slots to the stack. The 2786 // EPILOG must remove this many slots. amd64 needs two slots for 2787 // return address. 2788 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2789 2790 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2791 // for calls to C. Supports the var-args backing area for register parms. 2792 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2793 2794 // The after-PROLOG location of the return address. Location of 2795 // return address specifies a type (REG or STACK) and a number 2796 // representing the register number (i.e. - use a register name) or 2797 // stack slot. 2798 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2799 // Otherwise, it is above the locks and verification slot and alignment word 2800 return_addr(STACK - 2 + 2801 round_to((Compile::current()->in_preserve_stack_slots() + 2802 Compile::current()->fixed_slots()), 2803 stack_alignment_in_slots())); 2804 2805 // Body of function which returns an integer array locating 2806 // arguments either in registers or in stack slots. Passed an array 2807 // of ideal registers called "sig" and a "length" count. Stack-slot 2808 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2809 // arguments for a CALLEE. Incoming stack arguments are 2810 // automatically biased by the preserve_stack_slots field above. 2811 2812 calling_convention 2813 %{ 2814 // No difference between ingoing/outgoing just pass false 2815 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2816 %} 2817 2818 c_calling_convention 2819 %{ 2820 // This is obviously always outgoing 2821 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2822 %} 2823 2824 // Location of compiled Java return values. Same as C for now. 2825 return_value 2826 %{ 2827 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2828 "only return normal values"); 2829 2830 static const int lo[Op_RegL + 1] = { 2831 0, 2832 0, 2833 RAX_num, // Op_RegN 2834 RAX_num, // Op_RegI 2835 RAX_num, // Op_RegP 2836 XMM0_num, // Op_RegF 2837 XMM0_num, // Op_RegD 2838 RAX_num // Op_RegL 2839 }; 2840 static const int hi[Op_RegL + 1] = { 2841 0, 2842 0, 2843 OptoReg::Bad, // Op_RegN 2844 OptoReg::Bad, // Op_RegI 2845 RAX_H_num, // Op_RegP 2846 OptoReg::Bad, // Op_RegF 2847 XMM0b_num, // Op_RegD 2848 RAX_H_num // Op_RegL 2849 }; 2850 // Excluded flags and vector registers. 2851 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2852 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2853 %} 2854 %} 2855 2856 //----------ATTRIBUTES--------------------------------------------------------- 2857 //----------Operand Attributes------------------------------------------------- 2858 op_attrib op_cost(0); // Required cost attribute 2859 2860 //----------Instruction Attributes--------------------------------------------- 2861 ins_attrib ins_cost(100); // Required cost attribute 2862 ins_attrib ins_size(8); // Required size attribute (in bits) 2863 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2864 // a non-matching short branch variant 2865 // of some long branch? 2866 ins_attrib ins_alignment(1); // Required alignment attribute (must 2867 // be a power of 2) specifies the 2868 // alignment that some part of the 2869 // instruction (not necessarily the 2870 // start) requires. If > 1, a 2871 // compute_padding() function must be 2872 // provided for the instruction 2873 2874 //----------OPERANDS----------------------------------------------------------- 2875 // Operand definitions must precede instruction definitions for correct parsing 2876 // in the ADLC because operands constitute user defined types which are used in 2877 // instruction definitions. 2878 2879 //----------Simple Operands---------------------------------------------------- 2880 // Immediate Operands 2881 // Integer Immediate 2882 operand immI() 2883 %{ 2884 match(ConI); 2885 2886 op_cost(10); 2887 format %{ %} 2888 interface(CONST_INTER); 2889 %} 2890 2891 // Constant for test vs zero 2892 operand immI0() 2893 %{ 2894 predicate(n->get_int() == 0); 2895 match(ConI); 2896 2897 op_cost(0); 2898 format %{ %} 2899 interface(CONST_INTER); 2900 %} 2901 2902 // Constant for increment 2903 operand immI1() 2904 %{ 2905 predicate(n->get_int() == 1); 2906 match(ConI); 2907 2908 op_cost(0); 2909 format %{ %} 2910 interface(CONST_INTER); 2911 %} 2912 2913 // Constant for decrement 2914 operand immI_M1() 2915 %{ 2916 predicate(n->get_int() == -1); 2917 match(ConI); 2918 2919 op_cost(0); 2920 format %{ %} 2921 interface(CONST_INTER); 2922 %} 2923 2924 // Valid scale values for addressing modes 2925 operand immI2() 2926 %{ 2927 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2928 match(ConI); 2929 2930 format %{ %} 2931 interface(CONST_INTER); 2932 %} 2933 2934 operand immI8() 2935 %{ 2936 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2937 match(ConI); 2938 2939 op_cost(5); 2940 format %{ %} 2941 interface(CONST_INTER); 2942 %} 2943 2944 operand immI16() 2945 %{ 2946 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2947 match(ConI); 2948 2949 op_cost(10); 2950 format %{ %} 2951 interface(CONST_INTER); 2952 %} 2953 2954 // Int Immediate non-negative 2955 operand immU31() 2956 %{ 2957 predicate(n->get_int() >= 0); 2958 match(ConI); 2959 2960 op_cost(0); 2961 format %{ %} 2962 interface(CONST_INTER); 2963 %} 2964 2965 // Constant for long shifts 2966 operand immI_32() 2967 %{ 2968 predicate( n->get_int() == 32 ); 2969 match(ConI); 2970 2971 op_cost(0); 2972 format %{ %} 2973 interface(CONST_INTER); 2974 %} 2975 2976 // Constant for long shifts 2977 operand immI_64() 2978 %{ 2979 predicate( n->get_int() == 64 ); 2980 match(ConI); 2981 2982 op_cost(0); 2983 format %{ %} 2984 interface(CONST_INTER); 2985 %} 2986 2987 // Pointer Immediate 2988 operand immP() 2989 %{ 2990 match(ConP); 2991 2992 op_cost(10); 2993 format %{ %} 2994 interface(CONST_INTER); 2995 %} 2996 2997 // NULL Pointer Immediate 2998 operand immP0() 2999 %{ 3000 predicate(n->get_ptr() == 0); 3001 match(ConP); 3002 3003 op_cost(5); 3004 format %{ %} 3005 interface(CONST_INTER); 3006 %} 3007 3008 // Pointer Immediate 3009 operand immN() %{ 3010 match(ConN); 3011 3012 op_cost(10); 3013 format %{ %} 3014 interface(CONST_INTER); 3015 %} 3016 3017 operand immNKlass() %{ 3018 match(ConNKlass); 3019 3020 op_cost(10); 3021 format %{ %} 3022 interface(CONST_INTER); 3023 %} 3024 3025 // NULL Pointer Immediate 3026 operand immN0() %{ 3027 predicate(n->get_narrowcon() == 0); 3028 match(ConN); 3029 3030 op_cost(5); 3031 format %{ %} 3032 interface(CONST_INTER); 3033 %} 3034 3035 operand immP31() 3036 %{ 3037 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3038 && (n->get_ptr() >> 31) == 0); 3039 match(ConP); 3040 3041 op_cost(5); 3042 format %{ %} 3043 interface(CONST_INTER); 3044 %} 3045 3046 3047 // Long Immediate 3048 operand immL() 3049 %{ 3050 match(ConL); 3051 3052 op_cost(20); 3053 format %{ %} 3054 interface(CONST_INTER); 3055 %} 3056 3057 // Long Immediate 8-bit 3058 operand immL8() 3059 %{ 3060 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3061 match(ConL); 3062 3063 op_cost(5); 3064 format %{ %} 3065 interface(CONST_INTER); 3066 %} 3067 3068 // Long Immediate 32-bit unsigned 3069 operand immUL32() 3070 %{ 3071 predicate(n->get_long() == (unsigned int) (n->get_long())); 3072 match(ConL); 3073 3074 op_cost(10); 3075 format %{ %} 3076 interface(CONST_INTER); 3077 %} 3078 3079 // Long Immediate 32-bit signed 3080 operand immL32() 3081 %{ 3082 predicate(n->get_long() == (int) (n->get_long())); 3083 match(ConL); 3084 3085 op_cost(15); 3086 format %{ %} 3087 interface(CONST_INTER); 3088 %} 3089 3090 // Long Immediate zero 3091 operand immL0() 3092 %{ 3093 predicate(n->get_long() == 0L); 3094 match(ConL); 3095 3096 op_cost(10); 3097 format %{ %} 3098 interface(CONST_INTER); 3099 %} 3100 3101 // Constant for increment 3102 operand immL1() 3103 %{ 3104 predicate(n->get_long() == 1); 3105 match(ConL); 3106 3107 format %{ %} 3108 interface(CONST_INTER); 3109 %} 3110 3111 // Constant for decrement 3112 operand immL_M1() 3113 %{ 3114 predicate(n->get_long() == -1); 3115 match(ConL); 3116 3117 format %{ %} 3118 interface(CONST_INTER); 3119 %} 3120 3121 // Long Immediate: the value 10 3122 operand immL10() 3123 %{ 3124 predicate(n->get_long() == 10); 3125 match(ConL); 3126 3127 format %{ %} 3128 interface(CONST_INTER); 3129 %} 3130 3131 // Long immediate from 0 to 127. 3132 // Used for a shorter form of long mul by 10. 3133 operand immL_127() 3134 %{ 3135 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3136 match(ConL); 3137 3138 op_cost(10); 3139 format %{ %} 3140 interface(CONST_INTER); 3141 %} 3142 3143 // Long Immediate: low 32-bit mask 3144 operand immL_32bits() 3145 %{ 3146 predicate(n->get_long() == 0xFFFFFFFFL); 3147 match(ConL); 3148 op_cost(20); 3149 3150 format %{ %} 3151 interface(CONST_INTER); 3152 %} 3153 3154 // Float Immediate zero 3155 operand immF0() 3156 %{ 3157 predicate(jint_cast(n->getf()) == 0); 3158 match(ConF); 3159 3160 op_cost(5); 3161 format %{ %} 3162 interface(CONST_INTER); 3163 %} 3164 3165 // Float Immediate 3166 operand immF() 3167 %{ 3168 match(ConF); 3169 3170 op_cost(15); 3171 format %{ %} 3172 interface(CONST_INTER); 3173 %} 3174 3175 // Double Immediate zero 3176 operand immD0() 3177 %{ 3178 predicate(jlong_cast(n->getd()) == 0); 3179 match(ConD); 3180 3181 op_cost(5); 3182 format %{ %} 3183 interface(CONST_INTER); 3184 %} 3185 3186 // Double Immediate 3187 operand immD() 3188 %{ 3189 match(ConD); 3190 3191 op_cost(15); 3192 format %{ %} 3193 interface(CONST_INTER); 3194 %} 3195 3196 // Immediates for special shifts (sign extend) 3197 3198 // Constants for increment 3199 operand immI_16() 3200 %{ 3201 predicate(n->get_int() == 16); 3202 match(ConI); 3203 3204 format %{ %} 3205 interface(CONST_INTER); 3206 %} 3207 3208 operand immI_24() 3209 %{ 3210 predicate(n->get_int() == 24); 3211 match(ConI); 3212 3213 format %{ %} 3214 interface(CONST_INTER); 3215 %} 3216 3217 // Constant for byte-wide masking 3218 operand immI_255() 3219 %{ 3220 predicate(n->get_int() == 255); 3221 match(ConI); 3222 3223 format %{ %} 3224 interface(CONST_INTER); 3225 %} 3226 3227 // Constant for short-wide masking 3228 operand immI_65535() 3229 %{ 3230 predicate(n->get_int() == 65535); 3231 match(ConI); 3232 3233 format %{ %} 3234 interface(CONST_INTER); 3235 %} 3236 3237 // Constant for byte-wide masking 3238 operand immL_255() 3239 %{ 3240 predicate(n->get_long() == 255); 3241 match(ConL); 3242 3243 format %{ %} 3244 interface(CONST_INTER); 3245 %} 3246 3247 // Constant for short-wide masking 3248 operand immL_65535() 3249 %{ 3250 predicate(n->get_long() == 65535); 3251 match(ConL); 3252 3253 format %{ %} 3254 interface(CONST_INTER); 3255 %} 3256 3257 // Register Operands 3258 // Integer Register 3259 operand rRegI() 3260 %{ 3261 constraint(ALLOC_IN_RC(int_reg)); 3262 match(RegI); 3263 3264 match(rax_RegI); 3265 match(rbx_RegI); 3266 match(rcx_RegI); 3267 match(rdx_RegI); 3268 match(rdi_RegI); 3269 3270 format %{ %} 3271 interface(REG_INTER); 3272 %} 3273 3274 // Special Registers 3275 operand rax_RegI() 3276 %{ 3277 constraint(ALLOC_IN_RC(int_rax_reg)); 3278 match(RegI); 3279 match(rRegI); 3280 3281 format %{ "RAX" %} 3282 interface(REG_INTER); 3283 %} 3284 3285 // Special Registers 3286 operand rbx_RegI() 3287 %{ 3288 constraint(ALLOC_IN_RC(int_rbx_reg)); 3289 match(RegI); 3290 match(rRegI); 3291 3292 format %{ "RBX" %} 3293 interface(REG_INTER); 3294 %} 3295 3296 operand rcx_RegI() 3297 %{ 3298 constraint(ALLOC_IN_RC(int_rcx_reg)); 3299 match(RegI); 3300 match(rRegI); 3301 3302 format %{ "RCX" %} 3303 interface(REG_INTER); 3304 %} 3305 3306 operand rdx_RegI() 3307 %{ 3308 constraint(ALLOC_IN_RC(int_rdx_reg)); 3309 match(RegI); 3310 match(rRegI); 3311 3312 format %{ "RDX" %} 3313 interface(REG_INTER); 3314 %} 3315 3316 operand rdi_RegI() 3317 %{ 3318 constraint(ALLOC_IN_RC(int_rdi_reg)); 3319 match(RegI); 3320 match(rRegI); 3321 3322 format %{ "RDI" %} 3323 interface(REG_INTER); 3324 %} 3325 3326 operand no_rcx_RegI() 3327 %{ 3328 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3329 match(RegI); 3330 match(rax_RegI); 3331 match(rbx_RegI); 3332 match(rdx_RegI); 3333 match(rdi_RegI); 3334 3335 format %{ %} 3336 interface(REG_INTER); 3337 %} 3338 3339 operand no_rax_rdx_RegI() 3340 %{ 3341 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3342 match(RegI); 3343 match(rbx_RegI); 3344 match(rcx_RegI); 3345 match(rdi_RegI); 3346 3347 format %{ %} 3348 interface(REG_INTER); 3349 %} 3350 3351 // Pointer Register 3352 operand any_RegP() 3353 %{ 3354 constraint(ALLOC_IN_RC(any_reg)); 3355 match(RegP); 3356 match(rax_RegP); 3357 match(rbx_RegP); 3358 match(rdi_RegP); 3359 match(rsi_RegP); 3360 match(rbp_RegP); 3361 match(r15_RegP); 3362 match(rRegP); 3363 3364 format %{ %} 3365 interface(REG_INTER); 3366 %} 3367 3368 operand rRegP() 3369 %{ 3370 constraint(ALLOC_IN_RC(ptr_reg)); 3371 match(RegP); 3372 match(rax_RegP); 3373 match(rbx_RegP); 3374 match(rdi_RegP); 3375 match(rsi_RegP); 3376 match(rbp_RegP); // See Q&A below about 3377 match(r15_RegP); // r15_RegP and rbp_RegP. 3378 3379 format %{ %} 3380 interface(REG_INTER); 3381 %} 3382 3383 operand rRegN() %{ 3384 constraint(ALLOC_IN_RC(int_reg)); 3385 match(RegN); 3386 3387 format %{ %} 3388 interface(REG_INTER); 3389 %} 3390 3391 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3392 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3393 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3394 // The output of an instruction is controlled by the allocator, which respects 3395 // register class masks, not match rules. Unless an instruction mentions 3396 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3397 // by the allocator as an input. 3398 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3399 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3400 // result, RBP is not included in the output of the instruction either. 3401 3402 operand no_rax_RegP() 3403 %{ 3404 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3405 match(RegP); 3406 match(rbx_RegP); 3407 match(rsi_RegP); 3408 match(rdi_RegP); 3409 3410 format %{ %} 3411 interface(REG_INTER); 3412 %} 3413 3414 // This operand is not allowed to use RBP even if 3415 // RBP is not used to hold the frame pointer. 3416 operand no_rbp_RegP() 3417 %{ 3418 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3419 match(RegP); 3420 match(rbx_RegP); 3421 match(rsi_RegP); 3422 match(rdi_RegP); 3423 3424 format %{ %} 3425 interface(REG_INTER); 3426 %} 3427 3428 operand no_rax_rbx_RegP() 3429 %{ 3430 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3431 match(RegP); 3432 match(rsi_RegP); 3433 match(rdi_RegP); 3434 3435 format %{ %} 3436 interface(REG_INTER); 3437 %} 3438 3439 // Special Registers 3440 // Return a pointer value 3441 operand rax_RegP() 3442 %{ 3443 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3444 match(RegP); 3445 match(rRegP); 3446 3447 format %{ %} 3448 interface(REG_INTER); 3449 %} 3450 3451 // Special Registers 3452 // Return a compressed pointer value 3453 operand rax_RegN() 3454 %{ 3455 constraint(ALLOC_IN_RC(int_rax_reg)); 3456 match(RegN); 3457 match(rRegN); 3458 3459 format %{ %} 3460 interface(REG_INTER); 3461 %} 3462 3463 // Used in AtomicAdd 3464 operand rbx_RegP() 3465 %{ 3466 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3467 match(RegP); 3468 match(rRegP); 3469 3470 format %{ %} 3471 interface(REG_INTER); 3472 %} 3473 3474 operand rsi_RegP() 3475 %{ 3476 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3477 match(RegP); 3478 match(rRegP); 3479 3480 format %{ %} 3481 interface(REG_INTER); 3482 %} 3483 3484 // Used in rep stosq 3485 operand rdi_RegP() 3486 %{ 3487 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3488 match(RegP); 3489 match(rRegP); 3490 3491 format %{ %} 3492 interface(REG_INTER); 3493 %} 3494 3495 operand r15_RegP() 3496 %{ 3497 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3498 match(RegP); 3499 match(rRegP); 3500 3501 format %{ %} 3502 interface(REG_INTER); 3503 %} 3504 3505 operand rRegL() 3506 %{ 3507 constraint(ALLOC_IN_RC(long_reg)); 3508 match(RegL); 3509 match(rax_RegL); 3510 match(rdx_RegL); 3511 3512 format %{ %} 3513 interface(REG_INTER); 3514 %} 3515 3516 // Special Registers 3517 operand no_rax_rdx_RegL() 3518 %{ 3519 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3520 match(RegL); 3521 match(rRegL); 3522 3523 format %{ %} 3524 interface(REG_INTER); 3525 %} 3526 3527 operand no_rax_RegL() 3528 %{ 3529 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3530 match(RegL); 3531 match(rRegL); 3532 match(rdx_RegL); 3533 3534 format %{ %} 3535 interface(REG_INTER); 3536 %} 3537 3538 operand no_rcx_RegL() 3539 %{ 3540 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3541 match(RegL); 3542 match(rRegL); 3543 3544 format %{ %} 3545 interface(REG_INTER); 3546 %} 3547 3548 operand rax_RegL() 3549 %{ 3550 constraint(ALLOC_IN_RC(long_rax_reg)); 3551 match(RegL); 3552 match(rRegL); 3553 3554 format %{ "RAX" %} 3555 interface(REG_INTER); 3556 %} 3557 3558 operand rcx_RegL() 3559 %{ 3560 constraint(ALLOC_IN_RC(long_rcx_reg)); 3561 match(RegL); 3562 match(rRegL); 3563 3564 format %{ %} 3565 interface(REG_INTER); 3566 %} 3567 3568 operand rdx_RegL() 3569 %{ 3570 constraint(ALLOC_IN_RC(long_rdx_reg)); 3571 match(RegL); 3572 match(rRegL); 3573 3574 format %{ %} 3575 interface(REG_INTER); 3576 %} 3577 3578 // Flags register, used as output of compare instructions 3579 operand rFlagsReg() 3580 %{ 3581 constraint(ALLOC_IN_RC(int_flags)); 3582 match(RegFlags); 3583 3584 format %{ "RFLAGS" %} 3585 interface(REG_INTER); 3586 %} 3587 3588 // Flags register, used as output of FLOATING POINT compare instructions 3589 operand rFlagsRegU() 3590 %{ 3591 constraint(ALLOC_IN_RC(int_flags)); 3592 match(RegFlags); 3593 3594 format %{ "RFLAGS_U" %} 3595 interface(REG_INTER); 3596 %} 3597 3598 operand rFlagsRegUCF() %{ 3599 constraint(ALLOC_IN_RC(int_flags)); 3600 match(RegFlags); 3601 predicate(false); 3602 3603 format %{ "RFLAGS_U_CF" %} 3604 interface(REG_INTER); 3605 %} 3606 3607 // Float register operands 3608 operand regF() %{ 3609 constraint(ALLOC_IN_RC(float_reg)); 3610 match(RegF); 3611 3612 format %{ %} 3613 interface(REG_INTER); 3614 %} 3615 3616 // Double register operands 3617 operand regD() %{ 3618 constraint(ALLOC_IN_RC(double_reg)); 3619 match(RegD); 3620 3621 format %{ %} 3622 interface(REG_INTER); 3623 %} 3624 3625 // Vectors 3626 operand vecS() %{ 3627 constraint(ALLOC_IN_RC(vectors_reg)); 3628 match(VecS); 3629 3630 format %{ %} 3631 interface(REG_INTER); 3632 %} 3633 3634 operand vecD() %{ 3635 constraint(ALLOC_IN_RC(vectord_reg)); 3636 match(VecD); 3637 3638 format %{ %} 3639 interface(REG_INTER); 3640 %} 3641 3642 operand vecX() %{ 3643 constraint(ALLOC_IN_RC(vectorx_reg)); 3644 match(VecX); 3645 3646 format %{ %} 3647 interface(REG_INTER); 3648 %} 3649 3650 operand vecY() %{ 3651 constraint(ALLOC_IN_RC(vectory_reg)); 3652 match(VecY); 3653 3654 format %{ %} 3655 interface(REG_INTER); 3656 %} 3657 3658 //----------Memory Operands---------------------------------------------------- 3659 // Direct Memory Operand 3660 // operand direct(immP addr) 3661 // %{ 3662 // match(addr); 3663 3664 // format %{ "[$addr]" %} 3665 // interface(MEMORY_INTER) %{ 3666 // base(0xFFFFFFFF); 3667 // index(0x4); 3668 // scale(0x0); 3669 // disp($addr); 3670 // %} 3671 // %} 3672 3673 // Indirect Memory Operand 3674 operand indirect(any_RegP reg) 3675 %{ 3676 constraint(ALLOC_IN_RC(ptr_reg)); 3677 match(reg); 3678 3679 format %{ "[$reg]" %} 3680 interface(MEMORY_INTER) %{ 3681 base($reg); 3682 index(0x4); 3683 scale(0x0); 3684 disp(0x0); 3685 %} 3686 %} 3687 3688 // Indirect Memory Plus Short Offset Operand 3689 operand indOffset8(any_RegP reg, immL8 off) 3690 %{ 3691 constraint(ALLOC_IN_RC(ptr_reg)); 3692 match(AddP reg off); 3693 3694 format %{ "[$reg + $off (8-bit)]" %} 3695 interface(MEMORY_INTER) %{ 3696 base($reg); 3697 index(0x4); 3698 scale(0x0); 3699 disp($off); 3700 %} 3701 %} 3702 3703 // Indirect Memory Plus Long Offset Operand 3704 operand indOffset32(any_RegP reg, immL32 off) 3705 %{ 3706 constraint(ALLOC_IN_RC(ptr_reg)); 3707 match(AddP reg off); 3708 3709 format %{ "[$reg + $off (32-bit)]" %} 3710 interface(MEMORY_INTER) %{ 3711 base($reg); 3712 index(0x4); 3713 scale(0x0); 3714 disp($off); 3715 %} 3716 %} 3717 3718 // Indirect Memory Plus Index Register Plus Offset Operand 3719 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3720 %{ 3721 constraint(ALLOC_IN_RC(ptr_reg)); 3722 match(AddP (AddP reg lreg) off); 3723 3724 op_cost(10); 3725 format %{"[$reg + $off + $lreg]" %} 3726 interface(MEMORY_INTER) %{ 3727 base($reg); 3728 index($lreg); 3729 scale(0x0); 3730 disp($off); 3731 %} 3732 %} 3733 3734 // Indirect Memory Plus Index Register Plus Offset Operand 3735 operand indIndex(any_RegP reg, rRegL lreg) 3736 %{ 3737 constraint(ALLOC_IN_RC(ptr_reg)); 3738 match(AddP reg lreg); 3739 3740 op_cost(10); 3741 format %{"[$reg + $lreg]" %} 3742 interface(MEMORY_INTER) %{ 3743 base($reg); 3744 index($lreg); 3745 scale(0x0); 3746 disp(0x0); 3747 %} 3748 %} 3749 3750 // Indirect Memory Times Scale Plus Index Register 3751 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3752 %{ 3753 constraint(ALLOC_IN_RC(ptr_reg)); 3754 match(AddP reg (LShiftL lreg scale)); 3755 3756 op_cost(10); 3757 format %{"[$reg + $lreg << $scale]" %} 3758 interface(MEMORY_INTER) %{ 3759 base($reg); 3760 index($lreg); 3761 scale($scale); 3762 disp(0x0); 3763 %} 3764 %} 3765 3766 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3767 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3768 %{ 3769 constraint(ALLOC_IN_RC(ptr_reg)); 3770 match(AddP (AddP reg (LShiftL lreg scale)) off); 3771 3772 op_cost(10); 3773 format %{"[$reg + $off + $lreg << $scale]" %} 3774 interface(MEMORY_INTER) %{ 3775 base($reg); 3776 index($lreg); 3777 scale($scale); 3778 disp($off); 3779 %} 3780 %} 3781 3782 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3783 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3784 %{ 3785 constraint(ALLOC_IN_RC(ptr_reg)); 3786 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3787 match(AddP (AddP reg (ConvI2L idx)) off); 3788 3789 op_cost(10); 3790 format %{"[$reg + $off + $idx]" %} 3791 interface(MEMORY_INTER) %{ 3792 base($reg); 3793 index($idx); 3794 scale(0x0); 3795 disp($off); 3796 %} 3797 %} 3798 3799 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3800 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3801 %{ 3802 constraint(ALLOC_IN_RC(ptr_reg)); 3803 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3804 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3805 3806 op_cost(10); 3807 format %{"[$reg + $off + $idx << $scale]" %} 3808 interface(MEMORY_INTER) %{ 3809 base($reg); 3810 index($idx); 3811 scale($scale); 3812 disp($off); 3813 %} 3814 %} 3815 3816 // Indirect Narrow Oop Plus Offset Operand 3817 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3818 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3819 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3820 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3821 constraint(ALLOC_IN_RC(ptr_reg)); 3822 match(AddP (DecodeN reg) off); 3823 3824 op_cost(10); 3825 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3826 interface(MEMORY_INTER) %{ 3827 base(0xc); // R12 3828 index($reg); 3829 scale(0x3); 3830 disp($off); 3831 %} 3832 %} 3833 3834 // Indirect Memory Operand 3835 operand indirectNarrow(rRegN reg) 3836 %{ 3837 predicate(Universe::narrow_oop_shift() == 0); 3838 constraint(ALLOC_IN_RC(ptr_reg)); 3839 match(DecodeN reg); 3840 3841 format %{ "[$reg]" %} 3842 interface(MEMORY_INTER) %{ 3843 base($reg); 3844 index(0x4); 3845 scale(0x0); 3846 disp(0x0); 3847 %} 3848 %} 3849 3850 // Indirect Memory Plus Short Offset Operand 3851 operand indOffset8Narrow(rRegN reg, immL8 off) 3852 %{ 3853 predicate(Universe::narrow_oop_shift() == 0); 3854 constraint(ALLOC_IN_RC(ptr_reg)); 3855 match(AddP (DecodeN reg) off); 3856 3857 format %{ "[$reg + $off (8-bit)]" %} 3858 interface(MEMORY_INTER) %{ 3859 base($reg); 3860 index(0x4); 3861 scale(0x0); 3862 disp($off); 3863 %} 3864 %} 3865 3866 // Indirect Memory Plus Long Offset Operand 3867 operand indOffset32Narrow(rRegN reg, immL32 off) 3868 %{ 3869 predicate(Universe::narrow_oop_shift() == 0); 3870 constraint(ALLOC_IN_RC(ptr_reg)); 3871 match(AddP (DecodeN reg) off); 3872 3873 format %{ "[$reg + $off (32-bit)]" %} 3874 interface(MEMORY_INTER) %{ 3875 base($reg); 3876 index(0x4); 3877 scale(0x0); 3878 disp($off); 3879 %} 3880 %} 3881 3882 // Indirect Memory Plus Index Register Plus Offset Operand 3883 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3884 %{ 3885 predicate(Universe::narrow_oop_shift() == 0); 3886 constraint(ALLOC_IN_RC(ptr_reg)); 3887 match(AddP (AddP (DecodeN reg) lreg) off); 3888 3889 op_cost(10); 3890 format %{"[$reg + $off + $lreg]" %} 3891 interface(MEMORY_INTER) %{ 3892 base($reg); 3893 index($lreg); 3894 scale(0x0); 3895 disp($off); 3896 %} 3897 %} 3898 3899 // Indirect Memory Plus Index Register Plus Offset Operand 3900 operand indIndexNarrow(rRegN reg, rRegL lreg) 3901 %{ 3902 predicate(Universe::narrow_oop_shift() == 0); 3903 constraint(ALLOC_IN_RC(ptr_reg)); 3904 match(AddP (DecodeN reg) lreg); 3905 3906 op_cost(10); 3907 format %{"[$reg + $lreg]" %} 3908 interface(MEMORY_INTER) %{ 3909 base($reg); 3910 index($lreg); 3911 scale(0x0); 3912 disp(0x0); 3913 %} 3914 %} 3915 3916 // Indirect Memory Times Scale Plus Index Register 3917 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3918 %{ 3919 predicate(Universe::narrow_oop_shift() == 0); 3920 constraint(ALLOC_IN_RC(ptr_reg)); 3921 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3922 3923 op_cost(10); 3924 format %{"[$reg + $lreg << $scale]" %} 3925 interface(MEMORY_INTER) %{ 3926 base($reg); 3927 index($lreg); 3928 scale($scale); 3929 disp(0x0); 3930 %} 3931 %} 3932 3933 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3934 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3935 %{ 3936 predicate(Universe::narrow_oop_shift() == 0); 3937 constraint(ALLOC_IN_RC(ptr_reg)); 3938 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3939 3940 op_cost(10); 3941 format %{"[$reg + $off + $lreg << $scale]" %} 3942 interface(MEMORY_INTER) %{ 3943 base($reg); 3944 index($lreg); 3945 scale($scale); 3946 disp($off); 3947 %} 3948 %} 3949 3950 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3951 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3952 %{ 3953 constraint(ALLOC_IN_RC(ptr_reg)); 3954 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3955 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3956 3957 op_cost(10); 3958 format %{"[$reg + $off + $idx]" %} 3959 interface(MEMORY_INTER) %{ 3960 base($reg); 3961 index($idx); 3962 scale(0x0); 3963 disp($off); 3964 %} 3965 %} 3966 3967 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3968 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3969 %{ 3970 constraint(ALLOC_IN_RC(ptr_reg)); 3971 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3972 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3973 3974 op_cost(10); 3975 format %{"[$reg + $off + $idx << $scale]" %} 3976 interface(MEMORY_INTER) %{ 3977 base($reg); 3978 index($idx); 3979 scale($scale); 3980 disp($off); 3981 %} 3982 %} 3983 3984 //----------Special Memory Operands-------------------------------------------- 3985 // Stack Slot Operand - This operand is used for loading and storing temporary 3986 // values on the stack where a match requires a value to 3987 // flow through memory. 3988 operand stackSlotP(sRegP reg) 3989 %{ 3990 constraint(ALLOC_IN_RC(stack_slots)); 3991 // No match rule because this operand is only generated in matching 3992 3993 format %{ "[$reg]" %} 3994 interface(MEMORY_INTER) %{ 3995 base(0x4); // RSP 3996 index(0x4); // No Index 3997 scale(0x0); // No Scale 3998 disp($reg); // Stack Offset 3999 %} 4000 %} 4001 4002 operand stackSlotI(sRegI reg) 4003 %{ 4004 constraint(ALLOC_IN_RC(stack_slots)); 4005 // No match rule because this operand is only generated in matching 4006 4007 format %{ "[$reg]" %} 4008 interface(MEMORY_INTER) %{ 4009 base(0x4); // RSP 4010 index(0x4); // No Index 4011 scale(0x0); // No Scale 4012 disp($reg); // Stack Offset 4013 %} 4014 %} 4015 4016 operand stackSlotF(sRegF reg) 4017 %{ 4018 constraint(ALLOC_IN_RC(stack_slots)); 4019 // No match rule because this operand is only generated in matching 4020 4021 format %{ "[$reg]" %} 4022 interface(MEMORY_INTER) %{ 4023 base(0x4); // RSP 4024 index(0x4); // No Index 4025 scale(0x0); // No Scale 4026 disp($reg); // Stack Offset 4027 %} 4028 %} 4029 4030 operand stackSlotD(sRegD reg) 4031 %{ 4032 constraint(ALLOC_IN_RC(stack_slots)); 4033 // No match rule because this operand is only generated in matching 4034 4035 format %{ "[$reg]" %} 4036 interface(MEMORY_INTER) %{ 4037 base(0x4); // RSP 4038 index(0x4); // No Index 4039 scale(0x0); // No Scale 4040 disp($reg); // Stack Offset 4041 %} 4042 %} 4043 operand stackSlotL(sRegL reg) 4044 %{ 4045 constraint(ALLOC_IN_RC(stack_slots)); 4046 // No match rule because this operand is only generated in matching 4047 4048 format %{ "[$reg]" %} 4049 interface(MEMORY_INTER) %{ 4050 base(0x4); // RSP 4051 index(0x4); // No Index 4052 scale(0x0); // No Scale 4053 disp($reg); // Stack Offset 4054 %} 4055 %} 4056 4057 //----------Conditional Branch Operands---------------------------------------- 4058 // Comparison Op - This is the operation of the comparison, and is limited to 4059 // the following set of codes: 4060 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4061 // 4062 // Other attributes of the comparison, such as unsignedness, are specified 4063 // by the comparison instruction that sets a condition code flags register. 4064 // That result is represented by a flags operand whose subtype is appropriate 4065 // to the unsignedness (etc.) of the comparison. 4066 // 4067 // Later, the instruction which matches both the Comparison Op (a Bool) and 4068 // the flags (produced by the Cmp) specifies the coding of the comparison op 4069 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4070 4071 // Comparision Code 4072 operand cmpOp() 4073 %{ 4074 match(Bool); 4075 4076 format %{ "" %} 4077 interface(COND_INTER) %{ 4078 equal(0x4, "e"); 4079 not_equal(0x5, "ne"); 4080 less(0xC, "l"); 4081 greater_equal(0xD, "ge"); 4082 less_equal(0xE, "le"); 4083 greater(0xF, "g"); 4084 overflow(0x0, "o"); 4085 no_overflow(0x1, "no"); 4086 %} 4087 %} 4088 4089 // Comparison Code, unsigned compare. Used by FP also, with 4090 // C2 (unordered) turned into GT or LT already. The other bits 4091 // C0 and C3 are turned into Carry & Zero flags. 4092 operand cmpOpU() 4093 %{ 4094 match(Bool); 4095 4096 format %{ "" %} 4097 interface(COND_INTER) %{ 4098 equal(0x4, "e"); 4099 not_equal(0x5, "ne"); 4100 less(0x2, "b"); 4101 greater_equal(0x3, "nb"); 4102 less_equal(0x6, "be"); 4103 greater(0x7, "nbe"); 4104 overflow(0x0, "o"); 4105 no_overflow(0x1, "no"); 4106 %} 4107 %} 4108 4109 4110 // Floating comparisons that don't require any fixup for the unordered case 4111 operand cmpOpUCF() %{ 4112 match(Bool); 4113 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4114 n->as_Bool()->_test._test == BoolTest::ge || 4115 n->as_Bool()->_test._test == BoolTest::le || 4116 n->as_Bool()->_test._test == BoolTest::gt); 4117 format %{ "" %} 4118 interface(COND_INTER) %{ 4119 equal(0x4, "e"); 4120 not_equal(0x5, "ne"); 4121 less(0x2, "b"); 4122 greater_equal(0x3, "nb"); 4123 less_equal(0x6, "be"); 4124 greater(0x7, "nbe"); 4125 overflow(0x0, "o"); 4126 no_overflow(0x1, "no"); 4127 %} 4128 %} 4129 4130 4131 // Floating comparisons that can be fixed up with extra conditional jumps 4132 operand cmpOpUCF2() %{ 4133 match(Bool); 4134 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4135 n->as_Bool()->_test._test == BoolTest::eq); 4136 format %{ "" %} 4137 interface(COND_INTER) %{ 4138 equal(0x4, "e"); 4139 not_equal(0x5, "ne"); 4140 less(0x2, "b"); 4141 greater_equal(0x3, "nb"); 4142 less_equal(0x6, "be"); 4143 greater(0x7, "nbe"); 4144 overflow(0x0, "o"); 4145 no_overflow(0x1, "no"); 4146 %} 4147 %} 4148 4149 4150 //----------OPERAND CLASSES---------------------------------------------------- 4151 // Operand Classes are groups of operands that are used as to simplify 4152 // instruction definitions by not requiring the AD writer to specify separate 4153 // instructions for every form of operand when the instruction accepts 4154 // multiple operand types with the same basic encoding and format. The classic 4155 // case of this is memory operands. 4156 4157 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4158 indIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4159 indCompressedOopOffset, 4160 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4161 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4162 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4163 4164 //----------PIPELINE----------------------------------------------------------- 4165 // Rules which define the behavior of the target architectures pipeline. 4166 pipeline %{ 4167 4168 //----------ATTRIBUTES--------------------------------------------------------- 4169 attributes %{ 4170 variable_size_instructions; // Fixed size instructions 4171 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4172 instruction_unit_size = 1; // An instruction is 1 bytes long 4173 instruction_fetch_unit_size = 16; // The processor fetches one line 4174 instruction_fetch_units = 1; // of 16 bytes 4175 4176 // List of nop instructions 4177 nops( MachNop ); 4178 %} 4179 4180 //----------RESOURCES---------------------------------------------------------- 4181 // Resources are the functional units available to the machine 4182 4183 // Generic P2/P3 pipeline 4184 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4185 // 3 instructions decoded per cycle. 4186 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4187 // 3 ALU op, only ALU0 handles mul instructions. 4188 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4189 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4190 BR, FPU, 4191 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4192 4193 //----------PIPELINE DESCRIPTION----------------------------------------------- 4194 // Pipeline Description specifies the stages in the machine's pipeline 4195 4196 // Generic P2/P3 pipeline 4197 pipe_desc(S0, S1, S2, S3, S4, S5); 4198 4199 //----------PIPELINE CLASSES--------------------------------------------------- 4200 // Pipeline Classes describe the stages in which input and output are 4201 // referenced by the hardware pipeline. 4202 4203 // Naming convention: ialu or fpu 4204 // Then: _reg 4205 // Then: _reg if there is a 2nd register 4206 // Then: _long if it's a pair of instructions implementing a long 4207 // Then: _fat if it requires the big decoder 4208 // Or: _mem if it requires the big decoder and a memory unit. 4209 4210 // Integer ALU reg operation 4211 pipe_class ialu_reg(rRegI dst) 4212 %{ 4213 single_instruction; 4214 dst : S4(write); 4215 dst : S3(read); 4216 DECODE : S0; // any decoder 4217 ALU : S3; // any alu 4218 %} 4219 4220 // Long ALU reg operation 4221 pipe_class ialu_reg_long(rRegL dst) 4222 %{ 4223 instruction_count(2); 4224 dst : S4(write); 4225 dst : S3(read); 4226 DECODE : S0(2); // any 2 decoders 4227 ALU : S3(2); // both alus 4228 %} 4229 4230 // Integer ALU reg operation using big decoder 4231 pipe_class ialu_reg_fat(rRegI dst) 4232 %{ 4233 single_instruction; 4234 dst : S4(write); 4235 dst : S3(read); 4236 D0 : S0; // big decoder only 4237 ALU : S3; // any alu 4238 %} 4239 4240 // Long ALU reg operation using big decoder 4241 pipe_class ialu_reg_long_fat(rRegL dst) 4242 %{ 4243 instruction_count(2); 4244 dst : S4(write); 4245 dst : S3(read); 4246 D0 : S0(2); // big decoder only; twice 4247 ALU : S3(2); // any 2 alus 4248 %} 4249 4250 // Integer ALU reg-reg operation 4251 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4252 %{ 4253 single_instruction; 4254 dst : S4(write); 4255 src : S3(read); 4256 DECODE : S0; // any decoder 4257 ALU : S3; // any alu 4258 %} 4259 4260 // Long ALU reg-reg operation 4261 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4262 %{ 4263 instruction_count(2); 4264 dst : S4(write); 4265 src : S3(read); 4266 DECODE : S0(2); // any 2 decoders 4267 ALU : S3(2); // both alus 4268 %} 4269 4270 // Integer ALU reg-reg operation 4271 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4272 %{ 4273 single_instruction; 4274 dst : S4(write); 4275 src : S3(read); 4276 D0 : S0; // big decoder only 4277 ALU : S3; // any alu 4278 %} 4279 4280 // Long ALU reg-reg operation 4281 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4282 %{ 4283 instruction_count(2); 4284 dst : S4(write); 4285 src : S3(read); 4286 D0 : S0(2); // big decoder only; twice 4287 ALU : S3(2); // both alus 4288 %} 4289 4290 // Integer ALU reg-mem operation 4291 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4292 %{ 4293 single_instruction; 4294 dst : S5(write); 4295 mem : S3(read); 4296 D0 : S0; // big decoder only 4297 ALU : S4; // any alu 4298 MEM : S3; // any mem 4299 %} 4300 4301 // Integer mem operation (prefetch) 4302 pipe_class ialu_mem(memory mem) 4303 %{ 4304 single_instruction; 4305 mem : S3(read); 4306 D0 : S0; // big decoder only 4307 MEM : S3; // any mem 4308 %} 4309 4310 // Integer Store to Memory 4311 pipe_class ialu_mem_reg(memory mem, rRegI src) 4312 %{ 4313 single_instruction; 4314 mem : S3(read); 4315 src : S5(read); 4316 D0 : S0; // big decoder only 4317 ALU : S4; // any alu 4318 MEM : S3; 4319 %} 4320 4321 // // Long Store to Memory 4322 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4323 // %{ 4324 // instruction_count(2); 4325 // mem : S3(read); 4326 // src : S5(read); 4327 // D0 : S0(2); // big decoder only; twice 4328 // ALU : S4(2); // any 2 alus 4329 // MEM : S3(2); // Both mems 4330 // %} 4331 4332 // Integer Store to Memory 4333 pipe_class ialu_mem_imm(memory mem) 4334 %{ 4335 single_instruction; 4336 mem : S3(read); 4337 D0 : S0; // big decoder only 4338 ALU : S4; // any alu 4339 MEM : S3; 4340 %} 4341 4342 // Integer ALU0 reg-reg operation 4343 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4344 %{ 4345 single_instruction; 4346 dst : S4(write); 4347 src : S3(read); 4348 D0 : S0; // Big decoder only 4349 ALU0 : S3; // only alu0 4350 %} 4351 4352 // Integer ALU0 reg-mem operation 4353 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4354 %{ 4355 single_instruction; 4356 dst : S5(write); 4357 mem : S3(read); 4358 D0 : S0; // big decoder only 4359 ALU0 : S4; // ALU0 only 4360 MEM : S3; // any mem 4361 %} 4362 4363 // Integer ALU reg-reg operation 4364 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4365 %{ 4366 single_instruction; 4367 cr : S4(write); 4368 src1 : S3(read); 4369 src2 : S3(read); 4370 DECODE : S0; // any decoder 4371 ALU : S3; // any alu 4372 %} 4373 4374 // Integer ALU reg-imm operation 4375 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4376 %{ 4377 single_instruction; 4378 cr : S4(write); 4379 src1 : S3(read); 4380 DECODE : S0; // any decoder 4381 ALU : S3; // any alu 4382 %} 4383 4384 // Integer ALU reg-mem operation 4385 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4386 %{ 4387 single_instruction; 4388 cr : S4(write); 4389 src1 : S3(read); 4390 src2 : S3(read); 4391 D0 : S0; // big decoder only 4392 ALU : S4; // any alu 4393 MEM : S3; 4394 %} 4395 4396 // Conditional move reg-reg 4397 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4398 %{ 4399 instruction_count(4); 4400 y : S4(read); 4401 q : S3(read); 4402 p : S3(read); 4403 DECODE : S0(4); // any decoder 4404 %} 4405 4406 // Conditional move reg-reg 4407 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4408 %{ 4409 single_instruction; 4410 dst : S4(write); 4411 src : S3(read); 4412 cr : S3(read); 4413 DECODE : S0; // any decoder 4414 %} 4415 4416 // Conditional move reg-mem 4417 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4418 %{ 4419 single_instruction; 4420 dst : S4(write); 4421 src : S3(read); 4422 cr : S3(read); 4423 DECODE : S0; // any decoder 4424 MEM : S3; 4425 %} 4426 4427 // Conditional move reg-reg long 4428 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4429 %{ 4430 single_instruction; 4431 dst : S4(write); 4432 src : S3(read); 4433 cr : S3(read); 4434 DECODE : S0(2); // any 2 decoders 4435 %} 4436 4437 // XXX 4438 // // Conditional move double reg-reg 4439 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4440 // %{ 4441 // single_instruction; 4442 // dst : S4(write); 4443 // src : S3(read); 4444 // cr : S3(read); 4445 // DECODE : S0; // any decoder 4446 // %} 4447 4448 // Float reg-reg operation 4449 pipe_class fpu_reg(regD dst) 4450 %{ 4451 instruction_count(2); 4452 dst : S3(read); 4453 DECODE : S0(2); // any 2 decoders 4454 FPU : S3; 4455 %} 4456 4457 // Float reg-reg operation 4458 pipe_class fpu_reg_reg(regD dst, regD src) 4459 %{ 4460 instruction_count(2); 4461 dst : S4(write); 4462 src : S3(read); 4463 DECODE : S0(2); // any 2 decoders 4464 FPU : S3; 4465 %} 4466 4467 // Float reg-reg operation 4468 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4469 %{ 4470 instruction_count(3); 4471 dst : S4(write); 4472 src1 : S3(read); 4473 src2 : S3(read); 4474 DECODE : S0(3); // any 3 decoders 4475 FPU : S3(2); 4476 %} 4477 4478 // Float reg-reg operation 4479 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4480 %{ 4481 instruction_count(4); 4482 dst : S4(write); 4483 src1 : S3(read); 4484 src2 : S3(read); 4485 src3 : S3(read); 4486 DECODE : S0(4); // any 3 decoders 4487 FPU : S3(2); 4488 %} 4489 4490 // Float reg-reg operation 4491 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4492 %{ 4493 instruction_count(4); 4494 dst : S4(write); 4495 src1 : S3(read); 4496 src2 : S3(read); 4497 src3 : S3(read); 4498 DECODE : S1(3); // any 3 decoders 4499 D0 : S0; // Big decoder only 4500 FPU : S3(2); 4501 MEM : S3; 4502 %} 4503 4504 // Float reg-mem operation 4505 pipe_class fpu_reg_mem(regD dst, memory mem) 4506 %{ 4507 instruction_count(2); 4508 dst : S5(write); 4509 mem : S3(read); 4510 D0 : S0; // big decoder only 4511 DECODE : S1; // any decoder for FPU POP 4512 FPU : S4; 4513 MEM : S3; // any mem 4514 %} 4515 4516 // Float reg-mem operation 4517 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4518 %{ 4519 instruction_count(3); 4520 dst : S5(write); 4521 src1 : S3(read); 4522 mem : S3(read); 4523 D0 : S0; // big decoder only 4524 DECODE : S1(2); // any decoder for FPU POP 4525 FPU : S4; 4526 MEM : S3; // any mem 4527 %} 4528 4529 // Float mem-reg operation 4530 pipe_class fpu_mem_reg(memory mem, regD src) 4531 %{ 4532 instruction_count(2); 4533 src : S5(read); 4534 mem : S3(read); 4535 DECODE : S0; // any decoder for FPU PUSH 4536 D0 : S1; // big decoder only 4537 FPU : S4; 4538 MEM : S3; // any mem 4539 %} 4540 4541 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4542 %{ 4543 instruction_count(3); 4544 src1 : S3(read); 4545 src2 : S3(read); 4546 mem : S3(read); 4547 DECODE : S0(2); // any decoder for FPU PUSH 4548 D0 : S1; // big decoder only 4549 FPU : S4; 4550 MEM : S3; // any mem 4551 %} 4552 4553 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4554 %{ 4555 instruction_count(3); 4556 src1 : S3(read); 4557 src2 : S3(read); 4558 mem : S4(read); 4559 DECODE : S0; // any decoder for FPU PUSH 4560 D0 : S0(2); // big decoder only 4561 FPU : S4; 4562 MEM : S3(2); // any mem 4563 %} 4564 4565 pipe_class fpu_mem_mem(memory dst, memory src1) 4566 %{ 4567 instruction_count(2); 4568 src1 : S3(read); 4569 dst : S4(read); 4570 D0 : S0(2); // big decoder only 4571 MEM : S3(2); // any mem 4572 %} 4573 4574 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4575 %{ 4576 instruction_count(3); 4577 src1 : S3(read); 4578 src2 : S3(read); 4579 dst : S4(read); 4580 D0 : S0(3); // big decoder only 4581 FPU : S4; 4582 MEM : S3(3); // any mem 4583 %} 4584 4585 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4586 %{ 4587 instruction_count(3); 4588 src1 : S4(read); 4589 mem : S4(read); 4590 DECODE : S0; // any decoder for FPU PUSH 4591 D0 : S0(2); // big decoder only 4592 FPU : S4; 4593 MEM : S3(2); // any mem 4594 %} 4595 4596 // Float load constant 4597 pipe_class fpu_reg_con(regD dst) 4598 %{ 4599 instruction_count(2); 4600 dst : S5(write); 4601 D0 : S0; // big decoder only for the load 4602 DECODE : S1; // any decoder for FPU POP 4603 FPU : S4; 4604 MEM : S3; // any mem 4605 %} 4606 4607 // Float load constant 4608 pipe_class fpu_reg_reg_con(regD dst, regD src) 4609 %{ 4610 instruction_count(3); 4611 dst : S5(write); 4612 src : S3(read); 4613 D0 : S0; // big decoder only for the load 4614 DECODE : S1(2); // any decoder for FPU POP 4615 FPU : S4; 4616 MEM : S3; // any mem 4617 %} 4618 4619 // UnConditional branch 4620 pipe_class pipe_jmp(label labl) 4621 %{ 4622 single_instruction; 4623 BR : S3; 4624 %} 4625 4626 // Conditional branch 4627 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4628 %{ 4629 single_instruction; 4630 cr : S1(read); 4631 BR : S3; 4632 %} 4633 4634 // Allocation idiom 4635 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4636 %{ 4637 instruction_count(1); force_serialization; 4638 fixed_latency(6); 4639 heap_ptr : S3(read); 4640 DECODE : S0(3); 4641 D0 : S2; 4642 MEM : S3; 4643 ALU : S3(2); 4644 dst : S5(write); 4645 BR : S5; 4646 %} 4647 4648 // Generic big/slow expanded idiom 4649 pipe_class pipe_slow() 4650 %{ 4651 instruction_count(10); multiple_bundles; force_serialization; 4652 fixed_latency(100); 4653 D0 : S0(2); 4654 MEM : S3(2); 4655 %} 4656 4657 // The real do-nothing guy 4658 pipe_class empty() 4659 %{ 4660 instruction_count(0); 4661 %} 4662 4663 // Define the class for the Nop node 4664 define 4665 %{ 4666 MachNop = empty; 4667 %} 4668 4669 %} 4670 4671 //----------INSTRUCTIONS------------------------------------------------------- 4672 // 4673 // match -- States which machine-independent subtree may be replaced 4674 // by this instruction. 4675 // ins_cost -- The estimated cost of this instruction is used by instruction 4676 // selection to identify a minimum cost tree of machine 4677 // instructions that matches a tree of machine-independent 4678 // instructions. 4679 // format -- A string providing the disassembly for this instruction. 4680 // The value of an instruction's operand may be inserted 4681 // by referring to it with a '$' prefix. 4682 // opcode -- Three instruction opcodes may be provided. These are referred 4683 // to within an encode class as $primary, $secondary, and $tertiary 4684 // rrspectively. The primary opcode is commonly used to 4685 // indicate the type of machine instruction, while secondary 4686 // and tertiary are often used for prefix options or addressing 4687 // modes. 4688 // ins_encode -- A list of encode classes with parameters. The encode class 4689 // name must have been defined in an 'enc_class' specification 4690 // in the encode section of the architecture description. 4691 4692 4693 //----------Load/Store/Move Instructions--------------------------------------- 4694 //----------Load Instructions-------------------------------------------------- 4695 4696 // Load Byte (8 bit signed) 4697 instruct loadB(rRegI dst, memory mem) 4698 %{ 4699 match(Set dst (LoadB mem)); 4700 4701 ins_cost(125); 4702 format %{ "movsbl $dst, $mem\t# byte" %} 4703 4704 ins_encode %{ 4705 __ movsbl($dst$$Register, $mem$$Address); 4706 %} 4707 4708 ins_pipe(ialu_reg_mem); 4709 %} 4710 4711 // Load Byte (8 bit signed) into Long Register 4712 instruct loadB2L(rRegL dst, memory mem) 4713 %{ 4714 match(Set dst (ConvI2L (LoadB mem))); 4715 4716 ins_cost(125); 4717 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4718 4719 ins_encode %{ 4720 __ movsbq($dst$$Register, $mem$$Address); 4721 %} 4722 4723 ins_pipe(ialu_reg_mem); 4724 %} 4725 4726 // Load Unsigned Byte (8 bit UNsigned) 4727 instruct loadUB(rRegI dst, memory mem) 4728 %{ 4729 match(Set dst (LoadUB mem)); 4730 4731 ins_cost(125); 4732 format %{ "movzbl $dst, $mem\t# ubyte" %} 4733 4734 ins_encode %{ 4735 __ movzbl($dst$$Register, $mem$$Address); 4736 %} 4737 4738 ins_pipe(ialu_reg_mem); 4739 %} 4740 4741 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4742 instruct loadUB2L(rRegL dst, memory mem) 4743 %{ 4744 match(Set dst (ConvI2L (LoadUB mem))); 4745 4746 ins_cost(125); 4747 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4748 4749 ins_encode %{ 4750 __ movzbq($dst$$Register, $mem$$Address); 4751 %} 4752 4753 ins_pipe(ialu_reg_mem); 4754 %} 4755 4756 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register 4757 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ 4758 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4759 effect(KILL cr); 4760 4761 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" 4762 "andl $dst, $mask" %} 4763 ins_encode %{ 4764 Register Rdst = $dst$$Register; 4765 __ movzbq(Rdst, $mem$$Address); 4766 __ andl(Rdst, $mask$$constant); 4767 %} 4768 ins_pipe(ialu_reg_mem); 4769 %} 4770 4771 // Load Short (16 bit signed) 4772 instruct loadS(rRegI dst, memory mem) 4773 %{ 4774 match(Set dst (LoadS mem)); 4775 4776 ins_cost(125); 4777 format %{ "movswl $dst, $mem\t# short" %} 4778 4779 ins_encode %{ 4780 __ movswl($dst$$Register, $mem$$Address); 4781 %} 4782 4783 ins_pipe(ialu_reg_mem); 4784 %} 4785 4786 // Load Short (16 bit signed) to Byte (8 bit signed) 4787 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4788 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4789 4790 ins_cost(125); 4791 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4792 ins_encode %{ 4793 __ movsbl($dst$$Register, $mem$$Address); 4794 %} 4795 ins_pipe(ialu_reg_mem); 4796 %} 4797 4798 // Load Short (16 bit signed) into Long Register 4799 instruct loadS2L(rRegL dst, memory mem) 4800 %{ 4801 match(Set dst (ConvI2L (LoadS mem))); 4802 4803 ins_cost(125); 4804 format %{ "movswq $dst, $mem\t# short -> long" %} 4805 4806 ins_encode %{ 4807 __ movswq($dst$$Register, $mem$$Address); 4808 %} 4809 4810 ins_pipe(ialu_reg_mem); 4811 %} 4812 4813 // Load Unsigned Short/Char (16 bit UNsigned) 4814 instruct loadUS(rRegI dst, memory mem) 4815 %{ 4816 match(Set dst (LoadUS mem)); 4817 4818 ins_cost(125); 4819 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4820 4821 ins_encode %{ 4822 __ movzwl($dst$$Register, $mem$$Address); 4823 %} 4824 4825 ins_pipe(ialu_reg_mem); 4826 %} 4827 4828 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4829 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4830 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4831 4832 ins_cost(125); 4833 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4834 ins_encode %{ 4835 __ movsbl($dst$$Register, $mem$$Address); 4836 %} 4837 ins_pipe(ialu_reg_mem); 4838 %} 4839 4840 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4841 instruct loadUS2L(rRegL dst, memory mem) 4842 %{ 4843 match(Set dst (ConvI2L (LoadUS mem))); 4844 4845 ins_cost(125); 4846 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4847 4848 ins_encode %{ 4849 __ movzwq($dst$$Register, $mem$$Address); 4850 %} 4851 4852 ins_pipe(ialu_reg_mem); 4853 %} 4854 4855 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4856 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4857 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4858 4859 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4860 ins_encode %{ 4861 __ movzbq($dst$$Register, $mem$$Address); 4862 %} 4863 ins_pipe(ialu_reg_mem); 4864 %} 4865 4866 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register 4867 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ 4868 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4869 effect(KILL cr); 4870 4871 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" 4872 "andl $dst, $mask" %} 4873 ins_encode %{ 4874 Register Rdst = $dst$$Register; 4875 __ movzwq(Rdst, $mem$$Address); 4876 __ andl(Rdst, $mask$$constant); 4877 %} 4878 ins_pipe(ialu_reg_mem); 4879 %} 4880 4881 // Load Integer 4882 instruct loadI(rRegI dst, memory mem) 4883 %{ 4884 match(Set dst (LoadI mem)); 4885 4886 ins_cost(125); 4887 format %{ "movl $dst, $mem\t# int" %} 4888 4889 ins_encode %{ 4890 __ movl($dst$$Register, $mem$$Address); 4891 %} 4892 4893 ins_pipe(ialu_reg_mem); 4894 %} 4895 4896 // Load Integer (32 bit signed) to Byte (8 bit signed) 4897 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4898 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4899 4900 ins_cost(125); 4901 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4902 ins_encode %{ 4903 __ movsbl($dst$$Register, $mem$$Address); 4904 %} 4905 ins_pipe(ialu_reg_mem); 4906 %} 4907 4908 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4909 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4910 match(Set dst (AndI (LoadI mem) mask)); 4911 4912 ins_cost(125); 4913 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4914 ins_encode %{ 4915 __ movzbl($dst$$Register, $mem$$Address); 4916 %} 4917 ins_pipe(ialu_reg_mem); 4918 %} 4919 4920 // Load Integer (32 bit signed) to Short (16 bit signed) 4921 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4922 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4923 4924 ins_cost(125); 4925 format %{ "movswl $dst, $mem\t# int -> short" %} 4926 ins_encode %{ 4927 __ movswl($dst$$Register, $mem$$Address); 4928 %} 4929 ins_pipe(ialu_reg_mem); 4930 %} 4931 4932 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4933 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4934 match(Set dst (AndI (LoadI mem) mask)); 4935 4936 ins_cost(125); 4937 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4938 ins_encode %{ 4939 __ movzwl($dst$$Register, $mem$$Address); 4940 %} 4941 ins_pipe(ialu_reg_mem); 4942 %} 4943 4944 // Load Integer into Long Register 4945 instruct loadI2L(rRegL dst, memory mem) 4946 %{ 4947 match(Set dst (ConvI2L (LoadI mem))); 4948 4949 ins_cost(125); 4950 format %{ "movslq $dst, $mem\t# int -> long" %} 4951 4952 ins_encode %{ 4953 __ movslq($dst$$Register, $mem$$Address); 4954 %} 4955 4956 ins_pipe(ialu_reg_mem); 4957 %} 4958 4959 // Load Integer with mask 0xFF into Long Register 4960 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4961 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4962 4963 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4964 ins_encode %{ 4965 __ movzbq($dst$$Register, $mem$$Address); 4966 %} 4967 ins_pipe(ialu_reg_mem); 4968 %} 4969 4970 // Load Integer with mask 0xFFFF into Long Register 4971 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4972 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4973 4974 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4975 ins_encode %{ 4976 __ movzwq($dst$$Register, $mem$$Address); 4977 %} 4978 ins_pipe(ialu_reg_mem); 4979 %} 4980 4981 // Load Integer with a 31-bit mask into Long Register 4982 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4983 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4984 effect(KILL cr); 4985 4986 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4987 "andl $dst, $mask" %} 4988 ins_encode %{ 4989 Register Rdst = $dst$$Register; 4990 __ movl(Rdst, $mem$$Address); 4991 __ andl(Rdst, $mask$$constant); 4992 %} 4993 ins_pipe(ialu_reg_mem); 4994 %} 4995 4996 // Load Unsigned Integer into Long Register 4997 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4998 %{ 4999 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5000 5001 ins_cost(125); 5002 format %{ "movl $dst, $mem\t# uint -> long" %} 5003 5004 ins_encode %{ 5005 __ movl($dst$$Register, $mem$$Address); 5006 %} 5007 5008 ins_pipe(ialu_reg_mem); 5009 %} 5010 5011 // Load Long 5012 instruct loadL(rRegL dst, memory mem) 5013 %{ 5014 match(Set dst (LoadL mem)); 5015 5016 ins_cost(125); 5017 format %{ "movq $dst, $mem\t# long" %} 5018 5019 ins_encode %{ 5020 __ movq($dst$$Register, $mem$$Address); 5021 %} 5022 5023 ins_pipe(ialu_reg_mem); // XXX 5024 %} 5025 5026 // Load Range 5027 instruct loadRange(rRegI dst, memory mem) 5028 %{ 5029 match(Set dst (LoadRange mem)); 5030 5031 ins_cost(125); // XXX 5032 format %{ "movl $dst, $mem\t# range" %} 5033 opcode(0x8B); 5034 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5035 ins_pipe(ialu_reg_mem); 5036 %} 5037 5038 // Load Pointer 5039 instruct loadP(rRegP dst, memory mem) 5040 %{ 5041 match(Set dst (LoadP mem)); 5042 5043 ins_cost(125); // XXX 5044 format %{ "movq $dst, $mem\t# ptr" %} 5045 opcode(0x8B); 5046 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5047 ins_pipe(ialu_reg_mem); // XXX 5048 %} 5049 5050 // Load Compressed Pointer 5051 instruct loadN(rRegN dst, memory mem) 5052 %{ 5053 match(Set dst (LoadN mem)); 5054 5055 ins_cost(125); // XXX 5056 format %{ "movl $dst, $mem\t# compressed ptr" %} 5057 ins_encode %{ 5058 __ movl($dst$$Register, $mem$$Address); 5059 %} 5060 ins_pipe(ialu_reg_mem); // XXX 5061 %} 5062 5063 5064 // Load Klass Pointer 5065 instruct loadKlass(rRegP dst, memory mem) 5066 %{ 5067 match(Set dst (LoadKlass mem)); 5068 5069 ins_cost(125); // XXX 5070 format %{ "movq $dst, $mem\t# class" %} 5071 opcode(0x8B); 5072 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5073 ins_pipe(ialu_reg_mem); // XXX 5074 %} 5075 5076 // Load narrow Klass Pointer 5077 instruct loadNKlass(rRegN dst, memory mem) 5078 %{ 5079 match(Set dst (LoadNKlass mem)); 5080 5081 ins_cost(125); // XXX 5082 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5083 ins_encode %{ 5084 __ movl($dst$$Register, $mem$$Address); 5085 %} 5086 ins_pipe(ialu_reg_mem); // XXX 5087 %} 5088 5089 // Load Float 5090 instruct loadF(regF dst, memory mem) 5091 %{ 5092 match(Set dst (LoadF mem)); 5093 5094 ins_cost(145); // XXX 5095 format %{ "movss $dst, $mem\t# float" %} 5096 ins_encode %{ 5097 __ movflt($dst$$XMMRegister, $mem$$Address); 5098 %} 5099 ins_pipe(pipe_slow); // XXX 5100 %} 5101 5102 // Load Double 5103 instruct loadD_partial(regD dst, memory mem) 5104 %{ 5105 predicate(!UseXmmLoadAndClearUpper); 5106 match(Set dst (LoadD mem)); 5107 5108 ins_cost(145); // XXX 5109 format %{ "movlpd $dst, $mem\t# double" %} 5110 ins_encode %{ 5111 __ movdbl($dst$$XMMRegister, $mem$$Address); 5112 %} 5113 ins_pipe(pipe_slow); // XXX 5114 %} 5115 5116 instruct loadD(regD dst, memory mem) 5117 %{ 5118 predicate(UseXmmLoadAndClearUpper); 5119 match(Set dst (LoadD mem)); 5120 5121 ins_cost(145); // XXX 5122 format %{ "movsd $dst, $mem\t# double" %} 5123 ins_encode %{ 5124 __ movdbl($dst$$XMMRegister, $mem$$Address); 5125 %} 5126 ins_pipe(pipe_slow); // XXX 5127 %} 5128 5129 // Load Effective Address 5130 instruct leaP8(rRegP dst, indOffset8 mem) 5131 %{ 5132 match(Set dst mem); 5133 5134 ins_cost(110); // XXX 5135 format %{ "leaq $dst, $mem\t# ptr 8" %} 5136 opcode(0x8D); 5137 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5138 ins_pipe(ialu_reg_reg_fat); 5139 %} 5140 5141 instruct leaP32(rRegP dst, indOffset32 mem) 5142 %{ 5143 match(Set dst mem); 5144 5145 ins_cost(110); 5146 format %{ "leaq $dst, $mem\t# ptr 32" %} 5147 opcode(0x8D); 5148 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5149 ins_pipe(ialu_reg_reg_fat); 5150 %} 5151 5152 // instruct leaPIdx(rRegP dst, indIndex mem) 5153 // %{ 5154 // match(Set dst mem); 5155 5156 // ins_cost(110); 5157 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5158 // opcode(0x8D); 5159 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5160 // ins_pipe(ialu_reg_reg_fat); 5161 // %} 5162 5163 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5164 %{ 5165 match(Set dst mem); 5166 5167 ins_cost(110); 5168 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5169 opcode(0x8D); 5170 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5171 ins_pipe(ialu_reg_reg_fat); 5172 %} 5173 5174 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5175 %{ 5176 match(Set dst mem); 5177 5178 ins_cost(110); 5179 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5180 opcode(0x8D); 5181 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5182 ins_pipe(ialu_reg_reg_fat); 5183 %} 5184 5185 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5186 %{ 5187 match(Set dst mem); 5188 5189 ins_cost(110); 5190 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5191 opcode(0x8D); 5192 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5193 ins_pipe(ialu_reg_reg_fat); 5194 %} 5195 5196 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5197 %{ 5198 match(Set dst mem); 5199 5200 ins_cost(110); 5201 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5202 opcode(0x8D); 5203 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5204 ins_pipe(ialu_reg_reg_fat); 5205 %} 5206 5207 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5208 %{ 5209 match(Set dst mem); 5210 5211 ins_cost(110); 5212 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5213 opcode(0x8D); 5214 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5215 ins_pipe(ialu_reg_reg_fat); 5216 %} 5217 5218 // Load Effective Address which uses Narrow (32-bits) oop 5219 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5220 %{ 5221 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5222 match(Set dst mem); 5223 5224 ins_cost(110); 5225 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5226 opcode(0x8D); 5227 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5228 ins_pipe(ialu_reg_reg_fat); 5229 %} 5230 5231 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5232 %{ 5233 predicate(Universe::narrow_oop_shift() == 0); 5234 match(Set dst mem); 5235 5236 ins_cost(110); // XXX 5237 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5238 opcode(0x8D); 5239 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5240 ins_pipe(ialu_reg_reg_fat); 5241 %} 5242 5243 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5244 %{ 5245 predicate(Universe::narrow_oop_shift() == 0); 5246 match(Set dst mem); 5247 5248 ins_cost(110); 5249 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5250 opcode(0x8D); 5251 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5252 ins_pipe(ialu_reg_reg_fat); 5253 %} 5254 5255 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5256 %{ 5257 predicate(Universe::narrow_oop_shift() == 0); 5258 match(Set dst mem); 5259 5260 ins_cost(110); 5261 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5262 opcode(0x8D); 5263 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5264 ins_pipe(ialu_reg_reg_fat); 5265 %} 5266 5267 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5268 %{ 5269 predicate(Universe::narrow_oop_shift() == 0); 5270 match(Set dst mem); 5271 5272 ins_cost(110); 5273 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5274 opcode(0x8D); 5275 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5276 ins_pipe(ialu_reg_reg_fat); 5277 %} 5278 5279 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5280 %{ 5281 predicate(Universe::narrow_oop_shift() == 0); 5282 match(Set dst mem); 5283 5284 ins_cost(110); 5285 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5286 opcode(0x8D); 5287 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5288 ins_pipe(ialu_reg_reg_fat); 5289 %} 5290 5291 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5292 %{ 5293 predicate(Universe::narrow_oop_shift() == 0); 5294 match(Set dst mem); 5295 5296 ins_cost(110); 5297 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5298 opcode(0x8D); 5299 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5300 ins_pipe(ialu_reg_reg_fat); 5301 %} 5302 5303 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5304 %{ 5305 predicate(Universe::narrow_oop_shift() == 0); 5306 match(Set dst mem); 5307 5308 ins_cost(110); 5309 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5310 opcode(0x8D); 5311 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5312 ins_pipe(ialu_reg_reg_fat); 5313 %} 5314 5315 instruct loadConI(rRegI dst, immI src) 5316 %{ 5317 match(Set dst src); 5318 5319 format %{ "movl $dst, $src\t# int" %} 5320 ins_encode(load_immI(dst, src)); 5321 ins_pipe(ialu_reg_fat); // XXX 5322 %} 5323 5324 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5325 %{ 5326 match(Set dst src); 5327 effect(KILL cr); 5328 5329 ins_cost(50); 5330 format %{ "xorl $dst, $dst\t# int" %} 5331 opcode(0x33); /* + rd */ 5332 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5333 ins_pipe(ialu_reg); 5334 %} 5335 5336 instruct loadConL(rRegL dst, immL src) 5337 %{ 5338 match(Set dst src); 5339 5340 ins_cost(150); 5341 format %{ "movq $dst, $src\t# long" %} 5342 ins_encode(load_immL(dst, src)); 5343 ins_pipe(ialu_reg); 5344 %} 5345 5346 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5347 %{ 5348 match(Set dst src); 5349 effect(KILL cr); 5350 5351 ins_cost(50); 5352 format %{ "xorl $dst, $dst\t# long" %} 5353 opcode(0x33); /* + rd */ 5354 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5355 ins_pipe(ialu_reg); // XXX 5356 %} 5357 5358 instruct loadConUL32(rRegL dst, immUL32 src) 5359 %{ 5360 match(Set dst src); 5361 5362 ins_cost(60); 5363 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5364 ins_encode(load_immUL32(dst, src)); 5365 ins_pipe(ialu_reg); 5366 %} 5367 5368 instruct loadConL32(rRegL dst, immL32 src) 5369 %{ 5370 match(Set dst src); 5371 5372 ins_cost(70); 5373 format %{ "movq $dst, $src\t# long (32-bit)" %} 5374 ins_encode(load_immL32(dst, src)); 5375 ins_pipe(ialu_reg); 5376 %} 5377 5378 instruct loadConP(rRegP dst, immP con) %{ 5379 match(Set dst con); 5380 5381 format %{ "movq $dst, $con\t# ptr" %} 5382 ins_encode(load_immP(dst, con)); 5383 ins_pipe(ialu_reg_fat); // XXX 5384 %} 5385 5386 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5387 %{ 5388 match(Set dst src); 5389 effect(KILL cr); 5390 5391 ins_cost(50); 5392 format %{ "xorl $dst, $dst\t# ptr" %} 5393 opcode(0x33); /* + rd */ 5394 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5395 ins_pipe(ialu_reg); 5396 %} 5397 5398 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5399 %{ 5400 match(Set dst src); 5401 effect(KILL cr); 5402 5403 ins_cost(60); 5404 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5405 ins_encode(load_immP31(dst, src)); 5406 ins_pipe(ialu_reg); 5407 %} 5408 5409 instruct loadConF(regF dst, immF con) %{ 5410 match(Set dst con); 5411 ins_cost(125); 5412 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5413 ins_encode %{ 5414 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5415 %} 5416 ins_pipe(pipe_slow); 5417 %} 5418 5419 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5420 match(Set dst src); 5421 effect(KILL cr); 5422 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5423 ins_encode %{ 5424 __ xorq($dst$$Register, $dst$$Register); 5425 %} 5426 ins_pipe(ialu_reg); 5427 %} 5428 5429 instruct loadConN(rRegN dst, immN src) %{ 5430 match(Set dst src); 5431 5432 ins_cost(125); 5433 format %{ "movl $dst, $src\t# compressed ptr" %} 5434 ins_encode %{ 5435 address con = (address)$src$$constant; 5436 if (con == NULL) { 5437 ShouldNotReachHere(); 5438 } else { 5439 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5440 } 5441 %} 5442 ins_pipe(ialu_reg_fat); // XXX 5443 %} 5444 5445 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5446 match(Set dst src); 5447 5448 ins_cost(125); 5449 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5450 ins_encode %{ 5451 address con = (address)$src$$constant; 5452 if (con == NULL) { 5453 ShouldNotReachHere(); 5454 } else { 5455 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5456 } 5457 %} 5458 ins_pipe(ialu_reg_fat); // XXX 5459 %} 5460 5461 instruct loadConF0(regF dst, immF0 src) 5462 %{ 5463 match(Set dst src); 5464 ins_cost(100); 5465 5466 format %{ "xorps $dst, $dst\t# float 0.0" %} 5467 ins_encode %{ 5468 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5469 %} 5470 ins_pipe(pipe_slow); 5471 %} 5472 5473 // Use the same format since predicate() can not be used here. 5474 instruct loadConD(regD dst, immD con) %{ 5475 match(Set dst con); 5476 ins_cost(125); 5477 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5478 ins_encode %{ 5479 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5480 %} 5481 ins_pipe(pipe_slow); 5482 %} 5483 5484 instruct loadConD0(regD dst, immD0 src) 5485 %{ 5486 match(Set dst src); 5487 ins_cost(100); 5488 5489 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5490 ins_encode %{ 5491 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5492 %} 5493 ins_pipe(pipe_slow); 5494 %} 5495 5496 instruct loadSSI(rRegI dst, stackSlotI src) 5497 %{ 5498 match(Set dst src); 5499 5500 ins_cost(125); 5501 format %{ "movl $dst, $src\t# int stk" %} 5502 opcode(0x8B); 5503 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5504 ins_pipe(ialu_reg_mem); 5505 %} 5506 5507 instruct loadSSL(rRegL dst, stackSlotL src) 5508 %{ 5509 match(Set dst src); 5510 5511 ins_cost(125); 5512 format %{ "movq $dst, $src\t# long stk" %} 5513 opcode(0x8B); 5514 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5515 ins_pipe(ialu_reg_mem); 5516 %} 5517 5518 instruct loadSSP(rRegP dst, stackSlotP src) 5519 %{ 5520 match(Set dst src); 5521 5522 ins_cost(125); 5523 format %{ "movq $dst, $src\t# ptr stk" %} 5524 opcode(0x8B); 5525 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5526 ins_pipe(ialu_reg_mem); 5527 %} 5528 5529 instruct loadSSF(regF dst, stackSlotF src) 5530 %{ 5531 match(Set dst src); 5532 5533 ins_cost(125); 5534 format %{ "movss $dst, $src\t# float stk" %} 5535 ins_encode %{ 5536 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5537 %} 5538 ins_pipe(pipe_slow); // XXX 5539 %} 5540 5541 // Use the same format since predicate() can not be used here. 5542 instruct loadSSD(regD dst, stackSlotD src) 5543 %{ 5544 match(Set dst src); 5545 5546 ins_cost(125); 5547 format %{ "movsd $dst, $src\t# double stk" %} 5548 ins_encode %{ 5549 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5550 %} 5551 ins_pipe(pipe_slow); // XXX 5552 %} 5553 5554 // Prefetch instructions for allocation. 5555 // Must be safe to execute with invalid address (cannot fault). 5556 5557 instruct prefetchAlloc( memory mem ) %{ 5558 predicate(AllocatePrefetchInstr==3); 5559 match(PrefetchAllocation mem); 5560 ins_cost(125); 5561 5562 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5563 ins_encode %{ 5564 __ prefetchw($mem$$Address); 5565 %} 5566 ins_pipe(ialu_mem); 5567 %} 5568 5569 instruct prefetchAllocNTA( memory mem ) %{ 5570 predicate(AllocatePrefetchInstr==0); 5571 match(PrefetchAllocation mem); 5572 ins_cost(125); 5573 5574 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5575 ins_encode %{ 5576 __ prefetchnta($mem$$Address); 5577 %} 5578 ins_pipe(ialu_mem); 5579 %} 5580 5581 instruct prefetchAllocT0( memory mem ) %{ 5582 predicate(AllocatePrefetchInstr==1); 5583 match(PrefetchAllocation mem); 5584 ins_cost(125); 5585 5586 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5587 ins_encode %{ 5588 __ prefetcht0($mem$$Address); 5589 %} 5590 ins_pipe(ialu_mem); 5591 %} 5592 5593 instruct prefetchAllocT2( memory mem ) %{ 5594 predicate(AllocatePrefetchInstr==2); 5595 match(PrefetchAllocation mem); 5596 ins_cost(125); 5597 5598 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5599 ins_encode %{ 5600 __ prefetcht2($mem$$Address); 5601 %} 5602 ins_pipe(ialu_mem); 5603 %} 5604 5605 //----------Store Instructions------------------------------------------------- 5606 5607 // Store Byte 5608 instruct storeB(memory mem, rRegI src) 5609 %{ 5610 match(Set mem (StoreB mem src)); 5611 5612 ins_cost(125); // XXX 5613 format %{ "movb $mem, $src\t# byte" %} 5614 opcode(0x88); 5615 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5616 ins_pipe(ialu_mem_reg); 5617 %} 5618 5619 // Store Char/Short 5620 instruct storeC(memory mem, rRegI src) 5621 %{ 5622 match(Set mem (StoreC mem src)); 5623 5624 ins_cost(125); // XXX 5625 format %{ "movw $mem, $src\t# char/short" %} 5626 opcode(0x89); 5627 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5628 ins_pipe(ialu_mem_reg); 5629 %} 5630 5631 // Store Integer 5632 instruct storeI(memory mem, rRegI src) 5633 %{ 5634 match(Set mem (StoreI mem src)); 5635 5636 ins_cost(125); // XXX 5637 format %{ "movl $mem, $src\t# int" %} 5638 opcode(0x89); 5639 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5640 ins_pipe(ialu_mem_reg); 5641 %} 5642 5643 // Store Long 5644 instruct storeL(memory mem, rRegL src) 5645 %{ 5646 match(Set mem (StoreL mem src)); 5647 5648 ins_cost(125); // XXX 5649 format %{ "movq $mem, $src\t# long" %} 5650 opcode(0x89); 5651 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5652 ins_pipe(ialu_mem_reg); // XXX 5653 %} 5654 5655 // Store Pointer 5656 instruct storeP(memory mem, any_RegP src) 5657 %{ 5658 match(Set mem (StoreP mem src)); 5659 5660 ins_cost(125); // XXX 5661 format %{ "movq $mem, $src\t# ptr" %} 5662 opcode(0x89); 5663 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5664 ins_pipe(ialu_mem_reg); 5665 %} 5666 5667 instruct storeImmP0(memory mem, immP0 zero) 5668 %{ 5669 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5670 match(Set mem (StoreP mem zero)); 5671 5672 ins_cost(125); // XXX 5673 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5674 ins_encode %{ 5675 __ movq($mem$$Address, r12); 5676 %} 5677 ins_pipe(ialu_mem_reg); 5678 %} 5679 5680 // Store NULL Pointer, mark word, or other simple pointer constant. 5681 instruct storeImmP(memory mem, immP31 src) 5682 %{ 5683 match(Set mem (StoreP mem src)); 5684 5685 ins_cost(150); // XXX 5686 format %{ "movq $mem, $src\t# ptr" %} 5687 opcode(0xC7); /* C7 /0 */ 5688 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5689 ins_pipe(ialu_mem_imm); 5690 %} 5691 5692 // Store Compressed Pointer 5693 instruct storeN(memory mem, rRegN src) 5694 %{ 5695 match(Set mem (StoreN mem src)); 5696 5697 ins_cost(125); // XXX 5698 format %{ "movl $mem, $src\t# compressed ptr" %} 5699 ins_encode %{ 5700 __ movl($mem$$Address, $src$$Register); 5701 %} 5702 ins_pipe(ialu_mem_reg); 5703 %} 5704 5705 instruct storeNKlass(memory mem, rRegN src) 5706 %{ 5707 match(Set mem (StoreNKlass mem src)); 5708 5709 ins_cost(125); // XXX 5710 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5711 ins_encode %{ 5712 __ movl($mem$$Address, $src$$Register); 5713 %} 5714 ins_pipe(ialu_mem_reg); 5715 %} 5716 5717 instruct storeImmN0(memory mem, immN0 zero) 5718 %{ 5719 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5720 match(Set mem (StoreN mem zero)); 5721 5722 ins_cost(125); // XXX 5723 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5724 ins_encode %{ 5725 __ movl($mem$$Address, r12); 5726 %} 5727 ins_pipe(ialu_mem_reg); 5728 %} 5729 5730 instruct storeImmN(memory mem, immN src) 5731 %{ 5732 match(Set mem (StoreN mem src)); 5733 5734 ins_cost(150); // XXX 5735 format %{ "movl $mem, $src\t# compressed ptr" %} 5736 ins_encode %{ 5737 address con = (address)$src$$constant; 5738 if (con == NULL) { 5739 __ movl($mem$$Address, (int32_t)0); 5740 } else { 5741 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5742 } 5743 %} 5744 ins_pipe(ialu_mem_imm); 5745 %} 5746 5747 instruct storeImmNKlass(memory mem, immNKlass src) 5748 %{ 5749 match(Set mem (StoreNKlass mem src)); 5750 5751 ins_cost(150); // XXX 5752 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5753 ins_encode %{ 5754 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5755 %} 5756 ins_pipe(ialu_mem_imm); 5757 %} 5758 5759 // Store Integer Immediate 5760 instruct storeImmI0(memory mem, immI0 zero) 5761 %{ 5762 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5763 match(Set mem (StoreI mem zero)); 5764 5765 ins_cost(125); // XXX 5766 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5767 ins_encode %{ 5768 __ movl($mem$$Address, r12); 5769 %} 5770 ins_pipe(ialu_mem_reg); 5771 %} 5772 5773 instruct storeImmI(memory mem, immI src) 5774 %{ 5775 match(Set mem (StoreI mem src)); 5776 5777 ins_cost(150); 5778 format %{ "movl $mem, $src\t# int" %} 5779 opcode(0xC7); /* C7 /0 */ 5780 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5781 ins_pipe(ialu_mem_imm); 5782 %} 5783 5784 // Store Long Immediate 5785 instruct storeImmL0(memory mem, immL0 zero) 5786 %{ 5787 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5788 match(Set mem (StoreL mem zero)); 5789 5790 ins_cost(125); // XXX 5791 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5792 ins_encode %{ 5793 __ movq($mem$$Address, r12); 5794 %} 5795 ins_pipe(ialu_mem_reg); 5796 %} 5797 5798 instruct storeImmL(memory mem, immL32 src) 5799 %{ 5800 match(Set mem (StoreL mem src)); 5801 5802 ins_cost(150); 5803 format %{ "movq $mem, $src\t# long" %} 5804 opcode(0xC7); /* C7 /0 */ 5805 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5806 ins_pipe(ialu_mem_imm); 5807 %} 5808 5809 // Store Short/Char Immediate 5810 instruct storeImmC0(memory mem, immI0 zero) 5811 %{ 5812 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5813 match(Set mem (StoreC mem zero)); 5814 5815 ins_cost(125); // XXX 5816 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5817 ins_encode %{ 5818 __ movw($mem$$Address, r12); 5819 %} 5820 ins_pipe(ialu_mem_reg); 5821 %} 5822 5823 instruct storeImmI16(memory mem, immI16 src) 5824 %{ 5825 predicate(UseStoreImmI16); 5826 match(Set mem (StoreC mem src)); 5827 5828 ins_cost(150); 5829 format %{ "movw $mem, $src\t# short/char" %} 5830 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 5831 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 5832 ins_pipe(ialu_mem_imm); 5833 %} 5834 5835 // Store Byte Immediate 5836 instruct storeImmB0(memory mem, immI0 zero) 5837 %{ 5838 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5839 match(Set mem (StoreB mem zero)); 5840 5841 ins_cost(125); // XXX 5842 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5843 ins_encode %{ 5844 __ movb($mem$$Address, r12); 5845 %} 5846 ins_pipe(ialu_mem_reg); 5847 %} 5848 5849 instruct storeImmB(memory mem, immI8 src) 5850 %{ 5851 match(Set mem (StoreB mem src)); 5852 5853 ins_cost(150); // XXX 5854 format %{ "movb $mem, $src\t# byte" %} 5855 opcode(0xC6); /* C6 /0 */ 5856 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5857 ins_pipe(ialu_mem_imm); 5858 %} 5859 5860 // Store CMS card-mark Immediate 5861 instruct storeImmCM0_reg(memory mem, immI0 zero) 5862 %{ 5863 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5864 match(Set mem (StoreCM mem zero)); 5865 5866 ins_cost(125); // XXX 5867 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5868 ins_encode %{ 5869 __ movb($mem$$Address, r12); 5870 %} 5871 ins_pipe(ialu_mem_reg); 5872 %} 5873 5874 instruct storeImmCM0(memory mem, immI0 src) 5875 %{ 5876 match(Set mem (StoreCM mem src)); 5877 5878 ins_cost(150); // XXX 5879 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5880 opcode(0xC6); /* C6 /0 */ 5881 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5882 ins_pipe(ialu_mem_imm); 5883 %} 5884 5885 // Store Float 5886 instruct storeF(memory mem, regF src) 5887 %{ 5888 match(Set mem (StoreF mem src)); 5889 5890 ins_cost(95); // XXX 5891 format %{ "movss $mem, $src\t# float" %} 5892 ins_encode %{ 5893 __ movflt($mem$$Address, $src$$XMMRegister); 5894 %} 5895 ins_pipe(pipe_slow); // XXX 5896 %} 5897 5898 // Store immediate Float value (it is faster than store from XMM register) 5899 instruct storeF0(memory mem, immF0 zero) 5900 %{ 5901 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5902 match(Set mem (StoreF mem zero)); 5903 5904 ins_cost(25); // XXX 5905 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5906 ins_encode %{ 5907 __ movl($mem$$Address, r12); 5908 %} 5909 ins_pipe(ialu_mem_reg); 5910 %} 5911 5912 instruct storeF_imm(memory mem, immF src) 5913 %{ 5914 match(Set mem (StoreF mem src)); 5915 5916 ins_cost(50); 5917 format %{ "movl $mem, $src\t# float" %} 5918 opcode(0xC7); /* C7 /0 */ 5919 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5920 ins_pipe(ialu_mem_imm); 5921 %} 5922 5923 // Store Double 5924 instruct storeD(memory mem, regD src) 5925 %{ 5926 match(Set mem (StoreD mem src)); 5927 5928 ins_cost(95); // XXX 5929 format %{ "movsd $mem, $src\t# double" %} 5930 ins_encode %{ 5931 __ movdbl($mem$$Address, $src$$XMMRegister); 5932 %} 5933 ins_pipe(pipe_slow); // XXX 5934 %} 5935 5936 // Store immediate double 0.0 (it is faster than store from XMM register) 5937 instruct storeD0_imm(memory mem, immD0 src) 5938 %{ 5939 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 5940 match(Set mem (StoreD mem src)); 5941 5942 ins_cost(50); 5943 format %{ "movq $mem, $src\t# double 0." %} 5944 opcode(0xC7); /* C7 /0 */ 5945 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5946 ins_pipe(ialu_mem_imm); 5947 %} 5948 5949 instruct storeD0(memory mem, immD0 zero) 5950 %{ 5951 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5952 match(Set mem (StoreD mem zero)); 5953 5954 ins_cost(25); // XXX 5955 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5956 ins_encode %{ 5957 __ movq($mem$$Address, r12); 5958 %} 5959 ins_pipe(ialu_mem_reg); 5960 %} 5961 5962 instruct storeSSI(stackSlotI dst, rRegI src) 5963 %{ 5964 match(Set dst src); 5965 5966 ins_cost(100); 5967 format %{ "movl $dst, $src\t# int stk" %} 5968 opcode(0x89); 5969 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 5970 ins_pipe( ialu_mem_reg ); 5971 %} 5972 5973 instruct storeSSL(stackSlotL dst, rRegL src) 5974 %{ 5975 match(Set dst src); 5976 5977 ins_cost(100); 5978 format %{ "movq $dst, $src\t# long stk" %} 5979 opcode(0x89); 5980 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 5981 ins_pipe(ialu_mem_reg); 5982 %} 5983 5984 instruct storeSSP(stackSlotP dst, rRegP src) 5985 %{ 5986 match(Set dst src); 5987 5988 ins_cost(100); 5989 format %{ "movq $dst, $src\t# ptr stk" %} 5990 opcode(0x89); 5991 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 5992 ins_pipe(ialu_mem_reg); 5993 %} 5994 5995 instruct storeSSF(stackSlotF dst, regF src) 5996 %{ 5997 match(Set dst src); 5998 5999 ins_cost(95); // XXX 6000 format %{ "movss $dst, $src\t# float stk" %} 6001 ins_encode %{ 6002 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6003 %} 6004 ins_pipe(pipe_slow); // XXX 6005 %} 6006 6007 instruct storeSSD(stackSlotD dst, regD src) 6008 %{ 6009 match(Set dst src); 6010 6011 ins_cost(95); // XXX 6012 format %{ "movsd $dst, $src\t# double stk" %} 6013 ins_encode %{ 6014 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6015 %} 6016 ins_pipe(pipe_slow); // XXX 6017 %} 6018 6019 //----------BSWAP Instructions------------------------------------------------- 6020 instruct bytes_reverse_int(rRegI dst) %{ 6021 match(Set dst (ReverseBytesI dst)); 6022 6023 format %{ "bswapl $dst" %} 6024 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6025 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6026 ins_pipe( ialu_reg ); 6027 %} 6028 6029 instruct bytes_reverse_long(rRegL dst) %{ 6030 match(Set dst (ReverseBytesL dst)); 6031 6032 format %{ "bswapq $dst" %} 6033 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6034 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6035 ins_pipe( ialu_reg); 6036 %} 6037 6038 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6039 match(Set dst (ReverseBytesUS dst)); 6040 effect(KILL cr); 6041 6042 format %{ "bswapl $dst\n\t" 6043 "shrl $dst,16\n\t" %} 6044 ins_encode %{ 6045 __ bswapl($dst$$Register); 6046 __ shrl($dst$$Register, 16); 6047 %} 6048 ins_pipe( ialu_reg ); 6049 %} 6050 6051 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6052 match(Set dst (ReverseBytesS dst)); 6053 effect(KILL cr); 6054 6055 format %{ "bswapl $dst\n\t" 6056 "sar $dst,16\n\t" %} 6057 ins_encode %{ 6058 __ bswapl($dst$$Register); 6059 __ sarl($dst$$Register, 16); 6060 %} 6061 ins_pipe( ialu_reg ); 6062 %} 6063 6064 //---------- Zeros Count Instructions ------------------------------------------ 6065 6066 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6067 predicate(UseCountLeadingZerosInstruction); 6068 match(Set dst (CountLeadingZerosI src)); 6069 effect(KILL cr); 6070 6071 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6072 ins_encode %{ 6073 __ lzcntl($dst$$Register, $src$$Register); 6074 %} 6075 ins_pipe(ialu_reg); 6076 %} 6077 6078 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6079 predicate(!UseCountLeadingZerosInstruction); 6080 match(Set dst (CountLeadingZerosI src)); 6081 effect(KILL cr); 6082 6083 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6084 "jnz skip\n\t" 6085 "movl $dst, -1\n" 6086 "skip:\n\t" 6087 "negl $dst\n\t" 6088 "addl $dst, 31" %} 6089 ins_encode %{ 6090 Register Rdst = $dst$$Register; 6091 Register Rsrc = $src$$Register; 6092 Label skip; 6093 __ bsrl(Rdst, Rsrc); 6094 __ jccb(Assembler::notZero, skip); 6095 __ movl(Rdst, -1); 6096 __ bind(skip); 6097 __ negl(Rdst); 6098 __ addl(Rdst, BitsPerInt - 1); 6099 %} 6100 ins_pipe(ialu_reg); 6101 %} 6102 6103 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6104 predicate(UseCountLeadingZerosInstruction); 6105 match(Set dst (CountLeadingZerosL src)); 6106 effect(KILL cr); 6107 6108 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6109 ins_encode %{ 6110 __ lzcntq($dst$$Register, $src$$Register); 6111 %} 6112 ins_pipe(ialu_reg); 6113 %} 6114 6115 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6116 predicate(!UseCountLeadingZerosInstruction); 6117 match(Set dst (CountLeadingZerosL src)); 6118 effect(KILL cr); 6119 6120 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6121 "jnz skip\n\t" 6122 "movl $dst, -1\n" 6123 "skip:\n\t" 6124 "negl $dst\n\t" 6125 "addl $dst, 63" %} 6126 ins_encode %{ 6127 Register Rdst = $dst$$Register; 6128 Register Rsrc = $src$$Register; 6129 Label skip; 6130 __ bsrq(Rdst, Rsrc); 6131 __ jccb(Assembler::notZero, skip); 6132 __ movl(Rdst, -1); 6133 __ bind(skip); 6134 __ negl(Rdst); 6135 __ addl(Rdst, BitsPerLong - 1); 6136 %} 6137 ins_pipe(ialu_reg); 6138 %} 6139 6140 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6141 predicate(UseCountTrailingZerosInstruction); 6142 match(Set dst (CountTrailingZerosI src)); 6143 effect(KILL cr); 6144 6145 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6146 ins_encode %{ 6147 __ tzcntl($dst$$Register, $src$$Register); 6148 %} 6149 ins_pipe(ialu_reg); 6150 %} 6151 6152 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6153 predicate(!UseCountTrailingZerosInstruction); 6154 match(Set dst (CountTrailingZerosI src)); 6155 effect(KILL cr); 6156 6157 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6158 "jnz done\n\t" 6159 "movl $dst, 32\n" 6160 "done:" %} 6161 ins_encode %{ 6162 Register Rdst = $dst$$Register; 6163 Label done; 6164 __ bsfl(Rdst, $src$$Register); 6165 __ jccb(Assembler::notZero, done); 6166 __ movl(Rdst, BitsPerInt); 6167 __ bind(done); 6168 %} 6169 ins_pipe(ialu_reg); 6170 %} 6171 6172 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6173 predicate(UseCountTrailingZerosInstruction); 6174 match(Set dst (CountTrailingZerosL src)); 6175 effect(KILL cr); 6176 6177 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6178 ins_encode %{ 6179 __ tzcntq($dst$$Register, $src$$Register); 6180 %} 6181 ins_pipe(ialu_reg); 6182 %} 6183 6184 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6185 predicate(!UseCountTrailingZerosInstruction); 6186 match(Set dst (CountTrailingZerosL src)); 6187 effect(KILL cr); 6188 6189 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6190 "jnz done\n\t" 6191 "movl $dst, 64\n" 6192 "done:" %} 6193 ins_encode %{ 6194 Register Rdst = $dst$$Register; 6195 Label done; 6196 __ bsfq(Rdst, $src$$Register); 6197 __ jccb(Assembler::notZero, done); 6198 __ movl(Rdst, BitsPerLong); 6199 __ bind(done); 6200 %} 6201 ins_pipe(ialu_reg); 6202 %} 6203 6204 6205 //---------- Population Count Instructions ------------------------------------- 6206 6207 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6208 predicate(UsePopCountInstruction); 6209 match(Set dst (PopCountI src)); 6210 effect(KILL cr); 6211 6212 format %{ "popcnt $dst, $src" %} 6213 ins_encode %{ 6214 __ popcntl($dst$$Register, $src$$Register); 6215 %} 6216 ins_pipe(ialu_reg); 6217 %} 6218 6219 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6220 predicate(UsePopCountInstruction); 6221 match(Set dst (PopCountI (LoadI mem))); 6222 effect(KILL cr); 6223 6224 format %{ "popcnt $dst, $mem" %} 6225 ins_encode %{ 6226 __ popcntl($dst$$Register, $mem$$Address); 6227 %} 6228 ins_pipe(ialu_reg); 6229 %} 6230 6231 // Note: Long.bitCount(long) returns an int. 6232 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6233 predicate(UsePopCountInstruction); 6234 match(Set dst (PopCountL src)); 6235 effect(KILL cr); 6236 6237 format %{ "popcnt $dst, $src" %} 6238 ins_encode %{ 6239 __ popcntq($dst$$Register, $src$$Register); 6240 %} 6241 ins_pipe(ialu_reg); 6242 %} 6243 6244 // Note: Long.bitCount(long) returns an int. 6245 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6246 predicate(UsePopCountInstruction); 6247 match(Set dst (PopCountL (LoadL mem))); 6248 effect(KILL cr); 6249 6250 format %{ "popcnt $dst, $mem" %} 6251 ins_encode %{ 6252 __ popcntq($dst$$Register, $mem$$Address); 6253 %} 6254 ins_pipe(ialu_reg); 6255 %} 6256 6257 6258 //----------MemBar Instructions----------------------------------------------- 6259 // Memory barrier flavors 6260 6261 instruct membar_acquire() 6262 %{ 6263 match(MemBarAcquire); 6264 match(LoadFence); 6265 ins_cost(0); 6266 6267 size(0); 6268 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6269 ins_encode(); 6270 ins_pipe(empty); 6271 %} 6272 6273 instruct membar_acquire_lock() 6274 %{ 6275 match(MemBarAcquireLock); 6276 ins_cost(0); 6277 6278 size(0); 6279 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6280 ins_encode(); 6281 ins_pipe(empty); 6282 %} 6283 6284 instruct membar_release() 6285 %{ 6286 match(MemBarRelease); 6287 match(StoreFence); 6288 ins_cost(0); 6289 6290 size(0); 6291 format %{ "MEMBAR-release ! (empty encoding)" %} 6292 ins_encode(); 6293 ins_pipe(empty); 6294 %} 6295 6296 instruct membar_release_lock() 6297 %{ 6298 match(MemBarReleaseLock); 6299 ins_cost(0); 6300 6301 size(0); 6302 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6303 ins_encode(); 6304 ins_pipe(empty); 6305 %} 6306 6307 instruct membar_volatile(rFlagsReg cr) %{ 6308 match(MemBarVolatile); 6309 effect(KILL cr); 6310 ins_cost(400); 6311 6312 format %{ 6313 $$template 6314 if (os::is_MP()) { 6315 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6316 } else { 6317 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6318 } 6319 %} 6320 ins_encode %{ 6321 __ membar(Assembler::StoreLoad); 6322 %} 6323 ins_pipe(pipe_slow); 6324 %} 6325 6326 instruct unnecessary_membar_volatile() 6327 %{ 6328 match(MemBarVolatile); 6329 predicate(Matcher::post_store_load_barrier(n)); 6330 ins_cost(0); 6331 6332 size(0); 6333 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6334 ins_encode(); 6335 ins_pipe(empty); 6336 %} 6337 6338 instruct membar_storestore() %{ 6339 match(MemBarStoreStore); 6340 ins_cost(0); 6341 6342 size(0); 6343 format %{ "MEMBAR-storestore (empty encoding)" %} 6344 ins_encode( ); 6345 ins_pipe(empty); 6346 %} 6347 6348 //----------Move Instructions-------------------------------------------------- 6349 6350 instruct castX2P(rRegP dst, rRegL src) 6351 %{ 6352 match(Set dst (CastX2P src)); 6353 6354 format %{ "movq $dst, $src\t# long->ptr" %} 6355 ins_encode %{ 6356 if ($dst$$reg != $src$$reg) { 6357 __ movptr($dst$$Register, $src$$Register); 6358 } 6359 %} 6360 ins_pipe(ialu_reg_reg); // XXX 6361 %} 6362 6363 instruct castP2X(rRegL dst, rRegP src) 6364 %{ 6365 match(Set dst (CastP2X src)); 6366 6367 format %{ "movq $dst, $src\t# ptr -> long" %} 6368 ins_encode %{ 6369 if ($dst$$reg != $src$$reg) { 6370 __ movptr($dst$$Register, $src$$Register); 6371 } 6372 %} 6373 ins_pipe(ialu_reg_reg); // XXX 6374 %} 6375 6376 // Convert oop into int for vectors alignment masking 6377 instruct convP2I(rRegI dst, rRegP src) 6378 %{ 6379 match(Set dst (ConvL2I (CastP2X src))); 6380 6381 format %{ "movl $dst, $src\t# ptr -> int" %} 6382 ins_encode %{ 6383 __ movl($dst$$Register, $src$$Register); 6384 %} 6385 ins_pipe(ialu_reg_reg); // XXX 6386 %} 6387 6388 // Convert compressed oop into int for vectors alignment masking 6389 // in case of 32bit oops (heap < 4Gb). 6390 instruct convN2I(rRegI dst, rRegN src) 6391 %{ 6392 predicate(Universe::narrow_oop_shift() == 0); 6393 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6394 6395 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6396 ins_encode %{ 6397 __ movl($dst$$Register, $src$$Register); 6398 %} 6399 ins_pipe(ialu_reg_reg); // XXX 6400 %} 6401 6402 // Convert oop pointer into compressed form 6403 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6404 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6405 match(Set dst (EncodeP src)); 6406 effect(KILL cr); 6407 format %{ "encode_heap_oop $dst,$src" %} 6408 ins_encode %{ 6409 Register s = $src$$Register; 6410 Register d = $dst$$Register; 6411 if (s != d) { 6412 __ movq(d, s); 6413 } 6414 __ encode_heap_oop(d); 6415 %} 6416 ins_pipe(ialu_reg_long); 6417 %} 6418 6419 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6420 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6421 match(Set dst (EncodeP src)); 6422 effect(KILL cr); 6423 format %{ "encode_heap_oop_not_null $dst,$src" %} 6424 ins_encode %{ 6425 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6426 %} 6427 ins_pipe(ialu_reg_long); 6428 %} 6429 6430 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6431 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6432 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6433 match(Set dst (DecodeN src)); 6434 effect(KILL cr); 6435 format %{ "decode_heap_oop $dst,$src" %} 6436 ins_encode %{ 6437 Register s = $src$$Register; 6438 Register d = $dst$$Register; 6439 if (s != d) { 6440 __ movq(d, s); 6441 } 6442 __ decode_heap_oop(d); 6443 %} 6444 ins_pipe(ialu_reg_long); 6445 %} 6446 6447 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6448 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6449 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6450 match(Set dst (DecodeN src)); 6451 effect(KILL cr); 6452 format %{ "decode_heap_oop_not_null $dst,$src" %} 6453 ins_encode %{ 6454 Register s = $src$$Register; 6455 Register d = $dst$$Register; 6456 if (s != d) { 6457 __ decode_heap_oop_not_null(d, s); 6458 } else { 6459 __ decode_heap_oop_not_null(d); 6460 } 6461 %} 6462 ins_pipe(ialu_reg_long); 6463 %} 6464 6465 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6466 match(Set dst (EncodePKlass src)); 6467 effect(KILL cr); 6468 format %{ "encode_klass_not_null $dst,$src" %} 6469 ins_encode %{ 6470 __ encode_klass_not_null($dst$$Register, $src$$Register); 6471 %} 6472 ins_pipe(ialu_reg_long); 6473 %} 6474 6475 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6476 match(Set dst (DecodeNKlass src)); 6477 effect(KILL cr); 6478 format %{ "decode_klass_not_null $dst,$src" %} 6479 ins_encode %{ 6480 Register s = $src$$Register; 6481 Register d = $dst$$Register; 6482 if (s != d) { 6483 __ decode_klass_not_null(d, s); 6484 } else { 6485 __ decode_klass_not_null(d); 6486 } 6487 %} 6488 ins_pipe(ialu_reg_long); 6489 %} 6490 6491 6492 //----------Conditional Move--------------------------------------------------- 6493 // Jump 6494 // dummy instruction for generating temp registers 6495 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6496 match(Jump (LShiftL switch_val shift)); 6497 ins_cost(350); 6498 predicate(false); 6499 effect(TEMP dest); 6500 6501 format %{ "leaq $dest, [$constantaddress]\n\t" 6502 "jmp [$dest + $switch_val << $shift]\n\t" %} 6503 ins_encode %{ 6504 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6505 // to do that and the compiler is using that register as one it can allocate. 6506 // So we build it all by hand. 6507 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6508 // ArrayAddress dispatch(table, index); 6509 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6510 __ lea($dest$$Register, $constantaddress); 6511 __ jmp(dispatch); 6512 %} 6513 ins_pipe(pipe_jmp); 6514 %} 6515 6516 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6517 match(Jump (AddL (LShiftL switch_val shift) offset)); 6518 ins_cost(350); 6519 effect(TEMP dest); 6520 6521 format %{ "leaq $dest, [$constantaddress]\n\t" 6522 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6523 ins_encode %{ 6524 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6525 // to do that and the compiler is using that register as one it can allocate. 6526 // So we build it all by hand. 6527 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6528 // ArrayAddress dispatch(table, index); 6529 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6530 __ lea($dest$$Register, $constantaddress); 6531 __ jmp(dispatch); 6532 %} 6533 ins_pipe(pipe_jmp); 6534 %} 6535 6536 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6537 match(Jump switch_val); 6538 ins_cost(350); 6539 effect(TEMP dest); 6540 6541 format %{ "leaq $dest, [$constantaddress]\n\t" 6542 "jmp [$dest + $switch_val]\n\t" %} 6543 ins_encode %{ 6544 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6545 // to do that and the compiler is using that register as one it can allocate. 6546 // So we build it all by hand. 6547 // Address index(noreg, switch_reg, Address::times_1); 6548 // ArrayAddress dispatch(table, index); 6549 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6550 __ lea($dest$$Register, $constantaddress); 6551 __ jmp(dispatch); 6552 %} 6553 ins_pipe(pipe_jmp); 6554 %} 6555 6556 // Conditional move 6557 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6558 %{ 6559 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6560 6561 ins_cost(200); // XXX 6562 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6563 opcode(0x0F, 0x40); 6564 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6565 ins_pipe(pipe_cmov_reg); 6566 %} 6567 6568 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6569 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6570 6571 ins_cost(200); // XXX 6572 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6573 opcode(0x0F, 0x40); 6574 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6575 ins_pipe(pipe_cmov_reg); 6576 %} 6577 6578 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6579 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6580 ins_cost(200); 6581 expand %{ 6582 cmovI_regU(cop, cr, dst, src); 6583 %} 6584 %} 6585 6586 // Conditional move 6587 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6588 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6589 6590 ins_cost(250); // XXX 6591 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6592 opcode(0x0F, 0x40); 6593 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6594 ins_pipe(pipe_cmov_mem); 6595 %} 6596 6597 // Conditional move 6598 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6599 %{ 6600 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6601 6602 ins_cost(250); // XXX 6603 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6604 opcode(0x0F, 0x40); 6605 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6606 ins_pipe(pipe_cmov_mem); 6607 %} 6608 6609 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6610 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6611 ins_cost(250); 6612 expand %{ 6613 cmovI_memU(cop, cr, dst, src); 6614 %} 6615 %} 6616 6617 // Conditional move 6618 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6619 %{ 6620 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6621 6622 ins_cost(200); // XXX 6623 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6624 opcode(0x0F, 0x40); 6625 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6626 ins_pipe(pipe_cmov_reg); 6627 %} 6628 6629 // Conditional move 6630 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6631 %{ 6632 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6633 6634 ins_cost(200); // XXX 6635 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6636 opcode(0x0F, 0x40); 6637 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6638 ins_pipe(pipe_cmov_reg); 6639 %} 6640 6641 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6642 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6643 ins_cost(200); 6644 expand %{ 6645 cmovN_regU(cop, cr, dst, src); 6646 %} 6647 %} 6648 6649 // Conditional move 6650 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6651 %{ 6652 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6653 6654 ins_cost(200); // XXX 6655 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6656 opcode(0x0F, 0x40); 6657 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6658 ins_pipe(pipe_cmov_reg); // XXX 6659 %} 6660 6661 // Conditional move 6662 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6663 %{ 6664 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6665 6666 ins_cost(200); // XXX 6667 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6668 opcode(0x0F, 0x40); 6669 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6670 ins_pipe(pipe_cmov_reg); // XXX 6671 %} 6672 6673 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6674 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6675 ins_cost(200); 6676 expand %{ 6677 cmovP_regU(cop, cr, dst, src); 6678 %} 6679 %} 6680 6681 // DISABLED: Requires the ADLC to emit a bottom_type call that 6682 // correctly meets the two pointer arguments; one is an incoming 6683 // register but the other is a memory operand. ALSO appears to 6684 // be buggy with implicit null checks. 6685 // 6686 //// Conditional move 6687 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6688 //%{ 6689 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6690 // ins_cost(250); 6691 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6692 // opcode(0x0F,0x40); 6693 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6694 // ins_pipe( pipe_cmov_mem ); 6695 //%} 6696 // 6697 //// Conditional move 6698 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6699 //%{ 6700 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6701 // ins_cost(250); 6702 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6703 // opcode(0x0F,0x40); 6704 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6705 // ins_pipe( pipe_cmov_mem ); 6706 //%} 6707 6708 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6709 %{ 6710 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6711 6712 ins_cost(200); // XXX 6713 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6714 opcode(0x0F, 0x40); 6715 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6716 ins_pipe(pipe_cmov_reg); // XXX 6717 %} 6718 6719 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6720 %{ 6721 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6722 6723 ins_cost(200); // XXX 6724 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6725 opcode(0x0F, 0x40); 6726 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6727 ins_pipe(pipe_cmov_mem); // XXX 6728 %} 6729 6730 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6731 %{ 6732 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6733 6734 ins_cost(200); // XXX 6735 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6736 opcode(0x0F, 0x40); 6737 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6738 ins_pipe(pipe_cmov_reg); // XXX 6739 %} 6740 6741 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6742 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6743 ins_cost(200); 6744 expand %{ 6745 cmovL_regU(cop, cr, dst, src); 6746 %} 6747 %} 6748 6749 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6750 %{ 6751 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6752 6753 ins_cost(200); // XXX 6754 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6755 opcode(0x0F, 0x40); 6756 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6757 ins_pipe(pipe_cmov_mem); // XXX 6758 %} 6759 6760 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6761 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6762 ins_cost(200); 6763 expand %{ 6764 cmovL_memU(cop, cr, dst, src); 6765 %} 6766 %} 6767 6768 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6769 %{ 6770 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6771 6772 ins_cost(200); // XXX 6773 format %{ "jn$cop skip\t# signed cmove float\n\t" 6774 "movss $dst, $src\n" 6775 "skip:" %} 6776 ins_encode %{ 6777 Label Lskip; 6778 // Invert sense of branch from sense of CMOV 6779 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6780 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6781 __ bind(Lskip); 6782 %} 6783 ins_pipe(pipe_slow); 6784 %} 6785 6786 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6787 // %{ 6788 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 6789 6790 // ins_cost(200); // XXX 6791 // format %{ "jn$cop skip\t# signed cmove float\n\t" 6792 // "movss $dst, $src\n" 6793 // "skip:" %} 6794 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 6795 // ins_pipe(pipe_slow); 6796 // %} 6797 6798 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6799 %{ 6800 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6801 6802 ins_cost(200); // XXX 6803 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6804 "movss $dst, $src\n" 6805 "skip:" %} 6806 ins_encode %{ 6807 Label Lskip; 6808 // Invert sense of branch from sense of CMOV 6809 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6810 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6811 __ bind(Lskip); 6812 %} 6813 ins_pipe(pipe_slow); 6814 %} 6815 6816 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6817 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6818 ins_cost(200); 6819 expand %{ 6820 cmovF_regU(cop, cr, dst, src); 6821 %} 6822 %} 6823 6824 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6825 %{ 6826 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6827 6828 ins_cost(200); // XXX 6829 format %{ "jn$cop skip\t# signed cmove double\n\t" 6830 "movsd $dst, $src\n" 6831 "skip:" %} 6832 ins_encode %{ 6833 Label Lskip; 6834 // Invert sense of branch from sense of CMOV 6835 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6836 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6837 __ bind(Lskip); 6838 %} 6839 ins_pipe(pipe_slow); 6840 %} 6841 6842 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6843 %{ 6844 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6845 6846 ins_cost(200); // XXX 6847 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6848 "movsd $dst, $src\n" 6849 "skip:" %} 6850 ins_encode %{ 6851 Label Lskip; 6852 // Invert sense of branch from sense of CMOV 6853 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6854 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6855 __ bind(Lskip); 6856 %} 6857 ins_pipe(pipe_slow); 6858 %} 6859 6860 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6861 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6862 ins_cost(200); 6863 expand %{ 6864 cmovD_regU(cop, cr, dst, src); 6865 %} 6866 %} 6867 6868 //----------Arithmetic Instructions-------------------------------------------- 6869 //----------Addition Instructions---------------------------------------------- 6870 6871 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6872 %{ 6873 match(Set dst (AddI dst src)); 6874 effect(KILL cr); 6875 6876 format %{ "addl $dst, $src\t# int" %} 6877 opcode(0x03); 6878 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 6879 ins_pipe(ialu_reg_reg); 6880 %} 6881 6882 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6883 %{ 6884 match(Set dst (AddI dst src)); 6885 effect(KILL cr); 6886 6887 format %{ "addl $dst, $src\t# int" %} 6888 opcode(0x81, 0x00); /* /0 id */ 6889 ins_encode(OpcSErm(dst, src), Con8or32(src)); 6890 ins_pipe( ialu_reg ); 6891 %} 6892 6893 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6894 %{ 6895 match(Set dst (AddI dst (LoadI src))); 6896 effect(KILL cr); 6897 6898 ins_cost(125); // XXX 6899 format %{ "addl $dst, $src\t# int" %} 6900 opcode(0x03); 6901 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6902 ins_pipe(ialu_reg_mem); 6903 %} 6904 6905 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6906 %{ 6907 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6908 effect(KILL cr); 6909 6910 ins_cost(150); // XXX 6911 format %{ "addl $dst, $src\t# int" %} 6912 opcode(0x01); /* Opcode 01 /r */ 6913 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6914 ins_pipe(ialu_mem_reg); 6915 %} 6916 6917 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6918 %{ 6919 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6920 effect(KILL cr); 6921 6922 ins_cost(125); // XXX 6923 format %{ "addl $dst, $src\t# int" %} 6924 opcode(0x81); /* Opcode 81 /0 id */ 6925 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 6926 ins_pipe(ialu_mem_imm); 6927 %} 6928 6929 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 6930 %{ 6931 predicate(UseIncDec); 6932 match(Set dst (AddI dst src)); 6933 effect(KILL cr); 6934 6935 format %{ "incl $dst\t# int" %} 6936 opcode(0xFF, 0x00); // FF /0 6937 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6938 ins_pipe(ialu_reg); 6939 %} 6940 6941 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 6942 %{ 6943 predicate(UseIncDec); 6944 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6945 effect(KILL cr); 6946 6947 ins_cost(125); // XXX 6948 format %{ "incl $dst\t# int" %} 6949 opcode(0xFF); /* Opcode FF /0 */ 6950 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 6951 ins_pipe(ialu_mem_imm); 6952 %} 6953 6954 // XXX why does that use AddI 6955 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6956 %{ 6957 predicate(UseIncDec); 6958 match(Set dst (AddI dst src)); 6959 effect(KILL cr); 6960 6961 format %{ "decl $dst\t# int" %} 6962 opcode(0xFF, 0x01); // FF /1 6963 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6964 ins_pipe(ialu_reg); 6965 %} 6966 6967 // XXX why does that use AddI 6968 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6969 %{ 6970 predicate(UseIncDec); 6971 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6972 effect(KILL cr); 6973 6974 ins_cost(125); // XXX 6975 format %{ "decl $dst\t# int" %} 6976 opcode(0xFF); /* Opcode FF /1 */ 6977 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 6978 ins_pipe(ialu_mem_imm); 6979 %} 6980 6981 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 6982 %{ 6983 match(Set dst (AddI src0 src1)); 6984 6985 ins_cost(110); 6986 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 6987 opcode(0x8D); /* 0x8D /r */ 6988 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 6989 ins_pipe(ialu_reg_reg); 6990 %} 6991 6992 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6993 %{ 6994 match(Set dst (AddL dst src)); 6995 effect(KILL cr); 6996 6997 format %{ "addq $dst, $src\t# long" %} 6998 opcode(0x03); 6999 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7000 ins_pipe(ialu_reg_reg); 7001 %} 7002 7003 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7004 %{ 7005 match(Set dst (AddL dst src)); 7006 effect(KILL cr); 7007 7008 format %{ "addq $dst, $src\t# long" %} 7009 opcode(0x81, 0x00); /* /0 id */ 7010 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7011 ins_pipe( ialu_reg ); 7012 %} 7013 7014 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7015 %{ 7016 match(Set dst (AddL dst (LoadL src))); 7017 effect(KILL cr); 7018 7019 ins_cost(125); // XXX 7020 format %{ "addq $dst, $src\t# long" %} 7021 opcode(0x03); 7022 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7023 ins_pipe(ialu_reg_mem); 7024 %} 7025 7026 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7027 %{ 7028 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7029 effect(KILL cr); 7030 7031 ins_cost(150); // XXX 7032 format %{ "addq $dst, $src\t# long" %} 7033 opcode(0x01); /* Opcode 01 /r */ 7034 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7035 ins_pipe(ialu_mem_reg); 7036 %} 7037 7038 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7039 %{ 7040 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7041 effect(KILL cr); 7042 7043 ins_cost(125); // XXX 7044 format %{ "addq $dst, $src\t# long" %} 7045 opcode(0x81); /* Opcode 81 /0 id */ 7046 ins_encode(REX_mem_wide(dst), 7047 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7048 ins_pipe(ialu_mem_imm); 7049 %} 7050 7051 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7052 %{ 7053 predicate(UseIncDec); 7054 match(Set dst (AddL dst src)); 7055 effect(KILL cr); 7056 7057 format %{ "incq $dst\t# long" %} 7058 opcode(0xFF, 0x00); // FF /0 7059 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7060 ins_pipe(ialu_reg); 7061 %} 7062 7063 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7064 %{ 7065 predicate(UseIncDec); 7066 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7067 effect(KILL cr); 7068 7069 ins_cost(125); // XXX 7070 format %{ "incq $dst\t# long" %} 7071 opcode(0xFF); /* Opcode FF /0 */ 7072 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7073 ins_pipe(ialu_mem_imm); 7074 %} 7075 7076 // XXX why does that use AddL 7077 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7078 %{ 7079 predicate(UseIncDec); 7080 match(Set dst (AddL dst src)); 7081 effect(KILL cr); 7082 7083 format %{ "decq $dst\t# long" %} 7084 opcode(0xFF, 0x01); // FF /1 7085 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7086 ins_pipe(ialu_reg); 7087 %} 7088 7089 // XXX why does that use AddL 7090 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7091 %{ 7092 predicate(UseIncDec); 7093 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7094 effect(KILL cr); 7095 7096 ins_cost(125); // XXX 7097 format %{ "decq $dst\t# long" %} 7098 opcode(0xFF); /* Opcode FF /1 */ 7099 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7100 ins_pipe(ialu_mem_imm); 7101 %} 7102 7103 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7104 %{ 7105 match(Set dst (AddL src0 src1)); 7106 7107 ins_cost(110); 7108 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7109 opcode(0x8D); /* 0x8D /r */ 7110 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7111 ins_pipe(ialu_reg_reg); 7112 %} 7113 7114 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7115 %{ 7116 match(Set dst (AddP dst src)); 7117 effect(KILL cr); 7118 7119 format %{ "addq $dst, $src\t# ptr" %} 7120 opcode(0x03); 7121 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7122 ins_pipe(ialu_reg_reg); 7123 %} 7124 7125 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7126 %{ 7127 match(Set dst (AddP dst src)); 7128 effect(KILL cr); 7129 7130 format %{ "addq $dst, $src\t# ptr" %} 7131 opcode(0x81, 0x00); /* /0 id */ 7132 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7133 ins_pipe( ialu_reg ); 7134 %} 7135 7136 // XXX addP mem ops ???? 7137 7138 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7139 %{ 7140 match(Set dst (AddP src0 src1)); 7141 7142 ins_cost(110); 7143 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7144 opcode(0x8D); /* 0x8D /r */ 7145 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7146 ins_pipe(ialu_reg_reg); 7147 %} 7148 7149 instruct checkCastPP(rRegP dst) 7150 %{ 7151 match(Set dst (CheckCastPP dst)); 7152 7153 size(0); 7154 format %{ "# checkcastPP of $dst" %} 7155 ins_encode(/* empty encoding */); 7156 ins_pipe(empty); 7157 %} 7158 7159 instruct castPP(rRegP dst) 7160 %{ 7161 match(Set dst (CastPP dst)); 7162 7163 size(0); 7164 format %{ "# castPP of $dst" %} 7165 ins_encode(/* empty encoding */); 7166 ins_pipe(empty); 7167 %} 7168 7169 instruct castII(rRegI dst) 7170 %{ 7171 match(Set dst (CastII dst)); 7172 7173 size(0); 7174 format %{ "# castII of $dst" %} 7175 ins_encode(/* empty encoding */); 7176 ins_cost(0); 7177 ins_pipe(empty); 7178 %} 7179 7180 // LoadP-locked same as a regular LoadP when used with compare-swap 7181 instruct loadPLocked(rRegP dst, memory mem) 7182 %{ 7183 match(Set dst (LoadPLocked mem)); 7184 7185 ins_cost(125); // XXX 7186 format %{ "movq $dst, $mem\t# ptr locked" %} 7187 opcode(0x8B); 7188 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7189 ins_pipe(ialu_reg_mem); // XXX 7190 %} 7191 7192 // Conditional-store of the updated heap-top. 7193 // Used during allocation of the shared heap. 7194 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7195 7196 instruct storePConditional(memory heap_top_ptr, 7197 rax_RegP oldval, rRegP newval, 7198 rFlagsReg cr) 7199 %{ 7200 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7201 7202 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7203 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7204 opcode(0x0F, 0xB1); 7205 ins_encode(lock_prefix, 7206 REX_reg_mem_wide(newval, heap_top_ptr), 7207 OpcP, OpcS, 7208 reg_mem(newval, heap_top_ptr)); 7209 ins_pipe(pipe_cmpxchg); 7210 %} 7211 7212 // Conditional-store of an int value. 7213 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7214 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7215 %{ 7216 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7217 effect(KILL oldval); 7218 7219 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7220 opcode(0x0F, 0xB1); 7221 ins_encode(lock_prefix, 7222 REX_reg_mem(newval, mem), 7223 OpcP, OpcS, 7224 reg_mem(newval, mem)); 7225 ins_pipe(pipe_cmpxchg); 7226 %} 7227 7228 // Conditional-store of a long value. 7229 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7230 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7231 %{ 7232 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7233 effect(KILL oldval); 7234 7235 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7236 opcode(0x0F, 0xB1); 7237 ins_encode(lock_prefix, 7238 REX_reg_mem_wide(newval, mem), 7239 OpcP, OpcS, 7240 reg_mem(newval, mem)); 7241 ins_pipe(pipe_cmpxchg); 7242 %} 7243 7244 7245 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7246 instruct compareAndSwapP(rRegI res, 7247 memory mem_ptr, 7248 rax_RegP oldval, rRegP newval, 7249 rFlagsReg cr) 7250 %{ 7251 predicate(VM_Version::supports_cx8()); 7252 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7253 effect(KILL cr, KILL oldval); 7254 7255 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7256 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7257 "sete $res\n\t" 7258 "movzbl $res, $res" %} 7259 opcode(0x0F, 0xB1); 7260 ins_encode(lock_prefix, 7261 REX_reg_mem_wide(newval, mem_ptr), 7262 OpcP, OpcS, 7263 reg_mem(newval, mem_ptr), 7264 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7265 REX_reg_breg(res, res), // movzbl 7266 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7267 ins_pipe( pipe_cmpxchg ); 7268 %} 7269 7270 instruct compareAndSwapL(rRegI res, 7271 memory mem_ptr, 7272 rax_RegL oldval, rRegL newval, 7273 rFlagsReg cr) 7274 %{ 7275 predicate(VM_Version::supports_cx8()); 7276 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7277 effect(KILL cr, KILL oldval); 7278 7279 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7280 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7281 "sete $res\n\t" 7282 "movzbl $res, $res" %} 7283 opcode(0x0F, 0xB1); 7284 ins_encode(lock_prefix, 7285 REX_reg_mem_wide(newval, mem_ptr), 7286 OpcP, OpcS, 7287 reg_mem(newval, mem_ptr), 7288 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7289 REX_reg_breg(res, res), // movzbl 7290 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7291 ins_pipe( pipe_cmpxchg ); 7292 %} 7293 7294 instruct compareAndSwapI(rRegI res, 7295 memory mem_ptr, 7296 rax_RegI oldval, rRegI newval, 7297 rFlagsReg cr) 7298 %{ 7299 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7300 effect(KILL cr, KILL oldval); 7301 7302 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7303 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7304 "sete $res\n\t" 7305 "movzbl $res, $res" %} 7306 opcode(0x0F, 0xB1); 7307 ins_encode(lock_prefix, 7308 REX_reg_mem(newval, mem_ptr), 7309 OpcP, OpcS, 7310 reg_mem(newval, mem_ptr), 7311 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7312 REX_reg_breg(res, res), // movzbl 7313 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7314 ins_pipe( pipe_cmpxchg ); 7315 %} 7316 7317 7318 instruct compareAndSwapN(rRegI res, 7319 memory mem_ptr, 7320 rax_RegN oldval, rRegN newval, 7321 rFlagsReg cr) %{ 7322 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7323 effect(KILL cr, KILL oldval); 7324 7325 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7326 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7327 "sete $res\n\t" 7328 "movzbl $res, $res" %} 7329 opcode(0x0F, 0xB1); 7330 ins_encode(lock_prefix, 7331 REX_reg_mem(newval, mem_ptr), 7332 OpcP, OpcS, 7333 reg_mem(newval, mem_ptr), 7334 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7335 REX_reg_breg(res, res), // movzbl 7336 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7337 ins_pipe( pipe_cmpxchg ); 7338 %} 7339 7340 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7341 predicate(n->as_LoadStore()->result_not_used()); 7342 match(Set dummy (GetAndAddI mem add)); 7343 effect(KILL cr); 7344 format %{ "ADDL [$mem],$add" %} 7345 ins_encode %{ 7346 if (os::is_MP()) { __ lock(); } 7347 __ addl($mem$$Address, $add$$constant); 7348 %} 7349 ins_pipe( pipe_cmpxchg ); 7350 %} 7351 7352 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7353 match(Set newval (GetAndAddI mem newval)); 7354 effect(KILL cr); 7355 format %{ "XADDL [$mem],$newval" %} 7356 ins_encode %{ 7357 if (os::is_MP()) { __ lock(); } 7358 __ xaddl($mem$$Address, $newval$$Register); 7359 %} 7360 ins_pipe( pipe_cmpxchg ); 7361 %} 7362 7363 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7364 predicate(n->as_LoadStore()->result_not_used()); 7365 match(Set dummy (GetAndAddL mem add)); 7366 effect(KILL cr); 7367 format %{ "ADDQ [$mem],$add" %} 7368 ins_encode %{ 7369 if (os::is_MP()) { __ lock(); } 7370 __ addq($mem$$Address, $add$$constant); 7371 %} 7372 ins_pipe( pipe_cmpxchg ); 7373 %} 7374 7375 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7376 match(Set newval (GetAndAddL mem newval)); 7377 effect(KILL cr); 7378 format %{ "XADDQ [$mem],$newval" %} 7379 ins_encode %{ 7380 if (os::is_MP()) { __ lock(); } 7381 __ xaddq($mem$$Address, $newval$$Register); 7382 %} 7383 ins_pipe( pipe_cmpxchg ); 7384 %} 7385 7386 instruct xchgI( memory mem, rRegI newval) %{ 7387 match(Set newval (GetAndSetI mem newval)); 7388 format %{ "XCHGL $newval,[$mem]" %} 7389 ins_encode %{ 7390 __ xchgl($newval$$Register, $mem$$Address); 7391 %} 7392 ins_pipe( pipe_cmpxchg ); 7393 %} 7394 7395 instruct xchgL( memory mem, rRegL newval) %{ 7396 match(Set newval (GetAndSetL mem newval)); 7397 format %{ "XCHGL $newval,[$mem]" %} 7398 ins_encode %{ 7399 __ xchgq($newval$$Register, $mem$$Address); 7400 %} 7401 ins_pipe( pipe_cmpxchg ); 7402 %} 7403 7404 instruct xchgP( memory mem, rRegP newval) %{ 7405 match(Set newval (GetAndSetP mem newval)); 7406 format %{ "XCHGQ $newval,[$mem]" %} 7407 ins_encode %{ 7408 __ xchgq($newval$$Register, $mem$$Address); 7409 %} 7410 ins_pipe( pipe_cmpxchg ); 7411 %} 7412 7413 instruct xchgN( memory mem, rRegN newval) %{ 7414 match(Set newval (GetAndSetN mem newval)); 7415 format %{ "XCHGL $newval,$mem]" %} 7416 ins_encode %{ 7417 __ xchgl($newval$$Register, $mem$$Address); 7418 %} 7419 ins_pipe( pipe_cmpxchg ); 7420 %} 7421 7422 //----------Subtraction Instructions------------------------------------------- 7423 7424 // Integer Subtraction Instructions 7425 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7426 %{ 7427 match(Set dst (SubI dst src)); 7428 effect(KILL cr); 7429 7430 format %{ "subl $dst, $src\t# int" %} 7431 opcode(0x2B); 7432 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7433 ins_pipe(ialu_reg_reg); 7434 %} 7435 7436 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7437 %{ 7438 match(Set dst (SubI dst src)); 7439 effect(KILL cr); 7440 7441 format %{ "subl $dst, $src\t# int" %} 7442 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7443 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7444 ins_pipe(ialu_reg); 7445 %} 7446 7447 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7448 %{ 7449 match(Set dst (SubI dst (LoadI src))); 7450 effect(KILL cr); 7451 7452 ins_cost(125); 7453 format %{ "subl $dst, $src\t# int" %} 7454 opcode(0x2B); 7455 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7456 ins_pipe(ialu_reg_mem); 7457 %} 7458 7459 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7460 %{ 7461 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7462 effect(KILL cr); 7463 7464 ins_cost(150); 7465 format %{ "subl $dst, $src\t# int" %} 7466 opcode(0x29); /* Opcode 29 /r */ 7467 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7468 ins_pipe(ialu_mem_reg); 7469 %} 7470 7471 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7472 %{ 7473 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7474 effect(KILL cr); 7475 7476 ins_cost(125); // XXX 7477 format %{ "subl $dst, $src\t# int" %} 7478 opcode(0x81); /* Opcode 81 /5 id */ 7479 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7480 ins_pipe(ialu_mem_imm); 7481 %} 7482 7483 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7484 %{ 7485 match(Set dst (SubL dst src)); 7486 effect(KILL cr); 7487 7488 format %{ "subq $dst, $src\t# long" %} 7489 opcode(0x2B); 7490 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7491 ins_pipe(ialu_reg_reg); 7492 %} 7493 7494 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7495 %{ 7496 match(Set dst (SubL dst src)); 7497 effect(KILL cr); 7498 7499 format %{ "subq $dst, $src\t# long" %} 7500 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7501 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7502 ins_pipe(ialu_reg); 7503 %} 7504 7505 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7506 %{ 7507 match(Set dst (SubL dst (LoadL src))); 7508 effect(KILL cr); 7509 7510 ins_cost(125); 7511 format %{ "subq $dst, $src\t# long" %} 7512 opcode(0x2B); 7513 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7514 ins_pipe(ialu_reg_mem); 7515 %} 7516 7517 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7518 %{ 7519 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7520 effect(KILL cr); 7521 7522 ins_cost(150); 7523 format %{ "subq $dst, $src\t# long" %} 7524 opcode(0x29); /* Opcode 29 /r */ 7525 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7526 ins_pipe(ialu_mem_reg); 7527 %} 7528 7529 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7530 %{ 7531 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7532 effect(KILL cr); 7533 7534 ins_cost(125); // XXX 7535 format %{ "subq $dst, $src\t# long" %} 7536 opcode(0x81); /* Opcode 81 /5 id */ 7537 ins_encode(REX_mem_wide(dst), 7538 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7539 ins_pipe(ialu_mem_imm); 7540 %} 7541 7542 // Subtract from a pointer 7543 // XXX hmpf??? 7544 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7545 %{ 7546 match(Set dst (AddP dst (SubI zero src))); 7547 effect(KILL cr); 7548 7549 format %{ "subq $dst, $src\t# ptr - int" %} 7550 opcode(0x2B); 7551 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7552 ins_pipe(ialu_reg_reg); 7553 %} 7554 7555 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7556 %{ 7557 match(Set dst (SubI zero dst)); 7558 effect(KILL cr); 7559 7560 format %{ "negl $dst\t# int" %} 7561 opcode(0xF7, 0x03); // Opcode F7 /3 7562 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7563 ins_pipe(ialu_reg); 7564 %} 7565 7566 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7567 %{ 7568 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7569 effect(KILL cr); 7570 7571 format %{ "negl $dst\t# int" %} 7572 opcode(0xF7, 0x03); // Opcode F7 /3 7573 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7574 ins_pipe(ialu_reg); 7575 %} 7576 7577 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7578 %{ 7579 match(Set dst (SubL zero dst)); 7580 effect(KILL cr); 7581 7582 format %{ "negq $dst\t# long" %} 7583 opcode(0xF7, 0x03); // Opcode F7 /3 7584 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7585 ins_pipe(ialu_reg); 7586 %} 7587 7588 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7589 %{ 7590 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7591 effect(KILL cr); 7592 7593 format %{ "negq $dst\t# long" %} 7594 opcode(0xF7, 0x03); // Opcode F7 /3 7595 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7596 ins_pipe(ialu_reg); 7597 %} 7598 7599 //----------Multiplication/Division Instructions------------------------------- 7600 // Integer Multiplication Instructions 7601 // Multiply Register 7602 7603 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7604 %{ 7605 match(Set dst (MulI dst src)); 7606 effect(KILL cr); 7607 7608 ins_cost(300); 7609 format %{ "imull $dst, $src\t# int" %} 7610 opcode(0x0F, 0xAF); 7611 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7612 ins_pipe(ialu_reg_reg_alu0); 7613 %} 7614 7615 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7616 %{ 7617 match(Set dst (MulI src imm)); 7618 effect(KILL cr); 7619 7620 ins_cost(300); 7621 format %{ "imull $dst, $src, $imm\t# int" %} 7622 opcode(0x69); /* 69 /r id */ 7623 ins_encode(REX_reg_reg(dst, src), 7624 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7625 ins_pipe(ialu_reg_reg_alu0); 7626 %} 7627 7628 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7629 %{ 7630 match(Set dst (MulI dst (LoadI src))); 7631 effect(KILL cr); 7632 7633 ins_cost(350); 7634 format %{ "imull $dst, $src\t# int" %} 7635 opcode(0x0F, 0xAF); 7636 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7637 ins_pipe(ialu_reg_mem_alu0); 7638 %} 7639 7640 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7641 %{ 7642 match(Set dst (MulI (LoadI src) imm)); 7643 effect(KILL cr); 7644 7645 ins_cost(300); 7646 format %{ "imull $dst, $src, $imm\t# int" %} 7647 opcode(0x69); /* 69 /r id */ 7648 ins_encode(REX_reg_mem(dst, src), 7649 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7650 ins_pipe(ialu_reg_mem_alu0); 7651 %} 7652 7653 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7654 %{ 7655 match(Set dst (MulL dst src)); 7656 effect(KILL cr); 7657 7658 ins_cost(300); 7659 format %{ "imulq $dst, $src\t# long" %} 7660 opcode(0x0F, 0xAF); 7661 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7662 ins_pipe(ialu_reg_reg_alu0); 7663 %} 7664 7665 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7666 %{ 7667 match(Set dst (MulL src imm)); 7668 effect(KILL cr); 7669 7670 ins_cost(300); 7671 format %{ "imulq $dst, $src, $imm\t# long" %} 7672 opcode(0x69); /* 69 /r id */ 7673 ins_encode(REX_reg_reg_wide(dst, src), 7674 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7675 ins_pipe(ialu_reg_reg_alu0); 7676 %} 7677 7678 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7679 %{ 7680 match(Set dst (MulL dst (LoadL src))); 7681 effect(KILL cr); 7682 7683 ins_cost(350); 7684 format %{ "imulq $dst, $src\t# long" %} 7685 opcode(0x0F, 0xAF); 7686 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7687 ins_pipe(ialu_reg_mem_alu0); 7688 %} 7689 7690 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7691 %{ 7692 match(Set dst (MulL (LoadL src) imm)); 7693 effect(KILL cr); 7694 7695 ins_cost(300); 7696 format %{ "imulq $dst, $src, $imm\t# long" %} 7697 opcode(0x69); /* 69 /r id */ 7698 ins_encode(REX_reg_mem_wide(dst, src), 7699 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7700 ins_pipe(ialu_reg_mem_alu0); 7701 %} 7702 7703 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7704 %{ 7705 match(Set dst (MulHiL src rax)); 7706 effect(USE_KILL rax, KILL cr); 7707 7708 ins_cost(300); 7709 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7710 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7711 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7712 ins_pipe(ialu_reg_reg_alu0); 7713 %} 7714 7715 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7716 rFlagsReg cr) 7717 %{ 7718 match(Set rax (DivI rax div)); 7719 effect(KILL rdx, KILL cr); 7720 7721 ins_cost(30*100+10*100); // XXX 7722 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7723 "jne,s normal\n\t" 7724 "xorl rdx, rdx\n\t" 7725 "cmpl $div, -1\n\t" 7726 "je,s done\n" 7727 "normal: cdql\n\t" 7728 "idivl $div\n" 7729 "done:" %} 7730 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7731 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7732 ins_pipe(ialu_reg_reg_alu0); 7733 %} 7734 7735 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7736 rFlagsReg cr) 7737 %{ 7738 match(Set rax (DivL rax div)); 7739 effect(KILL rdx, KILL cr); 7740 7741 ins_cost(30*100+10*100); // XXX 7742 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7743 "cmpq rax, rdx\n\t" 7744 "jne,s normal\n\t" 7745 "xorl rdx, rdx\n\t" 7746 "cmpq $div, -1\n\t" 7747 "je,s done\n" 7748 "normal: cdqq\n\t" 7749 "idivq $div\n" 7750 "done:" %} 7751 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7752 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7753 ins_pipe(ialu_reg_reg_alu0); 7754 %} 7755 7756 // Integer DIVMOD with Register, both quotient and mod results 7757 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7758 rFlagsReg cr) 7759 %{ 7760 match(DivModI rax div); 7761 effect(KILL cr); 7762 7763 ins_cost(30*100+10*100); // XXX 7764 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7765 "jne,s normal\n\t" 7766 "xorl rdx, rdx\n\t" 7767 "cmpl $div, -1\n\t" 7768 "je,s done\n" 7769 "normal: cdql\n\t" 7770 "idivl $div\n" 7771 "done:" %} 7772 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7773 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7774 ins_pipe(pipe_slow); 7775 %} 7776 7777 // Long DIVMOD with Register, both quotient and mod results 7778 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7779 rFlagsReg cr) 7780 %{ 7781 match(DivModL rax div); 7782 effect(KILL cr); 7783 7784 ins_cost(30*100+10*100); // XXX 7785 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7786 "cmpq rax, rdx\n\t" 7787 "jne,s normal\n\t" 7788 "xorl rdx, rdx\n\t" 7789 "cmpq $div, -1\n\t" 7790 "je,s done\n" 7791 "normal: cdqq\n\t" 7792 "idivq $div\n" 7793 "done:" %} 7794 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7795 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7796 ins_pipe(pipe_slow); 7797 %} 7798 7799 //----------- DivL-By-Constant-Expansions-------------------------------------- 7800 // DivI cases are handled by the compiler 7801 7802 // Magic constant, reciprocal of 10 7803 instruct loadConL_0x6666666666666667(rRegL dst) 7804 %{ 7805 effect(DEF dst); 7806 7807 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 7808 ins_encode(load_immL(dst, 0x6666666666666667)); 7809 ins_pipe(ialu_reg); 7810 %} 7811 7812 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7813 %{ 7814 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 7815 7816 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 7817 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7818 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7819 ins_pipe(ialu_reg_reg_alu0); 7820 %} 7821 7822 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 7823 %{ 7824 effect(USE_DEF dst, KILL cr); 7825 7826 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 7827 opcode(0xC1, 0x7); /* C1 /7 ib */ 7828 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 7829 ins_pipe(ialu_reg); 7830 %} 7831 7832 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 7833 %{ 7834 effect(USE_DEF dst, KILL cr); 7835 7836 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 7837 opcode(0xC1, 0x7); /* C1 /7 ib */ 7838 ins_encode(reg_opc_imm_wide(dst, 0x2)); 7839 ins_pipe(ialu_reg); 7840 %} 7841 7842 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 7843 %{ 7844 match(Set dst (DivL src div)); 7845 7846 ins_cost((5+8)*100); 7847 expand %{ 7848 rax_RegL rax; // Killed temp 7849 rFlagsReg cr; // Killed 7850 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 7851 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 7852 sarL_rReg_63(src, cr); // sarq src, 63 7853 sarL_rReg_2(dst, cr); // sarq rdx, 2 7854 subL_rReg(dst, src, cr); // subl rdx, src 7855 %} 7856 %} 7857 7858 //----------------------------------------------------------------------------- 7859 7860 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7861 rFlagsReg cr) 7862 %{ 7863 match(Set rdx (ModI rax div)); 7864 effect(KILL rax, KILL cr); 7865 7866 ins_cost(300); // XXX 7867 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7868 "jne,s normal\n\t" 7869 "xorl rdx, rdx\n\t" 7870 "cmpl $div, -1\n\t" 7871 "je,s done\n" 7872 "normal: cdql\n\t" 7873 "idivl $div\n" 7874 "done:" %} 7875 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7876 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7877 ins_pipe(ialu_reg_reg_alu0); 7878 %} 7879 7880 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7881 rFlagsReg cr) 7882 %{ 7883 match(Set rdx (ModL rax div)); 7884 effect(KILL rax, KILL cr); 7885 7886 ins_cost(300); // XXX 7887 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 7888 "cmpq rax, rdx\n\t" 7889 "jne,s normal\n\t" 7890 "xorl rdx, rdx\n\t" 7891 "cmpq $div, -1\n\t" 7892 "je,s done\n" 7893 "normal: cdqq\n\t" 7894 "idivq $div\n" 7895 "done:" %} 7896 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7897 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7898 ins_pipe(ialu_reg_reg_alu0); 7899 %} 7900 7901 // Integer Shift Instructions 7902 // Shift Left by one 7903 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7904 %{ 7905 match(Set dst (LShiftI dst shift)); 7906 effect(KILL cr); 7907 7908 format %{ "sall $dst, $shift" %} 7909 opcode(0xD1, 0x4); /* D1 /4 */ 7910 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7911 ins_pipe(ialu_reg); 7912 %} 7913 7914 // Shift Left by one 7915 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7916 %{ 7917 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7918 effect(KILL cr); 7919 7920 format %{ "sall $dst, $shift\t" %} 7921 opcode(0xD1, 0x4); /* D1 /4 */ 7922 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7923 ins_pipe(ialu_mem_imm); 7924 %} 7925 7926 // Shift Left by 8-bit immediate 7927 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7928 %{ 7929 match(Set dst (LShiftI dst shift)); 7930 effect(KILL cr); 7931 7932 format %{ "sall $dst, $shift" %} 7933 opcode(0xC1, 0x4); /* C1 /4 ib */ 7934 ins_encode(reg_opc_imm(dst, shift)); 7935 ins_pipe(ialu_reg); 7936 %} 7937 7938 // Shift Left by 8-bit immediate 7939 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7940 %{ 7941 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7942 effect(KILL cr); 7943 7944 format %{ "sall $dst, $shift" %} 7945 opcode(0xC1, 0x4); /* C1 /4 ib */ 7946 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 7947 ins_pipe(ialu_mem_imm); 7948 %} 7949 7950 // Shift Left by variable 7951 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7952 %{ 7953 match(Set dst (LShiftI dst shift)); 7954 effect(KILL cr); 7955 7956 format %{ "sall $dst, $shift" %} 7957 opcode(0xD3, 0x4); /* D3 /4 */ 7958 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7959 ins_pipe(ialu_reg_reg); 7960 %} 7961 7962 // Shift Left by variable 7963 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 7964 %{ 7965 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7966 effect(KILL cr); 7967 7968 format %{ "sall $dst, $shift" %} 7969 opcode(0xD3, 0x4); /* D3 /4 */ 7970 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7971 ins_pipe(ialu_mem_reg); 7972 %} 7973 7974 // Arithmetic shift right by one 7975 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7976 %{ 7977 match(Set dst (RShiftI dst shift)); 7978 effect(KILL cr); 7979 7980 format %{ "sarl $dst, $shift" %} 7981 opcode(0xD1, 0x7); /* D1 /7 */ 7982 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7983 ins_pipe(ialu_reg); 7984 %} 7985 7986 // Arithmetic shift right by one 7987 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7988 %{ 7989 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 7990 effect(KILL cr); 7991 7992 format %{ "sarl $dst, $shift" %} 7993 opcode(0xD1, 0x7); /* D1 /7 */ 7994 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7995 ins_pipe(ialu_mem_imm); 7996 %} 7997 7998 // Arithmetic Shift Right by 8-bit immediate 7999 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8000 %{ 8001 match(Set dst (RShiftI dst shift)); 8002 effect(KILL cr); 8003 8004 format %{ "sarl $dst, $shift" %} 8005 opcode(0xC1, 0x7); /* C1 /7 ib */ 8006 ins_encode(reg_opc_imm(dst, shift)); 8007 ins_pipe(ialu_mem_imm); 8008 %} 8009 8010 // Arithmetic Shift Right by 8-bit immediate 8011 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8012 %{ 8013 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8014 effect(KILL cr); 8015 8016 format %{ "sarl $dst, $shift" %} 8017 opcode(0xC1, 0x7); /* C1 /7 ib */ 8018 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8019 ins_pipe(ialu_mem_imm); 8020 %} 8021 8022 // Arithmetic Shift Right by variable 8023 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8024 %{ 8025 match(Set dst (RShiftI dst shift)); 8026 effect(KILL cr); 8027 8028 format %{ "sarl $dst, $shift" %} 8029 opcode(0xD3, 0x7); /* D3 /7 */ 8030 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8031 ins_pipe(ialu_reg_reg); 8032 %} 8033 8034 // Arithmetic Shift Right by variable 8035 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8036 %{ 8037 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8038 effect(KILL cr); 8039 8040 format %{ "sarl $dst, $shift" %} 8041 opcode(0xD3, 0x7); /* D3 /7 */ 8042 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8043 ins_pipe(ialu_mem_reg); 8044 %} 8045 8046 // Logical shift right by one 8047 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8048 %{ 8049 match(Set dst (URShiftI dst shift)); 8050 effect(KILL cr); 8051 8052 format %{ "shrl $dst, $shift" %} 8053 opcode(0xD1, 0x5); /* D1 /5 */ 8054 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8055 ins_pipe(ialu_reg); 8056 %} 8057 8058 // Logical shift right by one 8059 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8060 %{ 8061 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8062 effect(KILL cr); 8063 8064 format %{ "shrl $dst, $shift" %} 8065 opcode(0xD1, 0x5); /* D1 /5 */ 8066 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8067 ins_pipe(ialu_mem_imm); 8068 %} 8069 8070 // Logical Shift Right by 8-bit immediate 8071 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8072 %{ 8073 match(Set dst (URShiftI dst shift)); 8074 effect(KILL cr); 8075 8076 format %{ "shrl $dst, $shift" %} 8077 opcode(0xC1, 0x5); /* C1 /5 ib */ 8078 ins_encode(reg_opc_imm(dst, shift)); 8079 ins_pipe(ialu_reg); 8080 %} 8081 8082 // Logical Shift Right by 8-bit immediate 8083 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8084 %{ 8085 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8086 effect(KILL cr); 8087 8088 format %{ "shrl $dst, $shift" %} 8089 opcode(0xC1, 0x5); /* C1 /5 ib */ 8090 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8091 ins_pipe(ialu_mem_imm); 8092 %} 8093 8094 // Logical Shift Right by variable 8095 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8096 %{ 8097 match(Set dst (URShiftI dst shift)); 8098 effect(KILL cr); 8099 8100 format %{ "shrl $dst, $shift" %} 8101 opcode(0xD3, 0x5); /* D3 /5 */ 8102 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8103 ins_pipe(ialu_reg_reg); 8104 %} 8105 8106 // Logical Shift Right by variable 8107 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8108 %{ 8109 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8110 effect(KILL cr); 8111 8112 format %{ "shrl $dst, $shift" %} 8113 opcode(0xD3, 0x5); /* D3 /5 */ 8114 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8115 ins_pipe(ialu_mem_reg); 8116 %} 8117 8118 // Long Shift Instructions 8119 // Shift Left by one 8120 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8121 %{ 8122 match(Set dst (LShiftL dst shift)); 8123 effect(KILL cr); 8124 8125 format %{ "salq $dst, $shift" %} 8126 opcode(0xD1, 0x4); /* D1 /4 */ 8127 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8128 ins_pipe(ialu_reg); 8129 %} 8130 8131 // Shift Left by one 8132 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8133 %{ 8134 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8135 effect(KILL cr); 8136 8137 format %{ "salq $dst, $shift" %} 8138 opcode(0xD1, 0x4); /* D1 /4 */ 8139 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8140 ins_pipe(ialu_mem_imm); 8141 %} 8142 8143 // Shift Left by 8-bit immediate 8144 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8145 %{ 8146 match(Set dst (LShiftL dst shift)); 8147 effect(KILL cr); 8148 8149 format %{ "salq $dst, $shift" %} 8150 opcode(0xC1, 0x4); /* C1 /4 ib */ 8151 ins_encode(reg_opc_imm_wide(dst, shift)); 8152 ins_pipe(ialu_reg); 8153 %} 8154 8155 // Shift Left by 8-bit immediate 8156 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8157 %{ 8158 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8159 effect(KILL cr); 8160 8161 format %{ "salq $dst, $shift" %} 8162 opcode(0xC1, 0x4); /* C1 /4 ib */ 8163 ins_encode(REX_mem_wide(dst), OpcP, 8164 RM_opc_mem(secondary, dst), Con8or32(shift)); 8165 ins_pipe(ialu_mem_imm); 8166 %} 8167 8168 // Shift Left by variable 8169 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8170 %{ 8171 match(Set dst (LShiftL dst shift)); 8172 effect(KILL cr); 8173 8174 format %{ "salq $dst, $shift" %} 8175 opcode(0xD3, 0x4); /* D3 /4 */ 8176 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8177 ins_pipe(ialu_reg_reg); 8178 %} 8179 8180 // Shift Left by variable 8181 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8182 %{ 8183 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8184 effect(KILL cr); 8185 8186 format %{ "salq $dst, $shift" %} 8187 opcode(0xD3, 0x4); /* D3 /4 */ 8188 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8189 ins_pipe(ialu_mem_reg); 8190 %} 8191 8192 // Arithmetic shift right by one 8193 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8194 %{ 8195 match(Set dst (RShiftL dst shift)); 8196 effect(KILL cr); 8197 8198 format %{ "sarq $dst, $shift" %} 8199 opcode(0xD1, 0x7); /* D1 /7 */ 8200 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8201 ins_pipe(ialu_reg); 8202 %} 8203 8204 // Arithmetic shift right by one 8205 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8206 %{ 8207 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8208 effect(KILL cr); 8209 8210 format %{ "sarq $dst, $shift" %} 8211 opcode(0xD1, 0x7); /* D1 /7 */ 8212 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8213 ins_pipe(ialu_mem_imm); 8214 %} 8215 8216 // Arithmetic Shift Right by 8-bit immediate 8217 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8218 %{ 8219 match(Set dst (RShiftL dst shift)); 8220 effect(KILL cr); 8221 8222 format %{ "sarq $dst, $shift" %} 8223 opcode(0xC1, 0x7); /* C1 /7 ib */ 8224 ins_encode(reg_opc_imm_wide(dst, shift)); 8225 ins_pipe(ialu_mem_imm); 8226 %} 8227 8228 // Arithmetic Shift Right by 8-bit immediate 8229 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8230 %{ 8231 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8232 effect(KILL cr); 8233 8234 format %{ "sarq $dst, $shift" %} 8235 opcode(0xC1, 0x7); /* C1 /7 ib */ 8236 ins_encode(REX_mem_wide(dst), OpcP, 8237 RM_opc_mem(secondary, dst), Con8or32(shift)); 8238 ins_pipe(ialu_mem_imm); 8239 %} 8240 8241 // Arithmetic Shift Right by variable 8242 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8243 %{ 8244 match(Set dst (RShiftL dst shift)); 8245 effect(KILL cr); 8246 8247 format %{ "sarq $dst, $shift" %} 8248 opcode(0xD3, 0x7); /* D3 /7 */ 8249 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8250 ins_pipe(ialu_reg_reg); 8251 %} 8252 8253 // Arithmetic Shift Right by variable 8254 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8255 %{ 8256 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8257 effect(KILL cr); 8258 8259 format %{ "sarq $dst, $shift" %} 8260 opcode(0xD3, 0x7); /* D3 /7 */ 8261 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8262 ins_pipe(ialu_mem_reg); 8263 %} 8264 8265 // Logical shift right by one 8266 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8267 %{ 8268 match(Set dst (URShiftL dst shift)); 8269 effect(KILL cr); 8270 8271 format %{ "shrq $dst, $shift" %} 8272 opcode(0xD1, 0x5); /* D1 /5 */ 8273 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8274 ins_pipe(ialu_reg); 8275 %} 8276 8277 // Logical shift right by one 8278 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8279 %{ 8280 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8281 effect(KILL cr); 8282 8283 format %{ "shrq $dst, $shift" %} 8284 opcode(0xD1, 0x5); /* D1 /5 */ 8285 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8286 ins_pipe(ialu_mem_imm); 8287 %} 8288 8289 // Logical Shift Right by 8-bit immediate 8290 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8291 %{ 8292 match(Set dst (URShiftL dst shift)); 8293 effect(KILL cr); 8294 8295 format %{ "shrq $dst, $shift" %} 8296 opcode(0xC1, 0x5); /* C1 /5 ib */ 8297 ins_encode(reg_opc_imm_wide(dst, shift)); 8298 ins_pipe(ialu_reg); 8299 %} 8300 8301 8302 // Logical Shift Right by 8-bit immediate 8303 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8304 %{ 8305 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8306 effect(KILL cr); 8307 8308 format %{ "shrq $dst, $shift" %} 8309 opcode(0xC1, 0x5); /* C1 /5 ib */ 8310 ins_encode(REX_mem_wide(dst), OpcP, 8311 RM_opc_mem(secondary, dst), Con8or32(shift)); 8312 ins_pipe(ialu_mem_imm); 8313 %} 8314 8315 // Logical Shift Right by variable 8316 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8317 %{ 8318 match(Set dst (URShiftL dst shift)); 8319 effect(KILL cr); 8320 8321 format %{ "shrq $dst, $shift" %} 8322 opcode(0xD3, 0x5); /* D3 /5 */ 8323 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8324 ins_pipe(ialu_reg_reg); 8325 %} 8326 8327 // Logical Shift Right by variable 8328 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8329 %{ 8330 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8331 effect(KILL cr); 8332 8333 format %{ "shrq $dst, $shift" %} 8334 opcode(0xD3, 0x5); /* D3 /5 */ 8335 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8336 ins_pipe(ialu_mem_reg); 8337 %} 8338 8339 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8340 // This idiom is used by the compiler for the i2b bytecode. 8341 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8342 %{ 8343 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8344 8345 format %{ "movsbl $dst, $src\t# i2b" %} 8346 opcode(0x0F, 0xBE); 8347 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8348 ins_pipe(ialu_reg_reg); 8349 %} 8350 8351 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8352 // This idiom is used by the compiler the i2s bytecode. 8353 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8354 %{ 8355 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8356 8357 format %{ "movswl $dst, $src\t# i2s" %} 8358 opcode(0x0F, 0xBF); 8359 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8360 ins_pipe(ialu_reg_reg); 8361 %} 8362 8363 // ROL/ROR instructions 8364 8365 // ROL expand 8366 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8367 effect(KILL cr, USE_DEF dst); 8368 8369 format %{ "roll $dst" %} 8370 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8371 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8372 ins_pipe(ialu_reg); 8373 %} 8374 8375 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8376 effect(USE_DEF dst, USE shift, KILL cr); 8377 8378 format %{ "roll $dst, $shift" %} 8379 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8380 ins_encode( reg_opc_imm(dst, shift) ); 8381 ins_pipe(ialu_reg); 8382 %} 8383 8384 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8385 %{ 8386 effect(USE_DEF dst, USE shift, KILL cr); 8387 8388 format %{ "roll $dst, $shift" %} 8389 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8390 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8391 ins_pipe(ialu_reg_reg); 8392 %} 8393 // end of ROL expand 8394 8395 // Rotate Left by one 8396 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8397 %{ 8398 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8399 8400 expand %{ 8401 rolI_rReg_imm1(dst, cr); 8402 %} 8403 %} 8404 8405 // Rotate Left by 8-bit immediate 8406 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8407 %{ 8408 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8409 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8410 8411 expand %{ 8412 rolI_rReg_imm8(dst, lshift, cr); 8413 %} 8414 %} 8415 8416 // Rotate Left by variable 8417 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8418 %{ 8419 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8420 8421 expand %{ 8422 rolI_rReg_CL(dst, shift, cr); 8423 %} 8424 %} 8425 8426 // Rotate Left by variable 8427 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8428 %{ 8429 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8430 8431 expand %{ 8432 rolI_rReg_CL(dst, shift, cr); 8433 %} 8434 %} 8435 8436 // ROR expand 8437 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8438 %{ 8439 effect(USE_DEF dst, KILL cr); 8440 8441 format %{ "rorl $dst" %} 8442 opcode(0xD1, 0x1); /* D1 /1 */ 8443 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8444 ins_pipe(ialu_reg); 8445 %} 8446 8447 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8448 %{ 8449 effect(USE_DEF dst, USE shift, KILL cr); 8450 8451 format %{ "rorl $dst, $shift" %} 8452 opcode(0xC1, 0x1); /* C1 /1 ib */ 8453 ins_encode(reg_opc_imm(dst, shift)); 8454 ins_pipe(ialu_reg); 8455 %} 8456 8457 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8458 %{ 8459 effect(USE_DEF dst, USE shift, KILL cr); 8460 8461 format %{ "rorl $dst, $shift" %} 8462 opcode(0xD3, 0x1); /* D3 /1 */ 8463 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8464 ins_pipe(ialu_reg_reg); 8465 %} 8466 // end of ROR expand 8467 8468 // Rotate Right by one 8469 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8470 %{ 8471 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8472 8473 expand %{ 8474 rorI_rReg_imm1(dst, cr); 8475 %} 8476 %} 8477 8478 // Rotate Right by 8-bit immediate 8479 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8480 %{ 8481 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8482 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8483 8484 expand %{ 8485 rorI_rReg_imm8(dst, rshift, cr); 8486 %} 8487 %} 8488 8489 // Rotate Right by variable 8490 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8491 %{ 8492 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8493 8494 expand %{ 8495 rorI_rReg_CL(dst, shift, cr); 8496 %} 8497 %} 8498 8499 // Rotate Right by variable 8500 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8501 %{ 8502 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8503 8504 expand %{ 8505 rorI_rReg_CL(dst, shift, cr); 8506 %} 8507 %} 8508 8509 // for long rotate 8510 // ROL expand 8511 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8512 effect(USE_DEF dst, KILL cr); 8513 8514 format %{ "rolq $dst" %} 8515 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8516 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8517 ins_pipe(ialu_reg); 8518 %} 8519 8520 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8521 effect(USE_DEF dst, USE shift, KILL cr); 8522 8523 format %{ "rolq $dst, $shift" %} 8524 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8525 ins_encode( reg_opc_imm_wide(dst, shift) ); 8526 ins_pipe(ialu_reg); 8527 %} 8528 8529 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8530 %{ 8531 effect(USE_DEF dst, USE shift, KILL cr); 8532 8533 format %{ "rolq $dst, $shift" %} 8534 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8535 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8536 ins_pipe(ialu_reg_reg); 8537 %} 8538 // end of ROL expand 8539 8540 // Rotate Left by one 8541 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8542 %{ 8543 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8544 8545 expand %{ 8546 rolL_rReg_imm1(dst, cr); 8547 %} 8548 %} 8549 8550 // Rotate Left by 8-bit immediate 8551 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8552 %{ 8553 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8554 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8555 8556 expand %{ 8557 rolL_rReg_imm8(dst, lshift, cr); 8558 %} 8559 %} 8560 8561 // Rotate Left by variable 8562 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8563 %{ 8564 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8565 8566 expand %{ 8567 rolL_rReg_CL(dst, shift, cr); 8568 %} 8569 %} 8570 8571 // Rotate Left by variable 8572 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8573 %{ 8574 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8575 8576 expand %{ 8577 rolL_rReg_CL(dst, shift, cr); 8578 %} 8579 %} 8580 8581 // ROR expand 8582 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8583 %{ 8584 effect(USE_DEF dst, KILL cr); 8585 8586 format %{ "rorq $dst" %} 8587 opcode(0xD1, 0x1); /* D1 /1 */ 8588 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8589 ins_pipe(ialu_reg); 8590 %} 8591 8592 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8593 %{ 8594 effect(USE_DEF dst, USE shift, KILL cr); 8595 8596 format %{ "rorq $dst, $shift" %} 8597 opcode(0xC1, 0x1); /* C1 /1 ib */ 8598 ins_encode(reg_opc_imm_wide(dst, shift)); 8599 ins_pipe(ialu_reg); 8600 %} 8601 8602 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8603 %{ 8604 effect(USE_DEF dst, USE shift, KILL cr); 8605 8606 format %{ "rorq $dst, $shift" %} 8607 opcode(0xD3, 0x1); /* D3 /1 */ 8608 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8609 ins_pipe(ialu_reg_reg); 8610 %} 8611 // end of ROR expand 8612 8613 // Rotate Right by one 8614 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8615 %{ 8616 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8617 8618 expand %{ 8619 rorL_rReg_imm1(dst, cr); 8620 %} 8621 %} 8622 8623 // Rotate Right by 8-bit immediate 8624 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8625 %{ 8626 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8627 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8628 8629 expand %{ 8630 rorL_rReg_imm8(dst, rshift, cr); 8631 %} 8632 %} 8633 8634 // Rotate Right by variable 8635 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8636 %{ 8637 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8638 8639 expand %{ 8640 rorL_rReg_CL(dst, shift, cr); 8641 %} 8642 %} 8643 8644 // Rotate Right by variable 8645 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8646 %{ 8647 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8648 8649 expand %{ 8650 rorL_rReg_CL(dst, shift, cr); 8651 %} 8652 %} 8653 8654 // Logical Instructions 8655 8656 // Integer Logical Instructions 8657 8658 // And Instructions 8659 // And Register with Register 8660 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8661 %{ 8662 match(Set dst (AndI dst src)); 8663 effect(KILL cr); 8664 8665 format %{ "andl $dst, $src\t# int" %} 8666 opcode(0x23); 8667 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8668 ins_pipe(ialu_reg_reg); 8669 %} 8670 8671 // And Register with Immediate 255 8672 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 8673 %{ 8674 match(Set dst (AndI dst src)); 8675 8676 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 8677 opcode(0x0F, 0xB6); 8678 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8679 ins_pipe(ialu_reg); 8680 %} 8681 8682 // And Register with Immediate 255 and promote to long 8683 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8684 %{ 8685 match(Set dst (ConvI2L (AndI src mask))); 8686 8687 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8688 opcode(0x0F, 0xB6); 8689 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8690 ins_pipe(ialu_reg); 8691 %} 8692 8693 // And Register with Immediate 65535 8694 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 8695 %{ 8696 match(Set dst (AndI dst src)); 8697 8698 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 8699 opcode(0x0F, 0xB7); 8700 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8701 ins_pipe(ialu_reg); 8702 %} 8703 8704 // And Register with Immediate 65535 and promote to long 8705 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8706 %{ 8707 match(Set dst (ConvI2L (AndI src mask))); 8708 8709 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8710 opcode(0x0F, 0xB7); 8711 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8712 ins_pipe(ialu_reg); 8713 %} 8714 8715 // And Register with Immediate 8716 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8717 %{ 8718 match(Set dst (AndI dst src)); 8719 effect(KILL cr); 8720 8721 format %{ "andl $dst, $src\t# int" %} 8722 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8723 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8724 ins_pipe(ialu_reg); 8725 %} 8726 8727 // And Register with Memory 8728 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8729 %{ 8730 match(Set dst (AndI dst (LoadI src))); 8731 effect(KILL cr); 8732 8733 ins_cost(125); 8734 format %{ "andl $dst, $src\t# int" %} 8735 opcode(0x23); 8736 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8737 ins_pipe(ialu_reg_mem); 8738 %} 8739 8740 // And Memory with Register 8741 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8742 %{ 8743 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8744 effect(KILL cr); 8745 8746 ins_cost(150); 8747 format %{ "andl $dst, $src\t# int" %} 8748 opcode(0x21); /* Opcode 21 /r */ 8749 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8750 ins_pipe(ialu_mem_reg); 8751 %} 8752 8753 // And Memory with Immediate 8754 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8755 %{ 8756 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8757 effect(KILL cr); 8758 8759 ins_cost(125); 8760 format %{ "andl $dst, $src\t# int" %} 8761 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 8762 ins_encode(REX_mem(dst), OpcSE(src), 8763 RM_opc_mem(secondary, dst), Con8or32(src)); 8764 ins_pipe(ialu_mem_imm); 8765 %} 8766 8767 // BMI1 instructions 8768 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8769 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8770 predicate(UseBMI1Instructions); 8771 effect(KILL cr); 8772 8773 ins_cost(125); 8774 format %{ "andnl $dst, $src1, $src2" %} 8775 8776 ins_encode %{ 8777 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8778 %} 8779 ins_pipe(ialu_reg_mem); 8780 %} 8781 8782 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8783 match(Set dst (AndI (XorI src1 minus_1) src2)); 8784 predicate(UseBMI1Instructions); 8785 effect(KILL cr); 8786 8787 format %{ "andnl $dst, $src1, $src2" %} 8788 8789 ins_encode %{ 8790 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8791 %} 8792 ins_pipe(ialu_reg); 8793 %} 8794 8795 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 8796 match(Set dst (AndI (SubI imm_zero src) src)); 8797 predicate(UseBMI1Instructions); 8798 effect(KILL cr); 8799 8800 format %{ "blsil $dst, $src" %} 8801 8802 ins_encode %{ 8803 __ blsil($dst$$Register, $src$$Register); 8804 %} 8805 ins_pipe(ialu_reg); 8806 %} 8807 8808 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 8809 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 8810 predicate(UseBMI1Instructions); 8811 effect(KILL cr); 8812 8813 ins_cost(125); 8814 format %{ "blsil $dst, $src" %} 8815 8816 ins_encode %{ 8817 __ blsil($dst$$Register, $src$$Address); 8818 %} 8819 ins_pipe(ialu_reg_mem); 8820 %} 8821 8822 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8823 %{ 8824 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8825 predicate(UseBMI1Instructions); 8826 effect(KILL cr); 8827 8828 ins_cost(125); 8829 format %{ "blsmskl $dst, $src" %} 8830 8831 ins_encode %{ 8832 __ blsmskl($dst$$Register, $src$$Address); 8833 %} 8834 ins_pipe(ialu_reg_mem); 8835 %} 8836 8837 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8838 %{ 8839 match(Set dst (XorI (AddI src minus_1) src)); 8840 predicate(UseBMI1Instructions); 8841 effect(KILL cr); 8842 8843 format %{ "blsmskl $dst, $src" %} 8844 8845 ins_encode %{ 8846 __ blsmskl($dst$$Register, $src$$Register); 8847 %} 8848 8849 ins_pipe(ialu_reg); 8850 %} 8851 8852 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8853 %{ 8854 match(Set dst (AndI (AddI src minus_1) src) ); 8855 predicate(UseBMI1Instructions); 8856 effect(KILL cr); 8857 8858 format %{ "blsrl $dst, $src" %} 8859 8860 ins_encode %{ 8861 __ blsrl($dst$$Register, $src$$Register); 8862 %} 8863 8864 ins_pipe(ialu_reg_mem); 8865 %} 8866 8867 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8868 %{ 8869 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8870 predicate(UseBMI1Instructions); 8871 effect(KILL cr); 8872 8873 ins_cost(125); 8874 format %{ "blsrl $dst, $src" %} 8875 8876 ins_encode %{ 8877 __ blsrl($dst$$Register, $src$$Address); 8878 %} 8879 8880 ins_pipe(ialu_reg); 8881 %} 8882 8883 // Or Instructions 8884 // Or Register with Register 8885 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8886 %{ 8887 match(Set dst (OrI dst src)); 8888 effect(KILL cr); 8889 8890 format %{ "orl $dst, $src\t# int" %} 8891 opcode(0x0B); 8892 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8893 ins_pipe(ialu_reg_reg); 8894 %} 8895 8896 // Or Register with Immediate 8897 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8898 %{ 8899 match(Set dst (OrI dst src)); 8900 effect(KILL cr); 8901 8902 format %{ "orl $dst, $src\t# int" %} 8903 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 8904 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8905 ins_pipe(ialu_reg); 8906 %} 8907 8908 // Or Register with Memory 8909 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8910 %{ 8911 match(Set dst (OrI dst (LoadI src))); 8912 effect(KILL cr); 8913 8914 ins_cost(125); 8915 format %{ "orl $dst, $src\t# int" %} 8916 opcode(0x0B); 8917 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8918 ins_pipe(ialu_reg_mem); 8919 %} 8920 8921 // Or Memory with Register 8922 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8923 %{ 8924 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8925 effect(KILL cr); 8926 8927 ins_cost(150); 8928 format %{ "orl $dst, $src\t# int" %} 8929 opcode(0x09); /* Opcode 09 /r */ 8930 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8931 ins_pipe(ialu_mem_reg); 8932 %} 8933 8934 // Or Memory with Immediate 8935 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 8936 %{ 8937 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8938 effect(KILL cr); 8939 8940 ins_cost(125); 8941 format %{ "orl $dst, $src\t# int" %} 8942 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 8943 ins_encode(REX_mem(dst), OpcSE(src), 8944 RM_opc_mem(secondary, dst), Con8or32(src)); 8945 ins_pipe(ialu_mem_imm); 8946 %} 8947 8948 // Xor Instructions 8949 // Xor Register with Register 8950 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8951 %{ 8952 match(Set dst (XorI dst src)); 8953 effect(KILL cr); 8954 8955 format %{ "xorl $dst, $src\t# int" %} 8956 opcode(0x33); 8957 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8958 ins_pipe(ialu_reg_reg); 8959 %} 8960 8961 // Xor Register with Immediate -1 8962 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 8963 match(Set dst (XorI dst imm)); 8964 8965 format %{ "not $dst" %} 8966 ins_encode %{ 8967 __ notl($dst$$Register); 8968 %} 8969 ins_pipe(ialu_reg); 8970 %} 8971 8972 // Xor Register with Immediate 8973 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8974 %{ 8975 match(Set dst (XorI dst src)); 8976 effect(KILL cr); 8977 8978 format %{ "xorl $dst, $src\t# int" %} 8979 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 8980 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8981 ins_pipe(ialu_reg); 8982 %} 8983 8984 // Xor Register with Memory 8985 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8986 %{ 8987 match(Set dst (XorI dst (LoadI src))); 8988 effect(KILL cr); 8989 8990 ins_cost(125); 8991 format %{ "xorl $dst, $src\t# int" %} 8992 opcode(0x33); 8993 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8994 ins_pipe(ialu_reg_mem); 8995 %} 8996 8997 // Xor Memory with Register 8998 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8999 %{ 9000 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9001 effect(KILL cr); 9002 9003 ins_cost(150); 9004 format %{ "xorl $dst, $src\t# int" %} 9005 opcode(0x31); /* Opcode 31 /r */ 9006 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9007 ins_pipe(ialu_mem_reg); 9008 %} 9009 9010 // Xor Memory with Immediate 9011 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9012 %{ 9013 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9014 effect(KILL cr); 9015 9016 ins_cost(125); 9017 format %{ "xorl $dst, $src\t# int" %} 9018 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9019 ins_encode(REX_mem(dst), OpcSE(src), 9020 RM_opc_mem(secondary, dst), Con8or32(src)); 9021 ins_pipe(ialu_mem_imm); 9022 %} 9023 9024 9025 // Long Logical Instructions 9026 9027 // And Instructions 9028 // And Register with Register 9029 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9030 %{ 9031 match(Set dst (AndL dst src)); 9032 effect(KILL cr); 9033 9034 format %{ "andq $dst, $src\t# long" %} 9035 opcode(0x23); 9036 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9037 ins_pipe(ialu_reg_reg); 9038 %} 9039 9040 // And Register with Immediate 255 9041 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9042 %{ 9043 match(Set dst (AndL dst src)); 9044 9045 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9046 opcode(0x0F, 0xB6); 9047 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9048 ins_pipe(ialu_reg); 9049 %} 9050 9051 // And Register with Immediate 65535 9052 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9053 %{ 9054 match(Set dst (AndL dst src)); 9055 9056 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9057 opcode(0x0F, 0xB7); 9058 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9059 ins_pipe(ialu_reg); 9060 %} 9061 9062 // And Register with Immediate 9063 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9064 %{ 9065 match(Set dst (AndL dst src)); 9066 effect(KILL cr); 9067 9068 format %{ "andq $dst, $src\t# long" %} 9069 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9070 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9071 ins_pipe(ialu_reg); 9072 %} 9073 9074 // And Register with Memory 9075 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9076 %{ 9077 match(Set dst (AndL dst (LoadL src))); 9078 effect(KILL cr); 9079 9080 ins_cost(125); 9081 format %{ "andq $dst, $src\t# long" %} 9082 opcode(0x23); 9083 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9084 ins_pipe(ialu_reg_mem); 9085 %} 9086 9087 // And Memory with Register 9088 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9089 %{ 9090 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9091 effect(KILL cr); 9092 9093 ins_cost(150); 9094 format %{ "andq $dst, $src\t# long" %} 9095 opcode(0x21); /* Opcode 21 /r */ 9096 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9097 ins_pipe(ialu_mem_reg); 9098 %} 9099 9100 // And Memory with Immediate 9101 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9102 %{ 9103 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9104 effect(KILL cr); 9105 9106 ins_cost(125); 9107 format %{ "andq $dst, $src\t# long" %} 9108 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9109 ins_encode(REX_mem_wide(dst), OpcSE(src), 9110 RM_opc_mem(secondary, dst), Con8or32(src)); 9111 ins_pipe(ialu_mem_imm); 9112 %} 9113 9114 // BMI1 instructions 9115 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9116 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9117 predicate(UseBMI1Instructions); 9118 effect(KILL cr); 9119 9120 ins_cost(125); 9121 format %{ "andnq $dst, $src1, $src2" %} 9122 9123 ins_encode %{ 9124 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9125 %} 9126 ins_pipe(ialu_reg_mem); 9127 %} 9128 9129 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9130 match(Set dst (AndL (XorL src1 minus_1) src2)); 9131 predicate(UseBMI1Instructions); 9132 effect(KILL cr); 9133 9134 format %{ "andnq $dst, $src1, $src2" %} 9135 9136 ins_encode %{ 9137 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9138 %} 9139 ins_pipe(ialu_reg_mem); 9140 %} 9141 9142 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9143 match(Set dst (AndL (SubL imm_zero src) src)); 9144 predicate(UseBMI1Instructions); 9145 effect(KILL cr); 9146 9147 format %{ "blsiq $dst, $src" %} 9148 9149 ins_encode %{ 9150 __ blsiq($dst$$Register, $src$$Register); 9151 %} 9152 ins_pipe(ialu_reg); 9153 %} 9154 9155 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9156 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9157 predicate(UseBMI1Instructions); 9158 effect(KILL cr); 9159 9160 ins_cost(125); 9161 format %{ "blsiq $dst, $src" %} 9162 9163 ins_encode %{ 9164 __ blsiq($dst$$Register, $src$$Address); 9165 %} 9166 ins_pipe(ialu_reg_mem); 9167 %} 9168 9169 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9170 %{ 9171 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9172 predicate(UseBMI1Instructions); 9173 effect(KILL cr); 9174 9175 ins_cost(125); 9176 format %{ "blsmskq $dst, $src" %} 9177 9178 ins_encode %{ 9179 __ blsmskq($dst$$Register, $src$$Address); 9180 %} 9181 ins_pipe(ialu_reg_mem); 9182 %} 9183 9184 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9185 %{ 9186 match(Set dst (XorL (AddL src minus_1) src)); 9187 predicate(UseBMI1Instructions); 9188 effect(KILL cr); 9189 9190 format %{ "blsmskq $dst, $src" %} 9191 9192 ins_encode %{ 9193 __ blsmskq($dst$$Register, $src$$Register); 9194 %} 9195 9196 ins_pipe(ialu_reg); 9197 %} 9198 9199 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9200 %{ 9201 match(Set dst (AndL (AddL src minus_1) src) ); 9202 predicate(UseBMI1Instructions); 9203 effect(KILL cr); 9204 9205 format %{ "blsrq $dst, $src" %} 9206 9207 ins_encode %{ 9208 __ blsrq($dst$$Register, $src$$Register); 9209 %} 9210 9211 ins_pipe(ialu_reg); 9212 %} 9213 9214 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9215 %{ 9216 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9217 predicate(UseBMI1Instructions); 9218 effect(KILL cr); 9219 9220 ins_cost(125); 9221 format %{ "blsrq $dst, $src" %} 9222 9223 ins_encode %{ 9224 __ blsrq($dst$$Register, $src$$Address); 9225 %} 9226 9227 ins_pipe(ialu_reg); 9228 %} 9229 9230 // Or Instructions 9231 // Or Register with Register 9232 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9233 %{ 9234 match(Set dst (OrL dst src)); 9235 effect(KILL cr); 9236 9237 format %{ "orq $dst, $src\t# long" %} 9238 opcode(0x0B); 9239 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9240 ins_pipe(ialu_reg_reg); 9241 %} 9242 9243 // Use any_RegP to match R15 (TLS register) without spilling. 9244 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9245 match(Set dst (OrL dst (CastP2X src))); 9246 effect(KILL cr); 9247 9248 format %{ "orq $dst, $src\t# long" %} 9249 opcode(0x0B); 9250 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9251 ins_pipe(ialu_reg_reg); 9252 %} 9253 9254 9255 // Or Register with Immediate 9256 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9257 %{ 9258 match(Set dst (OrL dst src)); 9259 effect(KILL cr); 9260 9261 format %{ "orq $dst, $src\t# long" %} 9262 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9263 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9264 ins_pipe(ialu_reg); 9265 %} 9266 9267 // Or Register with Memory 9268 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9269 %{ 9270 match(Set dst (OrL dst (LoadL src))); 9271 effect(KILL cr); 9272 9273 ins_cost(125); 9274 format %{ "orq $dst, $src\t# long" %} 9275 opcode(0x0B); 9276 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9277 ins_pipe(ialu_reg_mem); 9278 %} 9279 9280 // Or Memory with Register 9281 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9282 %{ 9283 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9284 effect(KILL cr); 9285 9286 ins_cost(150); 9287 format %{ "orq $dst, $src\t# long" %} 9288 opcode(0x09); /* Opcode 09 /r */ 9289 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9290 ins_pipe(ialu_mem_reg); 9291 %} 9292 9293 // Or Memory with Immediate 9294 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9295 %{ 9296 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9297 effect(KILL cr); 9298 9299 ins_cost(125); 9300 format %{ "orq $dst, $src\t# long" %} 9301 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9302 ins_encode(REX_mem_wide(dst), OpcSE(src), 9303 RM_opc_mem(secondary, dst), Con8or32(src)); 9304 ins_pipe(ialu_mem_imm); 9305 %} 9306 9307 // Xor Instructions 9308 // Xor Register with Register 9309 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9310 %{ 9311 match(Set dst (XorL dst src)); 9312 effect(KILL cr); 9313 9314 format %{ "xorq $dst, $src\t# long" %} 9315 opcode(0x33); 9316 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9317 ins_pipe(ialu_reg_reg); 9318 %} 9319 9320 // Xor Register with Immediate -1 9321 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9322 match(Set dst (XorL dst imm)); 9323 9324 format %{ "notq $dst" %} 9325 ins_encode %{ 9326 __ notq($dst$$Register); 9327 %} 9328 ins_pipe(ialu_reg); 9329 %} 9330 9331 // Xor Register with Immediate 9332 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9333 %{ 9334 match(Set dst (XorL dst src)); 9335 effect(KILL cr); 9336 9337 format %{ "xorq $dst, $src\t# long" %} 9338 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9339 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9340 ins_pipe(ialu_reg); 9341 %} 9342 9343 // Xor Register with Memory 9344 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9345 %{ 9346 match(Set dst (XorL dst (LoadL src))); 9347 effect(KILL cr); 9348 9349 ins_cost(125); 9350 format %{ "xorq $dst, $src\t# long" %} 9351 opcode(0x33); 9352 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9353 ins_pipe(ialu_reg_mem); 9354 %} 9355 9356 // Xor Memory with Register 9357 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9358 %{ 9359 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9360 effect(KILL cr); 9361 9362 ins_cost(150); 9363 format %{ "xorq $dst, $src\t# long" %} 9364 opcode(0x31); /* Opcode 31 /r */ 9365 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9366 ins_pipe(ialu_mem_reg); 9367 %} 9368 9369 // Xor Memory with Immediate 9370 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9371 %{ 9372 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9373 effect(KILL cr); 9374 9375 ins_cost(125); 9376 format %{ "xorq $dst, $src\t# long" %} 9377 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9378 ins_encode(REX_mem_wide(dst), OpcSE(src), 9379 RM_opc_mem(secondary, dst), Con8or32(src)); 9380 ins_pipe(ialu_mem_imm); 9381 %} 9382 9383 // Convert Int to Boolean 9384 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9385 %{ 9386 match(Set dst (Conv2B src)); 9387 effect(KILL cr); 9388 9389 format %{ "testl $src, $src\t# ci2b\n\t" 9390 "setnz $dst\n\t" 9391 "movzbl $dst, $dst" %} 9392 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9393 setNZ_reg(dst), 9394 REX_reg_breg(dst, dst), // movzbl 9395 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9396 ins_pipe(pipe_slow); // XXX 9397 %} 9398 9399 // Convert Pointer to Boolean 9400 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9401 %{ 9402 match(Set dst (Conv2B src)); 9403 effect(KILL cr); 9404 9405 format %{ "testq $src, $src\t# cp2b\n\t" 9406 "setnz $dst\n\t" 9407 "movzbl $dst, $dst" %} 9408 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9409 setNZ_reg(dst), 9410 REX_reg_breg(dst, dst), // movzbl 9411 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9412 ins_pipe(pipe_slow); // XXX 9413 %} 9414 9415 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9416 %{ 9417 match(Set dst (CmpLTMask p q)); 9418 effect(KILL cr); 9419 9420 ins_cost(400); 9421 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9422 "setlt $dst\n\t" 9423 "movzbl $dst, $dst\n\t" 9424 "negl $dst" %} 9425 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9426 setLT_reg(dst), 9427 REX_reg_breg(dst, dst), // movzbl 9428 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9429 neg_reg(dst)); 9430 ins_pipe(pipe_slow); 9431 %} 9432 9433 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9434 %{ 9435 match(Set dst (CmpLTMask dst zero)); 9436 effect(KILL cr); 9437 9438 ins_cost(100); 9439 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9440 ins_encode %{ 9441 __ sarl($dst$$Register, 31); 9442 %} 9443 ins_pipe(ialu_reg); 9444 %} 9445 9446 /* Better to save a register than avoid a branch */ 9447 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9448 %{ 9449 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9450 effect(KILL cr); 9451 ins_cost(300); 9452 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9453 "jge done\n\t" 9454 "addl $p,$y\n" 9455 "done: " %} 9456 ins_encode %{ 9457 Register Rp = $p$$Register; 9458 Register Rq = $q$$Register; 9459 Register Ry = $y$$Register; 9460 Label done; 9461 __ subl(Rp, Rq); 9462 __ jccb(Assembler::greaterEqual, done); 9463 __ addl(Rp, Ry); 9464 __ bind(done); 9465 %} 9466 ins_pipe(pipe_cmplt); 9467 %} 9468 9469 /* Better to save a register than avoid a branch */ 9470 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9471 %{ 9472 match(Set y (AndI (CmpLTMask p q) y)); 9473 effect(KILL cr); 9474 9475 ins_cost(300); 9476 9477 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9478 "jlt done\n\t" 9479 "xorl $y, $y\n" 9480 "done: " %} 9481 ins_encode %{ 9482 Register Rp = $p$$Register; 9483 Register Rq = $q$$Register; 9484 Register Ry = $y$$Register; 9485 Label done; 9486 __ cmpl(Rp, Rq); 9487 __ jccb(Assembler::less, done); 9488 __ xorl(Ry, Ry); 9489 __ bind(done); 9490 %} 9491 ins_pipe(pipe_cmplt); 9492 %} 9493 9494 9495 //---------- FP Instructions------------------------------------------------ 9496 9497 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9498 %{ 9499 match(Set cr (CmpF src1 src2)); 9500 9501 ins_cost(145); 9502 format %{ "ucomiss $src1, $src2\n\t" 9503 "jnp,s exit\n\t" 9504 "pushfq\t# saw NaN, set CF\n\t" 9505 "andq [rsp], #0xffffff2b\n\t" 9506 "popfq\n" 9507 "exit:" %} 9508 ins_encode %{ 9509 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9510 emit_cmpfp_fixup(_masm); 9511 %} 9512 ins_pipe(pipe_slow); 9513 %} 9514 9515 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9516 match(Set cr (CmpF src1 src2)); 9517 9518 ins_cost(100); 9519 format %{ "ucomiss $src1, $src2" %} 9520 ins_encode %{ 9521 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9522 %} 9523 ins_pipe(pipe_slow); 9524 %} 9525 9526 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9527 %{ 9528 match(Set cr (CmpF src1 (LoadF src2))); 9529 9530 ins_cost(145); 9531 format %{ "ucomiss $src1, $src2\n\t" 9532 "jnp,s exit\n\t" 9533 "pushfq\t# saw NaN, set CF\n\t" 9534 "andq [rsp], #0xffffff2b\n\t" 9535 "popfq\n" 9536 "exit:" %} 9537 ins_encode %{ 9538 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9539 emit_cmpfp_fixup(_masm); 9540 %} 9541 ins_pipe(pipe_slow); 9542 %} 9543 9544 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9545 match(Set cr (CmpF src1 (LoadF src2))); 9546 9547 ins_cost(100); 9548 format %{ "ucomiss $src1, $src2" %} 9549 ins_encode %{ 9550 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9551 %} 9552 ins_pipe(pipe_slow); 9553 %} 9554 9555 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9556 match(Set cr (CmpF src con)); 9557 9558 ins_cost(145); 9559 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9560 "jnp,s exit\n\t" 9561 "pushfq\t# saw NaN, set CF\n\t" 9562 "andq [rsp], #0xffffff2b\n\t" 9563 "popfq\n" 9564 "exit:" %} 9565 ins_encode %{ 9566 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9567 emit_cmpfp_fixup(_masm); 9568 %} 9569 ins_pipe(pipe_slow); 9570 %} 9571 9572 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9573 match(Set cr (CmpF src con)); 9574 ins_cost(100); 9575 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9576 ins_encode %{ 9577 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9578 %} 9579 ins_pipe(pipe_slow); 9580 %} 9581 9582 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9583 %{ 9584 match(Set cr (CmpD src1 src2)); 9585 9586 ins_cost(145); 9587 format %{ "ucomisd $src1, $src2\n\t" 9588 "jnp,s exit\n\t" 9589 "pushfq\t# saw NaN, set CF\n\t" 9590 "andq [rsp], #0xffffff2b\n\t" 9591 "popfq\n" 9592 "exit:" %} 9593 ins_encode %{ 9594 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9595 emit_cmpfp_fixup(_masm); 9596 %} 9597 ins_pipe(pipe_slow); 9598 %} 9599 9600 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9601 match(Set cr (CmpD src1 src2)); 9602 9603 ins_cost(100); 9604 format %{ "ucomisd $src1, $src2 test" %} 9605 ins_encode %{ 9606 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9607 %} 9608 ins_pipe(pipe_slow); 9609 %} 9610 9611 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9612 %{ 9613 match(Set cr (CmpD src1 (LoadD src2))); 9614 9615 ins_cost(145); 9616 format %{ "ucomisd $src1, $src2\n\t" 9617 "jnp,s exit\n\t" 9618 "pushfq\t# saw NaN, set CF\n\t" 9619 "andq [rsp], #0xffffff2b\n\t" 9620 "popfq\n" 9621 "exit:" %} 9622 ins_encode %{ 9623 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9624 emit_cmpfp_fixup(_masm); 9625 %} 9626 ins_pipe(pipe_slow); 9627 %} 9628 9629 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9630 match(Set cr (CmpD src1 (LoadD src2))); 9631 9632 ins_cost(100); 9633 format %{ "ucomisd $src1, $src2" %} 9634 ins_encode %{ 9635 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9636 %} 9637 ins_pipe(pipe_slow); 9638 %} 9639 9640 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9641 match(Set cr (CmpD src con)); 9642 9643 ins_cost(145); 9644 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9645 "jnp,s exit\n\t" 9646 "pushfq\t# saw NaN, set CF\n\t" 9647 "andq [rsp], #0xffffff2b\n\t" 9648 "popfq\n" 9649 "exit:" %} 9650 ins_encode %{ 9651 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9652 emit_cmpfp_fixup(_masm); 9653 %} 9654 ins_pipe(pipe_slow); 9655 %} 9656 9657 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9658 match(Set cr (CmpD src con)); 9659 ins_cost(100); 9660 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9661 ins_encode %{ 9662 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9663 %} 9664 ins_pipe(pipe_slow); 9665 %} 9666 9667 // Compare into -1,0,1 9668 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9669 %{ 9670 match(Set dst (CmpF3 src1 src2)); 9671 effect(KILL cr); 9672 9673 ins_cost(275); 9674 format %{ "ucomiss $src1, $src2\n\t" 9675 "movl $dst, #-1\n\t" 9676 "jp,s done\n\t" 9677 "jb,s done\n\t" 9678 "setne $dst\n\t" 9679 "movzbl $dst, $dst\n" 9680 "done:" %} 9681 ins_encode %{ 9682 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9683 emit_cmpfp3(_masm, $dst$$Register); 9684 %} 9685 ins_pipe(pipe_slow); 9686 %} 9687 9688 // Compare into -1,0,1 9689 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9690 %{ 9691 match(Set dst (CmpF3 src1 (LoadF src2))); 9692 effect(KILL cr); 9693 9694 ins_cost(275); 9695 format %{ "ucomiss $src1, $src2\n\t" 9696 "movl $dst, #-1\n\t" 9697 "jp,s done\n\t" 9698 "jb,s done\n\t" 9699 "setne $dst\n\t" 9700 "movzbl $dst, $dst\n" 9701 "done:" %} 9702 ins_encode %{ 9703 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9704 emit_cmpfp3(_masm, $dst$$Register); 9705 %} 9706 ins_pipe(pipe_slow); 9707 %} 9708 9709 // Compare into -1,0,1 9710 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9711 match(Set dst (CmpF3 src con)); 9712 effect(KILL cr); 9713 9714 ins_cost(275); 9715 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9716 "movl $dst, #-1\n\t" 9717 "jp,s done\n\t" 9718 "jb,s done\n\t" 9719 "setne $dst\n\t" 9720 "movzbl $dst, $dst\n" 9721 "done:" %} 9722 ins_encode %{ 9723 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9724 emit_cmpfp3(_masm, $dst$$Register); 9725 %} 9726 ins_pipe(pipe_slow); 9727 %} 9728 9729 // Compare into -1,0,1 9730 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9731 %{ 9732 match(Set dst (CmpD3 src1 src2)); 9733 effect(KILL cr); 9734 9735 ins_cost(275); 9736 format %{ "ucomisd $src1, $src2\n\t" 9737 "movl $dst, #-1\n\t" 9738 "jp,s done\n\t" 9739 "jb,s done\n\t" 9740 "setne $dst\n\t" 9741 "movzbl $dst, $dst\n" 9742 "done:" %} 9743 ins_encode %{ 9744 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9745 emit_cmpfp3(_masm, $dst$$Register); 9746 %} 9747 ins_pipe(pipe_slow); 9748 %} 9749 9750 // Compare into -1,0,1 9751 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9752 %{ 9753 match(Set dst (CmpD3 src1 (LoadD src2))); 9754 effect(KILL cr); 9755 9756 ins_cost(275); 9757 format %{ "ucomisd $src1, $src2\n\t" 9758 "movl $dst, #-1\n\t" 9759 "jp,s done\n\t" 9760 "jb,s done\n\t" 9761 "setne $dst\n\t" 9762 "movzbl $dst, $dst\n" 9763 "done:" %} 9764 ins_encode %{ 9765 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9766 emit_cmpfp3(_masm, $dst$$Register); 9767 %} 9768 ins_pipe(pipe_slow); 9769 %} 9770 9771 // Compare into -1,0,1 9772 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9773 match(Set dst (CmpD3 src con)); 9774 effect(KILL cr); 9775 9776 ins_cost(275); 9777 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9778 "movl $dst, #-1\n\t" 9779 "jp,s done\n\t" 9780 "jb,s done\n\t" 9781 "setne $dst\n\t" 9782 "movzbl $dst, $dst\n" 9783 "done:" %} 9784 ins_encode %{ 9785 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9786 emit_cmpfp3(_masm, $dst$$Register); 9787 %} 9788 ins_pipe(pipe_slow); 9789 %} 9790 9791 // -----------Trig and Trancendental Instructions------------------------------ 9792 instruct cosD_reg(regD dst) %{ 9793 match(Set dst (CosD dst)); 9794 9795 format %{ "dcos $dst\n\t" %} 9796 opcode(0xD9, 0xFF); 9797 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9798 ins_pipe( pipe_slow ); 9799 %} 9800 9801 instruct sinD_reg(regD dst) %{ 9802 match(Set dst (SinD dst)); 9803 9804 format %{ "dsin $dst\n\t" %} 9805 opcode(0xD9, 0xFE); 9806 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9807 ins_pipe( pipe_slow ); 9808 %} 9809 9810 instruct tanD_reg(regD dst) %{ 9811 match(Set dst (TanD dst)); 9812 9813 format %{ "dtan $dst\n\t" %} 9814 ins_encode( Push_SrcXD(dst), 9815 Opcode(0xD9), Opcode(0xF2), //fptan 9816 Opcode(0xDD), Opcode(0xD8), //fstp st 9817 Push_ResultXD(dst) ); 9818 ins_pipe( pipe_slow ); 9819 %} 9820 9821 instruct log10D_reg(regD dst) %{ 9822 // The source and result Double operands in XMM registers 9823 match(Set dst (Log10D dst)); 9824 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 9825 // fyl2x ; compute log_10(2) * log_2(x) 9826 format %{ "fldlg2\t\t\t#Log10\n\t" 9827 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 9828 %} 9829 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 9830 Push_SrcXD(dst), 9831 Opcode(0xD9), Opcode(0xF1), // fyl2x 9832 Push_ResultXD(dst)); 9833 9834 ins_pipe( pipe_slow ); 9835 %} 9836 9837 instruct logD_reg(regD dst) %{ 9838 // The source and result Double operands in XMM registers 9839 match(Set dst (LogD dst)); 9840 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 9841 // fyl2x ; compute log_e(2) * log_2(x) 9842 format %{ "fldln2\t\t\t#Log_e\n\t" 9843 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 9844 %} 9845 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 9846 Push_SrcXD(dst), 9847 Opcode(0xD9), Opcode(0xF1), // fyl2x 9848 Push_ResultXD(dst)); 9849 ins_pipe( pipe_slow ); 9850 %} 9851 9852 instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9853 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power 9854 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); 9855 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %} 9856 ins_encode %{ 9857 __ subptr(rsp, 8); 9858 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); 9859 __ fld_d(Address(rsp, 0)); 9860 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); 9861 __ fld_d(Address(rsp, 0)); 9862 __ fast_pow(); 9863 __ fstp_d(Address(rsp, 0)); 9864 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9865 __ addptr(rsp, 8); 9866 %} 9867 ins_pipe( pipe_slow ); 9868 %} 9869 9870 instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9871 match(Set dst (ExpD src)); 9872 effect(KILL rax, KILL rcx, KILL rdx, KILL cr); 9873 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %} 9874 ins_encode %{ 9875 __ subptr(rsp, 8); 9876 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9877 __ fld_d(Address(rsp, 0)); 9878 __ fast_exp(); 9879 __ fstp_d(Address(rsp, 0)); 9880 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9881 __ addptr(rsp, 8); 9882 %} 9883 ins_pipe( pipe_slow ); 9884 %} 9885 9886 //----------Arithmetic Conversion Instructions--------------------------------- 9887 9888 instruct roundFloat_nop(regF dst) 9889 %{ 9890 match(Set dst (RoundFloat dst)); 9891 9892 ins_cost(0); 9893 ins_encode(); 9894 ins_pipe(empty); 9895 %} 9896 9897 instruct roundDouble_nop(regD dst) 9898 %{ 9899 match(Set dst (RoundDouble dst)); 9900 9901 ins_cost(0); 9902 ins_encode(); 9903 ins_pipe(empty); 9904 %} 9905 9906 instruct convF2D_reg_reg(regD dst, regF src) 9907 %{ 9908 match(Set dst (ConvF2D src)); 9909 9910 format %{ "cvtss2sd $dst, $src" %} 9911 ins_encode %{ 9912 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 9913 %} 9914 ins_pipe(pipe_slow); // XXX 9915 %} 9916 9917 instruct convF2D_reg_mem(regD dst, memory src) 9918 %{ 9919 match(Set dst (ConvF2D (LoadF src))); 9920 9921 format %{ "cvtss2sd $dst, $src" %} 9922 ins_encode %{ 9923 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 9924 %} 9925 ins_pipe(pipe_slow); // XXX 9926 %} 9927 9928 instruct convD2F_reg_reg(regF dst, regD src) 9929 %{ 9930 match(Set dst (ConvD2F src)); 9931 9932 format %{ "cvtsd2ss $dst, $src" %} 9933 ins_encode %{ 9934 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 9935 %} 9936 ins_pipe(pipe_slow); // XXX 9937 %} 9938 9939 instruct convD2F_reg_mem(regF dst, memory src) 9940 %{ 9941 match(Set dst (ConvD2F (LoadD src))); 9942 9943 format %{ "cvtsd2ss $dst, $src" %} 9944 ins_encode %{ 9945 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 9946 %} 9947 ins_pipe(pipe_slow); // XXX 9948 %} 9949 9950 // XXX do mem variants 9951 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9952 %{ 9953 match(Set dst (ConvF2I src)); 9954 effect(KILL cr); 9955 9956 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 9957 "cmpl $dst, #0x80000000\n\t" 9958 "jne,s done\n\t" 9959 "subq rsp, #8\n\t" 9960 "movss [rsp], $src\n\t" 9961 "call f2i_fixup\n\t" 9962 "popq $dst\n" 9963 "done: "%} 9964 ins_encode %{ 9965 Label done; 9966 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 9967 __ cmpl($dst$$Register, 0x80000000); 9968 __ jccb(Assembler::notEqual, done); 9969 __ subptr(rsp, 8); 9970 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9971 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 9972 __ pop($dst$$Register); 9973 __ bind(done); 9974 %} 9975 ins_pipe(pipe_slow); 9976 %} 9977 9978 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 9979 %{ 9980 match(Set dst (ConvF2L src)); 9981 effect(KILL cr); 9982 9983 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 9984 "cmpq $dst, [0x8000000000000000]\n\t" 9985 "jne,s done\n\t" 9986 "subq rsp, #8\n\t" 9987 "movss [rsp], $src\n\t" 9988 "call f2l_fixup\n\t" 9989 "popq $dst\n" 9990 "done: "%} 9991 ins_encode %{ 9992 Label done; 9993 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 9994 __ cmp64($dst$$Register, 9995 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 9996 __ jccb(Assembler::notEqual, done); 9997 __ subptr(rsp, 8); 9998 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9999 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10000 __ pop($dst$$Register); 10001 __ bind(done); 10002 %} 10003 ins_pipe(pipe_slow); 10004 %} 10005 10006 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10007 %{ 10008 match(Set dst (ConvD2I src)); 10009 effect(KILL cr); 10010 10011 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10012 "cmpl $dst, #0x80000000\n\t" 10013 "jne,s done\n\t" 10014 "subq rsp, #8\n\t" 10015 "movsd [rsp], $src\n\t" 10016 "call d2i_fixup\n\t" 10017 "popq $dst\n" 10018 "done: "%} 10019 ins_encode %{ 10020 Label done; 10021 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10022 __ cmpl($dst$$Register, 0x80000000); 10023 __ jccb(Assembler::notEqual, done); 10024 __ subptr(rsp, 8); 10025 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10026 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10027 __ pop($dst$$Register); 10028 __ bind(done); 10029 %} 10030 ins_pipe(pipe_slow); 10031 %} 10032 10033 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10034 %{ 10035 match(Set dst (ConvD2L src)); 10036 effect(KILL cr); 10037 10038 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10039 "cmpq $dst, [0x8000000000000000]\n\t" 10040 "jne,s done\n\t" 10041 "subq rsp, #8\n\t" 10042 "movsd [rsp], $src\n\t" 10043 "call d2l_fixup\n\t" 10044 "popq $dst\n" 10045 "done: "%} 10046 ins_encode %{ 10047 Label done; 10048 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10049 __ cmp64($dst$$Register, 10050 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10051 __ jccb(Assembler::notEqual, done); 10052 __ subptr(rsp, 8); 10053 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10054 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10055 __ pop($dst$$Register); 10056 __ bind(done); 10057 %} 10058 ins_pipe(pipe_slow); 10059 %} 10060 10061 instruct convI2F_reg_reg(regF dst, rRegI src) 10062 %{ 10063 predicate(!UseXmmI2F); 10064 match(Set dst (ConvI2F src)); 10065 10066 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10067 ins_encode %{ 10068 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10069 %} 10070 ins_pipe(pipe_slow); // XXX 10071 %} 10072 10073 instruct convI2F_reg_mem(regF dst, memory src) 10074 %{ 10075 match(Set dst (ConvI2F (LoadI src))); 10076 10077 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10078 ins_encode %{ 10079 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10080 %} 10081 ins_pipe(pipe_slow); // XXX 10082 %} 10083 10084 instruct convI2D_reg_reg(regD dst, rRegI src) 10085 %{ 10086 predicate(!UseXmmI2D); 10087 match(Set dst (ConvI2D src)); 10088 10089 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10090 ins_encode %{ 10091 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10092 %} 10093 ins_pipe(pipe_slow); // XXX 10094 %} 10095 10096 instruct convI2D_reg_mem(regD dst, memory src) 10097 %{ 10098 match(Set dst (ConvI2D (LoadI src))); 10099 10100 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10101 ins_encode %{ 10102 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10103 %} 10104 ins_pipe(pipe_slow); // XXX 10105 %} 10106 10107 instruct convXI2F_reg(regF dst, rRegI src) 10108 %{ 10109 predicate(UseXmmI2F); 10110 match(Set dst (ConvI2F src)); 10111 10112 format %{ "movdl $dst, $src\n\t" 10113 "cvtdq2psl $dst, $dst\t# i2f" %} 10114 ins_encode %{ 10115 __ movdl($dst$$XMMRegister, $src$$Register); 10116 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10117 %} 10118 ins_pipe(pipe_slow); // XXX 10119 %} 10120 10121 instruct convXI2D_reg(regD dst, rRegI src) 10122 %{ 10123 predicate(UseXmmI2D); 10124 match(Set dst (ConvI2D src)); 10125 10126 format %{ "movdl $dst, $src\n\t" 10127 "cvtdq2pdl $dst, $dst\t# i2d" %} 10128 ins_encode %{ 10129 __ movdl($dst$$XMMRegister, $src$$Register); 10130 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10131 %} 10132 ins_pipe(pipe_slow); // XXX 10133 %} 10134 10135 instruct convL2F_reg_reg(regF dst, rRegL src) 10136 %{ 10137 match(Set dst (ConvL2F src)); 10138 10139 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10140 ins_encode %{ 10141 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10142 %} 10143 ins_pipe(pipe_slow); // XXX 10144 %} 10145 10146 instruct convL2F_reg_mem(regF dst, memory src) 10147 %{ 10148 match(Set dst (ConvL2F (LoadL src))); 10149 10150 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10151 ins_encode %{ 10152 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10153 %} 10154 ins_pipe(pipe_slow); // XXX 10155 %} 10156 10157 instruct convL2D_reg_reg(regD dst, rRegL src) 10158 %{ 10159 match(Set dst (ConvL2D src)); 10160 10161 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10162 ins_encode %{ 10163 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10164 %} 10165 ins_pipe(pipe_slow); // XXX 10166 %} 10167 10168 instruct convL2D_reg_mem(regD dst, memory src) 10169 %{ 10170 match(Set dst (ConvL2D (LoadL src))); 10171 10172 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10173 ins_encode %{ 10174 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10175 %} 10176 ins_pipe(pipe_slow); // XXX 10177 %} 10178 10179 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10180 %{ 10181 match(Set dst (ConvI2L src)); 10182 10183 ins_cost(125); 10184 format %{ "movslq $dst, $src\t# i2l" %} 10185 ins_encode %{ 10186 __ movslq($dst$$Register, $src$$Register); 10187 %} 10188 ins_pipe(ialu_reg_reg); 10189 %} 10190 10191 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10192 // %{ 10193 // match(Set dst (ConvI2L src)); 10194 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10195 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10196 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10197 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10198 // ((const TypeNode*) n)->type()->is_long()->_lo == 10199 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10200 10201 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10202 // ins_encode(enc_copy(dst, src)); 10203 // // opcode(0x63); // needs REX.W 10204 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10205 // ins_pipe(ialu_reg_reg); 10206 // %} 10207 10208 // Zero-extend convert int to long 10209 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10210 %{ 10211 match(Set dst (AndL (ConvI2L src) mask)); 10212 10213 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10214 ins_encode %{ 10215 if ($dst$$reg != $src$$reg) { 10216 __ movl($dst$$Register, $src$$Register); 10217 } 10218 %} 10219 ins_pipe(ialu_reg_reg); 10220 %} 10221 10222 // Zero-extend convert int to long 10223 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10224 %{ 10225 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10226 10227 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10228 ins_encode %{ 10229 __ movl($dst$$Register, $src$$Address); 10230 %} 10231 ins_pipe(ialu_reg_mem); 10232 %} 10233 10234 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10235 %{ 10236 match(Set dst (AndL src mask)); 10237 10238 format %{ "movl $dst, $src\t# zero-extend long" %} 10239 ins_encode %{ 10240 __ movl($dst$$Register, $src$$Register); 10241 %} 10242 ins_pipe(ialu_reg_reg); 10243 %} 10244 10245 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10246 %{ 10247 match(Set dst (ConvL2I src)); 10248 10249 format %{ "movl $dst, $src\t# l2i" %} 10250 ins_encode %{ 10251 __ movl($dst$$Register, $src$$Register); 10252 %} 10253 ins_pipe(ialu_reg_reg); 10254 %} 10255 10256 10257 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10258 match(Set dst (MoveF2I src)); 10259 effect(DEF dst, USE src); 10260 10261 ins_cost(125); 10262 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10263 ins_encode %{ 10264 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10265 %} 10266 ins_pipe(ialu_reg_mem); 10267 %} 10268 10269 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10270 match(Set dst (MoveI2F src)); 10271 effect(DEF dst, USE src); 10272 10273 ins_cost(125); 10274 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10275 ins_encode %{ 10276 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10277 %} 10278 ins_pipe(pipe_slow); 10279 %} 10280 10281 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10282 match(Set dst (MoveD2L src)); 10283 effect(DEF dst, USE src); 10284 10285 ins_cost(125); 10286 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10287 ins_encode %{ 10288 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10289 %} 10290 ins_pipe(ialu_reg_mem); 10291 %} 10292 10293 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10294 predicate(!UseXmmLoadAndClearUpper); 10295 match(Set dst (MoveL2D src)); 10296 effect(DEF dst, USE src); 10297 10298 ins_cost(125); 10299 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10300 ins_encode %{ 10301 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10302 %} 10303 ins_pipe(pipe_slow); 10304 %} 10305 10306 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10307 predicate(UseXmmLoadAndClearUpper); 10308 match(Set dst (MoveL2D src)); 10309 effect(DEF dst, USE src); 10310 10311 ins_cost(125); 10312 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10313 ins_encode %{ 10314 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10315 %} 10316 ins_pipe(pipe_slow); 10317 %} 10318 10319 10320 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10321 match(Set dst (MoveF2I src)); 10322 effect(DEF dst, USE src); 10323 10324 ins_cost(95); // XXX 10325 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10326 ins_encode %{ 10327 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10328 %} 10329 ins_pipe(pipe_slow); 10330 %} 10331 10332 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10333 match(Set dst (MoveI2F src)); 10334 effect(DEF dst, USE src); 10335 10336 ins_cost(100); 10337 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10338 ins_encode %{ 10339 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10340 %} 10341 ins_pipe( ialu_mem_reg ); 10342 %} 10343 10344 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10345 match(Set dst (MoveD2L src)); 10346 effect(DEF dst, USE src); 10347 10348 ins_cost(95); // XXX 10349 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10350 ins_encode %{ 10351 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10352 %} 10353 ins_pipe(pipe_slow); 10354 %} 10355 10356 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10357 match(Set dst (MoveL2D src)); 10358 effect(DEF dst, USE src); 10359 10360 ins_cost(100); 10361 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10362 ins_encode %{ 10363 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10364 %} 10365 ins_pipe(ialu_mem_reg); 10366 %} 10367 10368 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10369 match(Set dst (MoveF2I src)); 10370 effect(DEF dst, USE src); 10371 ins_cost(85); 10372 format %{ "movd $dst,$src\t# MoveF2I" %} 10373 ins_encode %{ 10374 __ movdl($dst$$Register, $src$$XMMRegister); 10375 %} 10376 ins_pipe( pipe_slow ); 10377 %} 10378 10379 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10380 match(Set dst (MoveD2L src)); 10381 effect(DEF dst, USE src); 10382 ins_cost(85); 10383 format %{ "movd $dst,$src\t# MoveD2L" %} 10384 ins_encode %{ 10385 __ movdq($dst$$Register, $src$$XMMRegister); 10386 %} 10387 ins_pipe( pipe_slow ); 10388 %} 10389 10390 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10391 match(Set dst (MoveI2F src)); 10392 effect(DEF dst, USE src); 10393 ins_cost(100); 10394 format %{ "movd $dst,$src\t# MoveI2F" %} 10395 ins_encode %{ 10396 __ movdl($dst$$XMMRegister, $src$$Register); 10397 %} 10398 ins_pipe( pipe_slow ); 10399 %} 10400 10401 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10402 match(Set dst (MoveL2D src)); 10403 effect(DEF dst, USE src); 10404 ins_cost(100); 10405 format %{ "movd $dst,$src\t# MoveL2D" %} 10406 ins_encode %{ 10407 __ movdq($dst$$XMMRegister, $src$$Register); 10408 %} 10409 ins_pipe( pipe_slow ); 10410 %} 10411 10412 10413 // ======================================================================= 10414 // fast clearing of an array 10415 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10416 rFlagsReg cr) 10417 %{ 10418 predicate(!UseFastStosb); 10419 match(Set dummy (ClearArray cnt base)); 10420 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10421 10422 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10423 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 10424 ins_encode %{ 10425 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10426 %} 10427 ins_pipe(pipe_slow); 10428 %} 10429 10430 instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10431 rFlagsReg cr) 10432 %{ 10433 predicate(UseFastStosb); 10434 match(Set dummy (ClearArray cnt base)); 10435 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10436 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10437 "shlq rcx,3\t# Convert doublewords to bytes\n\t" 10438 "rep stosb\t# Store rax to *rdi++ while rcx--" %} 10439 ins_encode %{ 10440 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10441 %} 10442 ins_pipe( pipe_slow ); 10443 %} 10444 10445 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10446 rax_RegI result, regD tmp1, rFlagsReg cr) 10447 %{ 10448 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10449 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10450 10451 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10452 ins_encode %{ 10453 __ string_compare($str1$$Register, $str2$$Register, 10454 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10455 $tmp1$$XMMRegister); 10456 %} 10457 ins_pipe( pipe_slow ); 10458 %} 10459 10460 // fast search of substring with known size. 10461 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10462 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10463 %{ 10464 predicate(UseSSE42Intrinsics); 10465 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10466 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10467 10468 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10469 ins_encode %{ 10470 int icnt2 = (int)$int_cnt2$$constant; 10471 if (icnt2 >= 8) { 10472 // IndexOf for constant substrings with size >= 8 elements 10473 // which don't need to be loaded through stack. 10474 __ string_indexofC8($str1$$Register, $str2$$Register, 10475 $cnt1$$Register, $cnt2$$Register, 10476 icnt2, $result$$Register, 10477 $vec$$XMMRegister, $tmp$$Register); 10478 } else { 10479 // Small strings are loaded through stack if they cross page boundary. 10480 __ string_indexof($str1$$Register, $str2$$Register, 10481 $cnt1$$Register, $cnt2$$Register, 10482 icnt2, $result$$Register, 10483 $vec$$XMMRegister, $tmp$$Register); 10484 } 10485 %} 10486 ins_pipe( pipe_slow ); 10487 %} 10488 10489 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10490 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10491 %{ 10492 predicate(UseSSE42Intrinsics); 10493 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10494 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10495 10496 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10497 ins_encode %{ 10498 __ string_indexof($str1$$Register, $str2$$Register, 10499 $cnt1$$Register, $cnt2$$Register, 10500 (-1), $result$$Register, 10501 $vec$$XMMRegister, $tmp$$Register); 10502 %} 10503 ins_pipe( pipe_slow ); 10504 %} 10505 10506 // fast string equals 10507 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10508 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10509 %{ 10510 match(Set result (StrEquals (Binary str1 str2) cnt)); 10511 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10512 10513 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10514 ins_encode %{ 10515 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 10516 $cnt$$Register, $result$$Register, $tmp3$$Register, 10517 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10518 %} 10519 ins_pipe( pipe_slow ); 10520 %} 10521 10522 // fast array equals 10523 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10524 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10525 %{ 10526 match(Set result (AryEq ary1 ary2)); 10527 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10528 //ins_cost(300); 10529 10530 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10531 ins_encode %{ 10532 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 10533 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10534 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10535 %} 10536 ins_pipe( pipe_slow ); 10537 %} 10538 10539 // encode char[] to byte[] in ISO_8859_1 10540 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 10541 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 10542 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 10543 match(Set result (EncodeISOArray src (Binary dst len))); 10544 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 10545 10546 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 10547 ins_encode %{ 10548 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 10549 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 10550 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 10551 %} 10552 ins_pipe( pipe_slow ); 10553 %} 10554 10555 //----------Overflow Math Instructions----------------------------------------- 10556 10557 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10558 %{ 10559 match(Set cr (OverflowAddI op1 op2)); 10560 effect(DEF cr, USE_KILL op1, USE op2); 10561 10562 format %{ "addl $op1, $op2\t# overflow check int" %} 10563 10564 ins_encode %{ 10565 __ addl($op1$$Register, $op2$$Register); 10566 %} 10567 ins_pipe(ialu_reg_reg); 10568 %} 10569 10570 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 10571 %{ 10572 match(Set cr (OverflowAddI op1 op2)); 10573 effect(DEF cr, USE_KILL op1, USE op2); 10574 10575 format %{ "addl $op1, $op2\t# overflow check int" %} 10576 10577 ins_encode %{ 10578 __ addl($op1$$Register, $op2$$constant); 10579 %} 10580 ins_pipe(ialu_reg_reg); 10581 %} 10582 10583 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10584 %{ 10585 match(Set cr (OverflowAddL op1 op2)); 10586 effect(DEF cr, USE_KILL op1, USE op2); 10587 10588 format %{ "addq $op1, $op2\t# overflow check long" %} 10589 ins_encode %{ 10590 __ addq($op1$$Register, $op2$$Register); 10591 %} 10592 ins_pipe(ialu_reg_reg); 10593 %} 10594 10595 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 10596 %{ 10597 match(Set cr (OverflowAddL op1 op2)); 10598 effect(DEF cr, USE_KILL op1, USE op2); 10599 10600 format %{ "addq $op1, $op2\t# overflow check long" %} 10601 ins_encode %{ 10602 __ addq($op1$$Register, $op2$$constant); 10603 %} 10604 ins_pipe(ialu_reg_reg); 10605 %} 10606 10607 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10608 %{ 10609 match(Set cr (OverflowSubI op1 op2)); 10610 10611 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10612 ins_encode %{ 10613 __ cmpl($op1$$Register, $op2$$Register); 10614 %} 10615 ins_pipe(ialu_reg_reg); 10616 %} 10617 10618 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10619 %{ 10620 match(Set cr (OverflowSubI op1 op2)); 10621 10622 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10623 ins_encode %{ 10624 __ cmpl($op1$$Register, $op2$$constant); 10625 %} 10626 ins_pipe(ialu_reg_reg); 10627 %} 10628 10629 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10630 %{ 10631 match(Set cr (OverflowSubL op1 op2)); 10632 10633 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10634 ins_encode %{ 10635 __ cmpq($op1$$Register, $op2$$Register); 10636 %} 10637 ins_pipe(ialu_reg_reg); 10638 %} 10639 10640 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10641 %{ 10642 match(Set cr (OverflowSubL op1 op2)); 10643 10644 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10645 ins_encode %{ 10646 __ cmpq($op1$$Register, $op2$$constant); 10647 %} 10648 ins_pipe(ialu_reg_reg); 10649 %} 10650 10651 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 10652 %{ 10653 match(Set cr (OverflowSubI zero op2)); 10654 effect(DEF cr, USE_KILL op2); 10655 10656 format %{ "negl $op2\t# overflow check int" %} 10657 ins_encode %{ 10658 __ negl($op2$$Register); 10659 %} 10660 ins_pipe(ialu_reg_reg); 10661 %} 10662 10663 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 10664 %{ 10665 match(Set cr (OverflowSubL zero op2)); 10666 effect(DEF cr, USE_KILL op2); 10667 10668 format %{ "negq $op2\t# overflow check long" %} 10669 ins_encode %{ 10670 __ negq($op2$$Register); 10671 %} 10672 ins_pipe(ialu_reg_reg); 10673 %} 10674 10675 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10676 %{ 10677 match(Set cr (OverflowMulI op1 op2)); 10678 effect(DEF cr, USE_KILL op1, USE op2); 10679 10680 format %{ "imull $op1, $op2\t# overflow check int" %} 10681 ins_encode %{ 10682 __ imull($op1$$Register, $op2$$Register); 10683 %} 10684 ins_pipe(ialu_reg_reg_alu0); 10685 %} 10686 10687 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 10688 %{ 10689 match(Set cr (OverflowMulI op1 op2)); 10690 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10691 10692 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 10693 ins_encode %{ 10694 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 10695 %} 10696 ins_pipe(ialu_reg_reg_alu0); 10697 %} 10698 10699 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10700 %{ 10701 match(Set cr (OverflowMulL op1 op2)); 10702 effect(DEF cr, USE_KILL op1, USE op2); 10703 10704 format %{ "imulq $op1, $op2\t# overflow check long" %} 10705 ins_encode %{ 10706 __ imulq($op1$$Register, $op2$$Register); 10707 %} 10708 ins_pipe(ialu_reg_reg_alu0); 10709 %} 10710 10711 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 10712 %{ 10713 match(Set cr (OverflowMulL op1 op2)); 10714 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10715 10716 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 10717 ins_encode %{ 10718 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 10719 %} 10720 ins_pipe(ialu_reg_reg_alu0); 10721 %} 10722 10723 10724 //----------Control Flow Instructions------------------------------------------ 10725 // Signed compare Instructions 10726 10727 // XXX more variants!! 10728 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10729 %{ 10730 match(Set cr (CmpI op1 op2)); 10731 effect(DEF cr, USE op1, USE op2); 10732 10733 format %{ "cmpl $op1, $op2" %} 10734 opcode(0x3B); /* Opcode 3B /r */ 10735 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10736 ins_pipe(ialu_cr_reg_reg); 10737 %} 10738 10739 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10740 %{ 10741 match(Set cr (CmpI op1 op2)); 10742 10743 format %{ "cmpl $op1, $op2" %} 10744 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10745 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10746 ins_pipe(ialu_cr_reg_imm); 10747 %} 10748 10749 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 10750 %{ 10751 match(Set cr (CmpI op1 (LoadI op2))); 10752 10753 ins_cost(500); // XXX 10754 format %{ "cmpl $op1, $op2" %} 10755 opcode(0x3B); /* Opcode 3B /r */ 10756 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10757 ins_pipe(ialu_cr_reg_mem); 10758 %} 10759 10760 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 10761 %{ 10762 match(Set cr (CmpI src zero)); 10763 10764 format %{ "testl $src, $src" %} 10765 opcode(0x85); 10766 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10767 ins_pipe(ialu_cr_reg_imm); 10768 %} 10769 10770 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 10771 %{ 10772 match(Set cr (CmpI (AndI src con) zero)); 10773 10774 format %{ "testl $src, $con" %} 10775 opcode(0xF7, 0x00); 10776 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 10777 ins_pipe(ialu_cr_reg_imm); 10778 %} 10779 10780 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 10781 %{ 10782 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 10783 10784 format %{ "testl $src, $mem" %} 10785 opcode(0x85); 10786 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 10787 ins_pipe(ialu_cr_reg_mem); 10788 %} 10789 10790 // Unsigned compare Instructions; really, same as signed except they 10791 // produce an rFlagsRegU instead of rFlagsReg. 10792 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 10793 %{ 10794 match(Set cr (CmpU op1 op2)); 10795 10796 format %{ "cmpl $op1, $op2\t# unsigned" %} 10797 opcode(0x3B); /* Opcode 3B /r */ 10798 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10799 ins_pipe(ialu_cr_reg_reg); 10800 %} 10801 10802 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 10803 %{ 10804 match(Set cr (CmpU op1 op2)); 10805 10806 format %{ "cmpl $op1, $op2\t# unsigned" %} 10807 opcode(0x81,0x07); /* Opcode 81 /7 */ 10808 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10809 ins_pipe(ialu_cr_reg_imm); 10810 %} 10811 10812 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 10813 %{ 10814 match(Set cr (CmpU op1 (LoadI op2))); 10815 10816 ins_cost(500); // XXX 10817 format %{ "cmpl $op1, $op2\t# unsigned" %} 10818 opcode(0x3B); /* Opcode 3B /r */ 10819 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10820 ins_pipe(ialu_cr_reg_mem); 10821 %} 10822 10823 // // // Cisc-spilled version of cmpU_rReg 10824 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 10825 // //%{ 10826 // // match(Set cr (CmpU (LoadI op1) op2)); 10827 // // 10828 // // format %{ "CMPu $op1,$op2" %} 10829 // // ins_cost(500); 10830 // // opcode(0x39); /* Opcode 39 /r */ 10831 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10832 // //%} 10833 10834 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 10835 %{ 10836 match(Set cr (CmpU src zero)); 10837 10838 format %{ "testl $src, $src\t# unsigned" %} 10839 opcode(0x85); 10840 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10841 ins_pipe(ialu_cr_reg_imm); 10842 %} 10843 10844 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 10845 %{ 10846 match(Set cr (CmpP op1 op2)); 10847 10848 format %{ "cmpq $op1, $op2\t# ptr" %} 10849 opcode(0x3B); /* Opcode 3B /r */ 10850 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10851 ins_pipe(ialu_cr_reg_reg); 10852 %} 10853 10854 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 10855 %{ 10856 match(Set cr (CmpP op1 (LoadP op2))); 10857 10858 ins_cost(500); // XXX 10859 format %{ "cmpq $op1, $op2\t# ptr" %} 10860 opcode(0x3B); /* Opcode 3B /r */ 10861 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10862 ins_pipe(ialu_cr_reg_mem); 10863 %} 10864 10865 // // // Cisc-spilled version of cmpP_rReg 10866 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 10867 // //%{ 10868 // // match(Set cr (CmpP (LoadP op1) op2)); 10869 // // 10870 // // format %{ "CMPu $op1,$op2" %} 10871 // // ins_cost(500); 10872 // // opcode(0x39); /* Opcode 39 /r */ 10873 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10874 // //%} 10875 10876 // XXX this is generalized by compP_rReg_mem??? 10877 // Compare raw pointer (used in out-of-heap check). 10878 // Only works because non-oop pointers must be raw pointers 10879 // and raw pointers have no anti-dependencies. 10880 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 10881 %{ 10882 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 10883 match(Set cr (CmpP op1 (LoadP op2))); 10884 10885 format %{ "cmpq $op1, $op2\t# raw ptr" %} 10886 opcode(0x3B); /* Opcode 3B /r */ 10887 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10888 ins_pipe(ialu_cr_reg_mem); 10889 %} 10890 10891 // This will generate a signed flags result. This should be OK since 10892 // any compare to a zero should be eq/neq. 10893 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 10894 %{ 10895 match(Set cr (CmpP src zero)); 10896 10897 format %{ "testq $src, $src\t# ptr" %} 10898 opcode(0x85); 10899 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10900 ins_pipe(ialu_cr_reg_imm); 10901 %} 10902 10903 // This will generate a signed flags result. This should be OK since 10904 // any compare to a zero should be eq/neq. 10905 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 10906 %{ 10907 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 10908 match(Set cr (CmpP (LoadP op) zero)); 10909 10910 ins_cost(500); // XXX 10911 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 10912 opcode(0xF7); /* Opcode F7 /0 */ 10913 ins_encode(REX_mem_wide(op), 10914 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 10915 ins_pipe(ialu_cr_reg_imm); 10916 %} 10917 10918 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 10919 %{ 10920 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 10921 match(Set cr (CmpP (LoadP mem) zero)); 10922 10923 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 10924 ins_encode %{ 10925 __ cmpq(r12, $mem$$Address); 10926 %} 10927 ins_pipe(ialu_cr_reg_mem); 10928 %} 10929 10930 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 10931 %{ 10932 match(Set cr (CmpN op1 op2)); 10933 10934 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10935 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 10936 ins_pipe(ialu_cr_reg_reg); 10937 %} 10938 10939 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 10940 %{ 10941 match(Set cr (CmpN src (LoadN mem))); 10942 10943 format %{ "cmpl $src, $mem\t# compressed ptr" %} 10944 ins_encode %{ 10945 __ cmpl($src$$Register, $mem$$Address); 10946 %} 10947 ins_pipe(ialu_cr_reg_mem); 10948 %} 10949 10950 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 10951 match(Set cr (CmpN op1 op2)); 10952 10953 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10954 ins_encode %{ 10955 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 10956 %} 10957 ins_pipe(ialu_cr_reg_imm); 10958 %} 10959 10960 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 10961 %{ 10962 match(Set cr (CmpN src (LoadN mem))); 10963 10964 format %{ "cmpl $mem, $src\t# compressed ptr" %} 10965 ins_encode %{ 10966 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 10967 %} 10968 ins_pipe(ialu_cr_reg_mem); 10969 %} 10970 10971 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 10972 match(Set cr (CmpN op1 op2)); 10973 10974 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 10975 ins_encode %{ 10976 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 10977 %} 10978 ins_pipe(ialu_cr_reg_imm); 10979 %} 10980 10981 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 10982 %{ 10983 match(Set cr (CmpN src (LoadNKlass mem))); 10984 10985 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 10986 ins_encode %{ 10987 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 10988 %} 10989 ins_pipe(ialu_cr_reg_mem); 10990 %} 10991 10992 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 10993 match(Set cr (CmpN src zero)); 10994 10995 format %{ "testl $src, $src\t# compressed ptr" %} 10996 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 10997 ins_pipe(ialu_cr_reg_imm); 10998 %} 10999 11000 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11001 %{ 11002 predicate(Universe::narrow_oop_base() != NULL); 11003 match(Set cr (CmpN (LoadN mem) zero)); 11004 11005 ins_cost(500); // XXX 11006 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11007 ins_encode %{ 11008 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11009 %} 11010 ins_pipe(ialu_cr_reg_mem); 11011 %} 11012 11013 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11014 %{ 11015 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11016 match(Set cr (CmpN (LoadN mem) zero)); 11017 11018 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11019 ins_encode %{ 11020 __ cmpl(r12, $mem$$Address); 11021 %} 11022 ins_pipe(ialu_cr_reg_mem); 11023 %} 11024 11025 // Yanked all unsigned pointer compare operations. 11026 // Pointer compares are done with CmpP which is already unsigned. 11027 11028 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11029 %{ 11030 match(Set cr (CmpL op1 op2)); 11031 11032 format %{ "cmpq $op1, $op2" %} 11033 opcode(0x3B); /* Opcode 3B /r */ 11034 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11035 ins_pipe(ialu_cr_reg_reg); 11036 %} 11037 11038 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11039 %{ 11040 match(Set cr (CmpL op1 op2)); 11041 11042 format %{ "cmpq $op1, $op2" %} 11043 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11044 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11045 ins_pipe(ialu_cr_reg_imm); 11046 %} 11047 11048 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11049 %{ 11050 match(Set cr (CmpL op1 (LoadL op2))); 11051 11052 format %{ "cmpq $op1, $op2" %} 11053 opcode(0x3B); /* Opcode 3B /r */ 11054 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11055 ins_pipe(ialu_cr_reg_mem); 11056 %} 11057 11058 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11059 %{ 11060 match(Set cr (CmpL src zero)); 11061 11062 format %{ "testq $src, $src" %} 11063 opcode(0x85); 11064 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11065 ins_pipe(ialu_cr_reg_imm); 11066 %} 11067 11068 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11069 %{ 11070 match(Set cr (CmpL (AndL src con) zero)); 11071 11072 format %{ "testq $src, $con\t# long" %} 11073 opcode(0xF7, 0x00); 11074 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11075 ins_pipe(ialu_cr_reg_imm); 11076 %} 11077 11078 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11079 %{ 11080 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11081 11082 format %{ "testq $src, $mem" %} 11083 opcode(0x85); 11084 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11085 ins_pipe(ialu_cr_reg_mem); 11086 %} 11087 11088 // Manifest a CmpL result in an integer register. Very painful. 11089 // This is the test to avoid. 11090 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11091 %{ 11092 match(Set dst (CmpL3 src1 src2)); 11093 effect(KILL flags); 11094 11095 ins_cost(275); // XXX 11096 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11097 "movl $dst, -1\n\t" 11098 "jl,s done\n\t" 11099 "setne $dst\n\t" 11100 "movzbl $dst, $dst\n\t" 11101 "done:" %} 11102 ins_encode(cmpl3_flag(src1, src2, dst)); 11103 ins_pipe(pipe_slow); 11104 %} 11105 11106 //----------Max and Min-------------------------------------------------------- 11107 // Min Instructions 11108 11109 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11110 %{ 11111 effect(USE_DEF dst, USE src, USE cr); 11112 11113 format %{ "cmovlgt $dst, $src\t# min" %} 11114 opcode(0x0F, 0x4F); 11115 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11116 ins_pipe(pipe_cmov_reg); 11117 %} 11118 11119 11120 instruct minI_rReg(rRegI dst, rRegI src) 11121 %{ 11122 match(Set dst (MinI dst src)); 11123 11124 ins_cost(200); 11125 expand %{ 11126 rFlagsReg cr; 11127 compI_rReg(cr, dst, src); 11128 cmovI_reg_g(dst, src, cr); 11129 %} 11130 %} 11131 11132 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11133 %{ 11134 effect(USE_DEF dst, USE src, USE cr); 11135 11136 format %{ "cmovllt $dst, $src\t# max" %} 11137 opcode(0x0F, 0x4C); 11138 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11139 ins_pipe(pipe_cmov_reg); 11140 %} 11141 11142 11143 instruct maxI_rReg(rRegI dst, rRegI src) 11144 %{ 11145 match(Set dst (MaxI dst src)); 11146 11147 ins_cost(200); 11148 expand %{ 11149 rFlagsReg cr; 11150 compI_rReg(cr, dst, src); 11151 cmovI_reg_l(dst, src, cr); 11152 %} 11153 %} 11154 11155 // ============================================================================ 11156 // Branch Instructions 11157 11158 // Jump Direct - Label defines a relative address from JMP+1 11159 instruct jmpDir(label labl) 11160 %{ 11161 match(Goto); 11162 effect(USE labl); 11163 11164 ins_cost(300); 11165 format %{ "jmp $labl" %} 11166 size(5); 11167 ins_encode %{ 11168 Label* L = $labl$$label; 11169 __ jmp(*L, false); // Always long jump 11170 %} 11171 ins_pipe(pipe_jmp); 11172 %} 11173 11174 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11175 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11176 %{ 11177 match(If cop cr); 11178 effect(USE labl); 11179 11180 ins_cost(300); 11181 format %{ "j$cop $labl" %} 11182 size(6); 11183 ins_encode %{ 11184 Label* L = $labl$$label; 11185 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11186 %} 11187 ins_pipe(pipe_jcc); 11188 %} 11189 11190 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11191 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11192 %{ 11193 match(CountedLoopEnd cop cr); 11194 effect(USE labl); 11195 11196 ins_cost(300); 11197 format %{ "j$cop $labl\t# loop end" %} 11198 size(6); 11199 ins_encode %{ 11200 Label* L = $labl$$label; 11201 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11202 %} 11203 ins_pipe(pipe_jcc); 11204 %} 11205 11206 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11207 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11208 match(CountedLoopEnd cop cmp); 11209 effect(USE labl); 11210 11211 ins_cost(300); 11212 format %{ "j$cop,u $labl\t# loop end" %} 11213 size(6); 11214 ins_encode %{ 11215 Label* L = $labl$$label; 11216 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11217 %} 11218 ins_pipe(pipe_jcc); 11219 %} 11220 11221 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11222 match(CountedLoopEnd cop cmp); 11223 effect(USE labl); 11224 11225 ins_cost(200); 11226 format %{ "j$cop,u $labl\t# loop end" %} 11227 size(6); 11228 ins_encode %{ 11229 Label* L = $labl$$label; 11230 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11231 %} 11232 ins_pipe(pipe_jcc); 11233 %} 11234 11235 // Jump Direct Conditional - using unsigned comparison 11236 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11237 match(If cop cmp); 11238 effect(USE labl); 11239 11240 ins_cost(300); 11241 format %{ "j$cop,u $labl" %} 11242 size(6); 11243 ins_encode %{ 11244 Label* L = $labl$$label; 11245 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11246 %} 11247 ins_pipe(pipe_jcc); 11248 %} 11249 11250 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11251 match(If cop cmp); 11252 effect(USE labl); 11253 11254 ins_cost(200); 11255 format %{ "j$cop,u $labl" %} 11256 size(6); 11257 ins_encode %{ 11258 Label* L = $labl$$label; 11259 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11260 %} 11261 ins_pipe(pipe_jcc); 11262 %} 11263 11264 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11265 match(If cop cmp); 11266 effect(USE labl); 11267 11268 ins_cost(200); 11269 format %{ $$template 11270 if ($cop$$cmpcode == Assembler::notEqual) { 11271 $$emit$$"jp,u $labl\n\t" 11272 $$emit$$"j$cop,u $labl" 11273 } else { 11274 $$emit$$"jp,u done\n\t" 11275 $$emit$$"j$cop,u $labl\n\t" 11276 $$emit$$"done:" 11277 } 11278 %} 11279 ins_encode %{ 11280 Label* l = $labl$$label; 11281 if ($cop$$cmpcode == Assembler::notEqual) { 11282 __ jcc(Assembler::parity, *l, false); 11283 __ jcc(Assembler::notEqual, *l, false); 11284 } else if ($cop$$cmpcode == Assembler::equal) { 11285 Label done; 11286 __ jccb(Assembler::parity, done); 11287 __ jcc(Assembler::equal, *l, false); 11288 __ bind(done); 11289 } else { 11290 ShouldNotReachHere(); 11291 } 11292 %} 11293 ins_pipe(pipe_jcc); 11294 %} 11295 11296 // ============================================================================ 11297 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11298 // superklass array for an instance of the superklass. Set a hidden 11299 // internal cache on a hit (cache is checked with exposed code in 11300 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11301 // encoding ALSO sets flags. 11302 11303 instruct partialSubtypeCheck(rdi_RegP result, 11304 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11305 rFlagsReg cr) 11306 %{ 11307 match(Set result (PartialSubtypeCheck sub super)); 11308 effect(KILL rcx, KILL cr); 11309 11310 ins_cost(1100); // slightly larger than the next version 11311 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11312 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11313 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11314 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11315 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11316 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11317 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11318 "miss:\t" %} 11319 11320 opcode(0x1); // Force a XOR of RDI 11321 ins_encode(enc_PartialSubtypeCheck()); 11322 ins_pipe(pipe_slow); 11323 %} 11324 11325 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11326 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11327 immP0 zero, 11328 rdi_RegP result) 11329 %{ 11330 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11331 effect(KILL rcx, KILL result); 11332 11333 ins_cost(1000); 11334 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11335 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11336 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11337 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11338 "jne,s miss\t\t# Missed: flags nz\n\t" 11339 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11340 "miss:\t" %} 11341 11342 opcode(0x0); // No need to XOR RDI 11343 ins_encode(enc_PartialSubtypeCheck()); 11344 ins_pipe(pipe_slow); 11345 %} 11346 11347 // ============================================================================ 11348 // Branch Instructions -- short offset versions 11349 // 11350 // These instructions are used to replace jumps of a long offset (the default 11351 // match) with jumps of a shorter offset. These instructions are all tagged 11352 // with the ins_short_branch attribute, which causes the ADLC to suppress the 11353 // match rules in general matching. Instead, the ADLC generates a conversion 11354 // method in the MachNode which can be used to do in-place replacement of the 11355 // long variant with the shorter variant. The compiler will determine if a 11356 // branch can be taken by the is_short_branch_offset() predicate in the machine 11357 // specific code section of the file. 11358 11359 // Jump Direct - Label defines a relative address from JMP+1 11360 instruct jmpDir_short(label labl) %{ 11361 match(Goto); 11362 effect(USE labl); 11363 11364 ins_cost(300); 11365 format %{ "jmp,s $labl" %} 11366 size(2); 11367 ins_encode %{ 11368 Label* L = $labl$$label; 11369 __ jmpb(*L); 11370 %} 11371 ins_pipe(pipe_jmp); 11372 ins_short_branch(1); 11373 %} 11374 11375 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11376 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11377 match(If cop cr); 11378 effect(USE labl); 11379 11380 ins_cost(300); 11381 format %{ "j$cop,s $labl" %} 11382 size(2); 11383 ins_encode %{ 11384 Label* L = $labl$$label; 11385 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11386 %} 11387 ins_pipe(pipe_jcc); 11388 ins_short_branch(1); 11389 %} 11390 11391 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11392 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11393 match(CountedLoopEnd cop cr); 11394 effect(USE labl); 11395 11396 ins_cost(300); 11397 format %{ "j$cop,s $labl\t# loop end" %} 11398 size(2); 11399 ins_encode %{ 11400 Label* L = $labl$$label; 11401 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11402 %} 11403 ins_pipe(pipe_jcc); 11404 ins_short_branch(1); 11405 %} 11406 11407 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11408 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11409 match(CountedLoopEnd cop cmp); 11410 effect(USE labl); 11411 11412 ins_cost(300); 11413 format %{ "j$cop,us $labl\t# loop end" %} 11414 size(2); 11415 ins_encode %{ 11416 Label* L = $labl$$label; 11417 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11418 %} 11419 ins_pipe(pipe_jcc); 11420 ins_short_branch(1); 11421 %} 11422 11423 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11424 match(CountedLoopEnd cop cmp); 11425 effect(USE labl); 11426 11427 ins_cost(300); 11428 format %{ "j$cop,us $labl\t# loop end" %} 11429 size(2); 11430 ins_encode %{ 11431 Label* L = $labl$$label; 11432 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11433 %} 11434 ins_pipe(pipe_jcc); 11435 ins_short_branch(1); 11436 %} 11437 11438 // Jump Direct Conditional - using unsigned comparison 11439 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11440 match(If cop cmp); 11441 effect(USE labl); 11442 11443 ins_cost(300); 11444 format %{ "j$cop,us $labl" %} 11445 size(2); 11446 ins_encode %{ 11447 Label* L = $labl$$label; 11448 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11449 %} 11450 ins_pipe(pipe_jcc); 11451 ins_short_branch(1); 11452 %} 11453 11454 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11455 match(If cop cmp); 11456 effect(USE labl); 11457 11458 ins_cost(300); 11459 format %{ "j$cop,us $labl" %} 11460 size(2); 11461 ins_encode %{ 11462 Label* L = $labl$$label; 11463 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11464 %} 11465 ins_pipe(pipe_jcc); 11466 ins_short_branch(1); 11467 %} 11468 11469 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11470 match(If cop cmp); 11471 effect(USE labl); 11472 11473 ins_cost(300); 11474 format %{ $$template 11475 if ($cop$$cmpcode == Assembler::notEqual) { 11476 $$emit$$"jp,u,s $labl\n\t" 11477 $$emit$$"j$cop,u,s $labl" 11478 } else { 11479 $$emit$$"jp,u,s done\n\t" 11480 $$emit$$"j$cop,u,s $labl\n\t" 11481 $$emit$$"done:" 11482 } 11483 %} 11484 size(4); 11485 ins_encode %{ 11486 Label* l = $labl$$label; 11487 if ($cop$$cmpcode == Assembler::notEqual) { 11488 __ jccb(Assembler::parity, *l); 11489 __ jccb(Assembler::notEqual, *l); 11490 } else if ($cop$$cmpcode == Assembler::equal) { 11491 Label done; 11492 __ jccb(Assembler::parity, done); 11493 __ jccb(Assembler::equal, *l); 11494 __ bind(done); 11495 } else { 11496 ShouldNotReachHere(); 11497 } 11498 %} 11499 ins_pipe(pipe_jcc); 11500 ins_short_branch(1); 11501 %} 11502 11503 // ============================================================================ 11504 // inlined locking and unlocking 11505 11506 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 11507 predicate(Compile::current()->use_rtm()); 11508 match(Set cr (FastLock object box)); 11509 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 11510 ins_cost(300); 11511 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 11512 ins_encode %{ 11513 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 11514 $scr$$Register, $cx1$$Register, $cx2$$Register, 11515 _counters, _rtm_counters, _stack_rtm_counters, 11516 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11517 true, ra_->C->profile_rtm()); 11518 %} 11519 ins_pipe(pipe_slow); 11520 %} 11521 11522 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 11523 predicate(!Compile::current()->use_rtm()); 11524 match(Set cr (FastLock object box)); 11525 effect(TEMP tmp, TEMP scr, USE_KILL box); 11526 ins_cost(300); 11527 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 11528 ins_encode %{ 11529 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 11530 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 11531 %} 11532 ins_pipe(pipe_slow); 11533 %} 11534 11535 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 11536 match(Set cr (FastUnlock object box)); 11537 effect(TEMP tmp, USE_KILL box); 11538 ins_cost(300); 11539 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 11540 ins_encode %{ 11541 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 11542 %} 11543 ins_pipe(pipe_slow); 11544 %} 11545 11546 11547 // ============================================================================ 11548 // Safepoint Instructions 11549 instruct safePoint_poll(rFlagsReg cr) 11550 %{ 11551 predicate(!Assembler::is_polling_page_far()); 11552 match(SafePoint); 11553 effect(KILL cr); 11554 11555 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 11556 "# Safepoint: poll for GC" %} 11557 ins_cost(125); 11558 ins_encode %{ 11559 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 11560 __ testl(rax, addr); 11561 %} 11562 ins_pipe(ialu_reg_mem); 11563 %} 11564 11565 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 11566 %{ 11567 predicate(Assembler::is_polling_page_far()); 11568 match(SafePoint poll); 11569 effect(KILL cr, USE poll); 11570 11571 format %{ "testl rax, [$poll]\t" 11572 "# Safepoint: poll for GC" %} 11573 ins_cost(125); 11574 ins_encode %{ 11575 __ relocate(relocInfo::poll_type); 11576 __ testl(rax, Address($poll$$Register, 0)); 11577 %} 11578 ins_pipe(ialu_reg_mem); 11579 %} 11580 11581 // ============================================================================ 11582 // Procedure Call/Return Instructions 11583 // Call Java Static Instruction 11584 // Note: If this code changes, the corresponding ret_addr_offset() and 11585 // compute_padding() functions will have to be adjusted. 11586 instruct CallStaticJavaDirect(method meth) %{ 11587 match(CallStaticJava); 11588 effect(USE meth); 11589 11590 ins_cost(300); 11591 format %{ "call,static " %} 11592 opcode(0xE8); /* E8 cd */ 11593 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 11594 ins_pipe(pipe_slow); 11595 ins_alignment(4); 11596 %} 11597 11598 // Call Java Dynamic Instruction 11599 // Note: If this code changes, the corresponding ret_addr_offset() and 11600 // compute_padding() functions will have to be adjusted. 11601 instruct CallDynamicJavaDirect(method meth) 11602 %{ 11603 match(CallDynamicJava); 11604 effect(USE meth); 11605 11606 ins_cost(300); 11607 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11608 "call,dynamic " %} 11609 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 11610 ins_pipe(pipe_slow); 11611 ins_alignment(4); 11612 %} 11613 11614 // Call Runtime Instruction 11615 instruct CallRuntimeDirect(method meth) 11616 %{ 11617 match(CallRuntime); 11618 effect(USE meth); 11619 11620 ins_cost(300); 11621 format %{ "call,runtime " %} 11622 ins_encode(clear_avx, Java_To_Runtime(meth)); 11623 ins_pipe(pipe_slow); 11624 %} 11625 11626 // Call runtime without safepoint 11627 instruct CallLeafDirect(method meth) 11628 %{ 11629 match(CallLeaf); 11630 effect(USE meth); 11631 11632 ins_cost(300); 11633 format %{ "call_leaf,runtime " %} 11634 ins_encode(clear_avx, Java_To_Runtime(meth)); 11635 ins_pipe(pipe_slow); 11636 %} 11637 11638 // Call runtime without safepoint 11639 instruct CallLeafNoFPDirect(method meth) 11640 %{ 11641 match(CallLeafNoFP); 11642 effect(USE meth); 11643 11644 ins_cost(300); 11645 format %{ "call_leaf_nofp,runtime " %} 11646 ins_encode(Java_To_Runtime(meth)); 11647 ins_pipe(pipe_slow); 11648 %} 11649 11650 // Return Instruction 11651 // Remove the return address & jump to it. 11652 // Notice: We always emit a nop after a ret to make sure there is room 11653 // for safepoint patching 11654 instruct Ret() 11655 %{ 11656 match(Return); 11657 11658 format %{ "ret" %} 11659 opcode(0xC3); 11660 ins_encode(OpcP); 11661 ins_pipe(pipe_jmp); 11662 %} 11663 11664 // Tail Call; Jump from runtime stub to Java code. 11665 // Also known as an 'interprocedural jump'. 11666 // Target of jump will eventually return to caller. 11667 // TailJump below removes the return address. 11668 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 11669 %{ 11670 match(TailCall jump_target method_oop); 11671 11672 ins_cost(300); 11673 format %{ "jmp $jump_target\t# rbx holds method oop" %} 11674 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11675 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11676 ins_pipe(pipe_jmp); 11677 %} 11678 11679 // Tail Jump; remove the return address; jump to target. 11680 // TailCall above leaves the return address around. 11681 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 11682 %{ 11683 match(TailJump jump_target ex_oop); 11684 11685 ins_cost(300); 11686 format %{ "popq rdx\t# pop return address\n\t" 11687 "jmp $jump_target" %} 11688 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11689 ins_encode(Opcode(0x5a), // popq rdx 11690 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11691 ins_pipe(pipe_jmp); 11692 %} 11693 11694 // Create exception oop: created by stack-crawling runtime code. 11695 // Created exception is now available to this handler, and is setup 11696 // just prior to jumping to this handler. No code emitted. 11697 instruct CreateException(rax_RegP ex_oop) 11698 %{ 11699 match(Set ex_oop (CreateEx)); 11700 11701 size(0); 11702 // use the following format syntax 11703 format %{ "# exception oop is in rax; no code emitted" %} 11704 ins_encode(); 11705 ins_pipe(empty); 11706 %} 11707 11708 // Rethrow exception: 11709 // The exception oop will come in the first argument position. 11710 // Then JUMP (not call) to the rethrow stub code. 11711 instruct RethrowException() 11712 %{ 11713 match(Rethrow); 11714 11715 // use the following format syntax 11716 format %{ "jmp rethrow_stub" %} 11717 ins_encode(enc_rethrow); 11718 ins_pipe(pipe_jmp); 11719 %} 11720 11721 11722 // ============================================================================ 11723 // This name is KNOWN by the ADLC and cannot be changed. 11724 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 11725 // for this guy. 11726 instruct tlsLoadP(r15_RegP dst) %{ 11727 match(Set dst (ThreadLocal)); 11728 effect(DEF dst); 11729 11730 size(0); 11731 format %{ "# TLS is in R15" %} 11732 ins_encode( /*empty encoding*/ ); 11733 ins_pipe(ialu_reg_reg); 11734 %} 11735 11736 11737 //----------PEEPHOLE RULES----------------------------------------------------- 11738 // These must follow all instruction definitions as they use the names 11739 // defined in the instructions definitions. 11740 // 11741 // peepmatch ( root_instr_name [preceding_instruction]* ); 11742 // 11743 // peepconstraint %{ 11744 // (instruction_number.operand_name relational_op instruction_number.operand_name 11745 // [, ...] ); 11746 // // instruction numbers are zero-based using left to right order in peepmatch 11747 // 11748 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 11749 // // provide an instruction_number.operand_name for each operand that appears 11750 // // in the replacement instruction's match rule 11751 // 11752 // ---------VM FLAGS--------------------------------------------------------- 11753 // 11754 // All peephole optimizations can be turned off using -XX:-OptoPeephole 11755 // 11756 // Each peephole rule is given an identifying number starting with zero and 11757 // increasing by one in the order seen by the parser. An individual peephole 11758 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 11759 // on the command-line. 11760 // 11761 // ---------CURRENT LIMITATIONS---------------------------------------------- 11762 // 11763 // Only match adjacent instructions in same basic block 11764 // Only equality constraints 11765 // Only constraints between operands, not (0.dest_reg == RAX_enc) 11766 // Only one replacement instruction 11767 // 11768 // ---------EXAMPLE---------------------------------------------------------- 11769 // 11770 // // pertinent parts of existing instructions in architecture description 11771 // instruct movI(rRegI dst, rRegI src) 11772 // %{ 11773 // match(Set dst (CopyI src)); 11774 // %} 11775 // 11776 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 11777 // %{ 11778 // match(Set dst (AddI dst src)); 11779 // effect(KILL cr); 11780 // %} 11781 // 11782 // // Change (inc mov) to lea 11783 // peephole %{ 11784 // // increment preceeded by register-register move 11785 // peepmatch ( incI_rReg movI ); 11786 // // require that the destination register of the increment 11787 // // match the destination register of the move 11788 // peepconstraint ( 0.dst == 1.dst ); 11789 // // construct a replacement instruction that sets 11790 // // the destination to ( move's source register + one ) 11791 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 11792 // %} 11793 // 11794 11795 // Implementation no longer uses movX instructions since 11796 // machine-independent system no longer uses CopyX nodes. 11797 // 11798 // peephole 11799 // %{ 11800 // peepmatch (incI_rReg movI); 11801 // peepconstraint (0.dst == 1.dst); 11802 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11803 // %} 11804 11805 // peephole 11806 // %{ 11807 // peepmatch (decI_rReg movI); 11808 // peepconstraint (0.dst == 1.dst); 11809 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11810 // %} 11811 11812 // peephole 11813 // %{ 11814 // peepmatch (addI_rReg_imm movI); 11815 // peepconstraint (0.dst == 1.dst); 11816 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11817 // %} 11818 11819 // peephole 11820 // %{ 11821 // peepmatch (incL_rReg movL); 11822 // peepconstraint (0.dst == 1.dst); 11823 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11824 // %} 11825 11826 // peephole 11827 // %{ 11828 // peepmatch (decL_rReg movL); 11829 // peepconstraint (0.dst == 1.dst); 11830 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11831 // %} 11832 11833 // peephole 11834 // %{ 11835 // peepmatch (addL_rReg_imm movL); 11836 // peepconstraint (0.dst == 1.dst); 11837 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11838 // %} 11839 11840 // peephole 11841 // %{ 11842 // peepmatch (addP_rReg_imm movP); 11843 // peepconstraint (0.dst == 1.dst); 11844 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 11845 // %} 11846 11847 // // Change load of spilled value to only a spill 11848 // instruct storeI(memory mem, rRegI src) 11849 // %{ 11850 // match(Set mem (StoreI mem src)); 11851 // %} 11852 // 11853 // instruct loadI(rRegI dst, memory mem) 11854 // %{ 11855 // match(Set dst (LoadI mem)); 11856 // %} 11857 // 11858 11859 peephole 11860 %{ 11861 peepmatch (loadI storeI); 11862 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11863 peepreplace (storeI(1.mem 1.mem 1.src)); 11864 %} 11865 11866 peephole 11867 %{ 11868 peepmatch (loadL storeL); 11869 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11870 peepreplace (storeL(1.mem 1.mem 1.src)); 11871 %} 11872 11873 //----------SMARTSPILL RULES--------------------------------------------------- 11874 // These must follow all instruction definitions as they use the names 11875 // defined in the instructions definitions.