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 return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper 540 } 541 542 // !!!!! Special hack to get all types of calls to specify the byte offset 543 // from the start of the call to the point where the return address 544 // will point. 545 int MachCallStaticJavaNode::ret_addr_offset() 546 { 547 int offset = 5; // 5 bytes from start of call to where return address points 548 offset += clear_avx_size(); 549 return offset; 550 } 551 552 int MachCallDynamicJavaNode::ret_addr_offset() 553 { 554 int offset = 15; // 15 bytes from start of call to where return address points 555 offset += clear_avx_size(); 556 return offset; 557 } 558 559 int MachCallRuntimeNode::ret_addr_offset() { 560 int offset = 13; // movq r10,#addr; callq (r10) 561 offset += clear_avx_size(); 562 return offset; 563 } 564 565 // Indicate if the safepoint node needs the polling page as an input, 566 // it does if the polling page is more than disp32 away. 567 bool SafePointNode::needs_polling_address_input() 568 { 569 return Assembler::is_polling_page_far(); 570 } 571 572 // 573 // Compute padding required for nodes which need alignment 574 // 575 576 // The address of the call instruction needs to be 4-byte aligned to 577 // ensure that it does not span a cache line so that it can be patched. 578 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 579 { 580 current_offset += clear_avx_size(); // skip vzeroupper 581 current_offset += 1; // skip call opcode byte 582 return round_to(current_offset, alignment_required()) - current_offset; 583 } 584 585 // The address of the call instruction needs to be 4-byte aligned to 586 // ensure that it does not span a cache line so that it can be patched. 587 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 588 { 589 current_offset += clear_avx_size(); // skip vzeroupper 590 current_offset += 11; // skip movq instruction + call opcode byte 591 return round_to(current_offset, alignment_required()) - current_offset; 592 } 593 594 // EMIT_RM() 595 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 596 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 597 cbuf.insts()->emit_int8(c); 598 } 599 600 // EMIT_CC() 601 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 602 unsigned char c = (unsigned char) (f1 | f2); 603 cbuf.insts()->emit_int8(c); 604 } 605 606 // EMIT_OPCODE() 607 void emit_opcode(CodeBuffer &cbuf, int code) { 608 cbuf.insts()->emit_int8((unsigned char) code); 609 } 610 611 // EMIT_OPCODE() w/ relocation information 612 void emit_opcode(CodeBuffer &cbuf, 613 int code, relocInfo::relocType reloc, int offset, int format) 614 { 615 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 616 emit_opcode(cbuf, code); 617 } 618 619 // EMIT_D8() 620 void emit_d8(CodeBuffer &cbuf, int d8) { 621 cbuf.insts()->emit_int8((unsigned char) d8); 622 } 623 624 // EMIT_D16() 625 void emit_d16(CodeBuffer &cbuf, int d16) { 626 cbuf.insts()->emit_int16(d16); 627 } 628 629 // EMIT_D32() 630 void emit_d32(CodeBuffer &cbuf, int d32) { 631 cbuf.insts()->emit_int32(d32); 632 } 633 634 // EMIT_D64() 635 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 636 cbuf.insts()->emit_int64(d64); 637 } 638 639 // emit 32 bit value and construct relocation entry from relocInfo::relocType 640 void emit_d32_reloc(CodeBuffer& cbuf, 641 int d32, 642 relocInfo::relocType reloc, 643 int format) 644 { 645 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 646 cbuf.relocate(cbuf.insts_mark(), reloc, format); 647 cbuf.insts()->emit_int32(d32); 648 } 649 650 // emit 32 bit value and construct relocation entry from RelocationHolder 651 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 652 #ifdef ASSERT 653 if (rspec.reloc()->type() == relocInfo::oop_type && 654 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 655 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 656 assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 657 } 658 #endif 659 cbuf.relocate(cbuf.insts_mark(), rspec, format); 660 cbuf.insts()->emit_int32(d32); 661 } 662 663 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 664 address next_ip = cbuf.insts_end() + 4; 665 emit_d32_reloc(cbuf, (int) (addr - next_ip), 666 external_word_Relocation::spec(addr), 667 RELOC_DISP32); 668 } 669 670 671 // emit 64 bit value and construct relocation entry from relocInfo::relocType 672 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 673 cbuf.relocate(cbuf.insts_mark(), reloc, format); 674 cbuf.insts()->emit_int64(d64); 675 } 676 677 // emit 64 bit value and construct relocation entry from RelocationHolder 678 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 679 #ifdef ASSERT 680 if (rspec.reloc()->type() == relocInfo::oop_type && 681 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 682 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 683 assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()), 684 "cannot embed scavengable oops in code"); 685 } 686 #endif 687 cbuf.relocate(cbuf.insts_mark(), rspec, format); 688 cbuf.insts()->emit_int64(d64); 689 } 690 691 // Access stack slot for load or store 692 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 693 { 694 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 695 if (-0x80 <= disp && disp < 0x80) { 696 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 697 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 698 emit_d8(cbuf, disp); // Displacement // R/M byte 699 } else { 700 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 701 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 702 emit_d32(cbuf, disp); // Displacement // R/M byte 703 } 704 } 705 706 // rRegI ereg, memory mem) %{ // emit_reg_mem 707 void encode_RegMem(CodeBuffer &cbuf, 708 int reg, 709 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 710 { 711 assert(disp_reloc == relocInfo::none, "cannot have disp"); 712 int regenc = reg & 7; 713 int baseenc = base & 7; 714 int indexenc = index & 7; 715 716 // There is no index & no scale, use form without SIB byte 717 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 718 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 719 if (disp == 0 && base != RBP_enc && base != R13_enc) { 720 emit_rm(cbuf, 0x0, regenc, baseenc); // * 721 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 722 // If 8-bit displacement, mode 0x1 723 emit_rm(cbuf, 0x1, regenc, baseenc); // * 724 emit_d8(cbuf, disp); 725 } else { 726 // If 32-bit displacement 727 if (base == -1) { // Special flag for absolute address 728 emit_rm(cbuf, 0x0, regenc, 0x5); // * 729 if (disp_reloc != relocInfo::none) { 730 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 731 } else { 732 emit_d32(cbuf, disp); 733 } 734 } else { 735 // Normal base + offset 736 emit_rm(cbuf, 0x2, regenc, baseenc); // * 737 if (disp_reloc != relocInfo::none) { 738 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 739 } else { 740 emit_d32(cbuf, disp); 741 } 742 } 743 } 744 } else { 745 // Else, encode with the SIB byte 746 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 747 if (disp == 0 && base != RBP_enc && base != R13_enc) { 748 // If no displacement 749 emit_rm(cbuf, 0x0, regenc, 0x4); // * 750 emit_rm(cbuf, scale, indexenc, baseenc); 751 } else { 752 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 753 // If 8-bit displacement, mode 0x1 754 emit_rm(cbuf, 0x1, regenc, 0x4); // * 755 emit_rm(cbuf, scale, indexenc, baseenc); 756 emit_d8(cbuf, disp); 757 } else { 758 // If 32-bit displacement 759 if (base == 0x04 ) { 760 emit_rm(cbuf, 0x2, regenc, 0x4); 761 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 762 } else { 763 emit_rm(cbuf, 0x2, regenc, 0x4); 764 emit_rm(cbuf, scale, indexenc, baseenc); // * 765 } 766 if (disp_reloc != relocInfo::none) { 767 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 768 } else { 769 emit_d32(cbuf, disp); 770 } 771 } 772 } 773 } 774 } 775 776 // This could be in MacroAssembler but it's fairly C2 specific 777 void emit_cmpfp_fixup(MacroAssembler& _masm) { 778 Label exit; 779 __ jccb(Assembler::noParity, exit); 780 __ pushf(); 781 // 782 // comiss/ucomiss instructions set ZF,PF,CF flags and 783 // zero OF,AF,SF for NaN values. 784 // Fixup flags by zeroing ZF,PF so that compare of NaN 785 // values returns 'less than' result (CF is set). 786 // Leave the rest of flags unchanged. 787 // 788 // 7 6 5 4 3 2 1 0 789 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 790 // 0 0 1 0 1 0 1 1 (0x2B) 791 // 792 __ andq(Address(rsp, 0), 0xffffff2b); 793 __ popf(); 794 __ bind(exit); 795 } 796 797 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 798 Label done; 799 __ movl(dst, -1); 800 __ jcc(Assembler::parity, done); 801 __ jcc(Assembler::below, done); 802 __ setb(Assembler::notEqual, dst); 803 __ movzbl(dst, dst); 804 __ bind(done); 805 } 806 807 808 //============================================================================= 809 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 810 811 int Compile::ConstantTable::calculate_table_base_offset() const { 812 return 0; // absolute addressing, no offset 813 } 814 815 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 816 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 817 ShouldNotReachHere(); 818 } 819 820 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 821 // Empty encoding 822 } 823 824 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 825 return 0; 826 } 827 828 #ifndef PRODUCT 829 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 830 st->print("# MachConstantBaseNode (empty encoding)"); 831 } 832 #endif 833 834 835 //============================================================================= 836 #ifndef PRODUCT 837 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 838 Compile* C = ra_->C; 839 840 int framesize = C->frame_size_in_bytes(); 841 int bangsize = C->bang_size_in_bytes(); 842 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 843 // Remove wordSize for return addr which is already pushed. 844 framesize -= wordSize; 845 846 if (C->need_stack_bang(bangsize)) { 847 framesize -= wordSize; 848 st->print("# stack bang (%d bytes)", bangsize); 849 st->print("\n\t"); 850 st->print("pushq rbp\t# Save rbp"); 851 if (PreserveFramePointer) { 852 st->print("\n\t"); 853 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 854 } 855 if (framesize) { 856 st->print("\n\t"); 857 st->print("subq rsp, #%d\t# Create frame",framesize); 858 } 859 } else { 860 st->print("subq rsp, #%d\t# Create frame",framesize); 861 st->print("\n\t"); 862 framesize -= wordSize; 863 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 864 if (PreserveFramePointer) { 865 st->print("\n\t"); 866 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 867 if (framesize > 0) { 868 st->print("\n\t"); 869 st->print("addq rbp, #%d", framesize); 870 } 871 } 872 } 873 874 if (VerifyStackAtCalls) { 875 st->print("\n\t"); 876 framesize -= wordSize; 877 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 878 #ifdef ASSERT 879 st->print("\n\t"); 880 st->print("# stack alignment check"); 881 #endif 882 } 883 st->cr(); 884 } 885 #endif 886 887 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 888 Compile* C = ra_->C; 889 MacroAssembler _masm(&cbuf); 890 891 int framesize = C->frame_size_in_bytes(); 892 int bangsize = C->bang_size_in_bytes(); 893 894 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); 895 896 C->set_frame_complete(cbuf.insts_size()); 897 898 if (C->has_mach_constant_base_node()) { 899 // NOTE: We set the table base offset here because users might be 900 // emitted before MachConstantBaseNode. 901 Compile::ConstantTable& constant_table = C->constant_table(); 902 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 903 } 904 } 905 906 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 907 { 908 return MachNode::size(ra_); // too many variables; just compute it 909 // the hard way 910 } 911 912 int MachPrologNode::reloc() const 913 { 914 return 0; // a large enough number 915 } 916 917 //============================================================================= 918 #ifndef PRODUCT 919 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 920 { 921 Compile* C = ra_->C; 922 if (C->max_vector_size() > 16) { 923 st->print("vzeroupper"); 924 st->cr(); st->print("\t"); 925 } 926 927 int framesize = C->frame_size_in_bytes(); 928 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 929 // Remove word for return adr already pushed 930 // and RBP 931 framesize -= 2*wordSize; 932 933 if (framesize) { 934 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 935 st->print("\t"); 936 } 937 938 st->print_cr("popq rbp"); 939 if (do_polling() && C->is_method_compilation()) { 940 st->print("\t"); 941 if (Assembler::is_polling_page_far()) { 942 st->print_cr("movq rscratch1, #polling_page_address\n\t" 943 "testl rax, [rscratch1]\t" 944 "# Safepoint: poll for GC"); 945 } else { 946 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 947 "# Safepoint: poll for GC"); 948 } 949 } 950 } 951 #endif 952 953 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 954 { 955 Compile* C = ra_->C; 956 if (C->max_vector_size() > 16) { 957 // Clear upper bits of YMM registers when current compiled code uses 958 // wide vectors to avoid AVX <-> SSE transition penalty during call. 959 MacroAssembler _masm(&cbuf); 960 __ vzeroupper(); 961 } 962 963 int framesize = C->frame_size_in_bytes(); 964 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 965 // Remove word for return adr already pushed 966 // and RBP 967 framesize -= 2*wordSize; 968 969 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 970 971 if (framesize) { 972 emit_opcode(cbuf, Assembler::REX_W); 973 if (framesize < 0x80) { 974 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 975 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 976 emit_d8(cbuf, framesize); 977 } else { 978 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 979 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 980 emit_d32(cbuf, framesize); 981 } 982 } 983 984 // popq rbp 985 emit_opcode(cbuf, 0x58 | RBP_enc); 986 987 if (do_polling() && C->is_method_compilation()) { 988 MacroAssembler _masm(&cbuf); 989 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 990 if (Assembler::is_polling_page_far()) { 991 __ lea(rscratch1, polling_page); 992 __ relocate(relocInfo::poll_return_type); 993 __ testl(rax, Address(rscratch1, 0)); 994 } else { 995 __ testl(rax, polling_page); 996 } 997 } 998 } 999 1000 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1001 { 1002 return MachNode::size(ra_); // too many variables; just compute it 1003 // the hard way 1004 } 1005 1006 int MachEpilogNode::reloc() const 1007 { 1008 return 2; // a large enough number 1009 } 1010 1011 const Pipeline* MachEpilogNode::pipeline() const 1012 { 1013 return MachNode::pipeline_class(); 1014 } 1015 1016 int MachEpilogNode::safepoint_offset() const 1017 { 1018 return 0; 1019 } 1020 1021 //============================================================================= 1022 1023 enum RC { 1024 rc_bad, 1025 rc_int, 1026 rc_float, 1027 rc_stack 1028 }; 1029 1030 static enum RC rc_class(OptoReg::Name reg) 1031 { 1032 if( !OptoReg::is_valid(reg) ) return rc_bad; 1033 1034 if (OptoReg::is_stack(reg)) return rc_stack; 1035 1036 VMReg r = OptoReg::as_VMReg(reg); 1037 1038 if (r->is_Register()) return rc_int; 1039 1040 assert(r->is_XMMRegister(), "must be"); 1041 return rc_float; 1042 } 1043 1044 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1045 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1046 int src_hi, int dst_hi, uint ireg, outputStream* st); 1047 1048 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1049 int stack_offset, int reg, uint ireg, outputStream* st); 1050 1051 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1052 int dst_offset, uint ireg, outputStream* st) { 1053 if (cbuf) { 1054 MacroAssembler _masm(cbuf); 1055 switch (ireg) { 1056 case Op_VecS: 1057 __ movq(Address(rsp, -8), rax); 1058 __ movl(rax, Address(rsp, src_offset)); 1059 __ movl(Address(rsp, dst_offset), rax); 1060 __ movq(rax, Address(rsp, -8)); 1061 break; 1062 case Op_VecD: 1063 __ pushq(Address(rsp, src_offset)); 1064 __ popq (Address(rsp, dst_offset)); 1065 break; 1066 case Op_VecX: 1067 __ pushq(Address(rsp, src_offset)); 1068 __ popq (Address(rsp, dst_offset)); 1069 __ pushq(Address(rsp, src_offset+8)); 1070 __ popq (Address(rsp, dst_offset+8)); 1071 break; 1072 case Op_VecY: 1073 __ vmovdqu(Address(rsp, -32), xmm0); 1074 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1075 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1076 __ vmovdqu(xmm0, Address(rsp, -32)); 1077 break; 1078 case Op_VecZ: 1079 __ evmovdqul(Address(rsp, -64), xmm0, 2); 1080 __ evmovdqul(xmm0, Address(rsp, src_offset), 2); 1081 __ evmovdqul(Address(rsp, dst_offset), xmm0, 2); 1082 __ evmovdqul(xmm0, Address(rsp, -64), 2); 1083 break; 1084 default: 1085 ShouldNotReachHere(); 1086 } 1087 #ifndef PRODUCT 1088 } else { 1089 switch (ireg) { 1090 case Op_VecS: 1091 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1092 "movl rax, [rsp + #%d]\n\t" 1093 "movl [rsp + #%d], rax\n\t" 1094 "movq rax, [rsp - #8]", 1095 src_offset, dst_offset); 1096 break; 1097 case Op_VecD: 1098 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1099 "popq [rsp + #%d]", 1100 src_offset, dst_offset); 1101 break; 1102 case Op_VecX: 1103 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1104 "popq [rsp + #%d]\n\t" 1105 "pushq [rsp + #%d]\n\t" 1106 "popq [rsp + #%d]", 1107 src_offset, dst_offset, src_offset+8, dst_offset+8); 1108 break; 1109 case Op_VecY: 1110 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1111 "vmovdqu xmm0, [rsp + #%d]\n\t" 1112 "vmovdqu [rsp + #%d], xmm0\n\t" 1113 "vmovdqu xmm0, [rsp - #32]", 1114 src_offset, dst_offset); 1115 break; 1116 case Op_VecZ: 1117 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1118 "vmovdqu xmm0, [rsp + #%d]\n\t" 1119 "vmovdqu [rsp + #%d], xmm0\n\t" 1120 "vmovdqu xmm0, [rsp - #64]", 1121 src_offset, dst_offset); 1122 break; 1123 default: 1124 ShouldNotReachHere(); 1125 } 1126 #endif 1127 } 1128 } 1129 1130 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1131 PhaseRegAlloc* ra_, 1132 bool do_size, 1133 outputStream* st) const { 1134 assert(cbuf != NULL || st != NULL, "sanity"); 1135 // Get registers to move 1136 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1137 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1138 OptoReg::Name dst_second = ra_->get_reg_second(this); 1139 OptoReg::Name dst_first = ra_->get_reg_first(this); 1140 1141 enum RC src_second_rc = rc_class(src_second); 1142 enum RC src_first_rc = rc_class(src_first); 1143 enum RC dst_second_rc = rc_class(dst_second); 1144 enum RC dst_first_rc = rc_class(dst_first); 1145 1146 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1147 "must move at least 1 register" ); 1148 1149 if (src_first == dst_first && src_second == dst_second) { 1150 // Self copy, no move 1151 return 0; 1152 } 1153 if (bottom_type()->isa_vect() != NULL) { 1154 uint ireg = ideal_reg(); 1155 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1156 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1157 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1158 // mem -> mem 1159 int src_offset = ra_->reg2offset(src_first); 1160 int dst_offset = ra_->reg2offset(dst_first); 1161 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1162 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1163 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1164 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1165 int stack_offset = ra_->reg2offset(dst_first); 1166 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1167 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1168 int stack_offset = ra_->reg2offset(src_first); 1169 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1170 } else { 1171 ShouldNotReachHere(); 1172 } 1173 return 0; 1174 } 1175 if (src_first_rc == rc_stack) { 1176 // mem -> 1177 if (dst_first_rc == rc_stack) { 1178 // mem -> mem 1179 assert(src_second != dst_first, "overlap"); 1180 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1181 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1182 // 64-bit 1183 int src_offset = ra_->reg2offset(src_first); 1184 int dst_offset = ra_->reg2offset(dst_first); 1185 if (cbuf) { 1186 MacroAssembler _masm(cbuf); 1187 __ pushq(Address(rsp, src_offset)); 1188 __ popq (Address(rsp, dst_offset)); 1189 #ifndef PRODUCT 1190 } else { 1191 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1192 "popq [rsp + #%d]", 1193 src_offset, dst_offset); 1194 #endif 1195 } 1196 } else { 1197 // 32-bit 1198 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1199 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1200 // No pushl/popl, so: 1201 int src_offset = ra_->reg2offset(src_first); 1202 int dst_offset = ra_->reg2offset(dst_first); 1203 if (cbuf) { 1204 MacroAssembler _masm(cbuf); 1205 __ movq(Address(rsp, -8), rax); 1206 __ movl(rax, Address(rsp, src_offset)); 1207 __ movl(Address(rsp, dst_offset), rax); 1208 __ movq(rax, Address(rsp, -8)); 1209 #ifndef PRODUCT 1210 } else { 1211 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1212 "movl rax, [rsp + #%d]\n\t" 1213 "movl [rsp + #%d], rax\n\t" 1214 "movq rax, [rsp - #8]", 1215 src_offset, dst_offset); 1216 #endif 1217 } 1218 } 1219 return 0; 1220 } else if (dst_first_rc == rc_int) { 1221 // mem -> gpr 1222 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1223 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1224 // 64-bit 1225 int offset = ra_->reg2offset(src_first); 1226 if (cbuf) { 1227 MacroAssembler _masm(cbuf); 1228 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1229 #ifndef PRODUCT 1230 } else { 1231 st->print("movq %s, [rsp + #%d]\t# spill", 1232 Matcher::regName[dst_first], 1233 offset); 1234 #endif 1235 } 1236 } else { 1237 // 32-bit 1238 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1239 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1240 int offset = ra_->reg2offset(src_first); 1241 if (cbuf) { 1242 MacroAssembler _masm(cbuf); 1243 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1244 #ifndef PRODUCT 1245 } else { 1246 st->print("movl %s, [rsp + #%d]\t# spill", 1247 Matcher::regName[dst_first], 1248 offset); 1249 #endif 1250 } 1251 } 1252 return 0; 1253 } else if (dst_first_rc == rc_float) { 1254 // mem-> xmm 1255 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1256 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1257 // 64-bit 1258 int offset = ra_->reg2offset(src_first); 1259 if (cbuf) { 1260 MacroAssembler _masm(cbuf); 1261 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1262 #ifndef PRODUCT 1263 } else { 1264 st->print("%s %s, [rsp + #%d]\t# spill", 1265 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1266 Matcher::regName[dst_first], 1267 offset); 1268 #endif 1269 } 1270 } else { 1271 // 32-bit 1272 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1273 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1274 int offset = ra_->reg2offset(src_first); 1275 if (cbuf) { 1276 MacroAssembler _masm(cbuf); 1277 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1278 #ifndef PRODUCT 1279 } else { 1280 st->print("movss %s, [rsp + #%d]\t# spill", 1281 Matcher::regName[dst_first], 1282 offset); 1283 #endif 1284 } 1285 } 1286 return 0; 1287 } 1288 } else if (src_first_rc == rc_int) { 1289 // gpr -> 1290 if (dst_first_rc == rc_stack) { 1291 // gpr -> mem 1292 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1293 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1294 // 64-bit 1295 int offset = ra_->reg2offset(dst_first); 1296 if (cbuf) { 1297 MacroAssembler _masm(cbuf); 1298 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1299 #ifndef PRODUCT 1300 } else { 1301 st->print("movq [rsp + #%d], %s\t# spill", 1302 offset, 1303 Matcher::regName[src_first]); 1304 #endif 1305 } 1306 } else { 1307 // 32-bit 1308 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1309 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1310 int offset = ra_->reg2offset(dst_first); 1311 if (cbuf) { 1312 MacroAssembler _masm(cbuf); 1313 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1314 #ifndef PRODUCT 1315 } else { 1316 st->print("movl [rsp + #%d], %s\t# spill", 1317 offset, 1318 Matcher::regName[src_first]); 1319 #endif 1320 } 1321 } 1322 return 0; 1323 } else if (dst_first_rc == rc_int) { 1324 // gpr -> gpr 1325 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1326 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1327 // 64-bit 1328 if (cbuf) { 1329 MacroAssembler _masm(cbuf); 1330 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1331 as_Register(Matcher::_regEncode[src_first])); 1332 #ifndef PRODUCT 1333 } else { 1334 st->print("movq %s, %s\t# spill", 1335 Matcher::regName[dst_first], 1336 Matcher::regName[src_first]); 1337 #endif 1338 } 1339 return 0; 1340 } else { 1341 // 32-bit 1342 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1343 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1344 if (cbuf) { 1345 MacroAssembler _masm(cbuf); 1346 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1347 as_Register(Matcher::_regEncode[src_first])); 1348 #ifndef PRODUCT 1349 } else { 1350 st->print("movl %s, %s\t# spill", 1351 Matcher::regName[dst_first], 1352 Matcher::regName[src_first]); 1353 #endif 1354 } 1355 return 0; 1356 } 1357 } else if (dst_first_rc == rc_float) { 1358 // gpr -> xmm 1359 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1360 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1361 // 64-bit 1362 if (cbuf) { 1363 MacroAssembler _masm(cbuf); 1364 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1365 #ifndef PRODUCT 1366 } else { 1367 st->print("movdq %s, %s\t# spill", 1368 Matcher::regName[dst_first], 1369 Matcher::regName[src_first]); 1370 #endif 1371 } 1372 } else { 1373 // 32-bit 1374 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1375 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1376 if (cbuf) { 1377 MacroAssembler _masm(cbuf); 1378 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1379 #ifndef PRODUCT 1380 } else { 1381 st->print("movdl %s, %s\t# spill", 1382 Matcher::regName[dst_first], 1383 Matcher::regName[src_first]); 1384 #endif 1385 } 1386 } 1387 return 0; 1388 } 1389 } else if (src_first_rc == rc_float) { 1390 // xmm -> 1391 if (dst_first_rc == rc_stack) { 1392 // xmm -> mem 1393 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1394 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1395 // 64-bit 1396 int offset = ra_->reg2offset(dst_first); 1397 if (cbuf) { 1398 MacroAssembler _masm(cbuf); 1399 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1400 #ifndef PRODUCT 1401 } else { 1402 st->print("movsd [rsp + #%d], %s\t# spill", 1403 offset, 1404 Matcher::regName[src_first]); 1405 #endif 1406 } 1407 } else { 1408 // 32-bit 1409 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1410 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1411 int offset = ra_->reg2offset(dst_first); 1412 if (cbuf) { 1413 MacroAssembler _masm(cbuf); 1414 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1415 #ifndef PRODUCT 1416 } else { 1417 st->print("movss [rsp + #%d], %s\t# spill", 1418 offset, 1419 Matcher::regName[src_first]); 1420 #endif 1421 } 1422 } 1423 return 0; 1424 } else if (dst_first_rc == rc_int) { 1425 // xmm -> gpr 1426 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1427 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1428 // 64-bit 1429 if (cbuf) { 1430 MacroAssembler _masm(cbuf); 1431 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1432 #ifndef PRODUCT 1433 } else { 1434 st->print("movdq %s, %s\t# spill", 1435 Matcher::regName[dst_first], 1436 Matcher::regName[src_first]); 1437 #endif 1438 } 1439 } else { 1440 // 32-bit 1441 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1442 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1443 if (cbuf) { 1444 MacroAssembler _masm(cbuf); 1445 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1446 #ifndef PRODUCT 1447 } else { 1448 st->print("movdl %s, %s\t# spill", 1449 Matcher::regName[dst_first], 1450 Matcher::regName[src_first]); 1451 #endif 1452 } 1453 } 1454 return 0; 1455 } else if (dst_first_rc == rc_float) { 1456 // xmm -> xmm 1457 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1458 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1459 // 64-bit 1460 if (cbuf) { 1461 MacroAssembler _masm(cbuf); 1462 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1463 #ifndef PRODUCT 1464 } else { 1465 st->print("%s %s, %s\t# spill", 1466 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1467 Matcher::regName[dst_first], 1468 Matcher::regName[src_first]); 1469 #endif 1470 } 1471 } else { 1472 // 32-bit 1473 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1474 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1475 if (cbuf) { 1476 MacroAssembler _masm(cbuf); 1477 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1478 #ifndef PRODUCT 1479 } else { 1480 st->print("%s %s, %s\t# spill", 1481 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1482 Matcher::regName[dst_first], 1483 Matcher::regName[src_first]); 1484 #endif 1485 } 1486 } 1487 return 0; 1488 } 1489 } 1490 1491 assert(0," foo "); 1492 Unimplemented(); 1493 return 0; 1494 } 1495 1496 #ifndef PRODUCT 1497 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1498 implementation(NULL, ra_, false, st); 1499 } 1500 #endif 1501 1502 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1503 implementation(&cbuf, ra_, false, NULL); 1504 } 1505 1506 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1507 return MachNode::size(ra_); 1508 } 1509 1510 //============================================================================= 1511 #ifndef PRODUCT 1512 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1513 { 1514 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1515 int reg = ra_->get_reg_first(this); 1516 st->print("leaq %s, [rsp + #%d]\t# box lock", 1517 Matcher::regName[reg], offset); 1518 } 1519 #endif 1520 1521 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1522 { 1523 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1524 int reg = ra_->get_encode(this); 1525 if (offset >= 0x80) { 1526 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1527 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1528 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1529 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1530 emit_d32(cbuf, offset); 1531 } else { 1532 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1533 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1534 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1535 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1536 emit_d8(cbuf, offset); 1537 } 1538 } 1539 1540 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1541 { 1542 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1543 return (offset < 0x80) ? 5 : 8; // REX 1544 } 1545 1546 //============================================================================= 1547 #ifndef PRODUCT 1548 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1549 { 1550 if (UseCompressedClassPointers) { 1551 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1552 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1553 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1554 } else { 1555 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1556 "# Inline cache check"); 1557 } 1558 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1559 st->print_cr("\tnop\t# nops to align entry point"); 1560 } 1561 #endif 1562 1563 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1564 { 1565 MacroAssembler masm(&cbuf); 1566 uint insts_size = cbuf.insts_size(); 1567 if (UseCompressedClassPointers) { 1568 masm.load_klass(rscratch1, j_rarg0); 1569 masm.cmpptr(rax, rscratch1); 1570 } else { 1571 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1572 } 1573 1574 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1575 1576 /* WARNING these NOPs are critical so that verified entry point is properly 1577 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1578 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1579 if (OptoBreakpoint) { 1580 // Leave space for int3 1581 nops_cnt -= 1; 1582 } 1583 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1584 if (nops_cnt > 0) 1585 masm.nop(nops_cnt); 1586 } 1587 1588 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1589 { 1590 return MachNode::size(ra_); // too many variables; just compute it 1591 // the hard way 1592 } 1593 1594 1595 //============================================================================= 1596 1597 int Matcher::regnum_to_fpu_offset(int regnum) 1598 { 1599 return regnum - 32; // The FP registers are in the second chunk 1600 } 1601 1602 // This is UltraSparc specific, true just means we have fast l2f conversion 1603 const bool Matcher::convL2FSupported(void) { 1604 return true; 1605 } 1606 1607 // Is this branch offset short enough that a short branch can be used? 1608 // 1609 // NOTE: If the platform does not provide any short branch variants, then 1610 // this method should return false for offset 0. 1611 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1612 // The passed offset is relative to address of the branch. 1613 // On 86 a branch displacement is calculated relative to address 1614 // of a next instruction. 1615 offset -= br_size; 1616 1617 // the short version of jmpConUCF2 contains multiple branches, 1618 // making the reach slightly less 1619 if (rule == jmpConUCF2_rule) 1620 return (-126 <= offset && offset <= 125); 1621 return (-128 <= offset && offset <= 127); 1622 } 1623 1624 const bool Matcher::isSimpleConstant64(jlong value) { 1625 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1626 //return value == (int) value; // Cf. storeImmL and immL32. 1627 1628 // Probably always true, even if a temp register is required. 1629 return true; 1630 } 1631 1632 // The ecx parameter to rep stosq for the ClearArray node is in words. 1633 const bool Matcher::init_array_count_is_in_bytes = false; 1634 1635 // Threshold size for cleararray. 1636 const int Matcher::init_array_short_size = 8 * BytesPerLong; 1637 1638 // No additional cost for CMOVL. 1639 const int Matcher::long_cmove_cost() { return 0; } 1640 1641 // No CMOVF/CMOVD with SSE2 1642 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1643 1644 // Does the CPU require late expand (see block.cpp for description of late expand)? 1645 const bool Matcher::require_postalloc_expand = false; 1646 1647 // Should the Matcher clone shifts on addressing modes, expecting them 1648 // to be subsumed into complex addressing expressions or compute them 1649 // into registers? True for Intel but false for most RISCs 1650 const bool Matcher::clone_shift_expressions = true; 1651 1652 // Do we need to mask the count passed to shift instructions or does 1653 // the cpu only look at the lower 5/6 bits anyway? 1654 const bool Matcher::need_masked_shift_count = false; 1655 1656 bool Matcher::narrow_oop_use_complex_address() { 1657 assert(UseCompressedOops, "only for compressed oops code"); 1658 return (LogMinObjAlignmentInBytes <= 3); 1659 } 1660 1661 bool Matcher::narrow_klass_use_complex_address() { 1662 assert(UseCompressedClassPointers, "only for compressed klass code"); 1663 return (LogKlassAlignmentInBytes <= 3); 1664 } 1665 1666 // Is it better to copy float constants, or load them directly from 1667 // memory? Intel can load a float constant from a direct address, 1668 // requiring no extra registers. Most RISCs will have to materialize 1669 // an address into a register first, so they would do better to copy 1670 // the constant from stack. 1671 const bool Matcher::rematerialize_float_constants = true; // XXX 1672 1673 // If CPU can load and store mis-aligned doubles directly then no 1674 // fixup is needed. Else we split the double into 2 integer pieces 1675 // and move it piece-by-piece. Only happens when passing doubles into 1676 // C code as the Java calling convention forces doubles to be aligned. 1677 const bool Matcher::misaligned_doubles_ok = true; 1678 1679 // No-op on amd64 1680 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1681 1682 // Advertise here if the CPU requires explicit rounding operations to 1683 // implement the UseStrictFP mode. 1684 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1685 1686 // Are floats conerted to double when stored to stack during deoptimization? 1687 // On x64 it is stored without convertion so we can use normal access. 1688 bool Matcher::float_in_double() { return false; } 1689 1690 // Do ints take an entire long register or just half? 1691 const bool Matcher::int_in_long = true; 1692 1693 // Return whether or not this register is ever used as an argument. 1694 // This function is used on startup to build the trampoline stubs in 1695 // generateOptoStub. Registers not mentioned will be killed by the VM 1696 // call in the trampoline, and arguments in those registers not be 1697 // available to the callee. 1698 bool Matcher::can_be_java_arg(int reg) 1699 { 1700 return 1701 reg == RDI_num || reg == RDI_H_num || 1702 reg == RSI_num || reg == RSI_H_num || 1703 reg == RDX_num || reg == RDX_H_num || 1704 reg == RCX_num || reg == RCX_H_num || 1705 reg == R8_num || reg == R8_H_num || 1706 reg == R9_num || reg == R9_H_num || 1707 reg == R12_num || reg == R12_H_num || 1708 reg == XMM0_num || reg == XMM0b_num || 1709 reg == XMM1_num || reg == XMM1b_num || 1710 reg == XMM2_num || reg == XMM2b_num || 1711 reg == XMM3_num || reg == XMM3b_num || 1712 reg == XMM4_num || reg == XMM4b_num || 1713 reg == XMM5_num || reg == XMM5b_num || 1714 reg == XMM6_num || reg == XMM6b_num || 1715 reg == XMM7_num || reg == XMM7b_num; 1716 } 1717 1718 bool Matcher::is_spillable_arg(int reg) 1719 { 1720 return can_be_java_arg(reg); 1721 } 1722 1723 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1724 // In 64 bit mode a code which use multiply when 1725 // devisor is constant is faster than hardware 1726 // DIV instruction (it uses MulHiL). 1727 return false; 1728 } 1729 1730 // Register for DIVI projection of divmodI 1731 RegMask Matcher::divI_proj_mask() { 1732 return INT_RAX_REG_mask(); 1733 } 1734 1735 // Register for MODI projection of divmodI 1736 RegMask Matcher::modI_proj_mask() { 1737 return INT_RDX_REG_mask(); 1738 } 1739 1740 // Register for DIVL projection of divmodL 1741 RegMask Matcher::divL_proj_mask() { 1742 return LONG_RAX_REG_mask(); 1743 } 1744 1745 // Register for MODL projection of divmodL 1746 RegMask Matcher::modL_proj_mask() { 1747 return LONG_RDX_REG_mask(); 1748 } 1749 1750 // Register for saving SP into on method handle invokes. Not used on x86_64. 1751 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1752 return NO_REG_mask(); 1753 } 1754 1755 %} 1756 1757 //----------ENCODING BLOCK----------------------------------------------------- 1758 // This block specifies the encoding classes used by the compiler to 1759 // output byte streams. Encoding classes are parameterized macros 1760 // used by Machine Instruction Nodes in order to generate the bit 1761 // encoding of the instruction. Operands specify their base encoding 1762 // interface with the interface keyword. There are currently 1763 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1764 // COND_INTER. REG_INTER causes an operand to generate a function 1765 // which returns its register number when queried. CONST_INTER causes 1766 // an operand to generate a function which returns the value of the 1767 // constant when queried. MEMORY_INTER causes an operand to generate 1768 // four functions which return the Base Register, the Index Register, 1769 // the Scale Value, and the Offset Value of the operand when queried. 1770 // COND_INTER causes an operand to generate six functions which return 1771 // the encoding code (ie - encoding bits for the instruction) 1772 // associated with each basic boolean condition for a conditional 1773 // instruction. 1774 // 1775 // Instructions specify two basic values for encoding. Again, a 1776 // function is available to check if the constant displacement is an 1777 // oop. They use the ins_encode keyword to specify their encoding 1778 // classes (which must be a sequence of enc_class names, and their 1779 // parameters, specified in the encoding block), and they use the 1780 // opcode keyword to specify, in order, their primary, secondary, and 1781 // tertiary opcode. Only the opcode sections which a particular 1782 // instruction needs for encoding need to be specified. 1783 encode %{ 1784 // Build emit functions for each basic byte or larger field in the 1785 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1786 // from C++ code in the enc_class source block. Emit functions will 1787 // live in the main source block for now. In future, we can 1788 // generalize this by adding a syntax that specifies the sizes of 1789 // fields in an order, so that the adlc can build the emit functions 1790 // automagically 1791 1792 // Emit primary opcode 1793 enc_class OpcP 1794 %{ 1795 emit_opcode(cbuf, $primary); 1796 %} 1797 1798 // Emit secondary opcode 1799 enc_class OpcS 1800 %{ 1801 emit_opcode(cbuf, $secondary); 1802 %} 1803 1804 // Emit tertiary opcode 1805 enc_class OpcT 1806 %{ 1807 emit_opcode(cbuf, $tertiary); 1808 %} 1809 1810 // Emit opcode directly 1811 enc_class Opcode(immI d8) 1812 %{ 1813 emit_opcode(cbuf, $d8$$constant); 1814 %} 1815 1816 // Emit size prefix 1817 enc_class SizePrefix 1818 %{ 1819 emit_opcode(cbuf, 0x66); 1820 %} 1821 1822 enc_class reg(rRegI reg) 1823 %{ 1824 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1825 %} 1826 1827 enc_class reg_reg(rRegI dst, rRegI src) 1828 %{ 1829 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1830 %} 1831 1832 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1833 %{ 1834 emit_opcode(cbuf, $opcode$$constant); 1835 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1836 %} 1837 1838 enc_class cdql_enc(no_rax_rdx_RegI div) 1839 %{ 1840 // Full implementation of Java idiv and irem; checks for 1841 // special case as described in JVM spec., p.243 & p.271. 1842 // 1843 // normal case special case 1844 // 1845 // input : rax: dividend min_int 1846 // reg: divisor -1 1847 // 1848 // output: rax: quotient (= rax idiv reg) min_int 1849 // rdx: remainder (= rax irem reg) 0 1850 // 1851 // Code sequnce: 1852 // 1853 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1854 // 5: 75 07/08 jne e <normal> 1855 // 7: 33 d2 xor %edx,%edx 1856 // [div >= 8 -> offset + 1] 1857 // [REX_B] 1858 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1859 // c: 74 03/04 je 11 <done> 1860 // 000000000000000e <normal>: 1861 // e: 99 cltd 1862 // [div >= 8 -> offset + 1] 1863 // [REX_B] 1864 // f: f7 f9 idiv $div 1865 // 0000000000000011 <done>: 1866 1867 // cmp $0x80000000,%eax 1868 emit_opcode(cbuf, 0x3d); 1869 emit_d8(cbuf, 0x00); 1870 emit_d8(cbuf, 0x00); 1871 emit_d8(cbuf, 0x00); 1872 emit_d8(cbuf, 0x80); 1873 1874 // jne e <normal> 1875 emit_opcode(cbuf, 0x75); 1876 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1877 1878 // xor %edx,%edx 1879 emit_opcode(cbuf, 0x33); 1880 emit_d8(cbuf, 0xD2); 1881 1882 // cmp $0xffffffffffffffff,%ecx 1883 if ($div$$reg >= 8) { 1884 emit_opcode(cbuf, Assembler::REX_B); 1885 } 1886 emit_opcode(cbuf, 0x83); 1887 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1888 emit_d8(cbuf, 0xFF); 1889 1890 // je 11 <done> 1891 emit_opcode(cbuf, 0x74); 1892 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1893 1894 // <normal> 1895 // cltd 1896 emit_opcode(cbuf, 0x99); 1897 1898 // idivl (note: must be emitted by the user of this rule) 1899 // <done> 1900 %} 1901 1902 enc_class cdqq_enc(no_rax_rdx_RegL div) 1903 %{ 1904 // Full implementation of Java ldiv and lrem; checks for 1905 // special case as described in JVM spec., p.243 & p.271. 1906 // 1907 // normal case special case 1908 // 1909 // input : rax: dividend min_long 1910 // reg: divisor -1 1911 // 1912 // output: rax: quotient (= rax idiv reg) min_long 1913 // rdx: remainder (= rax irem reg) 0 1914 // 1915 // Code sequnce: 1916 // 1917 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1918 // 7: 00 00 80 1919 // a: 48 39 d0 cmp %rdx,%rax 1920 // d: 75 08 jne 17 <normal> 1921 // f: 33 d2 xor %edx,%edx 1922 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1923 // 15: 74 05 je 1c <done> 1924 // 0000000000000017 <normal>: 1925 // 17: 48 99 cqto 1926 // 19: 48 f7 f9 idiv $div 1927 // 000000000000001c <done>: 1928 1929 // mov $0x8000000000000000,%rdx 1930 emit_opcode(cbuf, Assembler::REX_W); 1931 emit_opcode(cbuf, 0xBA); 1932 emit_d8(cbuf, 0x00); 1933 emit_d8(cbuf, 0x00); 1934 emit_d8(cbuf, 0x00); 1935 emit_d8(cbuf, 0x00); 1936 emit_d8(cbuf, 0x00); 1937 emit_d8(cbuf, 0x00); 1938 emit_d8(cbuf, 0x00); 1939 emit_d8(cbuf, 0x80); 1940 1941 // cmp %rdx,%rax 1942 emit_opcode(cbuf, Assembler::REX_W); 1943 emit_opcode(cbuf, 0x39); 1944 emit_d8(cbuf, 0xD0); 1945 1946 // jne 17 <normal> 1947 emit_opcode(cbuf, 0x75); 1948 emit_d8(cbuf, 0x08); 1949 1950 // xor %edx,%edx 1951 emit_opcode(cbuf, 0x33); 1952 emit_d8(cbuf, 0xD2); 1953 1954 // cmp $0xffffffffffffffff,$div 1955 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1956 emit_opcode(cbuf, 0x83); 1957 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1958 emit_d8(cbuf, 0xFF); 1959 1960 // je 1e <done> 1961 emit_opcode(cbuf, 0x74); 1962 emit_d8(cbuf, 0x05); 1963 1964 // <normal> 1965 // cqto 1966 emit_opcode(cbuf, Assembler::REX_W); 1967 emit_opcode(cbuf, 0x99); 1968 1969 // idivq (note: must be emitted by the user of this rule) 1970 // <done> 1971 %} 1972 1973 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1974 enc_class OpcSE(immI imm) 1975 %{ 1976 // Emit primary opcode and set sign-extend bit 1977 // Check for 8-bit immediate, and set sign extend bit in opcode 1978 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1979 emit_opcode(cbuf, $primary | 0x02); 1980 } else { 1981 // 32-bit immediate 1982 emit_opcode(cbuf, $primary); 1983 } 1984 %} 1985 1986 enc_class OpcSErm(rRegI dst, immI imm) 1987 %{ 1988 // OpcSEr/m 1989 int dstenc = $dst$$reg; 1990 if (dstenc >= 8) { 1991 emit_opcode(cbuf, Assembler::REX_B); 1992 dstenc -= 8; 1993 } 1994 // Emit primary opcode and set sign-extend bit 1995 // Check for 8-bit immediate, and set sign extend bit in opcode 1996 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1997 emit_opcode(cbuf, $primary | 0x02); 1998 } else { 1999 // 32-bit immediate 2000 emit_opcode(cbuf, $primary); 2001 } 2002 // Emit r/m byte with secondary opcode, after primary opcode. 2003 emit_rm(cbuf, 0x3, $secondary, dstenc); 2004 %} 2005 2006 enc_class OpcSErm_wide(rRegL dst, immI imm) 2007 %{ 2008 // OpcSEr/m 2009 int dstenc = $dst$$reg; 2010 if (dstenc < 8) { 2011 emit_opcode(cbuf, Assembler::REX_W); 2012 } else { 2013 emit_opcode(cbuf, Assembler::REX_WB); 2014 dstenc -= 8; 2015 } 2016 // Emit primary opcode and set sign-extend bit 2017 // Check for 8-bit immediate, and set sign extend bit in opcode 2018 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2019 emit_opcode(cbuf, $primary | 0x02); 2020 } else { 2021 // 32-bit immediate 2022 emit_opcode(cbuf, $primary); 2023 } 2024 // Emit r/m byte with secondary opcode, after primary opcode. 2025 emit_rm(cbuf, 0x3, $secondary, dstenc); 2026 %} 2027 2028 enc_class Con8or32(immI imm) 2029 %{ 2030 // Check for 8-bit immediate, and set sign extend bit in opcode 2031 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2032 $$$emit8$imm$$constant; 2033 } else { 2034 // 32-bit immediate 2035 $$$emit32$imm$$constant; 2036 } 2037 %} 2038 2039 enc_class opc2_reg(rRegI dst) 2040 %{ 2041 // BSWAP 2042 emit_cc(cbuf, $secondary, $dst$$reg); 2043 %} 2044 2045 enc_class opc3_reg(rRegI dst) 2046 %{ 2047 // BSWAP 2048 emit_cc(cbuf, $tertiary, $dst$$reg); 2049 %} 2050 2051 enc_class reg_opc(rRegI div) 2052 %{ 2053 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2054 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2055 %} 2056 2057 enc_class enc_cmov(cmpOp cop) 2058 %{ 2059 // CMOV 2060 $$$emit8$primary; 2061 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2062 %} 2063 2064 enc_class enc_PartialSubtypeCheck() 2065 %{ 2066 Register Rrdi = as_Register(RDI_enc); // result register 2067 Register Rrax = as_Register(RAX_enc); // super class 2068 Register Rrcx = as_Register(RCX_enc); // killed 2069 Register Rrsi = as_Register(RSI_enc); // sub class 2070 Label miss; 2071 const bool set_cond_codes = true; 2072 2073 MacroAssembler _masm(&cbuf); 2074 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2075 NULL, &miss, 2076 /*set_cond_codes:*/ true); 2077 if ($primary) { 2078 __ xorptr(Rrdi, Rrdi); 2079 } 2080 __ bind(miss); 2081 %} 2082 2083 enc_class clear_avx %{ 2084 debug_only(int off0 = cbuf.insts_size()); 2085 if (ra_->C->max_vector_size() > 16) { 2086 // Clear upper bits of YMM registers when current compiled code uses 2087 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2088 MacroAssembler _masm(&cbuf); 2089 __ vzeroupper(); 2090 } 2091 debug_only(int off1 = cbuf.insts_size()); 2092 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2093 %} 2094 2095 enc_class Java_To_Runtime(method meth) %{ 2096 // No relocation needed 2097 MacroAssembler _masm(&cbuf); 2098 __ mov64(r10, (int64_t) $meth$$method); 2099 __ call(r10); 2100 %} 2101 2102 enc_class Java_To_Interpreter(method meth) 2103 %{ 2104 // CALL Java_To_Interpreter 2105 // This is the instruction starting address for relocation info. 2106 cbuf.set_insts_mark(); 2107 $$$emit8$primary; 2108 // CALL directly to the runtime 2109 emit_d32_reloc(cbuf, 2110 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2111 runtime_call_Relocation::spec(), 2112 RELOC_DISP32); 2113 %} 2114 2115 enc_class Java_Static_Call(method meth) 2116 %{ 2117 // JAVA STATIC CALL 2118 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2119 // determine who we intended to call. 2120 cbuf.set_insts_mark(); 2121 $$$emit8$primary; 2122 2123 if (!_method) { 2124 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2125 runtime_call_Relocation::spec(), 2126 RELOC_DISP32); 2127 } else { 2128 int method_index = resolved_method_index(cbuf); 2129 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2130 : static_call_Relocation::spec(method_index); 2131 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2132 rspec, RELOC_DISP32); 2133 // Emit stubs for static call. 2134 address mark = cbuf.insts_mark(); 2135 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2136 if (stub == NULL) { 2137 ciEnv::current()->record_failure("CodeCache is full"); 2138 return; 2139 } 2140 } 2141 %} 2142 2143 enc_class Java_Dynamic_Call(method meth) %{ 2144 MacroAssembler _masm(&cbuf); 2145 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2146 %} 2147 2148 enc_class Java_Compiled_Call(method meth) 2149 %{ 2150 // JAVA COMPILED CALL 2151 int disp = in_bytes(Method:: from_compiled_offset()); 2152 2153 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2154 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2155 2156 // callq *disp(%rax) 2157 cbuf.set_insts_mark(); 2158 $$$emit8$primary; 2159 if (disp < 0x80) { 2160 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2161 emit_d8(cbuf, disp); // Displacement 2162 } else { 2163 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2164 emit_d32(cbuf, disp); // Displacement 2165 } 2166 %} 2167 2168 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2169 %{ 2170 // SAL, SAR, SHR 2171 int dstenc = $dst$$reg; 2172 if (dstenc >= 8) { 2173 emit_opcode(cbuf, Assembler::REX_B); 2174 dstenc -= 8; 2175 } 2176 $$$emit8$primary; 2177 emit_rm(cbuf, 0x3, $secondary, dstenc); 2178 $$$emit8$shift$$constant; 2179 %} 2180 2181 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2182 %{ 2183 // SAL, SAR, SHR 2184 int dstenc = $dst$$reg; 2185 if (dstenc < 8) { 2186 emit_opcode(cbuf, Assembler::REX_W); 2187 } else { 2188 emit_opcode(cbuf, Assembler::REX_WB); 2189 dstenc -= 8; 2190 } 2191 $$$emit8$primary; 2192 emit_rm(cbuf, 0x3, $secondary, dstenc); 2193 $$$emit8$shift$$constant; 2194 %} 2195 2196 enc_class load_immI(rRegI dst, immI src) 2197 %{ 2198 int dstenc = $dst$$reg; 2199 if (dstenc >= 8) { 2200 emit_opcode(cbuf, Assembler::REX_B); 2201 dstenc -= 8; 2202 } 2203 emit_opcode(cbuf, 0xB8 | dstenc); 2204 $$$emit32$src$$constant; 2205 %} 2206 2207 enc_class load_immL(rRegL dst, immL src) 2208 %{ 2209 int dstenc = $dst$$reg; 2210 if (dstenc < 8) { 2211 emit_opcode(cbuf, Assembler::REX_W); 2212 } else { 2213 emit_opcode(cbuf, Assembler::REX_WB); 2214 dstenc -= 8; 2215 } 2216 emit_opcode(cbuf, 0xB8 | dstenc); 2217 emit_d64(cbuf, $src$$constant); 2218 %} 2219 2220 enc_class load_immUL32(rRegL dst, immUL32 src) 2221 %{ 2222 // same as load_immI, but this time we care about zeroes in the high word 2223 int dstenc = $dst$$reg; 2224 if (dstenc >= 8) { 2225 emit_opcode(cbuf, Assembler::REX_B); 2226 dstenc -= 8; 2227 } 2228 emit_opcode(cbuf, 0xB8 | dstenc); 2229 $$$emit32$src$$constant; 2230 %} 2231 2232 enc_class load_immL32(rRegL dst, immL32 src) 2233 %{ 2234 int dstenc = $dst$$reg; 2235 if (dstenc < 8) { 2236 emit_opcode(cbuf, Assembler::REX_W); 2237 } else { 2238 emit_opcode(cbuf, Assembler::REX_WB); 2239 dstenc -= 8; 2240 } 2241 emit_opcode(cbuf, 0xC7); 2242 emit_rm(cbuf, 0x03, 0x00, dstenc); 2243 $$$emit32$src$$constant; 2244 %} 2245 2246 enc_class load_immP31(rRegP dst, immP32 src) 2247 %{ 2248 // same as load_immI, but this time we care about zeroes in the high word 2249 int dstenc = $dst$$reg; 2250 if (dstenc >= 8) { 2251 emit_opcode(cbuf, Assembler::REX_B); 2252 dstenc -= 8; 2253 } 2254 emit_opcode(cbuf, 0xB8 | dstenc); 2255 $$$emit32$src$$constant; 2256 %} 2257 2258 enc_class load_immP(rRegP dst, immP src) 2259 %{ 2260 int dstenc = $dst$$reg; 2261 if (dstenc < 8) { 2262 emit_opcode(cbuf, Assembler::REX_W); 2263 } else { 2264 emit_opcode(cbuf, Assembler::REX_WB); 2265 dstenc -= 8; 2266 } 2267 emit_opcode(cbuf, 0xB8 | dstenc); 2268 // This next line should be generated from ADLC 2269 if ($src->constant_reloc() != relocInfo::none) { 2270 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2271 } else { 2272 emit_d64(cbuf, $src$$constant); 2273 } 2274 %} 2275 2276 enc_class Con32(immI src) 2277 %{ 2278 // Output immediate 2279 $$$emit32$src$$constant; 2280 %} 2281 2282 enc_class Con32F_as_bits(immF src) 2283 %{ 2284 // Output Float immediate bits 2285 jfloat jf = $src$$constant; 2286 jint jf_as_bits = jint_cast(jf); 2287 emit_d32(cbuf, jf_as_bits); 2288 %} 2289 2290 enc_class Con16(immI src) 2291 %{ 2292 // Output immediate 2293 $$$emit16$src$$constant; 2294 %} 2295 2296 // How is this different from Con32??? XXX 2297 enc_class Con_d32(immI src) 2298 %{ 2299 emit_d32(cbuf,$src$$constant); 2300 %} 2301 2302 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2303 // Output immediate memory reference 2304 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2305 emit_d32(cbuf, 0x00); 2306 %} 2307 2308 enc_class lock_prefix() 2309 %{ 2310 if (os::is_MP()) { 2311 emit_opcode(cbuf, 0xF0); // lock 2312 } 2313 %} 2314 2315 enc_class REX_mem(memory mem) 2316 %{ 2317 if ($mem$$base >= 8) { 2318 if ($mem$$index < 8) { 2319 emit_opcode(cbuf, Assembler::REX_B); 2320 } else { 2321 emit_opcode(cbuf, Assembler::REX_XB); 2322 } 2323 } else { 2324 if ($mem$$index >= 8) { 2325 emit_opcode(cbuf, Assembler::REX_X); 2326 } 2327 } 2328 %} 2329 2330 enc_class REX_mem_wide(memory mem) 2331 %{ 2332 if ($mem$$base >= 8) { 2333 if ($mem$$index < 8) { 2334 emit_opcode(cbuf, Assembler::REX_WB); 2335 } else { 2336 emit_opcode(cbuf, Assembler::REX_WXB); 2337 } 2338 } else { 2339 if ($mem$$index < 8) { 2340 emit_opcode(cbuf, Assembler::REX_W); 2341 } else { 2342 emit_opcode(cbuf, Assembler::REX_WX); 2343 } 2344 } 2345 %} 2346 2347 // for byte regs 2348 enc_class REX_breg(rRegI reg) 2349 %{ 2350 if ($reg$$reg >= 4) { 2351 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2352 } 2353 %} 2354 2355 // for byte regs 2356 enc_class REX_reg_breg(rRegI dst, rRegI src) 2357 %{ 2358 if ($dst$$reg < 8) { 2359 if ($src$$reg >= 4) { 2360 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2361 } 2362 } else { 2363 if ($src$$reg < 8) { 2364 emit_opcode(cbuf, Assembler::REX_R); 2365 } else { 2366 emit_opcode(cbuf, Assembler::REX_RB); 2367 } 2368 } 2369 %} 2370 2371 // for byte regs 2372 enc_class REX_breg_mem(rRegI reg, memory mem) 2373 %{ 2374 if ($reg$$reg < 8) { 2375 if ($mem$$base < 8) { 2376 if ($mem$$index >= 8) { 2377 emit_opcode(cbuf, Assembler::REX_X); 2378 } else if ($reg$$reg >= 4) { 2379 emit_opcode(cbuf, Assembler::REX); 2380 } 2381 } else { 2382 if ($mem$$index < 8) { 2383 emit_opcode(cbuf, Assembler::REX_B); 2384 } else { 2385 emit_opcode(cbuf, Assembler::REX_XB); 2386 } 2387 } 2388 } else { 2389 if ($mem$$base < 8) { 2390 if ($mem$$index < 8) { 2391 emit_opcode(cbuf, Assembler::REX_R); 2392 } else { 2393 emit_opcode(cbuf, Assembler::REX_RX); 2394 } 2395 } else { 2396 if ($mem$$index < 8) { 2397 emit_opcode(cbuf, Assembler::REX_RB); 2398 } else { 2399 emit_opcode(cbuf, Assembler::REX_RXB); 2400 } 2401 } 2402 } 2403 %} 2404 2405 enc_class REX_reg(rRegI reg) 2406 %{ 2407 if ($reg$$reg >= 8) { 2408 emit_opcode(cbuf, Assembler::REX_B); 2409 } 2410 %} 2411 2412 enc_class REX_reg_wide(rRegI reg) 2413 %{ 2414 if ($reg$$reg < 8) { 2415 emit_opcode(cbuf, Assembler::REX_W); 2416 } else { 2417 emit_opcode(cbuf, Assembler::REX_WB); 2418 } 2419 %} 2420 2421 enc_class REX_reg_reg(rRegI dst, rRegI src) 2422 %{ 2423 if ($dst$$reg < 8) { 2424 if ($src$$reg >= 8) { 2425 emit_opcode(cbuf, Assembler::REX_B); 2426 } 2427 } else { 2428 if ($src$$reg < 8) { 2429 emit_opcode(cbuf, Assembler::REX_R); 2430 } else { 2431 emit_opcode(cbuf, Assembler::REX_RB); 2432 } 2433 } 2434 %} 2435 2436 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2437 %{ 2438 if ($dst$$reg < 8) { 2439 if ($src$$reg < 8) { 2440 emit_opcode(cbuf, Assembler::REX_W); 2441 } else { 2442 emit_opcode(cbuf, Assembler::REX_WB); 2443 } 2444 } else { 2445 if ($src$$reg < 8) { 2446 emit_opcode(cbuf, Assembler::REX_WR); 2447 } else { 2448 emit_opcode(cbuf, Assembler::REX_WRB); 2449 } 2450 } 2451 %} 2452 2453 enc_class REX_reg_mem(rRegI reg, memory mem) 2454 %{ 2455 if ($reg$$reg < 8) { 2456 if ($mem$$base < 8) { 2457 if ($mem$$index >= 8) { 2458 emit_opcode(cbuf, Assembler::REX_X); 2459 } 2460 } else { 2461 if ($mem$$index < 8) { 2462 emit_opcode(cbuf, Assembler::REX_B); 2463 } else { 2464 emit_opcode(cbuf, Assembler::REX_XB); 2465 } 2466 } 2467 } else { 2468 if ($mem$$base < 8) { 2469 if ($mem$$index < 8) { 2470 emit_opcode(cbuf, Assembler::REX_R); 2471 } else { 2472 emit_opcode(cbuf, Assembler::REX_RX); 2473 } 2474 } else { 2475 if ($mem$$index < 8) { 2476 emit_opcode(cbuf, Assembler::REX_RB); 2477 } else { 2478 emit_opcode(cbuf, Assembler::REX_RXB); 2479 } 2480 } 2481 } 2482 %} 2483 2484 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2485 %{ 2486 if ($reg$$reg < 8) { 2487 if ($mem$$base < 8) { 2488 if ($mem$$index < 8) { 2489 emit_opcode(cbuf, Assembler::REX_W); 2490 } else { 2491 emit_opcode(cbuf, Assembler::REX_WX); 2492 } 2493 } else { 2494 if ($mem$$index < 8) { 2495 emit_opcode(cbuf, Assembler::REX_WB); 2496 } else { 2497 emit_opcode(cbuf, Assembler::REX_WXB); 2498 } 2499 } 2500 } else { 2501 if ($mem$$base < 8) { 2502 if ($mem$$index < 8) { 2503 emit_opcode(cbuf, Assembler::REX_WR); 2504 } else { 2505 emit_opcode(cbuf, Assembler::REX_WRX); 2506 } 2507 } else { 2508 if ($mem$$index < 8) { 2509 emit_opcode(cbuf, Assembler::REX_WRB); 2510 } else { 2511 emit_opcode(cbuf, Assembler::REX_WRXB); 2512 } 2513 } 2514 } 2515 %} 2516 2517 enc_class reg_mem(rRegI ereg, memory mem) 2518 %{ 2519 // High registers handle in encode_RegMem 2520 int reg = $ereg$$reg; 2521 int base = $mem$$base; 2522 int index = $mem$$index; 2523 int scale = $mem$$scale; 2524 int disp = $mem$$disp; 2525 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2526 2527 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2528 %} 2529 2530 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2531 %{ 2532 int rm_byte_opcode = $rm_opcode$$constant; 2533 2534 // High registers handle in encode_RegMem 2535 int base = $mem$$base; 2536 int index = $mem$$index; 2537 int scale = $mem$$scale; 2538 int displace = $mem$$disp; 2539 2540 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2541 // working with static 2542 // globals 2543 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2544 disp_reloc); 2545 %} 2546 2547 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2548 %{ 2549 int reg_encoding = $dst$$reg; 2550 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2551 int index = 0x04; // 0x04 indicates no index 2552 int scale = 0x00; // 0x00 indicates no scale 2553 int displace = $src1$$constant; // 0x00 indicates no displacement 2554 relocInfo::relocType disp_reloc = relocInfo::none; 2555 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2556 disp_reloc); 2557 %} 2558 2559 enc_class neg_reg(rRegI dst) 2560 %{ 2561 int dstenc = $dst$$reg; 2562 if (dstenc >= 8) { 2563 emit_opcode(cbuf, Assembler::REX_B); 2564 dstenc -= 8; 2565 } 2566 // NEG $dst 2567 emit_opcode(cbuf, 0xF7); 2568 emit_rm(cbuf, 0x3, 0x03, dstenc); 2569 %} 2570 2571 enc_class neg_reg_wide(rRegI dst) 2572 %{ 2573 int dstenc = $dst$$reg; 2574 if (dstenc < 8) { 2575 emit_opcode(cbuf, Assembler::REX_W); 2576 } else { 2577 emit_opcode(cbuf, Assembler::REX_WB); 2578 dstenc -= 8; 2579 } 2580 // NEG $dst 2581 emit_opcode(cbuf, 0xF7); 2582 emit_rm(cbuf, 0x3, 0x03, dstenc); 2583 %} 2584 2585 enc_class setLT_reg(rRegI dst) 2586 %{ 2587 int dstenc = $dst$$reg; 2588 if (dstenc >= 8) { 2589 emit_opcode(cbuf, Assembler::REX_B); 2590 dstenc -= 8; 2591 } else if (dstenc >= 4) { 2592 emit_opcode(cbuf, Assembler::REX); 2593 } 2594 // SETLT $dst 2595 emit_opcode(cbuf, 0x0F); 2596 emit_opcode(cbuf, 0x9C); 2597 emit_rm(cbuf, 0x3, 0x0, dstenc); 2598 %} 2599 2600 enc_class setNZ_reg(rRegI dst) 2601 %{ 2602 int dstenc = $dst$$reg; 2603 if (dstenc >= 8) { 2604 emit_opcode(cbuf, Assembler::REX_B); 2605 dstenc -= 8; 2606 } else if (dstenc >= 4) { 2607 emit_opcode(cbuf, Assembler::REX); 2608 } 2609 // SETNZ $dst 2610 emit_opcode(cbuf, 0x0F); 2611 emit_opcode(cbuf, 0x95); 2612 emit_rm(cbuf, 0x3, 0x0, dstenc); 2613 %} 2614 2615 2616 // Compare the lonogs and set -1, 0, or 1 into dst 2617 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2618 %{ 2619 int src1enc = $src1$$reg; 2620 int src2enc = $src2$$reg; 2621 int dstenc = $dst$$reg; 2622 2623 // cmpq $src1, $src2 2624 if (src1enc < 8) { 2625 if (src2enc < 8) { 2626 emit_opcode(cbuf, Assembler::REX_W); 2627 } else { 2628 emit_opcode(cbuf, Assembler::REX_WB); 2629 } 2630 } else { 2631 if (src2enc < 8) { 2632 emit_opcode(cbuf, Assembler::REX_WR); 2633 } else { 2634 emit_opcode(cbuf, Assembler::REX_WRB); 2635 } 2636 } 2637 emit_opcode(cbuf, 0x3B); 2638 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2639 2640 // movl $dst, -1 2641 if (dstenc >= 8) { 2642 emit_opcode(cbuf, Assembler::REX_B); 2643 } 2644 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2645 emit_d32(cbuf, -1); 2646 2647 // jl,s done 2648 emit_opcode(cbuf, 0x7C); 2649 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2650 2651 // setne $dst 2652 if (dstenc >= 4) { 2653 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2654 } 2655 emit_opcode(cbuf, 0x0F); 2656 emit_opcode(cbuf, 0x95); 2657 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2658 2659 // movzbl $dst, $dst 2660 if (dstenc >= 4) { 2661 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2662 } 2663 emit_opcode(cbuf, 0x0F); 2664 emit_opcode(cbuf, 0xB6); 2665 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2666 %} 2667 2668 enc_class Push_ResultXD(regD dst) %{ 2669 MacroAssembler _masm(&cbuf); 2670 __ fstp_d(Address(rsp, 0)); 2671 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2672 __ addptr(rsp, 8); 2673 %} 2674 2675 enc_class Push_SrcXD(regD src) %{ 2676 MacroAssembler _masm(&cbuf); 2677 __ subptr(rsp, 8); 2678 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2679 __ fld_d(Address(rsp, 0)); 2680 %} 2681 2682 2683 enc_class enc_rethrow() 2684 %{ 2685 cbuf.set_insts_mark(); 2686 emit_opcode(cbuf, 0xE9); // jmp entry 2687 emit_d32_reloc(cbuf, 2688 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2689 runtime_call_Relocation::spec(), 2690 RELOC_DISP32); 2691 %} 2692 2693 %} 2694 2695 2696 2697 //----------FRAME-------------------------------------------------------------- 2698 // Definition of frame structure and management information. 2699 // 2700 // S T A C K L A Y O U T Allocators stack-slot number 2701 // | (to get allocators register number 2702 // G Owned by | | v add OptoReg::stack0()) 2703 // r CALLER | | 2704 // o | +--------+ pad to even-align allocators stack-slot 2705 // w V | pad0 | numbers; owned by CALLER 2706 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2707 // h ^ | in | 5 2708 // | | args | 4 Holes in incoming args owned by SELF 2709 // | | | | 3 2710 // | | +--------+ 2711 // V | | old out| Empty on Intel, window on Sparc 2712 // | old |preserve| Must be even aligned. 2713 // | SP-+--------+----> Matcher::_old_SP, even aligned 2714 // | | in | 3 area for Intel ret address 2715 // Owned by |preserve| Empty on Sparc. 2716 // SELF +--------+ 2717 // | | pad2 | 2 pad to align old SP 2718 // | +--------+ 1 2719 // | | locks | 0 2720 // | +--------+----> OptoReg::stack0(), even aligned 2721 // | | pad1 | 11 pad to align new SP 2722 // | +--------+ 2723 // | | | 10 2724 // | | spills | 9 spills 2725 // V | | 8 (pad0 slot for callee) 2726 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2727 // ^ | out | 7 2728 // | | args | 6 Holes in outgoing args owned by CALLEE 2729 // Owned by +--------+ 2730 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2731 // | new |preserve| Must be even-aligned. 2732 // | SP-+--------+----> Matcher::_new_SP, even aligned 2733 // | | | 2734 // 2735 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2736 // known from SELF's arguments and the Java calling convention. 2737 // Region 6-7 is determined per call site. 2738 // Note 2: If the calling convention leaves holes in the incoming argument 2739 // area, those holes are owned by SELF. Holes in the outgoing area 2740 // are owned by the CALLEE. Holes should not be nessecary in the 2741 // incoming area, as the Java calling convention is completely under 2742 // the control of the AD file. Doubles can be sorted and packed to 2743 // avoid holes. Holes in the outgoing arguments may be nessecary for 2744 // varargs C calling conventions. 2745 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2746 // even aligned with pad0 as needed. 2747 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2748 // region 6-11 is even aligned; it may be padded out more so that 2749 // the region from SP to FP meets the minimum stack alignment. 2750 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2751 // alignment. Region 11, pad1, may be dynamically extended so that 2752 // SP meets the minimum alignment. 2753 2754 frame 2755 %{ 2756 // What direction does stack grow in (assumed to be same for C & Java) 2757 stack_direction(TOWARDS_LOW); 2758 2759 // These three registers define part of the calling convention 2760 // between compiled code and the interpreter. 2761 inline_cache_reg(RAX); // Inline Cache Register 2762 interpreter_method_oop_reg(RBX); // Method Oop Register when 2763 // calling interpreter 2764 2765 // Optional: name the operand used by cisc-spilling to access 2766 // [stack_pointer + offset] 2767 cisc_spilling_operand_name(indOffset32); 2768 2769 // Number of stack slots consumed by locking an object 2770 sync_stack_slots(2); 2771 2772 // Compiled code's Frame Pointer 2773 frame_pointer(RSP); 2774 2775 // Interpreter stores its frame pointer in a register which is 2776 // stored to the stack by I2CAdaptors. 2777 // I2CAdaptors convert from interpreted java to compiled java. 2778 interpreter_frame_pointer(RBP); 2779 2780 // Stack alignment requirement 2781 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2782 2783 // Number of stack slots between incoming argument block and the start of 2784 // a new frame. The PROLOG must add this many slots to the stack. The 2785 // EPILOG must remove this many slots. amd64 needs two slots for 2786 // return address. 2787 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2788 2789 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2790 // for calls to C. Supports the var-args backing area for register parms. 2791 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2792 2793 // The after-PROLOG location of the return address. Location of 2794 // return address specifies a type (REG or STACK) and a number 2795 // representing the register number (i.e. - use a register name) or 2796 // stack slot. 2797 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2798 // Otherwise, it is above the locks and verification slot and alignment word 2799 return_addr(STACK - 2 + 2800 round_to((Compile::current()->in_preserve_stack_slots() + 2801 Compile::current()->fixed_slots()), 2802 stack_alignment_in_slots())); 2803 2804 // Body of function which returns an integer array locating 2805 // arguments either in registers or in stack slots. Passed an array 2806 // of ideal registers called "sig" and a "length" count. Stack-slot 2807 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2808 // arguments for a CALLEE. Incoming stack arguments are 2809 // automatically biased by the preserve_stack_slots field above. 2810 2811 calling_convention 2812 %{ 2813 // No difference between ingoing/outgoing just pass false 2814 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2815 %} 2816 2817 c_calling_convention 2818 %{ 2819 // This is obviously always outgoing 2820 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2821 %} 2822 2823 // Location of compiled Java return values. Same as C for now. 2824 return_value 2825 %{ 2826 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2827 "only return normal values"); 2828 2829 static const int lo[Op_RegL + 1] = { 2830 0, 2831 0, 2832 RAX_num, // Op_RegN 2833 RAX_num, // Op_RegI 2834 RAX_num, // Op_RegP 2835 XMM0_num, // Op_RegF 2836 XMM0_num, // Op_RegD 2837 RAX_num // Op_RegL 2838 }; 2839 static const int hi[Op_RegL + 1] = { 2840 0, 2841 0, 2842 OptoReg::Bad, // Op_RegN 2843 OptoReg::Bad, // Op_RegI 2844 RAX_H_num, // Op_RegP 2845 OptoReg::Bad, // Op_RegF 2846 XMM0b_num, // Op_RegD 2847 RAX_H_num // Op_RegL 2848 }; 2849 // Excluded flags and vector registers. 2850 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2851 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2852 %} 2853 %} 2854 2855 //----------ATTRIBUTES--------------------------------------------------------- 2856 //----------Operand Attributes------------------------------------------------- 2857 op_attrib op_cost(0); // Required cost attribute 2858 2859 //----------Instruction Attributes--------------------------------------------- 2860 ins_attrib ins_cost(100); // Required cost attribute 2861 ins_attrib ins_size(8); // Required size attribute (in bits) 2862 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2863 // a non-matching short branch variant 2864 // of some long branch? 2865 ins_attrib ins_alignment(1); // Required alignment attribute (must 2866 // be a power of 2) specifies the 2867 // alignment that some part of the 2868 // instruction (not necessarily the 2869 // start) requires. If > 1, a 2870 // compute_padding() function must be 2871 // provided for the instruction 2872 2873 //----------OPERANDS----------------------------------------------------------- 2874 // Operand definitions must precede instruction definitions for correct parsing 2875 // in the ADLC because operands constitute user defined types which are used in 2876 // instruction definitions. 2877 2878 //----------Simple Operands---------------------------------------------------- 2879 // Immediate Operands 2880 // Integer Immediate 2881 operand immI() 2882 %{ 2883 match(ConI); 2884 2885 op_cost(10); 2886 format %{ %} 2887 interface(CONST_INTER); 2888 %} 2889 2890 // Constant for test vs zero 2891 operand immI0() 2892 %{ 2893 predicate(n->get_int() == 0); 2894 match(ConI); 2895 2896 op_cost(0); 2897 format %{ %} 2898 interface(CONST_INTER); 2899 %} 2900 2901 // Constant for increment 2902 operand immI1() 2903 %{ 2904 predicate(n->get_int() == 1); 2905 match(ConI); 2906 2907 op_cost(0); 2908 format %{ %} 2909 interface(CONST_INTER); 2910 %} 2911 2912 // Constant for decrement 2913 operand immI_M1() 2914 %{ 2915 predicate(n->get_int() == -1); 2916 match(ConI); 2917 2918 op_cost(0); 2919 format %{ %} 2920 interface(CONST_INTER); 2921 %} 2922 2923 // Valid scale values for addressing modes 2924 operand immI2() 2925 %{ 2926 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2927 match(ConI); 2928 2929 format %{ %} 2930 interface(CONST_INTER); 2931 %} 2932 2933 operand immI8() 2934 %{ 2935 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2936 match(ConI); 2937 2938 op_cost(5); 2939 format %{ %} 2940 interface(CONST_INTER); 2941 %} 2942 2943 operand immI16() 2944 %{ 2945 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2946 match(ConI); 2947 2948 op_cost(10); 2949 format %{ %} 2950 interface(CONST_INTER); 2951 %} 2952 2953 // Int Immediate non-negative 2954 operand immU31() 2955 %{ 2956 predicate(n->get_int() >= 0); 2957 match(ConI); 2958 2959 op_cost(0); 2960 format %{ %} 2961 interface(CONST_INTER); 2962 %} 2963 2964 // Constant for long shifts 2965 operand immI_32() 2966 %{ 2967 predicate( n->get_int() == 32 ); 2968 match(ConI); 2969 2970 op_cost(0); 2971 format %{ %} 2972 interface(CONST_INTER); 2973 %} 2974 2975 // Constant for long shifts 2976 operand immI_64() 2977 %{ 2978 predicate( n->get_int() == 64 ); 2979 match(ConI); 2980 2981 op_cost(0); 2982 format %{ %} 2983 interface(CONST_INTER); 2984 %} 2985 2986 // Pointer Immediate 2987 operand immP() 2988 %{ 2989 match(ConP); 2990 2991 op_cost(10); 2992 format %{ %} 2993 interface(CONST_INTER); 2994 %} 2995 2996 // NULL Pointer Immediate 2997 operand immP0() 2998 %{ 2999 predicate(n->get_ptr() == 0); 3000 match(ConP); 3001 3002 op_cost(5); 3003 format %{ %} 3004 interface(CONST_INTER); 3005 %} 3006 3007 // Pointer Immediate 3008 operand immN() %{ 3009 match(ConN); 3010 3011 op_cost(10); 3012 format %{ %} 3013 interface(CONST_INTER); 3014 %} 3015 3016 operand immNKlass() %{ 3017 match(ConNKlass); 3018 3019 op_cost(10); 3020 format %{ %} 3021 interface(CONST_INTER); 3022 %} 3023 3024 // NULL Pointer Immediate 3025 operand immN0() %{ 3026 predicate(n->get_narrowcon() == 0); 3027 match(ConN); 3028 3029 op_cost(5); 3030 format %{ %} 3031 interface(CONST_INTER); 3032 %} 3033 3034 operand immP31() 3035 %{ 3036 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3037 && (n->get_ptr() >> 31) == 0); 3038 match(ConP); 3039 3040 op_cost(5); 3041 format %{ %} 3042 interface(CONST_INTER); 3043 %} 3044 3045 3046 // Long Immediate 3047 operand immL() 3048 %{ 3049 match(ConL); 3050 3051 op_cost(20); 3052 format %{ %} 3053 interface(CONST_INTER); 3054 %} 3055 3056 // Long Immediate 8-bit 3057 operand immL8() 3058 %{ 3059 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3060 match(ConL); 3061 3062 op_cost(5); 3063 format %{ %} 3064 interface(CONST_INTER); 3065 %} 3066 3067 // Long Immediate 32-bit unsigned 3068 operand immUL32() 3069 %{ 3070 predicate(n->get_long() == (unsigned int) (n->get_long())); 3071 match(ConL); 3072 3073 op_cost(10); 3074 format %{ %} 3075 interface(CONST_INTER); 3076 %} 3077 3078 // Long Immediate 32-bit signed 3079 operand immL32() 3080 %{ 3081 predicate(n->get_long() == (int) (n->get_long())); 3082 match(ConL); 3083 3084 op_cost(15); 3085 format %{ %} 3086 interface(CONST_INTER); 3087 %} 3088 3089 // Long Immediate zero 3090 operand immL0() 3091 %{ 3092 predicate(n->get_long() == 0L); 3093 match(ConL); 3094 3095 op_cost(10); 3096 format %{ %} 3097 interface(CONST_INTER); 3098 %} 3099 3100 // Constant for increment 3101 operand immL1() 3102 %{ 3103 predicate(n->get_long() == 1); 3104 match(ConL); 3105 3106 format %{ %} 3107 interface(CONST_INTER); 3108 %} 3109 3110 // Constant for decrement 3111 operand immL_M1() 3112 %{ 3113 predicate(n->get_long() == -1); 3114 match(ConL); 3115 3116 format %{ %} 3117 interface(CONST_INTER); 3118 %} 3119 3120 // Long Immediate: the value 10 3121 operand immL10() 3122 %{ 3123 predicate(n->get_long() == 10); 3124 match(ConL); 3125 3126 format %{ %} 3127 interface(CONST_INTER); 3128 %} 3129 3130 // Long immediate from 0 to 127. 3131 // Used for a shorter form of long mul by 10. 3132 operand immL_127() 3133 %{ 3134 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3135 match(ConL); 3136 3137 op_cost(10); 3138 format %{ %} 3139 interface(CONST_INTER); 3140 %} 3141 3142 // Long Immediate: low 32-bit mask 3143 operand immL_32bits() 3144 %{ 3145 predicate(n->get_long() == 0xFFFFFFFFL); 3146 match(ConL); 3147 op_cost(20); 3148 3149 format %{ %} 3150 interface(CONST_INTER); 3151 %} 3152 3153 // Float Immediate zero 3154 operand immF0() 3155 %{ 3156 predicate(jint_cast(n->getf()) == 0); 3157 match(ConF); 3158 3159 op_cost(5); 3160 format %{ %} 3161 interface(CONST_INTER); 3162 %} 3163 3164 // Float Immediate 3165 operand immF() 3166 %{ 3167 match(ConF); 3168 3169 op_cost(15); 3170 format %{ %} 3171 interface(CONST_INTER); 3172 %} 3173 3174 // Double Immediate zero 3175 operand immD0() 3176 %{ 3177 predicate(jlong_cast(n->getd()) == 0); 3178 match(ConD); 3179 3180 op_cost(5); 3181 format %{ %} 3182 interface(CONST_INTER); 3183 %} 3184 3185 // Double Immediate 3186 operand immD() 3187 %{ 3188 match(ConD); 3189 3190 op_cost(15); 3191 format %{ %} 3192 interface(CONST_INTER); 3193 %} 3194 3195 // Immediates for special shifts (sign extend) 3196 3197 // Constants for increment 3198 operand immI_16() 3199 %{ 3200 predicate(n->get_int() == 16); 3201 match(ConI); 3202 3203 format %{ %} 3204 interface(CONST_INTER); 3205 %} 3206 3207 operand immI_24() 3208 %{ 3209 predicate(n->get_int() == 24); 3210 match(ConI); 3211 3212 format %{ %} 3213 interface(CONST_INTER); 3214 %} 3215 3216 // Constant for byte-wide masking 3217 operand immI_255() 3218 %{ 3219 predicate(n->get_int() == 255); 3220 match(ConI); 3221 3222 format %{ %} 3223 interface(CONST_INTER); 3224 %} 3225 3226 // Constant for short-wide masking 3227 operand immI_65535() 3228 %{ 3229 predicate(n->get_int() == 65535); 3230 match(ConI); 3231 3232 format %{ %} 3233 interface(CONST_INTER); 3234 %} 3235 3236 // Constant for byte-wide masking 3237 operand immL_255() 3238 %{ 3239 predicate(n->get_long() == 255); 3240 match(ConL); 3241 3242 format %{ %} 3243 interface(CONST_INTER); 3244 %} 3245 3246 // Constant for short-wide masking 3247 operand immL_65535() 3248 %{ 3249 predicate(n->get_long() == 65535); 3250 match(ConL); 3251 3252 format %{ %} 3253 interface(CONST_INTER); 3254 %} 3255 3256 // Register Operands 3257 // Integer Register 3258 operand rRegI() 3259 %{ 3260 constraint(ALLOC_IN_RC(int_reg)); 3261 match(RegI); 3262 3263 match(rax_RegI); 3264 match(rbx_RegI); 3265 match(rcx_RegI); 3266 match(rdx_RegI); 3267 match(rdi_RegI); 3268 3269 format %{ %} 3270 interface(REG_INTER); 3271 %} 3272 3273 // Special Registers 3274 operand rax_RegI() 3275 %{ 3276 constraint(ALLOC_IN_RC(int_rax_reg)); 3277 match(RegI); 3278 match(rRegI); 3279 3280 format %{ "RAX" %} 3281 interface(REG_INTER); 3282 %} 3283 3284 // Special Registers 3285 operand rbx_RegI() 3286 %{ 3287 constraint(ALLOC_IN_RC(int_rbx_reg)); 3288 match(RegI); 3289 match(rRegI); 3290 3291 format %{ "RBX" %} 3292 interface(REG_INTER); 3293 %} 3294 3295 operand rcx_RegI() 3296 %{ 3297 constraint(ALLOC_IN_RC(int_rcx_reg)); 3298 match(RegI); 3299 match(rRegI); 3300 3301 format %{ "RCX" %} 3302 interface(REG_INTER); 3303 %} 3304 3305 operand rdx_RegI() 3306 %{ 3307 constraint(ALLOC_IN_RC(int_rdx_reg)); 3308 match(RegI); 3309 match(rRegI); 3310 3311 format %{ "RDX" %} 3312 interface(REG_INTER); 3313 %} 3314 3315 operand rdi_RegI() 3316 %{ 3317 constraint(ALLOC_IN_RC(int_rdi_reg)); 3318 match(RegI); 3319 match(rRegI); 3320 3321 format %{ "RDI" %} 3322 interface(REG_INTER); 3323 %} 3324 3325 operand no_rcx_RegI() 3326 %{ 3327 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3328 match(RegI); 3329 match(rax_RegI); 3330 match(rbx_RegI); 3331 match(rdx_RegI); 3332 match(rdi_RegI); 3333 3334 format %{ %} 3335 interface(REG_INTER); 3336 %} 3337 3338 operand no_rax_rdx_RegI() 3339 %{ 3340 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3341 match(RegI); 3342 match(rbx_RegI); 3343 match(rcx_RegI); 3344 match(rdi_RegI); 3345 3346 format %{ %} 3347 interface(REG_INTER); 3348 %} 3349 3350 // Pointer Register 3351 operand any_RegP() 3352 %{ 3353 constraint(ALLOC_IN_RC(any_reg)); 3354 match(RegP); 3355 match(rax_RegP); 3356 match(rbx_RegP); 3357 match(rdi_RegP); 3358 match(rsi_RegP); 3359 match(rbp_RegP); 3360 match(r15_RegP); 3361 match(rRegP); 3362 3363 format %{ %} 3364 interface(REG_INTER); 3365 %} 3366 3367 operand rRegP() 3368 %{ 3369 constraint(ALLOC_IN_RC(ptr_reg)); 3370 match(RegP); 3371 match(rax_RegP); 3372 match(rbx_RegP); 3373 match(rdi_RegP); 3374 match(rsi_RegP); 3375 match(rbp_RegP); // See Q&A below about 3376 match(r15_RegP); // r15_RegP and rbp_RegP. 3377 3378 format %{ %} 3379 interface(REG_INTER); 3380 %} 3381 3382 operand rRegN() %{ 3383 constraint(ALLOC_IN_RC(int_reg)); 3384 match(RegN); 3385 3386 format %{ %} 3387 interface(REG_INTER); 3388 %} 3389 3390 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3391 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3392 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 3393 // The output of an instruction is controlled by the allocator, which respects 3394 // register class masks, not match rules. Unless an instruction mentions 3395 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3396 // by the allocator as an input. 3397 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3398 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3399 // result, RBP is not included in the output of the instruction either. 3400 3401 operand no_rax_RegP() 3402 %{ 3403 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3404 match(RegP); 3405 match(rbx_RegP); 3406 match(rsi_RegP); 3407 match(rdi_RegP); 3408 3409 format %{ %} 3410 interface(REG_INTER); 3411 %} 3412 3413 // This operand is not allowed to use RBP even if 3414 // RBP is not used to hold the frame pointer. 3415 operand no_rbp_RegP() 3416 %{ 3417 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3418 match(RegP); 3419 match(rbx_RegP); 3420 match(rsi_RegP); 3421 match(rdi_RegP); 3422 3423 format %{ %} 3424 interface(REG_INTER); 3425 %} 3426 3427 operand no_rax_rbx_RegP() 3428 %{ 3429 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3430 match(RegP); 3431 match(rsi_RegP); 3432 match(rdi_RegP); 3433 3434 format %{ %} 3435 interface(REG_INTER); 3436 %} 3437 3438 // Special Registers 3439 // Return a pointer value 3440 operand rax_RegP() 3441 %{ 3442 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3443 match(RegP); 3444 match(rRegP); 3445 3446 format %{ %} 3447 interface(REG_INTER); 3448 %} 3449 3450 // Special Registers 3451 // Return a compressed pointer value 3452 operand rax_RegN() 3453 %{ 3454 constraint(ALLOC_IN_RC(int_rax_reg)); 3455 match(RegN); 3456 match(rRegN); 3457 3458 format %{ %} 3459 interface(REG_INTER); 3460 %} 3461 3462 // Used in AtomicAdd 3463 operand rbx_RegP() 3464 %{ 3465 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3466 match(RegP); 3467 match(rRegP); 3468 3469 format %{ %} 3470 interface(REG_INTER); 3471 %} 3472 3473 operand rsi_RegP() 3474 %{ 3475 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3476 match(RegP); 3477 match(rRegP); 3478 3479 format %{ %} 3480 interface(REG_INTER); 3481 %} 3482 3483 // Used in rep stosq 3484 operand rdi_RegP() 3485 %{ 3486 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3487 match(RegP); 3488 match(rRegP); 3489 3490 format %{ %} 3491 interface(REG_INTER); 3492 %} 3493 3494 operand r15_RegP() 3495 %{ 3496 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3497 match(RegP); 3498 match(rRegP); 3499 3500 format %{ %} 3501 interface(REG_INTER); 3502 %} 3503 3504 operand rRegL() 3505 %{ 3506 constraint(ALLOC_IN_RC(long_reg)); 3507 match(RegL); 3508 match(rax_RegL); 3509 match(rdx_RegL); 3510 3511 format %{ %} 3512 interface(REG_INTER); 3513 %} 3514 3515 // Special Registers 3516 operand no_rax_rdx_RegL() 3517 %{ 3518 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3519 match(RegL); 3520 match(rRegL); 3521 3522 format %{ %} 3523 interface(REG_INTER); 3524 %} 3525 3526 operand no_rax_RegL() 3527 %{ 3528 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3529 match(RegL); 3530 match(rRegL); 3531 match(rdx_RegL); 3532 3533 format %{ %} 3534 interface(REG_INTER); 3535 %} 3536 3537 operand no_rcx_RegL() 3538 %{ 3539 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3540 match(RegL); 3541 match(rRegL); 3542 3543 format %{ %} 3544 interface(REG_INTER); 3545 %} 3546 3547 operand rax_RegL() 3548 %{ 3549 constraint(ALLOC_IN_RC(long_rax_reg)); 3550 match(RegL); 3551 match(rRegL); 3552 3553 format %{ "RAX" %} 3554 interface(REG_INTER); 3555 %} 3556 3557 operand rcx_RegL() 3558 %{ 3559 constraint(ALLOC_IN_RC(long_rcx_reg)); 3560 match(RegL); 3561 match(rRegL); 3562 3563 format %{ %} 3564 interface(REG_INTER); 3565 %} 3566 3567 operand rdx_RegL() 3568 %{ 3569 constraint(ALLOC_IN_RC(long_rdx_reg)); 3570 match(RegL); 3571 match(rRegL); 3572 3573 format %{ %} 3574 interface(REG_INTER); 3575 %} 3576 3577 // Flags register, used as output of compare instructions 3578 operand rFlagsReg() 3579 %{ 3580 constraint(ALLOC_IN_RC(int_flags)); 3581 match(RegFlags); 3582 3583 format %{ "RFLAGS" %} 3584 interface(REG_INTER); 3585 %} 3586 3587 // Flags register, used as output of FLOATING POINT compare instructions 3588 operand rFlagsRegU() 3589 %{ 3590 constraint(ALLOC_IN_RC(int_flags)); 3591 match(RegFlags); 3592 3593 format %{ "RFLAGS_U" %} 3594 interface(REG_INTER); 3595 %} 3596 3597 operand rFlagsRegUCF() %{ 3598 constraint(ALLOC_IN_RC(int_flags)); 3599 match(RegFlags); 3600 predicate(false); 3601 3602 format %{ "RFLAGS_U_CF" %} 3603 interface(REG_INTER); 3604 %} 3605 3606 // Float register operands 3607 operand regF() %{ 3608 constraint(ALLOC_IN_RC(float_reg)); 3609 match(RegF); 3610 3611 format %{ %} 3612 interface(REG_INTER); 3613 %} 3614 3615 // Double register operands 3616 operand regD() %{ 3617 constraint(ALLOC_IN_RC(double_reg)); 3618 match(RegD); 3619 3620 format %{ %} 3621 interface(REG_INTER); 3622 %} 3623 3624 // Vectors 3625 operand vecS() %{ 3626 constraint(ALLOC_IN_RC(vectors_reg)); 3627 match(VecS); 3628 3629 format %{ %} 3630 interface(REG_INTER); 3631 %} 3632 3633 operand vecD() %{ 3634 constraint(ALLOC_IN_RC(vectord_reg)); 3635 match(VecD); 3636 3637 format %{ %} 3638 interface(REG_INTER); 3639 %} 3640 3641 operand vecX() %{ 3642 constraint(ALLOC_IN_RC(vectorx_reg)); 3643 match(VecX); 3644 3645 format %{ %} 3646 interface(REG_INTER); 3647 %} 3648 3649 operand vecY() %{ 3650 constraint(ALLOC_IN_RC(vectory_reg)); 3651 match(VecY); 3652 3653 format %{ %} 3654 interface(REG_INTER); 3655 %} 3656 3657 //----------Memory Operands---------------------------------------------------- 3658 // Direct Memory Operand 3659 // operand direct(immP addr) 3660 // %{ 3661 // match(addr); 3662 3663 // format %{ "[$addr]" %} 3664 // interface(MEMORY_INTER) %{ 3665 // base(0xFFFFFFFF); 3666 // index(0x4); 3667 // scale(0x0); 3668 // disp($addr); 3669 // %} 3670 // %} 3671 3672 // Indirect Memory Operand 3673 operand indirect(any_RegP reg) 3674 %{ 3675 constraint(ALLOC_IN_RC(ptr_reg)); 3676 match(reg); 3677 3678 format %{ "[$reg]" %} 3679 interface(MEMORY_INTER) %{ 3680 base($reg); 3681 index(0x4); 3682 scale(0x0); 3683 disp(0x0); 3684 %} 3685 %} 3686 3687 // Indirect Memory Plus Short Offset Operand 3688 operand indOffset8(any_RegP reg, immL8 off) 3689 %{ 3690 constraint(ALLOC_IN_RC(ptr_reg)); 3691 match(AddP reg off); 3692 3693 format %{ "[$reg + $off (8-bit)]" %} 3694 interface(MEMORY_INTER) %{ 3695 base($reg); 3696 index(0x4); 3697 scale(0x0); 3698 disp($off); 3699 %} 3700 %} 3701 3702 // Indirect Memory Plus Long Offset Operand 3703 operand indOffset32(any_RegP reg, immL32 off) 3704 %{ 3705 constraint(ALLOC_IN_RC(ptr_reg)); 3706 match(AddP reg off); 3707 3708 format %{ "[$reg + $off (32-bit)]" %} 3709 interface(MEMORY_INTER) %{ 3710 base($reg); 3711 index(0x4); 3712 scale(0x0); 3713 disp($off); 3714 %} 3715 %} 3716 3717 // Indirect Memory Plus Index Register Plus Offset Operand 3718 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3719 %{ 3720 constraint(ALLOC_IN_RC(ptr_reg)); 3721 match(AddP (AddP reg lreg) off); 3722 3723 op_cost(10); 3724 format %{"[$reg + $off + $lreg]" %} 3725 interface(MEMORY_INTER) %{ 3726 base($reg); 3727 index($lreg); 3728 scale(0x0); 3729 disp($off); 3730 %} 3731 %} 3732 3733 // Indirect Memory Plus Index Register Plus Offset Operand 3734 operand indIndex(any_RegP reg, rRegL lreg) 3735 %{ 3736 constraint(ALLOC_IN_RC(ptr_reg)); 3737 match(AddP reg lreg); 3738 3739 op_cost(10); 3740 format %{"[$reg + $lreg]" %} 3741 interface(MEMORY_INTER) %{ 3742 base($reg); 3743 index($lreg); 3744 scale(0x0); 3745 disp(0x0); 3746 %} 3747 %} 3748 3749 // Indirect Memory Times Scale Plus Index Register 3750 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3751 %{ 3752 constraint(ALLOC_IN_RC(ptr_reg)); 3753 match(AddP reg (LShiftL lreg scale)); 3754 3755 op_cost(10); 3756 format %{"[$reg + $lreg << $scale]" %} 3757 interface(MEMORY_INTER) %{ 3758 base($reg); 3759 index($lreg); 3760 scale($scale); 3761 disp(0x0); 3762 %} 3763 %} 3764 3765 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3766 %{ 3767 constraint(ALLOC_IN_RC(ptr_reg)); 3768 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3769 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3770 3771 op_cost(10); 3772 format %{"[$reg + pos $idx << $scale]" %} 3773 interface(MEMORY_INTER) %{ 3774 base($reg); 3775 index($idx); 3776 scale($scale); 3777 disp(0x0); 3778 %} 3779 %} 3780 3781 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3782 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3783 %{ 3784 constraint(ALLOC_IN_RC(ptr_reg)); 3785 match(AddP (AddP reg (LShiftL lreg scale)) off); 3786 3787 op_cost(10); 3788 format %{"[$reg + $off + $lreg << $scale]" %} 3789 interface(MEMORY_INTER) %{ 3790 base($reg); 3791 index($lreg); 3792 scale($scale); 3793 disp($off); 3794 %} 3795 %} 3796 3797 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3798 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3799 %{ 3800 constraint(ALLOC_IN_RC(ptr_reg)); 3801 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3802 match(AddP (AddP reg (ConvI2L idx)) off); 3803 3804 op_cost(10); 3805 format %{"[$reg + $off + $idx]" %} 3806 interface(MEMORY_INTER) %{ 3807 base($reg); 3808 index($idx); 3809 scale(0x0); 3810 disp($off); 3811 %} 3812 %} 3813 3814 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3815 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3816 %{ 3817 constraint(ALLOC_IN_RC(ptr_reg)); 3818 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3819 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3820 3821 op_cost(10); 3822 format %{"[$reg + $off + $idx << $scale]" %} 3823 interface(MEMORY_INTER) %{ 3824 base($reg); 3825 index($idx); 3826 scale($scale); 3827 disp($off); 3828 %} 3829 %} 3830 3831 // Indirect Narrow Oop Plus Offset Operand 3832 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3833 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3834 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3835 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3836 constraint(ALLOC_IN_RC(ptr_reg)); 3837 match(AddP (DecodeN reg) off); 3838 3839 op_cost(10); 3840 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3841 interface(MEMORY_INTER) %{ 3842 base(0xc); // R12 3843 index($reg); 3844 scale(0x3); 3845 disp($off); 3846 %} 3847 %} 3848 3849 // Indirect Memory Operand 3850 operand indirectNarrow(rRegN reg) 3851 %{ 3852 predicate(Universe::narrow_oop_shift() == 0); 3853 constraint(ALLOC_IN_RC(ptr_reg)); 3854 match(DecodeN reg); 3855 3856 format %{ "[$reg]" %} 3857 interface(MEMORY_INTER) %{ 3858 base($reg); 3859 index(0x4); 3860 scale(0x0); 3861 disp(0x0); 3862 %} 3863 %} 3864 3865 // Indirect Memory Plus Short Offset Operand 3866 operand indOffset8Narrow(rRegN reg, immL8 off) 3867 %{ 3868 predicate(Universe::narrow_oop_shift() == 0); 3869 constraint(ALLOC_IN_RC(ptr_reg)); 3870 match(AddP (DecodeN reg) off); 3871 3872 format %{ "[$reg + $off (8-bit)]" %} 3873 interface(MEMORY_INTER) %{ 3874 base($reg); 3875 index(0x4); 3876 scale(0x0); 3877 disp($off); 3878 %} 3879 %} 3880 3881 // Indirect Memory Plus Long Offset Operand 3882 operand indOffset32Narrow(rRegN reg, immL32 off) 3883 %{ 3884 predicate(Universe::narrow_oop_shift() == 0); 3885 constraint(ALLOC_IN_RC(ptr_reg)); 3886 match(AddP (DecodeN reg) off); 3887 3888 format %{ "[$reg + $off (32-bit)]" %} 3889 interface(MEMORY_INTER) %{ 3890 base($reg); 3891 index(0x4); 3892 scale(0x0); 3893 disp($off); 3894 %} 3895 %} 3896 3897 // Indirect Memory Plus Index Register Plus Offset Operand 3898 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3899 %{ 3900 predicate(Universe::narrow_oop_shift() == 0); 3901 constraint(ALLOC_IN_RC(ptr_reg)); 3902 match(AddP (AddP (DecodeN reg) lreg) off); 3903 3904 op_cost(10); 3905 format %{"[$reg + $off + $lreg]" %} 3906 interface(MEMORY_INTER) %{ 3907 base($reg); 3908 index($lreg); 3909 scale(0x0); 3910 disp($off); 3911 %} 3912 %} 3913 3914 // Indirect Memory Plus Index Register Plus Offset Operand 3915 operand indIndexNarrow(rRegN reg, rRegL lreg) 3916 %{ 3917 predicate(Universe::narrow_oop_shift() == 0); 3918 constraint(ALLOC_IN_RC(ptr_reg)); 3919 match(AddP (DecodeN reg) lreg); 3920 3921 op_cost(10); 3922 format %{"[$reg + $lreg]" %} 3923 interface(MEMORY_INTER) %{ 3924 base($reg); 3925 index($lreg); 3926 scale(0x0); 3927 disp(0x0); 3928 %} 3929 %} 3930 3931 // Indirect Memory Times Scale Plus Index Register 3932 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3933 %{ 3934 predicate(Universe::narrow_oop_shift() == 0); 3935 constraint(ALLOC_IN_RC(ptr_reg)); 3936 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3937 3938 op_cost(10); 3939 format %{"[$reg + $lreg << $scale]" %} 3940 interface(MEMORY_INTER) %{ 3941 base($reg); 3942 index($lreg); 3943 scale($scale); 3944 disp(0x0); 3945 %} 3946 %} 3947 3948 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3949 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3950 %{ 3951 predicate(Universe::narrow_oop_shift() == 0); 3952 constraint(ALLOC_IN_RC(ptr_reg)); 3953 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3954 3955 op_cost(10); 3956 format %{"[$reg + $off + $lreg << $scale]" %} 3957 interface(MEMORY_INTER) %{ 3958 base($reg); 3959 index($lreg); 3960 scale($scale); 3961 disp($off); 3962 %} 3963 %} 3964 3965 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3966 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3967 %{ 3968 constraint(ALLOC_IN_RC(ptr_reg)); 3969 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3970 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3971 3972 op_cost(10); 3973 format %{"[$reg + $off + $idx]" %} 3974 interface(MEMORY_INTER) %{ 3975 base($reg); 3976 index($idx); 3977 scale(0x0); 3978 disp($off); 3979 %} 3980 %} 3981 3982 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3983 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3984 %{ 3985 constraint(ALLOC_IN_RC(ptr_reg)); 3986 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3987 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3988 3989 op_cost(10); 3990 format %{"[$reg + $off + $idx << $scale]" %} 3991 interface(MEMORY_INTER) %{ 3992 base($reg); 3993 index($idx); 3994 scale($scale); 3995 disp($off); 3996 %} 3997 %} 3998 3999 //----------Special Memory Operands-------------------------------------------- 4000 // Stack Slot Operand - This operand is used for loading and storing temporary 4001 // values on the stack where a match requires a value to 4002 // flow through memory. 4003 operand stackSlotP(sRegP reg) 4004 %{ 4005 constraint(ALLOC_IN_RC(stack_slots)); 4006 // No match rule because this operand is only generated in matching 4007 4008 format %{ "[$reg]" %} 4009 interface(MEMORY_INTER) %{ 4010 base(0x4); // RSP 4011 index(0x4); // No Index 4012 scale(0x0); // No Scale 4013 disp($reg); // Stack Offset 4014 %} 4015 %} 4016 4017 operand stackSlotI(sRegI reg) 4018 %{ 4019 constraint(ALLOC_IN_RC(stack_slots)); 4020 // No match rule because this operand is only generated in matching 4021 4022 format %{ "[$reg]" %} 4023 interface(MEMORY_INTER) %{ 4024 base(0x4); // RSP 4025 index(0x4); // No Index 4026 scale(0x0); // No Scale 4027 disp($reg); // Stack Offset 4028 %} 4029 %} 4030 4031 operand stackSlotF(sRegF reg) 4032 %{ 4033 constraint(ALLOC_IN_RC(stack_slots)); 4034 // No match rule because this operand is only generated in matching 4035 4036 format %{ "[$reg]" %} 4037 interface(MEMORY_INTER) %{ 4038 base(0x4); // RSP 4039 index(0x4); // No Index 4040 scale(0x0); // No Scale 4041 disp($reg); // Stack Offset 4042 %} 4043 %} 4044 4045 operand stackSlotD(sRegD reg) 4046 %{ 4047 constraint(ALLOC_IN_RC(stack_slots)); 4048 // No match rule because this operand is only generated in matching 4049 4050 format %{ "[$reg]" %} 4051 interface(MEMORY_INTER) %{ 4052 base(0x4); // RSP 4053 index(0x4); // No Index 4054 scale(0x0); // No Scale 4055 disp($reg); // Stack Offset 4056 %} 4057 %} 4058 operand stackSlotL(sRegL reg) 4059 %{ 4060 constraint(ALLOC_IN_RC(stack_slots)); 4061 // No match rule because this operand is only generated in matching 4062 4063 format %{ "[$reg]" %} 4064 interface(MEMORY_INTER) %{ 4065 base(0x4); // RSP 4066 index(0x4); // No Index 4067 scale(0x0); // No Scale 4068 disp($reg); // Stack Offset 4069 %} 4070 %} 4071 4072 //----------Conditional Branch Operands---------------------------------------- 4073 // Comparison Op - This is the operation of the comparison, and is limited to 4074 // the following set of codes: 4075 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4076 // 4077 // Other attributes of the comparison, such as unsignedness, are specified 4078 // by the comparison instruction that sets a condition code flags register. 4079 // That result is represented by a flags operand whose subtype is appropriate 4080 // to the unsignedness (etc.) of the comparison. 4081 // 4082 // Later, the instruction which matches both the Comparison Op (a Bool) and 4083 // the flags (produced by the Cmp) specifies the coding of the comparison op 4084 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4085 4086 // Comparision Code 4087 operand cmpOp() 4088 %{ 4089 match(Bool); 4090 4091 format %{ "" %} 4092 interface(COND_INTER) %{ 4093 equal(0x4, "e"); 4094 not_equal(0x5, "ne"); 4095 less(0xC, "l"); 4096 greater_equal(0xD, "ge"); 4097 less_equal(0xE, "le"); 4098 greater(0xF, "g"); 4099 overflow(0x0, "o"); 4100 no_overflow(0x1, "no"); 4101 %} 4102 %} 4103 4104 // Comparison Code, unsigned compare. Used by FP also, with 4105 // C2 (unordered) turned into GT or LT already. The other bits 4106 // C0 and C3 are turned into Carry & Zero flags. 4107 operand cmpOpU() 4108 %{ 4109 match(Bool); 4110 4111 format %{ "" %} 4112 interface(COND_INTER) %{ 4113 equal(0x4, "e"); 4114 not_equal(0x5, "ne"); 4115 less(0x2, "b"); 4116 greater_equal(0x3, "nb"); 4117 less_equal(0x6, "be"); 4118 greater(0x7, "nbe"); 4119 overflow(0x0, "o"); 4120 no_overflow(0x1, "no"); 4121 %} 4122 %} 4123 4124 4125 // Floating comparisons that don't require any fixup for the unordered case 4126 operand cmpOpUCF() %{ 4127 match(Bool); 4128 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4129 n->as_Bool()->_test._test == BoolTest::ge || 4130 n->as_Bool()->_test._test == BoolTest::le || 4131 n->as_Bool()->_test._test == BoolTest::gt); 4132 format %{ "" %} 4133 interface(COND_INTER) %{ 4134 equal(0x4, "e"); 4135 not_equal(0x5, "ne"); 4136 less(0x2, "b"); 4137 greater_equal(0x3, "nb"); 4138 less_equal(0x6, "be"); 4139 greater(0x7, "nbe"); 4140 overflow(0x0, "o"); 4141 no_overflow(0x1, "no"); 4142 %} 4143 %} 4144 4145 4146 // Floating comparisons that can be fixed up with extra conditional jumps 4147 operand cmpOpUCF2() %{ 4148 match(Bool); 4149 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4150 n->as_Bool()->_test._test == BoolTest::eq); 4151 format %{ "" %} 4152 interface(COND_INTER) %{ 4153 equal(0x4, "e"); 4154 not_equal(0x5, "ne"); 4155 less(0x2, "b"); 4156 greater_equal(0x3, "nb"); 4157 less_equal(0x6, "be"); 4158 greater(0x7, "nbe"); 4159 overflow(0x0, "o"); 4160 no_overflow(0x1, "no"); 4161 %} 4162 %} 4163 4164 4165 //----------OPERAND CLASSES---------------------------------------------------- 4166 // Operand Classes are groups of operands that are used as to simplify 4167 // instruction definitions by not requiring the AD writer to specify separate 4168 // instructions for every form of operand when the instruction accepts 4169 // multiple operand types with the same basic encoding and format. The classic 4170 // case of this is memory operands. 4171 4172 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4173 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4174 indCompressedOopOffset, 4175 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4176 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4177 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4178 4179 //----------PIPELINE----------------------------------------------------------- 4180 // Rules which define the behavior of the target architectures pipeline. 4181 pipeline %{ 4182 4183 //----------ATTRIBUTES--------------------------------------------------------- 4184 attributes %{ 4185 variable_size_instructions; // Fixed size instructions 4186 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4187 instruction_unit_size = 1; // An instruction is 1 bytes long 4188 instruction_fetch_unit_size = 16; // The processor fetches one line 4189 instruction_fetch_units = 1; // of 16 bytes 4190 4191 // List of nop instructions 4192 nops( MachNop ); 4193 %} 4194 4195 //----------RESOURCES---------------------------------------------------------- 4196 // Resources are the functional units available to the machine 4197 4198 // Generic P2/P3 pipeline 4199 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4200 // 3 instructions decoded per cycle. 4201 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4202 // 3 ALU op, only ALU0 handles mul instructions. 4203 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4204 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4205 BR, FPU, 4206 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4207 4208 //----------PIPELINE DESCRIPTION----------------------------------------------- 4209 // Pipeline Description specifies the stages in the machine's pipeline 4210 4211 // Generic P2/P3 pipeline 4212 pipe_desc(S0, S1, S2, S3, S4, S5); 4213 4214 //----------PIPELINE CLASSES--------------------------------------------------- 4215 // Pipeline Classes describe the stages in which input and output are 4216 // referenced by the hardware pipeline. 4217 4218 // Naming convention: ialu or fpu 4219 // Then: _reg 4220 // Then: _reg if there is a 2nd register 4221 // Then: _long if it's a pair of instructions implementing a long 4222 // Then: _fat if it requires the big decoder 4223 // Or: _mem if it requires the big decoder and a memory unit. 4224 4225 // Integer ALU reg operation 4226 pipe_class ialu_reg(rRegI dst) 4227 %{ 4228 single_instruction; 4229 dst : S4(write); 4230 dst : S3(read); 4231 DECODE : S0; // any decoder 4232 ALU : S3; // any alu 4233 %} 4234 4235 // Long ALU reg operation 4236 pipe_class ialu_reg_long(rRegL dst) 4237 %{ 4238 instruction_count(2); 4239 dst : S4(write); 4240 dst : S3(read); 4241 DECODE : S0(2); // any 2 decoders 4242 ALU : S3(2); // both alus 4243 %} 4244 4245 // Integer ALU reg operation using big decoder 4246 pipe_class ialu_reg_fat(rRegI dst) 4247 %{ 4248 single_instruction; 4249 dst : S4(write); 4250 dst : S3(read); 4251 D0 : S0; // big decoder only 4252 ALU : S3; // any alu 4253 %} 4254 4255 // Long ALU reg operation using big decoder 4256 pipe_class ialu_reg_long_fat(rRegL dst) 4257 %{ 4258 instruction_count(2); 4259 dst : S4(write); 4260 dst : S3(read); 4261 D0 : S0(2); // big decoder only; twice 4262 ALU : S3(2); // any 2 alus 4263 %} 4264 4265 // Integer ALU reg-reg operation 4266 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4267 %{ 4268 single_instruction; 4269 dst : S4(write); 4270 src : S3(read); 4271 DECODE : S0; // any decoder 4272 ALU : S3; // any alu 4273 %} 4274 4275 // Long ALU reg-reg operation 4276 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4277 %{ 4278 instruction_count(2); 4279 dst : S4(write); 4280 src : S3(read); 4281 DECODE : S0(2); // any 2 decoders 4282 ALU : S3(2); // both alus 4283 %} 4284 4285 // Integer ALU reg-reg operation 4286 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4287 %{ 4288 single_instruction; 4289 dst : S4(write); 4290 src : S3(read); 4291 D0 : S0; // big decoder only 4292 ALU : S3; // any alu 4293 %} 4294 4295 // Long ALU reg-reg operation 4296 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4297 %{ 4298 instruction_count(2); 4299 dst : S4(write); 4300 src : S3(read); 4301 D0 : S0(2); // big decoder only; twice 4302 ALU : S3(2); // both alus 4303 %} 4304 4305 // Integer ALU reg-mem operation 4306 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4307 %{ 4308 single_instruction; 4309 dst : S5(write); 4310 mem : S3(read); 4311 D0 : S0; // big decoder only 4312 ALU : S4; // any alu 4313 MEM : S3; // any mem 4314 %} 4315 4316 // Integer mem operation (prefetch) 4317 pipe_class ialu_mem(memory mem) 4318 %{ 4319 single_instruction; 4320 mem : S3(read); 4321 D0 : S0; // big decoder only 4322 MEM : S3; // any mem 4323 %} 4324 4325 // Integer Store to Memory 4326 pipe_class ialu_mem_reg(memory mem, rRegI src) 4327 %{ 4328 single_instruction; 4329 mem : S3(read); 4330 src : S5(read); 4331 D0 : S0; // big decoder only 4332 ALU : S4; // any alu 4333 MEM : S3; 4334 %} 4335 4336 // // Long Store to Memory 4337 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4338 // %{ 4339 // instruction_count(2); 4340 // mem : S3(read); 4341 // src : S5(read); 4342 // D0 : S0(2); // big decoder only; twice 4343 // ALU : S4(2); // any 2 alus 4344 // MEM : S3(2); // Both mems 4345 // %} 4346 4347 // Integer Store to Memory 4348 pipe_class ialu_mem_imm(memory mem) 4349 %{ 4350 single_instruction; 4351 mem : S3(read); 4352 D0 : S0; // big decoder only 4353 ALU : S4; // any alu 4354 MEM : S3; 4355 %} 4356 4357 // Integer ALU0 reg-reg operation 4358 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4359 %{ 4360 single_instruction; 4361 dst : S4(write); 4362 src : S3(read); 4363 D0 : S0; // Big decoder only 4364 ALU0 : S3; // only alu0 4365 %} 4366 4367 // Integer ALU0 reg-mem operation 4368 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4369 %{ 4370 single_instruction; 4371 dst : S5(write); 4372 mem : S3(read); 4373 D0 : S0; // big decoder only 4374 ALU0 : S4; // ALU0 only 4375 MEM : S3; // any mem 4376 %} 4377 4378 // Integer ALU reg-reg operation 4379 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4380 %{ 4381 single_instruction; 4382 cr : S4(write); 4383 src1 : S3(read); 4384 src2 : S3(read); 4385 DECODE : S0; // any decoder 4386 ALU : S3; // any alu 4387 %} 4388 4389 // Integer ALU reg-imm operation 4390 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4391 %{ 4392 single_instruction; 4393 cr : S4(write); 4394 src1 : S3(read); 4395 DECODE : S0; // any decoder 4396 ALU : S3; // any alu 4397 %} 4398 4399 // Integer ALU reg-mem operation 4400 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4401 %{ 4402 single_instruction; 4403 cr : S4(write); 4404 src1 : S3(read); 4405 src2 : S3(read); 4406 D0 : S0; // big decoder only 4407 ALU : S4; // any alu 4408 MEM : S3; 4409 %} 4410 4411 // Conditional move reg-reg 4412 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4413 %{ 4414 instruction_count(4); 4415 y : S4(read); 4416 q : S3(read); 4417 p : S3(read); 4418 DECODE : S0(4); // any decoder 4419 %} 4420 4421 // Conditional move reg-reg 4422 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4423 %{ 4424 single_instruction; 4425 dst : S4(write); 4426 src : S3(read); 4427 cr : S3(read); 4428 DECODE : S0; // any decoder 4429 %} 4430 4431 // Conditional move reg-mem 4432 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4433 %{ 4434 single_instruction; 4435 dst : S4(write); 4436 src : S3(read); 4437 cr : S3(read); 4438 DECODE : S0; // any decoder 4439 MEM : S3; 4440 %} 4441 4442 // Conditional move reg-reg long 4443 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4444 %{ 4445 single_instruction; 4446 dst : S4(write); 4447 src : S3(read); 4448 cr : S3(read); 4449 DECODE : S0(2); // any 2 decoders 4450 %} 4451 4452 // XXX 4453 // // Conditional move double reg-reg 4454 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4455 // %{ 4456 // single_instruction; 4457 // dst : S4(write); 4458 // src : S3(read); 4459 // cr : S3(read); 4460 // DECODE : S0; // any decoder 4461 // %} 4462 4463 // Float reg-reg operation 4464 pipe_class fpu_reg(regD dst) 4465 %{ 4466 instruction_count(2); 4467 dst : S3(read); 4468 DECODE : S0(2); // any 2 decoders 4469 FPU : S3; 4470 %} 4471 4472 // Float reg-reg operation 4473 pipe_class fpu_reg_reg(regD dst, regD src) 4474 %{ 4475 instruction_count(2); 4476 dst : S4(write); 4477 src : S3(read); 4478 DECODE : S0(2); // any 2 decoders 4479 FPU : S3; 4480 %} 4481 4482 // Float reg-reg operation 4483 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4484 %{ 4485 instruction_count(3); 4486 dst : S4(write); 4487 src1 : S3(read); 4488 src2 : S3(read); 4489 DECODE : S0(3); // any 3 decoders 4490 FPU : S3(2); 4491 %} 4492 4493 // Float reg-reg operation 4494 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4495 %{ 4496 instruction_count(4); 4497 dst : S4(write); 4498 src1 : S3(read); 4499 src2 : S3(read); 4500 src3 : S3(read); 4501 DECODE : S0(4); // any 3 decoders 4502 FPU : S3(2); 4503 %} 4504 4505 // Float reg-reg operation 4506 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4507 %{ 4508 instruction_count(4); 4509 dst : S4(write); 4510 src1 : S3(read); 4511 src2 : S3(read); 4512 src3 : S3(read); 4513 DECODE : S1(3); // any 3 decoders 4514 D0 : S0; // Big decoder only 4515 FPU : S3(2); 4516 MEM : S3; 4517 %} 4518 4519 // Float reg-mem operation 4520 pipe_class fpu_reg_mem(regD dst, memory mem) 4521 %{ 4522 instruction_count(2); 4523 dst : S5(write); 4524 mem : S3(read); 4525 D0 : S0; // big decoder only 4526 DECODE : S1; // any decoder for FPU POP 4527 FPU : S4; 4528 MEM : S3; // any mem 4529 %} 4530 4531 // Float reg-mem operation 4532 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4533 %{ 4534 instruction_count(3); 4535 dst : S5(write); 4536 src1 : S3(read); 4537 mem : S3(read); 4538 D0 : S0; // big decoder only 4539 DECODE : S1(2); // any decoder for FPU POP 4540 FPU : S4; 4541 MEM : S3; // any mem 4542 %} 4543 4544 // Float mem-reg operation 4545 pipe_class fpu_mem_reg(memory mem, regD src) 4546 %{ 4547 instruction_count(2); 4548 src : S5(read); 4549 mem : S3(read); 4550 DECODE : S0; // any decoder for FPU PUSH 4551 D0 : S1; // big decoder only 4552 FPU : S4; 4553 MEM : S3; // any mem 4554 %} 4555 4556 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4557 %{ 4558 instruction_count(3); 4559 src1 : S3(read); 4560 src2 : S3(read); 4561 mem : S3(read); 4562 DECODE : S0(2); // any decoder for FPU PUSH 4563 D0 : S1; // big decoder only 4564 FPU : S4; 4565 MEM : S3; // any mem 4566 %} 4567 4568 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4569 %{ 4570 instruction_count(3); 4571 src1 : S3(read); 4572 src2 : S3(read); 4573 mem : S4(read); 4574 DECODE : S0; // any decoder for FPU PUSH 4575 D0 : S0(2); // big decoder only 4576 FPU : S4; 4577 MEM : S3(2); // any mem 4578 %} 4579 4580 pipe_class fpu_mem_mem(memory dst, memory src1) 4581 %{ 4582 instruction_count(2); 4583 src1 : S3(read); 4584 dst : S4(read); 4585 D0 : S0(2); // big decoder only 4586 MEM : S3(2); // any mem 4587 %} 4588 4589 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4590 %{ 4591 instruction_count(3); 4592 src1 : S3(read); 4593 src2 : S3(read); 4594 dst : S4(read); 4595 D0 : S0(3); // big decoder only 4596 FPU : S4; 4597 MEM : S3(3); // any mem 4598 %} 4599 4600 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4601 %{ 4602 instruction_count(3); 4603 src1 : S4(read); 4604 mem : S4(read); 4605 DECODE : S0; // any decoder for FPU PUSH 4606 D0 : S0(2); // big decoder only 4607 FPU : S4; 4608 MEM : S3(2); // any mem 4609 %} 4610 4611 // Float load constant 4612 pipe_class fpu_reg_con(regD dst) 4613 %{ 4614 instruction_count(2); 4615 dst : S5(write); 4616 D0 : S0; // big decoder only for the load 4617 DECODE : S1; // any decoder for FPU POP 4618 FPU : S4; 4619 MEM : S3; // any mem 4620 %} 4621 4622 // Float load constant 4623 pipe_class fpu_reg_reg_con(regD dst, regD src) 4624 %{ 4625 instruction_count(3); 4626 dst : S5(write); 4627 src : S3(read); 4628 D0 : S0; // big decoder only for the load 4629 DECODE : S1(2); // any decoder for FPU POP 4630 FPU : S4; 4631 MEM : S3; // any mem 4632 %} 4633 4634 // UnConditional branch 4635 pipe_class pipe_jmp(label labl) 4636 %{ 4637 single_instruction; 4638 BR : S3; 4639 %} 4640 4641 // Conditional branch 4642 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4643 %{ 4644 single_instruction; 4645 cr : S1(read); 4646 BR : S3; 4647 %} 4648 4649 // Allocation idiom 4650 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4651 %{ 4652 instruction_count(1); force_serialization; 4653 fixed_latency(6); 4654 heap_ptr : S3(read); 4655 DECODE : S0(3); 4656 D0 : S2; 4657 MEM : S3; 4658 ALU : S3(2); 4659 dst : S5(write); 4660 BR : S5; 4661 %} 4662 4663 // Generic big/slow expanded idiom 4664 pipe_class pipe_slow() 4665 %{ 4666 instruction_count(10); multiple_bundles; force_serialization; 4667 fixed_latency(100); 4668 D0 : S0(2); 4669 MEM : S3(2); 4670 %} 4671 4672 // The real do-nothing guy 4673 pipe_class empty() 4674 %{ 4675 instruction_count(0); 4676 %} 4677 4678 // Define the class for the Nop node 4679 define 4680 %{ 4681 MachNop = empty; 4682 %} 4683 4684 %} 4685 4686 //----------INSTRUCTIONS------------------------------------------------------- 4687 // 4688 // match -- States which machine-independent subtree may be replaced 4689 // by this instruction. 4690 // ins_cost -- The estimated cost of this instruction is used by instruction 4691 // selection to identify a minimum cost tree of machine 4692 // instructions that matches a tree of machine-independent 4693 // instructions. 4694 // format -- A string providing the disassembly for this instruction. 4695 // The value of an instruction's operand may be inserted 4696 // by referring to it with a '$' prefix. 4697 // opcode -- Three instruction opcodes may be provided. These are referred 4698 // to within an encode class as $primary, $secondary, and $tertiary 4699 // rrspectively. The primary opcode is commonly used to 4700 // indicate the type of machine instruction, while secondary 4701 // and tertiary are often used for prefix options or addressing 4702 // modes. 4703 // ins_encode -- A list of encode classes with parameters. The encode class 4704 // name must have been defined in an 'enc_class' specification 4705 // in the encode section of the architecture description. 4706 4707 4708 //----------Load/Store/Move Instructions--------------------------------------- 4709 //----------Load Instructions-------------------------------------------------- 4710 4711 // Load Byte (8 bit signed) 4712 instruct loadB(rRegI dst, memory mem) 4713 %{ 4714 match(Set dst (LoadB mem)); 4715 4716 ins_cost(125); 4717 format %{ "movsbl $dst, $mem\t# byte" %} 4718 4719 ins_encode %{ 4720 __ movsbl($dst$$Register, $mem$$Address); 4721 %} 4722 4723 ins_pipe(ialu_reg_mem); 4724 %} 4725 4726 // Load Byte (8 bit signed) into Long Register 4727 instruct loadB2L(rRegL dst, memory mem) 4728 %{ 4729 match(Set dst (ConvI2L (LoadB mem))); 4730 4731 ins_cost(125); 4732 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4733 4734 ins_encode %{ 4735 __ movsbq($dst$$Register, $mem$$Address); 4736 %} 4737 4738 ins_pipe(ialu_reg_mem); 4739 %} 4740 4741 // Load Unsigned Byte (8 bit UNsigned) 4742 instruct loadUB(rRegI dst, memory mem) 4743 %{ 4744 match(Set dst (LoadUB mem)); 4745 4746 ins_cost(125); 4747 format %{ "movzbl $dst, $mem\t# ubyte" %} 4748 4749 ins_encode %{ 4750 __ movzbl($dst$$Register, $mem$$Address); 4751 %} 4752 4753 ins_pipe(ialu_reg_mem); 4754 %} 4755 4756 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4757 instruct loadUB2L(rRegL dst, memory mem) 4758 %{ 4759 match(Set dst (ConvI2L (LoadUB mem))); 4760 4761 ins_cost(125); 4762 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4763 4764 ins_encode %{ 4765 __ movzbq($dst$$Register, $mem$$Address); 4766 %} 4767 4768 ins_pipe(ialu_reg_mem); 4769 %} 4770 4771 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4772 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4773 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4774 effect(KILL cr); 4775 4776 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4777 "andl $dst, right_n_bits($mask, 8)" %} 4778 ins_encode %{ 4779 Register Rdst = $dst$$Register; 4780 __ movzbq(Rdst, $mem$$Address); 4781 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4782 %} 4783 ins_pipe(ialu_reg_mem); 4784 %} 4785 4786 // Load Short (16 bit signed) 4787 instruct loadS(rRegI dst, memory mem) 4788 %{ 4789 match(Set dst (LoadS mem)); 4790 4791 ins_cost(125); 4792 format %{ "movswl $dst, $mem\t# short" %} 4793 4794 ins_encode %{ 4795 __ movswl($dst$$Register, $mem$$Address); 4796 %} 4797 4798 ins_pipe(ialu_reg_mem); 4799 %} 4800 4801 // Load Short (16 bit signed) to Byte (8 bit signed) 4802 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4803 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4804 4805 ins_cost(125); 4806 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4807 ins_encode %{ 4808 __ movsbl($dst$$Register, $mem$$Address); 4809 %} 4810 ins_pipe(ialu_reg_mem); 4811 %} 4812 4813 // Load Short (16 bit signed) into Long Register 4814 instruct loadS2L(rRegL dst, memory mem) 4815 %{ 4816 match(Set dst (ConvI2L (LoadS mem))); 4817 4818 ins_cost(125); 4819 format %{ "movswq $dst, $mem\t# short -> long" %} 4820 4821 ins_encode %{ 4822 __ movswq($dst$$Register, $mem$$Address); 4823 %} 4824 4825 ins_pipe(ialu_reg_mem); 4826 %} 4827 4828 // Load Unsigned Short/Char (16 bit UNsigned) 4829 instruct loadUS(rRegI dst, memory mem) 4830 %{ 4831 match(Set dst (LoadUS mem)); 4832 4833 ins_cost(125); 4834 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4835 4836 ins_encode %{ 4837 __ movzwl($dst$$Register, $mem$$Address); 4838 %} 4839 4840 ins_pipe(ialu_reg_mem); 4841 %} 4842 4843 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4844 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4845 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4846 4847 ins_cost(125); 4848 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4849 ins_encode %{ 4850 __ movsbl($dst$$Register, $mem$$Address); 4851 %} 4852 ins_pipe(ialu_reg_mem); 4853 %} 4854 4855 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4856 instruct loadUS2L(rRegL dst, memory mem) 4857 %{ 4858 match(Set dst (ConvI2L (LoadUS mem))); 4859 4860 ins_cost(125); 4861 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4862 4863 ins_encode %{ 4864 __ movzwq($dst$$Register, $mem$$Address); 4865 %} 4866 4867 ins_pipe(ialu_reg_mem); 4868 %} 4869 4870 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4871 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4872 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4873 4874 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4875 ins_encode %{ 4876 __ movzbq($dst$$Register, $mem$$Address); 4877 %} 4878 ins_pipe(ialu_reg_mem); 4879 %} 4880 4881 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4882 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4883 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4884 effect(KILL cr); 4885 4886 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4887 "andl $dst, right_n_bits($mask, 16)" %} 4888 ins_encode %{ 4889 Register Rdst = $dst$$Register; 4890 __ movzwq(Rdst, $mem$$Address); 4891 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4892 %} 4893 ins_pipe(ialu_reg_mem); 4894 %} 4895 4896 // Load Integer 4897 instruct loadI(rRegI dst, memory mem) 4898 %{ 4899 match(Set dst (LoadI mem)); 4900 4901 ins_cost(125); 4902 format %{ "movl $dst, $mem\t# int" %} 4903 4904 ins_encode %{ 4905 __ movl($dst$$Register, $mem$$Address); 4906 %} 4907 4908 ins_pipe(ialu_reg_mem); 4909 %} 4910 4911 // Load Integer (32 bit signed) to Byte (8 bit signed) 4912 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4913 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4914 4915 ins_cost(125); 4916 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4917 ins_encode %{ 4918 __ movsbl($dst$$Register, $mem$$Address); 4919 %} 4920 ins_pipe(ialu_reg_mem); 4921 %} 4922 4923 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4924 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4925 match(Set dst (AndI (LoadI mem) mask)); 4926 4927 ins_cost(125); 4928 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4929 ins_encode %{ 4930 __ movzbl($dst$$Register, $mem$$Address); 4931 %} 4932 ins_pipe(ialu_reg_mem); 4933 %} 4934 4935 // Load Integer (32 bit signed) to Short (16 bit signed) 4936 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4937 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4938 4939 ins_cost(125); 4940 format %{ "movswl $dst, $mem\t# int -> short" %} 4941 ins_encode %{ 4942 __ movswl($dst$$Register, $mem$$Address); 4943 %} 4944 ins_pipe(ialu_reg_mem); 4945 %} 4946 4947 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4948 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4949 match(Set dst (AndI (LoadI mem) mask)); 4950 4951 ins_cost(125); 4952 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4953 ins_encode %{ 4954 __ movzwl($dst$$Register, $mem$$Address); 4955 %} 4956 ins_pipe(ialu_reg_mem); 4957 %} 4958 4959 // Load Integer into Long Register 4960 instruct loadI2L(rRegL dst, memory mem) 4961 %{ 4962 match(Set dst (ConvI2L (LoadI mem))); 4963 4964 ins_cost(125); 4965 format %{ "movslq $dst, $mem\t# int -> long" %} 4966 4967 ins_encode %{ 4968 __ movslq($dst$$Register, $mem$$Address); 4969 %} 4970 4971 ins_pipe(ialu_reg_mem); 4972 %} 4973 4974 // Load Integer with mask 0xFF into Long Register 4975 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4976 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4977 4978 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4979 ins_encode %{ 4980 __ movzbq($dst$$Register, $mem$$Address); 4981 %} 4982 ins_pipe(ialu_reg_mem); 4983 %} 4984 4985 // Load Integer with mask 0xFFFF into Long Register 4986 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4987 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4988 4989 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4990 ins_encode %{ 4991 __ movzwq($dst$$Register, $mem$$Address); 4992 %} 4993 ins_pipe(ialu_reg_mem); 4994 %} 4995 4996 // Load Integer with a 31-bit mask into Long Register 4997 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4998 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4999 effect(KILL cr); 5000 5001 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5002 "andl $dst, $mask" %} 5003 ins_encode %{ 5004 Register Rdst = $dst$$Register; 5005 __ movl(Rdst, $mem$$Address); 5006 __ andl(Rdst, $mask$$constant); 5007 %} 5008 ins_pipe(ialu_reg_mem); 5009 %} 5010 5011 // Load Unsigned Integer into Long Register 5012 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5013 %{ 5014 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5015 5016 ins_cost(125); 5017 format %{ "movl $dst, $mem\t# uint -> long" %} 5018 5019 ins_encode %{ 5020 __ movl($dst$$Register, $mem$$Address); 5021 %} 5022 5023 ins_pipe(ialu_reg_mem); 5024 %} 5025 5026 // Load Long 5027 instruct loadL(rRegL dst, memory mem) 5028 %{ 5029 match(Set dst (LoadL mem)); 5030 5031 ins_cost(125); 5032 format %{ "movq $dst, $mem\t# long" %} 5033 5034 ins_encode %{ 5035 __ movq($dst$$Register, $mem$$Address); 5036 %} 5037 5038 ins_pipe(ialu_reg_mem); // XXX 5039 %} 5040 5041 // Load Range 5042 instruct loadRange(rRegI dst, memory mem) 5043 %{ 5044 match(Set dst (LoadRange mem)); 5045 5046 ins_cost(125); // XXX 5047 format %{ "movl $dst, $mem\t# range" %} 5048 opcode(0x8B); 5049 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5050 ins_pipe(ialu_reg_mem); 5051 %} 5052 5053 // Load Pointer 5054 instruct loadP(rRegP dst, memory mem) 5055 %{ 5056 match(Set dst (LoadP mem)); 5057 5058 ins_cost(125); // XXX 5059 format %{ "movq $dst, $mem\t# ptr" %} 5060 opcode(0x8B); 5061 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5062 ins_pipe(ialu_reg_mem); // XXX 5063 %} 5064 5065 // Load Compressed Pointer 5066 instruct loadN(rRegN dst, memory mem) 5067 %{ 5068 match(Set dst (LoadN mem)); 5069 5070 ins_cost(125); // XXX 5071 format %{ "movl $dst, $mem\t# compressed ptr" %} 5072 ins_encode %{ 5073 __ movl($dst$$Register, $mem$$Address); 5074 %} 5075 ins_pipe(ialu_reg_mem); // XXX 5076 %} 5077 5078 5079 // Load Klass Pointer 5080 instruct loadKlass(rRegP dst, memory mem) 5081 %{ 5082 match(Set dst (LoadKlass mem)); 5083 5084 ins_cost(125); // XXX 5085 format %{ "movq $dst, $mem\t# class" %} 5086 opcode(0x8B); 5087 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5088 ins_pipe(ialu_reg_mem); // XXX 5089 %} 5090 5091 // Load narrow Klass Pointer 5092 instruct loadNKlass(rRegN dst, memory mem) 5093 %{ 5094 match(Set dst (LoadNKlass mem)); 5095 5096 ins_cost(125); // XXX 5097 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5098 ins_encode %{ 5099 __ movl($dst$$Register, $mem$$Address); 5100 %} 5101 ins_pipe(ialu_reg_mem); // XXX 5102 %} 5103 5104 // Load Float 5105 instruct loadF(regF dst, memory mem) 5106 %{ 5107 match(Set dst (LoadF mem)); 5108 5109 ins_cost(145); // XXX 5110 format %{ "movss $dst, $mem\t# float" %} 5111 ins_encode %{ 5112 __ movflt($dst$$XMMRegister, $mem$$Address); 5113 %} 5114 ins_pipe(pipe_slow); // XXX 5115 %} 5116 5117 // Load Double 5118 instruct loadD_partial(regD dst, memory mem) 5119 %{ 5120 predicate(!UseXmmLoadAndClearUpper); 5121 match(Set dst (LoadD mem)); 5122 5123 ins_cost(145); // XXX 5124 format %{ "movlpd $dst, $mem\t# double" %} 5125 ins_encode %{ 5126 __ movdbl($dst$$XMMRegister, $mem$$Address); 5127 %} 5128 ins_pipe(pipe_slow); // XXX 5129 %} 5130 5131 instruct loadD(regD dst, memory mem) 5132 %{ 5133 predicate(UseXmmLoadAndClearUpper); 5134 match(Set dst (LoadD mem)); 5135 5136 ins_cost(145); // XXX 5137 format %{ "movsd $dst, $mem\t# double" %} 5138 ins_encode %{ 5139 __ movdbl($dst$$XMMRegister, $mem$$Address); 5140 %} 5141 ins_pipe(pipe_slow); // XXX 5142 %} 5143 5144 // Load Effective Address 5145 instruct leaP8(rRegP dst, indOffset8 mem) 5146 %{ 5147 match(Set dst mem); 5148 5149 ins_cost(110); // XXX 5150 format %{ "leaq $dst, $mem\t# ptr 8" %} 5151 opcode(0x8D); 5152 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5153 ins_pipe(ialu_reg_reg_fat); 5154 %} 5155 5156 instruct leaP32(rRegP dst, indOffset32 mem) 5157 %{ 5158 match(Set dst mem); 5159 5160 ins_cost(110); 5161 format %{ "leaq $dst, $mem\t# ptr 32" %} 5162 opcode(0x8D); 5163 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5164 ins_pipe(ialu_reg_reg_fat); 5165 %} 5166 5167 // instruct leaPIdx(rRegP dst, indIndex mem) 5168 // %{ 5169 // match(Set dst mem); 5170 5171 // ins_cost(110); 5172 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5173 // opcode(0x8D); 5174 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5175 // ins_pipe(ialu_reg_reg_fat); 5176 // %} 5177 5178 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5179 %{ 5180 match(Set dst mem); 5181 5182 ins_cost(110); 5183 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5184 opcode(0x8D); 5185 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5186 ins_pipe(ialu_reg_reg_fat); 5187 %} 5188 5189 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5190 %{ 5191 match(Set dst mem); 5192 5193 ins_cost(110); 5194 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5195 opcode(0x8D); 5196 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5197 ins_pipe(ialu_reg_reg_fat); 5198 %} 5199 5200 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5201 %{ 5202 match(Set dst mem); 5203 5204 ins_cost(110); 5205 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5206 opcode(0x8D); 5207 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5208 ins_pipe(ialu_reg_reg_fat); 5209 %} 5210 5211 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5212 %{ 5213 match(Set dst mem); 5214 5215 ins_cost(110); 5216 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5217 opcode(0x8D); 5218 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5219 ins_pipe(ialu_reg_reg_fat); 5220 %} 5221 5222 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5223 %{ 5224 match(Set dst mem); 5225 5226 ins_cost(110); 5227 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5228 opcode(0x8D); 5229 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5230 ins_pipe(ialu_reg_reg_fat); 5231 %} 5232 5233 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5234 %{ 5235 match(Set dst mem); 5236 5237 ins_cost(110); 5238 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5239 opcode(0x8D); 5240 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5241 ins_pipe(ialu_reg_reg_fat); 5242 %} 5243 5244 // Load Effective Address which uses Narrow (32-bits) oop 5245 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5246 %{ 5247 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5248 match(Set dst mem); 5249 5250 ins_cost(110); 5251 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5252 opcode(0x8D); 5253 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5254 ins_pipe(ialu_reg_reg_fat); 5255 %} 5256 5257 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5258 %{ 5259 predicate(Universe::narrow_oop_shift() == 0); 5260 match(Set dst mem); 5261 5262 ins_cost(110); // XXX 5263 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5264 opcode(0x8D); 5265 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5266 ins_pipe(ialu_reg_reg_fat); 5267 %} 5268 5269 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5270 %{ 5271 predicate(Universe::narrow_oop_shift() == 0); 5272 match(Set dst mem); 5273 5274 ins_cost(110); 5275 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5276 opcode(0x8D); 5277 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5278 ins_pipe(ialu_reg_reg_fat); 5279 %} 5280 5281 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5282 %{ 5283 predicate(Universe::narrow_oop_shift() == 0); 5284 match(Set dst mem); 5285 5286 ins_cost(110); 5287 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5288 opcode(0x8D); 5289 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5290 ins_pipe(ialu_reg_reg_fat); 5291 %} 5292 5293 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5294 %{ 5295 predicate(Universe::narrow_oop_shift() == 0); 5296 match(Set dst mem); 5297 5298 ins_cost(110); 5299 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5300 opcode(0x8D); 5301 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5302 ins_pipe(ialu_reg_reg_fat); 5303 %} 5304 5305 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5306 %{ 5307 predicate(Universe::narrow_oop_shift() == 0); 5308 match(Set dst mem); 5309 5310 ins_cost(110); 5311 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5312 opcode(0x8D); 5313 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5314 ins_pipe(ialu_reg_reg_fat); 5315 %} 5316 5317 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5318 %{ 5319 predicate(Universe::narrow_oop_shift() == 0); 5320 match(Set dst mem); 5321 5322 ins_cost(110); 5323 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5324 opcode(0x8D); 5325 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5326 ins_pipe(ialu_reg_reg_fat); 5327 %} 5328 5329 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5330 %{ 5331 predicate(Universe::narrow_oop_shift() == 0); 5332 match(Set dst mem); 5333 5334 ins_cost(110); 5335 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5336 opcode(0x8D); 5337 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5338 ins_pipe(ialu_reg_reg_fat); 5339 %} 5340 5341 instruct loadConI(rRegI dst, immI src) 5342 %{ 5343 match(Set dst src); 5344 5345 format %{ "movl $dst, $src\t# int" %} 5346 ins_encode(load_immI(dst, src)); 5347 ins_pipe(ialu_reg_fat); // XXX 5348 %} 5349 5350 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5351 %{ 5352 match(Set dst src); 5353 effect(KILL cr); 5354 5355 ins_cost(50); 5356 format %{ "xorl $dst, $dst\t# int" %} 5357 opcode(0x33); /* + rd */ 5358 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5359 ins_pipe(ialu_reg); 5360 %} 5361 5362 instruct loadConL(rRegL dst, immL src) 5363 %{ 5364 match(Set dst src); 5365 5366 ins_cost(150); 5367 format %{ "movq $dst, $src\t# long" %} 5368 ins_encode(load_immL(dst, src)); 5369 ins_pipe(ialu_reg); 5370 %} 5371 5372 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5373 %{ 5374 match(Set dst src); 5375 effect(KILL cr); 5376 5377 ins_cost(50); 5378 format %{ "xorl $dst, $dst\t# long" %} 5379 opcode(0x33); /* + rd */ 5380 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5381 ins_pipe(ialu_reg); // XXX 5382 %} 5383 5384 instruct loadConUL32(rRegL dst, immUL32 src) 5385 %{ 5386 match(Set dst src); 5387 5388 ins_cost(60); 5389 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5390 ins_encode(load_immUL32(dst, src)); 5391 ins_pipe(ialu_reg); 5392 %} 5393 5394 instruct loadConL32(rRegL dst, immL32 src) 5395 %{ 5396 match(Set dst src); 5397 5398 ins_cost(70); 5399 format %{ "movq $dst, $src\t# long (32-bit)" %} 5400 ins_encode(load_immL32(dst, src)); 5401 ins_pipe(ialu_reg); 5402 %} 5403 5404 instruct loadConP(rRegP dst, immP con) %{ 5405 match(Set dst con); 5406 5407 format %{ "movq $dst, $con\t# ptr" %} 5408 ins_encode(load_immP(dst, con)); 5409 ins_pipe(ialu_reg_fat); // XXX 5410 %} 5411 5412 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5413 %{ 5414 match(Set dst src); 5415 effect(KILL cr); 5416 5417 ins_cost(50); 5418 format %{ "xorl $dst, $dst\t# ptr" %} 5419 opcode(0x33); /* + rd */ 5420 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5421 ins_pipe(ialu_reg); 5422 %} 5423 5424 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5425 %{ 5426 match(Set dst src); 5427 effect(KILL cr); 5428 5429 ins_cost(60); 5430 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5431 ins_encode(load_immP31(dst, src)); 5432 ins_pipe(ialu_reg); 5433 %} 5434 5435 instruct loadConF(regF dst, immF con) %{ 5436 match(Set dst con); 5437 ins_cost(125); 5438 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5439 ins_encode %{ 5440 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5441 %} 5442 ins_pipe(pipe_slow); 5443 %} 5444 5445 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5446 match(Set dst src); 5447 effect(KILL cr); 5448 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5449 ins_encode %{ 5450 __ xorq($dst$$Register, $dst$$Register); 5451 %} 5452 ins_pipe(ialu_reg); 5453 %} 5454 5455 instruct loadConN(rRegN dst, immN src) %{ 5456 match(Set dst src); 5457 5458 ins_cost(125); 5459 format %{ "movl $dst, $src\t# compressed ptr" %} 5460 ins_encode %{ 5461 address con = (address)$src$$constant; 5462 if (con == NULL) { 5463 ShouldNotReachHere(); 5464 } else { 5465 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5466 } 5467 %} 5468 ins_pipe(ialu_reg_fat); // XXX 5469 %} 5470 5471 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5472 match(Set dst src); 5473 5474 ins_cost(125); 5475 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5476 ins_encode %{ 5477 address con = (address)$src$$constant; 5478 if (con == NULL) { 5479 ShouldNotReachHere(); 5480 } else { 5481 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5482 } 5483 %} 5484 ins_pipe(ialu_reg_fat); // XXX 5485 %} 5486 5487 instruct loadConF0(regF dst, immF0 src) 5488 %{ 5489 match(Set dst src); 5490 ins_cost(100); 5491 5492 format %{ "xorps $dst, $dst\t# float 0.0" %} 5493 ins_encode %{ 5494 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5495 %} 5496 ins_pipe(pipe_slow); 5497 %} 5498 5499 // Use the same format since predicate() can not be used here. 5500 instruct loadConD(regD dst, immD con) %{ 5501 match(Set dst con); 5502 ins_cost(125); 5503 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5504 ins_encode %{ 5505 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5506 %} 5507 ins_pipe(pipe_slow); 5508 %} 5509 5510 instruct loadConD0(regD dst, immD0 src) 5511 %{ 5512 match(Set dst src); 5513 ins_cost(100); 5514 5515 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5516 ins_encode %{ 5517 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5518 %} 5519 ins_pipe(pipe_slow); 5520 %} 5521 5522 instruct loadSSI(rRegI dst, stackSlotI src) 5523 %{ 5524 match(Set dst src); 5525 5526 ins_cost(125); 5527 format %{ "movl $dst, $src\t# int stk" %} 5528 opcode(0x8B); 5529 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5530 ins_pipe(ialu_reg_mem); 5531 %} 5532 5533 instruct loadSSL(rRegL dst, stackSlotL src) 5534 %{ 5535 match(Set dst src); 5536 5537 ins_cost(125); 5538 format %{ "movq $dst, $src\t# long stk" %} 5539 opcode(0x8B); 5540 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5541 ins_pipe(ialu_reg_mem); 5542 %} 5543 5544 instruct loadSSP(rRegP dst, stackSlotP src) 5545 %{ 5546 match(Set dst src); 5547 5548 ins_cost(125); 5549 format %{ "movq $dst, $src\t# ptr stk" %} 5550 opcode(0x8B); 5551 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5552 ins_pipe(ialu_reg_mem); 5553 %} 5554 5555 instruct loadSSF(regF dst, stackSlotF src) 5556 %{ 5557 match(Set dst src); 5558 5559 ins_cost(125); 5560 format %{ "movss $dst, $src\t# float stk" %} 5561 ins_encode %{ 5562 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5563 %} 5564 ins_pipe(pipe_slow); // XXX 5565 %} 5566 5567 // Use the same format since predicate() can not be used here. 5568 instruct loadSSD(regD dst, stackSlotD src) 5569 %{ 5570 match(Set dst src); 5571 5572 ins_cost(125); 5573 format %{ "movsd $dst, $src\t# double stk" %} 5574 ins_encode %{ 5575 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5576 %} 5577 ins_pipe(pipe_slow); // XXX 5578 %} 5579 5580 // Prefetch instructions for allocation. 5581 // Must be safe to execute with invalid address (cannot fault). 5582 5583 instruct prefetchAlloc( memory mem ) %{ 5584 predicate(AllocatePrefetchInstr==3); 5585 match(PrefetchAllocation mem); 5586 ins_cost(125); 5587 5588 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5589 ins_encode %{ 5590 __ prefetchw($mem$$Address); 5591 %} 5592 ins_pipe(ialu_mem); 5593 %} 5594 5595 instruct prefetchAllocNTA( memory mem ) %{ 5596 predicate(AllocatePrefetchInstr==0); 5597 match(PrefetchAllocation mem); 5598 ins_cost(125); 5599 5600 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5601 ins_encode %{ 5602 __ prefetchnta($mem$$Address); 5603 %} 5604 ins_pipe(ialu_mem); 5605 %} 5606 5607 instruct prefetchAllocT0( memory mem ) %{ 5608 predicate(AllocatePrefetchInstr==1); 5609 match(PrefetchAllocation mem); 5610 ins_cost(125); 5611 5612 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5613 ins_encode %{ 5614 __ prefetcht0($mem$$Address); 5615 %} 5616 ins_pipe(ialu_mem); 5617 %} 5618 5619 instruct prefetchAllocT2( memory mem ) %{ 5620 predicate(AllocatePrefetchInstr==2); 5621 match(PrefetchAllocation mem); 5622 ins_cost(125); 5623 5624 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5625 ins_encode %{ 5626 __ prefetcht2($mem$$Address); 5627 %} 5628 ins_pipe(ialu_mem); 5629 %} 5630 5631 //----------Store Instructions------------------------------------------------- 5632 5633 // Store Byte 5634 instruct storeB(memory mem, rRegI src) 5635 %{ 5636 match(Set mem (StoreB mem src)); 5637 5638 ins_cost(125); // XXX 5639 format %{ "movb $mem, $src\t# byte" %} 5640 opcode(0x88); 5641 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5642 ins_pipe(ialu_mem_reg); 5643 %} 5644 5645 // Store Char/Short 5646 instruct storeC(memory mem, rRegI src) 5647 %{ 5648 match(Set mem (StoreC mem src)); 5649 5650 ins_cost(125); // XXX 5651 format %{ "movw $mem, $src\t# char/short" %} 5652 opcode(0x89); 5653 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5654 ins_pipe(ialu_mem_reg); 5655 %} 5656 5657 // Store Integer 5658 instruct storeI(memory mem, rRegI src) 5659 %{ 5660 match(Set mem (StoreI mem src)); 5661 5662 ins_cost(125); // XXX 5663 format %{ "movl $mem, $src\t# int" %} 5664 opcode(0x89); 5665 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5666 ins_pipe(ialu_mem_reg); 5667 %} 5668 5669 // Store Long 5670 instruct storeL(memory mem, rRegL src) 5671 %{ 5672 match(Set mem (StoreL mem src)); 5673 5674 ins_cost(125); // XXX 5675 format %{ "movq $mem, $src\t# long" %} 5676 opcode(0x89); 5677 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5678 ins_pipe(ialu_mem_reg); // XXX 5679 %} 5680 5681 // Store Pointer 5682 instruct storeP(memory mem, any_RegP src) 5683 %{ 5684 match(Set mem (StoreP mem src)); 5685 5686 ins_cost(125); // XXX 5687 format %{ "movq $mem, $src\t# ptr" %} 5688 opcode(0x89); 5689 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5690 ins_pipe(ialu_mem_reg); 5691 %} 5692 5693 instruct storeImmP0(memory mem, immP0 zero) 5694 %{ 5695 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5696 match(Set mem (StoreP mem zero)); 5697 5698 ins_cost(125); // XXX 5699 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5700 ins_encode %{ 5701 __ movq($mem$$Address, r12); 5702 %} 5703 ins_pipe(ialu_mem_reg); 5704 %} 5705 5706 // Store NULL Pointer, mark word, or other simple pointer constant. 5707 instruct storeImmP(memory mem, immP31 src) 5708 %{ 5709 match(Set mem (StoreP mem src)); 5710 5711 ins_cost(150); // XXX 5712 format %{ "movq $mem, $src\t# ptr" %} 5713 opcode(0xC7); /* C7 /0 */ 5714 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5715 ins_pipe(ialu_mem_imm); 5716 %} 5717 5718 // Store Compressed Pointer 5719 instruct storeN(memory mem, rRegN src) 5720 %{ 5721 match(Set mem (StoreN mem src)); 5722 5723 ins_cost(125); // XXX 5724 format %{ "movl $mem, $src\t# compressed ptr" %} 5725 ins_encode %{ 5726 __ movl($mem$$Address, $src$$Register); 5727 %} 5728 ins_pipe(ialu_mem_reg); 5729 %} 5730 5731 instruct storeNKlass(memory mem, rRegN src) 5732 %{ 5733 match(Set mem (StoreNKlass mem src)); 5734 5735 ins_cost(125); // XXX 5736 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5737 ins_encode %{ 5738 __ movl($mem$$Address, $src$$Register); 5739 %} 5740 ins_pipe(ialu_mem_reg); 5741 %} 5742 5743 instruct storeImmN0(memory mem, immN0 zero) 5744 %{ 5745 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5746 match(Set mem (StoreN mem zero)); 5747 5748 ins_cost(125); // XXX 5749 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5750 ins_encode %{ 5751 __ movl($mem$$Address, r12); 5752 %} 5753 ins_pipe(ialu_mem_reg); 5754 %} 5755 5756 instruct storeImmN(memory mem, immN src) 5757 %{ 5758 match(Set mem (StoreN mem src)); 5759 5760 ins_cost(150); // XXX 5761 format %{ "movl $mem, $src\t# compressed ptr" %} 5762 ins_encode %{ 5763 address con = (address)$src$$constant; 5764 if (con == NULL) { 5765 __ movl($mem$$Address, (int32_t)0); 5766 } else { 5767 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5768 } 5769 %} 5770 ins_pipe(ialu_mem_imm); 5771 %} 5772 5773 instruct storeImmNKlass(memory mem, immNKlass src) 5774 %{ 5775 match(Set mem (StoreNKlass mem src)); 5776 5777 ins_cost(150); // XXX 5778 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5779 ins_encode %{ 5780 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5781 %} 5782 ins_pipe(ialu_mem_imm); 5783 %} 5784 5785 // Store Integer Immediate 5786 instruct storeImmI0(memory mem, immI0 zero) 5787 %{ 5788 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5789 match(Set mem (StoreI mem zero)); 5790 5791 ins_cost(125); // XXX 5792 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5793 ins_encode %{ 5794 __ movl($mem$$Address, r12); 5795 %} 5796 ins_pipe(ialu_mem_reg); 5797 %} 5798 5799 instruct storeImmI(memory mem, immI src) 5800 %{ 5801 match(Set mem (StoreI mem src)); 5802 5803 ins_cost(150); 5804 format %{ "movl $mem, $src\t# int" %} 5805 opcode(0xC7); /* C7 /0 */ 5806 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5807 ins_pipe(ialu_mem_imm); 5808 %} 5809 5810 // Store Long Immediate 5811 instruct storeImmL0(memory mem, immL0 zero) 5812 %{ 5813 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5814 match(Set mem (StoreL mem zero)); 5815 5816 ins_cost(125); // XXX 5817 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5818 ins_encode %{ 5819 __ movq($mem$$Address, r12); 5820 %} 5821 ins_pipe(ialu_mem_reg); 5822 %} 5823 5824 instruct storeImmL(memory mem, immL32 src) 5825 %{ 5826 match(Set mem (StoreL mem src)); 5827 5828 ins_cost(150); 5829 format %{ "movq $mem, $src\t# long" %} 5830 opcode(0xC7); /* C7 /0 */ 5831 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5832 ins_pipe(ialu_mem_imm); 5833 %} 5834 5835 // Store Short/Char Immediate 5836 instruct storeImmC0(memory mem, immI0 zero) 5837 %{ 5838 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5839 match(Set mem (StoreC mem zero)); 5840 5841 ins_cost(125); // XXX 5842 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5843 ins_encode %{ 5844 __ movw($mem$$Address, r12); 5845 %} 5846 ins_pipe(ialu_mem_reg); 5847 %} 5848 5849 instruct storeImmI16(memory mem, immI16 src) 5850 %{ 5851 predicate(UseStoreImmI16); 5852 match(Set mem (StoreC mem src)); 5853 5854 ins_cost(150); 5855 format %{ "movw $mem, $src\t# short/char" %} 5856 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 5857 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 5858 ins_pipe(ialu_mem_imm); 5859 %} 5860 5861 // Store Byte Immediate 5862 instruct storeImmB0(memory mem, immI0 zero) 5863 %{ 5864 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5865 match(Set mem (StoreB mem zero)); 5866 5867 ins_cost(125); // XXX 5868 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5869 ins_encode %{ 5870 __ movb($mem$$Address, r12); 5871 %} 5872 ins_pipe(ialu_mem_reg); 5873 %} 5874 5875 instruct storeImmB(memory mem, immI8 src) 5876 %{ 5877 match(Set mem (StoreB mem src)); 5878 5879 ins_cost(150); // XXX 5880 format %{ "movb $mem, $src\t# byte" %} 5881 opcode(0xC6); /* C6 /0 */ 5882 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5883 ins_pipe(ialu_mem_imm); 5884 %} 5885 5886 // Store CMS card-mark Immediate 5887 instruct storeImmCM0_reg(memory mem, immI0 zero) 5888 %{ 5889 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5890 match(Set mem (StoreCM mem zero)); 5891 5892 ins_cost(125); // XXX 5893 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5894 ins_encode %{ 5895 __ movb($mem$$Address, r12); 5896 %} 5897 ins_pipe(ialu_mem_reg); 5898 %} 5899 5900 instruct storeImmCM0(memory mem, immI0 src) 5901 %{ 5902 match(Set mem (StoreCM mem src)); 5903 5904 ins_cost(150); // XXX 5905 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5906 opcode(0xC6); /* C6 /0 */ 5907 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5908 ins_pipe(ialu_mem_imm); 5909 %} 5910 5911 // Store Float 5912 instruct storeF(memory mem, regF src) 5913 %{ 5914 match(Set mem (StoreF mem src)); 5915 5916 ins_cost(95); // XXX 5917 format %{ "movss $mem, $src\t# float" %} 5918 ins_encode %{ 5919 __ movflt($mem$$Address, $src$$XMMRegister); 5920 %} 5921 ins_pipe(pipe_slow); // XXX 5922 %} 5923 5924 // Store immediate Float value (it is faster than store from XMM register) 5925 instruct storeF0(memory mem, immF0 zero) 5926 %{ 5927 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5928 match(Set mem (StoreF mem zero)); 5929 5930 ins_cost(25); // XXX 5931 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5932 ins_encode %{ 5933 __ movl($mem$$Address, r12); 5934 %} 5935 ins_pipe(ialu_mem_reg); 5936 %} 5937 5938 instruct storeF_imm(memory mem, immF src) 5939 %{ 5940 match(Set mem (StoreF mem src)); 5941 5942 ins_cost(50); 5943 format %{ "movl $mem, $src\t# float" %} 5944 opcode(0xC7); /* C7 /0 */ 5945 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5946 ins_pipe(ialu_mem_imm); 5947 %} 5948 5949 // Store Double 5950 instruct storeD(memory mem, regD src) 5951 %{ 5952 match(Set mem (StoreD mem src)); 5953 5954 ins_cost(95); // XXX 5955 format %{ "movsd $mem, $src\t# double" %} 5956 ins_encode %{ 5957 __ movdbl($mem$$Address, $src$$XMMRegister); 5958 %} 5959 ins_pipe(pipe_slow); // XXX 5960 %} 5961 5962 // Store immediate double 0.0 (it is faster than store from XMM register) 5963 instruct storeD0_imm(memory mem, immD0 src) 5964 %{ 5965 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 5966 match(Set mem (StoreD mem src)); 5967 5968 ins_cost(50); 5969 format %{ "movq $mem, $src\t# double 0." %} 5970 opcode(0xC7); /* C7 /0 */ 5971 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5972 ins_pipe(ialu_mem_imm); 5973 %} 5974 5975 instruct storeD0(memory mem, immD0 zero) 5976 %{ 5977 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5978 match(Set mem (StoreD mem zero)); 5979 5980 ins_cost(25); // XXX 5981 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5982 ins_encode %{ 5983 __ movq($mem$$Address, r12); 5984 %} 5985 ins_pipe(ialu_mem_reg); 5986 %} 5987 5988 instruct storeSSI(stackSlotI dst, rRegI src) 5989 %{ 5990 match(Set dst src); 5991 5992 ins_cost(100); 5993 format %{ "movl $dst, $src\t# int stk" %} 5994 opcode(0x89); 5995 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 5996 ins_pipe( ialu_mem_reg ); 5997 %} 5998 5999 instruct storeSSL(stackSlotL dst, rRegL src) 6000 %{ 6001 match(Set dst src); 6002 6003 ins_cost(100); 6004 format %{ "movq $dst, $src\t# long stk" %} 6005 opcode(0x89); 6006 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6007 ins_pipe(ialu_mem_reg); 6008 %} 6009 6010 instruct storeSSP(stackSlotP dst, rRegP src) 6011 %{ 6012 match(Set dst src); 6013 6014 ins_cost(100); 6015 format %{ "movq $dst, $src\t# ptr stk" %} 6016 opcode(0x89); 6017 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6018 ins_pipe(ialu_mem_reg); 6019 %} 6020 6021 instruct storeSSF(stackSlotF dst, regF src) 6022 %{ 6023 match(Set dst src); 6024 6025 ins_cost(95); // XXX 6026 format %{ "movss $dst, $src\t# float stk" %} 6027 ins_encode %{ 6028 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6029 %} 6030 ins_pipe(pipe_slow); // XXX 6031 %} 6032 6033 instruct storeSSD(stackSlotD dst, regD src) 6034 %{ 6035 match(Set dst src); 6036 6037 ins_cost(95); // XXX 6038 format %{ "movsd $dst, $src\t# double stk" %} 6039 ins_encode %{ 6040 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6041 %} 6042 ins_pipe(pipe_slow); // XXX 6043 %} 6044 6045 //----------BSWAP Instructions------------------------------------------------- 6046 instruct bytes_reverse_int(rRegI dst) %{ 6047 match(Set dst (ReverseBytesI dst)); 6048 6049 format %{ "bswapl $dst" %} 6050 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6051 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6052 ins_pipe( ialu_reg ); 6053 %} 6054 6055 instruct bytes_reverse_long(rRegL dst) %{ 6056 match(Set dst (ReverseBytesL dst)); 6057 6058 format %{ "bswapq $dst" %} 6059 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6060 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6061 ins_pipe( ialu_reg); 6062 %} 6063 6064 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6065 match(Set dst (ReverseBytesUS dst)); 6066 effect(KILL cr); 6067 6068 format %{ "bswapl $dst\n\t" 6069 "shrl $dst,16\n\t" %} 6070 ins_encode %{ 6071 __ bswapl($dst$$Register); 6072 __ shrl($dst$$Register, 16); 6073 %} 6074 ins_pipe( ialu_reg ); 6075 %} 6076 6077 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6078 match(Set dst (ReverseBytesS dst)); 6079 effect(KILL cr); 6080 6081 format %{ "bswapl $dst\n\t" 6082 "sar $dst,16\n\t" %} 6083 ins_encode %{ 6084 __ bswapl($dst$$Register); 6085 __ sarl($dst$$Register, 16); 6086 %} 6087 ins_pipe( ialu_reg ); 6088 %} 6089 6090 //---------- Zeros Count Instructions ------------------------------------------ 6091 6092 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6093 predicate(UseCountLeadingZerosInstruction); 6094 match(Set dst (CountLeadingZerosI src)); 6095 effect(KILL cr); 6096 6097 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6098 ins_encode %{ 6099 __ lzcntl($dst$$Register, $src$$Register); 6100 %} 6101 ins_pipe(ialu_reg); 6102 %} 6103 6104 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6105 predicate(!UseCountLeadingZerosInstruction); 6106 match(Set dst (CountLeadingZerosI src)); 6107 effect(KILL cr); 6108 6109 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6110 "jnz skip\n\t" 6111 "movl $dst, -1\n" 6112 "skip:\n\t" 6113 "negl $dst\n\t" 6114 "addl $dst, 31" %} 6115 ins_encode %{ 6116 Register Rdst = $dst$$Register; 6117 Register Rsrc = $src$$Register; 6118 Label skip; 6119 __ bsrl(Rdst, Rsrc); 6120 __ jccb(Assembler::notZero, skip); 6121 __ movl(Rdst, -1); 6122 __ bind(skip); 6123 __ negl(Rdst); 6124 __ addl(Rdst, BitsPerInt - 1); 6125 %} 6126 ins_pipe(ialu_reg); 6127 %} 6128 6129 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6130 predicate(UseCountLeadingZerosInstruction); 6131 match(Set dst (CountLeadingZerosL src)); 6132 effect(KILL cr); 6133 6134 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6135 ins_encode %{ 6136 __ lzcntq($dst$$Register, $src$$Register); 6137 %} 6138 ins_pipe(ialu_reg); 6139 %} 6140 6141 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6142 predicate(!UseCountLeadingZerosInstruction); 6143 match(Set dst (CountLeadingZerosL src)); 6144 effect(KILL cr); 6145 6146 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6147 "jnz skip\n\t" 6148 "movl $dst, -1\n" 6149 "skip:\n\t" 6150 "negl $dst\n\t" 6151 "addl $dst, 63" %} 6152 ins_encode %{ 6153 Register Rdst = $dst$$Register; 6154 Register Rsrc = $src$$Register; 6155 Label skip; 6156 __ bsrq(Rdst, Rsrc); 6157 __ jccb(Assembler::notZero, skip); 6158 __ movl(Rdst, -1); 6159 __ bind(skip); 6160 __ negl(Rdst); 6161 __ addl(Rdst, BitsPerLong - 1); 6162 %} 6163 ins_pipe(ialu_reg); 6164 %} 6165 6166 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6167 predicate(UseCountTrailingZerosInstruction); 6168 match(Set dst (CountTrailingZerosI src)); 6169 effect(KILL cr); 6170 6171 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6172 ins_encode %{ 6173 __ tzcntl($dst$$Register, $src$$Register); 6174 %} 6175 ins_pipe(ialu_reg); 6176 %} 6177 6178 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6179 predicate(!UseCountTrailingZerosInstruction); 6180 match(Set dst (CountTrailingZerosI src)); 6181 effect(KILL cr); 6182 6183 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6184 "jnz done\n\t" 6185 "movl $dst, 32\n" 6186 "done:" %} 6187 ins_encode %{ 6188 Register Rdst = $dst$$Register; 6189 Label done; 6190 __ bsfl(Rdst, $src$$Register); 6191 __ jccb(Assembler::notZero, done); 6192 __ movl(Rdst, BitsPerInt); 6193 __ bind(done); 6194 %} 6195 ins_pipe(ialu_reg); 6196 %} 6197 6198 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6199 predicate(UseCountTrailingZerosInstruction); 6200 match(Set dst (CountTrailingZerosL src)); 6201 effect(KILL cr); 6202 6203 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6204 ins_encode %{ 6205 __ tzcntq($dst$$Register, $src$$Register); 6206 %} 6207 ins_pipe(ialu_reg); 6208 %} 6209 6210 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6211 predicate(!UseCountTrailingZerosInstruction); 6212 match(Set dst (CountTrailingZerosL src)); 6213 effect(KILL cr); 6214 6215 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6216 "jnz done\n\t" 6217 "movl $dst, 64\n" 6218 "done:" %} 6219 ins_encode %{ 6220 Register Rdst = $dst$$Register; 6221 Label done; 6222 __ bsfq(Rdst, $src$$Register); 6223 __ jccb(Assembler::notZero, done); 6224 __ movl(Rdst, BitsPerLong); 6225 __ bind(done); 6226 %} 6227 ins_pipe(ialu_reg); 6228 %} 6229 6230 6231 //---------- Population Count Instructions ------------------------------------- 6232 6233 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6234 predicate(UsePopCountInstruction); 6235 match(Set dst (PopCountI src)); 6236 effect(KILL cr); 6237 6238 format %{ "popcnt $dst, $src" %} 6239 ins_encode %{ 6240 __ popcntl($dst$$Register, $src$$Register); 6241 %} 6242 ins_pipe(ialu_reg); 6243 %} 6244 6245 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6246 predicate(UsePopCountInstruction); 6247 match(Set dst (PopCountI (LoadI mem))); 6248 effect(KILL cr); 6249 6250 format %{ "popcnt $dst, $mem" %} 6251 ins_encode %{ 6252 __ popcntl($dst$$Register, $mem$$Address); 6253 %} 6254 ins_pipe(ialu_reg); 6255 %} 6256 6257 // Note: Long.bitCount(long) returns an int. 6258 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6259 predicate(UsePopCountInstruction); 6260 match(Set dst (PopCountL src)); 6261 effect(KILL cr); 6262 6263 format %{ "popcnt $dst, $src" %} 6264 ins_encode %{ 6265 __ popcntq($dst$$Register, $src$$Register); 6266 %} 6267 ins_pipe(ialu_reg); 6268 %} 6269 6270 // Note: Long.bitCount(long) returns an int. 6271 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6272 predicate(UsePopCountInstruction); 6273 match(Set dst (PopCountL (LoadL mem))); 6274 effect(KILL cr); 6275 6276 format %{ "popcnt $dst, $mem" %} 6277 ins_encode %{ 6278 __ popcntq($dst$$Register, $mem$$Address); 6279 %} 6280 ins_pipe(ialu_reg); 6281 %} 6282 6283 6284 //----------MemBar Instructions----------------------------------------------- 6285 // Memory barrier flavors 6286 6287 instruct membar_acquire() 6288 %{ 6289 match(MemBarAcquire); 6290 match(LoadFence); 6291 ins_cost(0); 6292 6293 size(0); 6294 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6295 ins_encode(); 6296 ins_pipe(empty); 6297 %} 6298 6299 instruct membar_acquire_lock() 6300 %{ 6301 match(MemBarAcquireLock); 6302 ins_cost(0); 6303 6304 size(0); 6305 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6306 ins_encode(); 6307 ins_pipe(empty); 6308 %} 6309 6310 instruct membar_release() 6311 %{ 6312 match(MemBarRelease); 6313 match(StoreFence); 6314 ins_cost(0); 6315 6316 size(0); 6317 format %{ "MEMBAR-release ! (empty encoding)" %} 6318 ins_encode(); 6319 ins_pipe(empty); 6320 %} 6321 6322 instruct membar_release_lock() 6323 %{ 6324 match(MemBarReleaseLock); 6325 ins_cost(0); 6326 6327 size(0); 6328 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6329 ins_encode(); 6330 ins_pipe(empty); 6331 %} 6332 6333 instruct membar_volatile(rFlagsReg cr) %{ 6334 match(MemBarVolatile); 6335 effect(KILL cr); 6336 ins_cost(400); 6337 6338 format %{ 6339 $$template 6340 if (os::is_MP()) { 6341 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6342 } else { 6343 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6344 } 6345 %} 6346 ins_encode %{ 6347 __ membar(Assembler::StoreLoad); 6348 %} 6349 ins_pipe(pipe_slow); 6350 %} 6351 6352 instruct unnecessary_membar_volatile() 6353 %{ 6354 match(MemBarVolatile); 6355 predicate(Matcher::post_store_load_barrier(n)); 6356 ins_cost(0); 6357 6358 size(0); 6359 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6360 ins_encode(); 6361 ins_pipe(empty); 6362 %} 6363 6364 instruct membar_storestore() %{ 6365 match(MemBarStoreStore); 6366 ins_cost(0); 6367 6368 size(0); 6369 format %{ "MEMBAR-storestore (empty encoding)" %} 6370 ins_encode( ); 6371 ins_pipe(empty); 6372 %} 6373 6374 //----------Move Instructions-------------------------------------------------- 6375 6376 instruct castX2P(rRegP dst, rRegL src) 6377 %{ 6378 match(Set dst (CastX2P src)); 6379 6380 format %{ "movq $dst, $src\t# long->ptr" %} 6381 ins_encode %{ 6382 if ($dst$$reg != $src$$reg) { 6383 __ movptr($dst$$Register, $src$$Register); 6384 } 6385 %} 6386 ins_pipe(ialu_reg_reg); // XXX 6387 %} 6388 6389 instruct castP2X(rRegL dst, rRegP src) 6390 %{ 6391 match(Set dst (CastP2X src)); 6392 6393 format %{ "movq $dst, $src\t# ptr -> long" %} 6394 ins_encode %{ 6395 if ($dst$$reg != $src$$reg) { 6396 __ movptr($dst$$Register, $src$$Register); 6397 } 6398 %} 6399 ins_pipe(ialu_reg_reg); // XXX 6400 %} 6401 6402 // Convert oop into int for vectors alignment masking 6403 instruct convP2I(rRegI dst, rRegP src) 6404 %{ 6405 match(Set dst (ConvL2I (CastP2X src))); 6406 6407 format %{ "movl $dst, $src\t# ptr -> int" %} 6408 ins_encode %{ 6409 __ movl($dst$$Register, $src$$Register); 6410 %} 6411 ins_pipe(ialu_reg_reg); // XXX 6412 %} 6413 6414 // Convert compressed oop into int for vectors alignment masking 6415 // in case of 32bit oops (heap < 4Gb). 6416 instruct convN2I(rRegI dst, rRegN src) 6417 %{ 6418 predicate(Universe::narrow_oop_shift() == 0); 6419 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6420 6421 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6422 ins_encode %{ 6423 __ movl($dst$$Register, $src$$Register); 6424 %} 6425 ins_pipe(ialu_reg_reg); // XXX 6426 %} 6427 6428 // Convert oop pointer into compressed form 6429 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6430 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6431 match(Set dst (EncodeP src)); 6432 effect(KILL cr); 6433 format %{ "encode_heap_oop $dst,$src" %} 6434 ins_encode %{ 6435 Register s = $src$$Register; 6436 Register d = $dst$$Register; 6437 if (s != d) { 6438 __ movq(d, s); 6439 } 6440 __ encode_heap_oop(d); 6441 %} 6442 ins_pipe(ialu_reg_long); 6443 %} 6444 6445 instruct encodeHeapOop_not_null(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_not_null $dst,$src" %} 6450 ins_encode %{ 6451 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6452 %} 6453 ins_pipe(ialu_reg_long); 6454 %} 6455 6456 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6457 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6458 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6459 match(Set dst (DecodeN src)); 6460 effect(KILL cr); 6461 format %{ "decode_heap_oop $dst,$src" %} 6462 ins_encode %{ 6463 Register s = $src$$Register; 6464 Register d = $dst$$Register; 6465 if (s != d) { 6466 __ movq(d, s); 6467 } 6468 __ decode_heap_oop(d); 6469 %} 6470 ins_pipe(ialu_reg_long); 6471 %} 6472 6473 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6474 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6475 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6476 match(Set dst (DecodeN src)); 6477 effect(KILL cr); 6478 format %{ "decode_heap_oop_not_null $dst,$src" %} 6479 ins_encode %{ 6480 Register s = $src$$Register; 6481 Register d = $dst$$Register; 6482 if (s != d) { 6483 __ decode_heap_oop_not_null(d, s); 6484 } else { 6485 __ decode_heap_oop_not_null(d); 6486 } 6487 %} 6488 ins_pipe(ialu_reg_long); 6489 %} 6490 6491 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6492 match(Set dst (EncodePKlass src)); 6493 effect(KILL cr); 6494 format %{ "encode_klass_not_null $dst,$src" %} 6495 ins_encode %{ 6496 __ encode_klass_not_null($dst$$Register, $src$$Register); 6497 %} 6498 ins_pipe(ialu_reg_long); 6499 %} 6500 6501 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6502 match(Set dst (DecodeNKlass src)); 6503 effect(KILL cr); 6504 format %{ "decode_klass_not_null $dst,$src" %} 6505 ins_encode %{ 6506 Register s = $src$$Register; 6507 Register d = $dst$$Register; 6508 if (s != d) { 6509 __ decode_klass_not_null(d, s); 6510 } else { 6511 __ decode_klass_not_null(d); 6512 } 6513 %} 6514 ins_pipe(ialu_reg_long); 6515 %} 6516 6517 6518 //----------Conditional Move--------------------------------------------------- 6519 // Jump 6520 // dummy instruction for generating temp registers 6521 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6522 match(Jump (LShiftL switch_val shift)); 6523 ins_cost(350); 6524 predicate(false); 6525 effect(TEMP dest); 6526 6527 format %{ "leaq $dest, [$constantaddress]\n\t" 6528 "jmp [$dest + $switch_val << $shift]\n\t" %} 6529 ins_encode %{ 6530 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6531 // to do that and the compiler is using that register as one it can allocate. 6532 // So we build it all by hand. 6533 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6534 // ArrayAddress dispatch(table, index); 6535 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6536 __ lea($dest$$Register, $constantaddress); 6537 __ jmp(dispatch); 6538 %} 6539 ins_pipe(pipe_jmp); 6540 %} 6541 6542 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6543 match(Jump (AddL (LShiftL switch_val shift) offset)); 6544 ins_cost(350); 6545 effect(TEMP dest); 6546 6547 format %{ "leaq $dest, [$constantaddress]\n\t" 6548 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6549 ins_encode %{ 6550 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6551 // to do that and the compiler is using that register as one it can allocate. 6552 // So we build it all by hand. 6553 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6554 // ArrayAddress dispatch(table, index); 6555 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6556 __ lea($dest$$Register, $constantaddress); 6557 __ jmp(dispatch); 6558 %} 6559 ins_pipe(pipe_jmp); 6560 %} 6561 6562 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6563 match(Jump switch_val); 6564 ins_cost(350); 6565 effect(TEMP dest); 6566 6567 format %{ "leaq $dest, [$constantaddress]\n\t" 6568 "jmp [$dest + $switch_val]\n\t" %} 6569 ins_encode %{ 6570 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6571 // to do that and the compiler is using that register as one it can allocate. 6572 // So we build it all by hand. 6573 // Address index(noreg, switch_reg, Address::times_1); 6574 // ArrayAddress dispatch(table, index); 6575 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6576 __ lea($dest$$Register, $constantaddress); 6577 __ jmp(dispatch); 6578 %} 6579 ins_pipe(pipe_jmp); 6580 %} 6581 6582 // Conditional move 6583 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6584 %{ 6585 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6586 6587 ins_cost(200); // XXX 6588 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6589 opcode(0x0F, 0x40); 6590 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6591 ins_pipe(pipe_cmov_reg); 6592 %} 6593 6594 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6595 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6596 6597 ins_cost(200); // XXX 6598 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6599 opcode(0x0F, 0x40); 6600 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6601 ins_pipe(pipe_cmov_reg); 6602 %} 6603 6604 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6605 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6606 ins_cost(200); 6607 expand %{ 6608 cmovI_regU(cop, cr, dst, src); 6609 %} 6610 %} 6611 6612 // Conditional move 6613 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6614 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6615 6616 ins_cost(250); // XXX 6617 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6618 opcode(0x0F, 0x40); 6619 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6620 ins_pipe(pipe_cmov_mem); 6621 %} 6622 6623 // Conditional move 6624 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6625 %{ 6626 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6627 6628 ins_cost(250); // XXX 6629 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6630 opcode(0x0F, 0x40); 6631 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6632 ins_pipe(pipe_cmov_mem); 6633 %} 6634 6635 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6636 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6637 ins_cost(250); 6638 expand %{ 6639 cmovI_memU(cop, cr, dst, src); 6640 %} 6641 %} 6642 6643 // Conditional move 6644 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6645 %{ 6646 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6647 6648 ins_cost(200); // XXX 6649 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6650 opcode(0x0F, 0x40); 6651 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6652 ins_pipe(pipe_cmov_reg); 6653 %} 6654 6655 // Conditional move 6656 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6657 %{ 6658 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6659 6660 ins_cost(200); // XXX 6661 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6662 opcode(0x0F, 0x40); 6663 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6664 ins_pipe(pipe_cmov_reg); 6665 %} 6666 6667 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6668 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6669 ins_cost(200); 6670 expand %{ 6671 cmovN_regU(cop, cr, dst, src); 6672 %} 6673 %} 6674 6675 // Conditional move 6676 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6677 %{ 6678 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6679 6680 ins_cost(200); // XXX 6681 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6682 opcode(0x0F, 0x40); 6683 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6684 ins_pipe(pipe_cmov_reg); // XXX 6685 %} 6686 6687 // Conditional move 6688 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6689 %{ 6690 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6691 6692 ins_cost(200); // XXX 6693 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6694 opcode(0x0F, 0x40); 6695 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6696 ins_pipe(pipe_cmov_reg); // XXX 6697 %} 6698 6699 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6700 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6701 ins_cost(200); 6702 expand %{ 6703 cmovP_regU(cop, cr, dst, src); 6704 %} 6705 %} 6706 6707 // DISABLED: Requires the ADLC to emit a bottom_type call that 6708 // correctly meets the two pointer arguments; one is an incoming 6709 // register but the other is a memory operand. ALSO appears to 6710 // be buggy with implicit null checks. 6711 // 6712 //// Conditional move 6713 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6714 //%{ 6715 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6716 // ins_cost(250); 6717 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6718 // opcode(0x0F,0x40); 6719 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6720 // ins_pipe( pipe_cmov_mem ); 6721 //%} 6722 // 6723 //// Conditional move 6724 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6725 //%{ 6726 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6727 // ins_cost(250); 6728 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6729 // opcode(0x0F,0x40); 6730 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6731 // ins_pipe( pipe_cmov_mem ); 6732 //%} 6733 6734 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6735 %{ 6736 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6737 6738 ins_cost(200); // XXX 6739 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6740 opcode(0x0F, 0x40); 6741 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6742 ins_pipe(pipe_cmov_reg); // XXX 6743 %} 6744 6745 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6746 %{ 6747 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6748 6749 ins_cost(200); // XXX 6750 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6751 opcode(0x0F, 0x40); 6752 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6753 ins_pipe(pipe_cmov_mem); // XXX 6754 %} 6755 6756 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6757 %{ 6758 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6759 6760 ins_cost(200); // XXX 6761 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6762 opcode(0x0F, 0x40); 6763 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6764 ins_pipe(pipe_cmov_reg); // XXX 6765 %} 6766 6767 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6768 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6769 ins_cost(200); 6770 expand %{ 6771 cmovL_regU(cop, cr, dst, src); 6772 %} 6773 %} 6774 6775 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6776 %{ 6777 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6778 6779 ins_cost(200); // XXX 6780 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6781 opcode(0x0F, 0x40); 6782 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6783 ins_pipe(pipe_cmov_mem); // XXX 6784 %} 6785 6786 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6787 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6788 ins_cost(200); 6789 expand %{ 6790 cmovL_memU(cop, cr, dst, src); 6791 %} 6792 %} 6793 6794 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6795 %{ 6796 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6797 6798 ins_cost(200); // XXX 6799 format %{ "jn$cop skip\t# signed cmove float\n\t" 6800 "movss $dst, $src\n" 6801 "skip:" %} 6802 ins_encode %{ 6803 Label Lskip; 6804 // Invert sense of branch from sense of CMOV 6805 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6806 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6807 __ bind(Lskip); 6808 %} 6809 ins_pipe(pipe_slow); 6810 %} 6811 6812 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6813 // %{ 6814 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 6815 6816 // ins_cost(200); // XXX 6817 // format %{ "jn$cop skip\t# signed cmove float\n\t" 6818 // "movss $dst, $src\n" 6819 // "skip:" %} 6820 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 6821 // ins_pipe(pipe_slow); 6822 // %} 6823 6824 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6825 %{ 6826 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6827 6828 ins_cost(200); // XXX 6829 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6830 "movss $dst, $src\n" 6831 "skip:" %} 6832 ins_encode %{ 6833 Label Lskip; 6834 // Invert sense of branch from sense of CMOV 6835 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6836 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6837 __ bind(Lskip); 6838 %} 6839 ins_pipe(pipe_slow); 6840 %} 6841 6842 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6843 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6844 ins_cost(200); 6845 expand %{ 6846 cmovF_regU(cop, cr, dst, src); 6847 %} 6848 %} 6849 6850 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6851 %{ 6852 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6853 6854 ins_cost(200); // XXX 6855 format %{ "jn$cop skip\t# signed cmove double\n\t" 6856 "movsd $dst, $src\n" 6857 "skip:" %} 6858 ins_encode %{ 6859 Label Lskip; 6860 // Invert sense of branch from sense of CMOV 6861 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6862 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6863 __ bind(Lskip); 6864 %} 6865 ins_pipe(pipe_slow); 6866 %} 6867 6868 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6869 %{ 6870 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6871 6872 ins_cost(200); // XXX 6873 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6874 "movsd $dst, $src\n" 6875 "skip:" %} 6876 ins_encode %{ 6877 Label Lskip; 6878 // Invert sense of branch from sense of CMOV 6879 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6880 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6881 __ bind(Lskip); 6882 %} 6883 ins_pipe(pipe_slow); 6884 %} 6885 6886 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6887 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6888 ins_cost(200); 6889 expand %{ 6890 cmovD_regU(cop, cr, dst, src); 6891 %} 6892 %} 6893 6894 //----------Arithmetic Instructions-------------------------------------------- 6895 //----------Addition Instructions---------------------------------------------- 6896 6897 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6898 %{ 6899 match(Set dst (AddI dst src)); 6900 effect(KILL cr); 6901 6902 format %{ "addl $dst, $src\t# int" %} 6903 opcode(0x03); 6904 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 6905 ins_pipe(ialu_reg_reg); 6906 %} 6907 6908 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6909 %{ 6910 match(Set dst (AddI dst src)); 6911 effect(KILL cr); 6912 6913 format %{ "addl $dst, $src\t# int" %} 6914 opcode(0x81, 0x00); /* /0 id */ 6915 ins_encode(OpcSErm(dst, src), Con8or32(src)); 6916 ins_pipe( ialu_reg ); 6917 %} 6918 6919 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6920 %{ 6921 match(Set dst (AddI dst (LoadI src))); 6922 effect(KILL cr); 6923 6924 ins_cost(125); // XXX 6925 format %{ "addl $dst, $src\t# int" %} 6926 opcode(0x03); 6927 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6928 ins_pipe(ialu_reg_mem); 6929 %} 6930 6931 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6932 %{ 6933 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6934 effect(KILL cr); 6935 6936 ins_cost(150); // XXX 6937 format %{ "addl $dst, $src\t# int" %} 6938 opcode(0x01); /* Opcode 01 /r */ 6939 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6940 ins_pipe(ialu_mem_reg); 6941 %} 6942 6943 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6944 %{ 6945 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6946 effect(KILL cr); 6947 6948 ins_cost(125); // XXX 6949 format %{ "addl $dst, $src\t# int" %} 6950 opcode(0x81); /* Opcode 81 /0 id */ 6951 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 6952 ins_pipe(ialu_mem_imm); 6953 %} 6954 6955 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 6956 %{ 6957 predicate(UseIncDec); 6958 match(Set dst (AddI dst src)); 6959 effect(KILL cr); 6960 6961 format %{ "incl $dst\t# int" %} 6962 opcode(0xFF, 0x00); // FF /0 6963 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6964 ins_pipe(ialu_reg); 6965 %} 6966 6967 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 6968 %{ 6969 predicate(UseIncDec); 6970 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6971 effect(KILL cr); 6972 6973 ins_cost(125); // XXX 6974 format %{ "incl $dst\t# int" %} 6975 opcode(0xFF); /* Opcode FF /0 */ 6976 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 6977 ins_pipe(ialu_mem_imm); 6978 %} 6979 6980 // XXX why does that use AddI 6981 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6982 %{ 6983 predicate(UseIncDec); 6984 match(Set dst (AddI dst src)); 6985 effect(KILL cr); 6986 6987 format %{ "decl $dst\t# int" %} 6988 opcode(0xFF, 0x01); // FF /1 6989 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6990 ins_pipe(ialu_reg); 6991 %} 6992 6993 // XXX why does that use AddI 6994 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6995 %{ 6996 predicate(UseIncDec); 6997 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6998 effect(KILL cr); 6999 7000 ins_cost(125); // XXX 7001 format %{ "decl $dst\t# int" %} 7002 opcode(0xFF); /* Opcode FF /1 */ 7003 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7004 ins_pipe(ialu_mem_imm); 7005 %} 7006 7007 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7008 %{ 7009 match(Set dst (AddI src0 src1)); 7010 7011 ins_cost(110); 7012 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7013 opcode(0x8D); /* 0x8D /r */ 7014 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7015 ins_pipe(ialu_reg_reg); 7016 %} 7017 7018 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7019 %{ 7020 match(Set dst (AddL dst src)); 7021 effect(KILL cr); 7022 7023 format %{ "addq $dst, $src\t# long" %} 7024 opcode(0x03); 7025 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7026 ins_pipe(ialu_reg_reg); 7027 %} 7028 7029 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7030 %{ 7031 match(Set dst (AddL dst src)); 7032 effect(KILL cr); 7033 7034 format %{ "addq $dst, $src\t# long" %} 7035 opcode(0x81, 0x00); /* /0 id */ 7036 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7037 ins_pipe( ialu_reg ); 7038 %} 7039 7040 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7041 %{ 7042 match(Set dst (AddL dst (LoadL src))); 7043 effect(KILL cr); 7044 7045 ins_cost(125); // XXX 7046 format %{ "addq $dst, $src\t# long" %} 7047 opcode(0x03); 7048 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7049 ins_pipe(ialu_reg_mem); 7050 %} 7051 7052 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7053 %{ 7054 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7055 effect(KILL cr); 7056 7057 ins_cost(150); // XXX 7058 format %{ "addq $dst, $src\t# long" %} 7059 opcode(0x01); /* Opcode 01 /r */ 7060 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7061 ins_pipe(ialu_mem_reg); 7062 %} 7063 7064 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7065 %{ 7066 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7067 effect(KILL cr); 7068 7069 ins_cost(125); // XXX 7070 format %{ "addq $dst, $src\t# long" %} 7071 opcode(0x81); /* Opcode 81 /0 id */ 7072 ins_encode(REX_mem_wide(dst), 7073 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7074 ins_pipe(ialu_mem_imm); 7075 %} 7076 7077 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7078 %{ 7079 predicate(UseIncDec); 7080 match(Set dst (AddL dst src)); 7081 effect(KILL cr); 7082 7083 format %{ "incq $dst\t# long" %} 7084 opcode(0xFF, 0x00); // FF /0 7085 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7086 ins_pipe(ialu_reg); 7087 %} 7088 7089 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7090 %{ 7091 predicate(UseIncDec); 7092 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7093 effect(KILL cr); 7094 7095 ins_cost(125); // XXX 7096 format %{ "incq $dst\t# long" %} 7097 opcode(0xFF); /* Opcode FF /0 */ 7098 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7099 ins_pipe(ialu_mem_imm); 7100 %} 7101 7102 // XXX why does that use AddL 7103 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7104 %{ 7105 predicate(UseIncDec); 7106 match(Set dst (AddL dst src)); 7107 effect(KILL cr); 7108 7109 format %{ "decq $dst\t# long" %} 7110 opcode(0xFF, 0x01); // FF /1 7111 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7112 ins_pipe(ialu_reg); 7113 %} 7114 7115 // XXX why does that use AddL 7116 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7117 %{ 7118 predicate(UseIncDec); 7119 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7120 effect(KILL cr); 7121 7122 ins_cost(125); // XXX 7123 format %{ "decq $dst\t# long" %} 7124 opcode(0xFF); /* Opcode FF /1 */ 7125 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7126 ins_pipe(ialu_mem_imm); 7127 %} 7128 7129 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7130 %{ 7131 match(Set dst (AddL src0 src1)); 7132 7133 ins_cost(110); 7134 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7135 opcode(0x8D); /* 0x8D /r */ 7136 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7137 ins_pipe(ialu_reg_reg); 7138 %} 7139 7140 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7141 %{ 7142 match(Set dst (AddP dst src)); 7143 effect(KILL cr); 7144 7145 format %{ "addq $dst, $src\t# ptr" %} 7146 opcode(0x03); 7147 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7148 ins_pipe(ialu_reg_reg); 7149 %} 7150 7151 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7152 %{ 7153 match(Set dst (AddP dst src)); 7154 effect(KILL cr); 7155 7156 format %{ "addq $dst, $src\t# ptr" %} 7157 opcode(0x81, 0x00); /* /0 id */ 7158 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7159 ins_pipe( ialu_reg ); 7160 %} 7161 7162 // XXX addP mem ops ???? 7163 7164 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7165 %{ 7166 match(Set dst (AddP src0 src1)); 7167 7168 ins_cost(110); 7169 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7170 opcode(0x8D); /* 0x8D /r */ 7171 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7172 ins_pipe(ialu_reg_reg); 7173 %} 7174 7175 instruct checkCastPP(rRegP dst) 7176 %{ 7177 match(Set dst (CheckCastPP dst)); 7178 7179 size(0); 7180 format %{ "# checkcastPP of $dst" %} 7181 ins_encode(/* empty encoding */); 7182 ins_pipe(empty); 7183 %} 7184 7185 instruct castPP(rRegP dst) 7186 %{ 7187 match(Set dst (CastPP dst)); 7188 7189 size(0); 7190 format %{ "# castPP of $dst" %} 7191 ins_encode(/* empty encoding */); 7192 ins_pipe(empty); 7193 %} 7194 7195 instruct castII(rRegI dst) 7196 %{ 7197 match(Set dst (CastII dst)); 7198 7199 size(0); 7200 format %{ "# castII of $dst" %} 7201 ins_encode(/* empty encoding */); 7202 ins_cost(0); 7203 ins_pipe(empty); 7204 %} 7205 7206 // LoadP-locked same as a regular LoadP when used with compare-swap 7207 instruct loadPLocked(rRegP dst, memory mem) 7208 %{ 7209 match(Set dst (LoadPLocked mem)); 7210 7211 ins_cost(125); // XXX 7212 format %{ "movq $dst, $mem\t# ptr locked" %} 7213 opcode(0x8B); 7214 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7215 ins_pipe(ialu_reg_mem); // XXX 7216 %} 7217 7218 // Conditional-store of the updated heap-top. 7219 // Used during allocation of the shared heap. 7220 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7221 7222 instruct storePConditional(memory heap_top_ptr, 7223 rax_RegP oldval, rRegP newval, 7224 rFlagsReg cr) 7225 %{ 7226 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7227 7228 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7229 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7230 opcode(0x0F, 0xB1); 7231 ins_encode(lock_prefix, 7232 REX_reg_mem_wide(newval, heap_top_ptr), 7233 OpcP, OpcS, 7234 reg_mem(newval, heap_top_ptr)); 7235 ins_pipe(pipe_cmpxchg); 7236 %} 7237 7238 // Conditional-store of an int value. 7239 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7240 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7241 %{ 7242 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7243 effect(KILL oldval); 7244 7245 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7246 opcode(0x0F, 0xB1); 7247 ins_encode(lock_prefix, 7248 REX_reg_mem(newval, mem), 7249 OpcP, OpcS, 7250 reg_mem(newval, mem)); 7251 ins_pipe(pipe_cmpxchg); 7252 %} 7253 7254 // Conditional-store of a long value. 7255 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7256 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7257 %{ 7258 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7259 effect(KILL oldval); 7260 7261 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7262 opcode(0x0F, 0xB1); 7263 ins_encode(lock_prefix, 7264 REX_reg_mem_wide(newval, mem), 7265 OpcP, OpcS, 7266 reg_mem(newval, mem)); 7267 ins_pipe(pipe_cmpxchg); 7268 %} 7269 7270 7271 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7272 instruct compareAndSwapP(rRegI res, 7273 memory mem_ptr, 7274 rax_RegP oldval, rRegP newval, 7275 rFlagsReg cr) 7276 %{ 7277 predicate(VM_Version::supports_cx8()); 7278 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7279 effect(KILL cr, KILL oldval); 7280 7281 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7282 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7283 "sete $res\n\t" 7284 "movzbl $res, $res" %} 7285 opcode(0x0F, 0xB1); 7286 ins_encode(lock_prefix, 7287 REX_reg_mem_wide(newval, mem_ptr), 7288 OpcP, OpcS, 7289 reg_mem(newval, mem_ptr), 7290 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7291 REX_reg_breg(res, res), // movzbl 7292 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7293 ins_pipe( pipe_cmpxchg ); 7294 %} 7295 7296 instruct compareAndSwapL(rRegI res, 7297 memory mem_ptr, 7298 rax_RegL oldval, rRegL newval, 7299 rFlagsReg cr) 7300 %{ 7301 predicate(VM_Version::supports_cx8()); 7302 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7303 effect(KILL cr, KILL oldval); 7304 7305 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7306 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7307 "sete $res\n\t" 7308 "movzbl $res, $res" %} 7309 opcode(0x0F, 0xB1); 7310 ins_encode(lock_prefix, 7311 REX_reg_mem_wide(newval, mem_ptr), 7312 OpcP, OpcS, 7313 reg_mem(newval, mem_ptr), 7314 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7315 REX_reg_breg(res, res), // movzbl 7316 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7317 ins_pipe( pipe_cmpxchg ); 7318 %} 7319 7320 instruct compareAndSwapI(rRegI res, 7321 memory mem_ptr, 7322 rax_RegI oldval, rRegI newval, 7323 rFlagsReg cr) 7324 %{ 7325 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7326 effect(KILL cr, KILL oldval); 7327 7328 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7329 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7330 "sete $res\n\t" 7331 "movzbl $res, $res" %} 7332 opcode(0x0F, 0xB1); 7333 ins_encode(lock_prefix, 7334 REX_reg_mem(newval, mem_ptr), 7335 OpcP, OpcS, 7336 reg_mem(newval, mem_ptr), 7337 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7338 REX_reg_breg(res, res), // movzbl 7339 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7340 ins_pipe( pipe_cmpxchg ); 7341 %} 7342 7343 7344 instruct compareAndSwapN(rRegI res, 7345 memory mem_ptr, 7346 rax_RegN oldval, rRegN newval, 7347 rFlagsReg cr) %{ 7348 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7349 effect(KILL cr, KILL oldval); 7350 7351 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7352 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7353 "sete $res\n\t" 7354 "movzbl $res, $res" %} 7355 opcode(0x0F, 0xB1); 7356 ins_encode(lock_prefix, 7357 REX_reg_mem(newval, mem_ptr), 7358 OpcP, OpcS, 7359 reg_mem(newval, mem_ptr), 7360 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7361 REX_reg_breg(res, res), // movzbl 7362 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7363 ins_pipe( pipe_cmpxchg ); 7364 %} 7365 7366 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7367 predicate(n->as_LoadStore()->result_not_used()); 7368 match(Set dummy (GetAndAddI mem add)); 7369 effect(KILL cr); 7370 format %{ "ADDL [$mem],$add" %} 7371 ins_encode %{ 7372 if (os::is_MP()) { __ lock(); } 7373 __ addl($mem$$Address, $add$$constant); 7374 %} 7375 ins_pipe( pipe_cmpxchg ); 7376 %} 7377 7378 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7379 match(Set newval (GetAndAddI mem newval)); 7380 effect(KILL cr); 7381 format %{ "XADDL [$mem],$newval" %} 7382 ins_encode %{ 7383 if (os::is_MP()) { __ lock(); } 7384 __ xaddl($mem$$Address, $newval$$Register); 7385 %} 7386 ins_pipe( pipe_cmpxchg ); 7387 %} 7388 7389 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7390 predicate(n->as_LoadStore()->result_not_used()); 7391 match(Set dummy (GetAndAddL mem add)); 7392 effect(KILL cr); 7393 format %{ "ADDQ [$mem],$add" %} 7394 ins_encode %{ 7395 if (os::is_MP()) { __ lock(); } 7396 __ addq($mem$$Address, $add$$constant); 7397 %} 7398 ins_pipe( pipe_cmpxchg ); 7399 %} 7400 7401 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7402 match(Set newval (GetAndAddL mem newval)); 7403 effect(KILL cr); 7404 format %{ "XADDQ [$mem],$newval" %} 7405 ins_encode %{ 7406 if (os::is_MP()) { __ lock(); } 7407 __ xaddq($mem$$Address, $newval$$Register); 7408 %} 7409 ins_pipe( pipe_cmpxchg ); 7410 %} 7411 7412 instruct xchgI( memory mem, rRegI newval) %{ 7413 match(Set newval (GetAndSetI mem newval)); 7414 format %{ "XCHGL $newval,[$mem]" %} 7415 ins_encode %{ 7416 __ xchgl($newval$$Register, $mem$$Address); 7417 %} 7418 ins_pipe( pipe_cmpxchg ); 7419 %} 7420 7421 instruct xchgL( memory mem, rRegL newval) %{ 7422 match(Set newval (GetAndSetL mem newval)); 7423 format %{ "XCHGL $newval,[$mem]" %} 7424 ins_encode %{ 7425 __ xchgq($newval$$Register, $mem$$Address); 7426 %} 7427 ins_pipe( pipe_cmpxchg ); 7428 %} 7429 7430 instruct xchgP( memory mem, rRegP newval) %{ 7431 match(Set newval (GetAndSetP mem newval)); 7432 format %{ "XCHGQ $newval,[$mem]" %} 7433 ins_encode %{ 7434 __ xchgq($newval$$Register, $mem$$Address); 7435 %} 7436 ins_pipe( pipe_cmpxchg ); 7437 %} 7438 7439 instruct xchgN( memory mem, rRegN newval) %{ 7440 match(Set newval (GetAndSetN mem newval)); 7441 format %{ "XCHGL $newval,$mem]" %} 7442 ins_encode %{ 7443 __ xchgl($newval$$Register, $mem$$Address); 7444 %} 7445 ins_pipe( pipe_cmpxchg ); 7446 %} 7447 7448 //----------Subtraction Instructions------------------------------------------- 7449 7450 // Integer Subtraction Instructions 7451 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7452 %{ 7453 match(Set dst (SubI dst src)); 7454 effect(KILL cr); 7455 7456 format %{ "subl $dst, $src\t# int" %} 7457 opcode(0x2B); 7458 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7459 ins_pipe(ialu_reg_reg); 7460 %} 7461 7462 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7463 %{ 7464 match(Set dst (SubI dst src)); 7465 effect(KILL cr); 7466 7467 format %{ "subl $dst, $src\t# int" %} 7468 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7469 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7470 ins_pipe(ialu_reg); 7471 %} 7472 7473 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7474 %{ 7475 match(Set dst (SubI dst (LoadI src))); 7476 effect(KILL cr); 7477 7478 ins_cost(125); 7479 format %{ "subl $dst, $src\t# int" %} 7480 opcode(0x2B); 7481 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7482 ins_pipe(ialu_reg_mem); 7483 %} 7484 7485 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7486 %{ 7487 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7488 effect(KILL cr); 7489 7490 ins_cost(150); 7491 format %{ "subl $dst, $src\t# int" %} 7492 opcode(0x29); /* Opcode 29 /r */ 7493 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7494 ins_pipe(ialu_mem_reg); 7495 %} 7496 7497 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7498 %{ 7499 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7500 effect(KILL cr); 7501 7502 ins_cost(125); // XXX 7503 format %{ "subl $dst, $src\t# int" %} 7504 opcode(0x81); /* Opcode 81 /5 id */ 7505 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7506 ins_pipe(ialu_mem_imm); 7507 %} 7508 7509 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7510 %{ 7511 match(Set dst (SubL dst src)); 7512 effect(KILL cr); 7513 7514 format %{ "subq $dst, $src\t# long" %} 7515 opcode(0x2B); 7516 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7517 ins_pipe(ialu_reg_reg); 7518 %} 7519 7520 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7521 %{ 7522 match(Set dst (SubL dst src)); 7523 effect(KILL cr); 7524 7525 format %{ "subq $dst, $src\t# long" %} 7526 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7527 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7528 ins_pipe(ialu_reg); 7529 %} 7530 7531 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7532 %{ 7533 match(Set dst (SubL dst (LoadL src))); 7534 effect(KILL cr); 7535 7536 ins_cost(125); 7537 format %{ "subq $dst, $src\t# long" %} 7538 opcode(0x2B); 7539 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7540 ins_pipe(ialu_reg_mem); 7541 %} 7542 7543 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7544 %{ 7545 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7546 effect(KILL cr); 7547 7548 ins_cost(150); 7549 format %{ "subq $dst, $src\t# long" %} 7550 opcode(0x29); /* Opcode 29 /r */ 7551 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7552 ins_pipe(ialu_mem_reg); 7553 %} 7554 7555 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7556 %{ 7557 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7558 effect(KILL cr); 7559 7560 ins_cost(125); // XXX 7561 format %{ "subq $dst, $src\t# long" %} 7562 opcode(0x81); /* Opcode 81 /5 id */ 7563 ins_encode(REX_mem_wide(dst), 7564 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7565 ins_pipe(ialu_mem_imm); 7566 %} 7567 7568 // Subtract from a pointer 7569 // XXX hmpf??? 7570 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7571 %{ 7572 match(Set dst (AddP dst (SubI zero src))); 7573 effect(KILL cr); 7574 7575 format %{ "subq $dst, $src\t# ptr - int" %} 7576 opcode(0x2B); 7577 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7578 ins_pipe(ialu_reg_reg); 7579 %} 7580 7581 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7582 %{ 7583 match(Set dst (SubI zero dst)); 7584 effect(KILL cr); 7585 7586 format %{ "negl $dst\t# int" %} 7587 opcode(0xF7, 0x03); // Opcode F7 /3 7588 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7589 ins_pipe(ialu_reg); 7590 %} 7591 7592 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7593 %{ 7594 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7595 effect(KILL cr); 7596 7597 format %{ "negl $dst\t# int" %} 7598 opcode(0xF7, 0x03); // Opcode F7 /3 7599 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7600 ins_pipe(ialu_reg); 7601 %} 7602 7603 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7604 %{ 7605 match(Set dst (SubL zero dst)); 7606 effect(KILL cr); 7607 7608 format %{ "negq $dst\t# long" %} 7609 opcode(0xF7, 0x03); // Opcode F7 /3 7610 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7611 ins_pipe(ialu_reg); 7612 %} 7613 7614 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7615 %{ 7616 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7617 effect(KILL cr); 7618 7619 format %{ "negq $dst\t# long" %} 7620 opcode(0xF7, 0x03); // Opcode F7 /3 7621 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7622 ins_pipe(ialu_reg); 7623 %} 7624 7625 //----------Multiplication/Division Instructions------------------------------- 7626 // Integer Multiplication Instructions 7627 // Multiply Register 7628 7629 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7630 %{ 7631 match(Set dst (MulI dst src)); 7632 effect(KILL cr); 7633 7634 ins_cost(300); 7635 format %{ "imull $dst, $src\t# int" %} 7636 opcode(0x0F, 0xAF); 7637 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7638 ins_pipe(ialu_reg_reg_alu0); 7639 %} 7640 7641 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7642 %{ 7643 match(Set dst (MulI src imm)); 7644 effect(KILL cr); 7645 7646 ins_cost(300); 7647 format %{ "imull $dst, $src, $imm\t# int" %} 7648 opcode(0x69); /* 69 /r id */ 7649 ins_encode(REX_reg_reg(dst, src), 7650 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7651 ins_pipe(ialu_reg_reg_alu0); 7652 %} 7653 7654 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7655 %{ 7656 match(Set dst (MulI dst (LoadI src))); 7657 effect(KILL cr); 7658 7659 ins_cost(350); 7660 format %{ "imull $dst, $src\t# int" %} 7661 opcode(0x0F, 0xAF); 7662 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7663 ins_pipe(ialu_reg_mem_alu0); 7664 %} 7665 7666 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7667 %{ 7668 match(Set dst (MulI (LoadI src) imm)); 7669 effect(KILL cr); 7670 7671 ins_cost(300); 7672 format %{ "imull $dst, $src, $imm\t# int" %} 7673 opcode(0x69); /* 69 /r id */ 7674 ins_encode(REX_reg_mem(dst, src), 7675 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7676 ins_pipe(ialu_reg_mem_alu0); 7677 %} 7678 7679 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7680 %{ 7681 match(Set dst (MulL dst src)); 7682 effect(KILL cr); 7683 7684 ins_cost(300); 7685 format %{ "imulq $dst, $src\t# long" %} 7686 opcode(0x0F, 0xAF); 7687 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7688 ins_pipe(ialu_reg_reg_alu0); 7689 %} 7690 7691 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7692 %{ 7693 match(Set dst (MulL src imm)); 7694 effect(KILL cr); 7695 7696 ins_cost(300); 7697 format %{ "imulq $dst, $src, $imm\t# long" %} 7698 opcode(0x69); /* 69 /r id */ 7699 ins_encode(REX_reg_reg_wide(dst, src), 7700 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7701 ins_pipe(ialu_reg_reg_alu0); 7702 %} 7703 7704 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7705 %{ 7706 match(Set dst (MulL dst (LoadL src))); 7707 effect(KILL cr); 7708 7709 ins_cost(350); 7710 format %{ "imulq $dst, $src\t# long" %} 7711 opcode(0x0F, 0xAF); 7712 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7713 ins_pipe(ialu_reg_mem_alu0); 7714 %} 7715 7716 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7717 %{ 7718 match(Set dst (MulL (LoadL src) imm)); 7719 effect(KILL cr); 7720 7721 ins_cost(300); 7722 format %{ "imulq $dst, $src, $imm\t# long" %} 7723 opcode(0x69); /* 69 /r id */ 7724 ins_encode(REX_reg_mem_wide(dst, src), 7725 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7726 ins_pipe(ialu_reg_mem_alu0); 7727 %} 7728 7729 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7730 %{ 7731 match(Set dst (MulHiL src rax)); 7732 effect(USE_KILL rax, KILL cr); 7733 7734 ins_cost(300); 7735 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7736 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7737 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7738 ins_pipe(ialu_reg_reg_alu0); 7739 %} 7740 7741 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7742 rFlagsReg cr) 7743 %{ 7744 match(Set rax (DivI rax div)); 7745 effect(KILL rdx, KILL cr); 7746 7747 ins_cost(30*100+10*100); // XXX 7748 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7749 "jne,s normal\n\t" 7750 "xorl rdx, rdx\n\t" 7751 "cmpl $div, -1\n\t" 7752 "je,s done\n" 7753 "normal: cdql\n\t" 7754 "idivl $div\n" 7755 "done:" %} 7756 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7757 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7758 ins_pipe(ialu_reg_reg_alu0); 7759 %} 7760 7761 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7762 rFlagsReg cr) 7763 %{ 7764 match(Set rax (DivL rax div)); 7765 effect(KILL rdx, KILL cr); 7766 7767 ins_cost(30*100+10*100); // XXX 7768 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7769 "cmpq rax, rdx\n\t" 7770 "jne,s normal\n\t" 7771 "xorl rdx, rdx\n\t" 7772 "cmpq $div, -1\n\t" 7773 "je,s done\n" 7774 "normal: cdqq\n\t" 7775 "idivq $div\n" 7776 "done:" %} 7777 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7778 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7779 ins_pipe(ialu_reg_reg_alu0); 7780 %} 7781 7782 // Integer DIVMOD with Register, both quotient and mod results 7783 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7784 rFlagsReg cr) 7785 %{ 7786 match(DivModI rax div); 7787 effect(KILL cr); 7788 7789 ins_cost(30*100+10*100); // XXX 7790 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7791 "jne,s normal\n\t" 7792 "xorl rdx, rdx\n\t" 7793 "cmpl $div, -1\n\t" 7794 "je,s done\n" 7795 "normal: cdql\n\t" 7796 "idivl $div\n" 7797 "done:" %} 7798 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7799 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7800 ins_pipe(pipe_slow); 7801 %} 7802 7803 // Long DIVMOD with Register, both quotient and mod results 7804 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7805 rFlagsReg cr) 7806 %{ 7807 match(DivModL rax div); 7808 effect(KILL cr); 7809 7810 ins_cost(30*100+10*100); // XXX 7811 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7812 "cmpq rax, rdx\n\t" 7813 "jne,s normal\n\t" 7814 "xorl rdx, rdx\n\t" 7815 "cmpq $div, -1\n\t" 7816 "je,s done\n" 7817 "normal: cdqq\n\t" 7818 "idivq $div\n" 7819 "done:" %} 7820 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7821 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7822 ins_pipe(pipe_slow); 7823 %} 7824 7825 //----------- DivL-By-Constant-Expansions-------------------------------------- 7826 // DivI cases are handled by the compiler 7827 7828 // Magic constant, reciprocal of 10 7829 instruct loadConL_0x6666666666666667(rRegL dst) 7830 %{ 7831 effect(DEF dst); 7832 7833 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 7834 ins_encode(load_immL(dst, 0x6666666666666667)); 7835 ins_pipe(ialu_reg); 7836 %} 7837 7838 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7839 %{ 7840 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 7841 7842 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 7843 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7844 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7845 ins_pipe(ialu_reg_reg_alu0); 7846 %} 7847 7848 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 7849 %{ 7850 effect(USE_DEF dst, KILL cr); 7851 7852 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 7853 opcode(0xC1, 0x7); /* C1 /7 ib */ 7854 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 7855 ins_pipe(ialu_reg); 7856 %} 7857 7858 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 7859 %{ 7860 effect(USE_DEF dst, KILL cr); 7861 7862 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 7863 opcode(0xC1, 0x7); /* C1 /7 ib */ 7864 ins_encode(reg_opc_imm_wide(dst, 0x2)); 7865 ins_pipe(ialu_reg); 7866 %} 7867 7868 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 7869 %{ 7870 match(Set dst (DivL src div)); 7871 7872 ins_cost((5+8)*100); 7873 expand %{ 7874 rax_RegL rax; // Killed temp 7875 rFlagsReg cr; // Killed 7876 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 7877 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 7878 sarL_rReg_63(src, cr); // sarq src, 63 7879 sarL_rReg_2(dst, cr); // sarq rdx, 2 7880 subL_rReg(dst, src, cr); // subl rdx, src 7881 %} 7882 %} 7883 7884 //----------------------------------------------------------------------------- 7885 7886 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7887 rFlagsReg cr) 7888 %{ 7889 match(Set rdx (ModI rax div)); 7890 effect(KILL rax, KILL cr); 7891 7892 ins_cost(300); // XXX 7893 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7894 "jne,s normal\n\t" 7895 "xorl rdx, rdx\n\t" 7896 "cmpl $div, -1\n\t" 7897 "je,s done\n" 7898 "normal: cdql\n\t" 7899 "idivl $div\n" 7900 "done:" %} 7901 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7902 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7903 ins_pipe(ialu_reg_reg_alu0); 7904 %} 7905 7906 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7907 rFlagsReg cr) 7908 %{ 7909 match(Set rdx (ModL rax div)); 7910 effect(KILL rax, KILL cr); 7911 7912 ins_cost(300); // XXX 7913 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 7914 "cmpq rax, rdx\n\t" 7915 "jne,s normal\n\t" 7916 "xorl rdx, rdx\n\t" 7917 "cmpq $div, -1\n\t" 7918 "je,s done\n" 7919 "normal: cdqq\n\t" 7920 "idivq $div\n" 7921 "done:" %} 7922 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7923 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7924 ins_pipe(ialu_reg_reg_alu0); 7925 %} 7926 7927 // Integer Shift Instructions 7928 // Shift Left by one 7929 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7930 %{ 7931 match(Set dst (LShiftI dst shift)); 7932 effect(KILL cr); 7933 7934 format %{ "sall $dst, $shift" %} 7935 opcode(0xD1, 0x4); /* D1 /4 */ 7936 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7937 ins_pipe(ialu_reg); 7938 %} 7939 7940 // Shift Left by one 7941 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7942 %{ 7943 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7944 effect(KILL cr); 7945 7946 format %{ "sall $dst, $shift\t" %} 7947 opcode(0xD1, 0x4); /* D1 /4 */ 7948 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7949 ins_pipe(ialu_mem_imm); 7950 %} 7951 7952 // Shift Left by 8-bit immediate 7953 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7954 %{ 7955 match(Set dst (LShiftI dst shift)); 7956 effect(KILL cr); 7957 7958 format %{ "sall $dst, $shift" %} 7959 opcode(0xC1, 0x4); /* C1 /4 ib */ 7960 ins_encode(reg_opc_imm(dst, shift)); 7961 ins_pipe(ialu_reg); 7962 %} 7963 7964 // Shift Left by 8-bit immediate 7965 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7966 %{ 7967 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7968 effect(KILL cr); 7969 7970 format %{ "sall $dst, $shift" %} 7971 opcode(0xC1, 0x4); /* C1 /4 ib */ 7972 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 7973 ins_pipe(ialu_mem_imm); 7974 %} 7975 7976 // Shift Left by variable 7977 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7978 %{ 7979 match(Set dst (LShiftI dst shift)); 7980 effect(KILL cr); 7981 7982 format %{ "sall $dst, $shift" %} 7983 opcode(0xD3, 0x4); /* D3 /4 */ 7984 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7985 ins_pipe(ialu_reg_reg); 7986 %} 7987 7988 // Shift Left by variable 7989 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 7990 %{ 7991 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7992 effect(KILL cr); 7993 7994 format %{ "sall $dst, $shift" %} 7995 opcode(0xD3, 0x4); /* D3 /4 */ 7996 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7997 ins_pipe(ialu_mem_reg); 7998 %} 7999 8000 // Arithmetic shift right by one 8001 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8002 %{ 8003 match(Set dst (RShiftI dst shift)); 8004 effect(KILL cr); 8005 8006 format %{ "sarl $dst, $shift" %} 8007 opcode(0xD1, 0x7); /* D1 /7 */ 8008 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8009 ins_pipe(ialu_reg); 8010 %} 8011 8012 // Arithmetic shift right by one 8013 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8014 %{ 8015 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8016 effect(KILL cr); 8017 8018 format %{ "sarl $dst, $shift" %} 8019 opcode(0xD1, 0x7); /* D1 /7 */ 8020 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8021 ins_pipe(ialu_mem_imm); 8022 %} 8023 8024 // Arithmetic Shift Right by 8-bit immediate 8025 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8026 %{ 8027 match(Set dst (RShiftI dst shift)); 8028 effect(KILL cr); 8029 8030 format %{ "sarl $dst, $shift" %} 8031 opcode(0xC1, 0x7); /* C1 /7 ib */ 8032 ins_encode(reg_opc_imm(dst, shift)); 8033 ins_pipe(ialu_mem_imm); 8034 %} 8035 8036 // Arithmetic Shift Right by 8-bit immediate 8037 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8038 %{ 8039 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8040 effect(KILL cr); 8041 8042 format %{ "sarl $dst, $shift" %} 8043 opcode(0xC1, 0x7); /* C1 /7 ib */ 8044 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8045 ins_pipe(ialu_mem_imm); 8046 %} 8047 8048 // Arithmetic Shift Right by variable 8049 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8050 %{ 8051 match(Set dst (RShiftI dst shift)); 8052 effect(KILL cr); 8053 8054 format %{ "sarl $dst, $shift" %} 8055 opcode(0xD3, 0x7); /* D3 /7 */ 8056 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8057 ins_pipe(ialu_reg_reg); 8058 %} 8059 8060 // Arithmetic Shift Right by variable 8061 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8062 %{ 8063 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8064 effect(KILL cr); 8065 8066 format %{ "sarl $dst, $shift" %} 8067 opcode(0xD3, 0x7); /* D3 /7 */ 8068 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8069 ins_pipe(ialu_mem_reg); 8070 %} 8071 8072 // Logical shift right by one 8073 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8074 %{ 8075 match(Set dst (URShiftI dst shift)); 8076 effect(KILL cr); 8077 8078 format %{ "shrl $dst, $shift" %} 8079 opcode(0xD1, 0x5); /* D1 /5 */ 8080 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8081 ins_pipe(ialu_reg); 8082 %} 8083 8084 // Logical shift right by one 8085 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8086 %{ 8087 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8088 effect(KILL cr); 8089 8090 format %{ "shrl $dst, $shift" %} 8091 opcode(0xD1, 0x5); /* D1 /5 */ 8092 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8093 ins_pipe(ialu_mem_imm); 8094 %} 8095 8096 // Logical Shift Right by 8-bit immediate 8097 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8098 %{ 8099 match(Set dst (URShiftI dst shift)); 8100 effect(KILL cr); 8101 8102 format %{ "shrl $dst, $shift" %} 8103 opcode(0xC1, 0x5); /* C1 /5 ib */ 8104 ins_encode(reg_opc_imm(dst, shift)); 8105 ins_pipe(ialu_reg); 8106 %} 8107 8108 // Logical Shift Right by 8-bit immediate 8109 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8110 %{ 8111 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8112 effect(KILL cr); 8113 8114 format %{ "shrl $dst, $shift" %} 8115 opcode(0xC1, 0x5); /* C1 /5 ib */ 8116 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8117 ins_pipe(ialu_mem_imm); 8118 %} 8119 8120 // Logical Shift Right by variable 8121 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8122 %{ 8123 match(Set dst (URShiftI dst shift)); 8124 effect(KILL cr); 8125 8126 format %{ "shrl $dst, $shift" %} 8127 opcode(0xD3, 0x5); /* D3 /5 */ 8128 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8129 ins_pipe(ialu_reg_reg); 8130 %} 8131 8132 // Logical Shift Right by variable 8133 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8134 %{ 8135 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8136 effect(KILL cr); 8137 8138 format %{ "shrl $dst, $shift" %} 8139 opcode(0xD3, 0x5); /* D3 /5 */ 8140 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8141 ins_pipe(ialu_mem_reg); 8142 %} 8143 8144 // Long Shift Instructions 8145 // Shift Left by one 8146 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8147 %{ 8148 match(Set dst (LShiftL dst shift)); 8149 effect(KILL cr); 8150 8151 format %{ "salq $dst, $shift" %} 8152 opcode(0xD1, 0x4); /* D1 /4 */ 8153 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8154 ins_pipe(ialu_reg); 8155 %} 8156 8157 // Shift Left by one 8158 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8159 %{ 8160 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8161 effect(KILL cr); 8162 8163 format %{ "salq $dst, $shift" %} 8164 opcode(0xD1, 0x4); /* D1 /4 */ 8165 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8166 ins_pipe(ialu_mem_imm); 8167 %} 8168 8169 // Shift Left by 8-bit immediate 8170 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8171 %{ 8172 match(Set dst (LShiftL dst shift)); 8173 effect(KILL cr); 8174 8175 format %{ "salq $dst, $shift" %} 8176 opcode(0xC1, 0x4); /* C1 /4 ib */ 8177 ins_encode(reg_opc_imm_wide(dst, shift)); 8178 ins_pipe(ialu_reg); 8179 %} 8180 8181 // Shift Left by 8-bit immediate 8182 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8183 %{ 8184 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8185 effect(KILL cr); 8186 8187 format %{ "salq $dst, $shift" %} 8188 opcode(0xC1, 0x4); /* C1 /4 ib */ 8189 ins_encode(REX_mem_wide(dst), OpcP, 8190 RM_opc_mem(secondary, dst), Con8or32(shift)); 8191 ins_pipe(ialu_mem_imm); 8192 %} 8193 8194 // Shift Left by variable 8195 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8196 %{ 8197 match(Set dst (LShiftL dst shift)); 8198 effect(KILL cr); 8199 8200 format %{ "salq $dst, $shift" %} 8201 opcode(0xD3, 0x4); /* D3 /4 */ 8202 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8203 ins_pipe(ialu_reg_reg); 8204 %} 8205 8206 // Shift Left by variable 8207 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8208 %{ 8209 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8210 effect(KILL cr); 8211 8212 format %{ "salq $dst, $shift" %} 8213 opcode(0xD3, 0x4); /* D3 /4 */ 8214 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8215 ins_pipe(ialu_mem_reg); 8216 %} 8217 8218 // Arithmetic shift right by one 8219 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8220 %{ 8221 match(Set dst (RShiftL dst shift)); 8222 effect(KILL cr); 8223 8224 format %{ "sarq $dst, $shift" %} 8225 opcode(0xD1, 0x7); /* D1 /7 */ 8226 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8227 ins_pipe(ialu_reg); 8228 %} 8229 8230 // Arithmetic shift right by one 8231 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8232 %{ 8233 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8234 effect(KILL cr); 8235 8236 format %{ "sarq $dst, $shift" %} 8237 opcode(0xD1, 0x7); /* D1 /7 */ 8238 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8239 ins_pipe(ialu_mem_imm); 8240 %} 8241 8242 // Arithmetic Shift Right by 8-bit immediate 8243 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8244 %{ 8245 match(Set dst (RShiftL dst shift)); 8246 effect(KILL cr); 8247 8248 format %{ "sarq $dst, $shift" %} 8249 opcode(0xC1, 0x7); /* C1 /7 ib */ 8250 ins_encode(reg_opc_imm_wide(dst, shift)); 8251 ins_pipe(ialu_mem_imm); 8252 %} 8253 8254 // Arithmetic Shift Right by 8-bit immediate 8255 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8256 %{ 8257 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8258 effect(KILL cr); 8259 8260 format %{ "sarq $dst, $shift" %} 8261 opcode(0xC1, 0x7); /* C1 /7 ib */ 8262 ins_encode(REX_mem_wide(dst), OpcP, 8263 RM_opc_mem(secondary, dst), Con8or32(shift)); 8264 ins_pipe(ialu_mem_imm); 8265 %} 8266 8267 // Arithmetic Shift Right by variable 8268 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8269 %{ 8270 match(Set dst (RShiftL dst shift)); 8271 effect(KILL cr); 8272 8273 format %{ "sarq $dst, $shift" %} 8274 opcode(0xD3, 0x7); /* D3 /7 */ 8275 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8276 ins_pipe(ialu_reg_reg); 8277 %} 8278 8279 // Arithmetic Shift Right by variable 8280 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8281 %{ 8282 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8283 effect(KILL cr); 8284 8285 format %{ "sarq $dst, $shift" %} 8286 opcode(0xD3, 0x7); /* D3 /7 */ 8287 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8288 ins_pipe(ialu_mem_reg); 8289 %} 8290 8291 // Logical shift right by one 8292 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8293 %{ 8294 match(Set dst (URShiftL dst shift)); 8295 effect(KILL cr); 8296 8297 format %{ "shrq $dst, $shift" %} 8298 opcode(0xD1, 0x5); /* D1 /5 */ 8299 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8300 ins_pipe(ialu_reg); 8301 %} 8302 8303 // Logical shift right by one 8304 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8305 %{ 8306 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8307 effect(KILL cr); 8308 8309 format %{ "shrq $dst, $shift" %} 8310 opcode(0xD1, 0x5); /* D1 /5 */ 8311 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8312 ins_pipe(ialu_mem_imm); 8313 %} 8314 8315 // Logical Shift Right by 8-bit immediate 8316 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8317 %{ 8318 match(Set dst (URShiftL dst shift)); 8319 effect(KILL cr); 8320 8321 format %{ "shrq $dst, $shift" %} 8322 opcode(0xC1, 0x5); /* C1 /5 ib */ 8323 ins_encode(reg_opc_imm_wide(dst, shift)); 8324 ins_pipe(ialu_reg); 8325 %} 8326 8327 8328 // Logical Shift Right by 8-bit immediate 8329 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8330 %{ 8331 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8332 effect(KILL cr); 8333 8334 format %{ "shrq $dst, $shift" %} 8335 opcode(0xC1, 0x5); /* C1 /5 ib */ 8336 ins_encode(REX_mem_wide(dst), OpcP, 8337 RM_opc_mem(secondary, dst), Con8or32(shift)); 8338 ins_pipe(ialu_mem_imm); 8339 %} 8340 8341 // Logical Shift Right by variable 8342 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8343 %{ 8344 match(Set dst (URShiftL dst shift)); 8345 effect(KILL cr); 8346 8347 format %{ "shrq $dst, $shift" %} 8348 opcode(0xD3, 0x5); /* D3 /5 */ 8349 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8350 ins_pipe(ialu_reg_reg); 8351 %} 8352 8353 // Logical Shift Right by variable 8354 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8355 %{ 8356 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8357 effect(KILL cr); 8358 8359 format %{ "shrq $dst, $shift" %} 8360 opcode(0xD3, 0x5); /* D3 /5 */ 8361 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8362 ins_pipe(ialu_mem_reg); 8363 %} 8364 8365 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8366 // This idiom is used by the compiler for the i2b bytecode. 8367 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8368 %{ 8369 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8370 8371 format %{ "movsbl $dst, $src\t# i2b" %} 8372 opcode(0x0F, 0xBE); 8373 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8374 ins_pipe(ialu_reg_reg); 8375 %} 8376 8377 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8378 // This idiom is used by the compiler the i2s bytecode. 8379 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8380 %{ 8381 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8382 8383 format %{ "movswl $dst, $src\t# i2s" %} 8384 opcode(0x0F, 0xBF); 8385 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8386 ins_pipe(ialu_reg_reg); 8387 %} 8388 8389 // ROL/ROR instructions 8390 8391 // ROL expand 8392 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8393 effect(KILL cr, USE_DEF dst); 8394 8395 format %{ "roll $dst" %} 8396 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8397 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8398 ins_pipe(ialu_reg); 8399 %} 8400 8401 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8402 effect(USE_DEF dst, USE shift, KILL cr); 8403 8404 format %{ "roll $dst, $shift" %} 8405 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8406 ins_encode( reg_opc_imm(dst, shift) ); 8407 ins_pipe(ialu_reg); 8408 %} 8409 8410 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8411 %{ 8412 effect(USE_DEF dst, USE shift, KILL cr); 8413 8414 format %{ "roll $dst, $shift" %} 8415 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8416 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8417 ins_pipe(ialu_reg_reg); 8418 %} 8419 // end of ROL expand 8420 8421 // Rotate Left by one 8422 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8423 %{ 8424 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8425 8426 expand %{ 8427 rolI_rReg_imm1(dst, cr); 8428 %} 8429 %} 8430 8431 // Rotate Left by 8-bit immediate 8432 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8433 %{ 8434 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8435 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8436 8437 expand %{ 8438 rolI_rReg_imm8(dst, lshift, cr); 8439 %} 8440 %} 8441 8442 // Rotate Left by variable 8443 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8444 %{ 8445 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8446 8447 expand %{ 8448 rolI_rReg_CL(dst, shift, cr); 8449 %} 8450 %} 8451 8452 // Rotate Left by variable 8453 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8454 %{ 8455 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8456 8457 expand %{ 8458 rolI_rReg_CL(dst, shift, cr); 8459 %} 8460 %} 8461 8462 // ROR expand 8463 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8464 %{ 8465 effect(USE_DEF dst, KILL cr); 8466 8467 format %{ "rorl $dst" %} 8468 opcode(0xD1, 0x1); /* D1 /1 */ 8469 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8470 ins_pipe(ialu_reg); 8471 %} 8472 8473 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8474 %{ 8475 effect(USE_DEF dst, USE shift, KILL cr); 8476 8477 format %{ "rorl $dst, $shift" %} 8478 opcode(0xC1, 0x1); /* C1 /1 ib */ 8479 ins_encode(reg_opc_imm(dst, shift)); 8480 ins_pipe(ialu_reg); 8481 %} 8482 8483 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8484 %{ 8485 effect(USE_DEF dst, USE shift, KILL cr); 8486 8487 format %{ "rorl $dst, $shift" %} 8488 opcode(0xD3, 0x1); /* D3 /1 */ 8489 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8490 ins_pipe(ialu_reg_reg); 8491 %} 8492 // end of ROR expand 8493 8494 // Rotate Right by one 8495 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8496 %{ 8497 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8498 8499 expand %{ 8500 rorI_rReg_imm1(dst, cr); 8501 %} 8502 %} 8503 8504 // Rotate Right by 8-bit immediate 8505 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8506 %{ 8507 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8508 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8509 8510 expand %{ 8511 rorI_rReg_imm8(dst, rshift, cr); 8512 %} 8513 %} 8514 8515 // Rotate Right by variable 8516 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8517 %{ 8518 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8519 8520 expand %{ 8521 rorI_rReg_CL(dst, shift, cr); 8522 %} 8523 %} 8524 8525 // Rotate Right by variable 8526 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8527 %{ 8528 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8529 8530 expand %{ 8531 rorI_rReg_CL(dst, shift, cr); 8532 %} 8533 %} 8534 8535 // for long rotate 8536 // ROL expand 8537 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8538 effect(USE_DEF dst, KILL cr); 8539 8540 format %{ "rolq $dst" %} 8541 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8542 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8543 ins_pipe(ialu_reg); 8544 %} 8545 8546 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8547 effect(USE_DEF dst, USE shift, KILL cr); 8548 8549 format %{ "rolq $dst, $shift" %} 8550 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8551 ins_encode( reg_opc_imm_wide(dst, shift) ); 8552 ins_pipe(ialu_reg); 8553 %} 8554 8555 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8556 %{ 8557 effect(USE_DEF dst, USE shift, KILL cr); 8558 8559 format %{ "rolq $dst, $shift" %} 8560 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8561 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8562 ins_pipe(ialu_reg_reg); 8563 %} 8564 // end of ROL expand 8565 8566 // Rotate Left by one 8567 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8568 %{ 8569 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8570 8571 expand %{ 8572 rolL_rReg_imm1(dst, cr); 8573 %} 8574 %} 8575 8576 // Rotate Left by 8-bit immediate 8577 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8578 %{ 8579 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8580 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8581 8582 expand %{ 8583 rolL_rReg_imm8(dst, lshift, cr); 8584 %} 8585 %} 8586 8587 // Rotate Left by variable 8588 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8589 %{ 8590 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8591 8592 expand %{ 8593 rolL_rReg_CL(dst, shift, cr); 8594 %} 8595 %} 8596 8597 // Rotate Left by variable 8598 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8599 %{ 8600 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8601 8602 expand %{ 8603 rolL_rReg_CL(dst, shift, cr); 8604 %} 8605 %} 8606 8607 // ROR expand 8608 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8609 %{ 8610 effect(USE_DEF dst, KILL cr); 8611 8612 format %{ "rorq $dst" %} 8613 opcode(0xD1, 0x1); /* D1 /1 */ 8614 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8615 ins_pipe(ialu_reg); 8616 %} 8617 8618 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8619 %{ 8620 effect(USE_DEF dst, USE shift, KILL cr); 8621 8622 format %{ "rorq $dst, $shift" %} 8623 opcode(0xC1, 0x1); /* C1 /1 ib */ 8624 ins_encode(reg_opc_imm_wide(dst, shift)); 8625 ins_pipe(ialu_reg); 8626 %} 8627 8628 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8629 %{ 8630 effect(USE_DEF dst, USE shift, KILL cr); 8631 8632 format %{ "rorq $dst, $shift" %} 8633 opcode(0xD3, 0x1); /* D3 /1 */ 8634 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8635 ins_pipe(ialu_reg_reg); 8636 %} 8637 // end of ROR expand 8638 8639 // Rotate Right by one 8640 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8641 %{ 8642 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8643 8644 expand %{ 8645 rorL_rReg_imm1(dst, cr); 8646 %} 8647 %} 8648 8649 // Rotate Right by 8-bit immediate 8650 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8651 %{ 8652 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8653 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8654 8655 expand %{ 8656 rorL_rReg_imm8(dst, rshift, cr); 8657 %} 8658 %} 8659 8660 // Rotate Right by variable 8661 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8662 %{ 8663 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8664 8665 expand %{ 8666 rorL_rReg_CL(dst, shift, cr); 8667 %} 8668 %} 8669 8670 // Rotate Right by variable 8671 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8672 %{ 8673 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8674 8675 expand %{ 8676 rorL_rReg_CL(dst, shift, cr); 8677 %} 8678 %} 8679 8680 // Logical Instructions 8681 8682 // Integer Logical Instructions 8683 8684 // And Instructions 8685 // And Register with Register 8686 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8687 %{ 8688 match(Set dst (AndI dst src)); 8689 effect(KILL cr); 8690 8691 format %{ "andl $dst, $src\t# int" %} 8692 opcode(0x23); 8693 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8694 ins_pipe(ialu_reg_reg); 8695 %} 8696 8697 // And Register with Immediate 255 8698 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 8699 %{ 8700 match(Set dst (AndI dst src)); 8701 8702 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 8703 opcode(0x0F, 0xB6); 8704 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8705 ins_pipe(ialu_reg); 8706 %} 8707 8708 // And Register with Immediate 255 and promote to long 8709 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8710 %{ 8711 match(Set dst (ConvI2L (AndI src mask))); 8712 8713 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8714 opcode(0x0F, 0xB6); 8715 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8716 ins_pipe(ialu_reg); 8717 %} 8718 8719 // And Register with Immediate 65535 8720 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 8721 %{ 8722 match(Set dst (AndI dst src)); 8723 8724 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 8725 opcode(0x0F, 0xB7); 8726 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8727 ins_pipe(ialu_reg); 8728 %} 8729 8730 // And Register with Immediate 65535 and promote to long 8731 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8732 %{ 8733 match(Set dst (ConvI2L (AndI src mask))); 8734 8735 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8736 opcode(0x0F, 0xB7); 8737 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8738 ins_pipe(ialu_reg); 8739 %} 8740 8741 // And Register with Immediate 8742 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8743 %{ 8744 match(Set dst (AndI dst src)); 8745 effect(KILL cr); 8746 8747 format %{ "andl $dst, $src\t# int" %} 8748 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8749 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8750 ins_pipe(ialu_reg); 8751 %} 8752 8753 // And Register with Memory 8754 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8755 %{ 8756 match(Set dst (AndI dst (LoadI src))); 8757 effect(KILL cr); 8758 8759 ins_cost(125); 8760 format %{ "andl $dst, $src\t# int" %} 8761 opcode(0x23); 8762 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8763 ins_pipe(ialu_reg_mem); 8764 %} 8765 8766 // And Memory with Register 8767 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8768 %{ 8769 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8770 effect(KILL cr); 8771 8772 ins_cost(150); 8773 format %{ "andl $dst, $src\t# int" %} 8774 opcode(0x21); /* Opcode 21 /r */ 8775 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8776 ins_pipe(ialu_mem_reg); 8777 %} 8778 8779 // And Memory with Immediate 8780 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8781 %{ 8782 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8783 effect(KILL cr); 8784 8785 ins_cost(125); 8786 format %{ "andl $dst, $src\t# int" %} 8787 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 8788 ins_encode(REX_mem(dst), OpcSE(src), 8789 RM_opc_mem(secondary, dst), Con8or32(src)); 8790 ins_pipe(ialu_mem_imm); 8791 %} 8792 8793 // BMI1 instructions 8794 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8795 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8796 predicate(UseBMI1Instructions); 8797 effect(KILL cr); 8798 8799 ins_cost(125); 8800 format %{ "andnl $dst, $src1, $src2" %} 8801 8802 ins_encode %{ 8803 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8804 %} 8805 ins_pipe(ialu_reg_mem); 8806 %} 8807 8808 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8809 match(Set dst (AndI (XorI src1 minus_1) src2)); 8810 predicate(UseBMI1Instructions); 8811 effect(KILL cr); 8812 8813 format %{ "andnl $dst, $src1, $src2" %} 8814 8815 ins_encode %{ 8816 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8817 %} 8818 ins_pipe(ialu_reg); 8819 %} 8820 8821 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 8822 match(Set dst (AndI (SubI imm_zero src) src)); 8823 predicate(UseBMI1Instructions); 8824 effect(KILL cr); 8825 8826 format %{ "blsil $dst, $src" %} 8827 8828 ins_encode %{ 8829 __ blsil($dst$$Register, $src$$Register); 8830 %} 8831 ins_pipe(ialu_reg); 8832 %} 8833 8834 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 8835 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 8836 predicate(UseBMI1Instructions); 8837 effect(KILL cr); 8838 8839 ins_cost(125); 8840 format %{ "blsil $dst, $src" %} 8841 8842 ins_encode %{ 8843 __ blsil($dst$$Register, $src$$Address); 8844 %} 8845 ins_pipe(ialu_reg_mem); 8846 %} 8847 8848 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8849 %{ 8850 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8851 predicate(UseBMI1Instructions); 8852 effect(KILL cr); 8853 8854 ins_cost(125); 8855 format %{ "blsmskl $dst, $src" %} 8856 8857 ins_encode %{ 8858 __ blsmskl($dst$$Register, $src$$Address); 8859 %} 8860 ins_pipe(ialu_reg_mem); 8861 %} 8862 8863 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8864 %{ 8865 match(Set dst (XorI (AddI src minus_1) src)); 8866 predicate(UseBMI1Instructions); 8867 effect(KILL cr); 8868 8869 format %{ "blsmskl $dst, $src" %} 8870 8871 ins_encode %{ 8872 __ blsmskl($dst$$Register, $src$$Register); 8873 %} 8874 8875 ins_pipe(ialu_reg); 8876 %} 8877 8878 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8879 %{ 8880 match(Set dst (AndI (AddI src minus_1) src) ); 8881 predicate(UseBMI1Instructions); 8882 effect(KILL cr); 8883 8884 format %{ "blsrl $dst, $src" %} 8885 8886 ins_encode %{ 8887 __ blsrl($dst$$Register, $src$$Register); 8888 %} 8889 8890 ins_pipe(ialu_reg_mem); 8891 %} 8892 8893 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8894 %{ 8895 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8896 predicate(UseBMI1Instructions); 8897 effect(KILL cr); 8898 8899 ins_cost(125); 8900 format %{ "blsrl $dst, $src" %} 8901 8902 ins_encode %{ 8903 __ blsrl($dst$$Register, $src$$Address); 8904 %} 8905 8906 ins_pipe(ialu_reg); 8907 %} 8908 8909 // Or Instructions 8910 // Or Register with Register 8911 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8912 %{ 8913 match(Set dst (OrI dst src)); 8914 effect(KILL cr); 8915 8916 format %{ "orl $dst, $src\t# int" %} 8917 opcode(0x0B); 8918 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8919 ins_pipe(ialu_reg_reg); 8920 %} 8921 8922 // Or Register with Immediate 8923 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8924 %{ 8925 match(Set dst (OrI dst src)); 8926 effect(KILL cr); 8927 8928 format %{ "orl $dst, $src\t# int" %} 8929 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 8930 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8931 ins_pipe(ialu_reg); 8932 %} 8933 8934 // Or Register with Memory 8935 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8936 %{ 8937 match(Set dst (OrI dst (LoadI src))); 8938 effect(KILL cr); 8939 8940 ins_cost(125); 8941 format %{ "orl $dst, $src\t# int" %} 8942 opcode(0x0B); 8943 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8944 ins_pipe(ialu_reg_mem); 8945 %} 8946 8947 // Or Memory with Register 8948 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8949 %{ 8950 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8951 effect(KILL cr); 8952 8953 ins_cost(150); 8954 format %{ "orl $dst, $src\t# int" %} 8955 opcode(0x09); /* Opcode 09 /r */ 8956 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8957 ins_pipe(ialu_mem_reg); 8958 %} 8959 8960 // Or Memory with Immediate 8961 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 8962 %{ 8963 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8964 effect(KILL cr); 8965 8966 ins_cost(125); 8967 format %{ "orl $dst, $src\t# int" %} 8968 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 8969 ins_encode(REX_mem(dst), OpcSE(src), 8970 RM_opc_mem(secondary, dst), Con8or32(src)); 8971 ins_pipe(ialu_mem_imm); 8972 %} 8973 8974 // Xor Instructions 8975 // Xor Register with Register 8976 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8977 %{ 8978 match(Set dst (XorI dst src)); 8979 effect(KILL cr); 8980 8981 format %{ "xorl $dst, $src\t# int" %} 8982 opcode(0x33); 8983 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8984 ins_pipe(ialu_reg_reg); 8985 %} 8986 8987 // Xor Register with Immediate -1 8988 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 8989 match(Set dst (XorI dst imm)); 8990 8991 format %{ "not $dst" %} 8992 ins_encode %{ 8993 __ notl($dst$$Register); 8994 %} 8995 ins_pipe(ialu_reg); 8996 %} 8997 8998 // Xor Register with Immediate 8999 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9000 %{ 9001 match(Set dst (XorI dst src)); 9002 effect(KILL cr); 9003 9004 format %{ "xorl $dst, $src\t# int" %} 9005 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9006 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9007 ins_pipe(ialu_reg); 9008 %} 9009 9010 // Xor Register with Memory 9011 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9012 %{ 9013 match(Set dst (XorI dst (LoadI src))); 9014 effect(KILL cr); 9015 9016 ins_cost(125); 9017 format %{ "xorl $dst, $src\t# int" %} 9018 opcode(0x33); 9019 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9020 ins_pipe(ialu_reg_mem); 9021 %} 9022 9023 // Xor Memory with Register 9024 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9025 %{ 9026 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9027 effect(KILL cr); 9028 9029 ins_cost(150); 9030 format %{ "xorl $dst, $src\t# int" %} 9031 opcode(0x31); /* Opcode 31 /r */ 9032 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9033 ins_pipe(ialu_mem_reg); 9034 %} 9035 9036 // Xor Memory with Immediate 9037 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9038 %{ 9039 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9040 effect(KILL cr); 9041 9042 ins_cost(125); 9043 format %{ "xorl $dst, $src\t# int" %} 9044 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9045 ins_encode(REX_mem(dst), OpcSE(src), 9046 RM_opc_mem(secondary, dst), Con8or32(src)); 9047 ins_pipe(ialu_mem_imm); 9048 %} 9049 9050 9051 // Long Logical Instructions 9052 9053 // And Instructions 9054 // And Register with Register 9055 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9056 %{ 9057 match(Set dst (AndL dst src)); 9058 effect(KILL cr); 9059 9060 format %{ "andq $dst, $src\t# long" %} 9061 opcode(0x23); 9062 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9063 ins_pipe(ialu_reg_reg); 9064 %} 9065 9066 // And Register with Immediate 255 9067 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9068 %{ 9069 match(Set dst (AndL dst src)); 9070 9071 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9072 opcode(0x0F, 0xB6); 9073 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9074 ins_pipe(ialu_reg); 9075 %} 9076 9077 // And Register with Immediate 65535 9078 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9079 %{ 9080 match(Set dst (AndL dst src)); 9081 9082 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9083 opcode(0x0F, 0xB7); 9084 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9085 ins_pipe(ialu_reg); 9086 %} 9087 9088 // And Register with Immediate 9089 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9090 %{ 9091 match(Set dst (AndL dst src)); 9092 effect(KILL cr); 9093 9094 format %{ "andq $dst, $src\t# long" %} 9095 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9096 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9097 ins_pipe(ialu_reg); 9098 %} 9099 9100 // And Register with Memory 9101 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9102 %{ 9103 match(Set dst (AndL dst (LoadL src))); 9104 effect(KILL cr); 9105 9106 ins_cost(125); 9107 format %{ "andq $dst, $src\t# long" %} 9108 opcode(0x23); 9109 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9110 ins_pipe(ialu_reg_mem); 9111 %} 9112 9113 // And Memory with Register 9114 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9115 %{ 9116 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9117 effect(KILL cr); 9118 9119 ins_cost(150); 9120 format %{ "andq $dst, $src\t# long" %} 9121 opcode(0x21); /* Opcode 21 /r */ 9122 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9123 ins_pipe(ialu_mem_reg); 9124 %} 9125 9126 // And Memory with Immediate 9127 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9128 %{ 9129 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9130 effect(KILL cr); 9131 9132 ins_cost(125); 9133 format %{ "andq $dst, $src\t# long" %} 9134 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9135 ins_encode(REX_mem_wide(dst), OpcSE(src), 9136 RM_opc_mem(secondary, dst), Con8or32(src)); 9137 ins_pipe(ialu_mem_imm); 9138 %} 9139 9140 // BMI1 instructions 9141 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9142 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9143 predicate(UseBMI1Instructions); 9144 effect(KILL cr); 9145 9146 ins_cost(125); 9147 format %{ "andnq $dst, $src1, $src2" %} 9148 9149 ins_encode %{ 9150 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9151 %} 9152 ins_pipe(ialu_reg_mem); 9153 %} 9154 9155 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9156 match(Set dst (AndL (XorL src1 minus_1) src2)); 9157 predicate(UseBMI1Instructions); 9158 effect(KILL cr); 9159 9160 format %{ "andnq $dst, $src1, $src2" %} 9161 9162 ins_encode %{ 9163 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9164 %} 9165 ins_pipe(ialu_reg_mem); 9166 %} 9167 9168 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9169 match(Set dst (AndL (SubL imm_zero src) src)); 9170 predicate(UseBMI1Instructions); 9171 effect(KILL cr); 9172 9173 format %{ "blsiq $dst, $src" %} 9174 9175 ins_encode %{ 9176 __ blsiq($dst$$Register, $src$$Register); 9177 %} 9178 ins_pipe(ialu_reg); 9179 %} 9180 9181 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9182 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9183 predicate(UseBMI1Instructions); 9184 effect(KILL cr); 9185 9186 ins_cost(125); 9187 format %{ "blsiq $dst, $src" %} 9188 9189 ins_encode %{ 9190 __ blsiq($dst$$Register, $src$$Address); 9191 %} 9192 ins_pipe(ialu_reg_mem); 9193 %} 9194 9195 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9196 %{ 9197 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9198 predicate(UseBMI1Instructions); 9199 effect(KILL cr); 9200 9201 ins_cost(125); 9202 format %{ "blsmskq $dst, $src" %} 9203 9204 ins_encode %{ 9205 __ blsmskq($dst$$Register, $src$$Address); 9206 %} 9207 ins_pipe(ialu_reg_mem); 9208 %} 9209 9210 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9211 %{ 9212 match(Set dst (XorL (AddL src minus_1) src)); 9213 predicate(UseBMI1Instructions); 9214 effect(KILL cr); 9215 9216 format %{ "blsmskq $dst, $src" %} 9217 9218 ins_encode %{ 9219 __ blsmskq($dst$$Register, $src$$Register); 9220 %} 9221 9222 ins_pipe(ialu_reg); 9223 %} 9224 9225 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9226 %{ 9227 match(Set dst (AndL (AddL src minus_1) src) ); 9228 predicate(UseBMI1Instructions); 9229 effect(KILL cr); 9230 9231 format %{ "blsrq $dst, $src" %} 9232 9233 ins_encode %{ 9234 __ blsrq($dst$$Register, $src$$Register); 9235 %} 9236 9237 ins_pipe(ialu_reg); 9238 %} 9239 9240 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9241 %{ 9242 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9243 predicate(UseBMI1Instructions); 9244 effect(KILL cr); 9245 9246 ins_cost(125); 9247 format %{ "blsrq $dst, $src" %} 9248 9249 ins_encode %{ 9250 __ blsrq($dst$$Register, $src$$Address); 9251 %} 9252 9253 ins_pipe(ialu_reg); 9254 %} 9255 9256 // Or Instructions 9257 // Or Register with Register 9258 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9259 %{ 9260 match(Set dst (OrL dst src)); 9261 effect(KILL cr); 9262 9263 format %{ "orq $dst, $src\t# long" %} 9264 opcode(0x0B); 9265 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9266 ins_pipe(ialu_reg_reg); 9267 %} 9268 9269 // Use any_RegP to match R15 (TLS register) without spilling. 9270 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9271 match(Set dst (OrL dst (CastP2X src))); 9272 effect(KILL cr); 9273 9274 format %{ "orq $dst, $src\t# long" %} 9275 opcode(0x0B); 9276 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9277 ins_pipe(ialu_reg_reg); 9278 %} 9279 9280 9281 // Or Register with Immediate 9282 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9283 %{ 9284 match(Set dst (OrL dst src)); 9285 effect(KILL cr); 9286 9287 format %{ "orq $dst, $src\t# long" %} 9288 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9289 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9290 ins_pipe(ialu_reg); 9291 %} 9292 9293 // Or Register with Memory 9294 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9295 %{ 9296 match(Set dst (OrL dst (LoadL src))); 9297 effect(KILL cr); 9298 9299 ins_cost(125); 9300 format %{ "orq $dst, $src\t# long" %} 9301 opcode(0x0B); 9302 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9303 ins_pipe(ialu_reg_mem); 9304 %} 9305 9306 // Or Memory with Register 9307 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9308 %{ 9309 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9310 effect(KILL cr); 9311 9312 ins_cost(150); 9313 format %{ "orq $dst, $src\t# long" %} 9314 opcode(0x09); /* Opcode 09 /r */ 9315 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9316 ins_pipe(ialu_mem_reg); 9317 %} 9318 9319 // Or Memory with Immediate 9320 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9321 %{ 9322 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9323 effect(KILL cr); 9324 9325 ins_cost(125); 9326 format %{ "orq $dst, $src\t# long" %} 9327 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9328 ins_encode(REX_mem_wide(dst), OpcSE(src), 9329 RM_opc_mem(secondary, dst), Con8or32(src)); 9330 ins_pipe(ialu_mem_imm); 9331 %} 9332 9333 // Xor Instructions 9334 // Xor Register with Register 9335 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9336 %{ 9337 match(Set dst (XorL dst src)); 9338 effect(KILL cr); 9339 9340 format %{ "xorq $dst, $src\t# long" %} 9341 opcode(0x33); 9342 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9343 ins_pipe(ialu_reg_reg); 9344 %} 9345 9346 // Xor Register with Immediate -1 9347 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9348 match(Set dst (XorL dst imm)); 9349 9350 format %{ "notq $dst" %} 9351 ins_encode %{ 9352 __ notq($dst$$Register); 9353 %} 9354 ins_pipe(ialu_reg); 9355 %} 9356 9357 // Xor Register with Immediate 9358 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9359 %{ 9360 match(Set dst (XorL dst src)); 9361 effect(KILL cr); 9362 9363 format %{ "xorq $dst, $src\t# long" %} 9364 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9365 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9366 ins_pipe(ialu_reg); 9367 %} 9368 9369 // Xor Register with Memory 9370 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9371 %{ 9372 match(Set dst (XorL dst (LoadL src))); 9373 effect(KILL cr); 9374 9375 ins_cost(125); 9376 format %{ "xorq $dst, $src\t# long" %} 9377 opcode(0x33); 9378 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9379 ins_pipe(ialu_reg_mem); 9380 %} 9381 9382 // Xor Memory with Register 9383 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9384 %{ 9385 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9386 effect(KILL cr); 9387 9388 ins_cost(150); 9389 format %{ "xorq $dst, $src\t# long" %} 9390 opcode(0x31); /* Opcode 31 /r */ 9391 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9392 ins_pipe(ialu_mem_reg); 9393 %} 9394 9395 // Xor Memory with Immediate 9396 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9397 %{ 9398 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9399 effect(KILL cr); 9400 9401 ins_cost(125); 9402 format %{ "xorq $dst, $src\t# long" %} 9403 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9404 ins_encode(REX_mem_wide(dst), OpcSE(src), 9405 RM_opc_mem(secondary, dst), Con8or32(src)); 9406 ins_pipe(ialu_mem_imm); 9407 %} 9408 9409 // Convert Int to Boolean 9410 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9411 %{ 9412 match(Set dst (Conv2B src)); 9413 effect(KILL cr); 9414 9415 format %{ "testl $src, $src\t# ci2b\n\t" 9416 "setnz $dst\n\t" 9417 "movzbl $dst, $dst" %} 9418 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9419 setNZ_reg(dst), 9420 REX_reg_breg(dst, dst), // movzbl 9421 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9422 ins_pipe(pipe_slow); // XXX 9423 %} 9424 9425 // Convert Pointer to Boolean 9426 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9427 %{ 9428 match(Set dst (Conv2B src)); 9429 effect(KILL cr); 9430 9431 format %{ "testq $src, $src\t# cp2b\n\t" 9432 "setnz $dst\n\t" 9433 "movzbl $dst, $dst" %} 9434 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 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 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9442 %{ 9443 match(Set dst (CmpLTMask p q)); 9444 effect(KILL cr); 9445 9446 ins_cost(400); 9447 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9448 "setlt $dst\n\t" 9449 "movzbl $dst, $dst\n\t" 9450 "negl $dst" %} 9451 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9452 setLT_reg(dst), 9453 REX_reg_breg(dst, dst), // movzbl 9454 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9455 neg_reg(dst)); 9456 ins_pipe(pipe_slow); 9457 %} 9458 9459 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9460 %{ 9461 match(Set dst (CmpLTMask dst zero)); 9462 effect(KILL cr); 9463 9464 ins_cost(100); 9465 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9466 ins_encode %{ 9467 __ sarl($dst$$Register, 31); 9468 %} 9469 ins_pipe(ialu_reg); 9470 %} 9471 9472 /* Better to save a register than avoid a branch */ 9473 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9474 %{ 9475 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9476 effect(KILL cr); 9477 ins_cost(300); 9478 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9479 "jge done\n\t" 9480 "addl $p,$y\n" 9481 "done: " %} 9482 ins_encode %{ 9483 Register Rp = $p$$Register; 9484 Register Rq = $q$$Register; 9485 Register Ry = $y$$Register; 9486 Label done; 9487 __ subl(Rp, Rq); 9488 __ jccb(Assembler::greaterEqual, done); 9489 __ addl(Rp, Ry); 9490 __ bind(done); 9491 %} 9492 ins_pipe(pipe_cmplt); 9493 %} 9494 9495 /* Better to save a register than avoid a branch */ 9496 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9497 %{ 9498 match(Set y (AndI (CmpLTMask p q) y)); 9499 effect(KILL cr); 9500 9501 ins_cost(300); 9502 9503 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9504 "jlt done\n\t" 9505 "xorl $y, $y\n" 9506 "done: " %} 9507 ins_encode %{ 9508 Register Rp = $p$$Register; 9509 Register Rq = $q$$Register; 9510 Register Ry = $y$$Register; 9511 Label done; 9512 __ cmpl(Rp, Rq); 9513 __ jccb(Assembler::less, done); 9514 __ xorl(Ry, Ry); 9515 __ bind(done); 9516 %} 9517 ins_pipe(pipe_cmplt); 9518 %} 9519 9520 9521 //---------- FP Instructions------------------------------------------------ 9522 9523 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9524 %{ 9525 match(Set cr (CmpF src1 src2)); 9526 9527 ins_cost(145); 9528 format %{ "ucomiss $src1, $src2\n\t" 9529 "jnp,s exit\n\t" 9530 "pushfq\t# saw NaN, set CF\n\t" 9531 "andq [rsp], #0xffffff2b\n\t" 9532 "popfq\n" 9533 "exit:" %} 9534 ins_encode %{ 9535 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9536 emit_cmpfp_fixup(_masm); 9537 %} 9538 ins_pipe(pipe_slow); 9539 %} 9540 9541 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9542 match(Set cr (CmpF src1 src2)); 9543 9544 ins_cost(100); 9545 format %{ "ucomiss $src1, $src2" %} 9546 ins_encode %{ 9547 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9548 %} 9549 ins_pipe(pipe_slow); 9550 %} 9551 9552 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9553 %{ 9554 match(Set cr (CmpF src1 (LoadF src2))); 9555 9556 ins_cost(145); 9557 format %{ "ucomiss $src1, $src2\n\t" 9558 "jnp,s exit\n\t" 9559 "pushfq\t# saw NaN, set CF\n\t" 9560 "andq [rsp], #0xffffff2b\n\t" 9561 "popfq\n" 9562 "exit:" %} 9563 ins_encode %{ 9564 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9565 emit_cmpfp_fixup(_masm); 9566 %} 9567 ins_pipe(pipe_slow); 9568 %} 9569 9570 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9571 match(Set cr (CmpF src1 (LoadF src2))); 9572 9573 ins_cost(100); 9574 format %{ "ucomiss $src1, $src2" %} 9575 ins_encode %{ 9576 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9577 %} 9578 ins_pipe(pipe_slow); 9579 %} 9580 9581 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9582 match(Set cr (CmpF src con)); 9583 9584 ins_cost(145); 9585 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9586 "jnp,s exit\n\t" 9587 "pushfq\t# saw NaN, set CF\n\t" 9588 "andq [rsp], #0xffffff2b\n\t" 9589 "popfq\n" 9590 "exit:" %} 9591 ins_encode %{ 9592 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9593 emit_cmpfp_fixup(_masm); 9594 %} 9595 ins_pipe(pipe_slow); 9596 %} 9597 9598 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9599 match(Set cr (CmpF src con)); 9600 ins_cost(100); 9601 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9602 ins_encode %{ 9603 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9604 %} 9605 ins_pipe(pipe_slow); 9606 %} 9607 9608 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9609 %{ 9610 match(Set cr (CmpD src1 src2)); 9611 9612 ins_cost(145); 9613 format %{ "ucomisd $src1, $src2\n\t" 9614 "jnp,s exit\n\t" 9615 "pushfq\t# saw NaN, set CF\n\t" 9616 "andq [rsp], #0xffffff2b\n\t" 9617 "popfq\n" 9618 "exit:" %} 9619 ins_encode %{ 9620 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9621 emit_cmpfp_fixup(_masm); 9622 %} 9623 ins_pipe(pipe_slow); 9624 %} 9625 9626 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9627 match(Set cr (CmpD src1 src2)); 9628 9629 ins_cost(100); 9630 format %{ "ucomisd $src1, $src2 test" %} 9631 ins_encode %{ 9632 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9633 %} 9634 ins_pipe(pipe_slow); 9635 %} 9636 9637 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9638 %{ 9639 match(Set cr (CmpD src1 (LoadD src2))); 9640 9641 ins_cost(145); 9642 format %{ "ucomisd $src1, $src2\n\t" 9643 "jnp,s exit\n\t" 9644 "pushfq\t# saw NaN, set CF\n\t" 9645 "andq [rsp], #0xffffff2b\n\t" 9646 "popfq\n" 9647 "exit:" %} 9648 ins_encode %{ 9649 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9650 emit_cmpfp_fixup(_masm); 9651 %} 9652 ins_pipe(pipe_slow); 9653 %} 9654 9655 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9656 match(Set cr (CmpD src1 (LoadD src2))); 9657 9658 ins_cost(100); 9659 format %{ "ucomisd $src1, $src2" %} 9660 ins_encode %{ 9661 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9662 %} 9663 ins_pipe(pipe_slow); 9664 %} 9665 9666 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9667 match(Set cr (CmpD src con)); 9668 9669 ins_cost(145); 9670 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9671 "jnp,s exit\n\t" 9672 "pushfq\t# saw NaN, set CF\n\t" 9673 "andq [rsp], #0xffffff2b\n\t" 9674 "popfq\n" 9675 "exit:" %} 9676 ins_encode %{ 9677 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9678 emit_cmpfp_fixup(_masm); 9679 %} 9680 ins_pipe(pipe_slow); 9681 %} 9682 9683 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9684 match(Set cr (CmpD src con)); 9685 ins_cost(100); 9686 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9687 ins_encode %{ 9688 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9689 %} 9690 ins_pipe(pipe_slow); 9691 %} 9692 9693 // Compare into -1,0,1 9694 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9695 %{ 9696 match(Set dst (CmpF3 src1 src2)); 9697 effect(KILL cr); 9698 9699 ins_cost(275); 9700 format %{ "ucomiss $src1, $src2\n\t" 9701 "movl $dst, #-1\n\t" 9702 "jp,s done\n\t" 9703 "jb,s done\n\t" 9704 "setne $dst\n\t" 9705 "movzbl $dst, $dst\n" 9706 "done:" %} 9707 ins_encode %{ 9708 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9709 emit_cmpfp3(_masm, $dst$$Register); 9710 %} 9711 ins_pipe(pipe_slow); 9712 %} 9713 9714 // Compare into -1,0,1 9715 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9716 %{ 9717 match(Set dst (CmpF3 src1 (LoadF src2))); 9718 effect(KILL cr); 9719 9720 ins_cost(275); 9721 format %{ "ucomiss $src1, $src2\n\t" 9722 "movl $dst, #-1\n\t" 9723 "jp,s done\n\t" 9724 "jb,s done\n\t" 9725 "setne $dst\n\t" 9726 "movzbl $dst, $dst\n" 9727 "done:" %} 9728 ins_encode %{ 9729 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9730 emit_cmpfp3(_masm, $dst$$Register); 9731 %} 9732 ins_pipe(pipe_slow); 9733 %} 9734 9735 // Compare into -1,0,1 9736 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9737 match(Set dst (CmpF3 src con)); 9738 effect(KILL cr); 9739 9740 ins_cost(275); 9741 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9742 "movl $dst, #-1\n\t" 9743 "jp,s done\n\t" 9744 "jb,s done\n\t" 9745 "setne $dst\n\t" 9746 "movzbl $dst, $dst\n" 9747 "done:" %} 9748 ins_encode %{ 9749 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9750 emit_cmpfp3(_masm, $dst$$Register); 9751 %} 9752 ins_pipe(pipe_slow); 9753 %} 9754 9755 // Compare into -1,0,1 9756 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9757 %{ 9758 match(Set dst (CmpD3 src1 src2)); 9759 effect(KILL cr); 9760 9761 ins_cost(275); 9762 format %{ "ucomisd $src1, $src2\n\t" 9763 "movl $dst, #-1\n\t" 9764 "jp,s done\n\t" 9765 "jb,s done\n\t" 9766 "setne $dst\n\t" 9767 "movzbl $dst, $dst\n" 9768 "done:" %} 9769 ins_encode %{ 9770 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9771 emit_cmpfp3(_masm, $dst$$Register); 9772 %} 9773 ins_pipe(pipe_slow); 9774 %} 9775 9776 // Compare into -1,0,1 9777 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9778 %{ 9779 match(Set dst (CmpD3 src1 (LoadD src2))); 9780 effect(KILL cr); 9781 9782 ins_cost(275); 9783 format %{ "ucomisd $src1, $src2\n\t" 9784 "movl $dst, #-1\n\t" 9785 "jp,s done\n\t" 9786 "jb,s done\n\t" 9787 "setne $dst\n\t" 9788 "movzbl $dst, $dst\n" 9789 "done:" %} 9790 ins_encode %{ 9791 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9792 emit_cmpfp3(_masm, $dst$$Register); 9793 %} 9794 ins_pipe(pipe_slow); 9795 %} 9796 9797 // Compare into -1,0,1 9798 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9799 match(Set dst (CmpD3 src con)); 9800 effect(KILL cr); 9801 9802 ins_cost(275); 9803 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9804 "movl $dst, #-1\n\t" 9805 "jp,s done\n\t" 9806 "jb,s done\n\t" 9807 "setne $dst\n\t" 9808 "movzbl $dst, $dst\n" 9809 "done:" %} 9810 ins_encode %{ 9811 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9812 emit_cmpfp3(_masm, $dst$$Register); 9813 %} 9814 ins_pipe(pipe_slow); 9815 %} 9816 9817 // -----------Trig and Trancendental Instructions------------------------------ 9818 instruct cosD_reg(regD dst) %{ 9819 match(Set dst (CosD dst)); 9820 9821 format %{ "dcos $dst\n\t" %} 9822 opcode(0xD9, 0xFF); 9823 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9824 ins_pipe( pipe_slow ); 9825 %} 9826 9827 instruct sinD_reg(regD dst) %{ 9828 match(Set dst (SinD dst)); 9829 9830 format %{ "dsin $dst\n\t" %} 9831 opcode(0xD9, 0xFE); 9832 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9833 ins_pipe( pipe_slow ); 9834 %} 9835 9836 instruct tanD_reg(regD dst) %{ 9837 match(Set dst (TanD dst)); 9838 9839 format %{ "dtan $dst\n\t" %} 9840 ins_encode( Push_SrcXD(dst), 9841 Opcode(0xD9), Opcode(0xF2), //fptan 9842 Opcode(0xDD), Opcode(0xD8), //fstp st 9843 Push_ResultXD(dst) ); 9844 ins_pipe( pipe_slow ); 9845 %} 9846 9847 instruct log10D_reg(regD dst) %{ 9848 // The source and result Double operands in XMM registers 9849 match(Set dst (Log10D dst)); 9850 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 9851 // fyl2x ; compute log_10(2) * log_2(x) 9852 format %{ "fldlg2\t\t\t#Log10\n\t" 9853 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 9854 %} 9855 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 9856 Push_SrcXD(dst), 9857 Opcode(0xD9), Opcode(0xF1), // fyl2x 9858 Push_ResultXD(dst)); 9859 9860 ins_pipe( pipe_slow ); 9861 %} 9862 9863 instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9864 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power 9865 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); 9866 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %} 9867 ins_encode %{ 9868 __ subptr(rsp, 8); 9869 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); 9870 __ fld_d(Address(rsp, 0)); 9871 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); 9872 __ fld_d(Address(rsp, 0)); 9873 __ fast_pow(); 9874 __ fstp_d(Address(rsp, 0)); 9875 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9876 __ addptr(rsp, 8); 9877 %} 9878 ins_pipe( pipe_slow ); 9879 %} 9880 9881 //----------Arithmetic Conversion Instructions--------------------------------- 9882 9883 instruct roundFloat_nop(regF dst) 9884 %{ 9885 match(Set dst (RoundFloat dst)); 9886 9887 ins_cost(0); 9888 ins_encode(); 9889 ins_pipe(empty); 9890 %} 9891 9892 instruct roundDouble_nop(regD dst) 9893 %{ 9894 match(Set dst (RoundDouble dst)); 9895 9896 ins_cost(0); 9897 ins_encode(); 9898 ins_pipe(empty); 9899 %} 9900 9901 instruct convF2D_reg_reg(regD dst, regF src) 9902 %{ 9903 match(Set dst (ConvF2D src)); 9904 9905 format %{ "cvtss2sd $dst, $src" %} 9906 ins_encode %{ 9907 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 9908 %} 9909 ins_pipe(pipe_slow); // XXX 9910 %} 9911 9912 instruct convF2D_reg_mem(regD dst, memory src) 9913 %{ 9914 match(Set dst (ConvF2D (LoadF src))); 9915 9916 format %{ "cvtss2sd $dst, $src" %} 9917 ins_encode %{ 9918 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 9919 %} 9920 ins_pipe(pipe_slow); // XXX 9921 %} 9922 9923 instruct convD2F_reg_reg(regF dst, regD src) 9924 %{ 9925 match(Set dst (ConvD2F src)); 9926 9927 format %{ "cvtsd2ss $dst, $src" %} 9928 ins_encode %{ 9929 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 9930 %} 9931 ins_pipe(pipe_slow); // XXX 9932 %} 9933 9934 instruct convD2F_reg_mem(regF dst, memory src) 9935 %{ 9936 match(Set dst (ConvD2F (LoadD src))); 9937 9938 format %{ "cvtsd2ss $dst, $src" %} 9939 ins_encode %{ 9940 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 9941 %} 9942 ins_pipe(pipe_slow); // XXX 9943 %} 9944 9945 // XXX do mem variants 9946 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9947 %{ 9948 match(Set dst (ConvF2I src)); 9949 effect(KILL cr); 9950 9951 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 9952 "cmpl $dst, #0x80000000\n\t" 9953 "jne,s done\n\t" 9954 "subq rsp, #8\n\t" 9955 "movss [rsp], $src\n\t" 9956 "call f2i_fixup\n\t" 9957 "popq $dst\n" 9958 "done: "%} 9959 ins_encode %{ 9960 Label done; 9961 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 9962 __ cmpl($dst$$Register, 0x80000000); 9963 __ jccb(Assembler::notEqual, done); 9964 __ subptr(rsp, 8); 9965 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9966 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 9967 __ pop($dst$$Register); 9968 __ bind(done); 9969 %} 9970 ins_pipe(pipe_slow); 9971 %} 9972 9973 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 9974 %{ 9975 match(Set dst (ConvF2L src)); 9976 effect(KILL cr); 9977 9978 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 9979 "cmpq $dst, [0x8000000000000000]\n\t" 9980 "jne,s done\n\t" 9981 "subq rsp, #8\n\t" 9982 "movss [rsp], $src\n\t" 9983 "call f2l_fixup\n\t" 9984 "popq $dst\n" 9985 "done: "%} 9986 ins_encode %{ 9987 Label done; 9988 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 9989 __ cmp64($dst$$Register, 9990 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 9991 __ jccb(Assembler::notEqual, done); 9992 __ subptr(rsp, 8); 9993 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9994 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 9995 __ pop($dst$$Register); 9996 __ bind(done); 9997 %} 9998 ins_pipe(pipe_slow); 9999 %} 10000 10001 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10002 %{ 10003 match(Set dst (ConvD2I src)); 10004 effect(KILL cr); 10005 10006 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10007 "cmpl $dst, #0x80000000\n\t" 10008 "jne,s done\n\t" 10009 "subq rsp, #8\n\t" 10010 "movsd [rsp], $src\n\t" 10011 "call d2i_fixup\n\t" 10012 "popq $dst\n" 10013 "done: "%} 10014 ins_encode %{ 10015 Label done; 10016 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10017 __ cmpl($dst$$Register, 0x80000000); 10018 __ jccb(Assembler::notEqual, done); 10019 __ subptr(rsp, 8); 10020 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10021 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10022 __ pop($dst$$Register); 10023 __ bind(done); 10024 %} 10025 ins_pipe(pipe_slow); 10026 %} 10027 10028 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10029 %{ 10030 match(Set dst (ConvD2L src)); 10031 effect(KILL cr); 10032 10033 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10034 "cmpq $dst, [0x8000000000000000]\n\t" 10035 "jne,s done\n\t" 10036 "subq rsp, #8\n\t" 10037 "movsd [rsp], $src\n\t" 10038 "call d2l_fixup\n\t" 10039 "popq $dst\n" 10040 "done: "%} 10041 ins_encode %{ 10042 Label done; 10043 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10044 __ cmp64($dst$$Register, 10045 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10046 __ jccb(Assembler::notEqual, done); 10047 __ subptr(rsp, 8); 10048 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10049 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10050 __ pop($dst$$Register); 10051 __ bind(done); 10052 %} 10053 ins_pipe(pipe_slow); 10054 %} 10055 10056 instruct convI2F_reg_reg(regF dst, rRegI src) 10057 %{ 10058 predicate(!UseXmmI2F); 10059 match(Set dst (ConvI2F src)); 10060 10061 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10062 ins_encode %{ 10063 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10064 %} 10065 ins_pipe(pipe_slow); // XXX 10066 %} 10067 10068 instruct convI2F_reg_mem(regF dst, memory src) 10069 %{ 10070 match(Set dst (ConvI2F (LoadI src))); 10071 10072 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10073 ins_encode %{ 10074 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10075 %} 10076 ins_pipe(pipe_slow); // XXX 10077 %} 10078 10079 instruct convI2D_reg_reg(regD dst, rRegI src) 10080 %{ 10081 predicate(!UseXmmI2D); 10082 match(Set dst (ConvI2D src)); 10083 10084 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10085 ins_encode %{ 10086 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10087 %} 10088 ins_pipe(pipe_slow); // XXX 10089 %} 10090 10091 instruct convI2D_reg_mem(regD dst, memory src) 10092 %{ 10093 match(Set dst (ConvI2D (LoadI src))); 10094 10095 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10096 ins_encode %{ 10097 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10098 %} 10099 ins_pipe(pipe_slow); // XXX 10100 %} 10101 10102 instruct convXI2F_reg(regF dst, rRegI src) 10103 %{ 10104 predicate(UseXmmI2F); 10105 match(Set dst (ConvI2F src)); 10106 10107 format %{ "movdl $dst, $src\n\t" 10108 "cvtdq2psl $dst, $dst\t# i2f" %} 10109 ins_encode %{ 10110 __ movdl($dst$$XMMRegister, $src$$Register); 10111 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10112 %} 10113 ins_pipe(pipe_slow); // XXX 10114 %} 10115 10116 instruct convXI2D_reg(regD dst, rRegI src) 10117 %{ 10118 predicate(UseXmmI2D); 10119 match(Set dst (ConvI2D src)); 10120 10121 format %{ "movdl $dst, $src\n\t" 10122 "cvtdq2pdl $dst, $dst\t# i2d" %} 10123 ins_encode %{ 10124 __ movdl($dst$$XMMRegister, $src$$Register); 10125 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10126 %} 10127 ins_pipe(pipe_slow); // XXX 10128 %} 10129 10130 instruct convL2F_reg_reg(regF dst, rRegL src) 10131 %{ 10132 match(Set dst (ConvL2F src)); 10133 10134 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10135 ins_encode %{ 10136 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10137 %} 10138 ins_pipe(pipe_slow); // XXX 10139 %} 10140 10141 instruct convL2F_reg_mem(regF dst, memory src) 10142 %{ 10143 match(Set dst (ConvL2F (LoadL src))); 10144 10145 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10146 ins_encode %{ 10147 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10148 %} 10149 ins_pipe(pipe_slow); // XXX 10150 %} 10151 10152 instruct convL2D_reg_reg(regD dst, rRegL src) 10153 %{ 10154 match(Set dst (ConvL2D src)); 10155 10156 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10157 ins_encode %{ 10158 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10159 %} 10160 ins_pipe(pipe_slow); // XXX 10161 %} 10162 10163 instruct convL2D_reg_mem(regD dst, memory src) 10164 %{ 10165 match(Set dst (ConvL2D (LoadL src))); 10166 10167 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10168 ins_encode %{ 10169 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10170 %} 10171 ins_pipe(pipe_slow); // XXX 10172 %} 10173 10174 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10175 %{ 10176 match(Set dst (ConvI2L src)); 10177 10178 ins_cost(125); 10179 format %{ "movslq $dst, $src\t# i2l" %} 10180 ins_encode %{ 10181 __ movslq($dst$$Register, $src$$Register); 10182 %} 10183 ins_pipe(ialu_reg_reg); 10184 %} 10185 10186 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10187 // %{ 10188 // match(Set dst (ConvI2L src)); 10189 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10190 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10191 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10192 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10193 // ((const TypeNode*) n)->type()->is_long()->_lo == 10194 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10195 10196 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10197 // ins_encode(enc_copy(dst, src)); 10198 // // opcode(0x63); // needs REX.W 10199 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10200 // ins_pipe(ialu_reg_reg); 10201 // %} 10202 10203 // Zero-extend convert int to long 10204 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10205 %{ 10206 match(Set dst (AndL (ConvI2L src) mask)); 10207 10208 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10209 ins_encode %{ 10210 if ($dst$$reg != $src$$reg) { 10211 __ movl($dst$$Register, $src$$Register); 10212 } 10213 %} 10214 ins_pipe(ialu_reg_reg); 10215 %} 10216 10217 // Zero-extend convert int to long 10218 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10219 %{ 10220 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10221 10222 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10223 ins_encode %{ 10224 __ movl($dst$$Register, $src$$Address); 10225 %} 10226 ins_pipe(ialu_reg_mem); 10227 %} 10228 10229 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10230 %{ 10231 match(Set dst (AndL src mask)); 10232 10233 format %{ "movl $dst, $src\t# zero-extend long" %} 10234 ins_encode %{ 10235 __ movl($dst$$Register, $src$$Register); 10236 %} 10237 ins_pipe(ialu_reg_reg); 10238 %} 10239 10240 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10241 %{ 10242 match(Set dst (ConvL2I src)); 10243 10244 format %{ "movl $dst, $src\t# l2i" %} 10245 ins_encode %{ 10246 __ movl($dst$$Register, $src$$Register); 10247 %} 10248 ins_pipe(ialu_reg_reg); 10249 %} 10250 10251 10252 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10253 match(Set dst (MoveF2I src)); 10254 effect(DEF dst, USE src); 10255 10256 ins_cost(125); 10257 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10258 ins_encode %{ 10259 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10260 %} 10261 ins_pipe(ialu_reg_mem); 10262 %} 10263 10264 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10265 match(Set dst (MoveI2F src)); 10266 effect(DEF dst, USE src); 10267 10268 ins_cost(125); 10269 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10270 ins_encode %{ 10271 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10272 %} 10273 ins_pipe(pipe_slow); 10274 %} 10275 10276 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10277 match(Set dst (MoveD2L src)); 10278 effect(DEF dst, USE src); 10279 10280 ins_cost(125); 10281 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10282 ins_encode %{ 10283 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10284 %} 10285 ins_pipe(ialu_reg_mem); 10286 %} 10287 10288 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10289 predicate(!UseXmmLoadAndClearUpper); 10290 match(Set dst (MoveL2D src)); 10291 effect(DEF dst, USE src); 10292 10293 ins_cost(125); 10294 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10295 ins_encode %{ 10296 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10297 %} 10298 ins_pipe(pipe_slow); 10299 %} 10300 10301 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10302 predicate(UseXmmLoadAndClearUpper); 10303 match(Set dst (MoveL2D src)); 10304 effect(DEF dst, USE src); 10305 10306 ins_cost(125); 10307 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10308 ins_encode %{ 10309 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10310 %} 10311 ins_pipe(pipe_slow); 10312 %} 10313 10314 10315 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10316 match(Set dst (MoveF2I src)); 10317 effect(DEF dst, USE src); 10318 10319 ins_cost(95); // XXX 10320 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10321 ins_encode %{ 10322 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10323 %} 10324 ins_pipe(pipe_slow); 10325 %} 10326 10327 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10328 match(Set dst (MoveI2F src)); 10329 effect(DEF dst, USE src); 10330 10331 ins_cost(100); 10332 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10333 ins_encode %{ 10334 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10335 %} 10336 ins_pipe( ialu_mem_reg ); 10337 %} 10338 10339 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10340 match(Set dst (MoveD2L src)); 10341 effect(DEF dst, USE src); 10342 10343 ins_cost(95); // XXX 10344 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10345 ins_encode %{ 10346 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10347 %} 10348 ins_pipe(pipe_slow); 10349 %} 10350 10351 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10352 match(Set dst (MoveL2D src)); 10353 effect(DEF dst, USE src); 10354 10355 ins_cost(100); 10356 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10357 ins_encode %{ 10358 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10359 %} 10360 ins_pipe(ialu_mem_reg); 10361 %} 10362 10363 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10364 match(Set dst (MoveF2I src)); 10365 effect(DEF dst, USE src); 10366 ins_cost(85); 10367 format %{ "movd $dst,$src\t# MoveF2I" %} 10368 ins_encode %{ 10369 __ movdl($dst$$Register, $src$$XMMRegister); 10370 %} 10371 ins_pipe( pipe_slow ); 10372 %} 10373 10374 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10375 match(Set dst (MoveD2L src)); 10376 effect(DEF dst, USE src); 10377 ins_cost(85); 10378 format %{ "movd $dst,$src\t# MoveD2L" %} 10379 ins_encode %{ 10380 __ movdq($dst$$Register, $src$$XMMRegister); 10381 %} 10382 ins_pipe( pipe_slow ); 10383 %} 10384 10385 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10386 match(Set dst (MoveI2F src)); 10387 effect(DEF dst, USE src); 10388 ins_cost(100); 10389 format %{ "movd $dst,$src\t# MoveI2F" %} 10390 ins_encode %{ 10391 __ movdl($dst$$XMMRegister, $src$$Register); 10392 %} 10393 ins_pipe( pipe_slow ); 10394 %} 10395 10396 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10397 match(Set dst (MoveL2D src)); 10398 effect(DEF dst, USE src); 10399 ins_cost(100); 10400 format %{ "movd $dst,$src\t# MoveL2D" %} 10401 ins_encode %{ 10402 __ movdq($dst$$XMMRegister, $src$$Register); 10403 %} 10404 ins_pipe( pipe_slow ); 10405 %} 10406 10407 10408 // ======================================================================= 10409 // fast clearing of an array 10410 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10411 rFlagsReg cr) 10412 %{ 10413 predicate(!UseFastStosb); 10414 match(Set dummy (ClearArray cnt base)); 10415 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10416 10417 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10418 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 10419 ins_encode %{ 10420 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10421 %} 10422 ins_pipe(pipe_slow); 10423 %} 10424 10425 instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10426 rFlagsReg cr) 10427 %{ 10428 predicate(UseFastStosb); 10429 match(Set dummy (ClearArray cnt base)); 10430 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10431 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10432 "shlq rcx,3\t# Convert doublewords to bytes\n\t" 10433 "rep stosb\t# Store rax to *rdi++ while rcx--" %} 10434 ins_encode %{ 10435 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10436 %} 10437 ins_pipe( pipe_slow ); 10438 %} 10439 10440 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10441 rax_RegI result, regD tmp1, rFlagsReg cr) 10442 %{ 10443 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10444 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10445 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10446 10447 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10448 ins_encode %{ 10449 __ string_compare($str1$$Register, $str2$$Register, 10450 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10451 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 10452 %} 10453 ins_pipe( pipe_slow ); 10454 %} 10455 10456 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10457 rax_RegI result, regD tmp1, rFlagsReg cr) 10458 %{ 10459 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10460 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10461 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10462 10463 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10464 ins_encode %{ 10465 __ string_compare($str1$$Register, $str2$$Register, 10466 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10467 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 10468 %} 10469 ins_pipe( pipe_slow ); 10470 %} 10471 10472 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10473 rax_RegI result, regD tmp1, rFlagsReg cr) 10474 %{ 10475 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 10476 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10477 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10478 10479 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10480 ins_encode %{ 10481 __ string_compare($str1$$Register, $str2$$Register, 10482 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10483 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 10484 %} 10485 ins_pipe( pipe_slow ); 10486 %} 10487 10488 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 10489 rax_RegI result, regD tmp1, rFlagsReg cr) 10490 %{ 10491 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 10492 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10493 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10494 10495 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10496 ins_encode %{ 10497 __ string_compare($str2$$Register, $str1$$Register, 10498 $cnt2$$Register, $cnt1$$Register, $result$$Register, 10499 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 10500 %} 10501 ins_pipe( pipe_slow ); 10502 %} 10503 10504 // fast search of substring with known size. 10505 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10506 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10507 %{ 10508 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10509 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10510 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10511 10512 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10513 ins_encode %{ 10514 int icnt2 = (int)$int_cnt2$$constant; 10515 if (icnt2 >= 16) { 10516 // IndexOf for constant substrings with size >= 16 elements 10517 // which don't need to be loaded through stack. 10518 __ string_indexofC8($str1$$Register, $str2$$Register, 10519 $cnt1$$Register, $cnt2$$Register, 10520 icnt2, $result$$Register, 10521 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10522 } else { 10523 // Small strings are loaded through stack if they cross page boundary. 10524 __ string_indexof($str1$$Register, $str2$$Register, 10525 $cnt1$$Register, $cnt2$$Register, 10526 icnt2, $result$$Register, 10527 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10528 } 10529 %} 10530 ins_pipe( pipe_slow ); 10531 %} 10532 10533 // fast search of substring with known size. 10534 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10535 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10536 %{ 10537 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10538 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10539 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10540 10541 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10542 ins_encode %{ 10543 int icnt2 = (int)$int_cnt2$$constant; 10544 if (icnt2 >= 8) { 10545 // IndexOf for constant substrings with size >= 8 elements 10546 // which don't need to be loaded through stack. 10547 __ string_indexofC8($str1$$Register, $str2$$Register, 10548 $cnt1$$Register, $cnt2$$Register, 10549 icnt2, $result$$Register, 10550 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10551 } else { 10552 // Small strings are loaded through stack if they cross page boundary. 10553 __ string_indexof($str1$$Register, $str2$$Register, 10554 $cnt1$$Register, $cnt2$$Register, 10555 icnt2, $result$$Register, 10556 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10557 } 10558 %} 10559 ins_pipe( pipe_slow ); 10560 %} 10561 10562 // fast search of substring with known size. 10563 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10564 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10565 %{ 10566 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10567 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10568 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10569 10570 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10571 ins_encode %{ 10572 int icnt2 = (int)$int_cnt2$$constant; 10573 if (icnt2 >= 8) { 10574 // IndexOf for constant substrings with size >= 8 elements 10575 // which don't need to be loaded through stack. 10576 __ string_indexofC8($str1$$Register, $str2$$Register, 10577 $cnt1$$Register, $cnt2$$Register, 10578 icnt2, $result$$Register, 10579 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10580 } else { 10581 // Small strings are loaded through stack if they cross page boundary. 10582 __ string_indexof($str1$$Register, $str2$$Register, 10583 $cnt1$$Register, $cnt2$$Register, 10584 icnt2, $result$$Register, 10585 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10586 } 10587 %} 10588 ins_pipe( pipe_slow ); 10589 %} 10590 10591 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10592 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10593 %{ 10594 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 10595 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10596 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10597 10598 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10599 ins_encode %{ 10600 __ string_indexof($str1$$Register, $str2$$Register, 10601 $cnt1$$Register, $cnt2$$Register, 10602 (-1), $result$$Register, 10603 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 10604 %} 10605 ins_pipe( pipe_slow ); 10606 %} 10607 10608 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10609 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10610 %{ 10611 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 10612 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10613 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10614 10615 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10616 ins_encode %{ 10617 __ string_indexof($str1$$Register, $str2$$Register, 10618 $cnt1$$Register, $cnt2$$Register, 10619 (-1), $result$$Register, 10620 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 10621 %} 10622 ins_pipe( pipe_slow ); 10623 %} 10624 10625 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10626 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10627 %{ 10628 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 10629 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10630 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10631 10632 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10633 ins_encode %{ 10634 __ string_indexof($str1$$Register, $str2$$Register, 10635 $cnt1$$Register, $cnt2$$Register, 10636 (-1), $result$$Register, 10637 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 10638 %} 10639 ins_pipe( pipe_slow ); 10640 %} 10641 10642 instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 10643 rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr) 10644 %{ 10645 predicate(UseSSE42Intrinsics); 10646 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 10647 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 10648 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 10649 ins_encode %{ 10650 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 10651 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 10652 %} 10653 ins_pipe( pipe_slow ); 10654 %} 10655 10656 // fast string equals 10657 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10658 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10659 %{ 10660 match(Set result (StrEquals (Binary str1 str2) cnt)); 10661 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10662 10663 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10664 ins_encode %{ 10665 __ arrays_equals(false, $str1$$Register, $str2$$Register, 10666 $cnt$$Register, $result$$Register, $tmp3$$Register, 10667 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 10668 %} 10669 ins_pipe( pipe_slow ); 10670 %} 10671 10672 // fast array equals 10673 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10674 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10675 %{ 10676 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 10677 match(Set result (AryEq ary1 ary2)); 10678 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10679 10680 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10681 ins_encode %{ 10682 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 10683 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10684 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 10685 %} 10686 ins_pipe( pipe_slow ); 10687 %} 10688 10689 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10690 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10691 %{ 10692 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 10693 match(Set result (AryEq ary1 ary2)); 10694 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10695 10696 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10697 ins_encode %{ 10698 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 10699 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10700 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 10701 %} 10702 ins_pipe( pipe_slow ); 10703 %} 10704 10705 instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 10706 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10707 %{ 10708 match(Set result (HasNegatives ary1 len)); 10709 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 10710 10711 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10712 ins_encode %{ 10713 __ has_negatives($ary1$$Register, $len$$Register, 10714 $result$$Register, $tmp3$$Register, 10715 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10716 %} 10717 ins_pipe( pipe_slow ); 10718 %} 10719 10720 // fast char[] to byte[] compression 10721 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, 10722 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 10723 match(Set result (StrCompressedCopy src (Binary dst len))); 10724 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 10725 10726 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 10727 ins_encode %{ 10728 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 10729 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 10730 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 10731 %} 10732 ins_pipe( pipe_slow ); 10733 %} 10734 10735 // fast byte[] to char[] inflation 10736 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 10737 regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 10738 match(Set dummy (StrInflatedCopy src (Binary dst len))); 10739 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 10740 10741 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 10742 ins_encode %{ 10743 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 10744 $tmp1$$XMMRegister, $tmp2$$Register); 10745 %} 10746 ins_pipe( pipe_slow ); 10747 %} 10748 10749 // encode char[] to byte[] in ISO_8859_1 10750 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 10751 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 10752 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 10753 match(Set result (EncodeISOArray src (Binary dst len))); 10754 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 10755 10756 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 10757 ins_encode %{ 10758 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 10759 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 10760 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 10761 %} 10762 ins_pipe( pipe_slow ); 10763 %} 10764 10765 //----------Overflow Math Instructions----------------------------------------- 10766 10767 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10768 %{ 10769 match(Set cr (OverflowAddI op1 op2)); 10770 effect(DEF cr, USE_KILL op1, USE op2); 10771 10772 format %{ "addl $op1, $op2\t# overflow check int" %} 10773 10774 ins_encode %{ 10775 __ addl($op1$$Register, $op2$$Register); 10776 %} 10777 ins_pipe(ialu_reg_reg); 10778 %} 10779 10780 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 10781 %{ 10782 match(Set cr (OverflowAddI op1 op2)); 10783 effect(DEF cr, USE_KILL op1, USE op2); 10784 10785 format %{ "addl $op1, $op2\t# overflow check int" %} 10786 10787 ins_encode %{ 10788 __ addl($op1$$Register, $op2$$constant); 10789 %} 10790 ins_pipe(ialu_reg_reg); 10791 %} 10792 10793 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10794 %{ 10795 match(Set cr (OverflowAddL op1 op2)); 10796 effect(DEF cr, USE_KILL op1, USE op2); 10797 10798 format %{ "addq $op1, $op2\t# overflow check long" %} 10799 ins_encode %{ 10800 __ addq($op1$$Register, $op2$$Register); 10801 %} 10802 ins_pipe(ialu_reg_reg); 10803 %} 10804 10805 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 10806 %{ 10807 match(Set cr (OverflowAddL op1 op2)); 10808 effect(DEF cr, USE_KILL op1, USE op2); 10809 10810 format %{ "addq $op1, $op2\t# overflow check long" %} 10811 ins_encode %{ 10812 __ addq($op1$$Register, $op2$$constant); 10813 %} 10814 ins_pipe(ialu_reg_reg); 10815 %} 10816 10817 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10818 %{ 10819 match(Set cr (OverflowSubI op1 op2)); 10820 10821 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10822 ins_encode %{ 10823 __ cmpl($op1$$Register, $op2$$Register); 10824 %} 10825 ins_pipe(ialu_reg_reg); 10826 %} 10827 10828 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10829 %{ 10830 match(Set cr (OverflowSubI op1 op2)); 10831 10832 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10833 ins_encode %{ 10834 __ cmpl($op1$$Register, $op2$$constant); 10835 %} 10836 ins_pipe(ialu_reg_reg); 10837 %} 10838 10839 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10840 %{ 10841 match(Set cr (OverflowSubL op1 op2)); 10842 10843 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10844 ins_encode %{ 10845 __ cmpq($op1$$Register, $op2$$Register); 10846 %} 10847 ins_pipe(ialu_reg_reg); 10848 %} 10849 10850 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10851 %{ 10852 match(Set cr (OverflowSubL op1 op2)); 10853 10854 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10855 ins_encode %{ 10856 __ cmpq($op1$$Register, $op2$$constant); 10857 %} 10858 ins_pipe(ialu_reg_reg); 10859 %} 10860 10861 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 10862 %{ 10863 match(Set cr (OverflowSubI zero op2)); 10864 effect(DEF cr, USE_KILL op2); 10865 10866 format %{ "negl $op2\t# overflow check int" %} 10867 ins_encode %{ 10868 __ negl($op2$$Register); 10869 %} 10870 ins_pipe(ialu_reg_reg); 10871 %} 10872 10873 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 10874 %{ 10875 match(Set cr (OverflowSubL zero op2)); 10876 effect(DEF cr, USE_KILL op2); 10877 10878 format %{ "negq $op2\t# overflow check long" %} 10879 ins_encode %{ 10880 __ negq($op2$$Register); 10881 %} 10882 ins_pipe(ialu_reg_reg); 10883 %} 10884 10885 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10886 %{ 10887 match(Set cr (OverflowMulI op1 op2)); 10888 effect(DEF cr, USE_KILL op1, USE op2); 10889 10890 format %{ "imull $op1, $op2\t# overflow check int" %} 10891 ins_encode %{ 10892 __ imull($op1$$Register, $op2$$Register); 10893 %} 10894 ins_pipe(ialu_reg_reg_alu0); 10895 %} 10896 10897 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 10898 %{ 10899 match(Set cr (OverflowMulI op1 op2)); 10900 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10901 10902 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 10903 ins_encode %{ 10904 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 10905 %} 10906 ins_pipe(ialu_reg_reg_alu0); 10907 %} 10908 10909 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10910 %{ 10911 match(Set cr (OverflowMulL op1 op2)); 10912 effect(DEF cr, USE_KILL op1, USE op2); 10913 10914 format %{ "imulq $op1, $op2\t# overflow check long" %} 10915 ins_encode %{ 10916 __ imulq($op1$$Register, $op2$$Register); 10917 %} 10918 ins_pipe(ialu_reg_reg_alu0); 10919 %} 10920 10921 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 10922 %{ 10923 match(Set cr (OverflowMulL op1 op2)); 10924 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10925 10926 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 10927 ins_encode %{ 10928 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 10929 %} 10930 ins_pipe(ialu_reg_reg_alu0); 10931 %} 10932 10933 10934 //----------Control Flow Instructions------------------------------------------ 10935 // Signed compare Instructions 10936 10937 // XXX more variants!! 10938 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10939 %{ 10940 match(Set cr (CmpI op1 op2)); 10941 effect(DEF cr, USE op1, USE op2); 10942 10943 format %{ "cmpl $op1, $op2" %} 10944 opcode(0x3B); /* Opcode 3B /r */ 10945 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10946 ins_pipe(ialu_cr_reg_reg); 10947 %} 10948 10949 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10950 %{ 10951 match(Set cr (CmpI op1 op2)); 10952 10953 format %{ "cmpl $op1, $op2" %} 10954 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10955 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10956 ins_pipe(ialu_cr_reg_imm); 10957 %} 10958 10959 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 10960 %{ 10961 match(Set cr (CmpI op1 (LoadI op2))); 10962 10963 ins_cost(500); // XXX 10964 format %{ "cmpl $op1, $op2" %} 10965 opcode(0x3B); /* Opcode 3B /r */ 10966 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10967 ins_pipe(ialu_cr_reg_mem); 10968 %} 10969 10970 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 10971 %{ 10972 match(Set cr (CmpI src zero)); 10973 10974 format %{ "testl $src, $src" %} 10975 opcode(0x85); 10976 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10977 ins_pipe(ialu_cr_reg_imm); 10978 %} 10979 10980 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 10981 %{ 10982 match(Set cr (CmpI (AndI src con) zero)); 10983 10984 format %{ "testl $src, $con" %} 10985 opcode(0xF7, 0x00); 10986 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 10987 ins_pipe(ialu_cr_reg_imm); 10988 %} 10989 10990 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 10991 %{ 10992 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 10993 10994 format %{ "testl $src, $mem" %} 10995 opcode(0x85); 10996 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 10997 ins_pipe(ialu_cr_reg_mem); 10998 %} 10999 11000 // Unsigned compare Instructions; really, same as signed except they 11001 // produce an rFlagsRegU instead of rFlagsReg. 11002 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11003 %{ 11004 match(Set cr (CmpU op1 op2)); 11005 11006 format %{ "cmpl $op1, $op2\t# unsigned" %} 11007 opcode(0x3B); /* Opcode 3B /r */ 11008 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11009 ins_pipe(ialu_cr_reg_reg); 11010 %} 11011 11012 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11013 %{ 11014 match(Set cr (CmpU op1 op2)); 11015 11016 format %{ "cmpl $op1, $op2\t# unsigned" %} 11017 opcode(0x81,0x07); /* Opcode 81 /7 */ 11018 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11019 ins_pipe(ialu_cr_reg_imm); 11020 %} 11021 11022 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11023 %{ 11024 match(Set cr (CmpU op1 (LoadI op2))); 11025 11026 ins_cost(500); // XXX 11027 format %{ "cmpl $op1, $op2\t# unsigned" %} 11028 opcode(0x3B); /* Opcode 3B /r */ 11029 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11030 ins_pipe(ialu_cr_reg_mem); 11031 %} 11032 11033 // // // Cisc-spilled version of cmpU_rReg 11034 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11035 // //%{ 11036 // // match(Set cr (CmpU (LoadI op1) op2)); 11037 // // 11038 // // format %{ "CMPu $op1,$op2" %} 11039 // // ins_cost(500); 11040 // // opcode(0x39); /* Opcode 39 /r */ 11041 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11042 // //%} 11043 11044 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11045 %{ 11046 match(Set cr (CmpU src zero)); 11047 11048 format %{ "testl $src, $src\t# unsigned" %} 11049 opcode(0x85); 11050 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11051 ins_pipe(ialu_cr_reg_imm); 11052 %} 11053 11054 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11055 %{ 11056 match(Set cr (CmpP op1 op2)); 11057 11058 format %{ "cmpq $op1, $op2\t# ptr" %} 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 compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11065 %{ 11066 match(Set cr (CmpP op1 (LoadP op2))); 11067 11068 ins_cost(500); // XXX 11069 format %{ "cmpq $op1, $op2\t# ptr" %} 11070 opcode(0x3B); /* Opcode 3B /r */ 11071 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11072 ins_pipe(ialu_cr_reg_mem); 11073 %} 11074 11075 // // // Cisc-spilled version of cmpP_rReg 11076 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11077 // //%{ 11078 // // match(Set cr (CmpP (LoadP op1) op2)); 11079 // // 11080 // // format %{ "CMPu $op1,$op2" %} 11081 // // ins_cost(500); 11082 // // opcode(0x39); /* Opcode 39 /r */ 11083 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11084 // //%} 11085 11086 // XXX this is generalized by compP_rReg_mem??? 11087 // Compare raw pointer (used in out-of-heap check). 11088 // Only works because non-oop pointers must be raw pointers 11089 // and raw pointers have no anti-dependencies. 11090 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11091 %{ 11092 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11093 match(Set cr (CmpP op1 (LoadP op2))); 11094 11095 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11096 opcode(0x3B); /* Opcode 3B /r */ 11097 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11098 ins_pipe(ialu_cr_reg_mem); 11099 %} 11100 11101 // This will generate a signed flags result. This should be OK since 11102 // any compare to a zero should be eq/neq. 11103 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11104 %{ 11105 match(Set cr (CmpP src zero)); 11106 11107 format %{ "testq $src, $src\t# ptr" %} 11108 opcode(0x85); 11109 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11110 ins_pipe(ialu_cr_reg_imm); 11111 %} 11112 11113 // This will generate a signed flags result. This should be OK since 11114 // any compare to a zero should be eq/neq. 11115 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11116 %{ 11117 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11118 match(Set cr (CmpP (LoadP op) zero)); 11119 11120 ins_cost(500); // XXX 11121 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11122 opcode(0xF7); /* Opcode F7 /0 */ 11123 ins_encode(REX_mem_wide(op), 11124 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11125 ins_pipe(ialu_cr_reg_imm); 11126 %} 11127 11128 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11129 %{ 11130 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11131 match(Set cr (CmpP (LoadP mem) zero)); 11132 11133 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11134 ins_encode %{ 11135 __ cmpq(r12, $mem$$Address); 11136 %} 11137 ins_pipe(ialu_cr_reg_mem); 11138 %} 11139 11140 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11141 %{ 11142 match(Set cr (CmpN op1 op2)); 11143 11144 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11145 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11146 ins_pipe(ialu_cr_reg_reg); 11147 %} 11148 11149 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11150 %{ 11151 match(Set cr (CmpN src (LoadN mem))); 11152 11153 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11154 ins_encode %{ 11155 __ cmpl($src$$Register, $mem$$Address); 11156 %} 11157 ins_pipe(ialu_cr_reg_mem); 11158 %} 11159 11160 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11161 match(Set cr (CmpN op1 op2)); 11162 11163 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11164 ins_encode %{ 11165 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11166 %} 11167 ins_pipe(ialu_cr_reg_imm); 11168 %} 11169 11170 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11171 %{ 11172 match(Set cr (CmpN src (LoadN mem))); 11173 11174 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11175 ins_encode %{ 11176 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11177 %} 11178 ins_pipe(ialu_cr_reg_mem); 11179 %} 11180 11181 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11182 match(Set cr (CmpN op1 op2)); 11183 11184 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11185 ins_encode %{ 11186 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11187 %} 11188 ins_pipe(ialu_cr_reg_imm); 11189 %} 11190 11191 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11192 %{ 11193 match(Set cr (CmpN src (LoadNKlass mem))); 11194 11195 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11196 ins_encode %{ 11197 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11198 %} 11199 ins_pipe(ialu_cr_reg_mem); 11200 %} 11201 11202 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11203 match(Set cr (CmpN src zero)); 11204 11205 format %{ "testl $src, $src\t# compressed ptr" %} 11206 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11207 ins_pipe(ialu_cr_reg_imm); 11208 %} 11209 11210 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11211 %{ 11212 predicate(Universe::narrow_oop_base() != NULL); 11213 match(Set cr (CmpN (LoadN mem) zero)); 11214 11215 ins_cost(500); // XXX 11216 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11217 ins_encode %{ 11218 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11219 %} 11220 ins_pipe(ialu_cr_reg_mem); 11221 %} 11222 11223 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11224 %{ 11225 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11226 match(Set cr (CmpN (LoadN mem) zero)); 11227 11228 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11229 ins_encode %{ 11230 __ cmpl(r12, $mem$$Address); 11231 %} 11232 ins_pipe(ialu_cr_reg_mem); 11233 %} 11234 11235 // Yanked all unsigned pointer compare operations. 11236 // Pointer compares are done with CmpP which is already unsigned. 11237 11238 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11239 %{ 11240 match(Set cr (CmpL op1 op2)); 11241 11242 format %{ "cmpq $op1, $op2" %} 11243 opcode(0x3B); /* Opcode 3B /r */ 11244 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11245 ins_pipe(ialu_cr_reg_reg); 11246 %} 11247 11248 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11249 %{ 11250 match(Set cr (CmpL op1 op2)); 11251 11252 format %{ "cmpq $op1, $op2" %} 11253 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11254 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11255 ins_pipe(ialu_cr_reg_imm); 11256 %} 11257 11258 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11259 %{ 11260 match(Set cr (CmpL op1 (LoadL op2))); 11261 11262 format %{ "cmpq $op1, $op2" %} 11263 opcode(0x3B); /* Opcode 3B /r */ 11264 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11265 ins_pipe(ialu_cr_reg_mem); 11266 %} 11267 11268 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11269 %{ 11270 match(Set cr (CmpL src zero)); 11271 11272 format %{ "testq $src, $src" %} 11273 opcode(0x85); 11274 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11275 ins_pipe(ialu_cr_reg_imm); 11276 %} 11277 11278 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11279 %{ 11280 match(Set cr (CmpL (AndL src con) zero)); 11281 11282 format %{ "testq $src, $con\t# long" %} 11283 opcode(0xF7, 0x00); 11284 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11285 ins_pipe(ialu_cr_reg_imm); 11286 %} 11287 11288 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11289 %{ 11290 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11291 11292 format %{ "testq $src, $mem" %} 11293 opcode(0x85); 11294 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11295 ins_pipe(ialu_cr_reg_mem); 11296 %} 11297 11298 // Manifest a CmpL result in an integer register. Very painful. 11299 // This is the test to avoid. 11300 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11301 %{ 11302 match(Set dst (CmpL3 src1 src2)); 11303 effect(KILL flags); 11304 11305 ins_cost(275); // XXX 11306 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11307 "movl $dst, -1\n\t" 11308 "jl,s done\n\t" 11309 "setne $dst\n\t" 11310 "movzbl $dst, $dst\n\t" 11311 "done:" %} 11312 ins_encode(cmpl3_flag(src1, src2, dst)); 11313 ins_pipe(pipe_slow); 11314 %} 11315 11316 //----------Max and Min-------------------------------------------------------- 11317 // Min Instructions 11318 11319 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11320 %{ 11321 effect(USE_DEF dst, USE src, USE cr); 11322 11323 format %{ "cmovlgt $dst, $src\t# min" %} 11324 opcode(0x0F, 0x4F); 11325 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11326 ins_pipe(pipe_cmov_reg); 11327 %} 11328 11329 11330 instruct minI_rReg(rRegI dst, rRegI src) 11331 %{ 11332 match(Set dst (MinI dst src)); 11333 11334 ins_cost(200); 11335 expand %{ 11336 rFlagsReg cr; 11337 compI_rReg(cr, dst, src); 11338 cmovI_reg_g(dst, src, cr); 11339 %} 11340 %} 11341 11342 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11343 %{ 11344 effect(USE_DEF dst, USE src, USE cr); 11345 11346 format %{ "cmovllt $dst, $src\t# max" %} 11347 opcode(0x0F, 0x4C); 11348 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11349 ins_pipe(pipe_cmov_reg); 11350 %} 11351 11352 11353 instruct maxI_rReg(rRegI dst, rRegI src) 11354 %{ 11355 match(Set dst (MaxI dst src)); 11356 11357 ins_cost(200); 11358 expand %{ 11359 rFlagsReg cr; 11360 compI_rReg(cr, dst, src); 11361 cmovI_reg_l(dst, src, cr); 11362 %} 11363 %} 11364 11365 // ============================================================================ 11366 // Branch Instructions 11367 11368 // Jump Direct - Label defines a relative address from JMP+1 11369 instruct jmpDir(label labl) 11370 %{ 11371 match(Goto); 11372 effect(USE labl); 11373 11374 ins_cost(300); 11375 format %{ "jmp $labl" %} 11376 size(5); 11377 ins_encode %{ 11378 Label* L = $labl$$label; 11379 __ jmp(*L, false); // Always long jump 11380 %} 11381 ins_pipe(pipe_jmp); 11382 %} 11383 11384 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11385 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11386 %{ 11387 match(If cop cr); 11388 effect(USE labl); 11389 11390 ins_cost(300); 11391 format %{ "j$cop $labl" %} 11392 size(6); 11393 ins_encode %{ 11394 Label* L = $labl$$label; 11395 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11396 %} 11397 ins_pipe(pipe_jcc); 11398 %} 11399 11400 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11401 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11402 %{ 11403 match(CountedLoopEnd cop cr); 11404 effect(USE labl); 11405 11406 ins_cost(300); 11407 format %{ "j$cop $labl\t# loop end" %} 11408 size(6); 11409 ins_encode %{ 11410 Label* L = $labl$$label; 11411 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11412 %} 11413 ins_pipe(pipe_jcc); 11414 %} 11415 11416 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11417 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11418 match(CountedLoopEnd cop cmp); 11419 effect(USE labl); 11420 11421 ins_cost(300); 11422 format %{ "j$cop,u $labl\t# loop end" %} 11423 size(6); 11424 ins_encode %{ 11425 Label* L = $labl$$label; 11426 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11427 %} 11428 ins_pipe(pipe_jcc); 11429 %} 11430 11431 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11432 match(CountedLoopEnd cop cmp); 11433 effect(USE labl); 11434 11435 ins_cost(200); 11436 format %{ "j$cop,u $labl\t# loop end" %} 11437 size(6); 11438 ins_encode %{ 11439 Label* L = $labl$$label; 11440 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11441 %} 11442 ins_pipe(pipe_jcc); 11443 %} 11444 11445 // Jump Direct Conditional - using unsigned comparison 11446 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11447 match(If cop cmp); 11448 effect(USE labl); 11449 11450 ins_cost(300); 11451 format %{ "j$cop,u $labl" %} 11452 size(6); 11453 ins_encode %{ 11454 Label* L = $labl$$label; 11455 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11456 %} 11457 ins_pipe(pipe_jcc); 11458 %} 11459 11460 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11461 match(If cop cmp); 11462 effect(USE labl); 11463 11464 ins_cost(200); 11465 format %{ "j$cop,u $labl" %} 11466 size(6); 11467 ins_encode %{ 11468 Label* L = $labl$$label; 11469 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11470 %} 11471 ins_pipe(pipe_jcc); 11472 %} 11473 11474 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11475 match(If cop cmp); 11476 effect(USE labl); 11477 11478 ins_cost(200); 11479 format %{ $$template 11480 if ($cop$$cmpcode == Assembler::notEqual) { 11481 $$emit$$"jp,u $labl\n\t" 11482 $$emit$$"j$cop,u $labl" 11483 } else { 11484 $$emit$$"jp,u done\n\t" 11485 $$emit$$"j$cop,u $labl\n\t" 11486 $$emit$$"done:" 11487 } 11488 %} 11489 ins_encode %{ 11490 Label* l = $labl$$label; 11491 if ($cop$$cmpcode == Assembler::notEqual) { 11492 __ jcc(Assembler::parity, *l, false); 11493 __ jcc(Assembler::notEqual, *l, false); 11494 } else if ($cop$$cmpcode == Assembler::equal) { 11495 Label done; 11496 __ jccb(Assembler::parity, done); 11497 __ jcc(Assembler::equal, *l, false); 11498 __ bind(done); 11499 } else { 11500 ShouldNotReachHere(); 11501 } 11502 %} 11503 ins_pipe(pipe_jcc); 11504 %} 11505 11506 // ============================================================================ 11507 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11508 // superklass array for an instance of the superklass. Set a hidden 11509 // internal cache on a hit (cache is checked with exposed code in 11510 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11511 // encoding ALSO sets flags. 11512 11513 instruct partialSubtypeCheck(rdi_RegP result, 11514 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11515 rFlagsReg cr) 11516 %{ 11517 match(Set result (PartialSubtypeCheck sub super)); 11518 effect(KILL rcx, KILL cr); 11519 11520 ins_cost(1100); // slightly larger than the next version 11521 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11522 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11523 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11524 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11525 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11526 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11527 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11528 "miss:\t" %} 11529 11530 opcode(0x1); // Force a XOR of RDI 11531 ins_encode(enc_PartialSubtypeCheck()); 11532 ins_pipe(pipe_slow); 11533 %} 11534 11535 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11536 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11537 immP0 zero, 11538 rdi_RegP result) 11539 %{ 11540 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11541 effect(KILL rcx, KILL result); 11542 11543 ins_cost(1000); 11544 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11545 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11546 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11547 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11548 "jne,s miss\t\t# Missed: flags nz\n\t" 11549 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11550 "miss:\t" %} 11551 11552 opcode(0x0); // No need to XOR RDI 11553 ins_encode(enc_PartialSubtypeCheck()); 11554 ins_pipe(pipe_slow); 11555 %} 11556 11557 // ============================================================================ 11558 // Branch Instructions -- short offset versions 11559 // 11560 // These instructions are used to replace jumps of a long offset (the default 11561 // match) with jumps of a shorter offset. These instructions are all tagged 11562 // with the ins_short_branch attribute, which causes the ADLC to suppress the 11563 // match rules in general matching. Instead, the ADLC generates a conversion 11564 // method in the MachNode which can be used to do in-place replacement of the 11565 // long variant with the shorter variant. The compiler will determine if a 11566 // branch can be taken by the is_short_branch_offset() predicate in the machine 11567 // specific code section of the file. 11568 11569 // Jump Direct - Label defines a relative address from JMP+1 11570 instruct jmpDir_short(label labl) %{ 11571 match(Goto); 11572 effect(USE labl); 11573 11574 ins_cost(300); 11575 format %{ "jmp,s $labl" %} 11576 size(2); 11577 ins_encode %{ 11578 Label* L = $labl$$label; 11579 __ jmpb(*L); 11580 %} 11581 ins_pipe(pipe_jmp); 11582 ins_short_branch(1); 11583 %} 11584 11585 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11586 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11587 match(If cop cr); 11588 effect(USE labl); 11589 11590 ins_cost(300); 11591 format %{ "j$cop,s $labl" %} 11592 size(2); 11593 ins_encode %{ 11594 Label* L = $labl$$label; 11595 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11596 %} 11597 ins_pipe(pipe_jcc); 11598 ins_short_branch(1); 11599 %} 11600 11601 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11602 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11603 match(CountedLoopEnd cop cr); 11604 effect(USE labl); 11605 11606 ins_cost(300); 11607 format %{ "j$cop,s $labl\t# loop end" %} 11608 size(2); 11609 ins_encode %{ 11610 Label* L = $labl$$label; 11611 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11612 %} 11613 ins_pipe(pipe_jcc); 11614 ins_short_branch(1); 11615 %} 11616 11617 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11618 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11619 match(CountedLoopEnd cop cmp); 11620 effect(USE labl); 11621 11622 ins_cost(300); 11623 format %{ "j$cop,us $labl\t# loop end" %} 11624 size(2); 11625 ins_encode %{ 11626 Label* L = $labl$$label; 11627 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11628 %} 11629 ins_pipe(pipe_jcc); 11630 ins_short_branch(1); 11631 %} 11632 11633 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11634 match(CountedLoopEnd cop cmp); 11635 effect(USE labl); 11636 11637 ins_cost(300); 11638 format %{ "j$cop,us $labl\t# loop end" %} 11639 size(2); 11640 ins_encode %{ 11641 Label* L = $labl$$label; 11642 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11643 %} 11644 ins_pipe(pipe_jcc); 11645 ins_short_branch(1); 11646 %} 11647 11648 // Jump Direct Conditional - using unsigned comparison 11649 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11650 match(If cop cmp); 11651 effect(USE labl); 11652 11653 ins_cost(300); 11654 format %{ "j$cop,us $labl" %} 11655 size(2); 11656 ins_encode %{ 11657 Label* L = $labl$$label; 11658 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11659 %} 11660 ins_pipe(pipe_jcc); 11661 ins_short_branch(1); 11662 %} 11663 11664 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11665 match(If cop cmp); 11666 effect(USE labl); 11667 11668 ins_cost(300); 11669 format %{ "j$cop,us $labl" %} 11670 size(2); 11671 ins_encode %{ 11672 Label* L = $labl$$label; 11673 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11674 %} 11675 ins_pipe(pipe_jcc); 11676 ins_short_branch(1); 11677 %} 11678 11679 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11680 match(If cop cmp); 11681 effect(USE labl); 11682 11683 ins_cost(300); 11684 format %{ $$template 11685 if ($cop$$cmpcode == Assembler::notEqual) { 11686 $$emit$$"jp,u,s $labl\n\t" 11687 $$emit$$"j$cop,u,s $labl" 11688 } else { 11689 $$emit$$"jp,u,s done\n\t" 11690 $$emit$$"j$cop,u,s $labl\n\t" 11691 $$emit$$"done:" 11692 } 11693 %} 11694 size(4); 11695 ins_encode %{ 11696 Label* l = $labl$$label; 11697 if ($cop$$cmpcode == Assembler::notEqual) { 11698 __ jccb(Assembler::parity, *l); 11699 __ jccb(Assembler::notEqual, *l); 11700 } else if ($cop$$cmpcode == Assembler::equal) { 11701 Label done; 11702 __ jccb(Assembler::parity, done); 11703 __ jccb(Assembler::equal, *l); 11704 __ bind(done); 11705 } else { 11706 ShouldNotReachHere(); 11707 } 11708 %} 11709 ins_pipe(pipe_jcc); 11710 ins_short_branch(1); 11711 %} 11712 11713 // ============================================================================ 11714 // inlined locking and unlocking 11715 11716 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 11717 predicate(Compile::current()->use_rtm()); 11718 match(Set cr (FastLock object box)); 11719 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 11720 ins_cost(300); 11721 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 11722 ins_encode %{ 11723 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 11724 $scr$$Register, $cx1$$Register, $cx2$$Register, 11725 _counters, _rtm_counters, _stack_rtm_counters, 11726 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11727 true, ra_->C->profile_rtm()); 11728 %} 11729 ins_pipe(pipe_slow); 11730 %} 11731 11732 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 11733 predicate(!Compile::current()->use_rtm()); 11734 match(Set cr (FastLock object box)); 11735 effect(TEMP tmp, TEMP scr, USE_KILL box); 11736 ins_cost(300); 11737 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 11738 ins_encode %{ 11739 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 11740 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 11741 %} 11742 ins_pipe(pipe_slow); 11743 %} 11744 11745 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 11746 match(Set cr (FastUnlock object box)); 11747 effect(TEMP tmp, USE_KILL box); 11748 ins_cost(300); 11749 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 11750 ins_encode %{ 11751 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 11752 %} 11753 ins_pipe(pipe_slow); 11754 %} 11755 11756 11757 // ============================================================================ 11758 // Safepoint Instructions 11759 instruct safePoint_poll(rFlagsReg cr) 11760 %{ 11761 predicate(!Assembler::is_polling_page_far()); 11762 match(SafePoint); 11763 effect(KILL cr); 11764 11765 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 11766 "# Safepoint: poll for GC" %} 11767 ins_cost(125); 11768 ins_encode %{ 11769 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 11770 __ testl(rax, addr); 11771 %} 11772 ins_pipe(ialu_reg_mem); 11773 %} 11774 11775 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 11776 %{ 11777 predicate(Assembler::is_polling_page_far()); 11778 match(SafePoint poll); 11779 effect(KILL cr, USE poll); 11780 11781 format %{ "testl rax, [$poll]\t" 11782 "# Safepoint: poll for GC" %} 11783 ins_cost(125); 11784 ins_encode %{ 11785 __ relocate(relocInfo::poll_type); 11786 __ testl(rax, Address($poll$$Register, 0)); 11787 %} 11788 ins_pipe(ialu_reg_mem); 11789 %} 11790 11791 // ============================================================================ 11792 // Procedure Call/Return Instructions 11793 // Call Java Static Instruction 11794 // Note: If this code changes, the corresponding ret_addr_offset() and 11795 // compute_padding() functions will have to be adjusted. 11796 instruct CallStaticJavaDirect(method meth) %{ 11797 match(CallStaticJava); 11798 effect(USE meth); 11799 11800 ins_cost(300); 11801 format %{ "call,static " %} 11802 opcode(0xE8); /* E8 cd */ 11803 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 11804 ins_pipe(pipe_slow); 11805 ins_alignment(4); 11806 %} 11807 11808 // Call Java Dynamic Instruction 11809 // Note: If this code changes, the corresponding ret_addr_offset() and 11810 // compute_padding() functions will have to be adjusted. 11811 instruct CallDynamicJavaDirect(method meth) 11812 %{ 11813 match(CallDynamicJava); 11814 effect(USE meth); 11815 11816 ins_cost(300); 11817 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11818 "call,dynamic " %} 11819 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 11820 ins_pipe(pipe_slow); 11821 ins_alignment(4); 11822 %} 11823 11824 // Call Runtime Instruction 11825 instruct CallRuntimeDirect(method meth) 11826 %{ 11827 match(CallRuntime); 11828 effect(USE meth); 11829 11830 ins_cost(300); 11831 format %{ "call,runtime " %} 11832 ins_encode(clear_avx, Java_To_Runtime(meth)); 11833 ins_pipe(pipe_slow); 11834 %} 11835 11836 // Call runtime without safepoint 11837 instruct CallLeafDirect(method meth) 11838 %{ 11839 match(CallLeaf); 11840 effect(USE meth); 11841 11842 ins_cost(300); 11843 format %{ "call_leaf,runtime " %} 11844 ins_encode(clear_avx, Java_To_Runtime(meth)); 11845 ins_pipe(pipe_slow); 11846 %} 11847 11848 // Call runtime without safepoint 11849 instruct CallLeafNoFPDirect(method meth) 11850 %{ 11851 match(CallLeafNoFP); 11852 effect(USE meth); 11853 11854 ins_cost(300); 11855 format %{ "call_leaf_nofp,runtime " %} 11856 ins_encode(Java_To_Runtime(meth)); 11857 ins_pipe(pipe_slow); 11858 %} 11859 11860 // Return Instruction 11861 // Remove the return address & jump to it. 11862 // Notice: We always emit a nop after a ret to make sure there is room 11863 // for safepoint patching 11864 instruct Ret() 11865 %{ 11866 match(Return); 11867 11868 format %{ "ret" %} 11869 opcode(0xC3); 11870 ins_encode(OpcP); 11871 ins_pipe(pipe_jmp); 11872 %} 11873 11874 // Tail Call; Jump from runtime stub to Java code. 11875 // Also known as an 'interprocedural jump'. 11876 // Target of jump will eventually return to caller. 11877 // TailJump below removes the return address. 11878 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 11879 %{ 11880 match(TailCall jump_target method_oop); 11881 11882 ins_cost(300); 11883 format %{ "jmp $jump_target\t# rbx holds method oop" %} 11884 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11885 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11886 ins_pipe(pipe_jmp); 11887 %} 11888 11889 // Tail Jump; remove the return address; jump to target. 11890 // TailCall above leaves the return address around. 11891 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 11892 %{ 11893 match(TailJump jump_target ex_oop); 11894 11895 ins_cost(300); 11896 format %{ "popq rdx\t# pop return address\n\t" 11897 "jmp $jump_target" %} 11898 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11899 ins_encode(Opcode(0x5a), // popq rdx 11900 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11901 ins_pipe(pipe_jmp); 11902 %} 11903 11904 // Create exception oop: created by stack-crawling runtime code. 11905 // Created exception is now available to this handler, and is setup 11906 // just prior to jumping to this handler. No code emitted. 11907 instruct CreateException(rax_RegP ex_oop) 11908 %{ 11909 match(Set ex_oop (CreateEx)); 11910 11911 size(0); 11912 // use the following format syntax 11913 format %{ "# exception oop is in rax; no code emitted" %} 11914 ins_encode(); 11915 ins_pipe(empty); 11916 %} 11917 11918 // Rethrow exception: 11919 // The exception oop will come in the first argument position. 11920 // Then JUMP (not call) to the rethrow stub code. 11921 instruct RethrowException() 11922 %{ 11923 match(Rethrow); 11924 11925 // use the following format syntax 11926 format %{ "jmp rethrow_stub" %} 11927 ins_encode(enc_rethrow); 11928 ins_pipe(pipe_jmp); 11929 %} 11930 11931 11932 // ============================================================================ 11933 // This name is KNOWN by the ADLC and cannot be changed. 11934 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 11935 // for this guy. 11936 instruct tlsLoadP(r15_RegP dst) %{ 11937 match(Set dst (ThreadLocal)); 11938 effect(DEF dst); 11939 11940 size(0); 11941 format %{ "# TLS is in R15" %} 11942 ins_encode( /*empty encoding*/ ); 11943 ins_pipe(ialu_reg_reg); 11944 %} 11945 11946 11947 //----------PEEPHOLE RULES----------------------------------------------------- 11948 // These must follow all instruction definitions as they use the names 11949 // defined in the instructions definitions. 11950 // 11951 // peepmatch ( root_instr_name [preceding_instruction]* ); 11952 // 11953 // peepconstraint %{ 11954 // (instruction_number.operand_name relational_op instruction_number.operand_name 11955 // [, ...] ); 11956 // // instruction numbers are zero-based using left to right order in peepmatch 11957 // 11958 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 11959 // // provide an instruction_number.operand_name for each operand that appears 11960 // // in the replacement instruction's match rule 11961 // 11962 // ---------VM FLAGS--------------------------------------------------------- 11963 // 11964 // All peephole optimizations can be turned off using -XX:-OptoPeephole 11965 // 11966 // Each peephole rule is given an identifying number starting with zero and 11967 // increasing by one in the order seen by the parser. An individual peephole 11968 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 11969 // on the command-line. 11970 // 11971 // ---------CURRENT LIMITATIONS---------------------------------------------- 11972 // 11973 // Only match adjacent instructions in same basic block 11974 // Only equality constraints 11975 // Only constraints between operands, not (0.dest_reg == RAX_enc) 11976 // Only one replacement instruction 11977 // 11978 // ---------EXAMPLE---------------------------------------------------------- 11979 // 11980 // // pertinent parts of existing instructions in architecture description 11981 // instruct movI(rRegI dst, rRegI src) 11982 // %{ 11983 // match(Set dst (CopyI src)); 11984 // %} 11985 // 11986 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 11987 // %{ 11988 // match(Set dst (AddI dst src)); 11989 // effect(KILL cr); 11990 // %} 11991 // 11992 // // Change (inc mov) to lea 11993 // peephole %{ 11994 // // increment preceeded by register-register move 11995 // peepmatch ( incI_rReg movI ); 11996 // // require that the destination register of the increment 11997 // // match the destination register of the move 11998 // peepconstraint ( 0.dst == 1.dst ); 11999 // // construct a replacement instruction that sets 12000 // // the destination to ( move's source register + one ) 12001 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12002 // %} 12003 // 12004 12005 // Implementation no longer uses movX instructions since 12006 // machine-independent system no longer uses CopyX nodes. 12007 // 12008 // peephole 12009 // %{ 12010 // peepmatch (incI_rReg movI); 12011 // peepconstraint (0.dst == 1.dst); 12012 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12013 // %} 12014 12015 // peephole 12016 // %{ 12017 // peepmatch (decI_rReg movI); 12018 // peepconstraint (0.dst == 1.dst); 12019 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12020 // %} 12021 12022 // peephole 12023 // %{ 12024 // peepmatch (addI_rReg_imm movI); 12025 // peepconstraint (0.dst == 1.dst); 12026 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12027 // %} 12028 12029 // peephole 12030 // %{ 12031 // peepmatch (incL_rReg movL); 12032 // peepconstraint (0.dst == 1.dst); 12033 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12034 // %} 12035 12036 // peephole 12037 // %{ 12038 // peepmatch (decL_rReg movL); 12039 // peepconstraint (0.dst == 1.dst); 12040 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12041 // %} 12042 12043 // peephole 12044 // %{ 12045 // peepmatch (addL_rReg_imm movL); 12046 // peepconstraint (0.dst == 1.dst); 12047 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12048 // %} 12049 12050 // peephole 12051 // %{ 12052 // peepmatch (addP_rReg_imm movP); 12053 // peepconstraint (0.dst == 1.dst); 12054 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12055 // %} 12056 12057 // // Change load of spilled value to only a spill 12058 // instruct storeI(memory mem, rRegI src) 12059 // %{ 12060 // match(Set mem (StoreI mem src)); 12061 // %} 12062 // 12063 // instruct loadI(rRegI dst, memory mem) 12064 // %{ 12065 // match(Set dst (LoadI mem)); 12066 // %} 12067 // 12068 12069 peephole 12070 %{ 12071 peepmatch (loadI storeI); 12072 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12073 peepreplace (storeI(1.mem 1.mem 1.src)); 12074 %} 12075 12076 peephole 12077 %{ 12078 peepmatch (loadL storeL); 12079 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12080 peepreplace (storeL(1.mem 1.mem 1.src)); 12081 %} 12082 12083 //----------SMARTSPILL RULES--------------------------------------------------- 12084 // These must follow all instruction definitions as they use the names 12085 // defined in the instructions definitions.