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