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 (ThreadLocalSafepoints) { 942 st->print_cr("testb $1, [r15]\t" 943 "# Safepoint: poll for GC\n\t"); 944 st->print_cr("je #slow_safepoint_runtime"); 945 } else if (Assembler::is_polling_page_far()) { 946 st->print_cr("movq rscratch1, #polling_page_address\n\t" 947 "testl rax, [rscratch1]\t" 948 "# Safepoint: poll for GC"); 949 } else { 950 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 951 "# Safepoint: poll for GC"); 952 } 953 } 954 } 955 #endif 956 957 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 958 { 959 Compile* C = ra_->C; 960 if (C->max_vector_size() > 16) { 961 // Clear upper bits of YMM registers when current compiled code uses 962 // wide vectors to avoid AVX <-> SSE transition penalty during call. 963 MacroAssembler _masm(&cbuf); 964 __ vzeroupper(); 965 } 966 967 int framesize = C->frame_size_in_bytes(); 968 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 969 // Remove word for return adr already pushed 970 // and RBP 971 framesize -= 2*wordSize; 972 973 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 974 975 if (framesize) { 976 emit_opcode(cbuf, Assembler::REX_W); 977 if (framesize < 0x80) { 978 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 979 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 980 emit_d8(cbuf, framesize); 981 } else { 982 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 983 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 984 emit_d32(cbuf, framesize); 985 } 986 } 987 988 // popq rbp 989 emit_opcode(cbuf, 0x58 | RBP_enc); 990 991 if (do_polling() && C->is_method_compilation()) { 992 MacroAssembler _masm(&cbuf); 993 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 994 if (ThreadLocalSafepoints) { 995 InternalAddress safepoint_pc(__ pc()); 996 Label dummy_label; 997 Label &code_stub = &cbuf == C->code_buffer() ? C->tls_table()->add_safepoint(safepoint_pc, true) : dummy_label; 998 __ relocate(relocInfo::poll_return_type); 999 __ testb(Address(r15_thread, Thread::yieldpoint_offset()), 2); 1000 __ jcc(Assembler::equal, code_stub); 1001 } else if (Assembler::is_polling_page_far()) { 1002 __ lea(rscratch1, polling_page); 1003 __ relocate(relocInfo::poll_return_type); 1004 __ testl(rax, Address(rscratch1, 0)); 1005 } else { 1006 __ testl(rax, polling_page); 1007 } 1008 } 1009 } 1010 1011 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1012 { 1013 return MachNode::size(ra_); // too many variables; just compute it 1014 // the hard way 1015 } 1016 1017 int MachEpilogNode::reloc() const 1018 { 1019 return 3; // a large enough number 1020 } 1021 1022 const Pipeline* MachEpilogNode::pipeline() const 1023 { 1024 return MachNode::pipeline_class(); 1025 } 1026 1027 int MachEpilogNode::safepoint_offset() const 1028 { 1029 return 0; 1030 } 1031 1032 //============================================================================= 1033 1034 enum RC { 1035 rc_bad, 1036 rc_int, 1037 rc_float, 1038 rc_stack 1039 }; 1040 1041 static enum RC rc_class(OptoReg::Name reg) 1042 { 1043 if( !OptoReg::is_valid(reg) ) return rc_bad; 1044 1045 if (OptoReg::is_stack(reg)) return rc_stack; 1046 1047 VMReg r = OptoReg::as_VMReg(reg); 1048 1049 if (r->is_Register()) return rc_int; 1050 1051 assert(r->is_XMMRegister(), "must be"); 1052 return rc_float; 1053 } 1054 1055 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1056 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1057 int src_hi, int dst_hi, uint ireg, outputStream* st); 1058 1059 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1060 int stack_offset, int reg, uint ireg, outputStream* st); 1061 1062 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1063 int dst_offset, uint ireg, outputStream* st) { 1064 if (cbuf) { 1065 MacroAssembler _masm(cbuf); 1066 switch (ireg) { 1067 case Op_VecS: 1068 __ movq(Address(rsp, -8), rax); 1069 __ movl(rax, Address(rsp, src_offset)); 1070 __ movl(Address(rsp, dst_offset), rax); 1071 __ movq(rax, Address(rsp, -8)); 1072 break; 1073 case Op_VecD: 1074 __ pushq(Address(rsp, src_offset)); 1075 __ popq (Address(rsp, dst_offset)); 1076 break; 1077 case Op_VecX: 1078 __ pushq(Address(rsp, src_offset)); 1079 __ popq (Address(rsp, dst_offset)); 1080 __ pushq(Address(rsp, src_offset+8)); 1081 __ popq (Address(rsp, dst_offset+8)); 1082 break; 1083 case Op_VecY: 1084 __ vmovdqu(Address(rsp, -32), xmm0); 1085 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1086 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1087 __ vmovdqu(xmm0, Address(rsp, -32)); 1088 case Op_VecZ: 1089 __ evmovdqu(Address(rsp, -64), xmm0, 2); 1090 __ evmovdqu(xmm0, Address(rsp, src_offset), 2); 1091 __ evmovdqu(Address(rsp, dst_offset), xmm0, 2); 1092 __ evmovdqu(xmm0, Address(rsp, -64), 2); 1093 break; 1094 default: 1095 ShouldNotReachHere(); 1096 } 1097 #ifndef PRODUCT 1098 } else { 1099 switch (ireg) { 1100 case Op_VecS: 1101 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1102 "movl rax, [rsp + #%d]\n\t" 1103 "movl [rsp + #%d], rax\n\t" 1104 "movq rax, [rsp - #8]", 1105 src_offset, dst_offset); 1106 break; 1107 case Op_VecD: 1108 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1109 "popq [rsp + #%d]", 1110 src_offset, dst_offset); 1111 break; 1112 case Op_VecX: 1113 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1114 "popq [rsp + #%d]\n\t" 1115 "pushq [rsp + #%d]\n\t" 1116 "popq [rsp + #%d]", 1117 src_offset, dst_offset, src_offset+8, dst_offset+8); 1118 break; 1119 case Op_VecY: 1120 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1121 "vmovdqu xmm0, [rsp + #%d]\n\t" 1122 "vmovdqu [rsp + #%d], xmm0\n\t" 1123 "vmovdqu xmm0, [rsp - #32]", 1124 src_offset, dst_offset); 1125 break; 1126 case Op_VecZ: 1127 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1128 "vmovdqu xmm0, [rsp + #%d]\n\t" 1129 "vmovdqu [rsp + #%d], xmm0\n\t" 1130 "vmovdqu xmm0, [rsp - #64]", 1131 src_offset, dst_offset); 1132 break; 1133 default: 1134 ShouldNotReachHere(); 1135 } 1136 #endif 1137 } 1138 } 1139 1140 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1141 PhaseRegAlloc* ra_, 1142 bool do_size, 1143 outputStream* st) const { 1144 assert(cbuf != NULL || st != NULL, "sanity"); 1145 // Get registers to move 1146 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1147 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1148 OptoReg::Name dst_second = ra_->get_reg_second(this); 1149 OptoReg::Name dst_first = ra_->get_reg_first(this); 1150 1151 enum RC src_second_rc = rc_class(src_second); 1152 enum RC src_first_rc = rc_class(src_first); 1153 enum RC dst_second_rc = rc_class(dst_second); 1154 enum RC dst_first_rc = rc_class(dst_first); 1155 1156 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1157 "must move at least 1 register" ); 1158 1159 if (src_first == dst_first && src_second == dst_second) { 1160 // Self copy, no move 1161 return 0; 1162 } 1163 if (bottom_type()->isa_vect() != NULL) { 1164 uint ireg = ideal_reg(); 1165 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1166 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1167 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1168 // mem -> mem 1169 int src_offset = ra_->reg2offset(src_first); 1170 int dst_offset = ra_->reg2offset(dst_first); 1171 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1172 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1173 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1174 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1175 int stack_offset = ra_->reg2offset(dst_first); 1176 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1177 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1178 int stack_offset = ra_->reg2offset(src_first); 1179 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1180 } else { 1181 ShouldNotReachHere(); 1182 } 1183 return 0; 1184 } 1185 if (src_first_rc == rc_stack) { 1186 // mem -> 1187 if (dst_first_rc == rc_stack) { 1188 // mem -> mem 1189 assert(src_second != dst_first, "overlap"); 1190 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1191 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1192 // 64-bit 1193 int src_offset = ra_->reg2offset(src_first); 1194 int dst_offset = ra_->reg2offset(dst_first); 1195 if (cbuf) { 1196 MacroAssembler _masm(cbuf); 1197 __ pushq(Address(rsp, src_offset)); 1198 __ popq (Address(rsp, dst_offset)); 1199 #ifndef PRODUCT 1200 } else { 1201 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1202 "popq [rsp + #%d]", 1203 src_offset, dst_offset); 1204 #endif 1205 } 1206 } else { 1207 // 32-bit 1208 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1209 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1210 // No pushl/popl, so: 1211 int src_offset = ra_->reg2offset(src_first); 1212 int dst_offset = ra_->reg2offset(dst_first); 1213 if (cbuf) { 1214 MacroAssembler _masm(cbuf); 1215 __ movq(Address(rsp, -8), rax); 1216 __ movl(rax, Address(rsp, src_offset)); 1217 __ movl(Address(rsp, dst_offset), rax); 1218 __ movq(rax, Address(rsp, -8)); 1219 #ifndef PRODUCT 1220 } else { 1221 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1222 "movl rax, [rsp + #%d]\n\t" 1223 "movl [rsp + #%d], rax\n\t" 1224 "movq rax, [rsp - #8]", 1225 src_offset, dst_offset); 1226 #endif 1227 } 1228 } 1229 return 0; 1230 } else if (dst_first_rc == rc_int) { 1231 // mem -> gpr 1232 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1233 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1234 // 64-bit 1235 int offset = ra_->reg2offset(src_first); 1236 if (cbuf) { 1237 MacroAssembler _masm(cbuf); 1238 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1239 #ifndef PRODUCT 1240 } else { 1241 st->print("movq %s, [rsp + #%d]\t# spill", 1242 Matcher::regName[dst_first], 1243 offset); 1244 #endif 1245 } 1246 } else { 1247 // 32-bit 1248 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1249 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1250 int offset = ra_->reg2offset(src_first); 1251 if (cbuf) { 1252 MacroAssembler _masm(cbuf); 1253 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1254 #ifndef PRODUCT 1255 } else { 1256 st->print("movl %s, [rsp + #%d]\t# spill", 1257 Matcher::regName[dst_first], 1258 offset); 1259 #endif 1260 } 1261 } 1262 return 0; 1263 } else if (dst_first_rc == rc_float) { 1264 // mem-> xmm 1265 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1266 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1267 // 64-bit 1268 int offset = ra_->reg2offset(src_first); 1269 if (cbuf) { 1270 MacroAssembler _masm(cbuf); 1271 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1272 #ifndef PRODUCT 1273 } else { 1274 st->print("%s %s, [rsp + #%d]\t# spill", 1275 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1276 Matcher::regName[dst_first], 1277 offset); 1278 #endif 1279 } 1280 } else { 1281 // 32-bit 1282 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1283 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1284 int offset = ra_->reg2offset(src_first); 1285 if (cbuf) { 1286 MacroAssembler _masm(cbuf); 1287 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1288 #ifndef PRODUCT 1289 } else { 1290 st->print("movss %s, [rsp + #%d]\t# spill", 1291 Matcher::regName[dst_first], 1292 offset); 1293 #endif 1294 } 1295 } 1296 return 0; 1297 } 1298 } else if (src_first_rc == rc_int) { 1299 // gpr -> 1300 if (dst_first_rc == rc_stack) { 1301 // gpr -> mem 1302 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1303 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1304 // 64-bit 1305 int offset = ra_->reg2offset(dst_first); 1306 if (cbuf) { 1307 MacroAssembler _masm(cbuf); 1308 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1309 #ifndef PRODUCT 1310 } else { 1311 st->print("movq [rsp + #%d], %s\t# spill", 1312 offset, 1313 Matcher::regName[src_first]); 1314 #endif 1315 } 1316 } else { 1317 // 32-bit 1318 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1319 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1320 int offset = ra_->reg2offset(dst_first); 1321 if (cbuf) { 1322 MacroAssembler _masm(cbuf); 1323 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1324 #ifndef PRODUCT 1325 } else { 1326 st->print("movl [rsp + #%d], %s\t# spill", 1327 offset, 1328 Matcher::regName[src_first]); 1329 #endif 1330 } 1331 } 1332 return 0; 1333 } else if (dst_first_rc == rc_int) { 1334 // gpr -> gpr 1335 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1336 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1337 // 64-bit 1338 if (cbuf) { 1339 MacroAssembler _masm(cbuf); 1340 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1341 as_Register(Matcher::_regEncode[src_first])); 1342 #ifndef PRODUCT 1343 } else { 1344 st->print("movq %s, %s\t# spill", 1345 Matcher::regName[dst_first], 1346 Matcher::regName[src_first]); 1347 #endif 1348 } 1349 return 0; 1350 } else { 1351 // 32-bit 1352 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1353 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1354 if (cbuf) { 1355 MacroAssembler _masm(cbuf); 1356 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1357 as_Register(Matcher::_regEncode[src_first])); 1358 #ifndef PRODUCT 1359 } else { 1360 st->print("movl %s, %s\t# spill", 1361 Matcher::regName[dst_first], 1362 Matcher::regName[src_first]); 1363 #endif 1364 } 1365 return 0; 1366 } 1367 } else if (dst_first_rc == rc_float) { 1368 // gpr -> xmm 1369 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1370 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1371 // 64-bit 1372 if (cbuf) { 1373 MacroAssembler _masm(cbuf); 1374 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1375 #ifndef PRODUCT 1376 } else { 1377 st->print("movdq %s, %s\t# spill", 1378 Matcher::regName[dst_first], 1379 Matcher::regName[src_first]); 1380 #endif 1381 } 1382 } else { 1383 // 32-bit 1384 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1385 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1386 if (cbuf) { 1387 MacroAssembler _masm(cbuf); 1388 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1389 #ifndef PRODUCT 1390 } else { 1391 st->print("movdl %s, %s\t# spill", 1392 Matcher::regName[dst_first], 1393 Matcher::regName[src_first]); 1394 #endif 1395 } 1396 } 1397 return 0; 1398 } 1399 } else if (src_first_rc == rc_float) { 1400 // xmm -> 1401 if (dst_first_rc == rc_stack) { 1402 // xmm -> mem 1403 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1404 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1405 // 64-bit 1406 int offset = ra_->reg2offset(dst_first); 1407 if (cbuf) { 1408 MacroAssembler _masm(cbuf); 1409 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1410 #ifndef PRODUCT 1411 } else { 1412 st->print("movsd [rsp + #%d], %s\t# spill", 1413 offset, 1414 Matcher::regName[src_first]); 1415 #endif 1416 } 1417 } else { 1418 // 32-bit 1419 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1420 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1421 int offset = ra_->reg2offset(dst_first); 1422 if (cbuf) { 1423 MacroAssembler _masm(cbuf); 1424 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1425 #ifndef PRODUCT 1426 } else { 1427 st->print("movss [rsp + #%d], %s\t# spill", 1428 offset, 1429 Matcher::regName[src_first]); 1430 #endif 1431 } 1432 } 1433 return 0; 1434 } else if (dst_first_rc == rc_int) { 1435 // xmm -> gpr 1436 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1437 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1438 // 64-bit 1439 if (cbuf) { 1440 MacroAssembler _masm(cbuf); 1441 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1442 #ifndef PRODUCT 1443 } else { 1444 st->print("movdq %s, %s\t# spill", 1445 Matcher::regName[dst_first], 1446 Matcher::regName[src_first]); 1447 #endif 1448 } 1449 } else { 1450 // 32-bit 1451 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1452 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1453 if (cbuf) { 1454 MacroAssembler _masm(cbuf); 1455 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1456 #ifndef PRODUCT 1457 } else { 1458 st->print("movdl %s, %s\t# spill", 1459 Matcher::regName[dst_first], 1460 Matcher::regName[src_first]); 1461 #endif 1462 } 1463 } 1464 return 0; 1465 } else if (dst_first_rc == rc_float) { 1466 // xmm -> xmm 1467 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1468 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1469 // 64-bit 1470 if (cbuf) { 1471 MacroAssembler _masm(cbuf); 1472 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1473 #ifndef PRODUCT 1474 } else { 1475 st->print("%s %s, %s\t# spill", 1476 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1477 Matcher::regName[dst_first], 1478 Matcher::regName[src_first]); 1479 #endif 1480 } 1481 } else { 1482 // 32-bit 1483 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1484 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1485 if (cbuf) { 1486 MacroAssembler _masm(cbuf); 1487 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1488 #ifndef PRODUCT 1489 } else { 1490 st->print("%s %s, %s\t# spill", 1491 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1492 Matcher::regName[dst_first], 1493 Matcher::regName[src_first]); 1494 #endif 1495 } 1496 } 1497 return 0; 1498 } 1499 } 1500 1501 assert(0," foo "); 1502 Unimplemented(); 1503 return 0; 1504 } 1505 1506 #ifndef PRODUCT 1507 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1508 implementation(NULL, ra_, false, st); 1509 } 1510 #endif 1511 1512 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1513 implementation(&cbuf, ra_, false, NULL); 1514 } 1515 1516 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1517 return MachNode::size(ra_); 1518 } 1519 1520 //============================================================================= 1521 #ifndef PRODUCT 1522 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1523 { 1524 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1525 int reg = ra_->get_reg_first(this); 1526 st->print("leaq %s, [rsp + #%d]\t# box lock", 1527 Matcher::regName[reg], offset); 1528 } 1529 #endif 1530 1531 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1532 { 1533 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1534 int reg = ra_->get_encode(this); 1535 if (offset >= 0x80) { 1536 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1537 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1538 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1539 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1540 emit_d32(cbuf, offset); 1541 } else { 1542 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1543 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1544 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1545 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1546 emit_d8(cbuf, offset); 1547 } 1548 } 1549 1550 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1551 { 1552 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1553 return (offset < 0x80) ? 5 : 8; // REX 1554 } 1555 1556 //============================================================================= 1557 #ifndef PRODUCT 1558 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1559 { 1560 if (UseCompressedClassPointers) { 1561 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1562 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1563 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1564 } else { 1565 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1566 "# Inline cache check"); 1567 } 1568 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1569 st->print_cr("\tnop\t# nops to align entry point"); 1570 } 1571 #endif 1572 1573 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1574 { 1575 MacroAssembler masm(&cbuf); 1576 uint insts_size = cbuf.insts_size(); 1577 if (UseCompressedClassPointers) { 1578 masm.load_klass(rscratch1, j_rarg0); 1579 masm.cmpptr(rax, rscratch1); 1580 } else { 1581 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1582 } 1583 1584 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1585 1586 /* WARNING these NOPs are critical so that verified entry point is properly 1587 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1588 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1589 if (OptoBreakpoint) { 1590 // Leave space for int3 1591 nops_cnt -= 1; 1592 } 1593 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1594 if (nops_cnt > 0) 1595 masm.nop(nops_cnt); 1596 } 1597 1598 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1599 { 1600 return MachNode::size(ra_); // too many variables; just compute it 1601 // the hard way 1602 } 1603 1604 1605 //============================================================================= 1606 1607 int Matcher::regnum_to_fpu_offset(int regnum) 1608 { 1609 return regnum - 32; // The FP registers are in the second chunk 1610 } 1611 1612 // This is UltraSparc specific, true just means we have fast l2f conversion 1613 const bool Matcher::convL2FSupported(void) { 1614 return true; 1615 } 1616 1617 // Is this branch offset short enough that a short branch can be used? 1618 // 1619 // NOTE: If the platform does not provide any short branch variants, then 1620 // this method should return false for offset 0. 1621 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1622 // The passed offset is relative to address of the branch. 1623 // On 86 a branch displacement is calculated relative to address 1624 // of a next instruction. 1625 offset -= br_size; 1626 1627 // the short version of jmpConUCF2 contains multiple branches, 1628 // making the reach slightly less 1629 if (rule == jmpConUCF2_rule) 1630 return (-126 <= offset && offset <= 125); 1631 return (-128 <= offset && offset <= 127); 1632 } 1633 1634 const bool Matcher::isSimpleConstant64(jlong value) { 1635 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1636 //return value == (int) value; // Cf. storeImmL and immL32. 1637 1638 // Probably always true, even if a temp register is required. 1639 return true; 1640 } 1641 1642 // The ecx parameter to rep stosq for the ClearArray node is in words. 1643 const bool Matcher::init_array_count_is_in_bytes = false; 1644 1645 // Threshold size for cleararray. 1646 const int Matcher::init_array_short_size = 8 * BytesPerLong; 1647 1648 // No additional cost for CMOVL. 1649 const int Matcher::long_cmove_cost() { return 0; } 1650 1651 // No CMOVF/CMOVD with SSE2 1652 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1653 1654 // Does the CPU require late expand (see block.cpp for description of late expand)? 1655 const bool Matcher::require_postalloc_expand = false; 1656 1657 // Should the Matcher clone shifts on addressing modes, expecting them 1658 // to be subsumed into complex addressing expressions or compute them 1659 // into registers? True for Intel but false for most RISCs 1660 const bool Matcher::clone_shift_expressions = true; 1661 1662 // Do we need to mask the count passed to shift instructions or does 1663 // the cpu only look at the lower 5/6 bits anyway? 1664 const bool Matcher::need_masked_shift_count = false; 1665 1666 bool Matcher::narrow_oop_use_complex_address() { 1667 assert(UseCompressedOops, "only for compressed oops code"); 1668 return (LogMinObjAlignmentInBytes <= 3); 1669 } 1670 1671 bool Matcher::narrow_klass_use_complex_address() { 1672 assert(UseCompressedClassPointers, "only for compressed klass code"); 1673 return (LogKlassAlignmentInBytes <= 3); 1674 } 1675 1676 // Is it better to copy float constants, or load them directly from 1677 // memory? Intel can load a float constant from a direct address, 1678 // requiring no extra registers. Most RISCs will have to materialize 1679 // an address into a register first, so they would do better to copy 1680 // the constant from stack. 1681 const bool Matcher::rematerialize_float_constants = true; // XXX 1682 1683 // If CPU can load and store mis-aligned doubles directly then no 1684 // fixup is needed. Else we split the double into 2 integer pieces 1685 // and move it piece-by-piece. Only happens when passing doubles into 1686 // C code as the Java calling convention forces doubles to be aligned. 1687 const bool Matcher::misaligned_doubles_ok = true; 1688 1689 // No-op on amd64 1690 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1691 1692 // Advertise here if the CPU requires explicit rounding operations to 1693 // implement the UseStrictFP mode. 1694 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1695 1696 // Are floats conerted to double when stored to stack during deoptimization? 1697 // On x64 it is stored without convertion so we can use normal access. 1698 bool Matcher::float_in_double() { return false; } 1699 1700 // Do ints take an entire long register or just half? 1701 const bool Matcher::int_in_long = true; 1702 1703 // Return whether or not this register is ever used as an argument. 1704 // This function is used on startup to build the trampoline stubs in 1705 // generateOptoStub. Registers not mentioned will be killed by the VM 1706 // call in the trampoline, and arguments in those registers not be 1707 // available to the callee. 1708 bool Matcher::can_be_java_arg(int reg) 1709 { 1710 return 1711 reg == RDI_num || reg == RDI_H_num || 1712 reg == RSI_num || reg == RSI_H_num || 1713 reg == RDX_num || reg == RDX_H_num || 1714 reg == RCX_num || reg == RCX_H_num || 1715 reg == R8_num || reg == R8_H_num || 1716 reg == R9_num || reg == R9_H_num || 1717 reg == R12_num || reg == R12_H_num || 1718 reg == XMM0_num || reg == XMM0b_num || 1719 reg == XMM1_num || reg == XMM1b_num || 1720 reg == XMM2_num || reg == XMM2b_num || 1721 reg == XMM3_num || reg == XMM3b_num || 1722 reg == XMM4_num || reg == XMM4b_num || 1723 reg == XMM5_num || reg == XMM5b_num || 1724 reg == XMM6_num || reg == XMM6b_num || 1725 reg == XMM7_num || reg == XMM7b_num; 1726 } 1727 1728 bool Matcher::is_spillable_arg(int reg) 1729 { 1730 return can_be_java_arg(reg); 1731 } 1732 1733 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1734 // In 64 bit mode a code which use multiply when 1735 // devisor is constant is faster than hardware 1736 // DIV instruction (it uses MulHiL). 1737 return false; 1738 } 1739 1740 // Register for DIVI projection of divmodI 1741 RegMask Matcher::divI_proj_mask() { 1742 return INT_RAX_REG_mask(); 1743 } 1744 1745 // Register for MODI projection of divmodI 1746 RegMask Matcher::modI_proj_mask() { 1747 return INT_RDX_REG_mask(); 1748 } 1749 1750 // Register for DIVL projection of divmodL 1751 RegMask Matcher::divL_proj_mask() { 1752 return LONG_RAX_REG_mask(); 1753 } 1754 1755 // Register for MODL projection of divmodL 1756 RegMask Matcher::modL_proj_mask() { 1757 return LONG_RDX_REG_mask(); 1758 } 1759 1760 // Register for saving SP into on method handle invokes. Not used on x86_64. 1761 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1762 return NO_REG_mask(); 1763 } 1764 1765 %} 1766 1767 //----------ENCODING BLOCK----------------------------------------------------- 1768 // This block specifies the encoding classes used by the compiler to 1769 // output byte streams. Encoding classes are parameterized macros 1770 // used by Machine Instruction Nodes in order to generate the bit 1771 // encoding of the instruction. Operands specify their base encoding 1772 // interface with the interface keyword. There are currently 1773 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1774 // COND_INTER. REG_INTER causes an operand to generate a function 1775 // which returns its register number when queried. CONST_INTER causes 1776 // an operand to generate a function which returns the value of the 1777 // constant when queried. MEMORY_INTER causes an operand to generate 1778 // four functions which return the Base Register, the Index Register, 1779 // the Scale Value, and the Offset Value of the operand when queried. 1780 // COND_INTER causes an operand to generate six functions which return 1781 // the encoding code (ie - encoding bits for the instruction) 1782 // associated with each basic boolean condition for a conditional 1783 // instruction. 1784 // 1785 // Instructions specify two basic values for encoding. Again, a 1786 // function is available to check if the constant displacement is an 1787 // oop. They use the ins_encode keyword to specify their encoding 1788 // classes (which must be a sequence of enc_class names, and their 1789 // parameters, specified in the encoding block), and they use the 1790 // opcode keyword to specify, in order, their primary, secondary, and 1791 // tertiary opcode. Only the opcode sections which a particular 1792 // instruction needs for encoding need to be specified. 1793 encode %{ 1794 // Build emit functions for each basic byte or larger field in the 1795 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1796 // from C++ code in the enc_class source block. Emit functions will 1797 // live in the main source block for now. In future, we can 1798 // generalize this by adding a syntax that specifies the sizes of 1799 // fields in an order, so that the adlc can build the emit functions 1800 // automagically 1801 1802 // Emit primary opcode 1803 enc_class OpcP 1804 %{ 1805 emit_opcode(cbuf, $primary); 1806 %} 1807 1808 // Emit secondary opcode 1809 enc_class OpcS 1810 %{ 1811 emit_opcode(cbuf, $secondary); 1812 %} 1813 1814 // Emit tertiary opcode 1815 enc_class OpcT 1816 %{ 1817 emit_opcode(cbuf, $tertiary); 1818 %} 1819 1820 // Emit opcode directly 1821 enc_class Opcode(immI d8) 1822 %{ 1823 emit_opcode(cbuf, $d8$$constant); 1824 %} 1825 1826 // Emit size prefix 1827 enc_class SizePrefix 1828 %{ 1829 emit_opcode(cbuf, 0x66); 1830 %} 1831 1832 enc_class reg(rRegI reg) 1833 %{ 1834 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1835 %} 1836 1837 enc_class reg_reg(rRegI dst, rRegI src) 1838 %{ 1839 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1840 %} 1841 1842 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1843 %{ 1844 emit_opcode(cbuf, $opcode$$constant); 1845 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1846 %} 1847 1848 enc_class cdql_enc(no_rax_rdx_RegI div) 1849 %{ 1850 // Full implementation of Java idiv and irem; checks for 1851 // special case as described in JVM spec., p.243 & p.271. 1852 // 1853 // normal case special case 1854 // 1855 // input : rax: dividend min_int 1856 // reg: divisor -1 1857 // 1858 // output: rax: quotient (= rax idiv reg) min_int 1859 // rdx: remainder (= rax irem reg) 0 1860 // 1861 // Code sequnce: 1862 // 1863 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1864 // 5: 75 07/08 jne e <normal> 1865 // 7: 33 d2 xor %edx,%edx 1866 // [div >= 8 -> offset + 1] 1867 // [REX_B] 1868 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1869 // c: 74 03/04 je 11 <done> 1870 // 000000000000000e <normal>: 1871 // e: 99 cltd 1872 // [div >= 8 -> offset + 1] 1873 // [REX_B] 1874 // f: f7 f9 idiv $div 1875 // 0000000000000011 <done>: 1876 1877 // cmp $0x80000000,%eax 1878 emit_opcode(cbuf, 0x3d); 1879 emit_d8(cbuf, 0x00); 1880 emit_d8(cbuf, 0x00); 1881 emit_d8(cbuf, 0x00); 1882 emit_d8(cbuf, 0x80); 1883 1884 // jne e <normal> 1885 emit_opcode(cbuf, 0x75); 1886 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1887 1888 // xor %edx,%edx 1889 emit_opcode(cbuf, 0x33); 1890 emit_d8(cbuf, 0xD2); 1891 1892 // cmp $0xffffffffffffffff,%ecx 1893 if ($div$$reg >= 8) { 1894 emit_opcode(cbuf, Assembler::REX_B); 1895 } 1896 emit_opcode(cbuf, 0x83); 1897 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1898 emit_d8(cbuf, 0xFF); 1899 1900 // je 11 <done> 1901 emit_opcode(cbuf, 0x74); 1902 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1903 1904 // <normal> 1905 // cltd 1906 emit_opcode(cbuf, 0x99); 1907 1908 // idivl (note: must be emitted by the user of this rule) 1909 // <done> 1910 %} 1911 1912 enc_class cdqq_enc(no_rax_rdx_RegL div) 1913 %{ 1914 // Full implementation of Java ldiv and lrem; checks for 1915 // special case as described in JVM spec., p.243 & p.271. 1916 // 1917 // normal case special case 1918 // 1919 // input : rax: dividend min_long 1920 // reg: divisor -1 1921 // 1922 // output: rax: quotient (= rax idiv reg) min_long 1923 // rdx: remainder (= rax irem reg) 0 1924 // 1925 // Code sequnce: 1926 // 1927 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1928 // 7: 00 00 80 1929 // a: 48 39 d0 cmp %rdx,%rax 1930 // d: 75 08 jne 17 <normal> 1931 // f: 33 d2 xor %edx,%edx 1932 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1933 // 15: 74 05 je 1c <done> 1934 // 0000000000000017 <normal>: 1935 // 17: 48 99 cqto 1936 // 19: 48 f7 f9 idiv $div 1937 // 000000000000001c <done>: 1938 1939 // mov $0x8000000000000000,%rdx 1940 emit_opcode(cbuf, Assembler::REX_W); 1941 emit_opcode(cbuf, 0xBA); 1942 emit_d8(cbuf, 0x00); 1943 emit_d8(cbuf, 0x00); 1944 emit_d8(cbuf, 0x00); 1945 emit_d8(cbuf, 0x00); 1946 emit_d8(cbuf, 0x00); 1947 emit_d8(cbuf, 0x00); 1948 emit_d8(cbuf, 0x00); 1949 emit_d8(cbuf, 0x80); 1950 1951 // cmp %rdx,%rax 1952 emit_opcode(cbuf, Assembler::REX_W); 1953 emit_opcode(cbuf, 0x39); 1954 emit_d8(cbuf, 0xD0); 1955 1956 // jne 17 <normal> 1957 emit_opcode(cbuf, 0x75); 1958 emit_d8(cbuf, 0x08); 1959 1960 // xor %edx,%edx 1961 emit_opcode(cbuf, 0x33); 1962 emit_d8(cbuf, 0xD2); 1963 1964 // cmp $0xffffffffffffffff,$div 1965 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1966 emit_opcode(cbuf, 0x83); 1967 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1968 emit_d8(cbuf, 0xFF); 1969 1970 // je 1e <done> 1971 emit_opcode(cbuf, 0x74); 1972 emit_d8(cbuf, 0x05); 1973 1974 // <normal> 1975 // cqto 1976 emit_opcode(cbuf, Assembler::REX_W); 1977 emit_opcode(cbuf, 0x99); 1978 1979 // idivq (note: must be emitted by the user of this rule) 1980 // <done> 1981 %} 1982 1983 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1984 enc_class OpcSE(immI imm) 1985 %{ 1986 // Emit primary opcode and set sign-extend bit 1987 // Check for 8-bit immediate, and set sign extend bit in opcode 1988 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1989 emit_opcode(cbuf, $primary | 0x02); 1990 } else { 1991 // 32-bit immediate 1992 emit_opcode(cbuf, $primary); 1993 } 1994 %} 1995 1996 enc_class OpcSErm(rRegI dst, immI imm) 1997 %{ 1998 // OpcSEr/m 1999 int dstenc = $dst$$reg; 2000 if (dstenc >= 8) { 2001 emit_opcode(cbuf, Assembler::REX_B); 2002 dstenc -= 8; 2003 } 2004 // Emit primary opcode and set sign-extend bit 2005 // Check for 8-bit immediate, and set sign extend bit in opcode 2006 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2007 emit_opcode(cbuf, $primary | 0x02); 2008 } else { 2009 // 32-bit immediate 2010 emit_opcode(cbuf, $primary); 2011 } 2012 // Emit r/m byte with secondary opcode, after primary opcode. 2013 emit_rm(cbuf, 0x3, $secondary, dstenc); 2014 %} 2015 2016 enc_class OpcSErm_wide(rRegL dst, immI imm) 2017 %{ 2018 // OpcSEr/m 2019 int dstenc = $dst$$reg; 2020 if (dstenc < 8) { 2021 emit_opcode(cbuf, Assembler::REX_W); 2022 } else { 2023 emit_opcode(cbuf, Assembler::REX_WB); 2024 dstenc -= 8; 2025 } 2026 // Emit primary opcode and set sign-extend bit 2027 // Check for 8-bit immediate, and set sign extend bit in opcode 2028 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2029 emit_opcode(cbuf, $primary | 0x02); 2030 } else { 2031 // 32-bit immediate 2032 emit_opcode(cbuf, $primary); 2033 } 2034 // Emit r/m byte with secondary opcode, after primary opcode. 2035 emit_rm(cbuf, 0x3, $secondary, dstenc); 2036 %} 2037 2038 enc_class Con8or32(immI imm) 2039 %{ 2040 // Check for 8-bit immediate, and set sign extend bit in opcode 2041 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2042 $$$emit8$imm$$constant; 2043 } else { 2044 // 32-bit immediate 2045 $$$emit32$imm$$constant; 2046 } 2047 %} 2048 2049 enc_class opc2_reg(rRegI dst) 2050 %{ 2051 // BSWAP 2052 emit_cc(cbuf, $secondary, $dst$$reg); 2053 %} 2054 2055 enc_class opc3_reg(rRegI dst) 2056 %{ 2057 // BSWAP 2058 emit_cc(cbuf, $tertiary, $dst$$reg); 2059 %} 2060 2061 enc_class reg_opc(rRegI div) 2062 %{ 2063 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2064 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2065 %} 2066 2067 enc_class enc_cmov(cmpOp cop) 2068 %{ 2069 // CMOV 2070 $$$emit8$primary; 2071 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2072 %} 2073 2074 enc_class enc_PartialSubtypeCheck() 2075 %{ 2076 Register Rrdi = as_Register(RDI_enc); // result register 2077 Register Rrax = as_Register(RAX_enc); // super class 2078 Register Rrcx = as_Register(RCX_enc); // killed 2079 Register Rrsi = as_Register(RSI_enc); // sub class 2080 Label miss; 2081 const bool set_cond_codes = true; 2082 2083 MacroAssembler _masm(&cbuf); 2084 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2085 NULL, &miss, 2086 /*set_cond_codes:*/ true); 2087 if ($primary) { 2088 __ xorptr(Rrdi, Rrdi); 2089 } 2090 __ bind(miss); 2091 %} 2092 2093 enc_class clear_avx %{ 2094 debug_only(int off0 = cbuf.insts_size()); 2095 if (ra_->C->max_vector_size() > 16) { 2096 // Clear upper bits of YMM registers when current compiled code uses 2097 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2098 MacroAssembler _masm(&cbuf); 2099 __ vzeroupper(); 2100 } 2101 debug_only(int off1 = cbuf.insts_size()); 2102 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2103 %} 2104 2105 enc_class Java_To_Runtime(method meth) %{ 2106 // No relocation needed 2107 MacroAssembler _masm(&cbuf); 2108 __ mov64(r10, (int64_t) $meth$$method); 2109 __ call(r10); 2110 %} 2111 2112 enc_class Java_To_Interpreter(method meth) 2113 %{ 2114 // CALL Java_To_Interpreter 2115 // This is the instruction starting address for relocation info. 2116 cbuf.set_insts_mark(); 2117 $$$emit8$primary; 2118 // CALL directly to the runtime 2119 emit_d32_reloc(cbuf, 2120 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2121 runtime_call_Relocation::spec(), 2122 RELOC_DISP32); 2123 %} 2124 2125 enc_class Java_Static_Call(method meth) 2126 %{ 2127 // JAVA STATIC CALL 2128 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2129 // determine who we intended to call. 2130 cbuf.set_insts_mark(); 2131 $$$emit8$primary; 2132 2133 if (!_method) { 2134 emit_d32_reloc(cbuf, 2135 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2136 runtime_call_Relocation::spec(), 2137 RELOC_DISP32); 2138 } else if (_optimized_virtual) { 2139 emit_d32_reloc(cbuf, 2140 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2141 opt_virtual_call_Relocation::spec(), 2142 RELOC_DISP32); 2143 } else { 2144 emit_d32_reloc(cbuf, 2145 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2146 static_call_Relocation::spec(), 2147 RELOC_DISP32); 2148 } 2149 if (_method) { 2150 // Emit stub for static call. 2151 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 2152 if (stub == NULL) { 2153 ciEnv::current()->record_failure("CodeCache is full"); 2154 return; 2155 } 2156 } 2157 %} 2158 2159 enc_class Java_Dynamic_Call(method meth) %{ 2160 MacroAssembler _masm(&cbuf); 2161 __ ic_call((address)$meth$$method); 2162 %} 2163 2164 enc_class Java_Compiled_Call(method meth) 2165 %{ 2166 // JAVA COMPILED CALL 2167 int disp = in_bytes(Method:: from_compiled_offset()); 2168 2169 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2170 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2171 2172 // callq *disp(%rax) 2173 cbuf.set_insts_mark(); 2174 $$$emit8$primary; 2175 if (disp < 0x80) { 2176 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2177 emit_d8(cbuf, disp); // Displacement 2178 } else { 2179 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2180 emit_d32(cbuf, disp); // Displacement 2181 } 2182 %} 2183 2184 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2185 %{ 2186 // SAL, SAR, SHR 2187 int dstenc = $dst$$reg; 2188 if (dstenc >= 8) { 2189 emit_opcode(cbuf, Assembler::REX_B); 2190 dstenc -= 8; 2191 } 2192 $$$emit8$primary; 2193 emit_rm(cbuf, 0x3, $secondary, dstenc); 2194 $$$emit8$shift$$constant; 2195 %} 2196 2197 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2198 %{ 2199 // SAL, SAR, SHR 2200 int dstenc = $dst$$reg; 2201 if (dstenc < 8) { 2202 emit_opcode(cbuf, Assembler::REX_W); 2203 } else { 2204 emit_opcode(cbuf, Assembler::REX_WB); 2205 dstenc -= 8; 2206 } 2207 $$$emit8$primary; 2208 emit_rm(cbuf, 0x3, $secondary, dstenc); 2209 $$$emit8$shift$$constant; 2210 %} 2211 2212 enc_class load_immI(rRegI dst, immI src) 2213 %{ 2214 int dstenc = $dst$$reg; 2215 if (dstenc >= 8) { 2216 emit_opcode(cbuf, Assembler::REX_B); 2217 dstenc -= 8; 2218 } 2219 emit_opcode(cbuf, 0xB8 | dstenc); 2220 $$$emit32$src$$constant; 2221 %} 2222 2223 enc_class load_immL(rRegL dst, immL src) 2224 %{ 2225 int dstenc = $dst$$reg; 2226 if (dstenc < 8) { 2227 emit_opcode(cbuf, Assembler::REX_W); 2228 } else { 2229 emit_opcode(cbuf, Assembler::REX_WB); 2230 dstenc -= 8; 2231 } 2232 emit_opcode(cbuf, 0xB8 | dstenc); 2233 emit_d64(cbuf, $src$$constant); 2234 %} 2235 2236 enc_class load_immUL32(rRegL dst, immUL32 src) 2237 %{ 2238 // same as load_immI, but this time we care about zeroes in the high word 2239 int dstenc = $dst$$reg; 2240 if (dstenc >= 8) { 2241 emit_opcode(cbuf, Assembler::REX_B); 2242 dstenc -= 8; 2243 } 2244 emit_opcode(cbuf, 0xB8 | dstenc); 2245 $$$emit32$src$$constant; 2246 %} 2247 2248 enc_class load_immL32(rRegL dst, immL32 src) 2249 %{ 2250 int dstenc = $dst$$reg; 2251 if (dstenc < 8) { 2252 emit_opcode(cbuf, Assembler::REX_W); 2253 } else { 2254 emit_opcode(cbuf, Assembler::REX_WB); 2255 dstenc -= 8; 2256 } 2257 emit_opcode(cbuf, 0xC7); 2258 emit_rm(cbuf, 0x03, 0x00, dstenc); 2259 $$$emit32$src$$constant; 2260 %} 2261 2262 enc_class load_immP31(rRegP dst, immP32 src) 2263 %{ 2264 // same as load_immI, but this time we care about zeroes in the high word 2265 int dstenc = $dst$$reg; 2266 if (dstenc >= 8) { 2267 emit_opcode(cbuf, Assembler::REX_B); 2268 dstenc -= 8; 2269 } 2270 emit_opcode(cbuf, 0xB8 | dstenc); 2271 $$$emit32$src$$constant; 2272 %} 2273 2274 enc_class load_immP(rRegP dst, immP src) 2275 %{ 2276 int dstenc = $dst$$reg; 2277 if (dstenc < 8) { 2278 emit_opcode(cbuf, Assembler::REX_W); 2279 } else { 2280 emit_opcode(cbuf, Assembler::REX_WB); 2281 dstenc -= 8; 2282 } 2283 emit_opcode(cbuf, 0xB8 | dstenc); 2284 // This next line should be generated from ADLC 2285 if ($src->constant_reloc() != relocInfo::none) { 2286 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2287 } else { 2288 emit_d64(cbuf, $src$$constant); 2289 } 2290 %} 2291 2292 enc_class Con32(immI src) 2293 %{ 2294 // Output immediate 2295 $$$emit32$src$$constant; 2296 %} 2297 2298 enc_class Con32F_as_bits(immF src) 2299 %{ 2300 // Output Float immediate bits 2301 jfloat jf = $src$$constant; 2302 jint jf_as_bits = jint_cast(jf); 2303 emit_d32(cbuf, jf_as_bits); 2304 %} 2305 2306 enc_class Con16(immI src) 2307 %{ 2308 // Output immediate 2309 $$$emit16$src$$constant; 2310 %} 2311 2312 // How is this different from Con32??? XXX 2313 enc_class Con_d32(immI src) 2314 %{ 2315 emit_d32(cbuf,$src$$constant); 2316 %} 2317 2318 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2319 // Output immediate memory reference 2320 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2321 emit_d32(cbuf, 0x00); 2322 %} 2323 2324 enc_class lock_prefix() 2325 %{ 2326 if (os::is_MP()) { 2327 emit_opcode(cbuf, 0xF0); // lock 2328 } 2329 %} 2330 2331 enc_class REX_mem(memory mem) 2332 %{ 2333 if ($mem$$base >= 8) { 2334 if ($mem$$index < 8) { 2335 emit_opcode(cbuf, Assembler::REX_B); 2336 } else { 2337 emit_opcode(cbuf, Assembler::REX_XB); 2338 } 2339 } else { 2340 if ($mem$$index >= 8) { 2341 emit_opcode(cbuf, Assembler::REX_X); 2342 } 2343 } 2344 %} 2345 2346 enc_class REX_mem_wide(memory mem) 2347 %{ 2348 if ($mem$$base >= 8) { 2349 if ($mem$$index < 8) { 2350 emit_opcode(cbuf, Assembler::REX_WB); 2351 } else { 2352 emit_opcode(cbuf, Assembler::REX_WXB); 2353 } 2354 } else { 2355 if ($mem$$index < 8) { 2356 emit_opcode(cbuf, Assembler::REX_W); 2357 } else { 2358 emit_opcode(cbuf, Assembler::REX_WX); 2359 } 2360 } 2361 %} 2362 2363 // for byte regs 2364 enc_class REX_breg(rRegI reg) 2365 %{ 2366 if ($reg$$reg >= 4) { 2367 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2368 } 2369 %} 2370 2371 // for byte regs 2372 enc_class REX_reg_breg(rRegI dst, rRegI src) 2373 %{ 2374 if ($dst$$reg < 8) { 2375 if ($src$$reg >= 4) { 2376 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2377 } 2378 } else { 2379 if ($src$$reg < 8) { 2380 emit_opcode(cbuf, Assembler::REX_R); 2381 } else { 2382 emit_opcode(cbuf, Assembler::REX_RB); 2383 } 2384 } 2385 %} 2386 2387 // for byte regs 2388 enc_class REX_breg_mem(rRegI reg, memory mem) 2389 %{ 2390 if ($reg$$reg < 8) { 2391 if ($mem$$base < 8) { 2392 if ($mem$$index >= 8) { 2393 emit_opcode(cbuf, Assembler::REX_X); 2394 } else if ($reg$$reg >= 4) { 2395 emit_opcode(cbuf, Assembler::REX); 2396 } 2397 } else { 2398 if ($mem$$index < 8) { 2399 emit_opcode(cbuf, Assembler::REX_B); 2400 } else { 2401 emit_opcode(cbuf, Assembler::REX_XB); 2402 } 2403 } 2404 } else { 2405 if ($mem$$base < 8) { 2406 if ($mem$$index < 8) { 2407 emit_opcode(cbuf, Assembler::REX_R); 2408 } else { 2409 emit_opcode(cbuf, Assembler::REX_RX); 2410 } 2411 } else { 2412 if ($mem$$index < 8) { 2413 emit_opcode(cbuf, Assembler::REX_RB); 2414 } else { 2415 emit_opcode(cbuf, Assembler::REX_RXB); 2416 } 2417 } 2418 } 2419 %} 2420 2421 enc_class REX_reg(rRegI reg) 2422 %{ 2423 if ($reg$$reg >= 8) { 2424 emit_opcode(cbuf, Assembler::REX_B); 2425 } 2426 %} 2427 2428 enc_class REX_reg_wide(rRegI reg) 2429 %{ 2430 if ($reg$$reg < 8) { 2431 emit_opcode(cbuf, Assembler::REX_W); 2432 } else { 2433 emit_opcode(cbuf, Assembler::REX_WB); 2434 } 2435 %} 2436 2437 enc_class REX_reg_reg(rRegI dst, rRegI src) 2438 %{ 2439 if ($dst$$reg < 8) { 2440 if ($src$$reg >= 8) { 2441 emit_opcode(cbuf, Assembler::REX_B); 2442 } 2443 } else { 2444 if ($src$$reg < 8) { 2445 emit_opcode(cbuf, Assembler::REX_R); 2446 } else { 2447 emit_opcode(cbuf, Assembler::REX_RB); 2448 } 2449 } 2450 %} 2451 2452 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2453 %{ 2454 if ($dst$$reg < 8) { 2455 if ($src$$reg < 8) { 2456 emit_opcode(cbuf, Assembler::REX_W); 2457 } else { 2458 emit_opcode(cbuf, Assembler::REX_WB); 2459 } 2460 } else { 2461 if ($src$$reg < 8) { 2462 emit_opcode(cbuf, Assembler::REX_WR); 2463 } else { 2464 emit_opcode(cbuf, Assembler::REX_WRB); 2465 } 2466 } 2467 %} 2468 2469 enc_class REX_reg_mem(rRegI reg, memory mem) 2470 %{ 2471 if ($reg$$reg < 8) { 2472 if ($mem$$base < 8) { 2473 if ($mem$$index >= 8) { 2474 emit_opcode(cbuf, Assembler::REX_X); 2475 } 2476 } else { 2477 if ($mem$$index < 8) { 2478 emit_opcode(cbuf, Assembler::REX_B); 2479 } else { 2480 emit_opcode(cbuf, Assembler::REX_XB); 2481 } 2482 } 2483 } else { 2484 if ($mem$$base < 8) { 2485 if ($mem$$index < 8) { 2486 emit_opcode(cbuf, Assembler::REX_R); 2487 } else { 2488 emit_opcode(cbuf, Assembler::REX_RX); 2489 } 2490 } else { 2491 if ($mem$$index < 8) { 2492 emit_opcode(cbuf, Assembler::REX_RB); 2493 } else { 2494 emit_opcode(cbuf, Assembler::REX_RXB); 2495 } 2496 } 2497 } 2498 %} 2499 2500 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2501 %{ 2502 if ($reg$$reg < 8) { 2503 if ($mem$$base < 8) { 2504 if ($mem$$index < 8) { 2505 emit_opcode(cbuf, Assembler::REX_W); 2506 } else { 2507 emit_opcode(cbuf, Assembler::REX_WX); 2508 } 2509 } else { 2510 if ($mem$$index < 8) { 2511 emit_opcode(cbuf, Assembler::REX_WB); 2512 } else { 2513 emit_opcode(cbuf, Assembler::REX_WXB); 2514 } 2515 } 2516 } else { 2517 if ($mem$$base < 8) { 2518 if ($mem$$index < 8) { 2519 emit_opcode(cbuf, Assembler::REX_WR); 2520 } else { 2521 emit_opcode(cbuf, Assembler::REX_WRX); 2522 } 2523 } else { 2524 if ($mem$$index < 8) { 2525 emit_opcode(cbuf, Assembler::REX_WRB); 2526 } else { 2527 emit_opcode(cbuf, Assembler::REX_WRXB); 2528 } 2529 } 2530 } 2531 %} 2532 2533 enc_class reg_mem(rRegI ereg, memory mem) 2534 %{ 2535 // High registers handle in encode_RegMem 2536 int reg = $ereg$$reg; 2537 int base = $mem$$base; 2538 int index = $mem$$index; 2539 int scale = $mem$$scale; 2540 int disp = $mem$$disp; 2541 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2542 2543 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2544 %} 2545 2546 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2547 %{ 2548 int rm_byte_opcode = $rm_opcode$$constant; 2549 2550 // High registers handle in encode_RegMem 2551 int base = $mem$$base; 2552 int index = $mem$$index; 2553 int scale = $mem$$scale; 2554 int displace = $mem$$disp; 2555 2556 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2557 // working with static 2558 // globals 2559 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2560 disp_reloc); 2561 %} 2562 2563 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2564 %{ 2565 int reg_encoding = $dst$$reg; 2566 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2567 int index = 0x04; // 0x04 indicates no index 2568 int scale = 0x00; // 0x00 indicates no scale 2569 int displace = $src1$$constant; // 0x00 indicates no displacement 2570 relocInfo::relocType disp_reloc = relocInfo::none; 2571 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2572 disp_reloc); 2573 %} 2574 2575 enc_class neg_reg(rRegI dst) 2576 %{ 2577 int dstenc = $dst$$reg; 2578 if (dstenc >= 8) { 2579 emit_opcode(cbuf, Assembler::REX_B); 2580 dstenc -= 8; 2581 } 2582 // NEG $dst 2583 emit_opcode(cbuf, 0xF7); 2584 emit_rm(cbuf, 0x3, 0x03, dstenc); 2585 %} 2586 2587 enc_class neg_reg_wide(rRegI dst) 2588 %{ 2589 int dstenc = $dst$$reg; 2590 if (dstenc < 8) { 2591 emit_opcode(cbuf, Assembler::REX_W); 2592 } else { 2593 emit_opcode(cbuf, Assembler::REX_WB); 2594 dstenc -= 8; 2595 } 2596 // NEG $dst 2597 emit_opcode(cbuf, 0xF7); 2598 emit_rm(cbuf, 0x3, 0x03, dstenc); 2599 %} 2600 2601 enc_class setLT_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 // SETLT $dst 2611 emit_opcode(cbuf, 0x0F); 2612 emit_opcode(cbuf, 0x9C); 2613 emit_rm(cbuf, 0x3, 0x0, dstenc); 2614 %} 2615 2616 enc_class setNZ_reg(rRegI dst) 2617 %{ 2618 int dstenc = $dst$$reg; 2619 if (dstenc >= 8) { 2620 emit_opcode(cbuf, Assembler::REX_B); 2621 dstenc -= 8; 2622 } else if (dstenc >= 4) { 2623 emit_opcode(cbuf, Assembler::REX); 2624 } 2625 // SETNZ $dst 2626 emit_opcode(cbuf, 0x0F); 2627 emit_opcode(cbuf, 0x95); 2628 emit_rm(cbuf, 0x3, 0x0, dstenc); 2629 %} 2630 2631 2632 // Compare the lonogs and set -1, 0, or 1 into dst 2633 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2634 %{ 2635 int src1enc = $src1$$reg; 2636 int src2enc = $src2$$reg; 2637 int dstenc = $dst$$reg; 2638 2639 // cmpq $src1, $src2 2640 if (src1enc < 8) { 2641 if (src2enc < 8) { 2642 emit_opcode(cbuf, Assembler::REX_W); 2643 } else { 2644 emit_opcode(cbuf, Assembler::REX_WB); 2645 } 2646 } else { 2647 if (src2enc < 8) { 2648 emit_opcode(cbuf, Assembler::REX_WR); 2649 } else { 2650 emit_opcode(cbuf, Assembler::REX_WRB); 2651 } 2652 } 2653 emit_opcode(cbuf, 0x3B); 2654 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2655 2656 // movl $dst, -1 2657 if (dstenc >= 8) { 2658 emit_opcode(cbuf, Assembler::REX_B); 2659 } 2660 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2661 emit_d32(cbuf, -1); 2662 2663 // jl,s done 2664 emit_opcode(cbuf, 0x7C); 2665 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2666 2667 // setne $dst 2668 if (dstenc >= 4) { 2669 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2670 } 2671 emit_opcode(cbuf, 0x0F); 2672 emit_opcode(cbuf, 0x95); 2673 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2674 2675 // movzbl $dst, $dst 2676 if (dstenc >= 4) { 2677 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2678 } 2679 emit_opcode(cbuf, 0x0F); 2680 emit_opcode(cbuf, 0xB6); 2681 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2682 %} 2683 2684 enc_class Push_ResultXD(regD dst) %{ 2685 MacroAssembler _masm(&cbuf); 2686 __ fstp_d(Address(rsp, 0)); 2687 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2688 __ addptr(rsp, 8); 2689 %} 2690 2691 enc_class Push_SrcXD(regD src) %{ 2692 MacroAssembler _masm(&cbuf); 2693 __ subptr(rsp, 8); 2694 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2695 __ fld_d(Address(rsp, 0)); 2696 %} 2697 2698 2699 enc_class enc_rethrow() 2700 %{ 2701 cbuf.set_insts_mark(); 2702 emit_opcode(cbuf, 0xE9); // jmp entry 2703 emit_d32_reloc(cbuf, 2704 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2705 runtime_call_Relocation::spec(), 2706 RELOC_DISP32); 2707 %} 2708 2709 %} 2710 2711 2712 2713 //----------FRAME-------------------------------------------------------------- 2714 // Definition of frame structure and management information. 2715 // 2716 // S T A C K L A Y O U T Allocators stack-slot number 2717 // | (to get allocators register number 2718 // G Owned by | | v add OptoReg::stack0()) 2719 // r CALLER | | 2720 // o | +--------+ pad to even-align allocators stack-slot 2721 // w V | pad0 | numbers; owned by CALLER 2722 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2723 // h ^ | in | 5 2724 // | | args | 4 Holes in incoming args owned by SELF 2725 // | | | | 3 2726 // | | +--------+ 2727 // V | | old out| Empty on Intel, window on Sparc 2728 // | old |preserve| Must be even aligned. 2729 // | SP-+--------+----> Matcher::_old_SP, even aligned 2730 // | | in | 3 area for Intel ret address 2731 // Owned by |preserve| Empty on Sparc. 2732 // SELF +--------+ 2733 // | | pad2 | 2 pad to align old SP 2734 // | +--------+ 1 2735 // | | locks | 0 2736 // | +--------+----> OptoReg::stack0(), even aligned 2737 // | | pad1 | 11 pad to align new SP 2738 // | +--------+ 2739 // | | | 10 2740 // | | spills | 9 spills 2741 // V | | 8 (pad0 slot for callee) 2742 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2743 // ^ | out | 7 2744 // | | args | 6 Holes in outgoing args owned by CALLEE 2745 // Owned by +--------+ 2746 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2747 // | new |preserve| Must be even-aligned. 2748 // | SP-+--------+----> Matcher::_new_SP, even aligned 2749 // | | | 2750 // 2751 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2752 // known from SELF's arguments and the Java calling convention. 2753 // Region 6-7 is determined per call site. 2754 // Note 2: If the calling convention leaves holes in the incoming argument 2755 // area, those holes are owned by SELF. Holes in the outgoing area 2756 // are owned by the CALLEE. Holes should not be nessecary in the 2757 // incoming area, as the Java calling convention is completely under 2758 // the control of the AD file. Doubles can be sorted and packed to 2759 // avoid holes. Holes in the outgoing arguments may be nessecary for 2760 // varargs C calling conventions. 2761 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2762 // even aligned with pad0 as needed. 2763 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2764 // region 6-11 is even aligned; it may be padded out more so that 2765 // the region from SP to FP meets the minimum stack alignment. 2766 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2767 // alignment. Region 11, pad1, may be dynamically extended so that 2768 // SP meets the minimum alignment. 2769 2770 frame 2771 %{ 2772 // What direction does stack grow in (assumed to be same for C & Java) 2773 stack_direction(TOWARDS_LOW); 2774 2775 // These three registers define part of the calling convention 2776 // between compiled code and the interpreter. 2777 inline_cache_reg(RAX); // Inline Cache Register 2778 interpreter_method_oop_reg(RBX); // Method Oop Register when 2779 // calling interpreter 2780 2781 // Optional: name the operand used by cisc-spilling to access 2782 // [stack_pointer + offset] 2783 cisc_spilling_operand_name(indOffset32); 2784 2785 // Number of stack slots consumed by locking an object 2786 sync_stack_slots(2); 2787 2788 // Compiled code's Frame Pointer 2789 frame_pointer(RSP); 2790 2791 // Interpreter stores its frame pointer in a register which is 2792 // stored to the stack by I2CAdaptors. 2793 // I2CAdaptors convert from interpreted java to compiled java. 2794 interpreter_frame_pointer(RBP); 2795 2796 // Stack alignment requirement 2797 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2798 2799 // Number of stack slots between incoming argument block and the start of 2800 // a new frame. The PROLOG must add this many slots to the stack. The 2801 // EPILOG must remove this many slots. amd64 needs two slots for 2802 // return address. 2803 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2804 2805 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2806 // for calls to C. Supports the var-args backing area for register parms. 2807 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2808 2809 // The after-PROLOG location of the return address. Location of 2810 // return address specifies a type (REG or STACK) and a number 2811 // representing the register number (i.e. - use a register name) or 2812 // stack slot. 2813 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2814 // Otherwise, it is above the locks and verification slot and alignment word 2815 return_addr(STACK - 2 + 2816 round_to((Compile::current()->in_preserve_stack_slots() + 2817 Compile::current()->fixed_slots()), 2818 stack_alignment_in_slots())); 2819 2820 // Body of function which returns an integer array locating 2821 // arguments either in registers or in stack slots. Passed an array 2822 // of ideal registers called "sig" and a "length" count. Stack-slot 2823 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2824 // arguments for a CALLEE. Incoming stack arguments are 2825 // automatically biased by the preserve_stack_slots field above. 2826 2827 calling_convention 2828 %{ 2829 // No difference between ingoing/outgoing just pass false 2830 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2831 %} 2832 2833 c_calling_convention 2834 %{ 2835 // This is obviously always outgoing 2836 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2837 %} 2838 2839 // Location of compiled Java return values. Same as C for now. 2840 return_value 2841 %{ 2842 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2843 "only return normal values"); 2844 2845 static const int lo[Op_RegL + 1] = { 2846 0, 2847 0, 2848 RAX_num, // Op_RegN 2849 RAX_num, // Op_RegI 2850 RAX_num, // Op_RegP 2851 XMM0_num, // Op_RegF 2852 XMM0_num, // Op_RegD 2853 RAX_num // Op_RegL 2854 }; 2855 static const int hi[Op_RegL + 1] = { 2856 0, 2857 0, 2858 OptoReg::Bad, // Op_RegN 2859 OptoReg::Bad, // Op_RegI 2860 RAX_H_num, // Op_RegP 2861 OptoReg::Bad, // Op_RegF 2862 XMM0b_num, // Op_RegD 2863 RAX_H_num // Op_RegL 2864 }; 2865 // Excluded flags and vector registers. 2866 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2867 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2868 %} 2869 %} 2870 2871 //----------ATTRIBUTES--------------------------------------------------------- 2872 //----------Operand Attributes------------------------------------------------- 2873 op_attrib op_cost(0); // Required cost attribute 2874 2875 //----------Instruction Attributes--------------------------------------------- 2876 ins_attrib ins_cost(100); // Required cost attribute 2877 ins_attrib ins_size(8); // Required size attribute (in bits) 2878 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2879 // a non-matching short branch variant 2880 // of some long branch? 2881 ins_attrib ins_alignment(1); // Required alignment attribute (must 2882 // be a power of 2) specifies the 2883 // alignment that some part of the 2884 // instruction (not necessarily the 2885 // start) requires. If > 1, a 2886 // compute_padding() function must be 2887 // provided for the instruction 2888 2889 //----------OPERANDS----------------------------------------------------------- 2890 // Operand definitions must precede instruction definitions for correct parsing 2891 // in the ADLC because operands constitute user defined types which are used in 2892 // instruction definitions. 2893 2894 //----------Simple Operands---------------------------------------------------- 2895 // Immediate Operands 2896 // Integer Immediate 2897 operand immI() 2898 %{ 2899 match(ConI); 2900 2901 op_cost(10); 2902 format %{ %} 2903 interface(CONST_INTER); 2904 %} 2905 2906 // Constant for test vs zero 2907 operand immI0() 2908 %{ 2909 predicate(n->get_int() == 0); 2910 match(ConI); 2911 2912 op_cost(0); 2913 format %{ %} 2914 interface(CONST_INTER); 2915 %} 2916 2917 // Constant for increment 2918 operand immI1() 2919 %{ 2920 predicate(n->get_int() == 1); 2921 match(ConI); 2922 2923 op_cost(0); 2924 format %{ %} 2925 interface(CONST_INTER); 2926 %} 2927 2928 // Constant for decrement 2929 operand immI_M1() 2930 %{ 2931 predicate(n->get_int() == -1); 2932 match(ConI); 2933 2934 op_cost(0); 2935 format %{ %} 2936 interface(CONST_INTER); 2937 %} 2938 2939 // Valid scale values for addressing modes 2940 operand immI2() 2941 %{ 2942 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2943 match(ConI); 2944 2945 format %{ %} 2946 interface(CONST_INTER); 2947 %} 2948 2949 operand immI8() 2950 %{ 2951 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2952 match(ConI); 2953 2954 op_cost(5); 2955 format %{ %} 2956 interface(CONST_INTER); 2957 %} 2958 2959 operand immI16() 2960 %{ 2961 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2962 match(ConI); 2963 2964 op_cost(10); 2965 format %{ %} 2966 interface(CONST_INTER); 2967 %} 2968 2969 // Int Immediate non-negative 2970 operand immU31() 2971 %{ 2972 predicate(n->get_int() >= 0); 2973 match(ConI); 2974 2975 op_cost(0); 2976 format %{ %} 2977 interface(CONST_INTER); 2978 %} 2979 2980 // Constant for long shifts 2981 operand immI_32() 2982 %{ 2983 predicate( n->get_int() == 32 ); 2984 match(ConI); 2985 2986 op_cost(0); 2987 format %{ %} 2988 interface(CONST_INTER); 2989 %} 2990 2991 // Constant for long shifts 2992 operand immI_64() 2993 %{ 2994 predicate( n->get_int() == 64 ); 2995 match(ConI); 2996 2997 op_cost(0); 2998 format %{ %} 2999 interface(CONST_INTER); 3000 %} 3001 3002 // Pointer Immediate 3003 operand immP() 3004 %{ 3005 match(ConP); 3006 3007 op_cost(10); 3008 format %{ %} 3009 interface(CONST_INTER); 3010 %} 3011 3012 // NULL Pointer Immediate 3013 operand immP0() 3014 %{ 3015 predicate(n->get_ptr() == 0); 3016 match(ConP); 3017 3018 op_cost(5); 3019 format %{ %} 3020 interface(CONST_INTER); 3021 %} 3022 3023 // Pointer Immediate 3024 operand immN() %{ 3025 match(ConN); 3026 3027 op_cost(10); 3028 format %{ %} 3029 interface(CONST_INTER); 3030 %} 3031 3032 operand immNKlass() %{ 3033 match(ConNKlass); 3034 3035 op_cost(10); 3036 format %{ %} 3037 interface(CONST_INTER); 3038 %} 3039 3040 // NULL Pointer Immediate 3041 operand immN0() %{ 3042 predicate(n->get_narrowcon() == 0); 3043 match(ConN); 3044 3045 op_cost(5); 3046 format %{ %} 3047 interface(CONST_INTER); 3048 %} 3049 3050 operand immP31() 3051 %{ 3052 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3053 && (n->get_ptr() >> 31) == 0); 3054 match(ConP); 3055 3056 op_cost(5); 3057 format %{ %} 3058 interface(CONST_INTER); 3059 %} 3060 3061 3062 // Long Immediate 3063 operand immL() 3064 %{ 3065 match(ConL); 3066 3067 op_cost(20); 3068 format %{ %} 3069 interface(CONST_INTER); 3070 %} 3071 3072 // Long Immediate 8-bit 3073 operand immL8() 3074 %{ 3075 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3076 match(ConL); 3077 3078 op_cost(5); 3079 format %{ %} 3080 interface(CONST_INTER); 3081 %} 3082 3083 // Long Immediate 32-bit unsigned 3084 operand immUL32() 3085 %{ 3086 predicate(n->get_long() == (unsigned int) (n->get_long())); 3087 match(ConL); 3088 3089 op_cost(10); 3090 format %{ %} 3091 interface(CONST_INTER); 3092 %} 3093 3094 // Long Immediate 32-bit signed 3095 operand immL32() 3096 %{ 3097 predicate(n->get_long() == (int) (n->get_long())); 3098 match(ConL); 3099 3100 op_cost(15); 3101 format %{ %} 3102 interface(CONST_INTER); 3103 %} 3104 3105 // Long Immediate zero 3106 operand immL0() 3107 %{ 3108 predicate(n->get_long() == 0L); 3109 match(ConL); 3110 3111 op_cost(10); 3112 format %{ %} 3113 interface(CONST_INTER); 3114 %} 3115 3116 // Constant for increment 3117 operand immL1() 3118 %{ 3119 predicate(n->get_long() == 1); 3120 match(ConL); 3121 3122 format %{ %} 3123 interface(CONST_INTER); 3124 %} 3125 3126 // Constant for decrement 3127 operand immL_M1() 3128 %{ 3129 predicate(n->get_long() == -1); 3130 match(ConL); 3131 3132 format %{ %} 3133 interface(CONST_INTER); 3134 %} 3135 3136 // Long Immediate: the value 10 3137 operand immL10() 3138 %{ 3139 predicate(n->get_long() == 10); 3140 match(ConL); 3141 3142 format %{ %} 3143 interface(CONST_INTER); 3144 %} 3145 3146 // Long immediate from 0 to 127. 3147 // Used for a shorter form of long mul by 10. 3148 operand immL_127() 3149 %{ 3150 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3151 match(ConL); 3152 3153 op_cost(10); 3154 format %{ %} 3155 interface(CONST_INTER); 3156 %} 3157 3158 // Long Immediate: low 32-bit mask 3159 operand immL_32bits() 3160 %{ 3161 predicate(n->get_long() == 0xFFFFFFFFL); 3162 match(ConL); 3163 op_cost(20); 3164 3165 format %{ %} 3166 interface(CONST_INTER); 3167 %} 3168 3169 // Float Immediate zero 3170 operand immF0() 3171 %{ 3172 predicate(jint_cast(n->getf()) == 0); 3173 match(ConF); 3174 3175 op_cost(5); 3176 format %{ %} 3177 interface(CONST_INTER); 3178 %} 3179 3180 // Float Immediate 3181 operand immF() 3182 %{ 3183 match(ConF); 3184 3185 op_cost(15); 3186 format %{ %} 3187 interface(CONST_INTER); 3188 %} 3189 3190 // Double Immediate zero 3191 operand immD0() 3192 %{ 3193 predicate(jlong_cast(n->getd()) == 0); 3194 match(ConD); 3195 3196 op_cost(5); 3197 format %{ %} 3198 interface(CONST_INTER); 3199 %} 3200 3201 // Double Immediate 3202 operand immD() 3203 %{ 3204 match(ConD); 3205 3206 op_cost(15); 3207 format %{ %} 3208 interface(CONST_INTER); 3209 %} 3210 3211 // Immediates for special shifts (sign extend) 3212 3213 // Constants for increment 3214 operand immI_16() 3215 %{ 3216 predicate(n->get_int() == 16); 3217 match(ConI); 3218 3219 format %{ %} 3220 interface(CONST_INTER); 3221 %} 3222 3223 operand immI_24() 3224 %{ 3225 predicate(n->get_int() == 24); 3226 match(ConI); 3227 3228 format %{ %} 3229 interface(CONST_INTER); 3230 %} 3231 3232 // Constant for byte-wide masking 3233 operand immI_255() 3234 %{ 3235 predicate(n->get_int() == 255); 3236 match(ConI); 3237 3238 format %{ %} 3239 interface(CONST_INTER); 3240 %} 3241 3242 // Constant for short-wide masking 3243 operand immI_65535() 3244 %{ 3245 predicate(n->get_int() == 65535); 3246 match(ConI); 3247 3248 format %{ %} 3249 interface(CONST_INTER); 3250 %} 3251 3252 // Constant for byte-wide masking 3253 operand immL_255() 3254 %{ 3255 predicate(n->get_long() == 255); 3256 match(ConL); 3257 3258 format %{ %} 3259 interface(CONST_INTER); 3260 %} 3261 3262 // Constant for short-wide masking 3263 operand immL_65535() 3264 %{ 3265 predicate(n->get_long() == 65535); 3266 match(ConL); 3267 3268 format %{ %} 3269 interface(CONST_INTER); 3270 %} 3271 3272 // Register Operands 3273 // Integer Register 3274 operand rRegI() 3275 %{ 3276 constraint(ALLOC_IN_RC(int_reg)); 3277 match(RegI); 3278 3279 match(rax_RegI); 3280 match(rbx_RegI); 3281 match(rcx_RegI); 3282 match(rdx_RegI); 3283 match(rdi_RegI); 3284 3285 format %{ %} 3286 interface(REG_INTER); 3287 %} 3288 3289 // Special Registers 3290 operand rax_RegI() 3291 %{ 3292 constraint(ALLOC_IN_RC(int_rax_reg)); 3293 match(RegI); 3294 match(rRegI); 3295 3296 format %{ "RAX" %} 3297 interface(REG_INTER); 3298 %} 3299 3300 // Special Registers 3301 operand rbx_RegI() 3302 %{ 3303 constraint(ALLOC_IN_RC(int_rbx_reg)); 3304 match(RegI); 3305 match(rRegI); 3306 3307 format %{ "RBX" %} 3308 interface(REG_INTER); 3309 %} 3310 3311 operand rcx_RegI() 3312 %{ 3313 constraint(ALLOC_IN_RC(int_rcx_reg)); 3314 match(RegI); 3315 match(rRegI); 3316 3317 format %{ "RCX" %} 3318 interface(REG_INTER); 3319 %} 3320 3321 operand rdx_RegI() 3322 %{ 3323 constraint(ALLOC_IN_RC(int_rdx_reg)); 3324 match(RegI); 3325 match(rRegI); 3326 3327 format %{ "RDX" %} 3328 interface(REG_INTER); 3329 %} 3330 3331 operand rdi_RegI() 3332 %{ 3333 constraint(ALLOC_IN_RC(int_rdi_reg)); 3334 match(RegI); 3335 match(rRegI); 3336 3337 format %{ "RDI" %} 3338 interface(REG_INTER); 3339 %} 3340 3341 operand no_rcx_RegI() 3342 %{ 3343 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3344 match(RegI); 3345 match(rax_RegI); 3346 match(rbx_RegI); 3347 match(rdx_RegI); 3348 match(rdi_RegI); 3349 3350 format %{ %} 3351 interface(REG_INTER); 3352 %} 3353 3354 operand no_rax_rdx_RegI() 3355 %{ 3356 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3357 match(RegI); 3358 match(rbx_RegI); 3359 match(rcx_RegI); 3360 match(rdi_RegI); 3361 3362 format %{ %} 3363 interface(REG_INTER); 3364 %} 3365 3366 // Pointer Register 3367 operand any_RegP() 3368 %{ 3369 constraint(ALLOC_IN_RC(any_reg)); 3370 match(RegP); 3371 match(rax_RegP); 3372 match(rbx_RegP); 3373 match(rdi_RegP); 3374 match(rsi_RegP); 3375 match(rbp_RegP); 3376 match(r15_RegP); 3377 match(rRegP); 3378 3379 format %{ %} 3380 interface(REG_INTER); 3381 %} 3382 3383 operand rRegP() 3384 %{ 3385 constraint(ALLOC_IN_RC(ptr_reg)); 3386 match(RegP); 3387 match(rax_RegP); 3388 match(rbx_RegP); 3389 match(rdi_RegP); 3390 match(rsi_RegP); 3391 match(rbp_RegP); // See Q&A below about 3392 match(r15_RegP); // r15_RegP and rbp_RegP. 3393 3394 format %{ %} 3395 interface(REG_INTER); 3396 %} 3397 3398 operand rRegN() %{ 3399 constraint(ALLOC_IN_RC(int_reg)); 3400 match(RegN); 3401 3402 format %{ %} 3403 interface(REG_INTER); 3404 %} 3405 3406 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3407 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3408 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3409 // The output of an instruction is controlled by the allocator, which respects 3410 // register class masks, not match rules. Unless an instruction mentions 3411 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3412 // by the allocator as an input. 3413 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3414 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3415 // result, RBP is not included in the output of the instruction either. 3416 3417 operand no_rax_RegP() 3418 %{ 3419 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3420 match(RegP); 3421 match(rbx_RegP); 3422 match(rsi_RegP); 3423 match(rdi_RegP); 3424 3425 format %{ %} 3426 interface(REG_INTER); 3427 %} 3428 3429 // This operand is not allowed to use RBP even if 3430 // RBP is not used to hold the frame pointer. 3431 operand no_rbp_RegP() 3432 %{ 3433 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3434 match(RegP); 3435 match(rbx_RegP); 3436 match(rsi_RegP); 3437 match(rdi_RegP); 3438 3439 format %{ %} 3440 interface(REG_INTER); 3441 %} 3442 3443 operand no_rax_rbx_RegP() 3444 %{ 3445 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3446 match(RegP); 3447 match(rsi_RegP); 3448 match(rdi_RegP); 3449 3450 format %{ %} 3451 interface(REG_INTER); 3452 %} 3453 3454 // Special Registers 3455 // Return a pointer value 3456 operand rax_RegP() 3457 %{ 3458 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3459 match(RegP); 3460 match(rRegP); 3461 3462 format %{ %} 3463 interface(REG_INTER); 3464 %} 3465 3466 // Special Registers 3467 // Return a compressed pointer value 3468 operand rax_RegN() 3469 %{ 3470 constraint(ALLOC_IN_RC(int_rax_reg)); 3471 match(RegN); 3472 match(rRegN); 3473 3474 format %{ %} 3475 interface(REG_INTER); 3476 %} 3477 3478 // Used in AtomicAdd 3479 operand rbx_RegP() 3480 %{ 3481 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3482 match(RegP); 3483 match(rRegP); 3484 3485 format %{ %} 3486 interface(REG_INTER); 3487 %} 3488 3489 operand rsi_RegP() 3490 %{ 3491 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3492 match(RegP); 3493 match(rRegP); 3494 3495 format %{ %} 3496 interface(REG_INTER); 3497 %} 3498 3499 // Used in rep stosq 3500 operand rdi_RegP() 3501 %{ 3502 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3503 match(RegP); 3504 match(rRegP); 3505 3506 format %{ %} 3507 interface(REG_INTER); 3508 %} 3509 3510 operand r15_RegP() 3511 %{ 3512 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3513 match(RegP); 3514 match(rRegP); 3515 3516 format %{ %} 3517 interface(REG_INTER); 3518 %} 3519 3520 operand rRegL() 3521 %{ 3522 constraint(ALLOC_IN_RC(long_reg)); 3523 match(RegL); 3524 match(rax_RegL); 3525 match(rdx_RegL); 3526 3527 format %{ %} 3528 interface(REG_INTER); 3529 %} 3530 3531 // Special Registers 3532 operand no_rax_rdx_RegL() 3533 %{ 3534 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3535 match(RegL); 3536 match(rRegL); 3537 3538 format %{ %} 3539 interface(REG_INTER); 3540 %} 3541 3542 operand no_rax_RegL() 3543 %{ 3544 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3545 match(RegL); 3546 match(rRegL); 3547 match(rdx_RegL); 3548 3549 format %{ %} 3550 interface(REG_INTER); 3551 %} 3552 3553 operand no_rcx_RegL() 3554 %{ 3555 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3556 match(RegL); 3557 match(rRegL); 3558 3559 format %{ %} 3560 interface(REG_INTER); 3561 %} 3562 3563 operand rax_RegL() 3564 %{ 3565 constraint(ALLOC_IN_RC(long_rax_reg)); 3566 match(RegL); 3567 match(rRegL); 3568 3569 format %{ "RAX" %} 3570 interface(REG_INTER); 3571 %} 3572 3573 operand rcx_RegL() 3574 %{ 3575 constraint(ALLOC_IN_RC(long_rcx_reg)); 3576 match(RegL); 3577 match(rRegL); 3578 3579 format %{ %} 3580 interface(REG_INTER); 3581 %} 3582 3583 operand rdx_RegL() 3584 %{ 3585 constraint(ALLOC_IN_RC(long_rdx_reg)); 3586 match(RegL); 3587 match(rRegL); 3588 3589 format %{ %} 3590 interface(REG_INTER); 3591 %} 3592 3593 // Flags register, used as output of compare instructions 3594 operand rFlagsReg() 3595 %{ 3596 constraint(ALLOC_IN_RC(int_flags)); 3597 match(RegFlags); 3598 3599 format %{ "RFLAGS" %} 3600 interface(REG_INTER); 3601 %} 3602 3603 // Flags register, used as output of FLOATING POINT compare instructions 3604 operand rFlagsRegU() 3605 %{ 3606 constraint(ALLOC_IN_RC(int_flags)); 3607 match(RegFlags); 3608 3609 format %{ "RFLAGS_U" %} 3610 interface(REG_INTER); 3611 %} 3612 3613 operand rFlagsRegUCF() %{ 3614 constraint(ALLOC_IN_RC(int_flags)); 3615 match(RegFlags); 3616 predicate(false); 3617 3618 format %{ "RFLAGS_U_CF" %} 3619 interface(REG_INTER); 3620 %} 3621 3622 // Float register operands 3623 operand regF() %{ 3624 constraint(ALLOC_IN_RC(float_reg)); 3625 match(RegF); 3626 3627 format %{ %} 3628 interface(REG_INTER); 3629 %} 3630 3631 // Double register operands 3632 operand regD() %{ 3633 constraint(ALLOC_IN_RC(double_reg)); 3634 match(RegD); 3635 3636 format %{ %} 3637 interface(REG_INTER); 3638 %} 3639 3640 // Vectors 3641 operand vecS() %{ 3642 constraint(ALLOC_IN_RC(vectors_reg)); 3643 match(VecS); 3644 3645 format %{ %} 3646 interface(REG_INTER); 3647 %} 3648 3649 operand vecD() %{ 3650 constraint(ALLOC_IN_RC(vectord_reg)); 3651 match(VecD); 3652 3653 format %{ %} 3654 interface(REG_INTER); 3655 %} 3656 3657 operand vecX() %{ 3658 constraint(ALLOC_IN_RC(vectorx_reg)); 3659 match(VecX); 3660 3661 format %{ %} 3662 interface(REG_INTER); 3663 %} 3664 3665 operand vecY() %{ 3666 constraint(ALLOC_IN_RC(vectory_reg)); 3667 match(VecY); 3668 3669 format %{ %} 3670 interface(REG_INTER); 3671 %} 3672 3673 //----------Memory Operands---------------------------------------------------- 3674 // Direct Memory Operand 3675 // operand direct(immP addr) 3676 // %{ 3677 // match(addr); 3678 3679 // format %{ "[$addr]" %} 3680 // interface(MEMORY_INTER) %{ 3681 // base(0xFFFFFFFF); 3682 // index(0x4); 3683 // scale(0x0); 3684 // disp($addr); 3685 // %} 3686 // %} 3687 3688 // Indirect Memory Operand 3689 operand indirect(any_RegP reg) 3690 %{ 3691 constraint(ALLOC_IN_RC(ptr_reg)); 3692 match(reg); 3693 3694 format %{ "[$reg]" %} 3695 interface(MEMORY_INTER) %{ 3696 base($reg); 3697 index(0x4); 3698 scale(0x0); 3699 disp(0x0); 3700 %} 3701 %} 3702 3703 // Indirect Memory Plus Short Offset Operand 3704 operand indOffset8(any_RegP reg, immL8 off) 3705 %{ 3706 constraint(ALLOC_IN_RC(ptr_reg)); 3707 match(AddP reg off); 3708 3709 format %{ "[$reg + $off (8-bit)]" %} 3710 interface(MEMORY_INTER) %{ 3711 base($reg); 3712 index(0x4); 3713 scale(0x0); 3714 disp($off); 3715 %} 3716 %} 3717 3718 // Indirect Memory Plus Long Offset Operand 3719 operand indOffset32(any_RegP reg, immL32 off) 3720 %{ 3721 constraint(ALLOC_IN_RC(ptr_reg)); 3722 match(AddP reg off); 3723 3724 format %{ "[$reg + $off (32-bit)]" %} 3725 interface(MEMORY_INTER) %{ 3726 base($reg); 3727 index(0x4); 3728 scale(0x0); 3729 disp($off); 3730 %} 3731 %} 3732 3733 // Indirect Memory Plus Index Register Plus Offset Operand 3734 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3735 %{ 3736 constraint(ALLOC_IN_RC(ptr_reg)); 3737 match(AddP (AddP reg lreg) off); 3738 3739 op_cost(10); 3740 format %{"[$reg + $off + $lreg]" %} 3741 interface(MEMORY_INTER) %{ 3742 base($reg); 3743 index($lreg); 3744 scale(0x0); 3745 disp($off); 3746 %} 3747 %} 3748 3749 // Indirect Memory Plus Index Register Plus Offset Operand 3750 operand indIndex(any_RegP reg, rRegL lreg) 3751 %{ 3752 constraint(ALLOC_IN_RC(ptr_reg)); 3753 match(AddP reg lreg); 3754 3755 op_cost(10); 3756 format %{"[$reg + $lreg]" %} 3757 interface(MEMORY_INTER) %{ 3758 base($reg); 3759 index($lreg); 3760 scale(0x0); 3761 disp(0x0); 3762 %} 3763 %} 3764 3765 // Indirect Memory Times Scale Plus Index Register 3766 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3767 %{ 3768 constraint(ALLOC_IN_RC(ptr_reg)); 3769 match(AddP reg (LShiftL lreg scale)); 3770 3771 op_cost(10); 3772 format %{"[$reg + $lreg << $scale]" %} 3773 interface(MEMORY_INTER) %{ 3774 base($reg); 3775 index($lreg); 3776 scale($scale); 3777 disp(0x0); 3778 %} 3779 %} 3780 3781 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3782 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3783 %{ 3784 constraint(ALLOC_IN_RC(ptr_reg)); 3785 match(AddP (AddP reg (LShiftL lreg scale)) off); 3786 3787 op_cost(10); 3788 format %{"[$reg + $off + $lreg << $scale]" %} 3789 interface(MEMORY_INTER) %{ 3790 base($reg); 3791 index($lreg); 3792 scale($scale); 3793 disp($off); 3794 %} 3795 %} 3796 3797 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3798 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3799 %{ 3800 constraint(ALLOC_IN_RC(ptr_reg)); 3801 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3802 match(AddP (AddP reg (ConvI2L idx)) off); 3803 3804 op_cost(10); 3805 format %{"[$reg + $off + $idx]" %} 3806 interface(MEMORY_INTER) %{ 3807 base($reg); 3808 index($idx); 3809 scale(0x0); 3810 disp($off); 3811 %} 3812 %} 3813 3814 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3815 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3816 %{ 3817 constraint(ALLOC_IN_RC(ptr_reg)); 3818 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3819 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3820 3821 op_cost(10); 3822 format %{"[$reg + $off + $idx << $scale]" %} 3823 interface(MEMORY_INTER) %{ 3824 base($reg); 3825 index($idx); 3826 scale($scale); 3827 disp($off); 3828 %} 3829 %} 3830 3831 // Indirect Narrow Oop Plus Offset Operand 3832 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3833 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3834 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3835 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3836 constraint(ALLOC_IN_RC(ptr_reg)); 3837 match(AddP (DecodeN reg) off); 3838 3839 op_cost(10); 3840 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3841 interface(MEMORY_INTER) %{ 3842 base(0xc); // R12 3843 index($reg); 3844 scale(0x3); 3845 disp($off); 3846 %} 3847 %} 3848 3849 // Indirect Memory Operand 3850 operand indirectNarrow(rRegN reg) 3851 %{ 3852 predicate(Universe::narrow_oop_shift() == 0); 3853 constraint(ALLOC_IN_RC(ptr_reg)); 3854 match(DecodeN reg); 3855 3856 format %{ "[$reg]" %} 3857 interface(MEMORY_INTER) %{ 3858 base($reg); 3859 index(0x4); 3860 scale(0x0); 3861 disp(0x0); 3862 %} 3863 %} 3864 3865 // Indirect Memory Plus Short Offset Operand 3866 operand indOffset8Narrow(rRegN reg, immL8 off) 3867 %{ 3868 predicate(Universe::narrow_oop_shift() == 0); 3869 constraint(ALLOC_IN_RC(ptr_reg)); 3870 match(AddP (DecodeN reg) off); 3871 3872 format %{ "[$reg + $off (8-bit)]" %} 3873 interface(MEMORY_INTER) %{ 3874 base($reg); 3875 index(0x4); 3876 scale(0x0); 3877 disp($off); 3878 %} 3879 %} 3880 3881 // Indirect Memory Plus Long Offset Operand 3882 operand indOffset32Narrow(rRegN reg, immL32 off) 3883 %{ 3884 predicate(Universe::narrow_oop_shift() == 0); 3885 constraint(ALLOC_IN_RC(ptr_reg)); 3886 match(AddP (DecodeN reg) off); 3887 3888 format %{ "[$reg + $off (32-bit)]" %} 3889 interface(MEMORY_INTER) %{ 3890 base($reg); 3891 index(0x4); 3892 scale(0x0); 3893 disp($off); 3894 %} 3895 %} 3896 3897 // Indirect Memory Plus Index Register Plus Offset Operand 3898 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3899 %{ 3900 predicate(Universe::narrow_oop_shift() == 0); 3901 constraint(ALLOC_IN_RC(ptr_reg)); 3902 match(AddP (AddP (DecodeN reg) lreg) off); 3903 3904 op_cost(10); 3905 format %{"[$reg + $off + $lreg]" %} 3906 interface(MEMORY_INTER) %{ 3907 base($reg); 3908 index($lreg); 3909 scale(0x0); 3910 disp($off); 3911 %} 3912 %} 3913 3914 // Indirect Memory Plus Index Register Plus Offset Operand 3915 operand indIndexNarrow(rRegN reg, rRegL lreg) 3916 %{ 3917 predicate(Universe::narrow_oop_shift() == 0); 3918 constraint(ALLOC_IN_RC(ptr_reg)); 3919 match(AddP (DecodeN reg) lreg); 3920 3921 op_cost(10); 3922 format %{"[$reg + $lreg]" %} 3923 interface(MEMORY_INTER) %{ 3924 base($reg); 3925 index($lreg); 3926 scale(0x0); 3927 disp(0x0); 3928 %} 3929 %} 3930 3931 // Indirect Memory Times Scale Plus Index Register 3932 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3933 %{ 3934 predicate(Universe::narrow_oop_shift() == 0); 3935 constraint(ALLOC_IN_RC(ptr_reg)); 3936 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3937 3938 op_cost(10); 3939 format %{"[$reg + $lreg << $scale]" %} 3940 interface(MEMORY_INTER) %{ 3941 base($reg); 3942 index($lreg); 3943 scale($scale); 3944 disp(0x0); 3945 %} 3946 %} 3947 3948 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3949 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3950 %{ 3951 predicate(Universe::narrow_oop_shift() == 0); 3952 constraint(ALLOC_IN_RC(ptr_reg)); 3953 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3954 3955 op_cost(10); 3956 format %{"[$reg + $off + $lreg << $scale]" %} 3957 interface(MEMORY_INTER) %{ 3958 base($reg); 3959 index($lreg); 3960 scale($scale); 3961 disp($off); 3962 %} 3963 %} 3964 3965 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3966 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3967 %{ 3968 constraint(ALLOC_IN_RC(ptr_reg)); 3969 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3970 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3971 3972 op_cost(10); 3973 format %{"[$reg + $off + $idx]" %} 3974 interface(MEMORY_INTER) %{ 3975 base($reg); 3976 index($idx); 3977 scale(0x0); 3978 disp($off); 3979 %} 3980 %} 3981 3982 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3983 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3984 %{ 3985 constraint(ALLOC_IN_RC(ptr_reg)); 3986 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3987 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3988 3989 op_cost(10); 3990 format %{"[$reg + $off + $idx << $scale]" %} 3991 interface(MEMORY_INTER) %{ 3992 base($reg); 3993 index($idx); 3994 scale($scale); 3995 disp($off); 3996 %} 3997 %} 3998 3999 //----------Special Memory Operands-------------------------------------------- 4000 // Stack Slot Operand - This operand is used for loading and storing temporary 4001 // values on the stack where a match requires a value to 4002 // flow through memory. 4003 operand stackSlotP(sRegP reg) 4004 %{ 4005 constraint(ALLOC_IN_RC(stack_slots)); 4006 // No match rule because this operand is only generated in matching 4007 4008 format %{ "[$reg]" %} 4009 interface(MEMORY_INTER) %{ 4010 base(0x4); // RSP 4011 index(0x4); // No Index 4012 scale(0x0); // No Scale 4013 disp($reg); // Stack Offset 4014 %} 4015 %} 4016 4017 operand stackSlotI(sRegI reg) 4018 %{ 4019 constraint(ALLOC_IN_RC(stack_slots)); 4020 // No match rule because this operand is only generated in matching 4021 4022 format %{ "[$reg]" %} 4023 interface(MEMORY_INTER) %{ 4024 base(0x4); // RSP 4025 index(0x4); // No Index 4026 scale(0x0); // No Scale 4027 disp($reg); // Stack Offset 4028 %} 4029 %} 4030 4031 operand stackSlotF(sRegF reg) 4032 %{ 4033 constraint(ALLOC_IN_RC(stack_slots)); 4034 // No match rule because this operand is only generated in matching 4035 4036 format %{ "[$reg]" %} 4037 interface(MEMORY_INTER) %{ 4038 base(0x4); // RSP 4039 index(0x4); // No Index 4040 scale(0x0); // No Scale 4041 disp($reg); // Stack Offset 4042 %} 4043 %} 4044 4045 operand stackSlotD(sRegD reg) 4046 %{ 4047 constraint(ALLOC_IN_RC(stack_slots)); 4048 // No match rule because this operand is only generated in matching 4049 4050 format %{ "[$reg]" %} 4051 interface(MEMORY_INTER) %{ 4052 base(0x4); // RSP 4053 index(0x4); // No Index 4054 scale(0x0); // No Scale 4055 disp($reg); // Stack Offset 4056 %} 4057 %} 4058 operand stackSlotL(sRegL reg) 4059 %{ 4060 constraint(ALLOC_IN_RC(stack_slots)); 4061 // No match rule because this operand is only generated in matching 4062 4063 format %{ "[$reg]" %} 4064 interface(MEMORY_INTER) %{ 4065 base(0x4); // RSP 4066 index(0x4); // No Index 4067 scale(0x0); // No Scale 4068 disp($reg); // Stack Offset 4069 %} 4070 %} 4071 4072 //----------Conditional Branch Operands---------------------------------------- 4073 // Comparison Op - This is the operation of the comparison, and is limited to 4074 // the following set of codes: 4075 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4076 // 4077 // Other attributes of the comparison, such as unsignedness, are specified 4078 // by the comparison instruction that sets a condition code flags register. 4079 // That result is represented by a flags operand whose subtype is appropriate 4080 // to the unsignedness (etc.) of the comparison. 4081 // 4082 // Later, the instruction which matches both the Comparison Op (a Bool) and 4083 // the flags (produced by the Cmp) specifies the coding of the comparison op 4084 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4085 4086 // Comparision Code 4087 operand cmpOp() 4088 %{ 4089 match(Bool); 4090 4091 format %{ "" %} 4092 interface(COND_INTER) %{ 4093 equal(0x4, "e"); 4094 not_equal(0x5, "ne"); 4095 less(0xC, "l"); 4096 greater_equal(0xD, "ge"); 4097 less_equal(0xE, "le"); 4098 greater(0xF, "g"); 4099 overflow(0x0, "o"); 4100 no_overflow(0x1, "no"); 4101 %} 4102 %} 4103 4104 // Comparison Code, unsigned compare. Used by FP also, with 4105 // C2 (unordered) turned into GT or LT already. The other bits 4106 // C0 and C3 are turned into Carry & Zero flags. 4107 operand cmpOpU() 4108 %{ 4109 match(Bool); 4110 4111 format %{ "" %} 4112 interface(COND_INTER) %{ 4113 equal(0x4, "e"); 4114 not_equal(0x5, "ne"); 4115 less(0x2, "b"); 4116 greater_equal(0x3, "nb"); 4117 less_equal(0x6, "be"); 4118 greater(0x7, "nbe"); 4119 overflow(0x0, "o"); 4120 no_overflow(0x1, "no"); 4121 %} 4122 %} 4123 4124 4125 // Floating comparisons that don't require any fixup for the unordered case 4126 operand cmpOpUCF() %{ 4127 match(Bool); 4128 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4129 n->as_Bool()->_test._test == BoolTest::ge || 4130 n->as_Bool()->_test._test == BoolTest::le || 4131 n->as_Bool()->_test._test == BoolTest::gt); 4132 format %{ "" %} 4133 interface(COND_INTER) %{ 4134 equal(0x4, "e"); 4135 not_equal(0x5, "ne"); 4136 less(0x2, "b"); 4137 greater_equal(0x3, "nb"); 4138 less_equal(0x6, "be"); 4139 greater(0x7, "nbe"); 4140 overflow(0x0, "o"); 4141 no_overflow(0x1, "no"); 4142 %} 4143 %} 4144 4145 4146 // Floating comparisons that can be fixed up with extra conditional jumps 4147 operand cmpOpUCF2() %{ 4148 match(Bool); 4149 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4150 n->as_Bool()->_test._test == BoolTest::eq); 4151 format %{ "" %} 4152 interface(COND_INTER) %{ 4153 equal(0x4, "e"); 4154 not_equal(0x5, "ne"); 4155 less(0x2, "b"); 4156 greater_equal(0x3, "nb"); 4157 less_equal(0x6, "be"); 4158 greater(0x7, "nbe"); 4159 overflow(0x0, "o"); 4160 no_overflow(0x1, "no"); 4161 %} 4162 %} 4163 4164 4165 //----------OPERAND CLASSES---------------------------------------------------- 4166 // Operand Classes are groups of operands that are used as to simplify 4167 // instruction definitions by not requiring the AD writer to specify separate 4168 // instructions for every form of operand when the instruction accepts 4169 // multiple operand types with the same basic encoding and format. The classic 4170 // case of this is memory operands. 4171 4172 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4173 indIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4174 indCompressedOopOffset, 4175 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4176 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4177 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4178 4179 //----------PIPELINE----------------------------------------------------------- 4180 // Rules which define the behavior of the target architectures pipeline. 4181 pipeline %{ 4182 4183 //----------ATTRIBUTES--------------------------------------------------------- 4184 attributes %{ 4185 variable_size_instructions; // Fixed size instructions 4186 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4187 instruction_unit_size = 1; // An instruction is 1 bytes long 4188 instruction_fetch_unit_size = 16; // The processor fetches one line 4189 instruction_fetch_units = 1; // of 16 bytes 4190 4191 // List of nop instructions 4192 nops( MachNop ); 4193 %} 4194 4195 //----------RESOURCES---------------------------------------------------------- 4196 // Resources are the functional units available to the machine 4197 4198 // Generic P2/P3 pipeline 4199 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4200 // 3 instructions decoded per cycle. 4201 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4202 // 3 ALU op, only ALU0 handles mul instructions. 4203 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4204 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4205 BR, FPU, 4206 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4207 4208 //----------PIPELINE DESCRIPTION----------------------------------------------- 4209 // Pipeline Description specifies the stages in the machine's pipeline 4210 4211 // Generic P2/P3 pipeline 4212 pipe_desc(S0, S1, S2, S3, S4, S5); 4213 4214 //----------PIPELINE CLASSES--------------------------------------------------- 4215 // Pipeline Classes describe the stages in which input and output are 4216 // referenced by the hardware pipeline. 4217 4218 // Naming convention: ialu or fpu 4219 // Then: _reg 4220 // Then: _reg if there is a 2nd register 4221 // Then: _long if it's a pair of instructions implementing a long 4222 // Then: _fat if it requires the big decoder 4223 // Or: _mem if it requires the big decoder and a memory unit. 4224 4225 // Integer ALU reg operation 4226 pipe_class ialu_reg(rRegI dst) 4227 %{ 4228 single_instruction; 4229 dst : S4(write); 4230 dst : S3(read); 4231 DECODE : S0; // any decoder 4232 ALU : S3; // any alu 4233 %} 4234 4235 // Long ALU reg operation 4236 pipe_class ialu_reg_long(rRegL dst) 4237 %{ 4238 instruction_count(2); 4239 dst : S4(write); 4240 dst : S3(read); 4241 DECODE : S0(2); // any 2 decoders 4242 ALU : S3(2); // both alus 4243 %} 4244 4245 // Integer ALU reg operation using big decoder 4246 pipe_class ialu_reg_fat(rRegI dst) 4247 %{ 4248 single_instruction; 4249 dst : S4(write); 4250 dst : S3(read); 4251 D0 : S0; // big decoder only 4252 ALU : S3; // any alu 4253 %} 4254 4255 // Long ALU reg operation using big decoder 4256 pipe_class ialu_reg_long_fat(rRegL dst) 4257 %{ 4258 instruction_count(2); 4259 dst : S4(write); 4260 dst : S3(read); 4261 D0 : S0(2); // big decoder only; twice 4262 ALU : S3(2); // any 2 alus 4263 %} 4264 4265 // Integer ALU reg-reg operation 4266 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4267 %{ 4268 single_instruction; 4269 dst : S4(write); 4270 src : S3(read); 4271 DECODE : S0; // any decoder 4272 ALU : S3; // any alu 4273 %} 4274 4275 // Long ALU reg-reg operation 4276 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4277 %{ 4278 instruction_count(2); 4279 dst : S4(write); 4280 src : S3(read); 4281 DECODE : S0(2); // any 2 decoders 4282 ALU : S3(2); // both alus 4283 %} 4284 4285 // Integer ALU reg-reg operation 4286 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4287 %{ 4288 single_instruction; 4289 dst : S4(write); 4290 src : S3(read); 4291 D0 : S0; // big decoder only 4292 ALU : S3; // any alu 4293 %} 4294 4295 // Long ALU reg-reg operation 4296 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4297 %{ 4298 instruction_count(2); 4299 dst : S4(write); 4300 src : S3(read); 4301 D0 : S0(2); // big decoder only; twice 4302 ALU : S3(2); // both alus 4303 %} 4304 4305 // Integer ALU reg-mem operation 4306 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4307 %{ 4308 single_instruction; 4309 dst : S5(write); 4310 mem : S3(read); 4311 D0 : S0; // big decoder only 4312 ALU : S4; // any alu 4313 MEM : S3; // any mem 4314 %} 4315 4316 // Integer mem operation (prefetch) 4317 pipe_class ialu_mem(memory mem) 4318 %{ 4319 single_instruction; 4320 mem : S3(read); 4321 D0 : S0; // big decoder only 4322 MEM : S3; // any mem 4323 %} 4324 4325 // Integer Store to Memory 4326 pipe_class ialu_mem_reg(memory mem, rRegI src) 4327 %{ 4328 single_instruction; 4329 mem : S3(read); 4330 src : S5(read); 4331 D0 : S0; // big decoder only 4332 ALU : S4; // any alu 4333 MEM : S3; 4334 %} 4335 4336 // // Long Store to Memory 4337 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4338 // %{ 4339 // instruction_count(2); 4340 // mem : S3(read); 4341 // src : S5(read); 4342 // D0 : S0(2); // big decoder only; twice 4343 // ALU : S4(2); // any 2 alus 4344 // MEM : S3(2); // Both mems 4345 // %} 4346 4347 // Integer Store to Memory 4348 pipe_class ialu_mem_imm(memory mem) 4349 %{ 4350 single_instruction; 4351 mem : S3(read); 4352 D0 : S0; // big decoder only 4353 ALU : S4; // any alu 4354 MEM : S3; 4355 %} 4356 4357 // Integer ALU0 reg-reg operation 4358 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4359 %{ 4360 single_instruction; 4361 dst : S4(write); 4362 src : S3(read); 4363 D0 : S0; // Big decoder only 4364 ALU0 : S3; // only alu0 4365 %} 4366 4367 // Integer ALU0 reg-mem operation 4368 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4369 %{ 4370 single_instruction; 4371 dst : S5(write); 4372 mem : S3(read); 4373 D0 : S0; // big decoder only 4374 ALU0 : S4; // ALU0 only 4375 MEM : S3; // any mem 4376 %} 4377 4378 // Integer ALU reg-reg operation 4379 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4380 %{ 4381 single_instruction; 4382 cr : S4(write); 4383 src1 : S3(read); 4384 src2 : S3(read); 4385 DECODE : S0; // any decoder 4386 ALU : S3; // any alu 4387 %} 4388 4389 // Integer ALU reg-imm operation 4390 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4391 %{ 4392 single_instruction; 4393 cr : S4(write); 4394 src1 : S3(read); 4395 DECODE : S0; // any decoder 4396 ALU : S3; // any alu 4397 %} 4398 4399 // Integer ALU reg-mem operation 4400 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4401 %{ 4402 single_instruction; 4403 cr : S4(write); 4404 src1 : S3(read); 4405 src2 : S3(read); 4406 D0 : S0; // big decoder only 4407 ALU : S4; // any alu 4408 MEM : S3; 4409 %} 4410 4411 // Conditional move reg-reg 4412 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4413 %{ 4414 instruction_count(4); 4415 y : S4(read); 4416 q : S3(read); 4417 p : S3(read); 4418 DECODE : S0(4); // any decoder 4419 %} 4420 4421 // Conditional move reg-reg 4422 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4423 %{ 4424 single_instruction; 4425 dst : S4(write); 4426 src : S3(read); 4427 cr : S3(read); 4428 DECODE : S0; // any decoder 4429 %} 4430 4431 // Conditional move reg-mem 4432 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4433 %{ 4434 single_instruction; 4435 dst : S4(write); 4436 src : S3(read); 4437 cr : S3(read); 4438 DECODE : S0; // any decoder 4439 MEM : S3; 4440 %} 4441 4442 // Conditional move reg-reg long 4443 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4444 %{ 4445 single_instruction; 4446 dst : S4(write); 4447 src : S3(read); 4448 cr : S3(read); 4449 DECODE : S0(2); // any 2 decoders 4450 %} 4451 4452 // XXX 4453 // // Conditional move double reg-reg 4454 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4455 // %{ 4456 // single_instruction; 4457 // dst : S4(write); 4458 // src : S3(read); 4459 // cr : S3(read); 4460 // DECODE : S0; // any decoder 4461 // %} 4462 4463 // Float reg-reg operation 4464 pipe_class fpu_reg(regD dst) 4465 %{ 4466 instruction_count(2); 4467 dst : S3(read); 4468 DECODE : S0(2); // any 2 decoders 4469 FPU : S3; 4470 %} 4471 4472 // Float reg-reg operation 4473 pipe_class fpu_reg_reg(regD dst, regD src) 4474 %{ 4475 instruction_count(2); 4476 dst : S4(write); 4477 src : S3(read); 4478 DECODE : S0(2); // any 2 decoders 4479 FPU : S3; 4480 %} 4481 4482 // Float reg-reg operation 4483 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4484 %{ 4485 instruction_count(3); 4486 dst : S4(write); 4487 src1 : S3(read); 4488 src2 : S3(read); 4489 DECODE : S0(3); // any 3 decoders 4490 FPU : S3(2); 4491 %} 4492 4493 // Float reg-reg operation 4494 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4495 %{ 4496 instruction_count(4); 4497 dst : S4(write); 4498 src1 : S3(read); 4499 src2 : S3(read); 4500 src3 : S3(read); 4501 DECODE : S0(4); // any 3 decoders 4502 FPU : S3(2); 4503 %} 4504 4505 // Float reg-reg operation 4506 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4507 %{ 4508 instruction_count(4); 4509 dst : S4(write); 4510 src1 : S3(read); 4511 src2 : S3(read); 4512 src3 : S3(read); 4513 DECODE : S1(3); // any 3 decoders 4514 D0 : S0; // Big decoder only 4515 FPU : S3(2); 4516 MEM : S3; 4517 %} 4518 4519 // Float reg-mem operation 4520 pipe_class fpu_reg_mem(regD dst, memory mem) 4521 %{ 4522 instruction_count(2); 4523 dst : S5(write); 4524 mem : S3(read); 4525 D0 : S0; // big decoder only 4526 DECODE : S1; // any decoder for FPU POP 4527 FPU : S4; 4528 MEM : S3; // any mem 4529 %} 4530 4531 // Float reg-mem operation 4532 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4533 %{ 4534 instruction_count(3); 4535 dst : S5(write); 4536 src1 : S3(read); 4537 mem : S3(read); 4538 D0 : S0; // big decoder only 4539 DECODE : S1(2); // any decoder for FPU POP 4540 FPU : S4; 4541 MEM : S3; // any mem 4542 %} 4543 4544 // Float mem-reg operation 4545 pipe_class fpu_mem_reg(memory mem, regD src) 4546 %{ 4547 instruction_count(2); 4548 src : S5(read); 4549 mem : S3(read); 4550 DECODE : S0; // any decoder for FPU PUSH 4551 D0 : S1; // big decoder only 4552 FPU : S4; 4553 MEM : S3; // any mem 4554 %} 4555 4556 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4557 %{ 4558 instruction_count(3); 4559 src1 : S3(read); 4560 src2 : S3(read); 4561 mem : S3(read); 4562 DECODE : S0(2); // any decoder for FPU PUSH 4563 D0 : S1; // big decoder only 4564 FPU : S4; 4565 MEM : S3; // any mem 4566 %} 4567 4568 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4569 %{ 4570 instruction_count(3); 4571 src1 : S3(read); 4572 src2 : S3(read); 4573 mem : S4(read); 4574 DECODE : S0; // any decoder for FPU PUSH 4575 D0 : S0(2); // big decoder only 4576 FPU : S4; 4577 MEM : S3(2); // any mem 4578 %} 4579 4580 pipe_class fpu_mem_mem(memory dst, memory src1) 4581 %{ 4582 instruction_count(2); 4583 src1 : S3(read); 4584 dst : S4(read); 4585 D0 : S0(2); // big decoder only 4586 MEM : S3(2); // any mem 4587 %} 4588 4589 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4590 %{ 4591 instruction_count(3); 4592 src1 : S3(read); 4593 src2 : S3(read); 4594 dst : S4(read); 4595 D0 : S0(3); // big decoder only 4596 FPU : S4; 4597 MEM : S3(3); // any mem 4598 %} 4599 4600 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4601 %{ 4602 instruction_count(3); 4603 src1 : S4(read); 4604 mem : S4(read); 4605 DECODE : S0; // any decoder for FPU PUSH 4606 D0 : S0(2); // big decoder only 4607 FPU : S4; 4608 MEM : S3(2); // any mem 4609 %} 4610 4611 // Float load constant 4612 pipe_class fpu_reg_con(regD dst) 4613 %{ 4614 instruction_count(2); 4615 dst : S5(write); 4616 D0 : S0; // big decoder only for the load 4617 DECODE : S1; // any decoder for FPU POP 4618 FPU : S4; 4619 MEM : S3; // any mem 4620 %} 4621 4622 // Float load constant 4623 pipe_class fpu_reg_reg_con(regD dst, regD src) 4624 %{ 4625 instruction_count(3); 4626 dst : S5(write); 4627 src : S3(read); 4628 D0 : S0; // big decoder only for the load 4629 DECODE : S1(2); // any decoder for FPU POP 4630 FPU : S4; 4631 MEM : S3; // any mem 4632 %} 4633 4634 // UnConditional branch 4635 pipe_class pipe_jmp(label labl) 4636 %{ 4637 single_instruction; 4638 BR : S3; 4639 %} 4640 4641 // Conditional branch 4642 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4643 %{ 4644 single_instruction; 4645 cr : S1(read); 4646 BR : S3; 4647 %} 4648 4649 // Allocation idiom 4650 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4651 %{ 4652 instruction_count(1); force_serialization; 4653 fixed_latency(6); 4654 heap_ptr : S3(read); 4655 DECODE : S0(3); 4656 D0 : S2; 4657 MEM : S3; 4658 ALU : S3(2); 4659 dst : S5(write); 4660 BR : S5; 4661 %} 4662 4663 // Generic big/slow expanded idiom 4664 pipe_class pipe_slow() 4665 %{ 4666 instruction_count(10); multiple_bundles; force_serialization; 4667 fixed_latency(100); 4668 D0 : S0(2); 4669 MEM : S3(2); 4670 %} 4671 4672 // The real do-nothing guy 4673 pipe_class empty() 4674 %{ 4675 instruction_count(0); 4676 %} 4677 4678 // Define the class for the Nop node 4679 define 4680 %{ 4681 MachNop = empty; 4682 %} 4683 4684 %} 4685 4686 //----------INSTRUCTIONS------------------------------------------------------- 4687 // 4688 // match -- States which machine-independent subtree may be replaced 4689 // by this instruction. 4690 // ins_cost -- The estimated cost of this instruction is used by instruction 4691 // selection to identify a minimum cost tree of machine 4692 // instructions that matches a tree of machine-independent 4693 // instructions. 4694 // format -- A string providing the disassembly for this instruction. 4695 // The value of an instruction's operand may be inserted 4696 // by referring to it with a '$' prefix. 4697 // opcode -- Three instruction opcodes may be provided. These are referred 4698 // to within an encode class as $primary, $secondary, and $tertiary 4699 // rrspectively. The primary opcode is commonly used to 4700 // indicate the type of machine instruction, while secondary 4701 // and tertiary are often used for prefix options or addressing 4702 // modes. 4703 // ins_encode -- A list of encode classes with parameters. The encode class 4704 // name must have been defined in an 'enc_class' specification 4705 // in the encode section of the architecture description. 4706 4707 4708 //----------Load/Store/Move Instructions--------------------------------------- 4709 //----------Load Instructions-------------------------------------------------- 4710 4711 // Load Byte (8 bit signed) 4712 instruct loadB(rRegI dst, memory mem) 4713 %{ 4714 match(Set dst (LoadB mem)); 4715 4716 ins_cost(125); 4717 format %{ "movsbl $dst, $mem\t# byte" %} 4718 4719 ins_encode %{ 4720 __ movsbl($dst$$Register, $mem$$Address); 4721 %} 4722 4723 ins_pipe(ialu_reg_mem); 4724 %} 4725 4726 // Load Byte (8 bit signed) into Long Register 4727 instruct loadB2L(rRegL dst, memory mem) 4728 %{ 4729 match(Set dst (ConvI2L (LoadB mem))); 4730 4731 ins_cost(125); 4732 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4733 4734 ins_encode %{ 4735 __ movsbq($dst$$Register, $mem$$Address); 4736 %} 4737 4738 ins_pipe(ialu_reg_mem); 4739 %} 4740 4741 // Load Unsigned Byte (8 bit UNsigned) 4742 instruct loadUB(rRegI dst, memory mem) 4743 %{ 4744 match(Set dst (LoadUB mem)); 4745 4746 ins_cost(125); 4747 format %{ "movzbl $dst, $mem\t# ubyte" %} 4748 4749 ins_encode %{ 4750 __ movzbl($dst$$Register, $mem$$Address); 4751 %} 4752 4753 ins_pipe(ialu_reg_mem); 4754 %} 4755 4756 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4757 instruct loadUB2L(rRegL dst, memory mem) 4758 %{ 4759 match(Set dst (ConvI2L (LoadUB mem))); 4760 4761 ins_cost(125); 4762 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4763 4764 ins_encode %{ 4765 __ movzbq($dst$$Register, $mem$$Address); 4766 %} 4767 4768 ins_pipe(ialu_reg_mem); 4769 %} 4770 4771 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4772 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4773 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4774 effect(KILL cr); 4775 4776 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4777 "andl $dst, right_n_bits($mask, 8)" %} 4778 ins_encode %{ 4779 Register Rdst = $dst$$Register; 4780 __ movzbq(Rdst, $mem$$Address); 4781 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4782 %} 4783 ins_pipe(ialu_reg_mem); 4784 %} 4785 4786 // Load Short (16 bit signed) 4787 instruct loadS(rRegI dst, memory mem) 4788 %{ 4789 match(Set dst (LoadS mem)); 4790 4791 ins_cost(125); 4792 format %{ "movswl $dst, $mem\t# short" %} 4793 4794 ins_encode %{ 4795 __ movswl($dst$$Register, $mem$$Address); 4796 %} 4797 4798 ins_pipe(ialu_reg_mem); 4799 %} 4800 4801 // Load Short (16 bit signed) to Byte (8 bit signed) 4802 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4803 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4804 4805 ins_cost(125); 4806 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4807 ins_encode %{ 4808 __ movsbl($dst$$Register, $mem$$Address); 4809 %} 4810 ins_pipe(ialu_reg_mem); 4811 %} 4812 4813 // Load Short (16 bit signed) into Long Register 4814 instruct loadS2L(rRegL dst, memory mem) 4815 %{ 4816 match(Set dst (ConvI2L (LoadS mem))); 4817 4818 ins_cost(125); 4819 format %{ "movswq $dst, $mem\t# short -> long" %} 4820 4821 ins_encode %{ 4822 __ movswq($dst$$Register, $mem$$Address); 4823 %} 4824 4825 ins_pipe(ialu_reg_mem); 4826 %} 4827 4828 // Load Unsigned Short/Char (16 bit UNsigned) 4829 instruct loadUS(rRegI dst, memory mem) 4830 %{ 4831 match(Set dst (LoadUS mem)); 4832 4833 ins_cost(125); 4834 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4835 4836 ins_encode %{ 4837 __ movzwl($dst$$Register, $mem$$Address); 4838 %} 4839 4840 ins_pipe(ialu_reg_mem); 4841 %} 4842 4843 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4844 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4845 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4846 4847 ins_cost(125); 4848 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4849 ins_encode %{ 4850 __ movsbl($dst$$Register, $mem$$Address); 4851 %} 4852 ins_pipe(ialu_reg_mem); 4853 %} 4854 4855 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4856 instruct loadUS2L(rRegL dst, memory mem) 4857 %{ 4858 match(Set dst (ConvI2L (LoadUS mem))); 4859 4860 ins_cost(125); 4861 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4862 4863 ins_encode %{ 4864 __ movzwq($dst$$Register, $mem$$Address); 4865 %} 4866 4867 ins_pipe(ialu_reg_mem); 4868 %} 4869 4870 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4871 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4872 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4873 4874 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4875 ins_encode %{ 4876 __ movzbq($dst$$Register, $mem$$Address); 4877 %} 4878 ins_pipe(ialu_reg_mem); 4879 %} 4880 4881 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4882 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4883 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4884 effect(KILL cr); 4885 4886 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4887 "andl $dst, right_n_bits($mask, 16)" %} 4888 ins_encode %{ 4889 Register Rdst = $dst$$Register; 4890 __ movzwq(Rdst, $mem$$Address); 4891 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4892 %} 4893 ins_pipe(ialu_reg_mem); 4894 %} 4895 4896 // Load Integer 4897 instruct loadI(rRegI dst, memory mem) 4898 %{ 4899 match(Set dst (LoadI mem)); 4900 4901 ins_cost(125); 4902 format %{ "movl $dst, $mem\t# int" %} 4903 4904 ins_encode %{ 4905 __ movl($dst$$Register, $mem$$Address); 4906 %} 4907 4908 ins_pipe(ialu_reg_mem); 4909 %} 4910 4911 // Load Integer (32 bit signed) to Byte (8 bit signed) 4912 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4913 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4914 4915 ins_cost(125); 4916 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4917 ins_encode %{ 4918 __ movsbl($dst$$Register, $mem$$Address); 4919 %} 4920 ins_pipe(ialu_reg_mem); 4921 %} 4922 4923 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4924 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4925 match(Set dst (AndI (LoadI mem) mask)); 4926 4927 ins_cost(125); 4928 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4929 ins_encode %{ 4930 __ movzbl($dst$$Register, $mem$$Address); 4931 %} 4932 ins_pipe(ialu_reg_mem); 4933 %} 4934 4935 // Load Integer (32 bit signed) to Short (16 bit signed) 4936 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4937 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4938 4939 ins_cost(125); 4940 format %{ "movswl $dst, $mem\t# int -> short" %} 4941 ins_encode %{ 4942 __ movswl($dst$$Register, $mem$$Address); 4943 %} 4944 ins_pipe(ialu_reg_mem); 4945 %} 4946 4947 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4948 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4949 match(Set dst (AndI (LoadI mem) mask)); 4950 4951 ins_cost(125); 4952 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4953 ins_encode %{ 4954 __ movzwl($dst$$Register, $mem$$Address); 4955 %} 4956 ins_pipe(ialu_reg_mem); 4957 %} 4958 4959 // Load Integer into Long Register 4960 instruct loadI2L(rRegL dst, memory mem) 4961 %{ 4962 match(Set dst (ConvI2L (LoadI mem))); 4963 4964 ins_cost(125); 4965 format %{ "movslq $dst, $mem\t# int -> long" %} 4966 4967 ins_encode %{ 4968 __ movslq($dst$$Register, $mem$$Address); 4969 %} 4970 4971 ins_pipe(ialu_reg_mem); 4972 %} 4973 4974 // Load Integer with mask 0xFF into Long Register 4975 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4976 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4977 4978 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4979 ins_encode %{ 4980 __ movzbq($dst$$Register, $mem$$Address); 4981 %} 4982 ins_pipe(ialu_reg_mem); 4983 %} 4984 4985 // Load Integer with mask 0xFFFF into Long Register 4986 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4987 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4988 4989 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4990 ins_encode %{ 4991 __ movzwq($dst$$Register, $mem$$Address); 4992 %} 4993 ins_pipe(ialu_reg_mem); 4994 %} 4995 4996 // Load Integer with a 31-bit mask into Long Register 4997 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4998 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4999 effect(KILL cr); 5000 5001 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5002 "andl $dst, $mask" %} 5003 ins_encode %{ 5004 Register Rdst = $dst$$Register; 5005 __ movl(Rdst, $mem$$Address); 5006 __ andl(Rdst, $mask$$constant); 5007 %} 5008 ins_pipe(ialu_reg_mem); 5009 %} 5010 5011 // Load Unsigned Integer into Long Register 5012 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5013 %{ 5014 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5015 5016 ins_cost(125); 5017 format %{ "movl $dst, $mem\t# uint -> long" %} 5018 5019 ins_encode %{ 5020 __ movl($dst$$Register, $mem$$Address); 5021 %} 5022 5023 ins_pipe(ialu_reg_mem); 5024 %} 5025 5026 // Load Long 5027 instruct loadL(rRegL dst, memory mem) 5028 %{ 5029 match(Set dst (LoadL mem)); 5030 5031 ins_cost(125); 5032 format %{ "movq $dst, $mem\t# long" %} 5033 5034 ins_encode %{ 5035 __ movq($dst$$Register, $mem$$Address); 5036 %} 5037 5038 ins_pipe(ialu_reg_mem); // XXX 5039 %} 5040 5041 // Load Range 5042 instruct loadRange(rRegI dst, memory mem) 5043 %{ 5044 match(Set dst (LoadRange mem)); 5045 5046 ins_cost(125); // XXX 5047 format %{ "movl $dst, $mem\t# range" %} 5048 opcode(0x8B); 5049 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5050 ins_pipe(ialu_reg_mem); 5051 %} 5052 5053 // Load Pointer 5054 instruct loadP(rRegP dst, memory mem) 5055 %{ 5056 match(Set dst (LoadP mem)); 5057 5058 ins_cost(125); // XXX 5059 format %{ "movq $dst, $mem\t# ptr" %} 5060 opcode(0x8B); 5061 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5062 ins_pipe(ialu_reg_mem); // XXX 5063 %} 5064 5065 // Load Compressed Pointer 5066 instruct loadN(rRegN dst, memory mem) 5067 %{ 5068 match(Set dst (LoadN mem)); 5069 5070 ins_cost(125); // XXX 5071 format %{ "movl $dst, $mem\t# compressed ptr" %} 5072 ins_encode %{ 5073 __ movl($dst$$Register, $mem$$Address); 5074 %} 5075 ins_pipe(ialu_reg_mem); // XXX 5076 %} 5077 5078 5079 // Load Klass Pointer 5080 instruct loadKlass(rRegP dst, memory mem) 5081 %{ 5082 match(Set dst (LoadKlass mem)); 5083 5084 ins_cost(125); // XXX 5085 format %{ "movq $dst, $mem\t# class" %} 5086 opcode(0x8B); 5087 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5088 ins_pipe(ialu_reg_mem); // XXX 5089 %} 5090 5091 // Load narrow Klass Pointer 5092 instruct loadNKlass(rRegN dst, memory mem) 5093 %{ 5094 match(Set dst (LoadNKlass mem)); 5095 5096 ins_cost(125); // XXX 5097 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5098 ins_encode %{ 5099 __ movl($dst$$Register, $mem$$Address); 5100 %} 5101 ins_pipe(ialu_reg_mem); // XXX 5102 %} 5103 5104 // Load Float 5105 instruct loadF(regF dst, memory mem) 5106 %{ 5107 match(Set dst (LoadF mem)); 5108 5109 ins_cost(145); // XXX 5110 format %{ "movss $dst, $mem\t# float" %} 5111 ins_encode %{ 5112 __ movflt($dst$$XMMRegister, $mem$$Address); 5113 %} 5114 ins_pipe(pipe_slow); // XXX 5115 %} 5116 5117 // Load Double 5118 instruct loadD_partial(regD dst, memory mem) 5119 %{ 5120 predicate(!UseXmmLoadAndClearUpper); 5121 match(Set dst (LoadD mem)); 5122 5123 ins_cost(145); // XXX 5124 format %{ "movlpd $dst, $mem\t# double" %} 5125 ins_encode %{ 5126 __ movdbl($dst$$XMMRegister, $mem$$Address); 5127 %} 5128 ins_pipe(pipe_slow); // XXX 5129 %} 5130 5131 instruct loadD(regD dst, memory mem) 5132 %{ 5133 predicate(UseXmmLoadAndClearUpper); 5134 match(Set dst (LoadD mem)); 5135 5136 ins_cost(145); // XXX 5137 format %{ "movsd $dst, $mem\t# double" %} 5138 ins_encode %{ 5139 __ movdbl($dst$$XMMRegister, $mem$$Address); 5140 %} 5141 ins_pipe(pipe_slow); // XXX 5142 %} 5143 5144 // Load Effective Address 5145 instruct leaP8(rRegP dst, indOffset8 mem) 5146 %{ 5147 match(Set dst mem); 5148 5149 ins_cost(110); // XXX 5150 format %{ "leaq $dst, $mem\t# ptr 8" %} 5151 opcode(0x8D); 5152 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5153 ins_pipe(ialu_reg_reg_fat); 5154 %} 5155 5156 instruct leaP32(rRegP dst, indOffset32 mem) 5157 %{ 5158 match(Set dst mem); 5159 5160 ins_cost(110); 5161 format %{ "leaq $dst, $mem\t# ptr 32" %} 5162 opcode(0x8D); 5163 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5164 ins_pipe(ialu_reg_reg_fat); 5165 %} 5166 5167 // instruct leaPIdx(rRegP dst, indIndex mem) 5168 // %{ 5169 // match(Set dst mem); 5170 5171 // ins_cost(110); 5172 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5173 // opcode(0x8D); 5174 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5175 // ins_pipe(ialu_reg_reg_fat); 5176 // %} 5177 5178 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5179 %{ 5180 match(Set dst mem); 5181 5182 ins_cost(110); 5183 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5184 opcode(0x8D); 5185 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5186 ins_pipe(ialu_reg_reg_fat); 5187 %} 5188 5189 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5190 %{ 5191 match(Set dst mem); 5192 5193 ins_cost(110); 5194 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5195 opcode(0x8D); 5196 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5197 ins_pipe(ialu_reg_reg_fat); 5198 %} 5199 5200 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5201 %{ 5202 match(Set dst mem); 5203 5204 ins_cost(110); 5205 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5206 opcode(0x8D); 5207 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5208 ins_pipe(ialu_reg_reg_fat); 5209 %} 5210 5211 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5212 %{ 5213 match(Set dst mem); 5214 5215 ins_cost(110); 5216 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5217 opcode(0x8D); 5218 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5219 ins_pipe(ialu_reg_reg_fat); 5220 %} 5221 5222 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5223 %{ 5224 match(Set dst mem); 5225 5226 ins_cost(110); 5227 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5228 opcode(0x8D); 5229 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5230 ins_pipe(ialu_reg_reg_fat); 5231 %} 5232 5233 // Load Effective Address which uses Narrow (32-bits) oop 5234 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5235 %{ 5236 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5237 match(Set dst mem); 5238 5239 ins_cost(110); 5240 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5241 opcode(0x8D); 5242 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5243 ins_pipe(ialu_reg_reg_fat); 5244 %} 5245 5246 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5247 %{ 5248 predicate(Universe::narrow_oop_shift() == 0); 5249 match(Set dst mem); 5250 5251 ins_cost(110); // XXX 5252 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5253 opcode(0x8D); 5254 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5255 ins_pipe(ialu_reg_reg_fat); 5256 %} 5257 5258 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5259 %{ 5260 predicate(Universe::narrow_oop_shift() == 0); 5261 match(Set dst mem); 5262 5263 ins_cost(110); 5264 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5265 opcode(0x8D); 5266 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5267 ins_pipe(ialu_reg_reg_fat); 5268 %} 5269 5270 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5271 %{ 5272 predicate(Universe::narrow_oop_shift() == 0); 5273 match(Set dst mem); 5274 5275 ins_cost(110); 5276 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5277 opcode(0x8D); 5278 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5279 ins_pipe(ialu_reg_reg_fat); 5280 %} 5281 5282 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5283 %{ 5284 predicate(Universe::narrow_oop_shift() == 0); 5285 match(Set dst mem); 5286 5287 ins_cost(110); 5288 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5289 opcode(0x8D); 5290 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5291 ins_pipe(ialu_reg_reg_fat); 5292 %} 5293 5294 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5295 %{ 5296 predicate(Universe::narrow_oop_shift() == 0); 5297 match(Set dst mem); 5298 5299 ins_cost(110); 5300 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5301 opcode(0x8D); 5302 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5303 ins_pipe(ialu_reg_reg_fat); 5304 %} 5305 5306 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5307 %{ 5308 predicate(Universe::narrow_oop_shift() == 0); 5309 match(Set dst mem); 5310 5311 ins_cost(110); 5312 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5313 opcode(0x8D); 5314 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5315 ins_pipe(ialu_reg_reg_fat); 5316 %} 5317 5318 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5319 %{ 5320 predicate(Universe::narrow_oop_shift() == 0); 5321 match(Set dst mem); 5322 5323 ins_cost(110); 5324 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5325 opcode(0x8D); 5326 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5327 ins_pipe(ialu_reg_reg_fat); 5328 %} 5329 5330 instruct loadConI(rRegI dst, immI src) 5331 %{ 5332 match(Set dst src); 5333 5334 format %{ "movl $dst, $src\t# int" %} 5335 ins_encode(load_immI(dst, src)); 5336 ins_pipe(ialu_reg_fat); // XXX 5337 %} 5338 5339 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5340 %{ 5341 match(Set dst src); 5342 effect(KILL cr); 5343 5344 ins_cost(50); 5345 format %{ "xorl $dst, $dst\t# int" %} 5346 opcode(0x33); /* + rd */ 5347 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5348 ins_pipe(ialu_reg); 5349 %} 5350 5351 instruct loadConL(rRegL dst, immL src) 5352 %{ 5353 match(Set dst src); 5354 5355 ins_cost(150); 5356 format %{ "movq $dst, $src\t# long" %} 5357 ins_encode(load_immL(dst, src)); 5358 ins_pipe(ialu_reg); 5359 %} 5360 5361 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5362 %{ 5363 match(Set dst src); 5364 effect(KILL cr); 5365 5366 ins_cost(50); 5367 format %{ "xorl $dst, $dst\t# long" %} 5368 opcode(0x33); /* + rd */ 5369 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5370 ins_pipe(ialu_reg); // XXX 5371 %} 5372 5373 instruct loadConUL32(rRegL dst, immUL32 src) 5374 %{ 5375 match(Set dst src); 5376 5377 ins_cost(60); 5378 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5379 ins_encode(load_immUL32(dst, src)); 5380 ins_pipe(ialu_reg); 5381 %} 5382 5383 instruct loadConL32(rRegL dst, immL32 src) 5384 %{ 5385 match(Set dst src); 5386 5387 ins_cost(70); 5388 format %{ "movq $dst, $src\t# long (32-bit)" %} 5389 ins_encode(load_immL32(dst, src)); 5390 ins_pipe(ialu_reg); 5391 %} 5392 5393 instruct loadConP(rRegP dst, immP con) %{ 5394 match(Set dst con); 5395 5396 format %{ "movq $dst, $con\t# ptr" %} 5397 ins_encode(load_immP(dst, con)); 5398 ins_pipe(ialu_reg_fat); // XXX 5399 %} 5400 5401 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5402 %{ 5403 match(Set dst src); 5404 effect(KILL cr); 5405 5406 ins_cost(50); 5407 format %{ "xorl $dst, $dst\t# ptr" %} 5408 opcode(0x33); /* + rd */ 5409 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5410 ins_pipe(ialu_reg); 5411 %} 5412 5413 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5414 %{ 5415 match(Set dst src); 5416 effect(KILL cr); 5417 5418 ins_cost(60); 5419 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5420 ins_encode(load_immP31(dst, src)); 5421 ins_pipe(ialu_reg); 5422 %} 5423 5424 instruct loadConF(regF dst, immF con) %{ 5425 match(Set dst con); 5426 ins_cost(125); 5427 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5428 ins_encode %{ 5429 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5430 %} 5431 ins_pipe(pipe_slow); 5432 %} 5433 5434 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5435 match(Set dst src); 5436 effect(KILL cr); 5437 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5438 ins_encode %{ 5439 __ xorq($dst$$Register, $dst$$Register); 5440 %} 5441 ins_pipe(ialu_reg); 5442 %} 5443 5444 instruct loadConN(rRegN dst, immN src) %{ 5445 match(Set dst src); 5446 5447 ins_cost(125); 5448 format %{ "movl $dst, $src\t# compressed ptr" %} 5449 ins_encode %{ 5450 address con = (address)$src$$constant; 5451 if (con == NULL) { 5452 ShouldNotReachHere(); 5453 } else { 5454 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5455 } 5456 %} 5457 ins_pipe(ialu_reg_fat); // XXX 5458 %} 5459 5460 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5461 match(Set dst src); 5462 5463 ins_cost(125); 5464 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5465 ins_encode %{ 5466 address con = (address)$src$$constant; 5467 if (con == NULL) { 5468 ShouldNotReachHere(); 5469 } else { 5470 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5471 } 5472 %} 5473 ins_pipe(ialu_reg_fat); // XXX 5474 %} 5475 5476 instruct loadConF0(regF dst, immF0 src) 5477 %{ 5478 match(Set dst src); 5479 ins_cost(100); 5480 5481 format %{ "xorps $dst, $dst\t# float 0.0" %} 5482 ins_encode %{ 5483 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5484 %} 5485 ins_pipe(pipe_slow); 5486 %} 5487 5488 // Use the same format since predicate() can not be used here. 5489 instruct loadConD(regD dst, immD con) %{ 5490 match(Set dst con); 5491 ins_cost(125); 5492 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5493 ins_encode %{ 5494 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5495 %} 5496 ins_pipe(pipe_slow); 5497 %} 5498 5499 instruct loadConD0(regD dst, immD0 src) 5500 %{ 5501 match(Set dst src); 5502 ins_cost(100); 5503 5504 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5505 ins_encode %{ 5506 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5507 %} 5508 ins_pipe(pipe_slow); 5509 %} 5510 5511 instruct loadSSI(rRegI dst, stackSlotI src) 5512 %{ 5513 match(Set dst src); 5514 5515 ins_cost(125); 5516 format %{ "movl $dst, $src\t# int stk" %} 5517 opcode(0x8B); 5518 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5519 ins_pipe(ialu_reg_mem); 5520 %} 5521 5522 instruct loadSSL(rRegL dst, stackSlotL src) 5523 %{ 5524 match(Set dst src); 5525 5526 ins_cost(125); 5527 format %{ "movq $dst, $src\t# long stk" %} 5528 opcode(0x8B); 5529 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5530 ins_pipe(ialu_reg_mem); 5531 %} 5532 5533 instruct loadSSP(rRegP dst, stackSlotP src) 5534 %{ 5535 match(Set dst src); 5536 5537 ins_cost(125); 5538 format %{ "movq $dst, $src\t# ptr stk" %} 5539 opcode(0x8B); 5540 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5541 ins_pipe(ialu_reg_mem); 5542 %} 5543 5544 instruct loadSSF(regF dst, stackSlotF src) 5545 %{ 5546 match(Set dst src); 5547 5548 ins_cost(125); 5549 format %{ "movss $dst, $src\t# float stk" %} 5550 ins_encode %{ 5551 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5552 %} 5553 ins_pipe(pipe_slow); // XXX 5554 %} 5555 5556 // Use the same format since predicate() can not be used here. 5557 instruct loadSSD(regD dst, stackSlotD src) 5558 %{ 5559 match(Set dst src); 5560 5561 ins_cost(125); 5562 format %{ "movsd $dst, $src\t# double stk" %} 5563 ins_encode %{ 5564 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5565 %} 5566 ins_pipe(pipe_slow); // XXX 5567 %} 5568 5569 // Prefetch instructions for allocation. 5570 // Must be safe to execute with invalid address (cannot fault). 5571 5572 instruct prefetchAlloc( memory mem ) %{ 5573 predicate(AllocatePrefetchInstr==3); 5574 match(PrefetchAllocation mem); 5575 ins_cost(125); 5576 5577 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5578 ins_encode %{ 5579 __ prefetchw($mem$$Address); 5580 %} 5581 ins_pipe(ialu_mem); 5582 %} 5583 5584 instruct prefetchAllocNTA( memory mem ) %{ 5585 predicate(AllocatePrefetchInstr==0); 5586 match(PrefetchAllocation mem); 5587 ins_cost(125); 5588 5589 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5590 ins_encode %{ 5591 __ prefetchnta($mem$$Address); 5592 %} 5593 ins_pipe(ialu_mem); 5594 %} 5595 5596 instruct prefetchAllocT0( memory mem ) %{ 5597 predicate(AllocatePrefetchInstr==1); 5598 match(PrefetchAllocation mem); 5599 ins_cost(125); 5600 5601 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5602 ins_encode %{ 5603 __ prefetcht0($mem$$Address); 5604 %} 5605 ins_pipe(ialu_mem); 5606 %} 5607 5608 instruct prefetchAllocT2( memory mem ) %{ 5609 predicate(AllocatePrefetchInstr==2); 5610 match(PrefetchAllocation mem); 5611 ins_cost(125); 5612 5613 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5614 ins_encode %{ 5615 __ prefetcht2($mem$$Address); 5616 %} 5617 ins_pipe(ialu_mem); 5618 %} 5619 5620 //----------Store Instructions------------------------------------------------- 5621 5622 // Store Byte 5623 instruct storeB(memory mem, rRegI src) 5624 %{ 5625 match(Set mem (StoreB mem src)); 5626 5627 ins_cost(125); // XXX 5628 format %{ "movb $mem, $src\t# byte" %} 5629 opcode(0x88); 5630 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5631 ins_pipe(ialu_mem_reg); 5632 %} 5633 5634 // Store Char/Short 5635 instruct storeC(memory mem, rRegI src) 5636 %{ 5637 match(Set mem (StoreC mem src)); 5638 5639 ins_cost(125); // XXX 5640 format %{ "movw $mem, $src\t# char/short" %} 5641 opcode(0x89); 5642 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5643 ins_pipe(ialu_mem_reg); 5644 %} 5645 5646 // Store Integer 5647 instruct storeI(memory mem, rRegI src) 5648 %{ 5649 match(Set mem (StoreI mem src)); 5650 5651 ins_cost(125); // XXX 5652 format %{ "movl $mem, $src\t# int" %} 5653 opcode(0x89); 5654 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5655 ins_pipe(ialu_mem_reg); 5656 %} 5657 5658 // Store Long 5659 instruct storeL(memory mem, rRegL src) 5660 %{ 5661 match(Set mem (StoreL mem src)); 5662 5663 ins_cost(125); // XXX 5664 format %{ "movq $mem, $src\t# long" %} 5665 opcode(0x89); 5666 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5667 ins_pipe(ialu_mem_reg); // XXX 5668 %} 5669 5670 // Store Pointer 5671 instruct storeP(memory mem, any_RegP src) 5672 %{ 5673 match(Set mem (StoreP mem src)); 5674 5675 ins_cost(125); // XXX 5676 format %{ "movq $mem, $src\t# ptr" %} 5677 opcode(0x89); 5678 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5679 ins_pipe(ialu_mem_reg); 5680 %} 5681 5682 instruct storeImmP0(memory mem, immP0 zero) 5683 %{ 5684 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5685 match(Set mem (StoreP mem zero)); 5686 5687 ins_cost(125); // XXX 5688 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5689 ins_encode %{ 5690 __ movq($mem$$Address, r12); 5691 %} 5692 ins_pipe(ialu_mem_reg); 5693 %} 5694 5695 // Store NULL Pointer, mark word, or other simple pointer constant. 5696 instruct storeImmP(memory mem, immP31 src) 5697 %{ 5698 match(Set mem (StoreP mem src)); 5699 5700 ins_cost(150); // XXX 5701 format %{ "movq $mem, $src\t# ptr" %} 5702 opcode(0xC7); /* C7 /0 */ 5703 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5704 ins_pipe(ialu_mem_imm); 5705 %} 5706 5707 // Store Compressed Pointer 5708 instruct storeN(memory mem, rRegN src) 5709 %{ 5710 match(Set mem (StoreN mem src)); 5711 5712 ins_cost(125); // XXX 5713 format %{ "movl $mem, $src\t# compressed ptr" %} 5714 ins_encode %{ 5715 __ movl($mem$$Address, $src$$Register); 5716 %} 5717 ins_pipe(ialu_mem_reg); 5718 %} 5719 5720 instruct storeNKlass(memory mem, rRegN src) 5721 %{ 5722 match(Set mem (StoreNKlass mem src)); 5723 5724 ins_cost(125); // XXX 5725 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5726 ins_encode %{ 5727 __ movl($mem$$Address, $src$$Register); 5728 %} 5729 ins_pipe(ialu_mem_reg); 5730 %} 5731 5732 instruct storeImmN0(memory mem, immN0 zero) 5733 %{ 5734 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5735 match(Set mem (StoreN mem zero)); 5736 5737 ins_cost(125); // XXX 5738 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5739 ins_encode %{ 5740 __ movl($mem$$Address, r12); 5741 %} 5742 ins_pipe(ialu_mem_reg); 5743 %} 5744 5745 instruct storeImmN(memory mem, immN src) 5746 %{ 5747 match(Set mem (StoreN mem src)); 5748 5749 ins_cost(150); // XXX 5750 format %{ "movl $mem, $src\t# compressed ptr" %} 5751 ins_encode %{ 5752 address con = (address)$src$$constant; 5753 if (con == NULL) { 5754 __ movl($mem$$Address, (int32_t)0); 5755 } else { 5756 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5757 } 5758 %} 5759 ins_pipe(ialu_mem_imm); 5760 %} 5761 5762 instruct storeImmNKlass(memory mem, immNKlass src) 5763 %{ 5764 match(Set mem (StoreNKlass mem src)); 5765 5766 ins_cost(150); // XXX 5767 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5768 ins_encode %{ 5769 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5770 %} 5771 ins_pipe(ialu_mem_imm); 5772 %} 5773 5774 // Store Integer Immediate 5775 instruct storeImmI0(memory mem, immI0 zero) 5776 %{ 5777 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5778 match(Set mem (StoreI mem zero)); 5779 5780 ins_cost(125); // XXX 5781 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5782 ins_encode %{ 5783 __ movl($mem$$Address, r12); 5784 %} 5785 ins_pipe(ialu_mem_reg); 5786 %} 5787 5788 instruct storeImmI(memory mem, immI src) 5789 %{ 5790 match(Set mem (StoreI mem src)); 5791 5792 ins_cost(150); 5793 format %{ "movl $mem, $src\t# int" %} 5794 opcode(0xC7); /* C7 /0 */ 5795 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5796 ins_pipe(ialu_mem_imm); 5797 %} 5798 5799 // Store Long Immediate 5800 instruct storeImmL0(memory mem, immL0 zero) 5801 %{ 5802 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5803 match(Set mem (StoreL mem zero)); 5804 5805 ins_cost(125); // XXX 5806 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5807 ins_encode %{ 5808 __ movq($mem$$Address, r12); 5809 %} 5810 ins_pipe(ialu_mem_reg); 5811 %} 5812 5813 instruct storeImmL(memory mem, immL32 src) 5814 %{ 5815 match(Set mem (StoreL mem src)); 5816 5817 ins_cost(150); 5818 format %{ "movq $mem, $src\t# long" %} 5819 opcode(0xC7); /* C7 /0 */ 5820 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5821 ins_pipe(ialu_mem_imm); 5822 %} 5823 5824 // Store Short/Char Immediate 5825 instruct storeImmC0(memory mem, immI0 zero) 5826 %{ 5827 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5828 match(Set mem (StoreC mem zero)); 5829 5830 ins_cost(125); // XXX 5831 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5832 ins_encode %{ 5833 __ movw($mem$$Address, r12); 5834 %} 5835 ins_pipe(ialu_mem_reg); 5836 %} 5837 5838 instruct storeImmI16(memory mem, immI16 src) 5839 %{ 5840 predicate(UseStoreImmI16); 5841 match(Set mem (StoreC mem src)); 5842 5843 ins_cost(150); 5844 format %{ "movw $mem, $src\t# short/char" %} 5845 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 5846 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 5847 ins_pipe(ialu_mem_imm); 5848 %} 5849 5850 // Store Byte Immediate 5851 instruct storeImmB0(memory mem, immI0 zero) 5852 %{ 5853 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5854 match(Set mem (StoreB mem zero)); 5855 5856 ins_cost(125); // XXX 5857 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5858 ins_encode %{ 5859 __ movb($mem$$Address, r12); 5860 %} 5861 ins_pipe(ialu_mem_reg); 5862 %} 5863 5864 instruct storeImmB(memory mem, immI8 src) 5865 %{ 5866 match(Set mem (StoreB mem src)); 5867 5868 ins_cost(150); // XXX 5869 format %{ "movb $mem, $src\t# byte" %} 5870 opcode(0xC6); /* C6 /0 */ 5871 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5872 ins_pipe(ialu_mem_imm); 5873 %} 5874 5875 // Store CMS card-mark Immediate 5876 instruct storeImmCM0_reg(memory mem, immI0 zero) 5877 %{ 5878 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5879 match(Set mem (StoreCM mem zero)); 5880 5881 ins_cost(125); // XXX 5882 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5883 ins_encode %{ 5884 __ movb($mem$$Address, r12); 5885 %} 5886 ins_pipe(ialu_mem_reg); 5887 %} 5888 5889 instruct storeImmCM0(memory mem, immI0 src) 5890 %{ 5891 match(Set mem (StoreCM mem src)); 5892 5893 ins_cost(150); // XXX 5894 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5895 opcode(0xC6); /* C6 /0 */ 5896 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5897 ins_pipe(ialu_mem_imm); 5898 %} 5899 5900 // Store Float 5901 instruct storeF(memory mem, regF src) 5902 %{ 5903 match(Set mem (StoreF mem src)); 5904 5905 ins_cost(95); // XXX 5906 format %{ "movss $mem, $src\t# float" %} 5907 ins_encode %{ 5908 __ movflt($mem$$Address, $src$$XMMRegister); 5909 %} 5910 ins_pipe(pipe_slow); // XXX 5911 %} 5912 5913 // Store immediate Float value (it is faster than store from XMM register) 5914 instruct storeF0(memory mem, immF0 zero) 5915 %{ 5916 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5917 match(Set mem (StoreF mem zero)); 5918 5919 ins_cost(25); // XXX 5920 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5921 ins_encode %{ 5922 __ movl($mem$$Address, r12); 5923 %} 5924 ins_pipe(ialu_mem_reg); 5925 %} 5926 5927 instruct storeF_imm(memory mem, immF src) 5928 %{ 5929 match(Set mem (StoreF mem src)); 5930 5931 ins_cost(50); 5932 format %{ "movl $mem, $src\t# float" %} 5933 opcode(0xC7); /* C7 /0 */ 5934 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5935 ins_pipe(ialu_mem_imm); 5936 %} 5937 5938 // Store Double 5939 instruct storeD(memory mem, regD src) 5940 %{ 5941 match(Set mem (StoreD mem src)); 5942 5943 ins_cost(95); // XXX 5944 format %{ "movsd $mem, $src\t# double" %} 5945 ins_encode %{ 5946 __ movdbl($mem$$Address, $src$$XMMRegister); 5947 %} 5948 ins_pipe(pipe_slow); // XXX 5949 %} 5950 5951 // Store immediate double 0.0 (it is faster than store from XMM register) 5952 instruct storeD0_imm(memory mem, immD0 src) 5953 %{ 5954 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 5955 match(Set mem (StoreD mem src)); 5956 5957 ins_cost(50); 5958 format %{ "movq $mem, $src\t# double 0." %} 5959 opcode(0xC7); /* C7 /0 */ 5960 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5961 ins_pipe(ialu_mem_imm); 5962 %} 5963 5964 instruct storeD0(memory mem, immD0 zero) 5965 %{ 5966 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5967 match(Set mem (StoreD mem zero)); 5968 5969 ins_cost(25); // XXX 5970 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5971 ins_encode %{ 5972 __ movq($mem$$Address, r12); 5973 %} 5974 ins_pipe(ialu_mem_reg); 5975 %} 5976 5977 instruct storeSSI(stackSlotI dst, rRegI src) 5978 %{ 5979 match(Set dst src); 5980 5981 ins_cost(100); 5982 format %{ "movl $dst, $src\t# int stk" %} 5983 opcode(0x89); 5984 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 5985 ins_pipe( ialu_mem_reg ); 5986 %} 5987 5988 instruct storeSSL(stackSlotL dst, rRegL src) 5989 %{ 5990 match(Set dst src); 5991 5992 ins_cost(100); 5993 format %{ "movq $dst, $src\t# long stk" %} 5994 opcode(0x89); 5995 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 5996 ins_pipe(ialu_mem_reg); 5997 %} 5998 5999 instruct storeSSP(stackSlotP dst, rRegP src) 6000 %{ 6001 match(Set dst src); 6002 6003 ins_cost(100); 6004 format %{ "movq $dst, $src\t# ptr stk" %} 6005 opcode(0x89); 6006 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6007 ins_pipe(ialu_mem_reg); 6008 %} 6009 6010 instruct storeSSF(stackSlotF dst, regF src) 6011 %{ 6012 match(Set dst src); 6013 6014 ins_cost(95); // XXX 6015 format %{ "movss $dst, $src\t# float stk" %} 6016 ins_encode %{ 6017 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6018 %} 6019 ins_pipe(pipe_slow); // XXX 6020 %} 6021 6022 instruct storeSSD(stackSlotD dst, regD src) 6023 %{ 6024 match(Set dst src); 6025 6026 ins_cost(95); // XXX 6027 format %{ "movsd $dst, $src\t# double stk" %} 6028 ins_encode %{ 6029 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6030 %} 6031 ins_pipe(pipe_slow); // XXX 6032 %} 6033 6034 //----------BSWAP Instructions------------------------------------------------- 6035 instruct bytes_reverse_int(rRegI dst) %{ 6036 match(Set dst (ReverseBytesI dst)); 6037 6038 format %{ "bswapl $dst" %} 6039 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6040 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6041 ins_pipe( ialu_reg ); 6042 %} 6043 6044 instruct bytes_reverse_long(rRegL dst) %{ 6045 match(Set dst (ReverseBytesL dst)); 6046 6047 format %{ "bswapq $dst" %} 6048 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6049 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6050 ins_pipe( ialu_reg); 6051 %} 6052 6053 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6054 match(Set dst (ReverseBytesUS dst)); 6055 effect(KILL cr); 6056 6057 format %{ "bswapl $dst\n\t" 6058 "shrl $dst,16\n\t" %} 6059 ins_encode %{ 6060 __ bswapl($dst$$Register); 6061 __ shrl($dst$$Register, 16); 6062 %} 6063 ins_pipe( ialu_reg ); 6064 %} 6065 6066 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6067 match(Set dst (ReverseBytesS dst)); 6068 effect(KILL cr); 6069 6070 format %{ "bswapl $dst\n\t" 6071 "sar $dst,16\n\t" %} 6072 ins_encode %{ 6073 __ bswapl($dst$$Register); 6074 __ sarl($dst$$Register, 16); 6075 %} 6076 ins_pipe( ialu_reg ); 6077 %} 6078 6079 //---------- Zeros Count Instructions ------------------------------------------ 6080 6081 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6082 predicate(UseCountLeadingZerosInstruction); 6083 match(Set dst (CountLeadingZerosI src)); 6084 effect(KILL cr); 6085 6086 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6087 ins_encode %{ 6088 __ lzcntl($dst$$Register, $src$$Register); 6089 %} 6090 ins_pipe(ialu_reg); 6091 %} 6092 6093 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6094 predicate(!UseCountLeadingZerosInstruction); 6095 match(Set dst (CountLeadingZerosI src)); 6096 effect(KILL cr); 6097 6098 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6099 "jnz skip\n\t" 6100 "movl $dst, -1\n" 6101 "skip:\n\t" 6102 "negl $dst\n\t" 6103 "addl $dst, 31" %} 6104 ins_encode %{ 6105 Register Rdst = $dst$$Register; 6106 Register Rsrc = $src$$Register; 6107 Label skip; 6108 __ bsrl(Rdst, Rsrc); 6109 __ jccb(Assembler::notZero, skip); 6110 __ movl(Rdst, -1); 6111 __ bind(skip); 6112 __ negl(Rdst); 6113 __ addl(Rdst, BitsPerInt - 1); 6114 %} 6115 ins_pipe(ialu_reg); 6116 %} 6117 6118 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6119 predicate(UseCountLeadingZerosInstruction); 6120 match(Set dst (CountLeadingZerosL src)); 6121 effect(KILL cr); 6122 6123 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6124 ins_encode %{ 6125 __ lzcntq($dst$$Register, $src$$Register); 6126 %} 6127 ins_pipe(ialu_reg); 6128 %} 6129 6130 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6131 predicate(!UseCountLeadingZerosInstruction); 6132 match(Set dst (CountLeadingZerosL src)); 6133 effect(KILL cr); 6134 6135 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6136 "jnz skip\n\t" 6137 "movl $dst, -1\n" 6138 "skip:\n\t" 6139 "negl $dst\n\t" 6140 "addl $dst, 63" %} 6141 ins_encode %{ 6142 Register Rdst = $dst$$Register; 6143 Register Rsrc = $src$$Register; 6144 Label skip; 6145 __ bsrq(Rdst, Rsrc); 6146 __ jccb(Assembler::notZero, skip); 6147 __ movl(Rdst, -1); 6148 __ bind(skip); 6149 __ negl(Rdst); 6150 __ addl(Rdst, BitsPerLong - 1); 6151 %} 6152 ins_pipe(ialu_reg); 6153 %} 6154 6155 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6156 predicate(UseCountTrailingZerosInstruction); 6157 match(Set dst (CountTrailingZerosI src)); 6158 effect(KILL cr); 6159 6160 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6161 ins_encode %{ 6162 __ tzcntl($dst$$Register, $src$$Register); 6163 %} 6164 ins_pipe(ialu_reg); 6165 %} 6166 6167 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6168 predicate(!UseCountTrailingZerosInstruction); 6169 match(Set dst (CountTrailingZerosI src)); 6170 effect(KILL cr); 6171 6172 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6173 "jnz done\n\t" 6174 "movl $dst, 32\n" 6175 "done:" %} 6176 ins_encode %{ 6177 Register Rdst = $dst$$Register; 6178 Label done; 6179 __ bsfl(Rdst, $src$$Register); 6180 __ jccb(Assembler::notZero, done); 6181 __ movl(Rdst, BitsPerInt); 6182 __ bind(done); 6183 %} 6184 ins_pipe(ialu_reg); 6185 %} 6186 6187 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6188 predicate(UseCountTrailingZerosInstruction); 6189 match(Set dst (CountTrailingZerosL src)); 6190 effect(KILL cr); 6191 6192 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6193 ins_encode %{ 6194 __ tzcntq($dst$$Register, $src$$Register); 6195 %} 6196 ins_pipe(ialu_reg); 6197 %} 6198 6199 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6200 predicate(!UseCountTrailingZerosInstruction); 6201 match(Set dst (CountTrailingZerosL src)); 6202 effect(KILL cr); 6203 6204 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6205 "jnz done\n\t" 6206 "movl $dst, 64\n" 6207 "done:" %} 6208 ins_encode %{ 6209 Register Rdst = $dst$$Register; 6210 Label done; 6211 __ bsfq(Rdst, $src$$Register); 6212 __ jccb(Assembler::notZero, done); 6213 __ movl(Rdst, BitsPerLong); 6214 __ bind(done); 6215 %} 6216 ins_pipe(ialu_reg); 6217 %} 6218 6219 6220 //---------- Population Count Instructions ------------------------------------- 6221 6222 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6223 predicate(UsePopCountInstruction); 6224 match(Set dst (PopCountI src)); 6225 effect(KILL cr); 6226 6227 format %{ "popcnt $dst, $src" %} 6228 ins_encode %{ 6229 __ popcntl($dst$$Register, $src$$Register); 6230 %} 6231 ins_pipe(ialu_reg); 6232 %} 6233 6234 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6235 predicate(UsePopCountInstruction); 6236 match(Set dst (PopCountI (LoadI mem))); 6237 effect(KILL cr); 6238 6239 format %{ "popcnt $dst, $mem" %} 6240 ins_encode %{ 6241 __ popcntl($dst$$Register, $mem$$Address); 6242 %} 6243 ins_pipe(ialu_reg); 6244 %} 6245 6246 // Note: Long.bitCount(long) returns an int. 6247 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6248 predicate(UsePopCountInstruction); 6249 match(Set dst (PopCountL src)); 6250 effect(KILL cr); 6251 6252 format %{ "popcnt $dst, $src" %} 6253 ins_encode %{ 6254 __ popcntq($dst$$Register, $src$$Register); 6255 %} 6256 ins_pipe(ialu_reg); 6257 %} 6258 6259 // Note: Long.bitCount(long) returns an int. 6260 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6261 predicate(UsePopCountInstruction); 6262 match(Set dst (PopCountL (LoadL mem))); 6263 effect(KILL cr); 6264 6265 format %{ "popcnt $dst, $mem" %} 6266 ins_encode %{ 6267 __ popcntq($dst$$Register, $mem$$Address); 6268 %} 6269 ins_pipe(ialu_reg); 6270 %} 6271 6272 6273 //----------MemBar Instructions----------------------------------------------- 6274 // Memory barrier flavors 6275 6276 instruct membar_acquire() 6277 %{ 6278 match(MemBarAcquire); 6279 match(LoadFence); 6280 ins_cost(0); 6281 6282 size(0); 6283 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6284 ins_encode(); 6285 ins_pipe(empty); 6286 %} 6287 6288 instruct membar_acquire_lock() 6289 %{ 6290 match(MemBarAcquireLock); 6291 ins_cost(0); 6292 6293 size(0); 6294 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6295 ins_encode(); 6296 ins_pipe(empty); 6297 %} 6298 6299 instruct membar_release() 6300 %{ 6301 match(MemBarRelease); 6302 match(StoreFence); 6303 ins_cost(0); 6304 6305 size(0); 6306 format %{ "MEMBAR-release ! (empty encoding)" %} 6307 ins_encode(); 6308 ins_pipe(empty); 6309 %} 6310 6311 instruct membar_release_lock() 6312 %{ 6313 match(MemBarReleaseLock); 6314 ins_cost(0); 6315 6316 size(0); 6317 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6318 ins_encode(); 6319 ins_pipe(empty); 6320 %} 6321 6322 instruct membar_volatile(rFlagsReg cr) %{ 6323 match(MemBarVolatile); 6324 effect(KILL cr); 6325 ins_cost(400); 6326 6327 format %{ 6328 $$template 6329 if (os::is_MP()) { 6330 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6331 } else { 6332 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6333 } 6334 %} 6335 ins_encode %{ 6336 __ membar(Assembler::StoreLoad); 6337 %} 6338 ins_pipe(pipe_slow); 6339 %} 6340 6341 instruct unnecessary_membar_volatile() 6342 %{ 6343 match(MemBarVolatile); 6344 predicate(Matcher::post_store_load_barrier(n)); 6345 ins_cost(0); 6346 6347 size(0); 6348 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6349 ins_encode(); 6350 ins_pipe(empty); 6351 %} 6352 6353 instruct membar_storestore() %{ 6354 match(MemBarStoreStore); 6355 ins_cost(0); 6356 6357 size(0); 6358 format %{ "MEMBAR-storestore (empty encoding)" %} 6359 ins_encode( ); 6360 ins_pipe(empty); 6361 %} 6362 6363 //----------Move Instructions-------------------------------------------------- 6364 6365 instruct castX2P(rRegP dst, rRegL src) 6366 %{ 6367 match(Set dst (CastX2P src)); 6368 6369 format %{ "movq $dst, $src\t# long->ptr" %} 6370 ins_encode %{ 6371 if ($dst$$reg != $src$$reg) { 6372 __ movptr($dst$$Register, $src$$Register); 6373 } 6374 %} 6375 ins_pipe(ialu_reg_reg); // XXX 6376 %} 6377 6378 instruct castP2X(rRegL dst, rRegP src) 6379 %{ 6380 match(Set dst (CastP2X src)); 6381 6382 format %{ "movq $dst, $src\t# ptr -> long" %} 6383 ins_encode %{ 6384 if ($dst$$reg != $src$$reg) { 6385 __ movptr($dst$$Register, $src$$Register); 6386 } 6387 %} 6388 ins_pipe(ialu_reg_reg); // XXX 6389 %} 6390 6391 // Convert oop into int for vectors alignment masking 6392 instruct convP2I(rRegI dst, rRegP src) 6393 %{ 6394 match(Set dst (ConvL2I (CastP2X src))); 6395 6396 format %{ "movl $dst, $src\t# ptr -> int" %} 6397 ins_encode %{ 6398 __ movl($dst$$Register, $src$$Register); 6399 %} 6400 ins_pipe(ialu_reg_reg); // XXX 6401 %} 6402 6403 // Convert compressed oop into int for vectors alignment masking 6404 // in case of 32bit oops (heap < 4Gb). 6405 instruct convN2I(rRegI dst, rRegN src) 6406 %{ 6407 predicate(Universe::narrow_oop_shift() == 0); 6408 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6409 6410 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6411 ins_encode %{ 6412 __ movl($dst$$Register, $src$$Register); 6413 %} 6414 ins_pipe(ialu_reg_reg); // XXX 6415 %} 6416 6417 // Convert oop pointer into compressed form 6418 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6419 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6420 match(Set dst (EncodeP src)); 6421 effect(KILL cr); 6422 format %{ "encode_heap_oop $dst,$src" %} 6423 ins_encode %{ 6424 Register s = $src$$Register; 6425 Register d = $dst$$Register; 6426 if (s != d) { 6427 __ movq(d, s); 6428 } 6429 __ encode_heap_oop(d); 6430 %} 6431 ins_pipe(ialu_reg_long); 6432 %} 6433 6434 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6435 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6436 match(Set dst (EncodeP src)); 6437 effect(KILL cr); 6438 format %{ "encode_heap_oop_not_null $dst,$src" %} 6439 ins_encode %{ 6440 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6441 %} 6442 ins_pipe(ialu_reg_long); 6443 %} 6444 6445 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6446 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6447 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6448 match(Set dst (DecodeN src)); 6449 effect(KILL cr); 6450 format %{ "decode_heap_oop $dst,$src" %} 6451 ins_encode %{ 6452 Register s = $src$$Register; 6453 Register d = $dst$$Register; 6454 if (s != d) { 6455 __ movq(d, s); 6456 } 6457 __ decode_heap_oop(d); 6458 %} 6459 ins_pipe(ialu_reg_long); 6460 %} 6461 6462 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6463 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6464 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6465 match(Set dst (DecodeN src)); 6466 effect(KILL cr); 6467 format %{ "decode_heap_oop_not_null $dst,$src" %} 6468 ins_encode %{ 6469 Register s = $src$$Register; 6470 Register d = $dst$$Register; 6471 if (s != d) { 6472 __ decode_heap_oop_not_null(d, s); 6473 } else { 6474 __ decode_heap_oop_not_null(d); 6475 } 6476 %} 6477 ins_pipe(ialu_reg_long); 6478 %} 6479 6480 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6481 match(Set dst (EncodePKlass src)); 6482 effect(KILL cr); 6483 format %{ "encode_klass_not_null $dst,$src" %} 6484 ins_encode %{ 6485 __ encode_klass_not_null($dst$$Register, $src$$Register); 6486 %} 6487 ins_pipe(ialu_reg_long); 6488 %} 6489 6490 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6491 match(Set dst (DecodeNKlass src)); 6492 effect(KILL cr); 6493 format %{ "decode_klass_not_null $dst,$src" %} 6494 ins_encode %{ 6495 Register s = $src$$Register; 6496 Register d = $dst$$Register; 6497 if (s != d) { 6498 __ decode_klass_not_null(d, s); 6499 } else { 6500 __ decode_klass_not_null(d); 6501 } 6502 %} 6503 ins_pipe(ialu_reg_long); 6504 %} 6505 6506 6507 //----------Conditional Move--------------------------------------------------- 6508 // Jump 6509 // dummy instruction for generating temp registers 6510 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6511 match(Jump (LShiftL switch_val shift)); 6512 ins_cost(350); 6513 predicate(false); 6514 effect(TEMP dest); 6515 6516 format %{ "leaq $dest, [$constantaddress]\n\t" 6517 "jmp [$dest + $switch_val << $shift]\n\t" %} 6518 ins_encode %{ 6519 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6520 // to do that and the compiler is using that register as one it can allocate. 6521 // So we build it all by hand. 6522 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6523 // ArrayAddress dispatch(table, index); 6524 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6525 __ lea($dest$$Register, $constantaddress); 6526 __ jmp(dispatch); 6527 %} 6528 ins_pipe(pipe_jmp); 6529 %} 6530 6531 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6532 match(Jump (AddL (LShiftL switch_val shift) offset)); 6533 ins_cost(350); 6534 effect(TEMP dest); 6535 6536 format %{ "leaq $dest, [$constantaddress]\n\t" 6537 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6538 ins_encode %{ 6539 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6540 // to do that and the compiler is using that register as one it can allocate. 6541 // So we build it all by hand. 6542 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6543 // ArrayAddress dispatch(table, index); 6544 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6545 __ lea($dest$$Register, $constantaddress); 6546 __ jmp(dispatch); 6547 %} 6548 ins_pipe(pipe_jmp); 6549 %} 6550 6551 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6552 match(Jump switch_val); 6553 ins_cost(350); 6554 effect(TEMP dest); 6555 6556 format %{ "leaq $dest, [$constantaddress]\n\t" 6557 "jmp [$dest + $switch_val]\n\t" %} 6558 ins_encode %{ 6559 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6560 // to do that and the compiler is using that register as one it can allocate. 6561 // So we build it all by hand. 6562 // Address index(noreg, switch_reg, Address::times_1); 6563 // ArrayAddress dispatch(table, index); 6564 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6565 __ lea($dest$$Register, $constantaddress); 6566 __ jmp(dispatch); 6567 %} 6568 ins_pipe(pipe_jmp); 6569 %} 6570 6571 // Conditional move 6572 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6573 %{ 6574 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6575 6576 ins_cost(200); // XXX 6577 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6578 opcode(0x0F, 0x40); 6579 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6580 ins_pipe(pipe_cmov_reg); 6581 %} 6582 6583 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6584 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6585 6586 ins_cost(200); // XXX 6587 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6588 opcode(0x0F, 0x40); 6589 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6590 ins_pipe(pipe_cmov_reg); 6591 %} 6592 6593 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6594 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6595 ins_cost(200); 6596 expand %{ 6597 cmovI_regU(cop, cr, dst, src); 6598 %} 6599 %} 6600 6601 // Conditional move 6602 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6603 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6604 6605 ins_cost(250); // XXX 6606 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6607 opcode(0x0F, 0x40); 6608 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6609 ins_pipe(pipe_cmov_mem); 6610 %} 6611 6612 // Conditional move 6613 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6614 %{ 6615 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6616 6617 ins_cost(250); // XXX 6618 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6619 opcode(0x0F, 0x40); 6620 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6621 ins_pipe(pipe_cmov_mem); 6622 %} 6623 6624 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6625 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6626 ins_cost(250); 6627 expand %{ 6628 cmovI_memU(cop, cr, dst, src); 6629 %} 6630 %} 6631 6632 // Conditional move 6633 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6634 %{ 6635 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6636 6637 ins_cost(200); // XXX 6638 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6639 opcode(0x0F, 0x40); 6640 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6641 ins_pipe(pipe_cmov_reg); 6642 %} 6643 6644 // Conditional move 6645 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6646 %{ 6647 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6648 6649 ins_cost(200); // XXX 6650 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6651 opcode(0x0F, 0x40); 6652 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6653 ins_pipe(pipe_cmov_reg); 6654 %} 6655 6656 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6657 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6658 ins_cost(200); 6659 expand %{ 6660 cmovN_regU(cop, cr, dst, src); 6661 %} 6662 %} 6663 6664 // Conditional move 6665 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6666 %{ 6667 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6668 6669 ins_cost(200); // XXX 6670 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6671 opcode(0x0F, 0x40); 6672 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6673 ins_pipe(pipe_cmov_reg); // XXX 6674 %} 6675 6676 // Conditional move 6677 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6678 %{ 6679 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6680 6681 ins_cost(200); // XXX 6682 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6683 opcode(0x0F, 0x40); 6684 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6685 ins_pipe(pipe_cmov_reg); // XXX 6686 %} 6687 6688 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6689 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6690 ins_cost(200); 6691 expand %{ 6692 cmovP_regU(cop, cr, dst, src); 6693 %} 6694 %} 6695 6696 // DISABLED: Requires the ADLC to emit a bottom_type call that 6697 // correctly meets the two pointer arguments; one is an incoming 6698 // register but the other is a memory operand. ALSO appears to 6699 // be buggy with implicit null checks. 6700 // 6701 //// Conditional move 6702 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6703 //%{ 6704 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6705 // ins_cost(250); 6706 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6707 // opcode(0x0F,0x40); 6708 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6709 // ins_pipe( pipe_cmov_mem ); 6710 //%} 6711 // 6712 //// Conditional move 6713 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6714 //%{ 6715 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6716 // ins_cost(250); 6717 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6718 // opcode(0x0F,0x40); 6719 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6720 // ins_pipe( pipe_cmov_mem ); 6721 //%} 6722 6723 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6724 %{ 6725 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6726 6727 ins_cost(200); // XXX 6728 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6729 opcode(0x0F, 0x40); 6730 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6731 ins_pipe(pipe_cmov_reg); // XXX 6732 %} 6733 6734 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6735 %{ 6736 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6737 6738 ins_cost(200); // XXX 6739 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6740 opcode(0x0F, 0x40); 6741 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6742 ins_pipe(pipe_cmov_mem); // XXX 6743 %} 6744 6745 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6746 %{ 6747 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6748 6749 ins_cost(200); // XXX 6750 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6751 opcode(0x0F, 0x40); 6752 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6753 ins_pipe(pipe_cmov_reg); // XXX 6754 %} 6755 6756 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6757 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6758 ins_cost(200); 6759 expand %{ 6760 cmovL_regU(cop, cr, dst, src); 6761 %} 6762 %} 6763 6764 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6765 %{ 6766 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6767 6768 ins_cost(200); // XXX 6769 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6770 opcode(0x0F, 0x40); 6771 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6772 ins_pipe(pipe_cmov_mem); // XXX 6773 %} 6774 6775 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6776 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6777 ins_cost(200); 6778 expand %{ 6779 cmovL_memU(cop, cr, dst, src); 6780 %} 6781 %} 6782 6783 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6784 %{ 6785 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6786 6787 ins_cost(200); // XXX 6788 format %{ "jn$cop skip\t# signed cmove float\n\t" 6789 "movss $dst, $src\n" 6790 "skip:" %} 6791 ins_encode %{ 6792 Label Lskip; 6793 // Invert sense of branch from sense of CMOV 6794 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6795 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6796 __ bind(Lskip); 6797 %} 6798 ins_pipe(pipe_slow); 6799 %} 6800 6801 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6802 // %{ 6803 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 6804 6805 // ins_cost(200); // XXX 6806 // format %{ "jn$cop skip\t# signed cmove float\n\t" 6807 // "movss $dst, $src\n" 6808 // "skip:" %} 6809 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 6810 // ins_pipe(pipe_slow); 6811 // %} 6812 6813 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6814 %{ 6815 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6816 6817 ins_cost(200); // XXX 6818 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6819 "movss $dst, $src\n" 6820 "skip:" %} 6821 ins_encode %{ 6822 Label Lskip; 6823 // Invert sense of branch from sense of CMOV 6824 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6825 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6826 __ bind(Lskip); 6827 %} 6828 ins_pipe(pipe_slow); 6829 %} 6830 6831 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6832 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6833 ins_cost(200); 6834 expand %{ 6835 cmovF_regU(cop, cr, dst, src); 6836 %} 6837 %} 6838 6839 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6840 %{ 6841 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6842 6843 ins_cost(200); // XXX 6844 format %{ "jn$cop skip\t# signed cmove double\n\t" 6845 "movsd $dst, $src\n" 6846 "skip:" %} 6847 ins_encode %{ 6848 Label Lskip; 6849 // Invert sense of branch from sense of CMOV 6850 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6851 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6852 __ bind(Lskip); 6853 %} 6854 ins_pipe(pipe_slow); 6855 %} 6856 6857 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6858 %{ 6859 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6860 6861 ins_cost(200); // XXX 6862 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6863 "movsd $dst, $src\n" 6864 "skip:" %} 6865 ins_encode %{ 6866 Label Lskip; 6867 // Invert sense of branch from sense of CMOV 6868 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6869 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6870 __ bind(Lskip); 6871 %} 6872 ins_pipe(pipe_slow); 6873 %} 6874 6875 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6876 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6877 ins_cost(200); 6878 expand %{ 6879 cmovD_regU(cop, cr, dst, src); 6880 %} 6881 %} 6882 6883 //----------Arithmetic Instructions-------------------------------------------- 6884 //----------Addition Instructions---------------------------------------------- 6885 6886 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6887 %{ 6888 match(Set dst (AddI dst src)); 6889 effect(KILL cr); 6890 6891 format %{ "addl $dst, $src\t# int" %} 6892 opcode(0x03); 6893 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 6894 ins_pipe(ialu_reg_reg); 6895 %} 6896 6897 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6898 %{ 6899 match(Set dst (AddI dst src)); 6900 effect(KILL cr); 6901 6902 format %{ "addl $dst, $src\t# int" %} 6903 opcode(0x81, 0x00); /* /0 id */ 6904 ins_encode(OpcSErm(dst, src), Con8or32(src)); 6905 ins_pipe( ialu_reg ); 6906 %} 6907 6908 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6909 %{ 6910 match(Set dst (AddI dst (LoadI src))); 6911 effect(KILL cr); 6912 6913 ins_cost(125); // XXX 6914 format %{ "addl $dst, $src\t# int" %} 6915 opcode(0x03); 6916 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6917 ins_pipe(ialu_reg_mem); 6918 %} 6919 6920 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6921 %{ 6922 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6923 effect(KILL cr); 6924 6925 ins_cost(150); // XXX 6926 format %{ "addl $dst, $src\t# int" %} 6927 opcode(0x01); /* Opcode 01 /r */ 6928 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6929 ins_pipe(ialu_mem_reg); 6930 %} 6931 6932 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6933 %{ 6934 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6935 effect(KILL cr); 6936 6937 ins_cost(125); // XXX 6938 format %{ "addl $dst, $src\t# int" %} 6939 opcode(0x81); /* Opcode 81 /0 id */ 6940 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 6941 ins_pipe(ialu_mem_imm); 6942 %} 6943 6944 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 6945 %{ 6946 predicate(UseIncDec); 6947 match(Set dst (AddI dst src)); 6948 effect(KILL cr); 6949 6950 format %{ "incl $dst\t# int" %} 6951 opcode(0xFF, 0x00); // FF /0 6952 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6953 ins_pipe(ialu_reg); 6954 %} 6955 6956 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 6957 %{ 6958 predicate(UseIncDec); 6959 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6960 effect(KILL cr); 6961 6962 ins_cost(125); // XXX 6963 format %{ "incl $dst\t# int" %} 6964 opcode(0xFF); /* Opcode FF /0 */ 6965 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 6966 ins_pipe(ialu_mem_imm); 6967 %} 6968 6969 // XXX why does that use AddI 6970 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6971 %{ 6972 predicate(UseIncDec); 6973 match(Set dst (AddI dst src)); 6974 effect(KILL cr); 6975 6976 format %{ "decl $dst\t# int" %} 6977 opcode(0xFF, 0x01); // FF /1 6978 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6979 ins_pipe(ialu_reg); 6980 %} 6981 6982 // XXX why does that use AddI 6983 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6984 %{ 6985 predicate(UseIncDec); 6986 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6987 effect(KILL cr); 6988 6989 ins_cost(125); // XXX 6990 format %{ "decl $dst\t# int" %} 6991 opcode(0xFF); /* Opcode FF /1 */ 6992 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 6993 ins_pipe(ialu_mem_imm); 6994 %} 6995 6996 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 6997 %{ 6998 match(Set dst (AddI src0 src1)); 6999 7000 ins_cost(110); 7001 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7002 opcode(0x8D); /* 0x8D /r */ 7003 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7004 ins_pipe(ialu_reg_reg); 7005 %} 7006 7007 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7008 %{ 7009 match(Set dst (AddL dst src)); 7010 effect(KILL cr); 7011 7012 format %{ "addq $dst, $src\t# long" %} 7013 opcode(0x03); 7014 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7015 ins_pipe(ialu_reg_reg); 7016 %} 7017 7018 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7019 %{ 7020 match(Set dst (AddL dst src)); 7021 effect(KILL cr); 7022 7023 format %{ "addq $dst, $src\t# long" %} 7024 opcode(0x81, 0x00); /* /0 id */ 7025 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7026 ins_pipe( ialu_reg ); 7027 %} 7028 7029 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7030 %{ 7031 match(Set dst (AddL dst (LoadL src))); 7032 effect(KILL cr); 7033 7034 ins_cost(125); // XXX 7035 format %{ "addq $dst, $src\t# long" %} 7036 opcode(0x03); 7037 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7038 ins_pipe(ialu_reg_mem); 7039 %} 7040 7041 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7042 %{ 7043 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7044 effect(KILL cr); 7045 7046 ins_cost(150); // XXX 7047 format %{ "addq $dst, $src\t# long" %} 7048 opcode(0x01); /* Opcode 01 /r */ 7049 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7050 ins_pipe(ialu_mem_reg); 7051 %} 7052 7053 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7054 %{ 7055 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7056 effect(KILL cr); 7057 7058 ins_cost(125); // XXX 7059 format %{ "addq $dst, $src\t# long" %} 7060 opcode(0x81); /* Opcode 81 /0 id */ 7061 ins_encode(REX_mem_wide(dst), 7062 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7063 ins_pipe(ialu_mem_imm); 7064 %} 7065 7066 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7067 %{ 7068 predicate(UseIncDec); 7069 match(Set dst (AddL dst src)); 7070 effect(KILL cr); 7071 7072 format %{ "incq $dst\t# long" %} 7073 opcode(0xFF, 0x00); // FF /0 7074 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7075 ins_pipe(ialu_reg); 7076 %} 7077 7078 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7079 %{ 7080 predicate(UseIncDec); 7081 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7082 effect(KILL cr); 7083 7084 ins_cost(125); // XXX 7085 format %{ "incq $dst\t# long" %} 7086 opcode(0xFF); /* Opcode FF /0 */ 7087 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7088 ins_pipe(ialu_mem_imm); 7089 %} 7090 7091 // XXX why does that use AddL 7092 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7093 %{ 7094 predicate(UseIncDec); 7095 match(Set dst (AddL dst src)); 7096 effect(KILL cr); 7097 7098 format %{ "decq $dst\t# long" %} 7099 opcode(0xFF, 0x01); // FF /1 7100 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7101 ins_pipe(ialu_reg); 7102 %} 7103 7104 // XXX why does that use AddL 7105 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7106 %{ 7107 predicate(UseIncDec); 7108 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7109 effect(KILL cr); 7110 7111 ins_cost(125); // XXX 7112 format %{ "decq $dst\t# long" %} 7113 opcode(0xFF); /* Opcode FF /1 */ 7114 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7115 ins_pipe(ialu_mem_imm); 7116 %} 7117 7118 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7119 %{ 7120 match(Set dst (AddL src0 src1)); 7121 7122 ins_cost(110); 7123 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7124 opcode(0x8D); /* 0x8D /r */ 7125 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7126 ins_pipe(ialu_reg_reg); 7127 %} 7128 7129 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7130 %{ 7131 match(Set dst (AddP dst src)); 7132 effect(KILL cr); 7133 7134 format %{ "addq $dst, $src\t# ptr" %} 7135 opcode(0x03); 7136 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7137 ins_pipe(ialu_reg_reg); 7138 %} 7139 7140 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7141 %{ 7142 match(Set dst (AddP dst src)); 7143 effect(KILL cr); 7144 7145 format %{ "addq $dst, $src\t# ptr" %} 7146 opcode(0x81, 0x00); /* /0 id */ 7147 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7148 ins_pipe( ialu_reg ); 7149 %} 7150 7151 // XXX addP mem ops ???? 7152 7153 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7154 %{ 7155 match(Set dst (AddP src0 src1)); 7156 7157 ins_cost(110); 7158 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7159 opcode(0x8D); /* 0x8D /r */ 7160 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7161 ins_pipe(ialu_reg_reg); 7162 %} 7163 7164 instruct checkCastPP(rRegP dst) 7165 %{ 7166 match(Set dst (CheckCastPP dst)); 7167 7168 size(0); 7169 format %{ "# checkcastPP of $dst" %} 7170 ins_encode(/* empty encoding */); 7171 ins_pipe(empty); 7172 %} 7173 7174 instruct castPP(rRegP dst) 7175 %{ 7176 match(Set dst (CastPP dst)); 7177 7178 size(0); 7179 format %{ "# castPP of $dst" %} 7180 ins_encode(/* empty encoding */); 7181 ins_pipe(empty); 7182 %} 7183 7184 instruct castII(rRegI dst) 7185 %{ 7186 match(Set dst (CastII dst)); 7187 7188 size(0); 7189 format %{ "# castII of $dst" %} 7190 ins_encode(/* empty encoding */); 7191 ins_cost(0); 7192 ins_pipe(empty); 7193 %} 7194 7195 // LoadP-locked same as a regular LoadP when used with compare-swap 7196 instruct loadPLocked(rRegP dst, memory mem) 7197 %{ 7198 match(Set dst (LoadPLocked mem)); 7199 7200 ins_cost(125); // XXX 7201 format %{ "movq $dst, $mem\t# ptr locked" %} 7202 opcode(0x8B); 7203 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7204 ins_pipe(ialu_reg_mem); // XXX 7205 %} 7206 7207 // Conditional-store of the updated heap-top. 7208 // Used during allocation of the shared heap. 7209 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7210 7211 instruct storePConditional(memory heap_top_ptr, 7212 rax_RegP oldval, rRegP newval, 7213 rFlagsReg cr) 7214 %{ 7215 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7216 7217 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7218 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7219 opcode(0x0F, 0xB1); 7220 ins_encode(lock_prefix, 7221 REX_reg_mem_wide(newval, heap_top_ptr), 7222 OpcP, OpcS, 7223 reg_mem(newval, heap_top_ptr)); 7224 ins_pipe(pipe_cmpxchg); 7225 %} 7226 7227 // Conditional-store of an int value. 7228 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7229 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7230 %{ 7231 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7232 effect(KILL oldval); 7233 7234 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7235 opcode(0x0F, 0xB1); 7236 ins_encode(lock_prefix, 7237 REX_reg_mem(newval, mem), 7238 OpcP, OpcS, 7239 reg_mem(newval, mem)); 7240 ins_pipe(pipe_cmpxchg); 7241 %} 7242 7243 // Conditional-store of a long value. 7244 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7245 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7246 %{ 7247 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7248 effect(KILL oldval); 7249 7250 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7251 opcode(0x0F, 0xB1); 7252 ins_encode(lock_prefix, 7253 REX_reg_mem_wide(newval, mem), 7254 OpcP, OpcS, 7255 reg_mem(newval, mem)); 7256 ins_pipe(pipe_cmpxchg); 7257 %} 7258 7259 7260 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7261 instruct compareAndSwapP(rRegI res, 7262 memory mem_ptr, 7263 rax_RegP oldval, rRegP newval, 7264 rFlagsReg cr) 7265 %{ 7266 predicate(VM_Version::supports_cx8()); 7267 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7268 effect(KILL cr, KILL oldval); 7269 7270 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7271 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7272 "sete $res\n\t" 7273 "movzbl $res, $res" %} 7274 opcode(0x0F, 0xB1); 7275 ins_encode(lock_prefix, 7276 REX_reg_mem_wide(newval, mem_ptr), 7277 OpcP, OpcS, 7278 reg_mem(newval, mem_ptr), 7279 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7280 REX_reg_breg(res, res), // movzbl 7281 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7282 ins_pipe( pipe_cmpxchg ); 7283 %} 7284 7285 instruct compareAndSwapL(rRegI res, 7286 memory mem_ptr, 7287 rax_RegL oldval, rRegL newval, 7288 rFlagsReg cr) 7289 %{ 7290 predicate(VM_Version::supports_cx8()); 7291 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7292 effect(KILL cr, KILL oldval); 7293 7294 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7295 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7296 "sete $res\n\t" 7297 "movzbl $res, $res" %} 7298 opcode(0x0F, 0xB1); 7299 ins_encode(lock_prefix, 7300 REX_reg_mem_wide(newval, mem_ptr), 7301 OpcP, OpcS, 7302 reg_mem(newval, mem_ptr), 7303 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7304 REX_reg_breg(res, res), // movzbl 7305 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7306 ins_pipe( pipe_cmpxchg ); 7307 %} 7308 7309 instruct compareAndSwapI(rRegI res, 7310 memory mem_ptr, 7311 rax_RegI oldval, rRegI newval, 7312 rFlagsReg cr) 7313 %{ 7314 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7315 effect(KILL cr, KILL oldval); 7316 7317 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7318 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7319 "sete $res\n\t" 7320 "movzbl $res, $res" %} 7321 opcode(0x0F, 0xB1); 7322 ins_encode(lock_prefix, 7323 REX_reg_mem(newval, mem_ptr), 7324 OpcP, OpcS, 7325 reg_mem(newval, mem_ptr), 7326 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7327 REX_reg_breg(res, res), // movzbl 7328 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7329 ins_pipe( pipe_cmpxchg ); 7330 %} 7331 7332 7333 instruct compareAndSwapN(rRegI res, 7334 memory mem_ptr, 7335 rax_RegN oldval, rRegN newval, 7336 rFlagsReg cr) %{ 7337 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7338 effect(KILL cr, KILL oldval); 7339 7340 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7341 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7342 "sete $res\n\t" 7343 "movzbl $res, $res" %} 7344 opcode(0x0F, 0xB1); 7345 ins_encode(lock_prefix, 7346 REX_reg_mem(newval, mem_ptr), 7347 OpcP, OpcS, 7348 reg_mem(newval, mem_ptr), 7349 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7350 REX_reg_breg(res, res), // movzbl 7351 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7352 ins_pipe( pipe_cmpxchg ); 7353 %} 7354 7355 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7356 predicate(n->as_LoadStore()->result_not_used()); 7357 match(Set dummy (GetAndAddI mem add)); 7358 effect(KILL cr); 7359 format %{ "ADDL [$mem],$add" %} 7360 ins_encode %{ 7361 if (os::is_MP()) { __ lock(); } 7362 __ addl($mem$$Address, $add$$constant); 7363 %} 7364 ins_pipe( pipe_cmpxchg ); 7365 %} 7366 7367 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7368 match(Set newval (GetAndAddI mem newval)); 7369 effect(KILL cr); 7370 format %{ "XADDL [$mem],$newval" %} 7371 ins_encode %{ 7372 if (os::is_MP()) { __ lock(); } 7373 __ xaddl($mem$$Address, $newval$$Register); 7374 %} 7375 ins_pipe( pipe_cmpxchg ); 7376 %} 7377 7378 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7379 predicate(n->as_LoadStore()->result_not_used()); 7380 match(Set dummy (GetAndAddL mem add)); 7381 effect(KILL cr); 7382 format %{ "ADDQ [$mem],$add" %} 7383 ins_encode %{ 7384 if (os::is_MP()) { __ lock(); } 7385 __ addq($mem$$Address, $add$$constant); 7386 %} 7387 ins_pipe( pipe_cmpxchg ); 7388 %} 7389 7390 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7391 match(Set newval (GetAndAddL mem newval)); 7392 effect(KILL cr); 7393 format %{ "XADDQ [$mem],$newval" %} 7394 ins_encode %{ 7395 if (os::is_MP()) { __ lock(); } 7396 __ xaddq($mem$$Address, $newval$$Register); 7397 %} 7398 ins_pipe( pipe_cmpxchg ); 7399 %} 7400 7401 instruct xchgI( memory mem, rRegI newval) %{ 7402 match(Set newval (GetAndSetI mem newval)); 7403 format %{ "XCHGL $newval,[$mem]" %} 7404 ins_encode %{ 7405 __ xchgl($newval$$Register, $mem$$Address); 7406 %} 7407 ins_pipe( pipe_cmpxchg ); 7408 %} 7409 7410 instruct xchgL( memory mem, rRegL newval) %{ 7411 match(Set newval (GetAndSetL mem newval)); 7412 format %{ "XCHGL $newval,[$mem]" %} 7413 ins_encode %{ 7414 __ xchgq($newval$$Register, $mem$$Address); 7415 %} 7416 ins_pipe( pipe_cmpxchg ); 7417 %} 7418 7419 instruct xchgP( memory mem, rRegP newval) %{ 7420 match(Set newval (GetAndSetP mem newval)); 7421 format %{ "XCHGQ $newval,[$mem]" %} 7422 ins_encode %{ 7423 __ xchgq($newval$$Register, $mem$$Address); 7424 %} 7425 ins_pipe( pipe_cmpxchg ); 7426 %} 7427 7428 instruct xchgN( memory mem, rRegN newval) %{ 7429 match(Set newval (GetAndSetN mem newval)); 7430 format %{ "XCHGL $newval,$mem]" %} 7431 ins_encode %{ 7432 __ xchgl($newval$$Register, $mem$$Address); 7433 %} 7434 ins_pipe( pipe_cmpxchg ); 7435 %} 7436 7437 //----------Subtraction Instructions------------------------------------------- 7438 7439 // Integer Subtraction Instructions 7440 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7441 %{ 7442 match(Set dst (SubI dst src)); 7443 effect(KILL cr); 7444 7445 format %{ "subl $dst, $src\t# int" %} 7446 opcode(0x2B); 7447 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7448 ins_pipe(ialu_reg_reg); 7449 %} 7450 7451 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7452 %{ 7453 match(Set dst (SubI dst src)); 7454 effect(KILL cr); 7455 7456 format %{ "subl $dst, $src\t# int" %} 7457 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7458 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7459 ins_pipe(ialu_reg); 7460 %} 7461 7462 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7463 %{ 7464 match(Set dst (SubI dst (LoadI src))); 7465 effect(KILL cr); 7466 7467 ins_cost(125); 7468 format %{ "subl $dst, $src\t# int" %} 7469 opcode(0x2B); 7470 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7471 ins_pipe(ialu_reg_mem); 7472 %} 7473 7474 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7475 %{ 7476 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7477 effect(KILL cr); 7478 7479 ins_cost(150); 7480 format %{ "subl $dst, $src\t# int" %} 7481 opcode(0x29); /* Opcode 29 /r */ 7482 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7483 ins_pipe(ialu_mem_reg); 7484 %} 7485 7486 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7487 %{ 7488 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7489 effect(KILL cr); 7490 7491 ins_cost(125); // XXX 7492 format %{ "subl $dst, $src\t# int" %} 7493 opcode(0x81); /* Opcode 81 /5 id */ 7494 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7495 ins_pipe(ialu_mem_imm); 7496 %} 7497 7498 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7499 %{ 7500 match(Set dst (SubL dst src)); 7501 effect(KILL cr); 7502 7503 format %{ "subq $dst, $src\t# long" %} 7504 opcode(0x2B); 7505 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7506 ins_pipe(ialu_reg_reg); 7507 %} 7508 7509 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7510 %{ 7511 match(Set dst (SubL dst src)); 7512 effect(KILL cr); 7513 7514 format %{ "subq $dst, $src\t# long" %} 7515 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7516 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7517 ins_pipe(ialu_reg); 7518 %} 7519 7520 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7521 %{ 7522 match(Set dst (SubL dst (LoadL src))); 7523 effect(KILL cr); 7524 7525 ins_cost(125); 7526 format %{ "subq $dst, $src\t# long" %} 7527 opcode(0x2B); 7528 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7529 ins_pipe(ialu_reg_mem); 7530 %} 7531 7532 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7533 %{ 7534 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7535 effect(KILL cr); 7536 7537 ins_cost(150); 7538 format %{ "subq $dst, $src\t# long" %} 7539 opcode(0x29); /* Opcode 29 /r */ 7540 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7541 ins_pipe(ialu_mem_reg); 7542 %} 7543 7544 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7545 %{ 7546 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7547 effect(KILL cr); 7548 7549 ins_cost(125); // XXX 7550 format %{ "subq $dst, $src\t# long" %} 7551 opcode(0x81); /* Opcode 81 /5 id */ 7552 ins_encode(REX_mem_wide(dst), 7553 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7554 ins_pipe(ialu_mem_imm); 7555 %} 7556 7557 // Subtract from a pointer 7558 // XXX hmpf??? 7559 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7560 %{ 7561 match(Set dst (AddP dst (SubI zero src))); 7562 effect(KILL cr); 7563 7564 format %{ "subq $dst, $src\t# ptr - int" %} 7565 opcode(0x2B); 7566 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7567 ins_pipe(ialu_reg_reg); 7568 %} 7569 7570 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7571 %{ 7572 match(Set dst (SubI zero dst)); 7573 effect(KILL cr); 7574 7575 format %{ "negl $dst\t# int" %} 7576 opcode(0xF7, 0x03); // Opcode F7 /3 7577 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7578 ins_pipe(ialu_reg); 7579 %} 7580 7581 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7582 %{ 7583 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7584 effect(KILL cr); 7585 7586 format %{ "negl $dst\t# int" %} 7587 opcode(0xF7, 0x03); // Opcode F7 /3 7588 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7589 ins_pipe(ialu_reg); 7590 %} 7591 7592 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7593 %{ 7594 match(Set dst (SubL zero dst)); 7595 effect(KILL cr); 7596 7597 format %{ "negq $dst\t# long" %} 7598 opcode(0xF7, 0x03); // Opcode F7 /3 7599 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7600 ins_pipe(ialu_reg); 7601 %} 7602 7603 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7604 %{ 7605 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7606 effect(KILL cr); 7607 7608 format %{ "negq $dst\t# long" %} 7609 opcode(0xF7, 0x03); // Opcode F7 /3 7610 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7611 ins_pipe(ialu_reg); 7612 %} 7613 7614 //----------Multiplication/Division Instructions------------------------------- 7615 // Integer Multiplication Instructions 7616 // Multiply Register 7617 7618 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7619 %{ 7620 match(Set dst (MulI dst src)); 7621 effect(KILL cr); 7622 7623 ins_cost(300); 7624 format %{ "imull $dst, $src\t# int" %} 7625 opcode(0x0F, 0xAF); 7626 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7627 ins_pipe(ialu_reg_reg_alu0); 7628 %} 7629 7630 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7631 %{ 7632 match(Set dst (MulI src imm)); 7633 effect(KILL cr); 7634 7635 ins_cost(300); 7636 format %{ "imull $dst, $src, $imm\t# int" %} 7637 opcode(0x69); /* 69 /r id */ 7638 ins_encode(REX_reg_reg(dst, src), 7639 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7640 ins_pipe(ialu_reg_reg_alu0); 7641 %} 7642 7643 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7644 %{ 7645 match(Set dst (MulI dst (LoadI src))); 7646 effect(KILL cr); 7647 7648 ins_cost(350); 7649 format %{ "imull $dst, $src\t# int" %} 7650 opcode(0x0F, 0xAF); 7651 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7652 ins_pipe(ialu_reg_mem_alu0); 7653 %} 7654 7655 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7656 %{ 7657 match(Set dst (MulI (LoadI src) imm)); 7658 effect(KILL cr); 7659 7660 ins_cost(300); 7661 format %{ "imull $dst, $src, $imm\t# int" %} 7662 opcode(0x69); /* 69 /r id */ 7663 ins_encode(REX_reg_mem(dst, src), 7664 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7665 ins_pipe(ialu_reg_mem_alu0); 7666 %} 7667 7668 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7669 %{ 7670 match(Set dst (MulL dst src)); 7671 effect(KILL cr); 7672 7673 ins_cost(300); 7674 format %{ "imulq $dst, $src\t# long" %} 7675 opcode(0x0F, 0xAF); 7676 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7677 ins_pipe(ialu_reg_reg_alu0); 7678 %} 7679 7680 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7681 %{ 7682 match(Set dst (MulL src imm)); 7683 effect(KILL cr); 7684 7685 ins_cost(300); 7686 format %{ "imulq $dst, $src, $imm\t# long" %} 7687 opcode(0x69); /* 69 /r id */ 7688 ins_encode(REX_reg_reg_wide(dst, src), 7689 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7690 ins_pipe(ialu_reg_reg_alu0); 7691 %} 7692 7693 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7694 %{ 7695 match(Set dst (MulL dst (LoadL src))); 7696 effect(KILL cr); 7697 7698 ins_cost(350); 7699 format %{ "imulq $dst, $src\t# long" %} 7700 opcode(0x0F, 0xAF); 7701 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7702 ins_pipe(ialu_reg_mem_alu0); 7703 %} 7704 7705 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7706 %{ 7707 match(Set dst (MulL (LoadL src) imm)); 7708 effect(KILL cr); 7709 7710 ins_cost(300); 7711 format %{ "imulq $dst, $src, $imm\t# long" %} 7712 opcode(0x69); /* 69 /r id */ 7713 ins_encode(REX_reg_mem_wide(dst, src), 7714 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7715 ins_pipe(ialu_reg_mem_alu0); 7716 %} 7717 7718 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7719 %{ 7720 match(Set dst (MulHiL src rax)); 7721 effect(USE_KILL rax, KILL cr); 7722 7723 ins_cost(300); 7724 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7725 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7726 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7727 ins_pipe(ialu_reg_reg_alu0); 7728 %} 7729 7730 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7731 rFlagsReg cr) 7732 %{ 7733 match(Set rax (DivI rax div)); 7734 effect(KILL rdx, KILL cr); 7735 7736 ins_cost(30*100+10*100); // XXX 7737 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7738 "jne,s normal\n\t" 7739 "xorl rdx, rdx\n\t" 7740 "cmpl $div, -1\n\t" 7741 "je,s done\n" 7742 "normal: cdql\n\t" 7743 "idivl $div\n" 7744 "done:" %} 7745 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7746 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7747 ins_pipe(ialu_reg_reg_alu0); 7748 %} 7749 7750 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7751 rFlagsReg cr) 7752 %{ 7753 match(Set rax (DivL rax div)); 7754 effect(KILL rdx, KILL cr); 7755 7756 ins_cost(30*100+10*100); // XXX 7757 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7758 "cmpq rax, rdx\n\t" 7759 "jne,s normal\n\t" 7760 "xorl rdx, rdx\n\t" 7761 "cmpq $div, -1\n\t" 7762 "je,s done\n" 7763 "normal: cdqq\n\t" 7764 "idivq $div\n" 7765 "done:" %} 7766 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7767 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7768 ins_pipe(ialu_reg_reg_alu0); 7769 %} 7770 7771 // Integer DIVMOD with Register, both quotient and mod results 7772 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7773 rFlagsReg cr) 7774 %{ 7775 match(DivModI rax div); 7776 effect(KILL cr); 7777 7778 ins_cost(30*100+10*100); // XXX 7779 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7780 "jne,s normal\n\t" 7781 "xorl rdx, rdx\n\t" 7782 "cmpl $div, -1\n\t" 7783 "je,s done\n" 7784 "normal: cdql\n\t" 7785 "idivl $div\n" 7786 "done:" %} 7787 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7788 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7789 ins_pipe(pipe_slow); 7790 %} 7791 7792 // Long DIVMOD with Register, both quotient and mod results 7793 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7794 rFlagsReg cr) 7795 %{ 7796 match(DivModL rax div); 7797 effect(KILL cr); 7798 7799 ins_cost(30*100+10*100); // XXX 7800 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7801 "cmpq rax, rdx\n\t" 7802 "jne,s normal\n\t" 7803 "xorl rdx, rdx\n\t" 7804 "cmpq $div, -1\n\t" 7805 "je,s done\n" 7806 "normal: cdqq\n\t" 7807 "idivq $div\n" 7808 "done:" %} 7809 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7810 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7811 ins_pipe(pipe_slow); 7812 %} 7813 7814 //----------- DivL-By-Constant-Expansions-------------------------------------- 7815 // DivI cases are handled by the compiler 7816 7817 // Magic constant, reciprocal of 10 7818 instruct loadConL_0x6666666666666667(rRegL dst) 7819 %{ 7820 effect(DEF dst); 7821 7822 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 7823 ins_encode(load_immL(dst, 0x6666666666666667)); 7824 ins_pipe(ialu_reg); 7825 %} 7826 7827 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7828 %{ 7829 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 7830 7831 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 7832 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7833 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7834 ins_pipe(ialu_reg_reg_alu0); 7835 %} 7836 7837 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 7838 %{ 7839 effect(USE_DEF dst, KILL cr); 7840 7841 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 7842 opcode(0xC1, 0x7); /* C1 /7 ib */ 7843 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 7844 ins_pipe(ialu_reg); 7845 %} 7846 7847 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 7848 %{ 7849 effect(USE_DEF dst, KILL cr); 7850 7851 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 7852 opcode(0xC1, 0x7); /* C1 /7 ib */ 7853 ins_encode(reg_opc_imm_wide(dst, 0x2)); 7854 ins_pipe(ialu_reg); 7855 %} 7856 7857 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 7858 %{ 7859 match(Set dst (DivL src div)); 7860 7861 ins_cost((5+8)*100); 7862 expand %{ 7863 rax_RegL rax; // Killed temp 7864 rFlagsReg cr; // Killed 7865 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 7866 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 7867 sarL_rReg_63(src, cr); // sarq src, 63 7868 sarL_rReg_2(dst, cr); // sarq rdx, 2 7869 subL_rReg(dst, src, cr); // subl rdx, src 7870 %} 7871 %} 7872 7873 //----------------------------------------------------------------------------- 7874 7875 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7876 rFlagsReg cr) 7877 %{ 7878 match(Set rdx (ModI rax div)); 7879 effect(KILL rax, KILL cr); 7880 7881 ins_cost(300); // XXX 7882 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7883 "jne,s normal\n\t" 7884 "xorl rdx, rdx\n\t" 7885 "cmpl $div, -1\n\t" 7886 "je,s done\n" 7887 "normal: cdql\n\t" 7888 "idivl $div\n" 7889 "done:" %} 7890 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7891 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7892 ins_pipe(ialu_reg_reg_alu0); 7893 %} 7894 7895 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7896 rFlagsReg cr) 7897 %{ 7898 match(Set rdx (ModL rax div)); 7899 effect(KILL rax, KILL cr); 7900 7901 ins_cost(300); // XXX 7902 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 7903 "cmpq rax, rdx\n\t" 7904 "jne,s normal\n\t" 7905 "xorl rdx, rdx\n\t" 7906 "cmpq $div, -1\n\t" 7907 "je,s done\n" 7908 "normal: cdqq\n\t" 7909 "idivq $div\n" 7910 "done:" %} 7911 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7912 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7913 ins_pipe(ialu_reg_reg_alu0); 7914 %} 7915 7916 // Integer Shift Instructions 7917 // Shift Left by one 7918 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7919 %{ 7920 match(Set dst (LShiftI dst shift)); 7921 effect(KILL cr); 7922 7923 format %{ "sall $dst, $shift" %} 7924 opcode(0xD1, 0x4); /* D1 /4 */ 7925 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7926 ins_pipe(ialu_reg); 7927 %} 7928 7929 // Shift Left by one 7930 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7931 %{ 7932 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7933 effect(KILL cr); 7934 7935 format %{ "sall $dst, $shift\t" %} 7936 opcode(0xD1, 0x4); /* D1 /4 */ 7937 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7938 ins_pipe(ialu_mem_imm); 7939 %} 7940 7941 // Shift Left by 8-bit immediate 7942 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7943 %{ 7944 match(Set dst (LShiftI dst shift)); 7945 effect(KILL cr); 7946 7947 format %{ "sall $dst, $shift" %} 7948 opcode(0xC1, 0x4); /* C1 /4 ib */ 7949 ins_encode(reg_opc_imm(dst, shift)); 7950 ins_pipe(ialu_reg); 7951 %} 7952 7953 // Shift Left by 8-bit immediate 7954 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7955 %{ 7956 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7957 effect(KILL cr); 7958 7959 format %{ "sall $dst, $shift" %} 7960 opcode(0xC1, 0x4); /* C1 /4 ib */ 7961 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 7962 ins_pipe(ialu_mem_imm); 7963 %} 7964 7965 // Shift Left by variable 7966 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7967 %{ 7968 match(Set dst (LShiftI dst shift)); 7969 effect(KILL cr); 7970 7971 format %{ "sall $dst, $shift" %} 7972 opcode(0xD3, 0x4); /* D3 /4 */ 7973 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7974 ins_pipe(ialu_reg_reg); 7975 %} 7976 7977 // Shift Left by variable 7978 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 7979 %{ 7980 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7981 effect(KILL cr); 7982 7983 format %{ "sall $dst, $shift" %} 7984 opcode(0xD3, 0x4); /* D3 /4 */ 7985 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7986 ins_pipe(ialu_mem_reg); 7987 %} 7988 7989 // Arithmetic shift right by one 7990 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7991 %{ 7992 match(Set dst (RShiftI dst shift)); 7993 effect(KILL cr); 7994 7995 format %{ "sarl $dst, $shift" %} 7996 opcode(0xD1, 0x7); /* D1 /7 */ 7997 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7998 ins_pipe(ialu_reg); 7999 %} 8000 8001 // Arithmetic shift right by one 8002 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8003 %{ 8004 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8005 effect(KILL cr); 8006 8007 format %{ "sarl $dst, $shift" %} 8008 opcode(0xD1, 0x7); /* D1 /7 */ 8009 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8010 ins_pipe(ialu_mem_imm); 8011 %} 8012 8013 // Arithmetic Shift Right by 8-bit immediate 8014 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8015 %{ 8016 match(Set dst (RShiftI dst shift)); 8017 effect(KILL cr); 8018 8019 format %{ "sarl $dst, $shift" %} 8020 opcode(0xC1, 0x7); /* C1 /7 ib */ 8021 ins_encode(reg_opc_imm(dst, shift)); 8022 ins_pipe(ialu_mem_imm); 8023 %} 8024 8025 // Arithmetic Shift Right by 8-bit immediate 8026 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8027 %{ 8028 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8029 effect(KILL cr); 8030 8031 format %{ "sarl $dst, $shift" %} 8032 opcode(0xC1, 0x7); /* C1 /7 ib */ 8033 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8034 ins_pipe(ialu_mem_imm); 8035 %} 8036 8037 // Arithmetic Shift Right by variable 8038 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8039 %{ 8040 match(Set dst (RShiftI dst shift)); 8041 effect(KILL cr); 8042 8043 format %{ "sarl $dst, $shift" %} 8044 opcode(0xD3, 0x7); /* D3 /7 */ 8045 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8046 ins_pipe(ialu_reg_reg); 8047 %} 8048 8049 // Arithmetic Shift Right by variable 8050 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8051 %{ 8052 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8053 effect(KILL cr); 8054 8055 format %{ "sarl $dst, $shift" %} 8056 opcode(0xD3, 0x7); /* D3 /7 */ 8057 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8058 ins_pipe(ialu_mem_reg); 8059 %} 8060 8061 // Logical shift right by one 8062 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8063 %{ 8064 match(Set dst (URShiftI dst shift)); 8065 effect(KILL cr); 8066 8067 format %{ "shrl $dst, $shift" %} 8068 opcode(0xD1, 0x5); /* D1 /5 */ 8069 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8070 ins_pipe(ialu_reg); 8071 %} 8072 8073 // Logical shift right by one 8074 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8075 %{ 8076 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8077 effect(KILL cr); 8078 8079 format %{ "shrl $dst, $shift" %} 8080 opcode(0xD1, 0x5); /* D1 /5 */ 8081 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8082 ins_pipe(ialu_mem_imm); 8083 %} 8084 8085 // Logical Shift Right by 8-bit immediate 8086 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8087 %{ 8088 match(Set dst (URShiftI dst shift)); 8089 effect(KILL cr); 8090 8091 format %{ "shrl $dst, $shift" %} 8092 opcode(0xC1, 0x5); /* C1 /5 ib */ 8093 ins_encode(reg_opc_imm(dst, shift)); 8094 ins_pipe(ialu_reg); 8095 %} 8096 8097 // Logical Shift Right by 8-bit immediate 8098 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8099 %{ 8100 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8101 effect(KILL cr); 8102 8103 format %{ "shrl $dst, $shift" %} 8104 opcode(0xC1, 0x5); /* C1 /5 ib */ 8105 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8106 ins_pipe(ialu_mem_imm); 8107 %} 8108 8109 // Logical Shift Right by variable 8110 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8111 %{ 8112 match(Set dst (URShiftI dst shift)); 8113 effect(KILL cr); 8114 8115 format %{ "shrl $dst, $shift" %} 8116 opcode(0xD3, 0x5); /* D3 /5 */ 8117 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8118 ins_pipe(ialu_reg_reg); 8119 %} 8120 8121 // Logical Shift Right by variable 8122 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8123 %{ 8124 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8125 effect(KILL cr); 8126 8127 format %{ "shrl $dst, $shift" %} 8128 opcode(0xD3, 0x5); /* D3 /5 */ 8129 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8130 ins_pipe(ialu_mem_reg); 8131 %} 8132 8133 // Long Shift Instructions 8134 // Shift Left by one 8135 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8136 %{ 8137 match(Set dst (LShiftL dst shift)); 8138 effect(KILL cr); 8139 8140 format %{ "salq $dst, $shift" %} 8141 opcode(0xD1, 0x4); /* D1 /4 */ 8142 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8143 ins_pipe(ialu_reg); 8144 %} 8145 8146 // Shift Left by one 8147 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8148 %{ 8149 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8150 effect(KILL cr); 8151 8152 format %{ "salq $dst, $shift" %} 8153 opcode(0xD1, 0x4); /* D1 /4 */ 8154 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8155 ins_pipe(ialu_mem_imm); 8156 %} 8157 8158 // Shift Left by 8-bit immediate 8159 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8160 %{ 8161 match(Set dst (LShiftL dst shift)); 8162 effect(KILL cr); 8163 8164 format %{ "salq $dst, $shift" %} 8165 opcode(0xC1, 0x4); /* C1 /4 ib */ 8166 ins_encode(reg_opc_imm_wide(dst, shift)); 8167 ins_pipe(ialu_reg); 8168 %} 8169 8170 // Shift Left by 8-bit immediate 8171 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8172 %{ 8173 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8174 effect(KILL cr); 8175 8176 format %{ "salq $dst, $shift" %} 8177 opcode(0xC1, 0x4); /* C1 /4 ib */ 8178 ins_encode(REX_mem_wide(dst), OpcP, 8179 RM_opc_mem(secondary, dst), Con8or32(shift)); 8180 ins_pipe(ialu_mem_imm); 8181 %} 8182 8183 // Shift Left by variable 8184 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8185 %{ 8186 match(Set dst (LShiftL dst shift)); 8187 effect(KILL cr); 8188 8189 format %{ "salq $dst, $shift" %} 8190 opcode(0xD3, 0x4); /* D3 /4 */ 8191 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8192 ins_pipe(ialu_reg_reg); 8193 %} 8194 8195 // Shift Left by variable 8196 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8197 %{ 8198 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8199 effect(KILL cr); 8200 8201 format %{ "salq $dst, $shift" %} 8202 opcode(0xD3, 0x4); /* D3 /4 */ 8203 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8204 ins_pipe(ialu_mem_reg); 8205 %} 8206 8207 // Arithmetic shift right by one 8208 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8209 %{ 8210 match(Set dst (RShiftL dst shift)); 8211 effect(KILL cr); 8212 8213 format %{ "sarq $dst, $shift" %} 8214 opcode(0xD1, 0x7); /* D1 /7 */ 8215 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8216 ins_pipe(ialu_reg); 8217 %} 8218 8219 // Arithmetic shift right by one 8220 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8221 %{ 8222 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8223 effect(KILL cr); 8224 8225 format %{ "sarq $dst, $shift" %} 8226 opcode(0xD1, 0x7); /* D1 /7 */ 8227 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8228 ins_pipe(ialu_mem_imm); 8229 %} 8230 8231 // Arithmetic Shift Right by 8-bit immediate 8232 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8233 %{ 8234 match(Set dst (RShiftL dst shift)); 8235 effect(KILL cr); 8236 8237 format %{ "sarq $dst, $shift" %} 8238 opcode(0xC1, 0x7); /* C1 /7 ib */ 8239 ins_encode(reg_opc_imm_wide(dst, shift)); 8240 ins_pipe(ialu_mem_imm); 8241 %} 8242 8243 // Arithmetic Shift Right by 8-bit immediate 8244 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8245 %{ 8246 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8247 effect(KILL cr); 8248 8249 format %{ "sarq $dst, $shift" %} 8250 opcode(0xC1, 0x7); /* C1 /7 ib */ 8251 ins_encode(REX_mem_wide(dst), OpcP, 8252 RM_opc_mem(secondary, dst), Con8or32(shift)); 8253 ins_pipe(ialu_mem_imm); 8254 %} 8255 8256 // Arithmetic Shift Right by variable 8257 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8258 %{ 8259 match(Set dst (RShiftL dst shift)); 8260 effect(KILL cr); 8261 8262 format %{ "sarq $dst, $shift" %} 8263 opcode(0xD3, 0x7); /* D3 /7 */ 8264 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8265 ins_pipe(ialu_reg_reg); 8266 %} 8267 8268 // Arithmetic Shift Right by variable 8269 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8270 %{ 8271 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8272 effect(KILL cr); 8273 8274 format %{ "sarq $dst, $shift" %} 8275 opcode(0xD3, 0x7); /* D3 /7 */ 8276 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8277 ins_pipe(ialu_mem_reg); 8278 %} 8279 8280 // Logical shift right by one 8281 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8282 %{ 8283 match(Set dst (URShiftL dst shift)); 8284 effect(KILL cr); 8285 8286 format %{ "shrq $dst, $shift" %} 8287 opcode(0xD1, 0x5); /* D1 /5 */ 8288 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8289 ins_pipe(ialu_reg); 8290 %} 8291 8292 // Logical shift right by one 8293 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8294 %{ 8295 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8296 effect(KILL cr); 8297 8298 format %{ "shrq $dst, $shift" %} 8299 opcode(0xD1, 0x5); /* D1 /5 */ 8300 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8301 ins_pipe(ialu_mem_imm); 8302 %} 8303 8304 // Logical Shift Right by 8-bit immediate 8305 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8306 %{ 8307 match(Set dst (URShiftL dst shift)); 8308 effect(KILL cr); 8309 8310 format %{ "shrq $dst, $shift" %} 8311 opcode(0xC1, 0x5); /* C1 /5 ib */ 8312 ins_encode(reg_opc_imm_wide(dst, shift)); 8313 ins_pipe(ialu_reg); 8314 %} 8315 8316 8317 // Logical Shift Right by 8-bit immediate 8318 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8319 %{ 8320 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8321 effect(KILL cr); 8322 8323 format %{ "shrq $dst, $shift" %} 8324 opcode(0xC1, 0x5); /* C1 /5 ib */ 8325 ins_encode(REX_mem_wide(dst), OpcP, 8326 RM_opc_mem(secondary, dst), Con8or32(shift)); 8327 ins_pipe(ialu_mem_imm); 8328 %} 8329 8330 // Logical Shift Right by variable 8331 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8332 %{ 8333 match(Set dst (URShiftL dst shift)); 8334 effect(KILL cr); 8335 8336 format %{ "shrq $dst, $shift" %} 8337 opcode(0xD3, 0x5); /* D3 /5 */ 8338 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8339 ins_pipe(ialu_reg_reg); 8340 %} 8341 8342 // Logical Shift Right by variable 8343 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8344 %{ 8345 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8346 effect(KILL cr); 8347 8348 format %{ "shrq $dst, $shift" %} 8349 opcode(0xD3, 0x5); /* D3 /5 */ 8350 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8351 ins_pipe(ialu_mem_reg); 8352 %} 8353 8354 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8355 // This idiom is used by the compiler for the i2b bytecode. 8356 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8357 %{ 8358 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8359 8360 format %{ "movsbl $dst, $src\t# i2b" %} 8361 opcode(0x0F, 0xBE); 8362 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8363 ins_pipe(ialu_reg_reg); 8364 %} 8365 8366 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8367 // This idiom is used by the compiler the i2s bytecode. 8368 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8369 %{ 8370 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8371 8372 format %{ "movswl $dst, $src\t# i2s" %} 8373 opcode(0x0F, 0xBF); 8374 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8375 ins_pipe(ialu_reg_reg); 8376 %} 8377 8378 // ROL/ROR instructions 8379 8380 // ROL expand 8381 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8382 effect(KILL cr, USE_DEF dst); 8383 8384 format %{ "roll $dst" %} 8385 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8386 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8387 ins_pipe(ialu_reg); 8388 %} 8389 8390 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8391 effect(USE_DEF dst, USE shift, KILL cr); 8392 8393 format %{ "roll $dst, $shift" %} 8394 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8395 ins_encode( reg_opc_imm(dst, shift) ); 8396 ins_pipe(ialu_reg); 8397 %} 8398 8399 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8400 %{ 8401 effect(USE_DEF dst, USE shift, KILL cr); 8402 8403 format %{ "roll $dst, $shift" %} 8404 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8405 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8406 ins_pipe(ialu_reg_reg); 8407 %} 8408 // end of ROL expand 8409 8410 // Rotate Left by one 8411 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8412 %{ 8413 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8414 8415 expand %{ 8416 rolI_rReg_imm1(dst, cr); 8417 %} 8418 %} 8419 8420 // Rotate Left by 8-bit immediate 8421 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8422 %{ 8423 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8424 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8425 8426 expand %{ 8427 rolI_rReg_imm8(dst, lshift, cr); 8428 %} 8429 %} 8430 8431 // Rotate Left by variable 8432 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8433 %{ 8434 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8435 8436 expand %{ 8437 rolI_rReg_CL(dst, shift, cr); 8438 %} 8439 %} 8440 8441 // Rotate Left by variable 8442 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8443 %{ 8444 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8445 8446 expand %{ 8447 rolI_rReg_CL(dst, shift, cr); 8448 %} 8449 %} 8450 8451 // ROR expand 8452 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8453 %{ 8454 effect(USE_DEF dst, KILL cr); 8455 8456 format %{ "rorl $dst" %} 8457 opcode(0xD1, 0x1); /* D1 /1 */ 8458 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8459 ins_pipe(ialu_reg); 8460 %} 8461 8462 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8463 %{ 8464 effect(USE_DEF dst, USE shift, KILL cr); 8465 8466 format %{ "rorl $dst, $shift" %} 8467 opcode(0xC1, 0x1); /* C1 /1 ib */ 8468 ins_encode(reg_opc_imm(dst, shift)); 8469 ins_pipe(ialu_reg); 8470 %} 8471 8472 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8473 %{ 8474 effect(USE_DEF dst, USE shift, KILL cr); 8475 8476 format %{ "rorl $dst, $shift" %} 8477 opcode(0xD3, 0x1); /* D3 /1 */ 8478 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8479 ins_pipe(ialu_reg_reg); 8480 %} 8481 // end of ROR expand 8482 8483 // Rotate Right by one 8484 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8485 %{ 8486 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8487 8488 expand %{ 8489 rorI_rReg_imm1(dst, cr); 8490 %} 8491 %} 8492 8493 // Rotate Right by 8-bit immediate 8494 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8495 %{ 8496 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8497 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8498 8499 expand %{ 8500 rorI_rReg_imm8(dst, rshift, cr); 8501 %} 8502 %} 8503 8504 // Rotate Right by variable 8505 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8506 %{ 8507 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8508 8509 expand %{ 8510 rorI_rReg_CL(dst, shift, cr); 8511 %} 8512 %} 8513 8514 // Rotate Right by variable 8515 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8516 %{ 8517 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8518 8519 expand %{ 8520 rorI_rReg_CL(dst, shift, cr); 8521 %} 8522 %} 8523 8524 // for long rotate 8525 // ROL expand 8526 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8527 effect(USE_DEF dst, KILL cr); 8528 8529 format %{ "rolq $dst" %} 8530 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8531 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8532 ins_pipe(ialu_reg); 8533 %} 8534 8535 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8536 effect(USE_DEF dst, USE shift, KILL cr); 8537 8538 format %{ "rolq $dst, $shift" %} 8539 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8540 ins_encode( reg_opc_imm_wide(dst, shift) ); 8541 ins_pipe(ialu_reg); 8542 %} 8543 8544 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8545 %{ 8546 effect(USE_DEF dst, USE shift, KILL cr); 8547 8548 format %{ "rolq $dst, $shift" %} 8549 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8550 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8551 ins_pipe(ialu_reg_reg); 8552 %} 8553 // end of ROL expand 8554 8555 // Rotate Left by one 8556 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8557 %{ 8558 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8559 8560 expand %{ 8561 rolL_rReg_imm1(dst, cr); 8562 %} 8563 %} 8564 8565 // Rotate Left by 8-bit immediate 8566 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8567 %{ 8568 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8569 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8570 8571 expand %{ 8572 rolL_rReg_imm8(dst, lshift, cr); 8573 %} 8574 %} 8575 8576 // Rotate Left by variable 8577 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8578 %{ 8579 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8580 8581 expand %{ 8582 rolL_rReg_CL(dst, shift, cr); 8583 %} 8584 %} 8585 8586 // Rotate Left by variable 8587 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8588 %{ 8589 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8590 8591 expand %{ 8592 rolL_rReg_CL(dst, shift, cr); 8593 %} 8594 %} 8595 8596 // ROR expand 8597 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8598 %{ 8599 effect(USE_DEF dst, KILL cr); 8600 8601 format %{ "rorq $dst" %} 8602 opcode(0xD1, 0x1); /* D1 /1 */ 8603 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8604 ins_pipe(ialu_reg); 8605 %} 8606 8607 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8608 %{ 8609 effect(USE_DEF dst, USE shift, KILL cr); 8610 8611 format %{ "rorq $dst, $shift" %} 8612 opcode(0xC1, 0x1); /* C1 /1 ib */ 8613 ins_encode(reg_opc_imm_wide(dst, shift)); 8614 ins_pipe(ialu_reg); 8615 %} 8616 8617 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8618 %{ 8619 effect(USE_DEF dst, USE shift, KILL cr); 8620 8621 format %{ "rorq $dst, $shift" %} 8622 opcode(0xD3, 0x1); /* D3 /1 */ 8623 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8624 ins_pipe(ialu_reg_reg); 8625 %} 8626 // end of ROR expand 8627 8628 // Rotate Right by one 8629 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8630 %{ 8631 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8632 8633 expand %{ 8634 rorL_rReg_imm1(dst, cr); 8635 %} 8636 %} 8637 8638 // Rotate Right by 8-bit immediate 8639 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8640 %{ 8641 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8642 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8643 8644 expand %{ 8645 rorL_rReg_imm8(dst, rshift, cr); 8646 %} 8647 %} 8648 8649 // Rotate Right by variable 8650 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8651 %{ 8652 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8653 8654 expand %{ 8655 rorL_rReg_CL(dst, shift, cr); 8656 %} 8657 %} 8658 8659 // Rotate Right by variable 8660 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8661 %{ 8662 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8663 8664 expand %{ 8665 rorL_rReg_CL(dst, shift, cr); 8666 %} 8667 %} 8668 8669 // Logical Instructions 8670 8671 // Integer Logical Instructions 8672 8673 // And Instructions 8674 // And Register with Register 8675 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8676 %{ 8677 match(Set dst (AndI dst src)); 8678 effect(KILL cr); 8679 8680 format %{ "andl $dst, $src\t# int" %} 8681 opcode(0x23); 8682 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8683 ins_pipe(ialu_reg_reg); 8684 %} 8685 8686 // And Register with Immediate 255 8687 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 8688 %{ 8689 match(Set dst (AndI dst src)); 8690 8691 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 8692 opcode(0x0F, 0xB6); 8693 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8694 ins_pipe(ialu_reg); 8695 %} 8696 8697 // And Register with Immediate 255 and promote to long 8698 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8699 %{ 8700 match(Set dst (ConvI2L (AndI src mask))); 8701 8702 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8703 opcode(0x0F, 0xB6); 8704 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8705 ins_pipe(ialu_reg); 8706 %} 8707 8708 // And Register with Immediate 65535 8709 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 8710 %{ 8711 match(Set dst (AndI dst src)); 8712 8713 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 8714 opcode(0x0F, 0xB7); 8715 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8716 ins_pipe(ialu_reg); 8717 %} 8718 8719 // And Register with Immediate 65535 and promote to long 8720 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8721 %{ 8722 match(Set dst (ConvI2L (AndI src mask))); 8723 8724 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8725 opcode(0x0F, 0xB7); 8726 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8727 ins_pipe(ialu_reg); 8728 %} 8729 8730 // And Register with Immediate 8731 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8732 %{ 8733 match(Set dst (AndI dst src)); 8734 effect(KILL cr); 8735 8736 format %{ "andl $dst, $src\t# int" %} 8737 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8738 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8739 ins_pipe(ialu_reg); 8740 %} 8741 8742 // And Register with Memory 8743 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8744 %{ 8745 match(Set dst (AndI dst (LoadI src))); 8746 effect(KILL cr); 8747 8748 ins_cost(125); 8749 format %{ "andl $dst, $src\t# int" %} 8750 opcode(0x23); 8751 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8752 ins_pipe(ialu_reg_mem); 8753 %} 8754 8755 // And Memory with Register 8756 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8757 %{ 8758 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8759 effect(KILL cr); 8760 8761 ins_cost(150); 8762 format %{ "andl $dst, $src\t# int" %} 8763 opcode(0x21); /* Opcode 21 /r */ 8764 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8765 ins_pipe(ialu_mem_reg); 8766 %} 8767 8768 // And Memory with Immediate 8769 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8770 %{ 8771 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8772 effect(KILL cr); 8773 8774 ins_cost(125); 8775 format %{ "andl $dst, $src\t# int" %} 8776 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 8777 ins_encode(REX_mem(dst), OpcSE(src), 8778 RM_opc_mem(secondary, dst), Con8or32(src)); 8779 ins_pipe(ialu_mem_imm); 8780 %} 8781 8782 // BMI1 instructions 8783 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8784 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8785 predicate(UseBMI1Instructions); 8786 effect(KILL cr); 8787 8788 ins_cost(125); 8789 format %{ "andnl $dst, $src1, $src2" %} 8790 8791 ins_encode %{ 8792 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8793 %} 8794 ins_pipe(ialu_reg_mem); 8795 %} 8796 8797 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8798 match(Set dst (AndI (XorI src1 minus_1) src2)); 8799 predicate(UseBMI1Instructions); 8800 effect(KILL cr); 8801 8802 format %{ "andnl $dst, $src1, $src2" %} 8803 8804 ins_encode %{ 8805 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8806 %} 8807 ins_pipe(ialu_reg); 8808 %} 8809 8810 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 8811 match(Set dst (AndI (SubI imm_zero src) src)); 8812 predicate(UseBMI1Instructions); 8813 effect(KILL cr); 8814 8815 format %{ "blsil $dst, $src" %} 8816 8817 ins_encode %{ 8818 __ blsil($dst$$Register, $src$$Register); 8819 %} 8820 ins_pipe(ialu_reg); 8821 %} 8822 8823 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 8824 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 8825 predicate(UseBMI1Instructions); 8826 effect(KILL cr); 8827 8828 ins_cost(125); 8829 format %{ "blsil $dst, $src" %} 8830 8831 ins_encode %{ 8832 __ blsil($dst$$Register, $src$$Address); 8833 %} 8834 ins_pipe(ialu_reg_mem); 8835 %} 8836 8837 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8838 %{ 8839 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8840 predicate(UseBMI1Instructions); 8841 effect(KILL cr); 8842 8843 ins_cost(125); 8844 format %{ "blsmskl $dst, $src" %} 8845 8846 ins_encode %{ 8847 __ blsmskl($dst$$Register, $src$$Address); 8848 %} 8849 ins_pipe(ialu_reg_mem); 8850 %} 8851 8852 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8853 %{ 8854 match(Set dst (XorI (AddI src minus_1) src)); 8855 predicate(UseBMI1Instructions); 8856 effect(KILL cr); 8857 8858 format %{ "blsmskl $dst, $src" %} 8859 8860 ins_encode %{ 8861 __ blsmskl($dst$$Register, $src$$Register); 8862 %} 8863 8864 ins_pipe(ialu_reg); 8865 %} 8866 8867 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8868 %{ 8869 match(Set dst (AndI (AddI src minus_1) src) ); 8870 predicate(UseBMI1Instructions); 8871 effect(KILL cr); 8872 8873 format %{ "blsrl $dst, $src" %} 8874 8875 ins_encode %{ 8876 __ blsrl($dst$$Register, $src$$Register); 8877 %} 8878 8879 ins_pipe(ialu_reg_mem); 8880 %} 8881 8882 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8883 %{ 8884 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8885 predicate(UseBMI1Instructions); 8886 effect(KILL cr); 8887 8888 ins_cost(125); 8889 format %{ "blsrl $dst, $src" %} 8890 8891 ins_encode %{ 8892 __ blsrl($dst$$Register, $src$$Address); 8893 %} 8894 8895 ins_pipe(ialu_reg); 8896 %} 8897 8898 // Or Instructions 8899 // Or Register with Register 8900 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8901 %{ 8902 match(Set dst (OrI dst src)); 8903 effect(KILL cr); 8904 8905 format %{ "orl $dst, $src\t# int" %} 8906 opcode(0x0B); 8907 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8908 ins_pipe(ialu_reg_reg); 8909 %} 8910 8911 // Or Register with Immediate 8912 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8913 %{ 8914 match(Set dst (OrI dst src)); 8915 effect(KILL cr); 8916 8917 format %{ "orl $dst, $src\t# int" %} 8918 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 8919 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8920 ins_pipe(ialu_reg); 8921 %} 8922 8923 // Or Register with Memory 8924 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8925 %{ 8926 match(Set dst (OrI dst (LoadI src))); 8927 effect(KILL cr); 8928 8929 ins_cost(125); 8930 format %{ "orl $dst, $src\t# int" %} 8931 opcode(0x0B); 8932 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8933 ins_pipe(ialu_reg_mem); 8934 %} 8935 8936 // Or Memory with Register 8937 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8938 %{ 8939 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8940 effect(KILL cr); 8941 8942 ins_cost(150); 8943 format %{ "orl $dst, $src\t# int" %} 8944 opcode(0x09); /* Opcode 09 /r */ 8945 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8946 ins_pipe(ialu_mem_reg); 8947 %} 8948 8949 // Or Memory with Immediate 8950 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 8951 %{ 8952 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8953 effect(KILL cr); 8954 8955 ins_cost(125); 8956 format %{ "orl $dst, $src\t# int" %} 8957 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 8958 ins_encode(REX_mem(dst), OpcSE(src), 8959 RM_opc_mem(secondary, dst), Con8or32(src)); 8960 ins_pipe(ialu_mem_imm); 8961 %} 8962 8963 // Xor Instructions 8964 // Xor Register with Register 8965 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8966 %{ 8967 match(Set dst (XorI dst src)); 8968 effect(KILL cr); 8969 8970 format %{ "xorl $dst, $src\t# int" %} 8971 opcode(0x33); 8972 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8973 ins_pipe(ialu_reg_reg); 8974 %} 8975 8976 // Xor Register with Immediate -1 8977 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 8978 match(Set dst (XorI dst imm)); 8979 8980 format %{ "not $dst" %} 8981 ins_encode %{ 8982 __ notl($dst$$Register); 8983 %} 8984 ins_pipe(ialu_reg); 8985 %} 8986 8987 // Xor Register with Immediate 8988 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8989 %{ 8990 match(Set dst (XorI dst src)); 8991 effect(KILL cr); 8992 8993 format %{ "xorl $dst, $src\t# int" %} 8994 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 8995 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8996 ins_pipe(ialu_reg); 8997 %} 8998 8999 // Xor Register with Memory 9000 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9001 %{ 9002 match(Set dst (XorI dst (LoadI src))); 9003 effect(KILL cr); 9004 9005 ins_cost(125); 9006 format %{ "xorl $dst, $src\t# int" %} 9007 opcode(0x33); 9008 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9009 ins_pipe(ialu_reg_mem); 9010 %} 9011 9012 // Xor Memory with Register 9013 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9014 %{ 9015 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9016 effect(KILL cr); 9017 9018 ins_cost(150); 9019 format %{ "xorl $dst, $src\t# int" %} 9020 opcode(0x31); /* Opcode 31 /r */ 9021 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9022 ins_pipe(ialu_mem_reg); 9023 %} 9024 9025 // Xor Memory with Immediate 9026 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9027 %{ 9028 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9029 effect(KILL cr); 9030 9031 ins_cost(125); 9032 format %{ "xorl $dst, $src\t# int" %} 9033 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9034 ins_encode(REX_mem(dst), OpcSE(src), 9035 RM_opc_mem(secondary, dst), Con8or32(src)); 9036 ins_pipe(ialu_mem_imm); 9037 %} 9038 9039 9040 // Long Logical Instructions 9041 9042 // And Instructions 9043 // And Register with Register 9044 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9045 %{ 9046 match(Set dst (AndL dst src)); 9047 effect(KILL cr); 9048 9049 format %{ "andq $dst, $src\t# long" %} 9050 opcode(0x23); 9051 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9052 ins_pipe(ialu_reg_reg); 9053 %} 9054 9055 // And Register with Immediate 255 9056 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9057 %{ 9058 match(Set dst (AndL dst src)); 9059 9060 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9061 opcode(0x0F, 0xB6); 9062 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9063 ins_pipe(ialu_reg); 9064 %} 9065 9066 // And Register with Immediate 65535 9067 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9068 %{ 9069 match(Set dst (AndL dst src)); 9070 9071 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9072 opcode(0x0F, 0xB7); 9073 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9074 ins_pipe(ialu_reg); 9075 %} 9076 9077 // And Register with Immediate 9078 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9079 %{ 9080 match(Set dst (AndL dst src)); 9081 effect(KILL cr); 9082 9083 format %{ "andq $dst, $src\t# long" %} 9084 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9085 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9086 ins_pipe(ialu_reg); 9087 %} 9088 9089 // And Register with Memory 9090 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9091 %{ 9092 match(Set dst (AndL dst (LoadL src))); 9093 effect(KILL cr); 9094 9095 ins_cost(125); 9096 format %{ "andq $dst, $src\t# long" %} 9097 opcode(0x23); 9098 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9099 ins_pipe(ialu_reg_mem); 9100 %} 9101 9102 // And Memory with Register 9103 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9104 %{ 9105 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9106 effect(KILL cr); 9107 9108 ins_cost(150); 9109 format %{ "andq $dst, $src\t# long" %} 9110 opcode(0x21); /* Opcode 21 /r */ 9111 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9112 ins_pipe(ialu_mem_reg); 9113 %} 9114 9115 // And Memory with Immediate 9116 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9117 %{ 9118 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9119 effect(KILL cr); 9120 9121 ins_cost(125); 9122 format %{ "andq $dst, $src\t# long" %} 9123 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9124 ins_encode(REX_mem_wide(dst), OpcSE(src), 9125 RM_opc_mem(secondary, dst), Con8or32(src)); 9126 ins_pipe(ialu_mem_imm); 9127 %} 9128 9129 // BMI1 instructions 9130 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9131 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9132 predicate(UseBMI1Instructions); 9133 effect(KILL cr); 9134 9135 ins_cost(125); 9136 format %{ "andnq $dst, $src1, $src2" %} 9137 9138 ins_encode %{ 9139 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9140 %} 9141 ins_pipe(ialu_reg_mem); 9142 %} 9143 9144 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9145 match(Set dst (AndL (XorL src1 minus_1) src2)); 9146 predicate(UseBMI1Instructions); 9147 effect(KILL cr); 9148 9149 format %{ "andnq $dst, $src1, $src2" %} 9150 9151 ins_encode %{ 9152 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9153 %} 9154 ins_pipe(ialu_reg_mem); 9155 %} 9156 9157 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9158 match(Set dst (AndL (SubL imm_zero src) src)); 9159 predicate(UseBMI1Instructions); 9160 effect(KILL cr); 9161 9162 format %{ "blsiq $dst, $src" %} 9163 9164 ins_encode %{ 9165 __ blsiq($dst$$Register, $src$$Register); 9166 %} 9167 ins_pipe(ialu_reg); 9168 %} 9169 9170 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9171 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9172 predicate(UseBMI1Instructions); 9173 effect(KILL cr); 9174 9175 ins_cost(125); 9176 format %{ "blsiq $dst, $src" %} 9177 9178 ins_encode %{ 9179 __ blsiq($dst$$Register, $src$$Address); 9180 %} 9181 ins_pipe(ialu_reg_mem); 9182 %} 9183 9184 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9185 %{ 9186 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9187 predicate(UseBMI1Instructions); 9188 effect(KILL cr); 9189 9190 ins_cost(125); 9191 format %{ "blsmskq $dst, $src" %} 9192 9193 ins_encode %{ 9194 __ blsmskq($dst$$Register, $src$$Address); 9195 %} 9196 ins_pipe(ialu_reg_mem); 9197 %} 9198 9199 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9200 %{ 9201 match(Set dst (XorL (AddL src minus_1) src)); 9202 predicate(UseBMI1Instructions); 9203 effect(KILL cr); 9204 9205 format %{ "blsmskq $dst, $src" %} 9206 9207 ins_encode %{ 9208 __ blsmskq($dst$$Register, $src$$Register); 9209 %} 9210 9211 ins_pipe(ialu_reg); 9212 %} 9213 9214 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9215 %{ 9216 match(Set dst (AndL (AddL src minus_1) src) ); 9217 predicate(UseBMI1Instructions); 9218 effect(KILL cr); 9219 9220 format %{ "blsrq $dst, $src" %} 9221 9222 ins_encode %{ 9223 __ blsrq($dst$$Register, $src$$Register); 9224 %} 9225 9226 ins_pipe(ialu_reg); 9227 %} 9228 9229 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9230 %{ 9231 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9232 predicate(UseBMI1Instructions); 9233 effect(KILL cr); 9234 9235 ins_cost(125); 9236 format %{ "blsrq $dst, $src" %} 9237 9238 ins_encode %{ 9239 __ blsrq($dst$$Register, $src$$Address); 9240 %} 9241 9242 ins_pipe(ialu_reg); 9243 %} 9244 9245 // Or Instructions 9246 // Or Register with Register 9247 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9248 %{ 9249 match(Set dst (OrL dst src)); 9250 effect(KILL cr); 9251 9252 format %{ "orq $dst, $src\t# long" %} 9253 opcode(0x0B); 9254 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9255 ins_pipe(ialu_reg_reg); 9256 %} 9257 9258 // Use any_RegP to match R15 (TLS register) without spilling. 9259 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9260 match(Set dst (OrL dst (CastP2X src))); 9261 effect(KILL cr); 9262 9263 format %{ "orq $dst, $src\t# long" %} 9264 opcode(0x0B); 9265 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9266 ins_pipe(ialu_reg_reg); 9267 %} 9268 9269 9270 // Or Register with Immediate 9271 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9272 %{ 9273 match(Set dst (OrL dst src)); 9274 effect(KILL cr); 9275 9276 format %{ "orq $dst, $src\t# long" %} 9277 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9278 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9279 ins_pipe(ialu_reg); 9280 %} 9281 9282 // Or Register with Memory 9283 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9284 %{ 9285 match(Set dst (OrL dst (LoadL src))); 9286 effect(KILL cr); 9287 9288 ins_cost(125); 9289 format %{ "orq $dst, $src\t# long" %} 9290 opcode(0x0B); 9291 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9292 ins_pipe(ialu_reg_mem); 9293 %} 9294 9295 // Or Memory with Register 9296 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9297 %{ 9298 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9299 effect(KILL cr); 9300 9301 ins_cost(150); 9302 format %{ "orq $dst, $src\t# long" %} 9303 opcode(0x09); /* Opcode 09 /r */ 9304 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9305 ins_pipe(ialu_mem_reg); 9306 %} 9307 9308 // Or Memory with Immediate 9309 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9310 %{ 9311 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9312 effect(KILL cr); 9313 9314 ins_cost(125); 9315 format %{ "orq $dst, $src\t# long" %} 9316 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9317 ins_encode(REX_mem_wide(dst), OpcSE(src), 9318 RM_opc_mem(secondary, dst), Con8or32(src)); 9319 ins_pipe(ialu_mem_imm); 9320 %} 9321 9322 // Xor Instructions 9323 // Xor Register with Register 9324 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9325 %{ 9326 match(Set dst (XorL dst src)); 9327 effect(KILL cr); 9328 9329 format %{ "xorq $dst, $src\t# long" %} 9330 opcode(0x33); 9331 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9332 ins_pipe(ialu_reg_reg); 9333 %} 9334 9335 // Xor Register with Immediate -1 9336 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9337 match(Set dst (XorL dst imm)); 9338 9339 format %{ "notq $dst" %} 9340 ins_encode %{ 9341 __ notq($dst$$Register); 9342 %} 9343 ins_pipe(ialu_reg); 9344 %} 9345 9346 // Xor Register with Immediate 9347 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9348 %{ 9349 match(Set dst (XorL dst src)); 9350 effect(KILL cr); 9351 9352 format %{ "xorq $dst, $src\t# long" %} 9353 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9354 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9355 ins_pipe(ialu_reg); 9356 %} 9357 9358 // Xor Register with Memory 9359 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9360 %{ 9361 match(Set dst (XorL dst (LoadL src))); 9362 effect(KILL cr); 9363 9364 ins_cost(125); 9365 format %{ "xorq $dst, $src\t# long" %} 9366 opcode(0x33); 9367 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9368 ins_pipe(ialu_reg_mem); 9369 %} 9370 9371 // Xor Memory with Register 9372 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9373 %{ 9374 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9375 effect(KILL cr); 9376 9377 ins_cost(150); 9378 format %{ "xorq $dst, $src\t# long" %} 9379 opcode(0x31); /* Opcode 31 /r */ 9380 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9381 ins_pipe(ialu_mem_reg); 9382 %} 9383 9384 // Xor Memory with Immediate 9385 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9386 %{ 9387 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9388 effect(KILL cr); 9389 9390 ins_cost(125); 9391 format %{ "xorq $dst, $src\t# long" %} 9392 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9393 ins_encode(REX_mem_wide(dst), OpcSE(src), 9394 RM_opc_mem(secondary, dst), Con8or32(src)); 9395 ins_pipe(ialu_mem_imm); 9396 %} 9397 9398 // Convert Int to Boolean 9399 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9400 %{ 9401 match(Set dst (Conv2B src)); 9402 effect(KILL cr); 9403 9404 format %{ "testl $src, $src\t# ci2b\n\t" 9405 "setnz $dst\n\t" 9406 "movzbl $dst, $dst" %} 9407 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9408 setNZ_reg(dst), 9409 REX_reg_breg(dst, dst), // movzbl 9410 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9411 ins_pipe(pipe_slow); // XXX 9412 %} 9413 9414 // Convert Pointer to Boolean 9415 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9416 %{ 9417 match(Set dst (Conv2B src)); 9418 effect(KILL cr); 9419 9420 format %{ "testq $src, $src\t# cp2b\n\t" 9421 "setnz $dst\n\t" 9422 "movzbl $dst, $dst" %} 9423 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9424 setNZ_reg(dst), 9425 REX_reg_breg(dst, dst), // movzbl 9426 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9427 ins_pipe(pipe_slow); // XXX 9428 %} 9429 9430 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9431 %{ 9432 match(Set dst (CmpLTMask p q)); 9433 effect(KILL cr); 9434 9435 ins_cost(400); 9436 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9437 "setlt $dst\n\t" 9438 "movzbl $dst, $dst\n\t" 9439 "negl $dst" %} 9440 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9441 setLT_reg(dst), 9442 REX_reg_breg(dst, dst), // movzbl 9443 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9444 neg_reg(dst)); 9445 ins_pipe(pipe_slow); 9446 %} 9447 9448 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9449 %{ 9450 match(Set dst (CmpLTMask dst zero)); 9451 effect(KILL cr); 9452 9453 ins_cost(100); 9454 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9455 ins_encode %{ 9456 __ sarl($dst$$Register, 31); 9457 %} 9458 ins_pipe(ialu_reg); 9459 %} 9460 9461 /* Better to save a register than avoid a branch */ 9462 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9463 %{ 9464 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9465 effect(KILL cr); 9466 ins_cost(300); 9467 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9468 "jge done\n\t" 9469 "addl $p,$y\n" 9470 "done: " %} 9471 ins_encode %{ 9472 Register Rp = $p$$Register; 9473 Register Rq = $q$$Register; 9474 Register Ry = $y$$Register; 9475 Label done; 9476 __ subl(Rp, Rq); 9477 __ jccb(Assembler::greaterEqual, done); 9478 __ addl(Rp, Ry); 9479 __ bind(done); 9480 %} 9481 ins_pipe(pipe_cmplt); 9482 %} 9483 9484 /* Better to save a register than avoid a branch */ 9485 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9486 %{ 9487 match(Set y (AndI (CmpLTMask p q) y)); 9488 effect(KILL cr); 9489 9490 ins_cost(300); 9491 9492 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9493 "jlt done\n\t" 9494 "xorl $y, $y\n" 9495 "done: " %} 9496 ins_encode %{ 9497 Register Rp = $p$$Register; 9498 Register Rq = $q$$Register; 9499 Register Ry = $y$$Register; 9500 Label done; 9501 __ cmpl(Rp, Rq); 9502 __ jccb(Assembler::less, done); 9503 __ xorl(Ry, Ry); 9504 __ bind(done); 9505 %} 9506 ins_pipe(pipe_cmplt); 9507 %} 9508 9509 9510 //---------- FP Instructions------------------------------------------------ 9511 9512 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9513 %{ 9514 match(Set cr (CmpF src1 src2)); 9515 9516 ins_cost(145); 9517 format %{ "ucomiss $src1, $src2\n\t" 9518 "jnp,s exit\n\t" 9519 "pushfq\t# saw NaN, set CF\n\t" 9520 "andq [rsp], #0xffffff2b\n\t" 9521 "popfq\n" 9522 "exit:" %} 9523 ins_encode %{ 9524 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9525 emit_cmpfp_fixup(_masm); 9526 %} 9527 ins_pipe(pipe_slow); 9528 %} 9529 9530 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9531 match(Set cr (CmpF src1 src2)); 9532 9533 ins_cost(100); 9534 format %{ "ucomiss $src1, $src2" %} 9535 ins_encode %{ 9536 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9537 %} 9538 ins_pipe(pipe_slow); 9539 %} 9540 9541 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9542 %{ 9543 match(Set cr (CmpF src1 (LoadF src2))); 9544 9545 ins_cost(145); 9546 format %{ "ucomiss $src1, $src2\n\t" 9547 "jnp,s exit\n\t" 9548 "pushfq\t# saw NaN, set CF\n\t" 9549 "andq [rsp], #0xffffff2b\n\t" 9550 "popfq\n" 9551 "exit:" %} 9552 ins_encode %{ 9553 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9554 emit_cmpfp_fixup(_masm); 9555 %} 9556 ins_pipe(pipe_slow); 9557 %} 9558 9559 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9560 match(Set cr (CmpF src1 (LoadF src2))); 9561 9562 ins_cost(100); 9563 format %{ "ucomiss $src1, $src2" %} 9564 ins_encode %{ 9565 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9566 %} 9567 ins_pipe(pipe_slow); 9568 %} 9569 9570 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9571 match(Set cr (CmpF src con)); 9572 9573 ins_cost(145); 9574 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9575 "jnp,s exit\n\t" 9576 "pushfq\t# saw NaN, set CF\n\t" 9577 "andq [rsp], #0xffffff2b\n\t" 9578 "popfq\n" 9579 "exit:" %} 9580 ins_encode %{ 9581 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9582 emit_cmpfp_fixup(_masm); 9583 %} 9584 ins_pipe(pipe_slow); 9585 %} 9586 9587 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9588 match(Set cr (CmpF src con)); 9589 ins_cost(100); 9590 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9591 ins_encode %{ 9592 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9593 %} 9594 ins_pipe(pipe_slow); 9595 %} 9596 9597 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9598 %{ 9599 match(Set cr (CmpD src1 src2)); 9600 9601 ins_cost(145); 9602 format %{ "ucomisd $src1, $src2\n\t" 9603 "jnp,s exit\n\t" 9604 "pushfq\t# saw NaN, set CF\n\t" 9605 "andq [rsp], #0xffffff2b\n\t" 9606 "popfq\n" 9607 "exit:" %} 9608 ins_encode %{ 9609 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9610 emit_cmpfp_fixup(_masm); 9611 %} 9612 ins_pipe(pipe_slow); 9613 %} 9614 9615 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9616 match(Set cr (CmpD src1 src2)); 9617 9618 ins_cost(100); 9619 format %{ "ucomisd $src1, $src2 test" %} 9620 ins_encode %{ 9621 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9622 %} 9623 ins_pipe(pipe_slow); 9624 %} 9625 9626 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9627 %{ 9628 match(Set cr (CmpD src1 (LoadD src2))); 9629 9630 ins_cost(145); 9631 format %{ "ucomisd $src1, $src2\n\t" 9632 "jnp,s exit\n\t" 9633 "pushfq\t# saw NaN, set CF\n\t" 9634 "andq [rsp], #0xffffff2b\n\t" 9635 "popfq\n" 9636 "exit:" %} 9637 ins_encode %{ 9638 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9639 emit_cmpfp_fixup(_masm); 9640 %} 9641 ins_pipe(pipe_slow); 9642 %} 9643 9644 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9645 match(Set cr (CmpD src1 (LoadD src2))); 9646 9647 ins_cost(100); 9648 format %{ "ucomisd $src1, $src2" %} 9649 ins_encode %{ 9650 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9651 %} 9652 ins_pipe(pipe_slow); 9653 %} 9654 9655 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9656 match(Set cr (CmpD src con)); 9657 9658 ins_cost(145); 9659 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9660 "jnp,s exit\n\t" 9661 "pushfq\t# saw NaN, set CF\n\t" 9662 "andq [rsp], #0xffffff2b\n\t" 9663 "popfq\n" 9664 "exit:" %} 9665 ins_encode %{ 9666 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9667 emit_cmpfp_fixup(_masm); 9668 %} 9669 ins_pipe(pipe_slow); 9670 %} 9671 9672 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9673 match(Set cr (CmpD src con)); 9674 ins_cost(100); 9675 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9676 ins_encode %{ 9677 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9678 %} 9679 ins_pipe(pipe_slow); 9680 %} 9681 9682 // Compare into -1,0,1 9683 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9684 %{ 9685 match(Set dst (CmpF3 src1 src2)); 9686 effect(KILL cr); 9687 9688 ins_cost(275); 9689 format %{ "ucomiss $src1, $src2\n\t" 9690 "movl $dst, #-1\n\t" 9691 "jp,s done\n\t" 9692 "jb,s done\n\t" 9693 "setne $dst\n\t" 9694 "movzbl $dst, $dst\n" 9695 "done:" %} 9696 ins_encode %{ 9697 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9698 emit_cmpfp3(_masm, $dst$$Register); 9699 %} 9700 ins_pipe(pipe_slow); 9701 %} 9702 9703 // Compare into -1,0,1 9704 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9705 %{ 9706 match(Set dst (CmpF3 src1 (LoadF src2))); 9707 effect(KILL cr); 9708 9709 ins_cost(275); 9710 format %{ "ucomiss $src1, $src2\n\t" 9711 "movl $dst, #-1\n\t" 9712 "jp,s done\n\t" 9713 "jb,s done\n\t" 9714 "setne $dst\n\t" 9715 "movzbl $dst, $dst\n" 9716 "done:" %} 9717 ins_encode %{ 9718 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9719 emit_cmpfp3(_masm, $dst$$Register); 9720 %} 9721 ins_pipe(pipe_slow); 9722 %} 9723 9724 // Compare into -1,0,1 9725 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9726 match(Set dst (CmpF3 src con)); 9727 effect(KILL cr); 9728 9729 ins_cost(275); 9730 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9731 "movl $dst, #-1\n\t" 9732 "jp,s done\n\t" 9733 "jb,s done\n\t" 9734 "setne $dst\n\t" 9735 "movzbl $dst, $dst\n" 9736 "done:" %} 9737 ins_encode %{ 9738 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9739 emit_cmpfp3(_masm, $dst$$Register); 9740 %} 9741 ins_pipe(pipe_slow); 9742 %} 9743 9744 // Compare into -1,0,1 9745 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9746 %{ 9747 match(Set dst (CmpD3 src1 src2)); 9748 effect(KILL cr); 9749 9750 ins_cost(275); 9751 format %{ "ucomisd $src1, $src2\n\t" 9752 "movl $dst, #-1\n\t" 9753 "jp,s done\n\t" 9754 "jb,s done\n\t" 9755 "setne $dst\n\t" 9756 "movzbl $dst, $dst\n" 9757 "done:" %} 9758 ins_encode %{ 9759 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9760 emit_cmpfp3(_masm, $dst$$Register); 9761 %} 9762 ins_pipe(pipe_slow); 9763 %} 9764 9765 // Compare into -1,0,1 9766 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9767 %{ 9768 match(Set dst (CmpD3 src1 (LoadD src2))); 9769 effect(KILL cr); 9770 9771 ins_cost(275); 9772 format %{ "ucomisd $src1, $src2\n\t" 9773 "movl $dst, #-1\n\t" 9774 "jp,s done\n\t" 9775 "jb,s done\n\t" 9776 "setne $dst\n\t" 9777 "movzbl $dst, $dst\n" 9778 "done:" %} 9779 ins_encode %{ 9780 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9781 emit_cmpfp3(_masm, $dst$$Register); 9782 %} 9783 ins_pipe(pipe_slow); 9784 %} 9785 9786 // Compare into -1,0,1 9787 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9788 match(Set dst (CmpD3 src con)); 9789 effect(KILL cr); 9790 9791 ins_cost(275); 9792 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9793 "movl $dst, #-1\n\t" 9794 "jp,s done\n\t" 9795 "jb,s done\n\t" 9796 "setne $dst\n\t" 9797 "movzbl $dst, $dst\n" 9798 "done:" %} 9799 ins_encode %{ 9800 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9801 emit_cmpfp3(_masm, $dst$$Register); 9802 %} 9803 ins_pipe(pipe_slow); 9804 %} 9805 9806 // -----------Trig and Trancendental Instructions------------------------------ 9807 instruct cosD_reg(regD dst) %{ 9808 match(Set dst (CosD dst)); 9809 9810 format %{ "dcos $dst\n\t" %} 9811 opcode(0xD9, 0xFF); 9812 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9813 ins_pipe( pipe_slow ); 9814 %} 9815 9816 instruct sinD_reg(regD dst) %{ 9817 match(Set dst (SinD dst)); 9818 9819 format %{ "dsin $dst\n\t" %} 9820 opcode(0xD9, 0xFE); 9821 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9822 ins_pipe( pipe_slow ); 9823 %} 9824 9825 instruct tanD_reg(regD dst) %{ 9826 match(Set dst (TanD dst)); 9827 9828 format %{ "dtan $dst\n\t" %} 9829 ins_encode( Push_SrcXD(dst), 9830 Opcode(0xD9), Opcode(0xF2), //fptan 9831 Opcode(0xDD), Opcode(0xD8), //fstp st 9832 Push_ResultXD(dst) ); 9833 ins_pipe( pipe_slow ); 9834 %} 9835 9836 instruct log10D_reg(regD dst) %{ 9837 // The source and result Double operands in XMM registers 9838 match(Set dst (Log10D dst)); 9839 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 9840 // fyl2x ; compute log_10(2) * log_2(x) 9841 format %{ "fldlg2\t\t\t#Log10\n\t" 9842 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 9843 %} 9844 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 9845 Push_SrcXD(dst), 9846 Opcode(0xD9), Opcode(0xF1), // fyl2x 9847 Push_ResultXD(dst)); 9848 9849 ins_pipe( pipe_slow ); 9850 %} 9851 9852 instruct logD_reg(regD dst) %{ 9853 // The source and result Double operands in XMM registers 9854 match(Set dst (LogD dst)); 9855 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 9856 // fyl2x ; compute log_e(2) * log_2(x) 9857 format %{ "fldln2\t\t\t#Log_e\n\t" 9858 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 9859 %} 9860 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 9861 Push_SrcXD(dst), 9862 Opcode(0xD9), Opcode(0xF1), // fyl2x 9863 Push_ResultXD(dst)); 9864 ins_pipe( pipe_slow ); 9865 %} 9866 9867 instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9868 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power 9869 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); 9870 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %} 9871 ins_encode %{ 9872 __ subptr(rsp, 8); 9873 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); 9874 __ fld_d(Address(rsp, 0)); 9875 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); 9876 __ fld_d(Address(rsp, 0)); 9877 __ fast_pow(); 9878 __ fstp_d(Address(rsp, 0)); 9879 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9880 __ addptr(rsp, 8); 9881 %} 9882 ins_pipe( pipe_slow ); 9883 %} 9884 9885 instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9886 match(Set dst (ExpD src)); 9887 effect(KILL rax, KILL rcx, KILL rdx, KILL cr); 9888 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %} 9889 ins_encode %{ 9890 __ subptr(rsp, 8); 9891 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9892 __ fld_d(Address(rsp, 0)); 9893 __ fast_exp(); 9894 __ fstp_d(Address(rsp, 0)); 9895 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9896 __ addptr(rsp, 8); 9897 %} 9898 ins_pipe( pipe_slow ); 9899 %} 9900 9901 //----------Arithmetic Conversion Instructions--------------------------------- 9902 9903 instruct roundFloat_nop(regF dst) 9904 %{ 9905 match(Set dst (RoundFloat dst)); 9906 9907 ins_cost(0); 9908 ins_encode(); 9909 ins_pipe(empty); 9910 %} 9911 9912 instruct roundDouble_nop(regD dst) 9913 %{ 9914 match(Set dst (RoundDouble dst)); 9915 9916 ins_cost(0); 9917 ins_encode(); 9918 ins_pipe(empty); 9919 %} 9920 9921 instruct convF2D_reg_reg(regD dst, regF src) 9922 %{ 9923 match(Set dst (ConvF2D src)); 9924 9925 format %{ "cvtss2sd $dst, $src" %} 9926 ins_encode %{ 9927 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 9928 %} 9929 ins_pipe(pipe_slow); // XXX 9930 %} 9931 9932 instruct convF2D_reg_mem(regD dst, memory src) 9933 %{ 9934 match(Set dst (ConvF2D (LoadF src))); 9935 9936 format %{ "cvtss2sd $dst, $src" %} 9937 ins_encode %{ 9938 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 9939 %} 9940 ins_pipe(pipe_slow); // XXX 9941 %} 9942 9943 instruct convD2F_reg_reg(regF dst, regD src) 9944 %{ 9945 match(Set dst (ConvD2F src)); 9946 9947 format %{ "cvtsd2ss $dst, $src" %} 9948 ins_encode %{ 9949 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 9950 %} 9951 ins_pipe(pipe_slow); // XXX 9952 %} 9953 9954 instruct convD2F_reg_mem(regF dst, memory src) 9955 %{ 9956 match(Set dst (ConvD2F (LoadD src))); 9957 9958 format %{ "cvtsd2ss $dst, $src" %} 9959 ins_encode %{ 9960 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 9961 %} 9962 ins_pipe(pipe_slow); // XXX 9963 %} 9964 9965 // XXX do mem variants 9966 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9967 %{ 9968 match(Set dst (ConvF2I src)); 9969 effect(KILL cr); 9970 9971 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 9972 "cmpl $dst, #0x80000000\n\t" 9973 "jne,s done\n\t" 9974 "subq rsp, #8\n\t" 9975 "movss [rsp], $src\n\t" 9976 "call f2i_fixup\n\t" 9977 "popq $dst\n" 9978 "done: "%} 9979 ins_encode %{ 9980 Label done; 9981 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 9982 __ cmpl($dst$$Register, 0x80000000); 9983 __ jccb(Assembler::notEqual, done); 9984 __ subptr(rsp, 8); 9985 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9986 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 9987 __ pop($dst$$Register); 9988 __ bind(done); 9989 %} 9990 ins_pipe(pipe_slow); 9991 %} 9992 9993 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 9994 %{ 9995 match(Set dst (ConvF2L src)); 9996 effect(KILL cr); 9997 9998 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 9999 "cmpq $dst, [0x8000000000000000]\n\t" 10000 "jne,s done\n\t" 10001 "subq rsp, #8\n\t" 10002 "movss [rsp], $src\n\t" 10003 "call f2l_fixup\n\t" 10004 "popq $dst\n" 10005 "done: "%} 10006 ins_encode %{ 10007 Label done; 10008 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10009 __ cmp64($dst$$Register, 10010 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10011 __ jccb(Assembler::notEqual, done); 10012 __ subptr(rsp, 8); 10013 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10014 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10015 __ pop($dst$$Register); 10016 __ bind(done); 10017 %} 10018 ins_pipe(pipe_slow); 10019 %} 10020 10021 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10022 %{ 10023 match(Set dst (ConvD2I src)); 10024 effect(KILL cr); 10025 10026 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10027 "cmpl $dst, #0x80000000\n\t" 10028 "jne,s done\n\t" 10029 "subq rsp, #8\n\t" 10030 "movsd [rsp], $src\n\t" 10031 "call d2i_fixup\n\t" 10032 "popq $dst\n" 10033 "done: "%} 10034 ins_encode %{ 10035 Label done; 10036 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10037 __ cmpl($dst$$Register, 0x80000000); 10038 __ jccb(Assembler::notEqual, done); 10039 __ subptr(rsp, 8); 10040 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10041 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10042 __ pop($dst$$Register); 10043 __ bind(done); 10044 %} 10045 ins_pipe(pipe_slow); 10046 %} 10047 10048 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10049 %{ 10050 match(Set dst (ConvD2L src)); 10051 effect(KILL cr); 10052 10053 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10054 "cmpq $dst, [0x8000000000000000]\n\t" 10055 "jne,s done\n\t" 10056 "subq rsp, #8\n\t" 10057 "movsd [rsp], $src\n\t" 10058 "call d2l_fixup\n\t" 10059 "popq $dst\n" 10060 "done: "%} 10061 ins_encode %{ 10062 Label done; 10063 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10064 __ cmp64($dst$$Register, 10065 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10066 __ jccb(Assembler::notEqual, done); 10067 __ subptr(rsp, 8); 10068 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10069 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10070 __ pop($dst$$Register); 10071 __ bind(done); 10072 %} 10073 ins_pipe(pipe_slow); 10074 %} 10075 10076 instruct convI2F_reg_reg(regF dst, rRegI src) 10077 %{ 10078 predicate(!UseXmmI2F); 10079 match(Set dst (ConvI2F src)); 10080 10081 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10082 ins_encode %{ 10083 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10084 %} 10085 ins_pipe(pipe_slow); // XXX 10086 %} 10087 10088 instruct convI2F_reg_mem(regF dst, memory src) 10089 %{ 10090 match(Set dst (ConvI2F (LoadI src))); 10091 10092 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10093 ins_encode %{ 10094 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10095 %} 10096 ins_pipe(pipe_slow); // XXX 10097 %} 10098 10099 instruct convI2D_reg_reg(regD dst, rRegI src) 10100 %{ 10101 predicate(!UseXmmI2D); 10102 match(Set dst (ConvI2D src)); 10103 10104 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10105 ins_encode %{ 10106 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10107 %} 10108 ins_pipe(pipe_slow); // XXX 10109 %} 10110 10111 instruct convI2D_reg_mem(regD dst, memory src) 10112 %{ 10113 match(Set dst (ConvI2D (LoadI src))); 10114 10115 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10116 ins_encode %{ 10117 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10118 %} 10119 ins_pipe(pipe_slow); // XXX 10120 %} 10121 10122 instruct convXI2F_reg(regF dst, rRegI src) 10123 %{ 10124 predicate(UseXmmI2F); 10125 match(Set dst (ConvI2F src)); 10126 10127 format %{ "movdl $dst, $src\n\t" 10128 "cvtdq2psl $dst, $dst\t# i2f" %} 10129 ins_encode %{ 10130 __ movdl($dst$$XMMRegister, $src$$Register); 10131 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10132 %} 10133 ins_pipe(pipe_slow); // XXX 10134 %} 10135 10136 instruct convXI2D_reg(regD dst, rRegI src) 10137 %{ 10138 predicate(UseXmmI2D); 10139 match(Set dst (ConvI2D src)); 10140 10141 format %{ "movdl $dst, $src\n\t" 10142 "cvtdq2pdl $dst, $dst\t# i2d" %} 10143 ins_encode %{ 10144 __ movdl($dst$$XMMRegister, $src$$Register); 10145 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10146 %} 10147 ins_pipe(pipe_slow); // XXX 10148 %} 10149 10150 instruct convL2F_reg_reg(regF dst, rRegL src) 10151 %{ 10152 match(Set dst (ConvL2F src)); 10153 10154 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10155 ins_encode %{ 10156 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10157 %} 10158 ins_pipe(pipe_slow); // XXX 10159 %} 10160 10161 instruct convL2F_reg_mem(regF dst, memory src) 10162 %{ 10163 match(Set dst (ConvL2F (LoadL src))); 10164 10165 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10166 ins_encode %{ 10167 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10168 %} 10169 ins_pipe(pipe_slow); // XXX 10170 %} 10171 10172 instruct convL2D_reg_reg(regD dst, rRegL src) 10173 %{ 10174 match(Set dst (ConvL2D src)); 10175 10176 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10177 ins_encode %{ 10178 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10179 %} 10180 ins_pipe(pipe_slow); // XXX 10181 %} 10182 10183 instruct convL2D_reg_mem(regD dst, memory src) 10184 %{ 10185 match(Set dst (ConvL2D (LoadL src))); 10186 10187 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10188 ins_encode %{ 10189 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10190 %} 10191 ins_pipe(pipe_slow); // XXX 10192 %} 10193 10194 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10195 %{ 10196 match(Set dst (ConvI2L src)); 10197 10198 ins_cost(125); 10199 format %{ "movslq $dst, $src\t# i2l" %} 10200 ins_encode %{ 10201 __ movslq($dst$$Register, $src$$Register); 10202 %} 10203 ins_pipe(ialu_reg_reg); 10204 %} 10205 10206 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10207 // %{ 10208 // match(Set dst (ConvI2L src)); 10209 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10210 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10211 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10212 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10213 // ((const TypeNode*) n)->type()->is_long()->_lo == 10214 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10215 10216 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10217 // ins_encode(enc_copy(dst, src)); 10218 // // opcode(0x63); // needs REX.W 10219 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10220 // ins_pipe(ialu_reg_reg); 10221 // %} 10222 10223 // Zero-extend convert int to long 10224 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10225 %{ 10226 match(Set dst (AndL (ConvI2L src) mask)); 10227 10228 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10229 ins_encode %{ 10230 if ($dst$$reg != $src$$reg) { 10231 __ movl($dst$$Register, $src$$Register); 10232 } 10233 %} 10234 ins_pipe(ialu_reg_reg); 10235 %} 10236 10237 // Zero-extend convert int to long 10238 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10239 %{ 10240 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10241 10242 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10243 ins_encode %{ 10244 __ movl($dst$$Register, $src$$Address); 10245 %} 10246 ins_pipe(ialu_reg_mem); 10247 %} 10248 10249 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10250 %{ 10251 match(Set dst (AndL src mask)); 10252 10253 format %{ "movl $dst, $src\t# zero-extend long" %} 10254 ins_encode %{ 10255 __ movl($dst$$Register, $src$$Register); 10256 %} 10257 ins_pipe(ialu_reg_reg); 10258 %} 10259 10260 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10261 %{ 10262 match(Set dst (ConvL2I src)); 10263 10264 format %{ "movl $dst, $src\t# l2i" %} 10265 ins_encode %{ 10266 __ movl($dst$$Register, $src$$Register); 10267 %} 10268 ins_pipe(ialu_reg_reg); 10269 %} 10270 10271 10272 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10273 match(Set dst (MoveF2I src)); 10274 effect(DEF dst, USE src); 10275 10276 ins_cost(125); 10277 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10278 ins_encode %{ 10279 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10280 %} 10281 ins_pipe(ialu_reg_mem); 10282 %} 10283 10284 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10285 match(Set dst (MoveI2F src)); 10286 effect(DEF dst, USE src); 10287 10288 ins_cost(125); 10289 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10290 ins_encode %{ 10291 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10292 %} 10293 ins_pipe(pipe_slow); 10294 %} 10295 10296 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10297 match(Set dst (MoveD2L src)); 10298 effect(DEF dst, USE src); 10299 10300 ins_cost(125); 10301 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10302 ins_encode %{ 10303 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10304 %} 10305 ins_pipe(ialu_reg_mem); 10306 %} 10307 10308 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10309 predicate(!UseXmmLoadAndClearUpper); 10310 match(Set dst (MoveL2D src)); 10311 effect(DEF dst, USE src); 10312 10313 ins_cost(125); 10314 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10315 ins_encode %{ 10316 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10317 %} 10318 ins_pipe(pipe_slow); 10319 %} 10320 10321 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10322 predicate(UseXmmLoadAndClearUpper); 10323 match(Set dst (MoveL2D src)); 10324 effect(DEF dst, USE src); 10325 10326 ins_cost(125); 10327 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10328 ins_encode %{ 10329 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10330 %} 10331 ins_pipe(pipe_slow); 10332 %} 10333 10334 10335 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10336 match(Set dst (MoveF2I src)); 10337 effect(DEF dst, USE src); 10338 10339 ins_cost(95); // XXX 10340 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10341 ins_encode %{ 10342 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10343 %} 10344 ins_pipe(pipe_slow); 10345 %} 10346 10347 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10348 match(Set dst (MoveI2F src)); 10349 effect(DEF dst, USE src); 10350 10351 ins_cost(100); 10352 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10353 ins_encode %{ 10354 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10355 %} 10356 ins_pipe( ialu_mem_reg ); 10357 %} 10358 10359 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10360 match(Set dst (MoveD2L src)); 10361 effect(DEF dst, USE src); 10362 10363 ins_cost(95); // XXX 10364 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10365 ins_encode %{ 10366 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10367 %} 10368 ins_pipe(pipe_slow); 10369 %} 10370 10371 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10372 match(Set dst (MoveL2D src)); 10373 effect(DEF dst, USE src); 10374 10375 ins_cost(100); 10376 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10377 ins_encode %{ 10378 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10379 %} 10380 ins_pipe(ialu_mem_reg); 10381 %} 10382 10383 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10384 match(Set dst (MoveF2I src)); 10385 effect(DEF dst, USE src); 10386 ins_cost(85); 10387 format %{ "movd $dst,$src\t# MoveF2I" %} 10388 ins_encode %{ 10389 __ movdl($dst$$Register, $src$$XMMRegister); 10390 %} 10391 ins_pipe( pipe_slow ); 10392 %} 10393 10394 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10395 match(Set dst (MoveD2L src)); 10396 effect(DEF dst, USE src); 10397 ins_cost(85); 10398 format %{ "movd $dst,$src\t# MoveD2L" %} 10399 ins_encode %{ 10400 __ movdq($dst$$Register, $src$$XMMRegister); 10401 %} 10402 ins_pipe( pipe_slow ); 10403 %} 10404 10405 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10406 match(Set dst (MoveI2F src)); 10407 effect(DEF dst, USE src); 10408 ins_cost(100); 10409 format %{ "movd $dst,$src\t# MoveI2F" %} 10410 ins_encode %{ 10411 __ movdl($dst$$XMMRegister, $src$$Register); 10412 %} 10413 ins_pipe( pipe_slow ); 10414 %} 10415 10416 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10417 match(Set dst (MoveL2D src)); 10418 effect(DEF dst, USE src); 10419 ins_cost(100); 10420 format %{ "movd $dst,$src\t# MoveL2D" %} 10421 ins_encode %{ 10422 __ movdq($dst$$XMMRegister, $src$$Register); 10423 %} 10424 ins_pipe( pipe_slow ); 10425 %} 10426 10427 10428 // ======================================================================= 10429 // fast clearing of an array 10430 instruct rep_stos(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 10437 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10438 "rep stosq\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 rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10446 rFlagsReg cr) 10447 %{ 10448 predicate(UseFastStosb); 10449 match(Set dummy (ClearArray cnt base)); 10450 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10451 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10452 "shlq rcx,3\t# Convert doublewords to bytes\n\t" 10453 "rep stosb\t# Store rax to *rdi++ while rcx--" %} 10454 ins_encode %{ 10455 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10456 %} 10457 ins_pipe( pipe_slow ); 10458 %} 10459 10460 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10461 rax_RegI result, regD tmp1, rFlagsReg cr) 10462 %{ 10463 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10464 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10465 10466 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10467 ins_encode %{ 10468 __ string_compare($str1$$Register, $str2$$Register, 10469 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10470 $tmp1$$XMMRegister); 10471 %} 10472 ins_pipe( pipe_slow ); 10473 %} 10474 10475 // fast search of substring with known size. 10476 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10477 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10478 %{ 10479 predicate(UseSSE42Intrinsics); 10480 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10481 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10482 10483 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10484 ins_encode %{ 10485 int icnt2 = (int)$int_cnt2$$constant; 10486 if (icnt2 >= 8) { 10487 // IndexOf for constant substrings with size >= 8 elements 10488 // which don't need to be loaded through stack. 10489 __ string_indexofC8($str1$$Register, $str2$$Register, 10490 $cnt1$$Register, $cnt2$$Register, 10491 icnt2, $result$$Register, 10492 $vec$$XMMRegister, $tmp$$Register); 10493 } else { 10494 // Small strings are loaded through stack if they cross page boundary. 10495 __ string_indexof($str1$$Register, $str2$$Register, 10496 $cnt1$$Register, $cnt2$$Register, 10497 icnt2, $result$$Register, 10498 $vec$$XMMRegister, $tmp$$Register); 10499 } 10500 %} 10501 ins_pipe( pipe_slow ); 10502 %} 10503 10504 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10505 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10506 %{ 10507 predicate(UseSSE42Intrinsics); 10508 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10509 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10510 10511 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10512 ins_encode %{ 10513 __ string_indexof($str1$$Register, $str2$$Register, 10514 $cnt1$$Register, $cnt2$$Register, 10515 (-1), $result$$Register, 10516 $vec$$XMMRegister, $tmp$$Register); 10517 %} 10518 ins_pipe( pipe_slow ); 10519 %} 10520 10521 // fast string equals 10522 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10523 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10524 %{ 10525 match(Set result (StrEquals (Binary str1 str2) cnt)); 10526 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10527 10528 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10529 ins_encode %{ 10530 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 10531 $cnt$$Register, $result$$Register, $tmp3$$Register, 10532 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10533 %} 10534 ins_pipe( pipe_slow ); 10535 %} 10536 10537 // fast array equals 10538 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10539 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10540 %{ 10541 match(Set result (AryEq ary1 ary2)); 10542 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10543 //ins_cost(300); 10544 10545 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10546 ins_encode %{ 10547 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 10548 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10549 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10550 %} 10551 ins_pipe( pipe_slow ); 10552 %} 10553 10554 // encode char[] to byte[] in ISO_8859_1 10555 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 10556 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 10557 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 10558 match(Set result (EncodeISOArray src (Binary dst len))); 10559 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 10560 10561 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 10562 ins_encode %{ 10563 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 10564 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 10565 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 10566 %} 10567 ins_pipe( pipe_slow ); 10568 %} 10569 10570 //----------Overflow Math Instructions----------------------------------------- 10571 10572 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10573 %{ 10574 match(Set cr (OverflowAddI op1 op2)); 10575 effect(DEF cr, USE_KILL op1, USE op2); 10576 10577 format %{ "addl $op1, $op2\t# overflow check int" %} 10578 10579 ins_encode %{ 10580 __ addl($op1$$Register, $op2$$Register); 10581 %} 10582 ins_pipe(ialu_reg_reg); 10583 %} 10584 10585 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 10586 %{ 10587 match(Set cr (OverflowAddI op1 op2)); 10588 effect(DEF cr, USE_KILL op1, USE op2); 10589 10590 format %{ "addl $op1, $op2\t# overflow check int" %} 10591 10592 ins_encode %{ 10593 __ addl($op1$$Register, $op2$$constant); 10594 %} 10595 ins_pipe(ialu_reg_reg); 10596 %} 10597 10598 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10599 %{ 10600 match(Set cr (OverflowAddL op1 op2)); 10601 effect(DEF cr, USE_KILL op1, USE op2); 10602 10603 format %{ "addq $op1, $op2\t# overflow check long" %} 10604 ins_encode %{ 10605 __ addq($op1$$Register, $op2$$Register); 10606 %} 10607 ins_pipe(ialu_reg_reg); 10608 %} 10609 10610 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 10611 %{ 10612 match(Set cr (OverflowAddL op1 op2)); 10613 effect(DEF cr, USE_KILL op1, USE op2); 10614 10615 format %{ "addq $op1, $op2\t# overflow check long" %} 10616 ins_encode %{ 10617 __ addq($op1$$Register, $op2$$constant); 10618 %} 10619 ins_pipe(ialu_reg_reg); 10620 %} 10621 10622 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10623 %{ 10624 match(Set cr (OverflowSubI op1 op2)); 10625 10626 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10627 ins_encode %{ 10628 __ cmpl($op1$$Register, $op2$$Register); 10629 %} 10630 ins_pipe(ialu_reg_reg); 10631 %} 10632 10633 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10634 %{ 10635 match(Set cr (OverflowSubI op1 op2)); 10636 10637 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10638 ins_encode %{ 10639 __ cmpl($op1$$Register, $op2$$constant); 10640 %} 10641 ins_pipe(ialu_reg_reg); 10642 %} 10643 10644 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10645 %{ 10646 match(Set cr (OverflowSubL op1 op2)); 10647 10648 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10649 ins_encode %{ 10650 __ cmpq($op1$$Register, $op2$$Register); 10651 %} 10652 ins_pipe(ialu_reg_reg); 10653 %} 10654 10655 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10656 %{ 10657 match(Set cr (OverflowSubL op1 op2)); 10658 10659 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10660 ins_encode %{ 10661 __ cmpq($op1$$Register, $op2$$constant); 10662 %} 10663 ins_pipe(ialu_reg_reg); 10664 %} 10665 10666 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 10667 %{ 10668 match(Set cr (OverflowSubI zero op2)); 10669 effect(DEF cr, USE_KILL op2); 10670 10671 format %{ "negl $op2\t# overflow check int" %} 10672 ins_encode %{ 10673 __ negl($op2$$Register); 10674 %} 10675 ins_pipe(ialu_reg_reg); 10676 %} 10677 10678 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 10679 %{ 10680 match(Set cr (OverflowSubL zero op2)); 10681 effect(DEF cr, USE_KILL op2); 10682 10683 format %{ "negq $op2\t# overflow check long" %} 10684 ins_encode %{ 10685 __ negq($op2$$Register); 10686 %} 10687 ins_pipe(ialu_reg_reg); 10688 %} 10689 10690 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10691 %{ 10692 match(Set cr (OverflowMulI op1 op2)); 10693 effect(DEF cr, USE_KILL op1, USE op2); 10694 10695 format %{ "imull $op1, $op2\t# overflow check int" %} 10696 ins_encode %{ 10697 __ imull($op1$$Register, $op2$$Register); 10698 %} 10699 ins_pipe(ialu_reg_reg_alu0); 10700 %} 10701 10702 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 10703 %{ 10704 match(Set cr (OverflowMulI op1 op2)); 10705 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10706 10707 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 10708 ins_encode %{ 10709 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 10710 %} 10711 ins_pipe(ialu_reg_reg_alu0); 10712 %} 10713 10714 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10715 %{ 10716 match(Set cr (OverflowMulL op1 op2)); 10717 effect(DEF cr, USE_KILL op1, USE op2); 10718 10719 format %{ "imulq $op1, $op2\t# overflow check long" %} 10720 ins_encode %{ 10721 __ imulq($op1$$Register, $op2$$Register); 10722 %} 10723 ins_pipe(ialu_reg_reg_alu0); 10724 %} 10725 10726 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 10727 %{ 10728 match(Set cr (OverflowMulL op1 op2)); 10729 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10730 10731 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 10732 ins_encode %{ 10733 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 10734 %} 10735 ins_pipe(ialu_reg_reg_alu0); 10736 %} 10737 10738 10739 //----------Control Flow Instructions------------------------------------------ 10740 // Signed compare Instructions 10741 10742 // XXX more variants!! 10743 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10744 %{ 10745 match(Set cr (CmpI op1 op2)); 10746 effect(DEF cr, USE op1, USE op2); 10747 10748 format %{ "cmpl $op1, $op2" %} 10749 opcode(0x3B); /* Opcode 3B /r */ 10750 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10751 ins_pipe(ialu_cr_reg_reg); 10752 %} 10753 10754 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10755 %{ 10756 match(Set cr (CmpI op1 op2)); 10757 10758 format %{ "cmpl $op1, $op2" %} 10759 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10760 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10761 ins_pipe(ialu_cr_reg_imm); 10762 %} 10763 10764 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 10765 %{ 10766 match(Set cr (CmpI op1 (LoadI op2))); 10767 10768 ins_cost(500); // XXX 10769 format %{ "cmpl $op1, $op2" %} 10770 opcode(0x3B); /* Opcode 3B /r */ 10771 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10772 ins_pipe(ialu_cr_reg_mem); 10773 %} 10774 10775 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 10776 %{ 10777 match(Set cr (CmpI src zero)); 10778 10779 format %{ "testl $src, $src" %} 10780 opcode(0x85); 10781 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10782 ins_pipe(ialu_cr_reg_imm); 10783 %} 10784 10785 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 10786 %{ 10787 match(Set cr (CmpI (AndI src con) zero)); 10788 10789 format %{ "testl $src, $con" %} 10790 opcode(0xF7, 0x00); 10791 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 10792 ins_pipe(ialu_cr_reg_imm); 10793 %} 10794 10795 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 10796 %{ 10797 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 10798 10799 format %{ "testl $src, $mem" %} 10800 opcode(0x85); 10801 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 10802 ins_pipe(ialu_cr_reg_mem); 10803 %} 10804 10805 // Unsigned compare Instructions; really, same as signed except they 10806 // produce an rFlagsRegU instead of rFlagsReg. 10807 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 10808 %{ 10809 match(Set cr (CmpU op1 op2)); 10810 10811 format %{ "cmpl $op1, $op2\t# unsigned" %} 10812 opcode(0x3B); /* Opcode 3B /r */ 10813 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10814 ins_pipe(ialu_cr_reg_reg); 10815 %} 10816 10817 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 10818 %{ 10819 match(Set cr (CmpU op1 op2)); 10820 10821 format %{ "cmpl $op1, $op2\t# unsigned" %} 10822 opcode(0x81,0x07); /* Opcode 81 /7 */ 10823 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10824 ins_pipe(ialu_cr_reg_imm); 10825 %} 10826 10827 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 10828 %{ 10829 match(Set cr (CmpU op1 (LoadI op2))); 10830 10831 ins_cost(500); // XXX 10832 format %{ "cmpl $op1, $op2\t# unsigned" %} 10833 opcode(0x3B); /* Opcode 3B /r */ 10834 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10835 ins_pipe(ialu_cr_reg_mem); 10836 %} 10837 10838 // // // Cisc-spilled version of cmpU_rReg 10839 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 10840 // //%{ 10841 // // match(Set cr (CmpU (LoadI op1) op2)); 10842 // // 10843 // // format %{ "CMPu $op1,$op2" %} 10844 // // ins_cost(500); 10845 // // opcode(0x39); /* Opcode 39 /r */ 10846 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10847 // //%} 10848 10849 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 10850 %{ 10851 match(Set cr (CmpU src zero)); 10852 10853 format %{ "testl $src, $src\t# unsigned" %} 10854 opcode(0x85); 10855 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10856 ins_pipe(ialu_cr_reg_imm); 10857 %} 10858 10859 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 10860 %{ 10861 match(Set cr (CmpP op1 op2)); 10862 10863 format %{ "cmpq $op1, $op2\t# ptr" %} 10864 opcode(0x3B); /* Opcode 3B /r */ 10865 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10866 ins_pipe(ialu_cr_reg_reg); 10867 %} 10868 10869 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 10870 %{ 10871 match(Set cr (CmpP op1 (LoadP op2))); 10872 10873 ins_cost(500); // XXX 10874 format %{ "cmpq $op1, $op2\t# ptr" %} 10875 opcode(0x3B); /* Opcode 3B /r */ 10876 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10877 ins_pipe(ialu_cr_reg_mem); 10878 %} 10879 10880 // // // Cisc-spilled version of cmpP_rReg 10881 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 10882 // //%{ 10883 // // match(Set cr (CmpP (LoadP op1) op2)); 10884 // // 10885 // // format %{ "CMPu $op1,$op2" %} 10886 // // ins_cost(500); 10887 // // opcode(0x39); /* Opcode 39 /r */ 10888 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10889 // //%} 10890 10891 // XXX this is generalized by compP_rReg_mem??? 10892 // Compare raw pointer (used in out-of-heap check). 10893 // Only works because non-oop pointers must be raw pointers 10894 // and raw pointers have no anti-dependencies. 10895 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 10896 %{ 10897 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 10898 match(Set cr (CmpP op1 (LoadP op2))); 10899 10900 format %{ "cmpq $op1, $op2\t# raw ptr" %} 10901 opcode(0x3B); /* Opcode 3B /r */ 10902 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10903 ins_pipe(ialu_cr_reg_mem); 10904 %} 10905 10906 // This will generate a signed flags result. This should be OK since 10907 // any compare to a zero should be eq/neq. 10908 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 10909 %{ 10910 match(Set cr (CmpP src zero)); 10911 10912 format %{ "testq $src, $src\t# ptr" %} 10913 opcode(0x85); 10914 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10915 ins_pipe(ialu_cr_reg_imm); 10916 %} 10917 10918 // This will generate a signed flags result. This should be OK since 10919 // any compare to a zero should be eq/neq. 10920 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 10921 %{ 10922 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 10923 match(Set cr (CmpP (LoadP op) zero)); 10924 10925 ins_cost(500); // XXX 10926 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 10927 opcode(0xF7); /* Opcode F7 /0 */ 10928 ins_encode(REX_mem_wide(op), 10929 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 10930 ins_pipe(ialu_cr_reg_imm); 10931 %} 10932 10933 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 10934 %{ 10935 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 10936 match(Set cr (CmpP (LoadP mem) zero)); 10937 10938 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 10939 ins_encode %{ 10940 __ cmpq(r12, $mem$$Address); 10941 %} 10942 ins_pipe(ialu_cr_reg_mem); 10943 %} 10944 10945 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 10946 %{ 10947 match(Set cr (CmpN op1 op2)); 10948 10949 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10950 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 10951 ins_pipe(ialu_cr_reg_reg); 10952 %} 10953 10954 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 10955 %{ 10956 match(Set cr (CmpN src (LoadN mem))); 10957 10958 format %{ "cmpl $src, $mem\t# compressed ptr" %} 10959 ins_encode %{ 10960 __ cmpl($src$$Register, $mem$$Address); 10961 %} 10962 ins_pipe(ialu_cr_reg_mem); 10963 %} 10964 10965 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 10966 match(Set cr (CmpN op1 op2)); 10967 10968 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10969 ins_encode %{ 10970 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 10971 %} 10972 ins_pipe(ialu_cr_reg_imm); 10973 %} 10974 10975 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 10976 %{ 10977 match(Set cr (CmpN src (LoadN mem))); 10978 10979 format %{ "cmpl $mem, $src\t# compressed ptr" %} 10980 ins_encode %{ 10981 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 10982 %} 10983 ins_pipe(ialu_cr_reg_mem); 10984 %} 10985 10986 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 10987 match(Set cr (CmpN op1 op2)); 10988 10989 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 10990 ins_encode %{ 10991 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 10992 %} 10993 ins_pipe(ialu_cr_reg_imm); 10994 %} 10995 10996 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 10997 %{ 10998 match(Set cr (CmpN src (LoadNKlass mem))); 10999 11000 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11001 ins_encode %{ 11002 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11003 %} 11004 ins_pipe(ialu_cr_reg_mem); 11005 %} 11006 11007 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11008 match(Set cr (CmpN src zero)); 11009 11010 format %{ "testl $src, $src\t# compressed ptr" %} 11011 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11012 ins_pipe(ialu_cr_reg_imm); 11013 %} 11014 11015 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11016 %{ 11017 predicate(Universe::narrow_oop_base() != NULL); 11018 match(Set cr (CmpN (LoadN mem) zero)); 11019 11020 ins_cost(500); // XXX 11021 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11022 ins_encode %{ 11023 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11024 %} 11025 ins_pipe(ialu_cr_reg_mem); 11026 %} 11027 11028 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11029 %{ 11030 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11031 match(Set cr (CmpN (LoadN mem) zero)); 11032 11033 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11034 ins_encode %{ 11035 __ cmpl(r12, $mem$$Address); 11036 %} 11037 ins_pipe(ialu_cr_reg_mem); 11038 %} 11039 11040 // Yanked all unsigned pointer compare operations. 11041 // Pointer compares are done with CmpP which is already unsigned. 11042 11043 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11044 %{ 11045 match(Set cr (CmpL op1 op2)); 11046 11047 format %{ "cmpq $op1, $op2" %} 11048 opcode(0x3B); /* Opcode 3B /r */ 11049 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11050 ins_pipe(ialu_cr_reg_reg); 11051 %} 11052 11053 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11054 %{ 11055 match(Set cr (CmpL op1 op2)); 11056 11057 format %{ "cmpq $op1, $op2" %} 11058 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11059 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11060 ins_pipe(ialu_cr_reg_imm); 11061 %} 11062 11063 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11064 %{ 11065 match(Set cr (CmpL op1 (LoadL op2))); 11066 11067 format %{ "cmpq $op1, $op2" %} 11068 opcode(0x3B); /* Opcode 3B /r */ 11069 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11070 ins_pipe(ialu_cr_reg_mem); 11071 %} 11072 11073 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11074 %{ 11075 match(Set cr (CmpL src zero)); 11076 11077 format %{ "testq $src, $src" %} 11078 opcode(0x85); 11079 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11080 ins_pipe(ialu_cr_reg_imm); 11081 %} 11082 11083 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11084 %{ 11085 match(Set cr (CmpL (AndL src con) zero)); 11086 11087 format %{ "testq $src, $con\t# long" %} 11088 opcode(0xF7, 0x00); 11089 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11090 ins_pipe(ialu_cr_reg_imm); 11091 %} 11092 11093 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11094 %{ 11095 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11096 11097 format %{ "testq $src, $mem" %} 11098 opcode(0x85); 11099 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11100 ins_pipe(ialu_cr_reg_mem); 11101 %} 11102 11103 // Manifest a CmpL result in an integer register. Very painful. 11104 // This is the test to avoid. 11105 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11106 %{ 11107 match(Set dst (CmpL3 src1 src2)); 11108 effect(KILL flags); 11109 11110 ins_cost(275); // XXX 11111 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11112 "movl $dst, -1\n\t" 11113 "jl,s done\n\t" 11114 "setne $dst\n\t" 11115 "movzbl $dst, $dst\n\t" 11116 "done:" %} 11117 ins_encode(cmpl3_flag(src1, src2, dst)); 11118 ins_pipe(pipe_slow); 11119 %} 11120 11121 //----------Max and Min-------------------------------------------------------- 11122 // Min Instructions 11123 11124 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11125 %{ 11126 effect(USE_DEF dst, USE src, USE cr); 11127 11128 format %{ "cmovlgt $dst, $src\t# min" %} 11129 opcode(0x0F, 0x4F); 11130 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11131 ins_pipe(pipe_cmov_reg); 11132 %} 11133 11134 11135 instruct minI_rReg(rRegI dst, rRegI src) 11136 %{ 11137 match(Set dst (MinI dst src)); 11138 11139 ins_cost(200); 11140 expand %{ 11141 rFlagsReg cr; 11142 compI_rReg(cr, dst, src); 11143 cmovI_reg_g(dst, src, cr); 11144 %} 11145 %} 11146 11147 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11148 %{ 11149 effect(USE_DEF dst, USE src, USE cr); 11150 11151 format %{ "cmovllt $dst, $src\t# max" %} 11152 opcode(0x0F, 0x4C); 11153 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11154 ins_pipe(pipe_cmov_reg); 11155 %} 11156 11157 11158 instruct maxI_rReg(rRegI dst, rRegI src) 11159 %{ 11160 match(Set dst (MaxI dst src)); 11161 11162 ins_cost(200); 11163 expand %{ 11164 rFlagsReg cr; 11165 compI_rReg(cr, dst, src); 11166 cmovI_reg_l(dst, src, cr); 11167 %} 11168 %} 11169 11170 // ============================================================================ 11171 // Branch Instructions 11172 11173 // Jump Direct - Label defines a relative address from JMP+1 11174 instruct jmpDir(label labl) 11175 %{ 11176 match(Goto); 11177 effect(USE labl); 11178 11179 ins_cost(300); 11180 format %{ "jmp $labl" %} 11181 size(5); 11182 ins_encode %{ 11183 Label* L = $labl$$label; 11184 __ jmp(*L, false); // Always long jump 11185 %} 11186 ins_pipe(pipe_jmp); 11187 %} 11188 11189 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11190 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11191 %{ 11192 match(If cop cr); 11193 effect(USE labl); 11194 11195 ins_cost(300); 11196 format %{ "j$cop $labl" %} 11197 size(6); 11198 ins_encode %{ 11199 Label* L = $labl$$label; 11200 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11201 %} 11202 ins_pipe(pipe_jcc); 11203 %} 11204 11205 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11206 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11207 %{ 11208 match(CountedLoopEnd cop cr); 11209 effect(USE labl); 11210 11211 ins_cost(300); 11212 format %{ "j$cop $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 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11222 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11223 match(CountedLoopEnd cop cmp); 11224 effect(USE labl); 11225 11226 ins_cost(300); 11227 format %{ "j$cop,u $labl\t# loop end" %} 11228 size(6); 11229 ins_encode %{ 11230 Label* L = $labl$$label; 11231 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11232 %} 11233 ins_pipe(pipe_jcc); 11234 %} 11235 11236 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11237 match(CountedLoopEnd cop cmp); 11238 effect(USE labl); 11239 11240 ins_cost(200); 11241 format %{ "j$cop,u $labl\t# loop end" %} 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 // Jump Direct Conditional - using unsigned comparison 11251 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11252 match(If cop cmp); 11253 effect(USE labl); 11254 11255 ins_cost(300); 11256 format %{ "j$cop,u $labl" %} 11257 size(6); 11258 ins_encode %{ 11259 Label* L = $labl$$label; 11260 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11261 %} 11262 ins_pipe(pipe_jcc); 11263 %} 11264 11265 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11266 match(If cop cmp); 11267 effect(USE labl); 11268 11269 ins_cost(200); 11270 format %{ "j$cop,u $labl" %} 11271 size(6); 11272 ins_encode %{ 11273 Label* L = $labl$$label; 11274 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11275 %} 11276 ins_pipe(pipe_jcc); 11277 %} 11278 11279 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11280 match(If cop cmp); 11281 effect(USE labl); 11282 11283 ins_cost(200); 11284 format %{ $$template 11285 if ($cop$$cmpcode == Assembler::notEqual) { 11286 $$emit$$"jp,u $labl\n\t" 11287 $$emit$$"j$cop,u $labl" 11288 } else { 11289 $$emit$$"jp,u done\n\t" 11290 $$emit$$"j$cop,u $labl\n\t" 11291 $$emit$$"done:" 11292 } 11293 %} 11294 ins_encode %{ 11295 Label* l = $labl$$label; 11296 if ($cop$$cmpcode == Assembler::notEqual) { 11297 __ jcc(Assembler::parity, *l, false); 11298 __ jcc(Assembler::notEqual, *l, false); 11299 } else if ($cop$$cmpcode == Assembler::equal) { 11300 Label done; 11301 __ jccb(Assembler::parity, done); 11302 __ jcc(Assembler::equal, *l, false); 11303 __ bind(done); 11304 } else { 11305 ShouldNotReachHere(); 11306 } 11307 %} 11308 ins_pipe(pipe_jcc); 11309 %} 11310 11311 // ============================================================================ 11312 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11313 // superklass array for an instance of the superklass. Set a hidden 11314 // internal cache on a hit (cache is checked with exposed code in 11315 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11316 // encoding ALSO sets flags. 11317 11318 instruct partialSubtypeCheck(rdi_RegP result, 11319 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11320 rFlagsReg cr) 11321 %{ 11322 match(Set result (PartialSubtypeCheck sub super)); 11323 effect(KILL rcx, KILL cr); 11324 11325 ins_cost(1100); // slightly larger than the next version 11326 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11327 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11328 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11329 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11330 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11331 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11332 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11333 "miss:\t" %} 11334 11335 opcode(0x1); // Force a XOR of RDI 11336 ins_encode(enc_PartialSubtypeCheck()); 11337 ins_pipe(pipe_slow); 11338 %} 11339 11340 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11341 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11342 immP0 zero, 11343 rdi_RegP result) 11344 %{ 11345 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11346 effect(KILL rcx, KILL result); 11347 11348 ins_cost(1000); 11349 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11350 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11351 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11352 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11353 "jne,s miss\t\t# Missed: flags nz\n\t" 11354 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11355 "miss:\t" %} 11356 11357 opcode(0x0); // No need to XOR RDI 11358 ins_encode(enc_PartialSubtypeCheck()); 11359 ins_pipe(pipe_slow); 11360 %} 11361 11362 // ============================================================================ 11363 // Branch Instructions -- short offset versions 11364 // 11365 // These instructions are used to replace jumps of a long offset (the default 11366 // match) with jumps of a shorter offset. These instructions are all tagged 11367 // with the ins_short_branch attribute, which causes the ADLC to suppress the 11368 // match rules in general matching. Instead, the ADLC generates a conversion 11369 // method in the MachNode which can be used to do in-place replacement of the 11370 // long variant with the shorter variant. The compiler will determine if a 11371 // branch can be taken by the is_short_branch_offset() predicate in the machine 11372 // specific code section of the file. 11373 11374 // Jump Direct - Label defines a relative address from JMP+1 11375 instruct jmpDir_short(label labl) %{ 11376 match(Goto); 11377 effect(USE labl); 11378 11379 ins_cost(300); 11380 format %{ "jmp,s $labl" %} 11381 size(2); 11382 ins_encode %{ 11383 Label* L = $labl$$label; 11384 __ jmpb(*L); 11385 %} 11386 ins_pipe(pipe_jmp); 11387 ins_short_branch(1); 11388 %} 11389 11390 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11391 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11392 match(If cop cr); 11393 effect(USE labl); 11394 11395 ins_cost(300); 11396 format %{ "j$cop,s $labl" %} 11397 size(2); 11398 ins_encode %{ 11399 Label* L = $labl$$label; 11400 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11401 %} 11402 ins_pipe(pipe_jcc); 11403 ins_short_branch(1); 11404 %} 11405 11406 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11407 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11408 match(CountedLoopEnd cop cr); 11409 effect(USE labl); 11410 11411 ins_cost(300); 11412 format %{ "j$cop,s $labl\t# loop end" %} 11413 size(2); 11414 ins_encode %{ 11415 Label* L = $labl$$label; 11416 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11417 %} 11418 ins_pipe(pipe_jcc); 11419 ins_short_branch(1); 11420 %} 11421 11422 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11423 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU 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 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11439 match(CountedLoopEnd cop cmp); 11440 effect(USE labl); 11441 11442 ins_cost(300); 11443 format %{ "j$cop,us $labl\t# loop end" %} 11444 size(2); 11445 ins_encode %{ 11446 Label* L = $labl$$label; 11447 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11448 %} 11449 ins_pipe(pipe_jcc); 11450 ins_short_branch(1); 11451 %} 11452 11453 // Jump Direct Conditional - using unsigned comparison 11454 instruct jmpConU_short(cmpOpU cop, rFlagsRegU 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 jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11470 match(If cop cmp); 11471 effect(USE labl); 11472 11473 ins_cost(300); 11474 format %{ "j$cop,us $labl" %} 11475 size(2); 11476 ins_encode %{ 11477 Label* L = $labl$$label; 11478 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11479 %} 11480 ins_pipe(pipe_jcc); 11481 ins_short_branch(1); 11482 %} 11483 11484 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11485 match(If cop cmp); 11486 effect(USE labl); 11487 11488 ins_cost(300); 11489 format %{ $$template 11490 if ($cop$$cmpcode == Assembler::notEqual) { 11491 $$emit$$"jp,u,s $labl\n\t" 11492 $$emit$$"j$cop,u,s $labl" 11493 } else { 11494 $$emit$$"jp,u,s done\n\t" 11495 $$emit$$"j$cop,u,s $labl\n\t" 11496 $$emit$$"done:" 11497 } 11498 %} 11499 size(4); 11500 ins_encode %{ 11501 Label* l = $labl$$label; 11502 if ($cop$$cmpcode == Assembler::notEqual) { 11503 __ jccb(Assembler::parity, *l); 11504 __ jccb(Assembler::notEqual, *l); 11505 } else if ($cop$$cmpcode == Assembler::equal) { 11506 Label done; 11507 __ jccb(Assembler::parity, done); 11508 __ jccb(Assembler::equal, *l); 11509 __ bind(done); 11510 } else { 11511 ShouldNotReachHere(); 11512 } 11513 %} 11514 ins_pipe(pipe_jcc); 11515 ins_short_branch(1); 11516 %} 11517 11518 // ============================================================================ 11519 // inlined locking and unlocking 11520 11521 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 11522 predicate(Compile::current()->use_rtm()); 11523 match(Set cr (FastLock object box)); 11524 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 11525 ins_cost(300); 11526 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 11527 ins_encode %{ 11528 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 11529 $scr$$Register, $cx1$$Register, $cx2$$Register, 11530 _counters, _rtm_counters, _stack_rtm_counters, 11531 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11532 true, ra_->C->profile_rtm()); 11533 %} 11534 ins_pipe(pipe_slow); 11535 %} 11536 11537 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 11538 predicate(!Compile::current()->use_rtm()); 11539 match(Set cr (FastLock object box)); 11540 effect(TEMP tmp, TEMP scr, USE_KILL box); 11541 ins_cost(300); 11542 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 11543 ins_encode %{ 11544 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 11545 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 11546 %} 11547 ins_pipe(pipe_slow); 11548 %} 11549 11550 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 11551 match(Set cr (FastUnlock object box)); 11552 effect(TEMP tmp, USE_KILL box); 11553 ins_cost(300); 11554 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 11555 ins_encode %{ 11556 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 11557 %} 11558 ins_pipe(pipe_slow); 11559 %} 11560 11561 11562 // ============================================================================ 11563 // Safepoint Instructions 11564 instruct safePoint_poll(rFlagsReg cr) 11565 %{ 11566 predicate(!Assembler::is_polling_page_far() || ThreadLocalSafepoints); 11567 match(SafePoint); 11568 effect(KILL cr); 11569 11570 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 11571 "# Safepoint: poll for GC" %} 11572 ins_cost(125); 11573 ins_encode %{ 11574 if (ThreadLocalSafepoints) { 11575 Compile* C = ra_->C; 11576 InternalAddress safepoint_pc(__ pc()); 11577 Label dummy_label; 11578 Label &code_stub = &cbuf == C->code_buffer() ? C->tls_table()->add_safepoint(safepoint_pc, false) : dummy_label; 11579 __ relocate(relocInfo::poll_type); 11580 __ testb(Address(r15_thread, Thread::yieldpoint_offset()), 1); 11581 __ jcc(Assembler::equal, code_stub); 11582 } else { 11583 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 11584 __ testl(rax, addr); 11585 } 11586 %} 11587 ins_pipe(ialu_reg_mem); 11588 %} 11589 11590 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 11591 %{ 11592 predicate(Assembler::is_polling_page_far() && !ThreadLocalSafepoints); 11593 match(SafePoint poll); 11594 effect(KILL cr, USE poll); 11595 11596 format %{ "testl rax, [$poll]\t" 11597 "# Safepoint: poll for GC" %} 11598 ins_cost(125); 11599 ins_encode %{ 11600 __ relocate(relocInfo::poll_type); 11601 __ testl(rax, Address($poll$$Register, 0)); 11602 %} 11603 ins_pipe(ialu_reg_mem); 11604 %} 11605 11606 // ============================================================================ 11607 // Procedure Call/Return Instructions 11608 // Call Java Static Instruction 11609 // Note: If this code changes, the corresponding ret_addr_offset() and 11610 // compute_padding() functions will have to be adjusted. 11611 instruct CallStaticJavaDirect(method meth) %{ 11612 match(CallStaticJava); 11613 effect(USE meth); 11614 11615 ins_cost(300); 11616 format %{ "call,static " %} 11617 opcode(0xE8); /* E8 cd */ 11618 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 11619 ins_pipe(pipe_slow); 11620 ins_alignment(4); 11621 %} 11622 11623 // Call Java Dynamic Instruction 11624 // Note: If this code changes, the corresponding ret_addr_offset() and 11625 // compute_padding() functions will have to be adjusted. 11626 instruct CallDynamicJavaDirect(method meth) 11627 %{ 11628 match(CallDynamicJava); 11629 effect(USE meth); 11630 11631 ins_cost(300); 11632 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11633 "call,dynamic " %} 11634 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 11635 ins_pipe(pipe_slow); 11636 ins_alignment(4); 11637 %} 11638 11639 // Call Runtime Instruction 11640 instruct CallRuntimeDirect(method meth) 11641 %{ 11642 match(CallRuntime); 11643 effect(USE meth); 11644 11645 ins_cost(300); 11646 format %{ "call,runtime " %} 11647 ins_encode(clear_avx, Java_To_Runtime(meth)); 11648 ins_pipe(pipe_slow); 11649 %} 11650 11651 // Call runtime without safepoint 11652 instruct CallLeafDirect(method meth) 11653 %{ 11654 match(CallLeaf); 11655 effect(USE meth); 11656 11657 ins_cost(300); 11658 format %{ "call_leaf,runtime " %} 11659 ins_encode(clear_avx, Java_To_Runtime(meth)); 11660 ins_pipe(pipe_slow); 11661 %} 11662 11663 // Call runtime without safepoint 11664 instruct CallLeafNoFPDirect(method meth) 11665 %{ 11666 match(CallLeafNoFP); 11667 effect(USE meth); 11668 11669 ins_cost(300); 11670 format %{ "call_leaf_nofp,runtime " %} 11671 ins_encode(Java_To_Runtime(meth)); 11672 ins_pipe(pipe_slow); 11673 %} 11674 11675 // Return Instruction 11676 // Remove the return address & jump to it. 11677 // Notice: We always emit a nop after a ret to make sure there is room 11678 // for safepoint patching 11679 instruct Ret() 11680 %{ 11681 match(Return); 11682 11683 format %{ "ret" %} 11684 opcode(0xC3); 11685 ins_encode(OpcP); 11686 ins_pipe(pipe_jmp); 11687 %} 11688 11689 // Tail Call; Jump from runtime stub to Java code. 11690 // Also known as an 'interprocedural jump'. 11691 // Target of jump will eventually return to caller. 11692 // TailJump below removes the return address. 11693 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 11694 %{ 11695 match(TailCall jump_target method_oop); 11696 11697 ins_cost(300); 11698 format %{ "jmp $jump_target\t# rbx holds method oop" %} 11699 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11700 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11701 ins_pipe(pipe_jmp); 11702 %} 11703 11704 // Tail Jump; remove the return address; jump to target. 11705 // TailCall above leaves the return address around. 11706 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 11707 %{ 11708 match(TailJump jump_target ex_oop); 11709 11710 ins_cost(300); 11711 format %{ "popq rdx\t# pop return address\n\t" 11712 "jmp $jump_target" %} 11713 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11714 ins_encode(Opcode(0x5a), // popq rdx 11715 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11716 ins_pipe(pipe_jmp); 11717 %} 11718 11719 // Create exception oop: created by stack-crawling runtime code. 11720 // Created exception is now available to this handler, and is setup 11721 // just prior to jumping to this handler. No code emitted. 11722 instruct CreateException(rax_RegP ex_oop) 11723 %{ 11724 match(Set ex_oop (CreateEx)); 11725 11726 size(0); 11727 // use the following format syntax 11728 format %{ "# exception oop is in rax; no code emitted" %} 11729 ins_encode(); 11730 ins_pipe(empty); 11731 %} 11732 11733 // Rethrow exception: 11734 // The exception oop will come in the first argument position. 11735 // Then JUMP (not call) to the rethrow stub code. 11736 instruct RethrowException() 11737 %{ 11738 match(Rethrow); 11739 11740 // use the following format syntax 11741 format %{ "jmp rethrow_stub" %} 11742 ins_encode(enc_rethrow); 11743 ins_pipe(pipe_jmp); 11744 %} 11745 11746 11747 // ============================================================================ 11748 // This name is KNOWN by the ADLC and cannot be changed. 11749 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 11750 // for this guy. 11751 instruct tlsLoadP(r15_RegP dst) %{ 11752 match(Set dst (ThreadLocal)); 11753 effect(DEF dst); 11754 11755 size(0); 11756 format %{ "# TLS is in R15" %} 11757 ins_encode( /*empty encoding*/ ); 11758 ins_pipe(ialu_reg_reg); 11759 %} 11760 11761 11762 //----------PEEPHOLE RULES----------------------------------------------------- 11763 // These must follow all instruction definitions as they use the names 11764 // defined in the instructions definitions. 11765 // 11766 // peepmatch ( root_instr_name [preceding_instruction]* ); 11767 // 11768 // peepconstraint %{ 11769 // (instruction_number.operand_name relational_op instruction_number.operand_name 11770 // [, ...] ); 11771 // // instruction numbers are zero-based using left to right order in peepmatch 11772 // 11773 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 11774 // // provide an instruction_number.operand_name for each operand that appears 11775 // // in the replacement instruction's match rule 11776 // 11777 // ---------VM FLAGS--------------------------------------------------------- 11778 // 11779 // All peephole optimizations can be turned off using -XX:-OptoPeephole 11780 // 11781 // Each peephole rule is given an identifying number starting with zero and 11782 // increasing by one in the order seen by the parser. An individual peephole 11783 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 11784 // on the command-line. 11785 // 11786 // ---------CURRENT LIMITATIONS---------------------------------------------- 11787 // 11788 // Only match adjacent instructions in same basic block 11789 // Only equality constraints 11790 // Only constraints between operands, not (0.dest_reg == RAX_enc) 11791 // Only one replacement instruction 11792 // 11793 // ---------EXAMPLE---------------------------------------------------------- 11794 // 11795 // // pertinent parts of existing instructions in architecture description 11796 // instruct movI(rRegI dst, rRegI src) 11797 // %{ 11798 // match(Set dst (CopyI src)); 11799 // %} 11800 // 11801 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 11802 // %{ 11803 // match(Set dst (AddI dst src)); 11804 // effect(KILL cr); 11805 // %} 11806 // 11807 // // Change (inc mov) to lea 11808 // peephole %{ 11809 // // increment preceeded by register-register move 11810 // peepmatch ( incI_rReg movI ); 11811 // // require that the destination register of the increment 11812 // // match the destination register of the move 11813 // peepconstraint ( 0.dst == 1.dst ); 11814 // // construct a replacement instruction that sets 11815 // // the destination to ( move's source register + one ) 11816 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 11817 // %} 11818 // 11819 11820 // Implementation no longer uses movX instructions since 11821 // machine-independent system no longer uses CopyX nodes. 11822 // 11823 // peephole 11824 // %{ 11825 // peepmatch (incI_rReg movI); 11826 // peepconstraint (0.dst == 1.dst); 11827 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11828 // %} 11829 11830 // peephole 11831 // %{ 11832 // peepmatch (decI_rReg movI); 11833 // peepconstraint (0.dst == 1.dst); 11834 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11835 // %} 11836 11837 // peephole 11838 // %{ 11839 // peepmatch (addI_rReg_imm movI); 11840 // peepconstraint (0.dst == 1.dst); 11841 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11842 // %} 11843 11844 // peephole 11845 // %{ 11846 // peepmatch (incL_rReg movL); 11847 // peepconstraint (0.dst == 1.dst); 11848 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11849 // %} 11850 11851 // peephole 11852 // %{ 11853 // peepmatch (decL_rReg movL); 11854 // peepconstraint (0.dst == 1.dst); 11855 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11856 // %} 11857 11858 // peephole 11859 // %{ 11860 // peepmatch (addL_rReg_imm movL); 11861 // peepconstraint (0.dst == 1.dst); 11862 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11863 // %} 11864 11865 // peephole 11866 // %{ 11867 // peepmatch (addP_rReg_imm movP); 11868 // peepconstraint (0.dst == 1.dst); 11869 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 11870 // %} 11871 11872 // // Change load of spilled value to only a spill 11873 // instruct storeI(memory mem, rRegI src) 11874 // %{ 11875 // match(Set mem (StoreI mem src)); 11876 // %} 11877 // 11878 // instruct loadI(rRegI dst, memory mem) 11879 // %{ 11880 // match(Set dst (LoadI mem)); 11881 // %} 11882 // 11883 11884 peephole 11885 %{ 11886 peepmatch (loadI storeI); 11887 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11888 peepreplace (storeI(1.mem 1.mem 1.src)); 11889 %} 11890 11891 peephole 11892 %{ 11893 peepmatch (loadL storeL); 11894 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11895 peepreplace (storeL(1.mem 1.mem 1.src)); 11896 %} 11897 11898 //----------SMARTSPILL RULES--------------------------------------------------- 11899 // These must follow all instruction definitions as they use the names 11900 // defined in the instructions definitions.