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