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