1// 2// Copyright (c) 2003, 2018, 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 32register %{ 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 70reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83reg_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 86reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89#ifdef _WIN64 90 91reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97#else 98 99reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105#endif 106 107reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129reg_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 142alloc_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. 170reg_class no_reg(); 171 172// Class for all pointer registers (including RSP and RBP) 173reg_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) 191reg_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; 210reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %}); 211 212// Class for all pointer registers (excluding RSP) 213reg_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) 228reg_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. 242reg_class_dynamic ptr_reg(ptr_reg_no_rbp, ptr_reg_with_rbp, %{ PreserveFramePointer %}); 243 244// Class for all pointer registers (excluding RAX and RSP) 245reg_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) 259reg_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. 272reg_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) 275reg_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) 288reg_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. 300reg_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 303reg_class ptr_rax_reg(RAX, RAX_H); 304 305// Singleton class for RBX pointer register 306reg_class ptr_rbx_reg(RBX, RBX_H); 307 308// Singleton class for RSI pointer register 309reg_class ptr_rsi_reg(RSI, RSI_H); 310 311// Singleton class for RDI pointer register 312reg_class ptr_rdi_reg(RDI, RDI_H); 313 314// Singleton class for stack pointer 315reg_class ptr_rsp_reg(RSP, RSP_H); 316 317// Singleton class for TLS pointer 318reg_class ptr_r15_reg(R15, R15_H); 319 320// Class for all long registers (excluding RSP) 321reg_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) 336reg_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. 350reg_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) 353reg_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) 366reg_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. 378reg_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) 381reg_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) 395reg_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. 408reg_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 411reg_class long_rax_reg(RAX, RAX_H); 412 413// Singleton class for RCX long register 414reg_class long_rcx_reg(RCX, RCX_H); 415 416// Singleton class for RDX long register 417reg_class long_rdx_reg(RDX, RDX_H); 418 419// Class for all int registers (excluding RSP) 420reg_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) 435reg_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. 449reg_class_dynamic int_reg(int_reg_no_rbp, int_reg_with_rbp, %{ PreserveFramePointer %}); 450 451// Class for all int registers (excluding RCX and RSP) 452reg_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) 466reg_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. 479reg_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) 482reg_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) 495reg_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. 507reg_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 510reg_class int_rax_reg(RAX); 511 512// Singleton class for RBX int register 513reg_class int_rbx_reg(RBX); 514 515// Singleton class for RCX int register 516reg_class int_rcx_reg(RCX); 517 518// Singleton class for RCX int register 519reg_class int_rdx_reg(RDX); 520 521// Singleton class for RCX int register 522reg_class int_rdi_reg(RDI); 523 524// Singleton class for instruction pointer 525// reg_class ip_reg(RIP); 526 527%} 528 529source_hpp %{ 530#if INCLUDE_ZGC 531#include "gc/z/zBarrierSetAssembler.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 538source %{ 539#define RELOC_IMM64 Assembler::imm_operand 540#define RELOC_DISP32 Assembler::disp32_operand 541 542#define __ _masm. 543 544static bool generate_vzeroupper(Compile* C) { 545 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 546} 547 548static int clear_avx_size() { 549 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 550} 551 552// !!!!! Special hack to get all types of calls to specify the byte offset 553// from the start of the call to the point where the return address 554// will point. 555int MachCallStaticJavaNode::ret_addr_offset() 556{ 557 int offset = 5; // 5 bytes from start of call to where return address points 558 offset += clear_avx_size(); 559 return offset; 560} 561 562int MachCallDynamicJavaNode::ret_addr_offset() 563{ 564 int offset = 15; // 15 bytes from start of call to where return address points 565 offset += clear_avx_size(); 566 return offset; 567} 568 569int MachCallRuntimeNode::ret_addr_offset() { 570 int offset = 13; // movq r10,#addr; callq (r10) 571 offset += clear_avx_size(); 572 return offset; 573} 574 575// Indicate if the safepoint node needs the polling page as an input, 576// it does if the polling page is more than disp32 away. 577bool SafePointNode::needs_polling_address_input() 578{ 579 return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far(); 580} 581 582// 583// Compute padding required for nodes which need alignment 584// 585 586// The address of the call instruction needs to be 4-byte aligned to 587// ensure that it does not span a cache line so that it can be patched. 588int CallStaticJavaDirectNode::compute_padding(int current_offset) const 589{ 590 current_offset += clear_avx_size(); // skip vzeroupper 591 current_offset += 1; // skip call opcode byte 592 return align_up(current_offset, alignment_required()) - current_offset; 593} 594 595// The address of the call instruction needs to be 4-byte aligned to 596// ensure that it does not span a cache line so that it can be patched. 597int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 598{ 599 current_offset += clear_avx_size(); // skip vzeroupper 600 current_offset += 11; // skip movq instruction + call opcode byte 601 return align_up(current_offset, alignment_required()) - current_offset; 602} 603 604// EMIT_RM() 605void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 606 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 607 cbuf.insts()->emit_int8(c); 608} 609 610// EMIT_CC() 611void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 612 unsigned char c = (unsigned char) (f1 | f2); 613 cbuf.insts()->emit_int8(c); 614} 615 616// EMIT_OPCODE() 617void emit_opcode(CodeBuffer &cbuf, int code) { 618 cbuf.insts()->emit_int8((unsigned char) code); 619} 620 621// EMIT_OPCODE() w/ relocation information 622void emit_opcode(CodeBuffer &cbuf, 623 int code, relocInfo::relocType reloc, int offset, int format) 624{ 625 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 626 emit_opcode(cbuf, code); 627} 628 629// EMIT_D8() 630void emit_d8(CodeBuffer &cbuf, int d8) { 631 cbuf.insts()->emit_int8((unsigned char) d8); 632} 633 634// EMIT_D16() 635void emit_d16(CodeBuffer &cbuf, int d16) { 636 cbuf.insts()->emit_int16(d16); 637} 638 639// EMIT_D32() 640void emit_d32(CodeBuffer &cbuf, int d32) { 641 cbuf.insts()->emit_int32(d32); 642} 643 644// EMIT_D64() 645void emit_d64(CodeBuffer &cbuf, int64_t d64) { 646 cbuf.insts()->emit_int64(d64); 647} 648 649// emit 32 bit value and construct relocation entry from relocInfo::relocType 650void emit_d32_reloc(CodeBuffer& cbuf, 651 int d32, 652 relocInfo::relocType reloc, 653 int format) 654{ 655 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 656 cbuf.relocate(cbuf.insts_mark(), reloc, format); 657 cbuf.insts()->emit_int32(d32); 658} 659 660// emit 32 bit value and construct relocation entry from RelocationHolder 661void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 662#ifdef ASSERT 663 if (rspec.reloc()->type() == relocInfo::oop_type && 664 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 665 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 666 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop((intptr_t)d32))), "cannot embed scavengable oops in code"); 667 } 668#endif 669 cbuf.relocate(cbuf.insts_mark(), rspec, format); 670 cbuf.insts()->emit_int32(d32); 671} 672 673void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 674 address next_ip = cbuf.insts_end() + 4; 675 emit_d32_reloc(cbuf, (int) (addr - next_ip), 676 external_word_Relocation::spec(addr), 677 RELOC_DISP32); 678} 679 680 681// emit 64 bit value and construct relocation entry from relocInfo::relocType 682void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 683 cbuf.relocate(cbuf.insts_mark(), reloc, format); 684 cbuf.insts()->emit_int64(d64); 685} 686 687// emit 64 bit value and construct relocation entry from RelocationHolder 688void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 689#ifdef ASSERT 690 if (rspec.reloc()->type() == relocInfo::oop_type && 691 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 692 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 693 assert(oopDesc::is_oop(cast_to_oop(d64)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop(d64))), 694 "cannot embed scavengable oops in code"); 695 } 696#endif 697 cbuf.relocate(cbuf.insts_mark(), rspec, format); 698 cbuf.insts()->emit_int64(d64); 699} 700 701// Access stack slot for load or store 702void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 703{ 704 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 705 if (-0x80 <= disp && disp < 0x80) { 706 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 707 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 708 emit_d8(cbuf, disp); // Displacement // R/M byte 709 } else { 710 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 711 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 712 emit_d32(cbuf, disp); // Displacement // R/M byte 713 } 714} 715 716 // rRegI ereg, memory mem) %{ // emit_reg_mem 717void encode_RegMem(CodeBuffer &cbuf, 718 int reg, 719 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 720{ 721 assert(disp_reloc == relocInfo::none, "cannot have disp"); 722 int regenc = reg & 7; 723 int baseenc = base & 7; 724 int indexenc = index & 7; 725 726 // There is no index & no scale, use form without SIB byte 727 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 728 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 729 if (disp == 0 && base != RBP_enc && base != R13_enc) { 730 emit_rm(cbuf, 0x0, regenc, baseenc); // * 731 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 732 // If 8-bit displacement, mode 0x1 733 emit_rm(cbuf, 0x1, regenc, baseenc); // * 734 emit_d8(cbuf, disp); 735 } else { 736 // If 32-bit displacement 737 if (base == -1) { // Special flag for absolute address 738 emit_rm(cbuf, 0x0, regenc, 0x5); // * 739 if (disp_reloc != relocInfo::none) { 740 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 741 } else { 742 emit_d32(cbuf, disp); 743 } 744 } else { 745 // Normal base + offset 746 emit_rm(cbuf, 0x2, regenc, baseenc); // * 747 if (disp_reloc != relocInfo::none) { 748 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 749 } else { 750 emit_d32(cbuf, disp); 751 } 752 } 753 } 754 } else { 755 // Else, encode with the SIB byte 756 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 757 if (disp == 0 && base != RBP_enc && base != R13_enc) { 758 // If no displacement 759 emit_rm(cbuf, 0x0, regenc, 0x4); // * 760 emit_rm(cbuf, scale, indexenc, baseenc); 761 } else { 762 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 763 // If 8-bit displacement, mode 0x1 764 emit_rm(cbuf, 0x1, regenc, 0x4); // * 765 emit_rm(cbuf, scale, indexenc, baseenc); 766 emit_d8(cbuf, disp); 767 } else { 768 // If 32-bit displacement 769 if (base == 0x04 ) { 770 emit_rm(cbuf, 0x2, regenc, 0x4); 771 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 772 } else { 773 emit_rm(cbuf, 0x2, regenc, 0x4); 774 emit_rm(cbuf, scale, indexenc, baseenc); // * 775 } 776 if (disp_reloc != relocInfo::none) { 777 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 778 } else { 779 emit_d32(cbuf, disp); 780 } 781 } 782 } 783 } 784} 785 786// This could be in MacroAssembler but it's fairly C2 specific 787void emit_cmpfp_fixup(MacroAssembler& _masm) { 788 Label exit; 789 __ jccb(Assembler::noParity, exit); 790 __ pushf(); 791 // 792 // comiss/ucomiss instructions set ZF,PF,CF flags and 793 // zero OF,AF,SF for NaN values. 794 // Fixup flags by zeroing ZF,PF so that compare of NaN 795 // values returns 'less than' result (CF is set). 796 // Leave the rest of flags unchanged. 797 // 798 // 7 6 5 4 3 2 1 0 799 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 800 // 0 0 1 0 1 0 1 1 (0x2B) 801 // 802 __ andq(Address(rsp, 0), 0xffffff2b); 803 __ popf(); 804 __ bind(exit); 805} 806 807void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 808 Label done; 809 __ movl(dst, -1); 810 __ jcc(Assembler::parity, done); 811 __ jcc(Assembler::below, done); 812 __ setb(Assembler::notEqual, dst); 813 __ movzbl(dst, dst); 814 __ bind(done); 815} 816 817 818//============================================================================= 819const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 820 821int Compile::ConstantTable::calculate_table_base_offset() const { 822 return 0; // absolute addressing, no offset 823} 824 825bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 826void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 827 ShouldNotReachHere(); 828} 829 830void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 831 // Empty encoding 832} 833 834uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 835 return 0; 836} 837 838#ifndef PRODUCT 839void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 840 st->print("# MachConstantBaseNode (empty encoding)"); 841} 842#endif 843 844 845//============================================================================= 846#ifndef PRODUCT 847void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 848 Compile* C = ra_->C; 849 850 int framesize = C->frame_size_in_bytes(); 851 int bangsize = C->bang_size_in_bytes(); 852 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 853 // Remove wordSize for return addr which is already pushed. 854 framesize -= wordSize; 855 856 if (C->need_stack_bang(bangsize)) { 857 framesize -= wordSize; 858 st->print("# stack bang (%d bytes)", bangsize); 859 st->print("\n\t"); 860 st->print("pushq rbp\t# Save rbp"); 861 if (PreserveFramePointer) { 862 st->print("\n\t"); 863 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 864 } 865 if (framesize) { 866 st->print("\n\t"); 867 st->print("subq rsp, #%d\t# Create frame",framesize); 868 } 869 } else { 870 st->print("subq rsp, #%d\t# Create frame",framesize); 871 st->print("\n\t"); 872 framesize -= wordSize; 873 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 874 if (PreserveFramePointer) { 875 st->print("\n\t"); 876 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 877 if (framesize > 0) { 878 st->print("\n\t"); 879 st->print("addq rbp, #%d", framesize); 880 } 881 } 882 } 883 884 if (VerifyStackAtCalls) { 885 st->print("\n\t"); 886 framesize -= wordSize; 887 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 888#ifdef ASSERT 889 st->print("\n\t"); 890 st->print("# stack alignment check"); 891#endif 892 } 893 if (C->stub_function() != NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) { 894 st->print("\n\t"); 895 st->print("cmpl [r15_thread + #disarmed_offset], #disarmed_value\t"); 896 st->print("\n\t"); 897 st->print("je fast_entry\t"); 898 st->print("\n\t"); 899 st->print("call #nmethod_entry_barrier_stub\t"); 900 st->print("\n\tfast_entry:"); 901 } 902 st->cr(); 903} 904#endif 905 906void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 907 Compile* C = ra_->C; 908 MacroAssembler _masm(&cbuf); 909 910 int framesize = C->frame_size_in_bytes(); 911 int bangsize = C->bang_size_in_bytes(); 912 913 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != NULL); 914 915 C->set_frame_complete(cbuf.insts_size()); 916 917 if (C->has_mach_constant_base_node()) { 918 // NOTE: We set the table base offset here because users might be 919 // emitted before MachConstantBaseNode. 920 Compile::ConstantTable& constant_table = C->constant_table(); 921 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 922 } 923} 924 925uint MachPrologNode::size(PhaseRegAlloc* ra_) const 926{ 927 return MachNode::size(ra_); // too many variables; just compute it 928 // the hard way 929} 930 931int MachPrologNode::reloc() const 932{ 933 return 0; // a large enough number 934} 935 936//============================================================================= 937#ifndef PRODUCT 938void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 939{ 940 Compile* C = ra_->C; 941 if (generate_vzeroupper(C)) { 942 st->print("vzeroupper"); 943 st->cr(); st->print("\t"); 944 } 945 946 int framesize = C->frame_size_in_bytes(); 947 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 948 // Remove word for return adr already pushed 949 // and RBP 950 framesize -= 2*wordSize; 951 952 if (framesize) { 953 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 954 st->print("\t"); 955 } 956 957 st->print_cr("popq rbp"); 958 if (do_polling() && C->is_method_compilation()) { 959 st->print("\t"); 960 if (SafepointMechanism::uses_thread_local_poll()) { 961 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 962 "testl rax, [rscratch1]\t" 963 "# Safepoint: poll for GC"); 964 } else if (Assembler::is_polling_page_far()) { 965 st->print_cr("movq rscratch1, #polling_page_address\n\t" 966 "testl rax, [rscratch1]\t" 967 "# Safepoint: poll for GC"); 968 } else { 969 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 970 "# Safepoint: poll for GC"); 971 } 972 } 973} 974#endif 975 976void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 977{ 978 Compile* C = ra_->C; 979 MacroAssembler _masm(&cbuf); 980 981 if (generate_vzeroupper(C)) { 982 // Clear upper bits of YMM registers when current compiled code uses 983 // wide vectors to avoid AVX <-> SSE transition penalty during call. 984 __ vzeroupper(); 985 } 986 987 int framesize = C->frame_size_in_bytes(); 988 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 989 // Remove word for return adr already pushed 990 // and RBP 991 framesize -= 2*wordSize; 992 993 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 994 995 if (framesize) { 996 emit_opcode(cbuf, Assembler::REX_W); 997 if (framesize < 0x80) { 998 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 999 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1000 emit_d8(cbuf, framesize); 1001 } else { 1002 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 1003 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1004 emit_d32(cbuf, framesize); 1005 } 1006 } 1007 1008 // popq rbp 1009 emit_opcode(cbuf, 0x58 | RBP_enc); 1010 1011 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1012 __ reserved_stack_check(); 1013 } 1014 1015 if (do_polling() && C->is_method_compilation()) { 1016 MacroAssembler _masm(&cbuf); 1017 if (SafepointMechanism::uses_thread_local_poll()) { 1018 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 1019 __ relocate(relocInfo::poll_return_type); 1020 __ testl(rax, Address(rscratch1, 0)); 1021 } else { 1022 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1023 if (Assembler::is_polling_page_far()) { 1024 __ lea(rscratch1, polling_page); 1025 __ relocate(relocInfo::poll_return_type); 1026 __ testl(rax, Address(rscratch1, 0)); 1027 } else { 1028 __ testl(rax, polling_page); 1029 } 1030 } 1031 } 1032} 1033 1034uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1035{ 1036 return MachNode::size(ra_); // too many variables; just compute it 1037 // the hard way 1038} 1039 1040int MachEpilogNode::reloc() const 1041{ 1042 return 2; // a large enough number 1043} 1044 1045const Pipeline* MachEpilogNode::pipeline() const 1046{ 1047 return MachNode::pipeline_class(); 1048} 1049 1050int MachEpilogNode::safepoint_offset() const 1051{ 1052 return 0; 1053} 1054 1055//============================================================================= 1056 1057enum RC { 1058 rc_bad, 1059 rc_int, 1060 rc_float, 1061 rc_stack 1062}; 1063 1064static enum RC rc_class(OptoReg::Name reg) 1065{ 1066 if( !OptoReg::is_valid(reg) ) return rc_bad; 1067 1068 if (OptoReg::is_stack(reg)) return rc_stack; 1069 1070 VMReg r = OptoReg::as_VMReg(reg); 1071 1072 if (r->is_Register()) return rc_int; 1073 1074 assert(r->is_XMMRegister(), "must be"); 1075 return rc_float; 1076} 1077 1078// Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1079static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1080 int src_hi, int dst_hi, uint ireg, outputStream* st); 1081 1082static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1083 int stack_offset, int reg, uint ireg, outputStream* st); 1084 1085static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1086 int dst_offset, uint ireg, outputStream* st) { 1087 if (cbuf) { 1088 MacroAssembler _masm(cbuf); 1089 switch (ireg) { 1090 case Op_VecS: 1091 __ movq(Address(rsp, -8), rax); 1092 __ movl(rax, Address(rsp, src_offset)); 1093 __ movl(Address(rsp, dst_offset), rax); 1094 __ movq(rax, Address(rsp, -8)); 1095 break; 1096 case Op_VecD: 1097 __ pushq(Address(rsp, src_offset)); 1098 __ popq (Address(rsp, dst_offset)); 1099 break; 1100 case Op_VecX: 1101 __ pushq(Address(rsp, src_offset)); 1102 __ popq (Address(rsp, dst_offset)); 1103 __ pushq(Address(rsp, src_offset+8)); 1104 __ popq (Address(rsp, dst_offset+8)); 1105 break; 1106 case Op_VecY: 1107 __ vmovdqu(Address(rsp, -32), xmm0); 1108 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1109 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1110 __ vmovdqu(xmm0, Address(rsp, -32)); 1111 break; 1112 case Op_VecZ: 1113 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1114 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1115 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1116 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1117 break; 1118 default: 1119 ShouldNotReachHere(); 1120 } 1121#ifndef PRODUCT 1122 } else { 1123 switch (ireg) { 1124 case Op_VecS: 1125 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1126 "movl rax, [rsp + #%d]\n\t" 1127 "movl [rsp + #%d], rax\n\t" 1128 "movq rax, [rsp - #8]", 1129 src_offset, dst_offset); 1130 break; 1131 case Op_VecD: 1132 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1133 "popq [rsp + #%d]", 1134 src_offset, dst_offset); 1135 break; 1136 case Op_VecX: 1137 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1138 "popq [rsp + #%d]\n\t" 1139 "pushq [rsp + #%d]\n\t" 1140 "popq [rsp + #%d]", 1141 src_offset, dst_offset, src_offset+8, dst_offset+8); 1142 break; 1143 case Op_VecY: 1144 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1145 "vmovdqu xmm0, [rsp + #%d]\n\t" 1146 "vmovdqu [rsp + #%d], xmm0\n\t" 1147 "vmovdqu xmm0, [rsp - #32]", 1148 src_offset, dst_offset); 1149 break; 1150 case Op_VecZ: 1151 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1152 "vmovdqu xmm0, [rsp + #%d]\n\t" 1153 "vmovdqu [rsp + #%d], xmm0\n\t" 1154 "vmovdqu xmm0, [rsp - #64]", 1155 src_offset, dst_offset); 1156 break; 1157 default: 1158 ShouldNotReachHere(); 1159 } 1160#endif 1161 } 1162} 1163 1164uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1165 PhaseRegAlloc* ra_, 1166 bool do_size, 1167 outputStream* st) const { 1168 assert(cbuf != NULL || st != NULL, "sanity"); 1169 // Get registers to move 1170 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1171 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1172 OptoReg::Name dst_second = ra_->get_reg_second(this); 1173 OptoReg::Name dst_first = ra_->get_reg_first(this); 1174 1175 enum RC src_second_rc = rc_class(src_second); 1176 enum RC src_first_rc = rc_class(src_first); 1177 enum RC dst_second_rc = rc_class(dst_second); 1178 enum RC dst_first_rc = rc_class(dst_first); 1179 1180 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1181 "must move at least 1 register" ); 1182 1183 if (src_first == dst_first && src_second == dst_second) { 1184 // Self copy, no move 1185 return 0; 1186 } 1187 if (bottom_type()->isa_vect() != NULL) { 1188 uint ireg = ideal_reg(); 1189 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1190 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1191 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1192 // mem -> mem 1193 int src_offset = ra_->reg2offset(src_first); 1194 int dst_offset = ra_->reg2offset(dst_first); 1195 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1196 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1197 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1198 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1199 int stack_offset = ra_->reg2offset(dst_first); 1200 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1201 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1202 int stack_offset = ra_->reg2offset(src_first); 1203 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1204 } else { 1205 ShouldNotReachHere(); 1206 } 1207 return 0; 1208 } 1209 if (src_first_rc == rc_stack) { 1210 // mem -> 1211 if (dst_first_rc == rc_stack) { 1212 // mem -> mem 1213 assert(src_second != dst_first, "overlap"); 1214 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1215 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1216 // 64-bit 1217 int src_offset = ra_->reg2offset(src_first); 1218 int dst_offset = ra_->reg2offset(dst_first); 1219 if (cbuf) { 1220 MacroAssembler _masm(cbuf); 1221 __ pushq(Address(rsp, src_offset)); 1222 __ popq (Address(rsp, dst_offset)); 1223#ifndef PRODUCT 1224 } else { 1225 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1226 "popq [rsp + #%d]", 1227 src_offset, dst_offset); 1228#endif 1229 } 1230 } else { 1231 // 32-bit 1232 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1233 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1234 // No pushl/popl, so: 1235 int src_offset = ra_->reg2offset(src_first); 1236 int dst_offset = ra_->reg2offset(dst_first); 1237 if (cbuf) { 1238 MacroAssembler _masm(cbuf); 1239 __ movq(Address(rsp, -8), rax); 1240 __ movl(rax, Address(rsp, src_offset)); 1241 __ movl(Address(rsp, dst_offset), rax); 1242 __ movq(rax, Address(rsp, -8)); 1243#ifndef PRODUCT 1244 } else { 1245 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1246 "movl rax, [rsp + #%d]\n\t" 1247 "movl [rsp + #%d], rax\n\t" 1248 "movq rax, [rsp - #8]", 1249 src_offset, dst_offset); 1250#endif 1251 } 1252 } 1253 return 0; 1254 } else if (dst_first_rc == rc_int) { 1255 // mem -> gpr 1256 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1257 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1258 // 64-bit 1259 int offset = ra_->reg2offset(src_first); 1260 if (cbuf) { 1261 MacroAssembler _masm(cbuf); 1262 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1263#ifndef PRODUCT 1264 } else { 1265 st->print("movq %s, [rsp + #%d]\t# spill", 1266 Matcher::regName[dst_first], 1267 offset); 1268#endif 1269 } 1270 } else { 1271 // 32-bit 1272 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1273 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1274 int offset = ra_->reg2offset(src_first); 1275 if (cbuf) { 1276 MacroAssembler _masm(cbuf); 1277 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1278#ifndef PRODUCT 1279 } else { 1280 st->print("movl %s, [rsp + #%d]\t# spill", 1281 Matcher::regName[dst_first], 1282 offset); 1283#endif 1284 } 1285 } 1286 return 0; 1287 } else if (dst_first_rc == rc_float) { 1288 // mem-> xmm 1289 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1290 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1291 // 64-bit 1292 int offset = ra_->reg2offset(src_first); 1293 if (cbuf) { 1294 MacroAssembler _masm(cbuf); 1295 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1296#ifndef PRODUCT 1297 } else { 1298 st->print("%s %s, [rsp + #%d]\t# spill", 1299 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1300 Matcher::regName[dst_first], 1301 offset); 1302#endif 1303 } 1304 } else { 1305 // 32-bit 1306 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1307 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1308 int offset = ra_->reg2offset(src_first); 1309 if (cbuf) { 1310 MacroAssembler _masm(cbuf); 1311 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1312#ifndef PRODUCT 1313 } else { 1314 st->print("movss %s, [rsp + #%d]\t# spill", 1315 Matcher::regName[dst_first], 1316 offset); 1317#endif 1318 } 1319 } 1320 return 0; 1321 } 1322 } else if (src_first_rc == rc_int) { 1323 // gpr -> 1324 if (dst_first_rc == rc_stack) { 1325 // gpr -> mem 1326 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1327 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1328 // 64-bit 1329 int offset = ra_->reg2offset(dst_first); 1330 if (cbuf) { 1331 MacroAssembler _masm(cbuf); 1332 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1333#ifndef PRODUCT 1334 } else { 1335 st->print("movq [rsp + #%d], %s\t# spill", 1336 offset, 1337 Matcher::regName[src_first]); 1338#endif 1339 } 1340 } else { 1341 // 32-bit 1342 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1343 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1344 int offset = ra_->reg2offset(dst_first); 1345 if (cbuf) { 1346 MacroAssembler _masm(cbuf); 1347 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1348#ifndef PRODUCT 1349 } else { 1350 st->print("movl [rsp + #%d], %s\t# spill", 1351 offset, 1352 Matcher::regName[src_first]); 1353#endif 1354 } 1355 } 1356 return 0; 1357 } else if (dst_first_rc == rc_int) { 1358 // gpr -> gpr 1359 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1360 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1361 // 64-bit 1362 if (cbuf) { 1363 MacroAssembler _masm(cbuf); 1364 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1365 as_Register(Matcher::_regEncode[src_first])); 1366#ifndef PRODUCT 1367 } else { 1368 st->print("movq %s, %s\t# spill", 1369 Matcher::regName[dst_first], 1370 Matcher::regName[src_first]); 1371#endif 1372 } 1373 return 0; 1374 } else { 1375 // 32-bit 1376 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1377 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1378 if (cbuf) { 1379 MacroAssembler _masm(cbuf); 1380 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1381 as_Register(Matcher::_regEncode[src_first])); 1382#ifndef PRODUCT 1383 } else { 1384 st->print("movl %s, %s\t# spill", 1385 Matcher::regName[dst_first], 1386 Matcher::regName[src_first]); 1387#endif 1388 } 1389 return 0; 1390 } 1391 } else if (dst_first_rc == rc_float) { 1392 // gpr -> xmm 1393 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1394 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1395 // 64-bit 1396 if (cbuf) { 1397 MacroAssembler _masm(cbuf); 1398 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1399#ifndef PRODUCT 1400 } else { 1401 st->print("movdq %s, %s\t# spill", 1402 Matcher::regName[dst_first], 1403 Matcher::regName[src_first]); 1404#endif 1405 } 1406 } else { 1407 // 32-bit 1408 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1409 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1410 if (cbuf) { 1411 MacroAssembler _masm(cbuf); 1412 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1413#ifndef PRODUCT 1414 } else { 1415 st->print("movdl %s, %s\t# spill", 1416 Matcher::regName[dst_first], 1417 Matcher::regName[src_first]); 1418#endif 1419 } 1420 } 1421 return 0; 1422 } 1423 } else if (src_first_rc == rc_float) { 1424 // xmm -> 1425 if (dst_first_rc == rc_stack) { 1426 // xmm -> mem 1427 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1428 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1429 // 64-bit 1430 int offset = ra_->reg2offset(dst_first); 1431 if (cbuf) { 1432 MacroAssembler _masm(cbuf); 1433 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1434#ifndef PRODUCT 1435 } else { 1436 st->print("movsd [rsp + #%d], %s\t# spill", 1437 offset, 1438 Matcher::regName[src_first]); 1439#endif 1440 } 1441 } else { 1442 // 32-bit 1443 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1444 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1445 int offset = ra_->reg2offset(dst_first); 1446 if (cbuf) { 1447 MacroAssembler _masm(cbuf); 1448 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1449#ifndef PRODUCT 1450 } else { 1451 st->print("movss [rsp + #%d], %s\t# spill", 1452 offset, 1453 Matcher::regName[src_first]); 1454#endif 1455 } 1456 } 1457 return 0; 1458 } else if (dst_first_rc == rc_int) { 1459 // xmm -> gpr 1460 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1461 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1462 // 64-bit 1463 if (cbuf) { 1464 MacroAssembler _masm(cbuf); 1465 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1466#ifndef PRODUCT 1467 } else { 1468 st->print("movdq %s, %s\t# spill", 1469 Matcher::regName[dst_first], 1470 Matcher::regName[src_first]); 1471#endif 1472 } 1473 } else { 1474 // 32-bit 1475 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1476 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1477 if (cbuf) { 1478 MacroAssembler _masm(cbuf); 1479 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1480#ifndef PRODUCT 1481 } else { 1482 st->print("movdl %s, %s\t# spill", 1483 Matcher::regName[dst_first], 1484 Matcher::regName[src_first]); 1485#endif 1486 } 1487 } 1488 return 0; 1489 } else if (dst_first_rc == rc_float) { 1490 // xmm -> xmm 1491 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1492 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1493 // 64-bit 1494 if (cbuf) { 1495 MacroAssembler _masm(cbuf); 1496 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1497#ifndef PRODUCT 1498 } else { 1499 st->print("%s %s, %s\t# spill", 1500 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1501 Matcher::regName[dst_first], 1502 Matcher::regName[src_first]); 1503#endif 1504 } 1505 } else { 1506 // 32-bit 1507 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1508 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1509 if (cbuf) { 1510 MacroAssembler _masm(cbuf); 1511 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1512#ifndef PRODUCT 1513 } else { 1514 st->print("%s %s, %s\t# spill", 1515 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1516 Matcher::regName[dst_first], 1517 Matcher::regName[src_first]); 1518#endif 1519 } 1520 } 1521 return 0; 1522 } 1523 } 1524 1525 assert(0," foo "); 1526 Unimplemented(); 1527 return 0; 1528} 1529 1530#ifndef PRODUCT 1531void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1532 implementation(NULL, ra_, false, st); 1533} 1534#endif 1535 1536void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1537 implementation(&cbuf, ra_, false, NULL); 1538} 1539 1540uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1541 return MachNode::size(ra_); 1542} 1543 1544//============================================================================= 1545#ifndef PRODUCT 1546void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1547{ 1548 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1549 int reg = ra_->get_reg_first(this); 1550 st->print("leaq %s, [rsp + #%d]\t# box lock", 1551 Matcher::regName[reg], offset); 1552} 1553#endif 1554 1555void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1556{ 1557 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1558 int reg = ra_->get_encode(this); 1559 if (offset >= 0x80) { 1560 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1561 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1562 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1563 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1564 emit_d32(cbuf, offset); 1565 } else { 1566 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1567 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1568 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1569 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1570 emit_d8(cbuf, offset); 1571 } 1572} 1573 1574uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1575{ 1576 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1577 return (offset < 0x80) ? 5 : 8; // REX 1578} 1579 1580//============================================================================= 1581#ifndef PRODUCT 1582void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1583{ 1584 if (UseCompressedClassPointers) { 1585 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1586 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1587 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1588 } else { 1589 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1590 "# Inline cache check"); 1591 } 1592 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1593 st->print_cr("\tnop\t# nops to align entry point"); 1594} 1595#endif 1596 1597void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1598{ 1599 MacroAssembler masm(&cbuf); 1600 uint insts_size = cbuf.insts_size(); 1601 if (UseCompressedClassPointers) { 1602 masm.load_klass(rscratch1, j_rarg0); 1603 masm.cmpptr(rax, rscratch1); 1604 } else { 1605 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1606 } 1607 1608 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1609 1610 /* WARNING these NOPs are critical so that verified entry point is properly 1611 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1612 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1613 if (OptoBreakpoint) { 1614 // Leave space for int3 1615 nops_cnt -= 1; 1616 } 1617 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1618 if (nops_cnt > 0) 1619 masm.nop(nops_cnt); 1620} 1621 1622uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1623{ 1624 return MachNode::size(ra_); // too many variables; just compute it 1625 // the hard way 1626} 1627 1628 1629//============================================================================= 1630 1631int Matcher::regnum_to_fpu_offset(int regnum) 1632{ 1633 return regnum - 32; // The FP registers are in the second chunk 1634} 1635 1636// This is UltraSparc specific, true just means we have fast l2f conversion 1637const bool Matcher::convL2FSupported(void) { 1638 return true; 1639} 1640 1641// Is this branch offset short enough that a short branch can be used? 1642// 1643// NOTE: If the platform does not provide any short branch variants, then 1644// this method should return false for offset 0. 1645bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1646 // The passed offset is relative to address of the branch. 1647 // On 86 a branch displacement is calculated relative to address 1648 // of a next instruction. 1649 offset -= br_size; 1650 1651 // the short version of jmpConUCF2 contains multiple branches, 1652 // making the reach slightly less 1653 if (rule == jmpConUCF2_rule) 1654 return (-126 <= offset && offset <= 125); 1655 return (-128 <= offset && offset <= 127); 1656} 1657 1658const bool Matcher::isSimpleConstant64(jlong value) { 1659 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1660 //return value == (int) value; // Cf. storeImmL and immL32. 1661 1662 // Probably always true, even if a temp register is required. 1663 return true; 1664} 1665 1666// The ecx parameter to rep stosq for the ClearArray node is in words. 1667const bool Matcher::init_array_count_is_in_bytes = false; 1668 1669// No additional cost for CMOVL. 1670const int Matcher::long_cmove_cost() { return 0; } 1671 1672// No CMOVF/CMOVD with SSE2 1673const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1674 1675// Does the CPU require late expand (see block.cpp for description of late expand)? 1676const bool Matcher::require_postalloc_expand = false; 1677 1678// Do we need to mask the count passed to shift instructions or does 1679// the cpu only look at the lower 5/6 bits anyway? 1680const bool Matcher::need_masked_shift_count = false; 1681 1682bool Matcher::narrow_oop_use_complex_address() { 1683 assert(UseCompressedOops, "only for compressed oops code"); 1684 return (LogMinObjAlignmentInBytes <= 3); 1685} 1686 1687bool Matcher::narrow_klass_use_complex_address() { 1688 assert(UseCompressedClassPointers, "only for compressed klass code"); 1689 return (LogKlassAlignmentInBytes <= 3); 1690} 1691 1692bool Matcher::const_oop_prefer_decode() { 1693 // Prefer ConN+DecodeN over ConP. 1694 return true; 1695} 1696 1697bool Matcher::const_klass_prefer_decode() { 1698 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1699 // or condisider the following: 1700 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1701 //return Universe::narrow_klass_base() == NULL; 1702 return true; 1703} 1704 1705// Is it better to copy float constants, or load them directly from 1706// memory? Intel can load a float constant from a direct address, 1707// requiring no extra registers. Most RISCs will have to materialize 1708// an address into a register first, so they would do better to copy 1709// the constant from stack. 1710const bool Matcher::rematerialize_float_constants = true; // XXX 1711 1712// If CPU can load and store mis-aligned doubles directly then no 1713// fixup is needed. Else we split the double into 2 integer pieces 1714// and move it piece-by-piece. Only happens when passing doubles into 1715// C code as the Java calling convention forces doubles to be aligned. 1716const bool Matcher::misaligned_doubles_ok = true; 1717 1718// No-op on amd64 1719void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1720 1721// Advertise here if the CPU requires explicit rounding operations to 1722// implement the UseStrictFP mode. 1723const bool Matcher::strict_fp_requires_explicit_rounding = true; 1724 1725// Are floats conerted to double when stored to stack during deoptimization? 1726// On x64 it is stored without convertion so we can use normal access. 1727bool Matcher::float_in_double() { return false; } 1728 1729// Do ints take an entire long register or just half? 1730const bool Matcher::int_in_long = true; 1731 1732// Return whether or not this register is ever used as an argument. 1733// This function is used on startup to build the trampoline stubs in 1734// generateOptoStub. Registers not mentioned will be killed by the VM 1735// call in the trampoline, and arguments in those registers not be 1736// available to the callee. 1737bool Matcher::can_be_java_arg(int reg) 1738{ 1739 return 1740 reg == RDI_num || reg == RDI_H_num || 1741 reg == RSI_num || reg == RSI_H_num || 1742 reg == RDX_num || reg == RDX_H_num || 1743 reg == RCX_num || reg == RCX_H_num || 1744 reg == R8_num || reg == R8_H_num || 1745 reg == R9_num || reg == R9_H_num || 1746 reg == R12_num || reg == R12_H_num || 1747 reg == XMM0_num || reg == XMM0b_num || 1748 reg == XMM1_num || reg == XMM1b_num || 1749 reg == XMM2_num || reg == XMM2b_num || 1750 reg == XMM3_num || reg == XMM3b_num || 1751 reg == XMM4_num || reg == XMM4b_num || 1752 reg == XMM5_num || reg == XMM5b_num || 1753 reg == XMM6_num || reg == XMM6b_num || 1754 reg == XMM7_num || reg == XMM7b_num; 1755} 1756 1757bool Matcher::is_spillable_arg(int reg) 1758{ 1759 return can_be_java_arg(reg); 1760} 1761 1762bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1763 // In 64 bit mode a code which use multiply when 1764 // devisor is constant is faster than hardware 1765 // DIV instruction (it uses MulHiL). 1766 return false; 1767} 1768 1769// Register for DIVI projection of divmodI 1770RegMask Matcher::divI_proj_mask() { 1771 return INT_RAX_REG_mask(); 1772} 1773 1774// Register for MODI projection of divmodI 1775RegMask Matcher::modI_proj_mask() { 1776 return INT_RDX_REG_mask(); 1777} 1778 1779// Register for DIVL projection of divmodL 1780RegMask Matcher::divL_proj_mask() { 1781 return LONG_RAX_REG_mask(); 1782} 1783 1784// Register for MODL projection of divmodL 1785RegMask Matcher::modL_proj_mask() { 1786 return LONG_RDX_REG_mask(); 1787} 1788 1789// Register for saving SP into on method handle invokes. Not used on x86_64. 1790const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1791 return NO_REG_mask(); 1792} 1793 1794%} 1795 1796//----------ENCODING BLOCK----------------------------------------------------- 1797// This block specifies the encoding classes used by the compiler to 1798// output byte streams. Encoding classes are parameterized macros 1799// used by Machine Instruction Nodes in order to generate the bit 1800// encoding of the instruction. Operands specify their base encoding 1801// interface with the interface keyword. There are currently 1802// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1803// COND_INTER. REG_INTER causes an operand to generate a function 1804// which returns its register number when queried. CONST_INTER causes 1805// an operand to generate a function which returns the value of the 1806// constant when queried. MEMORY_INTER causes an operand to generate 1807// four functions which return the Base Register, the Index Register, 1808// the Scale Value, and the Offset Value of the operand when queried. 1809// COND_INTER causes an operand to generate six functions which return 1810// the encoding code (ie - encoding bits for the instruction) 1811// associated with each basic boolean condition for a conditional 1812// instruction. 1813// 1814// Instructions specify two basic values for encoding. Again, a 1815// function is available to check if the constant displacement is an 1816// oop. They use the ins_encode keyword to specify their encoding 1817// classes (which must be a sequence of enc_class names, and their 1818// parameters, specified in the encoding block), and they use the 1819// opcode keyword to specify, in order, their primary, secondary, and 1820// tertiary opcode. Only the opcode sections which a particular 1821// instruction needs for encoding need to be specified. 1822encode %{ 1823 // Build emit functions for each basic byte or larger field in the 1824 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1825 // from C++ code in the enc_class source block. Emit functions will 1826 // live in the main source block for now. In future, we can 1827 // generalize this by adding a syntax that specifies the sizes of 1828 // fields in an order, so that the adlc can build the emit functions 1829 // automagically 1830 1831 // Emit primary opcode 1832 enc_class OpcP 1833 %{ 1834 emit_opcode(cbuf, $primary); 1835 %} 1836 1837 // Emit secondary opcode 1838 enc_class OpcS 1839 %{ 1840 emit_opcode(cbuf, $secondary); 1841 %} 1842 1843 // Emit tertiary opcode 1844 enc_class OpcT 1845 %{ 1846 emit_opcode(cbuf, $tertiary); 1847 %} 1848 1849 // Emit opcode directly 1850 enc_class Opcode(immI d8) 1851 %{ 1852 emit_opcode(cbuf, $d8$$constant); 1853 %} 1854 1855 // Emit size prefix 1856 enc_class SizePrefix 1857 %{ 1858 emit_opcode(cbuf, 0x66); 1859 %} 1860 1861 enc_class reg(rRegI reg) 1862 %{ 1863 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1864 %} 1865 1866 enc_class reg_reg(rRegI dst, rRegI src) 1867 %{ 1868 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1869 %} 1870 1871 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1872 %{ 1873 emit_opcode(cbuf, $opcode$$constant); 1874 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1875 %} 1876 1877 enc_class cdql_enc(no_rax_rdx_RegI div) 1878 %{ 1879 // Full implementation of Java idiv and irem; checks for 1880 // special case as described in JVM spec., p.243 & p.271. 1881 // 1882 // normal case special case 1883 // 1884 // input : rax: dividend min_int 1885 // reg: divisor -1 1886 // 1887 // output: rax: quotient (= rax idiv reg) min_int 1888 // rdx: remainder (= rax irem reg) 0 1889 // 1890 // Code sequnce: 1891 // 1892 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1893 // 5: 75 07/08 jne e <normal> 1894 // 7: 33 d2 xor %edx,%edx 1895 // [div >= 8 -> offset + 1] 1896 // [REX_B] 1897 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1898 // c: 74 03/04 je 11 <done> 1899 // 000000000000000e <normal>: 1900 // e: 99 cltd 1901 // [div >= 8 -> offset + 1] 1902 // [REX_B] 1903 // f: f7 f9 idiv $div 1904 // 0000000000000011 <done>: 1905 1906 // cmp $0x80000000,%eax 1907 emit_opcode(cbuf, 0x3d); 1908 emit_d8(cbuf, 0x00); 1909 emit_d8(cbuf, 0x00); 1910 emit_d8(cbuf, 0x00); 1911 emit_d8(cbuf, 0x80); 1912 1913 // jne e <normal> 1914 emit_opcode(cbuf, 0x75); 1915 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1916 1917 // xor %edx,%edx 1918 emit_opcode(cbuf, 0x33); 1919 emit_d8(cbuf, 0xD2); 1920 1921 // cmp $0xffffffffffffffff,%ecx 1922 if ($div$$reg >= 8) { 1923 emit_opcode(cbuf, Assembler::REX_B); 1924 } 1925 emit_opcode(cbuf, 0x83); 1926 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1927 emit_d8(cbuf, 0xFF); 1928 1929 // je 11 <done> 1930 emit_opcode(cbuf, 0x74); 1931 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1932 1933 // <normal> 1934 // cltd 1935 emit_opcode(cbuf, 0x99); 1936 1937 // idivl (note: must be emitted by the user of this rule) 1938 // <done> 1939 %} 1940 1941 enc_class cdqq_enc(no_rax_rdx_RegL div) 1942 %{ 1943 // Full implementation of Java ldiv and lrem; checks for 1944 // special case as described in JVM spec., p.243 & p.271. 1945 // 1946 // normal case special case 1947 // 1948 // input : rax: dividend min_long 1949 // reg: divisor -1 1950 // 1951 // output: rax: quotient (= rax idiv reg) min_long 1952 // rdx: remainder (= rax irem reg) 0 1953 // 1954 // Code sequnce: 1955 // 1956 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1957 // 7: 00 00 80 1958 // a: 48 39 d0 cmp %rdx,%rax 1959 // d: 75 08 jne 17 <normal> 1960 // f: 33 d2 xor %edx,%edx 1961 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1962 // 15: 74 05 je 1c <done> 1963 // 0000000000000017 <normal>: 1964 // 17: 48 99 cqto 1965 // 19: 48 f7 f9 idiv $div 1966 // 000000000000001c <done>: 1967 1968 // mov $0x8000000000000000,%rdx 1969 emit_opcode(cbuf, Assembler::REX_W); 1970 emit_opcode(cbuf, 0xBA); 1971 emit_d8(cbuf, 0x00); 1972 emit_d8(cbuf, 0x00); 1973 emit_d8(cbuf, 0x00); 1974 emit_d8(cbuf, 0x00); 1975 emit_d8(cbuf, 0x00); 1976 emit_d8(cbuf, 0x00); 1977 emit_d8(cbuf, 0x00); 1978 emit_d8(cbuf, 0x80); 1979 1980 // cmp %rdx,%rax 1981 emit_opcode(cbuf, Assembler::REX_W); 1982 emit_opcode(cbuf, 0x39); 1983 emit_d8(cbuf, 0xD0); 1984 1985 // jne 17 <normal> 1986 emit_opcode(cbuf, 0x75); 1987 emit_d8(cbuf, 0x08); 1988 1989 // xor %edx,%edx 1990 emit_opcode(cbuf, 0x33); 1991 emit_d8(cbuf, 0xD2); 1992 1993 // cmp $0xffffffffffffffff,$div 1994 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1995 emit_opcode(cbuf, 0x83); 1996 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1997 emit_d8(cbuf, 0xFF); 1998 1999 // je 1e <done> 2000 emit_opcode(cbuf, 0x74); 2001 emit_d8(cbuf, 0x05); 2002 2003 // <normal> 2004 // cqto 2005 emit_opcode(cbuf, Assembler::REX_W); 2006 emit_opcode(cbuf, 0x99); 2007 2008 // idivq (note: must be emitted by the user of this rule) 2009 // <done> 2010 %} 2011 2012 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2013 enc_class OpcSE(immI imm) 2014 %{ 2015 // Emit primary opcode and set sign-extend bit 2016 // Check for 8-bit immediate, and set sign extend bit in opcode 2017 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2018 emit_opcode(cbuf, $primary | 0x02); 2019 } else { 2020 // 32-bit immediate 2021 emit_opcode(cbuf, $primary); 2022 } 2023 %} 2024 2025 enc_class OpcSErm(rRegI dst, immI imm) 2026 %{ 2027 // OpcSEr/m 2028 int dstenc = $dst$$reg; 2029 if (dstenc >= 8) { 2030 emit_opcode(cbuf, Assembler::REX_B); 2031 dstenc -= 8; 2032 } 2033 // Emit primary opcode and set sign-extend bit 2034 // Check for 8-bit immediate, and set sign extend bit in opcode 2035 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2036 emit_opcode(cbuf, $primary | 0x02); 2037 } else { 2038 // 32-bit immediate 2039 emit_opcode(cbuf, $primary); 2040 } 2041 // Emit r/m byte with secondary opcode, after primary opcode. 2042 emit_rm(cbuf, 0x3, $secondary, dstenc); 2043 %} 2044 2045 enc_class OpcSErm_wide(rRegL dst, immI imm) 2046 %{ 2047 // OpcSEr/m 2048 int dstenc = $dst$$reg; 2049 if (dstenc < 8) { 2050 emit_opcode(cbuf, Assembler::REX_W); 2051 } else { 2052 emit_opcode(cbuf, Assembler::REX_WB); 2053 dstenc -= 8; 2054 } 2055 // Emit primary opcode and set sign-extend bit 2056 // Check for 8-bit immediate, and set sign extend bit in opcode 2057 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2058 emit_opcode(cbuf, $primary | 0x02); 2059 } else { 2060 // 32-bit immediate 2061 emit_opcode(cbuf, $primary); 2062 } 2063 // Emit r/m byte with secondary opcode, after primary opcode. 2064 emit_rm(cbuf, 0x3, $secondary, dstenc); 2065 %} 2066 2067 enc_class Con8or32(immI imm) 2068 %{ 2069 // Check for 8-bit immediate, and set sign extend bit in opcode 2070 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2071 $$$emit8$imm$$constant; 2072 } else { 2073 // 32-bit immediate 2074 $$$emit32$imm$$constant; 2075 } 2076 %} 2077 2078 enc_class opc2_reg(rRegI dst) 2079 %{ 2080 // BSWAP 2081 emit_cc(cbuf, $secondary, $dst$$reg); 2082 %} 2083 2084 enc_class opc3_reg(rRegI dst) 2085 %{ 2086 // BSWAP 2087 emit_cc(cbuf, $tertiary, $dst$$reg); 2088 %} 2089 2090 enc_class reg_opc(rRegI div) 2091 %{ 2092 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2093 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2094 %} 2095 2096 enc_class enc_cmov(cmpOp cop) 2097 %{ 2098 // CMOV 2099 $$$emit8$primary; 2100 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2101 %} 2102 2103 enc_class enc_PartialSubtypeCheck() 2104 %{ 2105 Register Rrdi = as_Register(RDI_enc); // result register 2106 Register Rrax = as_Register(RAX_enc); // super class 2107 Register Rrcx = as_Register(RCX_enc); // killed 2108 Register Rrsi = as_Register(RSI_enc); // sub class 2109 Label miss; 2110 const bool set_cond_codes = true; 2111 2112 MacroAssembler _masm(&cbuf); 2113 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2114 NULL, &miss, 2115 /*set_cond_codes:*/ true); 2116 if ($primary) { 2117 __ xorptr(Rrdi, Rrdi); 2118 } 2119 __ bind(miss); 2120 %} 2121 2122 enc_class clear_avx %{ 2123 debug_only(int off0 = cbuf.insts_size()); 2124 if (generate_vzeroupper(Compile::current())) { 2125 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2126 // Clear upper bits of YMM registers when current compiled code uses 2127 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2128 MacroAssembler _masm(&cbuf); 2129 __ vzeroupper(); 2130 } 2131 debug_only(int off1 = cbuf.insts_size()); 2132 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2133 %} 2134 2135 enc_class Java_To_Runtime(method meth) %{ 2136 // No relocation needed 2137 MacroAssembler _masm(&cbuf); 2138 __ mov64(r10, (int64_t) $meth$$method); 2139 __ call(r10); 2140 %} 2141 2142 enc_class Java_To_Interpreter(method meth) 2143 %{ 2144 // CALL Java_To_Interpreter 2145 // This is the instruction starting address for relocation info. 2146 cbuf.set_insts_mark(); 2147 $$$emit8$primary; 2148 // CALL directly to the runtime 2149 emit_d32_reloc(cbuf, 2150 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2151 runtime_call_Relocation::spec(), 2152 RELOC_DISP32); 2153 %} 2154 2155 enc_class Java_Static_Call(method meth) 2156 %{ 2157 // JAVA STATIC CALL 2158 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2159 // determine who we intended to call. 2160 cbuf.set_insts_mark(); 2161 $$$emit8$primary; 2162 2163 if (!_method) { 2164 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2165 runtime_call_Relocation::spec(), 2166 RELOC_DISP32); 2167 } else { 2168 int method_index = resolved_method_index(cbuf); 2169 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2170 : static_call_Relocation::spec(method_index); 2171 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2172 rspec, RELOC_DISP32); 2173 // Emit stubs for static call. 2174 address mark = cbuf.insts_mark(); 2175 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2176 if (stub == NULL) { 2177 ciEnv::current()->record_failure("CodeCache is full"); 2178 return; 2179 } 2180#if INCLUDE_AOT 2181 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2182#endif 2183 } 2184 %} 2185 2186 enc_class Java_Dynamic_Call(method meth) %{ 2187 MacroAssembler _masm(&cbuf); 2188 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2189 %} 2190 2191 enc_class Java_Compiled_Call(method meth) 2192 %{ 2193 // JAVA COMPILED CALL 2194 int disp = in_bytes(Method:: from_compiled_offset()); 2195 2196 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2197 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2198 2199 // callq *disp(%rax) 2200 cbuf.set_insts_mark(); 2201 $$$emit8$primary; 2202 if (disp < 0x80) { 2203 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2204 emit_d8(cbuf, disp); // Displacement 2205 } else { 2206 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2207 emit_d32(cbuf, disp); // Displacement 2208 } 2209 %} 2210 2211 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2212 %{ 2213 // SAL, SAR, SHR 2214 int dstenc = $dst$$reg; 2215 if (dstenc >= 8) { 2216 emit_opcode(cbuf, Assembler::REX_B); 2217 dstenc -= 8; 2218 } 2219 $$$emit8$primary; 2220 emit_rm(cbuf, 0x3, $secondary, dstenc); 2221 $$$emit8$shift$$constant; 2222 %} 2223 2224 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2225 %{ 2226 // SAL, SAR, SHR 2227 int dstenc = $dst$$reg; 2228 if (dstenc < 8) { 2229 emit_opcode(cbuf, Assembler::REX_W); 2230 } else { 2231 emit_opcode(cbuf, Assembler::REX_WB); 2232 dstenc -= 8; 2233 } 2234 $$$emit8$primary; 2235 emit_rm(cbuf, 0x3, $secondary, dstenc); 2236 $$$emit8$shift$$constant; 2237 %} 2238 2239 enc_class load_immI(rRegI dst, immI src) 2240 %{ 2241 int dstenc = $dst$$reg; 2242 if (dstenc >= 8) { 2243 emit_opcode(cbuf, Assembler::REX_B); 2244 dstenc -= 8; 2245 } 2246 emit_opcode(cbuf, 0xB8 | dstenc); 2247 $$$emit32$src$$constant; 2248 %} 2249 2250 enc_class load_immL(rRegL dst, immL src) 2251 %{ 2252 int dstenc = $dst$$reg; 2253 if (dstenc < 8) { 2254 emit_opcode(cbuf, Assembler::REX_W); 2255 } else { 2256 emit_opcode(cbuf, Assembler::REX_WB); 2257 dstenc -= 8; 2258 } 2259 emit_opcode(cbuf, 0xB8 | dstenc); 2260 emit_d64(cbuf, $src$$constant); 2261 %} 2262 2263 enc_class load_immUL32(rRegL dst, immUL32 src) 2264 %{ 2265 // same as load_immI, but this time we care about zeroes in the high word 2266 int dstenc = $dst$$reg; 2267 if (dstenc >= 8) { 2268 emit_opcode(cbuf, Assembler::REX_B); 2269 dstenc -= 8; 2270 } 2271 emit_opcode(cbuf, 0xB8 | dstenc); 2272 $$$emit32$src$$constant; 2273 %} 2274 2275 enc_class load_immL32(rRegL dst, immL32 src) 2276 %{ 2277 int dstenc = $dst$$reg; 2278 if (dstenc < 8) { 2279 emit_opcode(cbuf, Assembler::REX_W); 2280 } else { 2281 emit_opcode(cbuf, Assembler::REX_WB); 2282 dstenc -= 8; 2283 } 2284 emit_opcode(cbuf, 0xC7); 2285 emit_rm(cbuf, 0x03, 0x00, dstenc); 2286 $$$emit32$src$$constant; 2287 %} 2288 2289 enc_class load_immP31(rRegP dst, immP32 src) 2290 %{ 2291 // same as load_immI, but this time we care about zeroes in the high word 2292 int dstenc = $dst$$reg; 2293 if (dstenc >= 8) { 2294 emit_opcode(cbuf, Assembler::REX_B); 2295 dstenc -= 8; 2296 } 2297 emit_opcode(cbuf, 0xB8 | dstenc); 2298 $$$emit32$src$$constant; 2299 %} 2300 2301 enc_class load_immP(rRegP dst, immP src) 2302 %{ 2303 int dstenc = $dst$$reg; 2304 if (dstenc < 8) { 2305 emit_opcode(cbuf, Assembler::REX_W); 2306 } else { 2307 emit_opcode(cbuf, Assembler::REX_WB); 2308 dstenc -= 8; 2309 } 2310 emit_opcode(cbuf, 0xB8 | dstenc); 2311 // This next line should be generated from ADLC 2312 if ($src->constant_reloc() != relocInfo::none) { 2313 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2314 } else { 2315 emit_d64(cbuf, $src$$constant); 2316 } 2317 %} 2318 2319 enc_class Con32(immI src) 2320 %{ 2321 // Output immediate 2322 $$$emit32$src$$constant; 2323 %} 2324 2325 enc_class Con32F_as_bits(immF src) 2326 %{ 2327 // Output Float immediate bits 2328 jfloat jf = $src$$constant; 2329 jint jf_as_bits = jint_cast(jf); 2330 emit_d32(cbuf, jf_as_bits); 2331 %} 2332 2333 enc_class Con16(immI src) 2334 %{ 2335 // Output immediate 2336 $$$emit16$src$$constant; 2337 %} 2338 2339 // How is this different from Con32??? XXX 2340 enc_class Con_d32(immI src) 2341 %{ 2342 emit_d32(cbuf,$src$$constant); 2343 %} 2344 2345 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2346 // Output immediate memory reference 2347 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2348 emit_d32(cbuf, 0x00); 2349 %} 2350 2351 enc_class lock_prefix() 2352 %{ 2353 emit_opcode(cbuf, 0xF0); // lock 2354 %} 2355 2356 enc_class REX_mem(memory mem) 2357 %{ 2358 if ($mem$$base >= 8) { 2359 if ($mem$$index < 8) { 2360 emit_opcode(cbuf, Assembler::REX_B); 2361 } else { 2362 emit_opcode(cbuf, Assembler::REX_XB); 2363 } 2364 } else { 2365 if ($mem$$index >= 8) { 2366 emit_opcode(cbuf, Assembler::REX_X); 2367 } 2368 } 2369 %} 2370 2371 enc_class REX_mem_wide(memory mem) 2372 %{ 2373 if ($mem$$base >= 8) { 2374 if ($mem$$index < 8) { 2375 emit_opcode(cbuf, Assembler::REX_WB); 2376 } else { 2377 emit_opcode(cbuf, Assembler::REX_WXB); 2378 } 2379 } else { 2380 if ($mem$$index < 8) { 2381 emit_opcode(cbuf, Assembler::REX_W); 2382 } else { 2383 emit_opcode(cbuf, Assembler::REX_WX); 2384 } 2385 } 2386 %} 2387 2388 // for byte regs 2389 enc_class REX_breg(rRegI reg) 2390 %{ 2391 if ($reg$$reg >= 4) { 2392 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2393 } 2394 %} 2395 2396 // for byte regs 2397 enc_class REX_reg_breg(rRegI dst, rRegI src) 2398 %{ 2399 if ($dst$$reg < 8) { 2400 if ($src$$reg >= 4) { 2401 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2402 } 2403 } else { 2404 if ($src$$reg < 8) { 2405 emit_opcode(cbuf, Assembler::REX_R); 2406 } else { 2407 emit_opcode(cbuf, Assembler::REX_RB); 2408 } 2409 } 2410 %} 2411 2412 // for byte regs 2413 enc_class REX_breg_mem(rRegI reg, memory mem) 2414 %{ 2415 if ($reg$$reg < 8) { 2416 if ($mem$$base < 8) { 2417 if ($mem$$index >= 8) { 2418 emit_opcode(cbuf, Assembler::REX_X); 2419 } else if ($reg$$reg >= 4) { 2420 emit_opcode(cbuf, Assembler::REX); 2421 } 2422 } else { 2423 if ($mem$$index < 8) { 2424 emit_opcode(cbuf, Assembler::REX_B); 2425 } else { 2426 emit_opcode(cbuf, Assembler::REX_XB); 2427 } 2428 } 2429 } else { 2430 if ($mem$$base < 8) { 2431 if ($mem$$index < 8) { 2432 emit_opcode(cbuf, Assembler::REX_R); 2433 } else { 2434 emit_opcode(cbuf, Assembler::REX_RX); 2435 } 2436 } else { 2437 if ($mem$$index < 8) { 2438 emit_opcode(cbuf, Assembler::REX_RB); 2439 } else { 2440 emit_opcode(cbuf, Assembler::REX_RXB); 2441 } 2442 } 2443 } 2444 %} 2445 2446 enc_class REX_reg(rRegI reg) 2447 %{ 2448 if ($reg$$reg >= 8) { 2449 emit_opcode(cbuf, Assembler::REX_B); 2450 } 2451 %} 2452 2453 enc_class REX_reg_wide(rRegI reg) 2454 %{ 2455 if ($reg$$reg < 8) { 2456 emit_opcode(cbuf, Assembler::REX_W); 2457 } else { 2458 emit_opcode(cbuf, Assembler::REX_WB); 2459 } 2460 %} 2461 2462 enc_class REX_reg_reg(rRegI dst, rRegI src) 2463 %{ 2464 if ($dst$$reg < 8) { 2465 if ($src$$reg >= 8) { 2466 emit_opcode(cbuf, Assembler::REX_B); 2467 } 2468 } else { 2469 if ($src$$reg < 8) { 2470 emit_opcode(cbuf, Assembler::REX_R); 2471 } else { 2472 emit_opcode(cbuf, Assembler::REX_RB); 2473 } 2474 } 2475 %} 2476 2477 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2478 %{ 2479 if ($dst$$reg < 8) { 2480 if ($src$$reg < 8) { 2481 emit_opcode(cbuf, Assembler::REX_W); 2482 } else { 2483 emit_opcode(cbuf, Assembler::REX_WB); 2484 } 2485 } else { 2486 if ($src$$reg < 8) { 2487 emit_opcode(cbuf, Assembler::REX_WR); 2488 } else { 2489 emit_opcode(cbuf, Assembler::REX_WRB); 2490 } 2491 } 2492 %} 2493 2494 enc_class REX_reg_mem(rRegI reg, memory mem) 2495 %{ 2496 if ($reg$$reg < 8) { 2497 if ($mem$$base < 8) { 2498 if ($mem$$index >= 8) { 2499 emit_opcode(cbuf, Assembler::REX_X); 2500 } 2501 } else { 2502 if ($mem$$index < 8) { 2503 emit_opcode(cbuf, Assembler::REX_B); 2504 } else { 2505 emit_opcode(cbuf, Assembler::REX_XB); 2506 } 2507 } 2508 } else { 2509 if ($mem$$base < 8) { 2510 if ($mem$$index < 8) { 2511 emit_opcode(cbuf, Assembler::REX_R); 2512 } else { 2513 emit_opcode(cbuf, Assembler::REX_RX); 2514 } 2515 } else { 2516 if ($mem$$index < 8) { 2517 emit_opcode(cbuf, Assembler::REX_RB); 2518 } else { 2519 emit_opcode(cbuf, Assembler::REX_RXB); 2520 } 2521 } 2522 } 2523 %} 2524 2525 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2526 %{ 2527 if ($reg$$reg < 8) { 2528 if ($mem$$base < 8) { 2529 if ($mem$$index < 8) { 2530 emit_opcode(cbuf, Assembler::REX_W); 2531 } else { 2532 emit_opcode(cbuf, Assembler::REX_WX); 2533 } 2534 } else { 2535 if ($mem$$index < 8) { 2536 emit_opcode(cbuf, Assembler::REX_WB); 2537 } else { 2538 emit_opcode(cbuf, Assembler::REX_WXB); 2539 } 2540 } 2541 } else { 2542 if ($mem$$base < 8) { 2543 if ($mem$$index < 8) { 2544 emit_opcode(cbuf, Assembler::REX_WR); 2545 } else { 2546 emit_opcode(cbuf, Assembler::REX_WRX); 2547 } 2548 } else { 2549 if ($mem$$index < 8) { 2550 emit_opcode(cbuf, Assembler::REX_WRB); 2551 } else { 2552 emit_opcode(cbuf, Assembler::REX_WRXB); 2553 } 2554 } 2555 } 2556 %} 2557 2558 enc_class reg_mem(rRegI ereg, memory mem) 2559 %{ 2560 // High registers handle in encode_RegMem 2561 int reg = $ereg$$reg; 2562 int base = $mem$$base; 2563 int index = $mem$$index; 2564 int scale = $mem$$scale; 2565 int disp = $mem$$disp; 2566 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2567 2568 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2569 %} 2570 2571 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2572 %{ 2573 int rm_byte_opcode = $rm_opcode$$constant; 2574 2575 // High registers handle in encode_RegMem 2576 int base = $mem$$base; 2577 int index = $mem$$index; 2578 int scale = $mem$$scale; 2579 int displace = $mem$$disp; 2580 2581 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2582 // working with static 2583 // globals 2584 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2585 disp_reloc); 2586 %} 2587 2588 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2589 %{ 2590 int reg_encoding = $dst$$reg; 2591 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2592 int index = 0x04; // 0x04 indicates no index 2593 int scale = 0x00; // 0x00 indicates no scale 2594 int displace = $src1$$constant; // 0x00 indicates no displacement 2595 relocInfo::relocType disp_reloc = relocInfo::none; 2596 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2597 disp_reloc); 2598 %} 2599 2600 enc_class neg_reg(rRegI dst) 2601 %{ 2602 int dstenc = $dst$$reg; 2603 if (dstenc >= 8) { 2604 emit_opcode(cbuf, Assembler::REX_B); 2605 dstenc -= 8; 2606 } 2607 // NEG $dst 2608 emit_opcode(cbuf, 0xF7); 2609 emit_rm(cbuf, 0x3, 0x03, dstenc); 2610 %} 2611 2612 enc_class neg_reg_wide(rRegI dst) 2613 %{ 2614 int dstenc = $dst$$reg; 2615 if (dstenc < 8) { 2616 emit_opcode(cbuf, Assembler::REX_W); 2617 } else { 2618 emit_opcode(cbuf, Assembler::REX_WB); 2619 dstenc -= 8; 2620 } 2621 // NEG $dst 2622 emit_opcode(cbuf, 0xF7); 2623 emit_rm(cbuf, 0x3, 0x03, dstenc); 2624 %} 2625 2626 enc_class setLT_reg(rRegI dst) 2627 %{ 2628 int dstenc = $dst$$reg; 2629 if (dstenc >= 8) { 2630 emit_opcode(cbuf, Assembler::REX_B); 2631 dstenc -= 8; 2632 } else if (dstenc >= 4) { 2633 emit_opcode(cbuf, Assembler::REX); 2634 } 2635 // SETLT $dst 2636 emit_opcode(cbuf, 0x0F); 2637 emit_opcode(cbuf, 0x9C); 2638 emit_rm(cbuf, 0x3, 0x0, dstenc); 2639 %} 2640 2641 enc_class setNZ_reg(rRegI dst) 2642 %{ 2643 int dstenc = $dst$$reg; 2644 if (dstenc >= 8) { 2645 emit_opcode(cbuf, Assembler::REX_B); 2646 dstenc -= 8; 2647 } else if (dstenc >= 4) { 2648 emit_opcode(cbuf, Assembler::REX); 2649 } 2650 // SETNZ $dst 2651 emit_opcode(cbuf, 0x0F); 2652 emit_opcode(cbuf, 0x95); 2653 emit_rm(cbuf, 0x3, 0x0, dstenc); 2654 %} 2655 2656 2657 // Compare the lonogs and set -1, 0, or 1 into dst 2658 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2659 %{ 2660 int src1enc = $src1$$reg; 2661 int src2enc = $src2$$reg; 2662 int dstenc = $dst$$reg; 2663 2664 // cmpq $src1, $src2 2665 if (src1enc < 8) { 2666 if (src2enc < 8) { 2667 emit_opcode(cbuf, Assembler::REX_W); 2668 } else { 2669 emit_opcode(cbuf, Assembler::REX_WB); 2670 } 2671 } else { 2672 if (src2enc < 8) { 2673 emit_opcode(cbuf, Assembler::REX_WR); 2674 } else { 2675 emit_opcode(cbuf, Assembler::REX_WRB); 2676 } 2677 } 2678 emit_opcode(cbuf, 0x3B); 2679 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2680 2681 // movl $dst, -1 2682 if (dstenc >= 8) { 2683 emit_opcode(cbuf, Assembler::REX_B); 2684 } 2685 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2686 emit_d32(cbuf, -1); 2687 2688 // jl,s done 2689 emit_opcode(cbuf, 0x7C); 2690 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2691 2692 // setne $dst 2693 if (dstenc >= 4) { 2694 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2695 } 2696 emit_opcode(cbuf, 0x0F); 2697 emit_opcode(cbuf, 0x95); 2698 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2699 2700 // movzbl $dst, $dst 2701 if (dstenc >= 4) { 2702 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2703 } 2704 emit_opcode(cbuf, 0x0F); 2705 emit_opcode(cbuf, 0xB6); 2706 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2707 %} 2708 2709 enc_class Push_ResultXD(regD dst) %{ 2710 MacroAssembler _masm(&cbuf); 2711 __ fstp_d(Address(rsp, 0)); 2712 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2713 __ addptr(rsp, 8); 2714 %} 2715 2716 enc_class Push_SrcXD(regD src) %{ 2717 MacroAssembler _masm(&cbuf); 2718 __ subptr(rsp, 8); 2719 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2720 __ fld_d(Address(rsp, 0)); 2721 %} 2722 2723 2724 enc_class enc_rethrow() 2725 %{ 2726 cbuf.set_insts_mark(); 2727 emit_opcode(cbuf, 0xE9); // jmp entry 2728 emit_d32_reloc(cbuf, 2729 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2730 runtime_call_Relocation::spec(), 2731 RELOC_DISP32); 2732 %} 2733 2734%} 2735 2736 2737 2738//----------FRAME-------------------------------------------------------------- 2739// Definition of frame structure and management information. 2740// 2741// S T A C K L A Y O U T Allocators stack-slot number 2742// | (to get allocators register number 2743// G Owned by | | v add OptoReg::stack0()) 2744// r CALLER | | 2745// o | +--------+ pad to even-align allocators stack-slot 2746// w V | pad0 | numbers; owned by CALLER 2747// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2748// h ^ | in | 5 2749// | | args | 4 Holes in incoming args owned by SELF 2750// | | | | 3 2751// | | +--------+ 2752// V | | old out| Empty on Intel, window on Sparc 2753// | old |preserve| Must be even aligned. 2754// | SP-+--------+----> Matcher::_old_SP, even aligned 2755// | | in | 3 area for Intel ret address 2756// Owned by |preserve| Empty on Sparc. 2757// SELF +--------+ 2758// | | pad2 | 2 pad to align old SP 2759// | +--------+ 1 2760// | | locks | 0 2761// | +--------+----> OptoReg::stack0(), even aligned 2762// | | pad1 | 11 pad to align new SP 2763// | +--------+ 2764// | | | 10 2765// | | spills | 9 spills 2766// V | | 8 (pad0 slot for callee) 2767// -----------+--------+----> Matcher::_out_arg_limit, unaligned 2768// ^ | out | 7 2769// | | args | 6 Holes in outgoing args owned by CALLEE 2770// Owned by +--------+ 2771// CALLEE | new out| 6 Empty on Intel, window on Sparc 2772// | new |preserve| Must be even-aligned. 2773// | SP-+--------+----> Matcher::_new_SP, even aligned 2774// | | | 2775// 2776// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2777// known from SELF's arguments and the Java calling convention. 2778// Region 6-7 is determined per call site. 2779// Note 2: If the calling convention leaves holes in the incoming argument 2780// area, those holes are owned by SELF. Holes in the outgoing area 2781// are owned by the CALLEE. Holes should not be nessecary in the 2782// incoming area, as the Java calling convention is completely under 2783// the control of the AD file. Doubles can be sorted and packed to 2784// avoid holes. Holes in the outgoing arguments may be nessecary for 2785// varargs C calling conventions. 2786// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2787// even aligned with pad0 as needed. 2788// Region 6 is even aligned. Region 6-7 is NOT even aligned; 2789// region 6-11 is even aligned; it may be padded out more so that 2790// the region from SP to FP meets the minimum stack alignment. 2791// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2792// alignment. Region 11, pad1, may be dynamically extended so that 2793// SP meets the minimum alignment. 2794 2795frame 2796%{ 2797 // What direction does stack grow in (assumed to be same for C & Java) 2798 stack_direction(TOWARDS_LOW); 2799 2800 // These three registers define part of the calling convention 2801 // between compiled code and the interpreter. 2802 inline_cache_reg(RAX); // Inline Cache Register 2803 interpreter_method_oop_reg(RBX); // Method Oop Register when 2804 // calling interpreter 2805 2806 // Optional: name the operand used by cisc-spilling to access 2807 // [stack_pointer + offset] 2808 cisc_spilling_operand_name(indOffset32); 2809 2810 // Number of stack slots consumed by locking an object 2811 sync_stack_slots(2); 2812 2813 // Compiled code's Frame Pointer 2814 frame_pointer(RSP); 2815 2816 // Interpreter stores its frame pointer in a register which is 2817 // stored to the stack by I2CAdaptors. 2818 // I2CAdaptors convert from interpreted java to compiled java. 2819 interpreter_frame_pointer(RBP); 2820 2821 // Stack alignment requirement 2822 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2823 2824 // Number of stack slots between incoming argument block and the start of 2825 // a new frame. The PROLOG must add this many slots to the stack. The 2826 // EPILOG must remove this many slots. amd64 needs two slots for 2827 // return address. 2828 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2829 2830 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2831 // for calls to C. Supports the var-args backing area for register parms. 2832 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2833 2834 // The after-PROLOG location of the return address. Location of 2835 // return address specifies a type (REG or STACK) and a number 2836 // representing the register number (i.e. - use a register name) or 2837 // stack slot. 2838 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2839 // Otherwise, it is above the locks and verification slot and alignment word 2840 return_addr(STACK - 2 + 2841 align_up((Compile::current()->in_preserve_stack_slots() + 2842 Compile::current()->fixed_slots()), 2843 stack_alignment_in_slots())); 2844 2845 // Body of function which returns an integer array locating 2846 // arguments either in registers or in stack slots. Passed an array 2847 // of ideal registers called "sig" and a "length" count. Stack-slot 2848 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2849 // arguments for a CALLEE. Incoming stack arguments are 2850 // automatically biased by the preserve_stack_slots field above. 2851 2852 calling_convention 2853 %{ 2854 // No difference between ingoing/outgoing just pass false 2855 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2856 %} 2857 2858 c_calling_convention 2859 %{ 2860 // This is obviously always outgoing 2861 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2862 %} 2863 2864 // Location of compiled Java return values. Same as C for now. 2865 return_value 2866 %{ 2867 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2868 "only return normal values"); 2869 2870 static const int lo[Op_RegL + 1] = { 2871 0, 2872 0, 2873 RAX_num, // Op_RegN 2874 RAX_num, // Op_RegI 2875 RAX_num, // Op_RegP 2876 XMM0_num, // Op_RegF 2877 XMM0_num, // Op_RegD 2878 RAX_num // Op_RegL 2879 }; 2880 static const int hi[Op_RegL + 1] = { 2881 0, 2882 0, 2883 OptoReg::Bad, // Op_RegN 2884 OptoReg::Bad, // Op_RegI 2885 RAX_H_num, // Op_RegP 2886 OptoReg::Bad, // Op_RegF 2887 XMM0b_num, // Op_RegD 2888 RAX_H_num // Op_RegL 2889 }; 2890 // Excluded flags and vector registers. 2891 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2892 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2893 %} 2894%} 2895 2896//----------ATTRIBUTES--------------------------------------------------------- 2897//----------Operand Attributes------------------------------------------------- 2898op_attrib op_cost(0); // Required cost attribute 2899 2900//----------Instruction Attributes--------------------------------------------- 2901ins_attrib ins_cost(100); // Required cost attribute 2902ins_attrib ins_size(8); // Required size attribute (in bits) 2903ins_attrib ins_short_branch(0); // Required flag: is this instruction 2904 // a non-matching short branch variant 2905 // of some long branch? 2906ins_attrib ins_alignment(1); // Required alignment attribute (must 2907 // be a power of 2) specifies the 2908 // alignment that some part of the 2909 // instruction (not necessarily the 2910 // start) requires. If > 1, a 2911 // compute_padding() function must be 2912 // provided for the instruction 2913 2914//----------OPERANDS----------------------------------------------------------- 2915// Operand definitions must precede instruction definitions for correct parsing 2916// in the ADLC because operands constitute user defined types which are used in 2917// instruction definitions. 2918 2919//----------Simple Operands---------------------------------------------------- 2920// Immediate Operands 2921// Integer Immediate 2922operand immI() 2923%{ 2924 match(ConI); 2925 2926 op_cost(10); 2927 format %{ %} 2928 interface(CONST_INTER); 2929%} 2930 2931// Constant for test vs zero 2932operand immI0() 2933%{ 2934 predicate(n->get_int() == 0); 2935 match(ConI); 2936 2937 op_cost(0); 2938 format %{ %} 2939 interface(CONST_INTER); 2940%} 2941 2942// Constant for increment 2943operand immI1() 2944%{ 2945 predicate(n->get_int() == 1); 2946 match(ConI); 2947 2948 op_cost(0); 2949 format %{ %} 2950 interface(CONST_INTER); 2951%} 2952 2953// Constant for decrement 2954operand immI_M1() 2955%{ 2956 predicate(n->get_int() == -1); 2957 match(ConI); 2958 2959 op_cost(0); 2960 format %{ %} 2961 interface(CONST_INTER); 2962%} 2963 2964// Valid scale values for addressing modes 2965operand immI2() 2966%{ 2967 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2968 match(ConI); 2969 2970 format %{ %} 2971 interface(CONST_INTER); 2972%} 2973 2974operand immI8() 2975%{ 2976 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2977 match(ConI); 2978 2979 op_cost(5); 2980 format %{ %} 2981 interface(CONST_INTER); 2982%} 2983 2984operand immU8() 2985%{ 2986 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2987 match(ConI); 2988 2989 op_cost(5); 2990 format %{ %} 2991 interface(CONST_INTER); 2992%} 2993 2994operand immI16() 2995%{ 2996 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2997 match(ConI); 2998 2999 op_cost(10); 3000 format %{ %} 3001 interface(CONST_INTER); 3002%} 3003 3004// Int Immediate non-negative 3005operand immU31() 3006%{ 3007 predicate(n->get_int() >= 0); 3008 match(ConI); 3009 3010 op_cost(0); 3011 format %{ %} 3012 interface(CONST_INTER); 3013%} 3014 3015// Constant for long shifts 3016operand immI_32() 3017%{ 3018 predicate( n->get_int() == 32 ); 3019 match(ConI); 3020 3021 op_cost(0); 3022 format %{ %} 3023 interface(CONST_INTER); 3024%} 3025 3026// Constant for long shifts 3027operand immI_64() 3028%{ 3029 predicate( n->get_int() == 64 ); 3030 match(ConI); 3031 3032 op_cost(0); 3033 format %{ %} 3034 interface(CONST_INTER); 3035%} 3036 3037// Pointer Immediate 3038operand immP() 3039%{ 3040 match(ConP); 3041 3042 op_cost(10); 3043 format %{ %} 3044 interface(CONST_INTER); 3045%} 3046 3047// NULL Pointer Immediate 3048operand immP0() 3049%{ 3050 predicate(n->get_ptr() == 0); 3051 match(ConP); 3052 3053 op_cost(5); 3054 format %{ %} 3055 interface(CONST_INTER); 3056%} 3057 3058// Pointer Immediate 3059operand immN() %{ 3060 match(ConN); 3061 3062 op_cost(10); 3063 format %{ %} 3064 interface(CONST_INTER); 3065%} 3066 3067operand immNKlass() %{ 3068 match(ConNKlass); 3069 3070 op_cost(10); 3071 format %{ %} 3072 interface(CONST_INTER); 3073%} 3074 3075// NULL Pointer Immediate 3076operand immN0() %{ 3077 predicate(n->get_narrowcon() == 0); 3078 match(ConN); 3079 3080 op_cost(5); 3081 format %{ %} 3082 interface(CONST_INTER); 3083%} 3084 3085operand immP31() 3086%{ 3087 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3088 && (n->get_ptr() >> 31) == 0); 3089 match(ConP); 3090 3091 op_cost(5); 3092 format %{ %} 3093 interface(CONST_INTER); 3094%} 3095 3096 3097// Long Immediate 3098operand immL() 3099%{ 3100 match(ConL); 3101 3102 op_cost(20); 3103 format %{ %} 3104 interface(CONST_INTER); 3105%} 3106 3107// Long Immediate 8-bit 3108operand immL8() 3109%{ 3110 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3111 match(ConL); 3112 3113 op_cost(5); 3114 format %{ %} 3115 interface(CONST_INTER); 3116%} 3117 3118// Long Immediate 32-bit unsigned 3119operand immUL32() 3120%{ 3121 predicate(n->get_long() == (unsigned int) (n->get_long())); 3122 match(ConL); 3123 3124 op_cost(10); 3125 format %{ %} 3126 interface(CONST_INTER); 3127%} 3128 3129// Long Immediate 32-bit signed 3130operand immL32() 3131%{ 3132 predicate(n->get_long() == (int) (n->get_long())); 3133 match(ConL); 3134 3135 op_cost(15); 3136 format %{ %} 3137 interface(CONST_INTER); 3138%} 3139 3140// Long Immediate zero 3141operand immL0() 3142%{ 3143 predicate(n->get_long() == 0L); 3144 match(ConL); 3145 3146 op_cost(10); 3147 format %{ %} 3148 interface(CONST_INTER); 3149%} 3150 3151// Constant for increment 3152operand immL1() 3153%{ 3154 predicate(n->get_long() == 1); 3155 match(ConL); 3156 3157 format %{ %} 3158 interface(CONST_INTER); 3159%} 3160 3161// Constant for decrement 3162operand immL_M1() 3163%{ 3164 predicate(n->get_long() == -1); 3165 match(ConL); 3166 3167 format %{ %} 3168 interface(CONST_INTER); 3169%} 3170 3171// Long Immediate: the value 10 3172operand immL10() 3173%{ 3174 predicate(n->get_long() == 10); 3175 match(ConL); 3176 3177 format %{ %} 3178 interface(CONST_INTER); 3179%} 3180 3181// Long immediate from 0 to 127. 3182// Used for a shorter form of long mul by 10. 3183operand immL_127() 3184%{ 3185 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3186 match(ConL); 3187 3188 op_cost(10); 3189 format %{ %} 3190 interface(CONST_INTER); 3191%} 3192 3193// Long Immediate: low 32-bit mask 3194operand immL_32bits() 3195%{ 3196 predicate(n->get_long() == 0xFFFFFFFFL); 3197 match(ConL); 3198 op_cost(20); 3199 3200 format %{ %} 3201 interface(CONST_INTER); 3202%} 3203 3204// Float Immediate zero 3205operand immF0() 3206%{ 3207 predicate(jint_cast(n->getf()) == 0); 3208 match(ConF); 3209 3210 op_cost(5); 3211 format %{ %} 3212 interface(CONST_INTER); 3213%} 3214 3215// Float Immediate 3216operand immF() 3217%{ 3218 match(ConF); 3219 3220 op_cost(15); 3221 format %{ %} 3222 interface(CONST_INTER); 3223%} 3224 3225// Double Immediate zero 3226operand immD0() 3227%{ 3228 predicate(jlong_cast(n->getd()) == 0); 3229 match(ConD); 3230 3231 op_cost(5); 3232 format %{ %} 3233 interface(CONST_INTER); 3234%} 3235 3236// Double Immediate 3237operand immD() 3238%{ 3239 match(ConD); 3240 3241 op_cost(15); 3242 format %{ %} 3243 interface(CONST_INTER); 3244%} 3245 3246// Immediates for special shifts (sign extend) 3247 3248// Constants for increment 3249operand immI_16() 3250%{ 3251 predicate(n->get_int() == 16); 3252 match(ConI); 3253 3254 format %{ %} 3255 interface(CONST_INTER); 3256%} 3257 3258operand immI_24() 3259%{ 3260 predicate(n->get_int() == 24); 3261 match(ConI); 3262 3263 format %{ %} 3264 interface(CONST_INTER); 3265%} 3266 3267// Constant for byte-wide masking 3268operand immI_255() 3269%{ 3270 predicate(n->get_int() == 255); 3271 match(ConI); 3272 3273 format %{ %} 3274 interface(CONST_INTER); 3275%} 3276 3277// Constant for short-wide masking 3278operand immI_65535() 3279%{ 3280 predicate(n->get_int() == 65535); 3281 match(ConI); 3282 3283 format %{ %} 3284 interface(CONST_INTER); 3285%} 3286 3287// Constant for byte-wide masking 3288operand immL_255() 3289%{ 3290 predicate(n->get_long() == 255); 3291 match(ConL); 3292 3293 format %{ %} 3294 interface(CONST_INTER); 3295%} 3296 3297// Constant for short-wide masking 3298operand immL_65535() 3299%{ 3300 predicate(n->get_long() == 65535); 3301 match(ConL); 3302 3303 format %{ %} 3304 interface(CONST_INTER); 3305%} 3306 3307// Register Operands 3308// Integer Register 3309operand rRegI() 3310%{ 3311 constraint(ALLOC_IN_RC(int_reg)); 3312 match(RegI); 3313 3314 match(rax_RegI); 3315 match(rbx_RegI); 3316 match(rcx_RegI); 3317 match(rdx_RegI); 3318 match(rdi_RegI); 3319 3320 format %{ %} 3321 interface(REG_INTER); 3322%} 3323 3324// Special Registers 3325operand rax_RegI() 3326%{ 3327 constraint(ALLOC_IN_RC(int_rax_reg)); 3328 match(RegI); 3329 match(rRegI); 3330 3331 format %{ "RAX" %} 3332 interface(REG_INTER); 3333%} 3334 3335// Special Registers 3336operand rbx_RegI() 3337%{ 3338 constraint(ALLOC_IN_RC(int_rbx_reg)); 3339 match(RegI); 3340 match(rRegI); 3341 3342 format %{ "RBX" %} 3343 interface(REG_INTER); 3344%} 3345 3346operand rcx_RegI() 3347%{ 3348 constraint(ALLOC_IN_RC(int_rcx_reg)); 3349 match(RegI); 3350 match(rRegI); 3351 3352 format %{ "RCX" %} 3353 interface(REG_INTER); 3354%} 3355 3356operand rdx_RegI() 3357%{ 3358 constraint(ALLOC_IN_RC(int_rdx_reg)); 3359 match(RegI); 3360 match(rRegI); 3361 3362 format %{ "RDX" %} 3363 interface(REG_INTER); 3364%} 3365 3366operand rdi_RegI() 3367%{ 3368 constraint(ALLOC_IN_RC(int_rdi_reg)); 3369 match(RegI); 3370 match(rRegI); 3371 3372 format %{ "RDI" %} 3373 interface(REG_INTER); 3374%} 3375 3376operand no_rcx_RegI() 3377%{ 3378 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3379 match(RegI); 3380 match(rax_RegI); 3381 match(rbx_RegI); 3382 match(rdx_RegI); 3383 match(rdi_RegI); 3384 3385 format %{ %} 3386 interface(REG_INTER); 3387%} 3388 3389operand no_rax_rdx_RegI() 3390%{ 3391 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3392 match(RegI); 3393 match(rbx_RegI); 3394 match(rcx_RegI); 3395 match(rdi_RegI); 3396 3397 format %{ %} 3398 interface(REG_INTER); 3399%} 3400 3401// Pointer Register 3402operand any_RegP() 3403%{ 3404 constraint(ALLOC_IN_RC(any_reg)); 3405 match(RegP); 3406 match(rax_RegP); 3407 match(rbx_RegP); 3408 match(rdi_RegP); 3409 match(rsi_RegP); 3410 match(rbp_RegP); 3411 match(r15_RegP); 3412 match(rRegP); 3413 3414 format %{ %} 3415 interface(REG_INTER); 3416%} 3417 3418operand rRegP() 3419%{ 3420 constraint(ALLOC_IN_RC(ptr_reg)); 3421 match(RegP); 3422 match(rax_RegP); 3423 match(rbx_RegP); 3424 match(rdi_RegP); 3425 match(rsi_RegP); 3426 match(rbp_RegP); // See Q&A below about 3427 match(r15_RegP); // r15_RegP and rbp_RegP. 3428 3429 format %{ %} 3430 interface(REG_INTER); 3431%} 3432 3433operand rRegN() %{ 3434 constraint(ALLOC_IN_RC(int_reg)); 3435 match(RegN); 3436 3437 format %{ %} 3438 interface(REG_INTER); 3439%} 3440 3441// Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3442// Answer: Operand match rules govern the DFA as it processes instruction inputs. 3443// It's fine for an instruction input that expects rRegP to match a r15_RegP. 3444// The output of an instruction is controlled by the allocator, which respects 3445// register class masks, not match rules. Unless an instruction mentions 3446// r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3447// by the allocator as an input. 3448// The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3449// the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3450// result, RBP is not included in the output of the instruction either. 3451 3452operand no_rax_RegP() 3453%{ 3454 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3455 match(RegP); 3456 match(rbx_RegP); 3457 match(rsi_RegP); 3458 match(rdi_RegP); 3459 3460 format %{ %} 3461 interface(REG_INTER); 3462%} 3463 3464// This operand is not allowed to use RBP even if 3465// RBP is not used to hold the frame pointer. 3466operand no_rbp_RegP() 3467%{ 3468 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3469 match(RegP); 3470 match(rbx_RegP); 3471 match(rsi_RegP); 3472 match(rdi_RegP); 3473 3474 format %{ %} 3475 interface(REG_INTER); 3476%} 3477 3478operand no_rax_rbx_RegP() 3479%{ 3480 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3481 match(RegP); 3482 match(rsi_RegP); 3483 match(rdi_RegP); 3484 3485 format %{ %} 3486 interface(REG_INTER); 3487%} 3488 3489// Special Registers 3490// Return a pointer value 3491operand rax_RegP() 3492%{ 3493 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3494 match(RegP); 3495 match(rRegP); 3496 3497 format %{ %} 3498 interface(REG_INTER); 3499%} 3500 3501// Special Registers 3502// Return a compressed pointer value 3503operand rax_RegN() 3504%{ 3505 constraint(ALLOC_IN_RC(int_rax_reg)); 3506 match(RegN); 3507 match(rRegN); 3508 3509 format %{ %} 3510 interface(REG_INTER); 3511%} 3512 3513// Used in AtomicAdd 3514operand rbx_RegP() 3515%{ 3516 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3517 match(RegP); 3518 match(rRegP); 3519 3520 format %{ %} 3521 interface(REG_INTER); 3522%} 3523 3524operand rsi_RegP() 3525%{ 3526 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3527 match(RegP); 3528 match(rRegP); 3529 3530 format %{ %} 3531 interface(REG_INTER); 3532%} 3533 3534// Used in rep stosq 3535operand rdi_RegP() 3536%{ 3537 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3538 match(RegP); 3539 match(rRegP); 3540 3541 format %{ %} 3542 interface(REG_INTER); 3543%} 3544 3545operand r15_RegP() 3546%{ 3547 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3548 match(RegP); 3549 match(rRegP); 3550 3551 format %{ %} 3552 interface(REG_INTER); 3553%} 3554 3555operand rRegL() 3556%{ 3557 constraint(ALLOC_IN_RC(long_reg)); 3558 match(RegL); 3559 match(rax_RegL); 3560 match(rdx_RegL); 3561 3562 format %{ %} 3563 interface(REG_INTER); 3564%} 3565 3566// Special Registers 3567operand no_rax_rdx_RegL() 3568%{ 3569 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3570 match(RegL); 3571 match(rRegL); 3572 3573 format %{ %} 3574 interface(REG_INTER); 3575%} 3576 3577operand no_rax_RegL() 3578%{ 3579 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3580 match(RegL); 3581 match(rRegL); 3582 match(rdx_RegL); 3583 3584 format %{ %} 3585 interface(REG_INTER); 3586%} 3587 3588operand no_rcx_RegL() 3589%{ 3590 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3591 match(RegL); 3592 match(rRegL); 3593 3594 format %{ %} 3595 interface(REG_INTER); 3596%} 3597 3598operand rax_RegL() 3599%{ 3600 constraint(ALLOC_IN_RC(long_rax_reg)); 3601 match(RegL); 3602 match(rRegL); 3603 3604 format %{ "RAX" %} 3605 interface(REG_INTER); 3606%} 3607 3608operand rcx_RegL() 3609%{ 3610 constraint(ALLOC_IN_RC(long_rcx_reg)); 3611 match(RegL); 3612 match(rRegL); 3613 3614 format %{ %} 3615 interface(REG_INTER); 3616%} 3617 3618operand rdx_RegL() 3619%{ 3620 constraint(ALLOC_IN_RC(long_rdx_reg)); 3621 match(RegL); 3622 match(rRegL); 3623 3624 format %{ %} 3625 interface(REG_INTER); 3626%} 3627 3628// Flags register, used as output of compare instructions 3629operand rFlagsReg() 3630%{ 3631 constraint(ALLOC_IN_RC(int_flags)); 3632 match(RegFlags); 3633 3634 format %{ "RFLAGS" %} 3635 interface(REG_INTER); 3636%} 3637 3638// Flags register, used as output of FLOATING POINT compare instructions 3639operand rFlagsRegU() 3640%{ 3641 constraint(ALLOC_IN_RC(int_flags)); 3642 match(RegFlags); 3643 3644 format %{ "RFLAGS_U" %} 3645 interface(REG_INTER); 3646%} 3647 3648operand rFlagsRegUCF() %{ 3649 constraint(ALLOC_IN_RC(int_flags)); 3650 match(RegFlags); 3651 predicate(false); 3652 3653 format %{ "RFLAGS_U_CF" %} 3654 interface(REG_INTER); 3655%} 3656 3657// Float register operands 3658operand regF() %{ 3659 constraint(ALLOC_IN_RC(float_reg)); 3660 match(RegF); 3661 3662 format %{ %} 3663 interface(REG_INTER); 3664%} 3665 3666// Float register operands 3667operand vlRegF() %{ 3668 constraint(ALLOC_IN_RC(float_reg_vl)); 3669 match(RegF); 3670 3671 format %{ %} 3672 interface(REG_INTER); 3673%} 3674 3675// Double register operands 3676operand regD() %{ 3677 constraint(ALLOC_IN_RC(double_reg)); 3678 match(RegD); 3679 3680 format %{ %} 3681 interface(REG_INTER); 3682%} 3683 3684// Double register operands 3685operand vlRegD() %{ 3686 constraint(ALLOC_IN_RC(double_reg_vl)); 3687 match(RegD); 3688 3689 format %{ %} 3690 interface(REG_INTER); 3691%} 3692 3693// Vectors 3694operand vecS() %{ 3695 constraint(ALLOC_IN_RC(vectors_reg_vlbwdq)); 3696 match(VecS); 3697 3698 format %{ %} 3699 interface(REG_INTER); 3700%} 3701 3702// Vectors 3703operand legVecS() %{ 3704 constraint(ALLOC_IN_RC(vectors_reg_legacy)); 3705 match(VecS); 3706 3707 format %{ %} 3708 interface(REG_INTER); 3709%} 3710 3711operand vecD() %{ 3712 constraint(ALLOC_IN_RC(vectord_reg_vlbwdq)); 3713 match(VecD); 3714 3715 format %{ %} 3716 interface(REG_INTER); 3717%} 3718 3719operand legVecD() %{ 3720 constraint(ALLOC_IN_RC(vectord_reg_legacy)); 3721 match(VecD); 3722 3723 format %{ %} 3724 interface(REG_INTER); 3725%} 3726 3727operand vecX() %{ 3728 constraint(ALLOC_IN_RC(vectorx_reg_vlbwdq)); 3729 match(VecX); 3730 3731 format %{ %} 3732 interface(REG_INTER); 3733%} 3734 3735operand legVecX() %{ 3736 constraint(ALLOC_IN_RC(vectorx_reg_legacy)); 3737 match(VecX); 3738 3739 format %{ %} 3740 interface(REG_INTER); 3741%} 3742 3743operand vecY() %{ 3744 constraint(ALLOC_IN_RC(vectory_reg_vlbwdq)); 3745 match(VecY); 3746 3747 format %{ %} 3748 interface(REG_INTER); 3749%} 3750 3751operand legVecY() %{ 3752 constraint(ALLOC_IN_RC(vectory_reg_legacy)); 3753 match(VecY); 3754 3755 format %{ %} 3756 interface(REG_INTER); 3757%} 3758 3759//----------Memory Operands---------------------------------------------------- 3760// Direct Memory Operand 3761// operand direct(immP addr) 3762// %{ 3763// match(addr); 3764 3765// format %{ "[$addr]" %} 3766// interface(MEMORY_INTER) %{ 3767// base(0xFFFFFFFF); 3768// index(0x4); 3769// scale(0x0); 3770// disp($addr); 3771// %} 3772// %} 3773 3774// Indirect Memory Operand 3775operand indirect(any_RegP reg) 3776%{ 3777 constraint(ALLOC_IN_RC(ptr_reg)); 3778 match(reg); 3779 3780 format %{ "[$reg]" %} 3781 interface(MEMORY_INTER) %{ 3782 base($reg); 3783 index(0x4); 3784 scale(0x0); 3785 disp(0x0); 3786 %} 3787%} 3788 3789// Indirect Memory Plus Short Offset Operand 3790operand indOffset8(any_RegP reg, immL8 off) 3791%{ 3792 constraint(ALLOC_IN_RC(ptr_reg)); 3793 match(AddP reg off); 3794 3795 format %{ "[$reg + $off (8-bit)]" %} 3796 interface(MEMORY_INTER) %{ 3797 base($reg); 3798 index(0x4); 3799 scale(0x0); 3800 disp($off); 3801 %} 3802%} 3803 3804// Indirect Memory Plus Long Offset Operand 3805operand indOffset32(any_RegP reg, immL32 off) 3806%{ 3807 constraint(ALLOC_IN_RC(ptr_reg)); 3808 match(AddP reg off); 3809 3810 format %{ "[$reg + $off (32-bit)]" %} 3811 interface(MEMORY_INTER) %{ 3812 base($reg); 3813 index(0x4); 3814 scale(0x0); 3815 disp($off); 3816 %} 3817%} 3818 3819// Indirect Memory Plus Index Register Plus Offset Operand 3820operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3821%{ 3822 constraint(ALLOC_IN_RC(ptr_reg)); 3823 match(AddP (AddP reg lreg) off); 3824 3825 op_cost(10); 3826 format %{"[$reg + $off + $lreg]" %} 3827 interface(MEMORY_INTER) %{ 3828 base($reg); 3829 index($lreg); 3830 scale(0x0); 3831 disp($off); 3832 %} 3833%} 3834 3835// Indirect Memory Plus Index Register Plus Offset Operand 3836operand indIndex(any_RegP reg, rRegL lreg) 3837%{ 3838 constraint(ALLOC_IN_RC(ptr_reg)); 3839 match(AddP reg lreg); 3840 3841 op_cost(10); 3842 format %{"[$reg + $lreg]" %} 3843 interface(MEMORY_INTER) %{ 3844 base($reg); 3845 index($lreg); 3846 scale(0x0); 3847 disp(0x0); 3848 %} 3849%} 3850 3851// Indirect Memory Times Scale Plus Index Register 3852operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3853%{ 3854 constraint(ALLOC_IN_RC(ptr_reg)); 3855 match(AddP reg (LShiftL lreg scale)); 3856 3857 op_cost(10); 3858 format %{"[$reg + $lreg << $scale]" %} 3859 interface(MEMORY_INTER) %{ 3860 base($reg); 3861 index($lreg); 3862 scale($scale); 3863 disp(0x0); 3864 %} 3865%} 3866 3867operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3868%{ 3869 constraint(ALLOC_IN_RC(ptr_reg)); 3870 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3871 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3872 3873 op_cost(10); 3874 format %{"[$reg + pos $idx << $scale]" %} 3875 interface(MEMORY_INTER) %{ 3876 base($reg); 3877 index($idx); 3878 scale($scale); 3879 disp(0x0); 3880 %} 3881%} 3882 3883// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3884operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3885%{ 3886 constraint(ALLOC_IN_RC(ptr_reg)); 3887 match(AddP (AddP reg (LShiftL lreg scale)) off); 3888 3889 op_cost(10); 3890 format %{"[$reg + $off + $lreg << $scale]" %} 3891 interface(MEMORY_INTER) %{ 3892 base($reg); 3893 index($lreg); 3894 scale($scale); 3895 disp($off); 3896 %} 3897%} 3898 3899// Indirect Memory Plus Positive Index Register Plus Offset Operand 3900operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3901%{ 3902 constraint(ALLOC_IN_RC(ptr_reg)); 3903 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3904 match(AddP (AddP reg (ConvI2L idx)) off); 3905 3906 op_cost(10); 3907 format %{"[$reg + $off + $idx]" %} 3908 interface(MEMORY_INTER) %{ 3909 base($reg); 3910 index($idx); 3911 scale(0x0); 3912 disp($off); 3913 %} 3914%} 3915 3916// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3917operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3918%{ 3919 constraint(ALLOC_IN_RC(ptr_reg)); 3920 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3921 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3922 3923 op_cost(10); 3924 format %{"[$reg + $off + $idx << $scale]" %} 3925 interface(MEMORY_INTER) %{ 3926 base($reg); 3927 index($idx); 3928 scale($scale); 3929 disp($off); 3930 %} 3931%} 3932 3933// Indirect Narrow Oop Plus Offset Operand 3934// Note: x86 architecture doesn't support "scale * index + offset" without a base 3935// we can't free r12 even with Universe::narrow_oop_base() == NULL. 3936operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3937 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3938 constraint(ALLOC_IN_RC(ptr_reg)); 3939 match(AddP (DecodeN reg) off); 3940 3941 op_cost(10); 3942 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3943 interface(MEMORY_INTER) %{ 3944 base(0xc); // R12 3945 index($reg); 3946 scale(0x3); 3947 disp($off); 3948 %} 3949%} 3950 3951// Indirect Memory Operand 3952operand indirectNarrow(rRegN reg) 3953%{ 3954 predicate(Universe::narrow_oop_shift() == 0); 3955 constraint(ALLOC_IN_RC(ptr_reg)); 3956 match(DecodeN reg); 3957 3958 format %{ "[$reg]" %} 3959 interface(MEMORY_INTER) %{ 3960 base($reg); 3961 index(0x4); 3962 scale(0x0); 3963 disp(0x0); 3964 %} 3965%} 3966 3967// Indirect Memory Plus Short Offset Operand 3968operand indOffset8Narrow(rRegN reg, immL8 off) 3969%{ 3970 predicate(Universe::narrow_oop_shift() == 0); 3971 constraint(ALLOC_IN_RC(ptr_reg)); 3972 match(AddP (DecodeN reg) off); 3973 3974 format %{ "[$reg + $off (8-bit)]" %} 3975 interface(MEMORY_INTER) %{ 3976 base($reg); 3977 index(0x4); 3978 scale(0x0); 3979 disp($off); 3980 %} 3981%} 3982 3983// Indirect Memory Plus Long Offset Operand 3984operand indOffset32Narrow(rRegN reg, immL32 off) 3985%{ 3986 predicate(Universe::narrow_oop_shift() == 0); 3987 constraint(ALLOC_IN_RC(ptr_reg)); 3988 match(AddP (DecodeN reg) off); 3989 3990 format %{ "[$reg + $off (32-bit)]" %} 3991 interface(MEMORY_INTER) %{ 3992 base($reg); 3993 index(0x4); 3994 scale(0x0); 3995 disp($off); 3996 %} 3997%} 3998 3999// Indirect Memory Plus Index Register Plus Offset Operand 4000operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 4001%{ 4002 predicate(Universe::narrow_oop_shift() == 0); 4003 constraint(ALLOC_IN_RC(ptr_reg)); 4004 match(AddP (AddP (DecodeN reg) lreg) off); 4005 4006 op_cost(10); 4007 format %{"[$reg + $off + $lreg]" %} 4008 interface(MEMORY_INTER) %{ 4009 base($reg); 4010 index($lreg); 4011 scale(0x0); 4012 disp($off); 4013 %} 4014%} 4015 4016// Indirect Memory Plus Index Register Plus Offset Operand 4017operand indIndexNarrow(rRegN reg, rRegL lreg) 4018%{ 4019 predicate(Universe::narrow_oop_shift() == 0); 4020 constraint(ALLOC_IN_RC(ptr_reg)); 4021 match(AddP (DecodeN reg) lreg); 4022 4023 op_cost(10); 4024 format %{"[$reg + $lreg]" %} 4025 interface(MEMORY_INTER) %{ 4026 base($reg); 4027 index($lreg); 4028 scale(0x0); 4029 disp(0x0); 4030 %} 4031%} 4032 4033// Indirect Memory Times Scale Plus Index Register 4034operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4035%{ 4036 predicate(Universe::narrow_oop_shift() == 0); 4037 constraint(ALLOC_IN_RC(ptr_reg)); 4038 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4039 4040 op_cost(10); 4041 format %{"[$reg + $lreg << $scale]" %} 4042 interface(MEMORY_INTER) %{ 4043 base($reg); 4044 index($lreg); 4045 scale($scale); 4046 disp(0x0); 4047 %} 4048%} 4049 4050// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4051operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4052%{ 4053 predicate(Universe::narrow_oop_shift() == 0); 4054 constraint(ALLOC_IN_RC(ptr_reg)); 4055 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4056 4057 op_cost(10); 4058 format %{"[$reg + $off + $lreg << $scale]" %} 4059 interface(MEMORY_INTER) %{ 4060 base($reg); 4061 index($lreg); 4062 scale($scale); 4063 disp($off); 4064 %} 4065%} 4066 4067// Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4068operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4069%{ 4070 constraint(ALLOC_IN_RC(ptr_reg)); 4071 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4072 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4073 4074 op_cost(10); 4075 format %{"[$reg + $off + $idx]" %} 4076 interface(MEMORY_INTER) %{ 4077 base($reg); 4078 index($idx); 4079 scale(0x0); 4080 disp($off); 4081 %} 4082%} 4083 4084// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4085operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4086%{ 4087 constraint(ALLOC_IN_RC(ptr_reg)); 4088 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4089 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4090 4091 op_cost(10); 4092 format %{"[$reg + $off + $idx << $scale]" %} 4093 interface(MEMORY_INTER) %{ 4094 base($reg); 4095 index($idx); 4096 scale($scale); 4097 disp($off); 4098 %} 4099%} 4100 4101//----------Special Memory Operands-------------------------------------------- 4102// Stack Slot Operand - This operand is used for loading and storing temporary 4103// values on the stack where a match requires a value to 4104// flow through memory. 4105operand stackSlotP(sRegP reg) 4106%{ 4107 constraint(ALLOC_IN_RC(stack_slots)); 4108 // No match rule because this operand is only generated in matching 4109 4110 format %{ "[$reg]" %} 4111 interface(MEMORY_INTER) %{ 4112 base(0x4); // RSP 4113 index(0x4); // No Index 4114 scale(0x0); // No Scale 4115 disp($reg); // Stack Offset 4116 %} 4117%} 4118 4119operand stackSlotI(sRegI reg) 4120%{ 4121 constraint(ALLOC_IN_RC(stack_slots)); 4122 // No match rule because this operand is only generated in matching 4123 4124 format %{ "[$reg]" %} 4125 interface(MEMORY_INTER) %{ 4126 base(0x4); // RSP 4127 index(0x4); // No Index 4128 scale(0x0); // No Scale 4129 disp($reg); // Stack Offset 4130 %} 4131%} 4132 4133operand stackSlotF(sRegF reg) 4134%{ 4135 constraint(ALLOC_IN_RC(stack_slots)); 4136 // No match rule because this operand is only generated in matching 4137 4138 format %{ "[$reg]" %} 4139 interface(MEMORY_INTER) %{ 4140 base(0x4); // RSP 4141 index(0x4); // No Index 4142 scale(0x0); // No Scale 4143 disp($reg); // Stack Offset 4144 %} 4145%} 4146 4147operand stackSlotD(sRegD reg) 4148%{ 4149 constraint(ALLOC_IN_RC(stack_slots)); 4150 // No match rule because this operand is only generated in matching 4151 4152 format %{ "[$reg]" %} 4153 interface(MEMORY_INTER) %{ 4154 base(0x4); // RSP 4155 index(0x4); // No Index 4156 scale(0x0); // No Scale 4157 disp($reg); // Stack Offset 4158 %} 4159%} 4160operand stackSlotL(sRegL reg) 4161%{ 4162 constraint(ALLOC_IN_RC(stack_slots)); 4163 // No match rule because this operand is only generated in matching 4164 4165 format %{ "[$reg]" %} 4166 interface(MEMORY_INTER) %{ 4167 base(0x4); // RSP 4168 index(0x4); // No Index 4169 scale(0x0); // No Scale 4170 disp($reg); // Stack Offset 4171 %} 4172%} 4173 4174//----------Conditional Branch Operands---------------------------------------- 4175// Comparison Op - This is the operation of the comparison, and is limited to 4176// the following set of codes: 4177// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4178// 4179// Other attributes of the comparison, such as unsignedness, are specified 4180// by the comparison instruction that sets a condition code flags register. 4181// That result is represented by a flags operand whose subtype is appropriate 4182// to the unsignedness (etc.) of the comparison. 4183// 4184// Later, the instruction which matches both the Comparison Op (a Bool) and 4185// the flags (produced by the Cmp) specifies the coding of the comparison op 4186// by matching a specific subtype of Bool operand below, such as cmpOpU. 4187 4188// Comparision Code 4189operand cmpOp() 4190%{ 4191 match(Bool); 4192 4193 format %{ "" %} 4194 interface(COND_INTER) %{ 4195 equal(0x4, "e"); 4196 not_equal(0x5, "ne"); 4197 less(0xC, "l"); 4198 greater_equal(0xD, "ge"); 4199 less_equal(0xE, "le"); 4200 greater(0xF, "g"); 4201 overflow(0x0, "o"); 4202 no_overflow(0x1, "no"); 4203 %} 4204%} 4205 4206// Comparison Code, unsigned compare. Used by FP also, with 4207// C2 (unordered) turned into GT or LT already. The other bits 4208// C0 and C3 are turned into Carry & Zero flags. 4209operand cmpOpU() 4210%{ 4211 match(Bool); 4212 4213 format %{ "" %} 4214 interface(COND_INTER) %{ 4215 equal(0x4, "e"); 4216 not_equal(0x5, "ne"); 4217 less(0x2, "b"); 4218 greater_equal(0x3, "nb"); 4219 less_equal(0x6, "be"); 4220 greater(0x7, "nbe"); 4221 overflow(0x0, "o"); 4222 no_overflow(0x1, "no"); 4223 %} 4224%} 4225 4226 4227// Floating comparisons that don't require any fixup for the unordered case 4228operand cmpOpUCF() %{ 4229 match(Bool); 4230 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4231 n->as_Bool()->_test._test == BoolTest::ge || 4232 n->as_Bool()->_test._test == BoolTest::le || 4233 n->as_Bool()->_test._test == BoolTest::gt); 4234 format %{ "" %} 4235 interface(COND_INTER) %{ 4236 equal(0x4, "e"); 4237 not_equal(0x5, "ne"); 4238 less(0x2, "b"); 4239 greater_equal(0x3, "nb"); 4240 less_equal(0x6, "be"); 4241 greater(0x7, "nbe"); 4242 overflow(0x0, "o"); 4243 no_overflow(0x1, "no"); 4244 %} 4245%} 4246 4247 4248// Floating comparisons that can be fixed up with extra conditional jumps 4249operand cmpOpUCF2() %{ 4250 match(Bool); 4251 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4252 n->as_Bool()->_test._test == BoolTest::eq); 4253 format %{ "" %} 4254 interface(COND_INTER) %{ 4255 equal(0x4, "e"); 4256 not_equal(0x5, "ne"); 4257 less(0x2, "b"); 4258 greater_equal(0x3, "nb"); 4259 less_equal(0x6, "be"); 4260 greater(0x7, "nbe"); 4261 overflow(0x0, "o"); 4262 no_overflow(0x1, "no"); 4263 %} 4264%} 4265 4266// Operands for bound floating pointer register arguments 4267operand rxmm0() %{ 4268 constraint(ALLOC_IN_RC(xmm0_reg)); 4269 match(VecX); 4270 format%{%} 4271 interface(REG_INTER); 4272%} 4273operand rxmm1() %{ 4274 constraint(ALLOC_IN_RC(xmm1_reg)); 4275 match(VecX); 4276 format%{%} 4277 interface(REG_INTER); 4278%} 4279operand rxmm2() %{ 4280 constraint(ALLOC_IN_RC(xmm2_reg)); 4281 match(VecX); 4282 format%{%} 4283 interface(REG_INTER); 4284%} 4285operand rxmm3() %{ 4286 constraint(ALLOC_IN_RC(xmm3_reg)); 4287 match(VecX); 4288 format%{%} 4289 interface(REG_INTER); 4290%} 4291operand rxmm4() %{ 4292 constraint(ALLOC_IN_RC(xmm4_reg)); 4293 match(VecX); 4294 format%{%} 4295 interface(REG_INTER); 4296%} 4297operand rxmm5() %{ 4298 constraint(ALLOC_IN_RC(xmm5_reg)); 4299 match(VecX); 4300 format%{%} 4301 interface(REG_INTER); 4302%} 4303operand rxmm6() %{ 4304 constraint(ALLOC_IN_RC(xmm6_reg)); 4305 match(VecX); 4306 format%{%} 4307 interface(REG_INTER); 4308%} 4309operand rxmm7() %{ 4310 constraint(ALLOC_IN_RC(xmm7_reg)); 4311 match(VecX); 4312 format%{%} 4313 interface(REG_INTER); 4314%} 4315operand rxmm8() %{ 4316 constraint(ALLOC_IN_RC(xmm8_reg)); 4317 match(VecX); 4318 format%{%} 4319 interface(REG_INTER); 4320%} 4321operand rxmm9() %{ 4322 constraint(ALLOC_IN_RC(xmm9_reg)); 4323 match(VecX); 4324 format%{%} 4325 interface(REG_INTER); 4326%} 4327operand rxmm10() %{ 4328 constraint(ALLOC_IN_RC(xmm10_reg)); 4329 match(VecX); 4330 format%{%} 4331 interface(REG_INTER); 4332%} 4333operand rxmm11() %{ 4334 constraint(ALLOC_IN_RC(xmm11_reg)); 4335 match(VecX); 4336 format%{%} 4337 interface(REG_INTER); 4338%} 4339operand rxmm12() %{ 4340 constraint(ALLOC_IN_RC(xmm12_reg)); 4341 match(VecX); 4342 format%{%} 4343 interface(REG_INTER); 4344%} 4345operand rxmm13() %{ 4346 constraint(ALLOC_IN_RC(xmm13_reg)); 4347 match(VecX); 4348 format%{%} 4349 interface(REG_INTER); 4350%} 4351operand rxmm14() %{ 4352 constraint(ALLOC_IN_RC(xmm14_reg)); 4353 match(VecX); 4354 format%{%} 4355 interface(REG_INTER); 4356%} 4357operand rxmm15() %{ 4358 constraint(ALLOC_IN_RC(xmm15_reg)); 4359 match(VecX); 4360 format%{%} 4361 interface(REG_INTER); 4362%} 4363operand rxmm16() %{ 4364 constraint(ALLOC_IN_RC(xmm16_reg)); 4365 match(VecX); 4366 format%{%} 4367 interface(REG_INTER); 4368%} 4369operand rxmm17() %{ 4370 constraint(ALLOC_IN_RC(xmm17_reg)); 4371 match(VecX); 4372 format%{%} 4373 interface(REG_INTER); 4374%} 4375operand rxmm18() %{ 4376 constraint(ALLOC_IN_RC(xmm18_reg)); 4377 match(VecX); 4378 format%{%} 4379 interface(REG_INTER); 4380%} 4381operand rxmm19() %{ 4382 constraint(ALLOC_IN_RC(xmm19_reg)); 4383 match(VecX); 4384 format%{%} 4385 interface(REG_INTER); 4386%} 4387operand rxmm20() %{ 4388 constraint(ALLOC_IN_RC(xmm20_reg)); 4389 match(VecX); 4390 format%{%} 4391 interface(REG_INTER); 4392%} 4393operand rxmm21() %{ 4394 constraint(ALLOC_IN_RC(xmm21_reg)); 4395 match(VecX); 4396 format%{%} 4397 interface(REG_INTER); 4398%} 4399operand rxmm22() %{ 4400 constraint(ALLOC_IN_RC(xmm22_reg)); 4401 match(VecX); 4402 format%{%} 4403 interface(REG_INTER); 4404%} 4405operand rxmm23() %{ 4406 constraint(ALLOC_IN_RC(xmm23_reg)); 4407 match(VecX); 4408 format%{%} 4409 interface(REG_INTER); 4410%} 4411operand rxmm24() %{ 4412 constraint(ALLOC_IN_RC(xmm24_reg)); 4413 match(VecX); 4414 format%{%} 4415 interface(REG_INTER); 4416%} 4417operand rxmm25() %{ 4418 constraint(ALLOC_IN_RC(xmm25_reg)); 4419 match(VecX); 4420 format%{%} 4421 interface(REG_INTER); 4422%} 4423operand rxmm26() %{ 4424 constraint(ALLOC_IN_RC(xmm26_reg)); 4425 match(VecX); 4426 format%{%} 4427 interface(REG_INTER); 4428%} 4429operand rxmm27() %{ 4430 constraint(ALLOC_IN_RC(xmm27_reg)); 4431 match(VecX); 4432 format%{%} 4433 interface(REG_INTER); 4434%} 4435operand rxmm28() %{ 4436 constraint(ALLOC_IN_RC(xmm28_reg)); 4437 match(VecX); 4438 format%{%} 4439 interface(REG_INTER); 4440%} 4441operand rxmm29() %{ 4442 constraint(ALLOC_IN_RC(xmm29_reg)); 4443 match(VecX); 4444 format%{%} 4445 interface(REG_INTER); 4446%} 4447operand rxmm30() %{ 4448 constraint(ALLOC_IN_RC(xmm30_reg)); 4449 match(VecX); 4450 format%{%} 4451 interface(REG_INTER); 4452%} 4453operand rxmm31() %{ 4454 constraint(ALLOC_IN_RC(xmm31_reg)); 4455 match(VecX); 4456 format%{%} 4457 interface(REG_INTER); 4458%} 4459 4460//----------OPERAND CLASSES---------------------------------------------------- 4461// Operand Classes are groups of operands that are used as to simplify 4462// instruction definitions by not requiring the AD writer to specify separate 4463// instructions for every form of operand when the instruction accepts 4464// multiple operand types with the same basic encoding and format. The classic 4465// case of this is memory operands. 4466 4467opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4468 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4469 indCompressedOopOffset, 4470 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4471 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4472 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4473 4474//----------PIPELINE----------------------------------------------------------- 4475// Rules which define the behavior of the target architectures pipeline. 4476pipeline %{ 4477 4478//----------ATTRIBUTES--------------------------------------------------------- 4479attributes %{ 4480 variable_size_instructions; // Fixed size instructions 4481 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4482 instruction_unit_size = 1; // An instruction is 1 bytes long 4483 instruction_fetch_unit_size = 16; // The processor fetches one line 4484 instruction_fetch_units = 1; // of 16 bytes 4485 4486 // List of nop instructions 4487 nops( MachNop ); 4488%} 4489 4490//----------RESOURCES---------------------------------------------------------- 4491// Resources are the functional units available to the machine 4492 4493// Generic P2/P3 pipeline 4494// 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4495// 3 instructions decoded per cycle. 4496// 2 load/store ops per cycle, 1 branch, 1 FPU, 4497// 3 ALU op, only ALU0 handles mul instructions. 4498resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4499 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4500 BR, FPU, 4501 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4502 4503//----------PIPELINE DESCRIPTION----------------------------------------------- 4504// Pipeline Description specifies the stages in the machine's pipeline 4505 4506// Generic P2/P3 pipeline 4507pipe_desc(S0, S1, S2, S3, S4, S5); 4508 4509//----------PIPELINE CLASSES--------------------------------------------------- 4510// Pipeline Classes describe the stages in which input and output are 4511// referenced by the hardware pipeline. 4512 4513// Naming convention: ialu or fpu 4514// Then: _reg 4515// Then: _reg if there is a 2nd register 4516// Then: _long if it's a pair of instructions implementing a long 4517// Then: _fat if it requires the big decoder 4518// Or: _mem if it requires the big decoder and a memory unit. 4519 4520// Integer ALU reg operation 4521pipe_class ialu_reg(rRegI dst) 4522%{ 4523 single_instruction; 4524 dst : S4(write); 4525 dst : S3(read); 4526 DECODE : S0; // any decoder 4527 ALU : S3; // any alu 4528%} 4529 4530// Long ALU reg operation 4531pipe_class ialu_reg_long(rRegL dst) 4532%{ 4533 instruction_count(2); 4534 dst : S4(write); 4535 dst : S3(read); 4536 DECODE : S0(2); // any 2 decoders 4537 ALU : S3(2); // both alus 4538%} 4539 4540// Integer ALU reg operation using big decoder 4541pipe_class ialu_reg_fat(rRegI dst) 4542%{ 4543 single_instruction; 4544 dst : S4(write); 4545 dst : S3(read); 4546 D0 : S0; // big decoder only 4547 ALU : S3; // any alu 4548%} 4549 4550// Long ALU reg operation using big decoder 4551pipe_class ialu_reg_long_fat(rRegL dst) 4552%{ 4553 instruction_count(2); 4554 dst : S4(write); 4555 dst : S3(read); 4556 D0 : S0(2); // big decoder only; twice 4557 ALU : S3(2); // any 2 alus 4558%} 4559 4560// Integer ALU reg-reg operation 4561pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4562%{ 4563 single_instruction; 4564 dst : S4(write); 4565 src : S3(read); 4566 DECODE : S0; // any decoder 4567 ALU : S3; // any alu 4568%} 4569 4570// Long ALU reg-reg operation 4571pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4572%{ 4573 instruction_count(2); 4574 dst : S4(write); 4575 src : S3(read); 4576 DECODE : S0(2); // any 2 decoders 4577 ALU : S3(2); // both alus 4578%} 4579 4580// Integer ALU reg-reg operation 4581pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4582%{ 4583 single_instruction; 4584 dst : S4(write); 4585 src : S3(read); 4586 D0 : S0; // big decoder only 4587 ALU : S3; // any alu 4588%} 4589 4590// Long ALU reg-reg operation 4591pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4592%{ 4593 instruction_count(2); 4594 dst : S4(write); 4595 src : S3(read); 4596 D0 : S0(2); // big decoder only; twice 4597 ALU : S3(2); // both alus 4598%} 4599 4600// Integer ALU reg-mem operation 4601pipe_class ialu_reg_mem(rRegI dst, memory mem) 4602%{ 4603 single_instruction; 4604 dst : S5(write); 4605 mem : S3(read); 4606 D0 : S0; // big decoder only 4607 ALU : S4; // any alu 4608 MEM : S3; // any mem 4609%} 4610 4611// Integer mem operation (prefetch) 4612pipe_class ialu_mem(memory mem) 4613%{ 4614 single_instruction; 4615 mem : S3(read); 4616 D0 : S0; // big decoder only 4617 MEM : S3; // any mem 4618%} 4619 4620// Integer Store to Memory 4621pipe_class ialu_mem_reg(memory mem, rRegI src) 4622%{ 4623 single_instruction; 4624 mem : S3(read); 4625 src : S5(read); 4626 D0 : S0; // big decoder only 4627 ALU : S4; // any alu 4628 MEM : S3; 4629%} 4630 4631// // Long Store to Memory 4632// pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4633// %{ 4634// instruction_count(2); 4635// mem : S3(read); 4636// src : S5(read); 4637// D0 : S0(2); // big decoder only; twice 4638// ALU : S4(2); // any 2 alus 4639// MEM : S3(2); // Both mems 4640// %} 4641 4642// Integer Store to Memory 4643pipe_class ialu_mem_imm(memory mem) 4644%{ 4645 single_instruction; 4646 mem : S3(read); 4647 D0 : S0; // big decoder only 4648 ALU : S4; // any alu 4649 MEM : S3; 4650%} 4651 4652// Integer ALU0 reg-reg operation 4653pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4654%{ 4655 single_instruction; 4656 dst : S4(write); 4657 src : S3(read); 4658 D0 : S0; // Big decoder only 4659 ALU0 : S3; // only alu0 4660%} 4661 4662// Integer ALU0 reg-mem operation 4663pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4664%{ 4665 single_instruction; 4666 dst : S5(write); 4667 mem : S3(read); 4668 D0 : S0; // big decoder only 4669 ALU0 : S4; // ALU0 only 4670 MEM : S3; // any mem 4671%} 4672 4673// Integer ALU reg-reg operation 4674pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4675%{ 4676 single_instruction; 4677 cr : S4(write); 4678 src1 : S3(read); 4679 src2 : S3(read); 4680 DECODE : S0; // any decoder 4681 ALU : S3; // any alu 4682%} 4683 4684// Integer ALU reg-imm operation 4685pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4686%{ 4687 single_instruction; 4688 cr : S4(write); 4689 src1 : S3(read); 4690 DECODE : S0; // any decoder 4691 ALU : S3; // any alu 4692%} 4693 4694// Integer ALU reg-mem operation 4695pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4696%{ 4697 single_instruction; 4698 cr : S4(write); 4699 src1 : S3(read); 4700 src2 : S3(read); 4701 D0 : S0; // big decoder only 4702 ALU : S4; // any alu 4703 MEM : S3; 4704%} 4705 4706// Conditional move reg-reg 4707pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4708%{ 4709 instruction_count(4); 4710 y : S4(read); 4711 q : S3(read); 4712 p : S3(read); 4713 DECODE : S0(4); // any decoder 4714%} 4715 4716// Conditional move reg-reg 4717pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4718%{ 4719 single_instruction; 4720 dst : S4(write); 4721 src : S3(read); 4722 cr : S3(read); 4723 DECODE : S0; // any decoder 4724%} 4725 4726// Conditional move reg-mem 4727pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4728%{ 4729 single_instruction; 4730 dst : S4(write); 4731 src : S3(read); 4732 cr : S3(read); 4733 DECODE : S0; // any decoder 4734 MEM : S3; 4735%} 4736 4737// Conditional move reg-reg long 4738pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4739%{ 4740 single_instruction; 4741 dst : S4(write); 4742 src : S3(read); 4743 cr : S3(read); 4744 DECODE : S0(2); // any 2 decoders 4745%} 4746 4747// XXX 4748// // Conditional move double reg-reg 4749// pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4750// %{ 4751// single_instruction; 4752// dst : S4(write); 4753// src : S3(read); 4754// cr : S3(read); 4755// DECODE : S0; // any decoder 4756// %} 4757 4758// Float reg-reg operation 4759pipe_class fpu_reg(regD dst) 4760%{ 4761 instruction_count(2); 4762 dst : S3(read); 4763 DECODE : S0(2); // any 2 decoders 4764 FPU : S3; 4765%} 4766 4767// Float reg-reg operation 4768pipe_class fpu_reg_reg(regD dst, regD src) 4769%{ 4770 instruction_count(2); 4771 dst : S4(write); 4772 src : S3(read); 4773 DECODE : S0(2); // any 2 decoders 4774 FPU : S3; 4775%} 4776 4777// Float reg-reg operation 4778pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4779%{ 4780 instruction_count(3); 4781 dst : S4(write); 4782 src1 : S3(read); 4783 src2 : S3(read); 4784 DECODE : S0(3); // any 3 decoders 4785 FPU : S3(2); 4786%} 4787 4788// Float reg-reg operation 4789pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4790%{ 4791 instruction_count(4); 4792 dst : S4(write); 4793 src1 : S3(read); 4794 src2 : S3(read); 4795 src3 : S3(read); 4796 DECODE : S0(4); // any 3 decoders 4797 FPU : S3(2); 4798%} 4799 4800// Float reg-reg operation 4801pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4802%{ 4803 instruction_count(4); 4804 dst : S4(write); 4805 src1 : S3(read); 4806 src2 : S3(read); 4807 src3 : S3(read); 4808 DECODE : S1(3); // any 3 decoders 4809 D0 : S0; // Big decoder only 4810 FPU : S3(2); 4811 MEM : S3; 4812%} 4813 4814// Float reg-mem operation 4815pipe_class fpu_reg_mem(regD dst, memory mem) 4816%{ 4817 instruction_count(2); 4818 dst : S5(write); 4819 mem : S3(read); 4820 D0 : S0; // big decoder only 4821 DECODE : S1; // any decoder for FPU POP 4822 FPU : S4; 4823 MEM : S3; // any mem 4824%} 4825 4826// Float reg-mem operation 4827pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4828%{ 4829 instruction_count(3); 4830 dst : S5(write); 4831 src1 : S3(read); 4832 mem : S3(read); 4833 D0 : S0; // big decoder only 4834 DECODE : S1(2); // any decoder for FPU POP 4835 FPU : S4; 4836 MEM : S3; // any mem 4837%} 4838 4839// Float mem-reg operation 4840pipe_class fpu_mem_reg(memory mem, regD src) 4841%{ 4842 instruction_count(2); 4843 src : S5(read); 4844 mem : S3(read); 4845 DECODE : S0; // any decoder for FPU PUSH 4846 D0 : S1; // big decoder only 4847 FPU : S4; 4848 MEM : S3; // any mem 4849%} 4850 4851pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4852%{ 4853 instruction_count(3); 4854 src1 : S3(read); 4855 src2 : S3(read); 4856 mem : S3(read); 4857 DECODE : S0(2); // any decoder for FPU PUSH 4858 D0 : S1; // big decoder only 4859 FPU : S4; 4860 MEM : S3; // any mem 4861%} 4862 4863pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4864%{ 4865 instruction_count(3); 4866 src1 : S3(read); 4867 src2 : S3(read); 4868 mem : S4(read); 4869 DECODE : S0; // any decoder for FPU PUSH 4870 D0 : S0(2); // big decoder only 4871 FPU : S4; 4872 MEM : S3(2); // any mem 4873%} 4874 4875pipe_class fpu_mem_mem(memory dst, memory src1) 4876%{ 4877 instruction_count(2); 4878 src1 : S3(read); 4879 dst : S4(read); 4880 D0 : S0(2); // big decoder only 4881 MEM : S3(2); // any mem 4882%} 4883 4884pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4885%{ 4886 instruction_count(3); 4887 src1 : S3(read); 4888 src2 : S3(read); 4889 dst : S4(read); 4890 D0 : S0(3); // big decoder only 4891 FPU : S4; 4892 MEM : S3(3); // any mem 4893%} 4894 4895pipe_class fpu_mem_reg_con(memory mem, regD src1) 4896%{ 4897 instruction_count(3); 4898 src1 : S4(read); 4899 mem : S4(read); 4900 DECODE : S0; // any decoder for FPU PUSH 4901 D0 : S0(2); // big decoder only 4902 FPU : S4; 4903 MEM : S3(2); // any mem 4904%} 4905 4906// Float load constant 4907pipe_class fpu_reg_con(regD dst) 4908%{ 4909 instruction_count(2); 4910 dst : S5(write); 4911 D0 : S0; // big decoder only for the load 4912 DECODE : S1; // any decoder for FPU POP 4913 FPU : S4; 4914 MEM : S3; // any mem 4915%} 4916 4917// Float load constant 4918pipe_class fpu_reg_reg_con(regD dst, regD src) 4919%{ 4920 instruction_count(3); 4921 dst : S5(write); 4922 src : S3(read); 4923 D0 : S0; // big decoder only for the load 4924 DECODE : S1(2); // any decoder for FPU POP 4925 FPU : S4; 4926 MEM : S3; // any mem 4927%} 4928 4929// UnConditional branch 4930pipe_class pipe_jmp(label labl) 4931%{ 4932 single_instruction; 4933 BR : S3; 4934%} 4935 4936// Conditional branch 4937pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4938%{ 4939 single_instruction; 4940 cr : S1(read); 4941 BR : S3; 4942%} 4943 4944// Allocation idiom 4945pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4946%{ 4947 instruction_count(1); force_serialization; 4948 fixed_latency(6); 4949 heap_ptr : S3(read); 4950 DECODE : S0(3); 4951 D0 : S2; 4952 MEM : S3; 4953 ALU : S3(2); 4954 dst : S5(write); 4955 BR : S5; 4956%} 4957 4958// Generic big/slow expanded idiom 4959pipe_class pipe_slow() 4960%{ 4961 instruction_count(10); multiple_bundles; force_serialization; 4962 fixed_latency(100); 4963 D0 : S0(2); 4964 MEM : S3(2); 4965%} 4966 4967// The real do-nothing guy 4968pipe_class empty() 4969%{ 4970 instruction_count(0); 4971%} 4972 4973// Define the class for the Nop node 4974define 4975%{ 4976 MachNop = empty; 4977%} 4978 4979%} 4980 4981//----------INSTRUCTIONS------------------------------------------------------- 4982// 4983// match -- States which machine-independent subtree may be replaced 4984// by this instruction. 4985// ins_cost -- The estimated cost of this instruction is used by instruction 4986// selection to identify a minimum cost tree of machine 4987// instructions that matches a tree of machine-independent 4988// instructions. 4989// format -- A string providing the disassembly for this instruction. 4990// The value of an instruction's operand may be inserted 4991// by referring to it with a '$' prefix. 4992// opcode -- Three instruction opcodes may be provided. These are referred 4993// to within an encode class as $primary, $secondary, and $tertiary 4994// rrspectively. The primary opcode is commonly used to 4995// indicate the type of machine instruction, while secondary 4996// and tertiary are often used for prefix options or addressing 4997// modes. 4998// ins_encode -- A list of encode classes with parameters. The encode class 4999// name must have been defined in an 'enc_class' specification 5000// in the encode section of the architecture description. 5001 5002 5003//----------Load/Store/Move Instructions--------------------------------------- 5004//----------Load Instructions-------------------------------------------------- 5005 5006// Load Byte (8 bit signed) 5007instruct loadB(rRegI dst, memory mem) 5008%{ 5009 match(Set dst (LoadB mem)); 5010 5011 ins_cost(125); 5012 format %{ "movsbl $dst, $mem\t# byte" %} 5013 5014 ins_encode %{ 5015 __ movsbl($dst$$Register, $mem$$Address); 5016 %} 5017 5018 ins_pipe(ialu_reg_mem); 5019%} 5020 5021// Load Byte (8 bit signed) into Long Register 5022instruct loadB2L(rRegL dst, memory mem) 5023%{ 5024 match(Set dst (ConvI2L (LoadB mem))); 5025 5026 ins_cost(125); 5027 format %{ "movsbq $dst, $mem\t# byte -> long" %} 5028 5029 ins_encode %{ 5030 __ movsbq($dst$$Register, $mem$$Address); 5031 %} 5032 5033 ins_pipe(ialu_reg_mem); 5034%} 5035 5036// Load Unsigned Byte (8 bit UNsigned) 5037instruct loadUB(rRegI dst, memory mem) 5038%{ 5039 match(Set dst (LoadUB mem)); 5040 5041 ins_cost(125); 5042 format %{ "movzbl $dst, $mem\t# ubyte" %} 5043 5044 ins_encode %{ 5045 __ movzbl($dst$$Register, $mem$$Address); 5046 %} 5047 5048 ins_pipe(ialu_reg_mem); 5049%} 5050 5051// Load Unsigned Byte (8 bit UNsigned) into Long Register 5052instruct loadUB2L(rRegL dst, memory mem) 5053%{ 5054 match(Set dst (ConvI2L (LoadUB mem))); 5055 5056 ins_cost(125); 5057 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 5058 5059 ins_encode %{ 5060 __ movzbq($dst$$Register, $mem$$Address); 5061 %} 5062 5063 ins_pipe(ialu_reg_mem); 5064%} 5065 5066// Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 5067instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5068 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5069 effect(KILL cr); 5070 5071 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 5072 "andl $dst, right_n_bits($mask, 8)" %} 5073 ins_encode %{ 5074 Register Rdst = $dst$$Register; 5075 __ movzbq(Rdst, $mem$$Address); 5076 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 5077 %} 5078 ins_pipe(ialu_reg_mem); 5079%} 5080 5081// Load Short (16 bit signed) 5082instruct loadS(rRegI dst, memory mem) 5083%{ 5084 match(Set dst (LoadS mem)); 5085 5086 ins_cost(125); 5087 format %{ "movswl $dst, $mem\t# short" %} 5088 5089 ins_encode %{ 5090 __ movswl($dst$$Register, $mem$$Address); 5091 %} 5092 5093 ins_pipe(ialu_reg_mem); 5094%} 5095 5096// Load Short (16 bit signed) to Byte (8 bit signed) 5097instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5098 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5099 5100 ins_cost(125); 5101 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5102 ins_encode %{ 5103 __ movsbl($dst$$Register, $mem$$Address); 5104 %} 5105 ins_pipe(ialu_reg_mem); 5106%} 5107 5108// Load Short (16 bit signed) into Long Register 5109instruct loadS2L(rRegL dst, memory mem) 5110%{ 5111 match(Set dst (ConvI2L (LoadS mem))); 5112 5113 ins_cost(125); 5114 format %{ "movswq $dst, $mem\t# short -> long" %} 5115 5116 ins_encode %{ 5117 __ movswq($dst$$Register, $mem$$Address); 5118 %} 5119 5120 ins_pipe(ialu_reg_mem); 5121%} 5122 5123// Load Unsigned Short/Char (16 bit UNsigned) 5124instruct loadUS(rRegI dst, memory mem) 5125%{ 5126 match(Set dst (LoadUS mem)); 5127 5128 ins_cost(125); 5129 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5130 5131 ins_encode %{ 5132 __ movzwl($dst$$Register, $mem$$Address); 5133 %} 5134 5135 ins_pipe(ialu_reg_mem); 5136%} 5137 5138// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5139instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5140 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5141 5142 ins_cost(125); 5143 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5144 ins_encode %{ 5145 __ movsbl($dst$$Register, $mem$$Address); 5146 %} 5147 ins_pipe(ialu_reg_mem); 5148%} 5149 5150// Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5151instruct loadUS2L(rRegL dst, memory mem) 5152%{ 5153 match(Set dst (ConvI2L (LoadUS mem))); 5154 5155 ins_cost(125); 5156 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5157 5158 ins_encode %{ 5159 __ movzwq($dst$$Register, $mem$$Address); 5160 %} 5161 5162 ins_pipe(ialu_reg_mem); 5163%} 5164 5165// Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5166instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5167 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5168 5169 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5170 ins_encode %{ 5171 __ movzbq($dst$$Register, $mem$$Address); 5172 %} 5173 ins_pipe(ialu_reg_mem); 5174%} 5175 5176// Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 5177instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5178 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5179 effect(KILL cr); 5180 5181 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 5182 "andl $dst, right_n_bits($mask, 16)" %} 5183 ins_encode %{ 5184 Register Rdst = $dst$$Register; 5185 __ movzwq(Rdst, $mem$$Address); 5186 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 5187 %} 5188 ins_pipe(ialu_reg_mem); 5189%} 5190 5191// Load Integer 5192instruct loadI(rRegI dst, memory mem) 5193%{ 5194 match(Set dst (LoadI mem)); 5195 5196 ins_cost(125); 5197 format %{ "movl $dst, $mem\t# int" %} 5198 5199 ins_encode %{ 5200 __ movl($dst$$Register, $mem$$Address); 5201 %} 5202 5203 ins_pipe(ialu_reg_mem); 5204%} 5205 5206// Load Integer (32 bit signed) to Byte (8 bit signed) 5207instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5208 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5209 5210 ins_cost(125); 5211 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5212 ins_encode %{ 5213 __ movsbl($dst$$Register, $mem$$Address); 5214 %} 5215 ins_pipe(ialu_reg_mem); 5216%} 5217 5218// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5219instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5220 match(Set dst (AndI (LoadI mem) mask)); 5221 5222 ins_cost(125); 5223 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5224 ins_encode %{ 5225 __ movzbl($dst$$Register, $mem$$Address); 5226 %} 5227 ins_pipe(ialu_reg_mem); 5228%} 5229 5230// Load Integer (32 bit signed) to Short (16 bit signed) 5231instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5232 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5233 5234 ins_cost(125); 5235 format %{ "movswl $dst, $mem\t# int -> short" %} 5236 ins_encode %{ 5237 __ movswl($dst$$Register, $mem$$Address); 5238 %} 5239 ins_pipe(ialu_reg_mem); 5240%} 5241 5242// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5243instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5244 match(Set dst (AndI (LoadI mem) mask)); 5245 5246 ins_cost(125); 5247 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5248 ins_encode %{ 5249 __ movzwl($dst$$Register, $mem$$Address); 5250 %} 5251 ins_pipe(ialu_reg_mem); 5252%} 5253 5254// Load Integer into Long Register 5255instruct loadI2L(rRegL dst, memory mem) 5256%{ 5257 match(Set dst (ConvI2L (LoadI mem))); 5258 5259 ins_cost(125); 5260 format %{ "movslq $dst, $mem\t# int -> long" %} 5261 5262 ins_encode %{ 5263 __ movslq($dst$$Register, $mem$$Address); 5264 %} 5265 5266 ins_pipe(ialu_reg_mem); 5267%} 5268 5269// Load Integer with mask 0xFF into Long Register 5270instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5271 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5272 5273 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5274 ins_encode %{ 5275 __ movzbq($dst$$Register, $mem$$Address); 5276 %} 5277 ins_pipe(ialu_reg_mem); 5278%} 5279 5280// Load Integer with mask 0xFFFF into Long Register 5281instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5282 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5283 5284 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5285 ins_encode %{ 5286 __ movzwq($dst$$Register, $mem$$Address); 5287 %} 5288 ins_pipe(ialu_reg_mem); 5289%} 5290 5291// Load Integer with a 31-bit mask into Long Register 5292instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5293 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5294 effect(KILL cr); 5295 5296 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5297 "andl $dst, $mask" %} 5298 ins_encode %{ 5299 Register Rdst = $dst$$Register; 5300 __ movl(Rdst, $mem$$Address); 5301 __ andl(Rdst, $mask$$constant); 5302 %} 5303 ins_pipe(ialu_reg_mem); 5304%} 5305 5306// Load Unsigned Integer into Long Register 5307instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5308%{ 5309 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5310 5311 ins_cost(125); 5312 format %{ "movl $dst, $mem\t# uint -> long" %} 5313 5314 ins_encode %{ 5315 __ movl($dst$$Register, $mem$$Address); 5316 %} 5317 5318 ins_pipe(ialu_reg_mem); 5319%} 5320 5321// Load Long 5322instruct loadL(rRegL dst, memory mem) 5323%{ 5324 match(Set dst (LoadL mem)); 5325 5326 ins_cost(125); 5327 format %{ "movq $dst, $mem\t# long" %} 5328 5329 ins_encode %{ 5330 __ movq($dst$$Register, $mem$$Address); 5331 %} 5332 5333 ins_pipe(ialu_reg_mem); // XXX 5334%} 5335 5336// Load Range 5337instruct loadRange(rRegI dst, memory mem) 5338%{ 5339 match(Set dst (LoadRange mem)); 5340 5341 ins_cost(125); // XXX 5342 format %{ "movl $dst, $mem\t# range" %} 5343 opcode(0x8B); 5344 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5345 ins_pipe(ialu_reg_mem); 5346%} 5347 5348// Load Pointer 5349instruct loadP(rRegP dst, memory mem) 5350%{ 5351 match(Set dst (LoadP mem)); 5352 5353 ins_cost(125); // XXX 5354 format %{ "movq $dst, $mem\t# ptr" %} 5355 opcode(0x8B); 5356 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5357 ins_pipe(ialu_reg_mem); // XXX 5358%} 5359 5360// Load Compressed Pointer 5361instruct loadN(rRegN dst, memory mem) 5362%{ 5363 match(Set dst (LoadN mem)); 5364 5365 ins_cost(125); // XXX 5366 format %{ "movl $dst, $mem\t# compressed ptr" %} 5367 ins_encode %{ 5368 __ movl($dst$$Register, $mem$$Address); 5369 %} 5370 ins_pipe(ialu_reg_mem); // XXX 5371%} 5372 5373 5374// Load Klass Pointer 5375instruct loadKlass(rRegP dst, memory mem) 5376%{ 5377 match(Set dst (LoadKlass mem)); 5378 5379 ins_cost(125); // XXX 5380 format %{ "movq $dst, $mem\t# class" %} 5381 opcode(0x8B); 5382 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5383 ins_pipe(ialu_reg_mem); // XXX 5384%} 5385 5386// Load narrow Klass Pointer 5387instruct loadNKlass(rRegN dst, memory mem) 5388%{ 5389 match(Set dst (LoadNKlass mem)); 5390 5391 ins_cost(125); // XXX 5392 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5393 ins_encode %{ 5394 __ movl($dst$$Register, $mem$$Address); 5395 %} 5396 ins_pipe(ialu_reg_mem); // XXX 5397%} 5398 5399// Load Float 5400instruct loadF(regF dst, memory mem) 5401%{ 5402 match(Set dst (LoadF mem)); 5403 5404 ins_cost(145); // XXX 5405 format %{ "movss $dst, $mem\t# float" %} 5406 ins_encode %{ 5407 __ movflt($dst$$XMMRegister, $mem$$Address); 5408 %} 5409 ins_pipe(pipe_slow); // XXX 5410%} 5411 5412// Load Float 5413instruct MoveF2VL(vlRegF dst, regF src) %{ 5414 match(Set dst src); 5415 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5416 ins_encode %{ 5417 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5418 %} 5419 ins_pipe( fpu_reg_reg ); 5420%} 5421 5422// Load Float 5423instruct MoveVL2F(regF dst, vlRegF src) %{ 5424 match(Set dst src); 5425 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5426 ins_encode %{ 5427 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5428 %} 5429 ins_pipe( fpu_reg_reg ); 5430%} 5431 5432// Load Double 5433instruct loadD_partial(regD dst, memory mem) 5434%{ 5435 predicate(!UseXmmLoadAndClearUpper); 5436 match(Set dst (LoadD mem)); 5437 5438 ins_cost(145); // XXX 5439 format %{ "movlpd $dst, $mem\t# double" %} 5440 ins_encode %{ 5441 __ movdbl($dst$$XMMRegister, $mem$$Address); 5442 %} 5443 ins_pipe(pipe_slow); // XXX 5444%} 5445 5446instruct loadD(regD dst, memory mem) 5447%{ 5448 predicate(UseXmmLoadAndClearUpper); 5449 match(Set dst (LoadD mem)); 5450 5451 ins_cost(145); // XXX 5452 format %{ "movsd $dst, $mem\t# double" %} 5453 ins_encode %{ 5454 __ movdbl($dst$$XMMRegister, $mem$$Address); 5455 %} 5456 ins_pipe(pipe_slow); // XXX 5457%} 5458 5459// Load Double 5460instruct MoveD2VL(vlRegD dst, regD src) %{ 5461 match(Set dst src); 5462 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5463 ins_encode %{ 5464 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5465 %} 5466 ins_pipe( fpu_reg_reg ); 5467%} 5468 5469// Load Double 5470instruct MoveVL2D(regD dst, vlRegD src) %{ 5471 match(Set dst src); 5472 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5473 ins_encode %{ 5474 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5475 %} 5476 ins_pipe( fpu_reg_reg ); 5477%} 5478 5479// Load Effective Address 5480instruct leaP8(rRegP dst, indOffset8 mem) 5481%{ 5482 match(Set dst mem); 5483 5484 ins_cost(110); // XXX 5485 format %{ "leaq $dst, $mem\t# ptr 8" %} 5486 opcode(0x8D); 5487 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5488 ins_pipe(ialu_reg_reg_fat); 5489%} 5490 5491instruct leaP32(rRegP dst, indOffset32 mem) 5492%{ 5493 match(Set dst mem); 5494 5495 ins_cost(110); 5496 format %{ "leaq $dst, $mem\t# ptr 32" %} 5497 opcode(0x8D); 5498 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5499 ins_pipe(ialu_reg_reg_fat); 5500%} 5501 5502// instruct leaPIdx(rRegP dst, indIndex mem) 5503// %{ 5504// match(Set dst mem); 5505 5506// ins_cost(110); 5507// format %{ "leaq $dst, $mem\t# ptr idx" %} 5508// opcode(0x8D); 5509// ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5510// ins_pipe(ialu_reg_reg_fat); 5511// %} 5512 5513instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5514%{ 5515 match(Set dst mem); 5516 5517 ins_cost(110); 5518 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5519 opcode(0x8D); 5520 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5521 ins_pipe(ialu_reg_reg_fat); 5522%} 5523 5524instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5525%{ 5526 match(Set dst mem); 5527 5528 ins_cost(110); 5529 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5530 opcode(0x8D); 5531 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5532 ins_pipe(ialu_reg_reg_fat); 5533%} 5534 5535instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5536%{ 5537 match(Set dst mem); 5538 5539 ins_cost(110); 5540 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5541 opcode(0x8D); 5542 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5543 ins_pipe(ialu_reg_reg_fat); 5544%} 5545 5546instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5547%{ 5548 match(Set dst mem); 5549 5550 ins_cost(110); 5551 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5552 opcode(0x8D); 5553 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5554 ins_pipe(ialu_reg_reg_fat); 5555%} 5556 5557instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5558%{ 5559 match(Set dst mem); 5560 5561 ins_cost(110); 5562 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5563 opcode(0x8D); 5564 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5565 ins_pipe(ialu_reg_reg_fat); 5566%} 5567 5568instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5569%{ 5570 match(Set dst mem); 5571 5572 ins_cost(110); 5573 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5574 opcode(0x8D); 5575 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5576 ins_pipe(ialu_reg_reg_fat); 5577%} 5578 5579// Load Effective Address which uses Narrow (32-bits) oop 5580instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5581%{ 5582 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5583 match(Set dst mem); 5584 5585 ins_cost(110); 5586 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5587 opcode(0x8D); 5588 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5589 ins_pipe(ialu_reg_reg_fat); 5590%} 5591 5592instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5593%{ 5594 predicate(Universe::narrow_oop_shift() == 0); 5595 match(Set dst mem); 5596 5597 ins_cost(110); // XXX 5598 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5599 opcode(0x8D); 5600 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5601 ins_pipe(ialu_reg_reg_fat); 5602%} 5603 5604instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5605%{ 5606 predicate(Universe::narrow_oop_shift() == 0); 5607 match(Set dst mem); 5608 5609 ins_cost(110); 5610 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5611 opcode(0x8D); 5612 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5613 ins_pipe(ialu_reg_reg_fat); 5614%} 5615 5616instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5617%{ 5618 predicate(Universe::narrow_oop_shift() == 0); 5619 match(Set dst mem); 5620 5621 ins_cost(110); 5622 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5623 opcode(0x8D); 5624 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5625 ins_pipe(ialu_reg_reg_fat); 5626%} 5627 5628instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5629%{ 5630 predicate(Universe::narrow_oop_shift() == 0); 5631 match(Set dst mem); 5632 5633 ins_cost(110); 5634 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5635 opcode(0x8D); 5636 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5637 ins_pipe(ialu_reg_reg_fat); 5638%} 5639 5640instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5641%{ 5642 predicate(Universe::narrow_oop_shift() == 0); 5643 match(Set dst mem); 5644 5645 ins_cost(110); 5646 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5647 opcode(0x8D); 5648 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5649 ins_pipe(ialu_reg_reg_fat); 5650%} 5651 5652instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5653%{ 5654 predicate(Universe::narrow_oop_shift() == 0); 5655 match(Set dst mem); 5656 5657 ins_cost(110); 5658 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5659 opcode(0x8D); 5660 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5661 ins_pipe(ialu_reg_reg_fat); 5662%} 5663 5664instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5665%{ 5666 predicate(Universe::narrow_oop_shift() == 0); 5667 match(Set dst mem); 5668 5669 ins_cost(110); 5670 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5671 opcode(0x8D); 5672 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5673 ins_pipe(ialu_reg_reg_fat); 5674%} 5675 5676instruct loadConI(rRegI dst, immI src) 5677%{ 5678 match(Set dst src); 5679 5680 format %{ "movl $dst, $src\t# int" %} 5681 ins_encode(load_immI(dst, src)); 5682 ins_pipe(ialu_reg_fat); // XXX 5683%} 5684 5685instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5686%{ 5687 match(Set dst src); 5688 effect(KILL cr); 5689 5690 ins_cost(50); 5691 format %{ "xorl $dst, $dst\t# int" %} 5692 opcode(0x33); /* + rd */ 5693 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5694 ins_pipe(ialu_reg); 5695%} 5696 5697instruct loadConL(rRegL dst, immL src) 5698%{ 5699 match(Set dst src); 5700 5701 ins_cost(150); 5702 format %{ "movq $dst, $src\t# long" %} 5703 ins_encode(load_immL(dst, src)); 5704 ins_pipe(ialu_reg); 5705%} 5706 5707instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5708%{ 5709 match(Set dst src); 5710 effect(KILL cr); 5711 5712 ins_cost(50); 5713 format %{ "xorl $dst, $dst\t# long" %} 5714 opcode(0x33); /* + rd */ 5715 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5716 ins_pipe(ialu_reg); // XXX 5717%} 5718 5719instruct loadConUL32(rRegL dst, immUL32 src) 5720%{ 5721 match(Set dst src); 5722 5723 ins_cost(60); 5724 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5725 ins_encode(load_immUL32(dst, src)); 5726 ins_pipe(ialu_reg); 5727%} 5728 5729instruct loadConL32(rRegL dst, immL32 src) 5730%{ 5731 match(Set dst src); 5732 5733 ins_cost(70); 5734 format %{ "movq $dst, $src\t# long (32-bit)" %} 5735 ins_encode(load_immL32(dst, src)); 5736 ins_pipe(ialu_reg); 5737%} 5738 5739instruct loadConP(rRegP dst, immP con) %{ 5740 match(Set dst con); 5741 5742 format %{ "movq $dst, $con\t# ptr" %} 5743 ins_encode(load_immP(dst, con)); 5744 ins_pipe(ialu_reg_fat); // XXX 5745%} 5746 5747instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5748%{ 5749 match(Set dst src); 5750 effect(KILL cr); 5751 5752 ins_cost(50); 5753 format %{ "xorl $dst, $dst\t# ptr" %} 5754 opcode(0x33); /* + rd */ 5755 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5756 ins_pipe(ialu_reg); 5757%} 5758 5759instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5760%{ 5761 match(Set dst src); 5762 effect(KILL cr); 5763 5764 ins_cost(60); 5765 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5766 ins_encode(load_immP31(dst, src)); 5767 ins_pipe(ialu_reg); 5768%} 5769 5770instruct loadConF(regF dst, immF con) %{ 5771 match(Set dst con); 5772 ins_cost(125); 5773 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5774 ins_encode %{ 5775 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5776 %} 5777 ins_pipe(pipe_slow); 5778%} 5779 5780instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5781 match(Set dst src); 5782 effect(KILL cr); 5783 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5784 ins_encode %{ 5785 __ xorq($dst$$Register, $dst$$Register); 5786 %} 5787 ins_pipe(ialu_reg); 5788%} 5789 5790instruct loadConN(rRegN dst, immN src) %{ 5791 match(Set dst src); 5792 5793 ins_cost(125); 5794 format %{ "movl $dst, $src\t# compressed ptr" %} 5795 ins_encode %{ 5796 address con = (address)$src$$constant; 5797 if (con == NULL) { 5798 ShouldNotReachHere(); 5799 } else { 5800 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5801 } 5802 %} 5803 ins_pipe(ialu_reg_fat); // XXX 5804%} 5805 5806instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5807 match(Set dst src); 5808 5809 ins_cost(125); 5810 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5811 ins_encode %{ 5812 address con = (address)$src$$constant; 5813 if (con == NULL) { 5814 ShouldNotReachHere(); 5815 } else { 5816 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5817 } 5818 %} 5819 ins_pipe(ialu_reg_fat); // XXX 5820%} 5821 5822instruct loadConF0(regF dst, immF0 src) 5823%{ 5824 match(Set dst src); 5825 ins_cost(100); 5826 5827 format %{ "xorps $dst, $dst\t# float 0.0" %} 5828 ins_encode %{ 5829 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5830 %} 5831 ins_pipe(pipe_slow); 5832%} 5833 5834// Use the same format since predicate() can not be used here. 5835instruct loadConD(regD dst, immD con) %{ 5836 match(Set dst con); 5837 ins_cost(125); 5838 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5839 ins_encode %{ 5840 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5841 %} 5842 ins_pipe(pipe_slow); 5843%} 5844 5845instruct loadConD0(regD dst, immD0 src) 5846%{ 5847 match(Set dst src); 5848 ins_cost(100); 5849 5850 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5851 ins_encode %{ 5852 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5853 %} 5854 ins_pipe(pipe_slow); 5855%} 5856 5857instruct loadSSI(rRegI dst, stackSlotI src) 5858%{ 5859 match(Set dst src); 5860 5861 ins_cost(125); 5862 format %{ "movl $dst, $src\t# int stk" %} 5863 opcode(0x8B); 5864 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5865 ins_pipe(ialu_reg_mem); 5866%} 5867 5868instruct loadSSL(rRegL dst, stackSlotL src) 5869%{ 5870 match(Set dst src); 5871 5872 ins_cost(125); 5873 format %{ "movq $dst, $src\t# long stk" %} 5874 opcode(0x8B); 5875 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5876 ins_pipe(ialu_reg_mem); 5877%} 5878 5879instruct loadSSP(rRegP dst, stackSlotP src) 5880%{ 5881 match(Set dst src); 5882 5883 ins_cost(125); 5884 format %{ "movq $dst, $src\t# ptr stk" %} 5885 opcode(0x8B); 5886 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5887 ins_pipe(ialu_reg_mem); 5888%} 5889 5890instruct loadSSF(regF dst, stackSlotF src) 5891%{ 5892 match(Set dst src); 5893 5894 ins_cost(125); 5895 format %{ "movss $dst, $src\t# float stk" %} 5896 ins_encode %{ 5897 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5898 %} 5899 ins_pipe(pipe_slow); // XXX 5900%} 5901 5902// Use the same format since predicate() can not be used here. 5903instruct loadSSD(regD dst, stackSlotD src) 5904%{ 5905 match(Set dst src); 5906 5907 ins_cost(125); 5908 format %{ "movsd $dst, $src\t# double stk" %} 5909 ins_encode %{ 5910 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5911 %} 5912 ins_pipe(pipe_slow); // XXX 5913%} 5914 5915// Prefetch instructions for allocation. 5916// Must be safe to execute with invalid address (cannot fault). 5917 5918instruct prefetchAlloc( memory mem ) %{ 5919 predicate(AllocatePrefetchInstr==3); 5920 match(PrefetchAllocation mem); 5921 ins_cost(125); 5922 5923 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5924 ins_encode %{ 5925 __ prefetchw($mem$$Address); 5926 %} 5927 ins_pipe(ialu_mem); 5928%} 5929 5930instruct prefetchAllocNTA( memory mem ) %{ 5931 predicate(AllocatePrefetchInstr==0); 5932 match(PrefetchAllocation mem); 5933 ins_cost(125); 5934 5935 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5936 ins_encode %{ 5937 __ prefetchnta($mem$$Address); 5938 %} 5939 ins_pipe(ialu_mem); 5940%} 5941 5942instruct prefetchAllocT0( memory mem ) %{ 5943 predicate(AllocatePrefetchInstr==1); 5944 match(PrefetchAllocation mem); 5945 ins_cost(125); 5946 5947 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5948 ins_encode %{ 5949 __ prefetcht0($mem$$Address); 5950 %} 5951 ins_pipe(ialu_mem); 5952%} 5953 5954instruct prefetchAllocT2( memory mem ) %{ 5955 predicate(AllocatePrefetchInstr==2); 5956 match(PrefetchAllocation mem); 5957 ins_cost(125); 5958 5959 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5960 ins_encode %{ 5961 __ prefetcht2($mem$$Address); 5962 %} 5963 ins_pipe(ialu_mem); 5964%} 5965 5966//----------Store Instructions------------------------------------------------- 5967 5968// Store Byte 5969instruct storeB(memory mem, rRegI src) 5970%{ 5971 match(Set mem (StoreB mem src)); 5972 5973 ins_cost(125); // XXX 5974 format %{ "movb $mem, $src\t# byte" %} 5975 opcode(0x88); 5976 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5977 ins_pipe(ialu_mem_reg); 5978%} 5979 5980// Store Char/Short 5981instruct storeC(memory mem, rRegI src) 5982%{ 5983 match(Set mem (StoreC mem src)); 5984 5985 ins_cost(125); // XXX 5986 format %{ "movw $mem, $src\t# char/short" %} 5987 opcode(0x89); 5988 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5989 ins_pipe(ialu_mem_reg); 5990%} 5991 5992// Store Integer 5993instruct storeI(memory mem, rRegI src) 5994%{ 5995 match(Set mem (StoreI mem src)); 5996 5997 ins_cost(125); // XXX 5998 format %{ "movl $mem, $src\t# int" %} 5999 opcode(0x89); 6000 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6001 ins_pipe(ialu_mem_reg); 6002%} 6003 6004// Store Long 6005instruct storeL(memory mem, rRegL src) 6006%{ 6007 match(Set mem (StoreL mem src)); 6008 6009 ins_cost(125); // XXX 6010 format %{ "movq $mem, $src\t# long" %} 6011 opcode(0x89); 6012 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6013 ins_pipe(ialu_mem_reg); // XXX 6014%} 6015 6016// Store Pointer 6017instruct storeP(memory mem, any_RegP src) 6018%{ 6019 match(Set mem (StoreP mem src)); 6020 6021 ins_cost(125); // XXX 6022 format %{ "movq $mem, $src\t# ptr" %} 6023 opcode(0x89); 6024 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6025 ins_pipe(ialu_mem_reg); 6026%} 6027 6028instruct storeImmP0(memory mem, immP0 zero) 6029%{ 6030 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6031 match(Set mem (StoreP mem zero)); 6032 6033 ins_cost(125); // XXX 6034 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 6035 ins_encode %{ 6036 __ movq($mem$$Address, r12); 6037 %} 6038 ins_pipe(ialu_mem_reg); 6039%} 6040 6041// Store NULL Pointer, mark word, or other simple pointer constant. 6042instruct storeImmP(memory mem, immP31 src) 6043%{ 6044 match(Set mem (StoreP mem src)); 6045 6046 ins_cost(150); // XXX 6047 format %{ "movq $mem, $src\t# ptr" %} 6048 opcode(0xC7); /* C7 /0 */ 6049 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6050 ins_pipe(ialu_mem_imm); 6051%} 6052 6053// Store Compressed Pointer 6054instruct storeN(memory mem, rRegN src) 6055%{ 6056 match(Set mem (StoreN mem src)); 6057 6058 ins_cost(125); // XXX 6059 format %{ "movl $mem, $src\t# compressed ptr" %} 6060 ins_encode %{ 6061 __ movl($mem$$Address, $src$$Register); 6062 %} 6063 ins_pipe(ialu_mem_reg); 6064%} 6065 6066instruct storeNKlass(memory mem, rRegN src) 6067%{ 6068 match(Set mem (StoreNKlass mem src)); 6069 6070 ins_cost(125); // XXX 6071 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6072 ins_encode %{ 6073 __ movl($mem$$Address, $src$$Register); 6074 %} 6075 ins_pipe(ialu_mem_reg); 6076%} 6077 6078instruct storeImmN0(memory mem, immN0 zero) 6079%{ 6080 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 6081 match(Set mem (StoreN mem zero)); 6082 6083 ins_cost(125); // XXX 6084 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6085 ins_encode %{ 6086 __ movl($mem$$Address, r12); 6087 %} 6088 ins_pipe(ialu_mem_reg); 6089%} 6090 6091instruct storeImmN(memory mem, immN src) 6092%{ 6093 match(Set mem (StoreN mem src)); 6094 6095 ins_cost(150); // XXX 6096 format %{ "movl $mem, $src\t# compressed ptr" %} 6097 ins_encode %{ 6098 address con = (address)$src$$constant; 6099 if (con == NULL) { 6100 __ movl($mem$$Address, (int32_t)0); 6101 } else { 6102 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6103 } 6104 %} 6105 ins_pipe(ialu_mem_imm); 6106%} 6107 6108instruct storeImmNKlass(memory mem, immNKlass src) 6109%{ 6110 match(Set mem (StoreNKlass mem src)); 6111 6112 ins_cost(150); // XXX 6113 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6114 ins_encode %{ 6115 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 6116 %} 6117 ins_pipe(ialu_mem_imm); 6118%} 6119 6120// Store Integer Immediate 6121instruct storeImmI0(memory mem, immI0 zero) 6122%{ 6123 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6124 match(Set mem (StoreI mem zero)); 6125 6126 ins_cost(125); // XXX 6127 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6128 ins_encode %{ 6129 __ movl($mem$$Address, r12); 6130 %} 6131 ins_pipe(ialu_mem_reg); 6132%} 6133 6134instruct storeImmI(memory mem, immI src) 6135%{ 6136 match(Set mem (StoreI mem src)); 6137 6138 ins_cost(150); 6139 format %{ "movl $mem, $src\t# int" %} 6140 opcode(0xC7); /* C7 /0 */ 6141 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6142 ins_pipe(ialu_mem_imm); 6143%} 6144 6145// Store Long Immediate 6146instruct storeImmL0(memory mem, immL0 zero) 6147%{ 6148 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6149 match(Set mem (StoreL mem zero)); 6150 6151 ins_cost(125); // XXX 6152 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6153 ins_encode %{ 6154 __ movq($mem$$Address, r12); 6155 %} 6156 ins_pipe(ialu_mem_reg); 6157%} 6158 6159instruct storeImmL(memory mem, immL32 src) 6160%{ 6161 match(Set mem (StoreL mem src)); 6162 6163 ins_cost(150); 6164 format %{ "movq $mem, $src\t# long" %} 6165 opcode(0xC7); /* C7 /0 */ 6166 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6167 ins_pipe(ialu_mem_imm); 6168%} 6169 6170// Store Short/Char Immediate 6171instruct storeImmC0(memory mem, immI0 zero) 6172%{ 6173 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6174 match(Set mem (StoreC mem zero)); 6175 6176 ins_cost(125); // XXX 6177 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6178 ins_encode %{ 6179 __ movw($mem$$Address, r12); 6180 %} 6181 ins_pipe(ialu_mem_reg); 6182%} 6183 6184instruct storeImmI16(memory mem, immI16 src) 6185%{ 6186 predicate(UseStoreImmI16); 6187 match(Set mem (StoreC mem src)); 6188 6189 ins_cost(150); 6190 format %{ "movw $mem, $src\t# short/char" %} 6191 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6192 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6193 ins_pipe(ialu_mem_imm); 6194%} 6195 6196// Store Byte Immediate 6197instruct storeImmB0(memory mem, immI0 zero) 6198%{ 6199 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6200 match(Set mem (StoreB mem zero)); 6201 6202 ins_cost(125); // XXX 6203 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6204 ins_encode %{ 6205 __ movb($mem$$Address, r12); 6206 %} 6207 ins_pipe(ialu_mem_reg); 6208%} 6209 6210instruct storeImmB(memory mem, immI8 src) 6211%{ 6212 match(Set mem (StoreB mem src)); 6213 6214 ins_cost(150); // XXX 6215 format %{ "movb $mem, $src\t# byte" %} 6216 opcode(0xC6); /* C6 /0 */ 6217 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6218 ins_pipe(ialu_mem_imm); 6219%} 6220 6221// Store CMS card-mark Immediate 6222instruct storeImmCM0_reg(memory mem, immI0 zero) 6223%{ 6224 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6225 match(Set mem (StoreCM mem zero)); 6226 6227 ins_cost(125); // XXX 6228 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6229 ins_encode %{ 6230 __ movb($mem$$Address, r12); 6231 %} 6232 ins_pipe(ialu_mem_reg); 6233%} 6234 6235instruct storeImmCM0(memory mem, immI0 src) 6236%{ 6237 match(Set mem (StoreCM mem src)); 6238 6239 ins_cost(150); // XXX 6240 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6241 opcode(0xC6); /* C6 /0 */ 6242 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6243 ins_pipe(ialu_mem_imm); 6244%} 6245 6246// Store Float 6247instruct storeF(memory mem, regF src) 6248%{ 6249 match(Set mem (StoreF mem src)); 6250 6251 ins_cost(95); // XXX 6252 format %{ "movss $mem, $src\t# float" %} 6253 ins_encode %{ 6254 __ movflt($mem$$Address, $src$$XMMRegister); 6255 %} 6256 ins_pipe(pipe_slow); // XXX 6257%} 6258 6259// Store immediate Float value (it is faster than store from XMM register) 6260instruct storeF0(memory mem, immF0 zero) 6261%{ 6262 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6263 match(Set mem (StoreF mem zero)); 6264 6265 ins_cost(25); // XXX 6266 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6267 ins_encode %{ 6268 __ movl($mem$$Address, r12); 6269 %} 6270 ins_pipe(ialu_mem_reg); 6271%} 6272 6273instruct storeF_imm(memory mem, immF src) 6274%{ 6275 match(Set mem (StoreF mem src)); 6276 6277 ins_cost(50); 6278 format %{ "movl $mem, $src\t# float" %} 6279 opcode(0xC7); /* C7 /0 */ 6280 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6281 ins_pipe(ialu_mem_imm); 6282%} 6283 6284// Store Double 6285instruct storeD(memory mem, regD src) 6286%{ 6287 match(Set mem (StoreD mem src)); 6288 6289 ins_cost(95); // XXX 6290 format %{ "movsd $mem, $src\t# double" %} 6291 ins_encode %{ 6292 __ movdbl($mem$$Address, $src$$XMMRegister); 6293 %} 6294 ins_pipe(pipe_slow); // XXX 6295%} 6296 6297// Store immediate double 0.0 (it is faster than store from XMM register) 6298instruct storeD0_imm(memory mem, immD0 src) 6299%{ 6300 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6301 match(Set mem (StoreD mem src)); 6302 6303 ins_cost(50); 6304 format %{ "movq $mem, $src\t# double 0." %} 6305 opcode(0xC7); /* C7 /0 */ 6306 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6307 ins_pipe(ialu_mem_imm); 6308%} 6309 6310instruct storeD0(memory mem, immD0 zero) 6311%{ 6312 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6313 match(Set mem (StoreD mem zero)); 6314 6315 ins_cost(25); // XXX 6316 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6317 ins_encode %{ 6318 __ movq($mem$$Address, r12); 6319 %} 6320 ins_pipe(ialu_mem_reg); 6321%} 6322 6323instruct storeSSI(stackSlotI dst, rRegI src) 6324%{ 6325 match(Set dst src); 6326 6327 ins_cost(100); 6328 format %{ "movl $dst, $src\t# int stk" %} 6329 opcode(0x89); 6330 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6331 ins_pipe( ialu_mem_reg ); 6332%} 6333 6334instruct storeSSL(stackSlotL dst, rRegL src) 6335%{ 6336 match(Set dst src); 6337 6338 ins_cost(100); 6339 format %{ "movq $dst, $src\t# long stk" %} 6340 opcode(0x89); 6341 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6342 ins_pipe(ialu_mem_reg); 6343%} 6344 6345instruct storeSSP(stackSlotP dst, rRegP src) 6346%{ 6347 match(Set dst src); 6348 6349 ins_cost(100); 6350 format %{ "movq $dst, $src\t# ptr stk" %} 6351 opcode(0x89); 6352 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6353 ins_pipe(ialu_mem_reg); 6354%} 6355 6356instruct storeSSF(stackSlotF dst, regF src) 6357%{ 6358 match(Set dst src); 6359 6360 ins_cost(95); // XXX 6361 format %{ "movss $dst, $src\t# float stk" %} 6362 ins_encode %{ 6363 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6364 %} 6365 ins_pipe(pipe_slow); // XXX 6366%} 6367 6368instruct storeSSD(stackSlotD dst, regD src) 6369%{ 6370 match(Set dst src); 6371 6372 ins_cost(95); // XXX 6373 format %{ "movsd $dst, $src\t# double stk" %} 6374 ins_encode %{ 6375 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6376 %} 6377 ins_pipe(pipe_slow); // XXX 6378%} 6379 6380//----------BSWAP Instructions------------------------------------------------- 6381instruct bytes_reverse_int(rRegI dst) %{ 6382 match(Set dst (ReverseBytesI dst)); 6383 6384 format %{ "bswapl $dst" %} 6385 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6386 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6387 ins_pipe( ialu_reg ); 6388%} 6389 6390instruct bytes_reverse_long(rRegL dst) %{ 6391 match(Set dst (ReverseBytesL dst)); 6392 6393 format %{ "bswapq $dst" %} 6394 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6395 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6396 ins_pipe( ialu_reg); 6397%} 6398 6399instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6400 match(Set dst (ReverseBytesUS dst)); 6401 effect(KILL cr); 6402 6403 format %{ "bswapl $dst\n\t" 6404 "shrl $dst,16\n\t" %} 6405 ins_encode %{ 6406 __ bswapl($dst$$Register); 6407 __ shrl($dst$$Register, 16); 6408 %} 6409 ins_pipe( ialu_reg ); 6410%} 6411 6412instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6413 match(Set dst (ReverseBytesS dst)); 6414 effect(KILL cr); 6415 6416 format %{ "bswapl $dst\n\t" 6417 "sar $dst,16\n\t" %} 6418 ins_encode %{ 6419 __ bswapl($dst$$Register); 6420 __ sarl($dst$$Register, 16); 6421 %} 6422 ins_pipe( ialu_reg ); 6423%} 6424 6425//---------- Zeros Count Instructions ------------------------------------------ 6426 6427instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6428 predicate(UseCountLeadingZerosInstruction); 6429 match(Set dst (CountLeadingZerosI src)); 6430 effect(KILL cr); 6431 6432 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6433 ins_encode %{ 6434 __ lzcntl($dst$$Register, $src$$Register); 6435 %} 6436 ins_pipe(ialu_reg); 6437%} 6438 6439instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6440 predicate(!UseCountLeadingZerosInstruction); 6441 match(Set dst (CountLeadingZerosI src)); 6442 effect(KILL cr); 6443 6444 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6445 "jnz skip\n\t" 6446 "movl $dst, -1\n" 6447 "skip:\n\t" 6448 "negl $dst\n\t" 6449 "addl $dst, 31" %} 6450 ins_encode %{ 6451 Register Rdst = $dst$$Register; 6452 Register Rsrc = $src$$Register; 6453 Label skip; 6454 __ bsrl(Rdst, Rsrc); 6455 __ jccb(Assembler::notZero, skip); 6456 __ movl(Rdst, -1); 6457 __ bind(skip); 6458 __ negl(Rdst); 6459 __ addl(Rdst, BitsPerInt - 1); 6460 %} 6461 ins_pipe(ialu_reg); 6462%} 6463 6464instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6465 predicate(UseCountLeadingZerosInstruction); 6466 match(Set dst (CountLeadingZerosL src)); 6467 effect(KILL cr); 6468 6469 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6470 ins_encode %{ 6471 __ lzcntq($dst$$Register, $src$$Register); 6472 %} 6473 ins_pipe(ialu_reg); 6474%} 6475 6476instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6477 predicate(!UseCountLeadingZerosInstruction); 6478 match(Set dst (CountLeadingZerosL src)); 6479 effect(KILL cr); 6480 6481 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6482 "jnz skip\n\t" 6483 "movl $dst, -1\n" 6484 "skip:\n\t" 6485 "negl $dst\n\t" 6486 "addl $dst, 63" %} 6487 ins_encode %{ 6488 Register Rdst = $dst$$Register; 6489 Register Rsrc = $src$$Register; 6490 Label skip; 6491 __ bsrq(Rdst, Rsrc); 6492 __ jccb(Assembler::notZero, skip); 6493 __ movl(Rdst, -1); 6494 __ bind(skip); 6495 __ negl(Rdst); 6496 __ addl(Rdst, BitsPerLong - 1); 6497 %} 6498 ins_pipe(ialu_reg); 6499%} 6500 6501instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6502 predicate(UseCountTrailingZerosInstruction); 6503 match(Set dst (CountTrailingZerosI src)); 6504 effect(KILL cr); 6505 6506 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6507 ins_encode %{ 6508 __ tzcntl($dst$$Register, $src$$Register); 6509 %} 6510 ins_pipe(ialu_reg); 6511%} 6512 6513instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6514 predicate(!UseCountTrailingZerosInstruction); 6515 match(Set dst (CountTrailingZerosI src)); 6516 effect(KILL cr); 6517 6518 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6519 "jnz done\n\t" 6520 "movl $dst, 32\n" 6521 "done:" %} 6522 ins_encode %{ 6523 Register Rdst = $dst$$Register; 6524 Label done; 6525 __ bsfl(Rdst, $src$$Register); 6526 __ jccb(Assembler::notZero, done); 6527 __ movl(Rdst, BitsPerInt); 6528 __ bind(done); 6529 %} 6530 ins_pipe(ialu_reg); 6531%} 6532 6533instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6534 predicate(UseCountTrailingZerosInstruction); 6535 match(Set dst (CountTrailingZerosL src)); 6536 effect(KILL cr); 6537 6538 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6539 ins_encode %{ 6540 __ tzcntq($dst$$Register, $src$$Register); 6541 %} 6542 ins_pipe(ialu_reg); 6543%} 6544 6545instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6546 predicate(!UseCountTrailingZerosInstruction); 6547 match(Set dst (CountTrailingZerosL src)); 6548 effect(KILL cr); 6549 6550 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6551 "jnz done\n\t" 6552 "movl $dst, 64\n" 6553 "done:" %} 6554 ins_encode %{ 6555 Register Rdst = $dst$$Register; 6556 Label done; 6557 __ bsfq(Rdst, $src$$Register); 6558 __ jccb(Assembler::notZero, done); 6559 __ movl(Rdst, BitsPerLong); 6560 __ bind(done); 6561 %} 6562 ins_pipe(ialu_reg); 6563%} 6564 6565 6566//---------- Population Count Instructions ------------------------------------- 6567 6568instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6569 predicate(UsePopCountInstruction); 6570 match(Set dst (PopCountI src)); 6571 effect(KILL cr); 6572 6573 format %{ "popcnt $dst, $src" %} 6574 ins_encode %{ 6575 __ popcntl($dst$$Register, $src$$Register); 6576 %} 6577 ins_pipe(ialu_reg); 6578%} 6579 6580instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6581 predicate(UsePopCountInstruction); 6582 match(Set dst (PopCountI (LoadI mem))); 6583 effect(KILL cr); 6584 6585 format %{ "popcnt $dst, $mem" %} 6586 ins_encode %{ 6587 __ popcntl($dst$$Register, $mem$$Address); 6588 %} 6589 ins_pipe(ialu_reg); 6590%} 6591 6592// Note: Long.bitCount(long) returns an int. 6593instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6594 predicate(UsePopCountInstruction); 6595 match(Set dst (PopCountL src)); 6596 effect(KILL cr); 6597 6598 format %{ "popcnt $dst, $src" %} 6599 ins_encode %{ 6600 __ popcntq($dst$$Register, $src$$Register); 6601 %} 6602 ins_pipe(ialu_reg); 6603%} 6604 6605// Note: Long.bitCount(long) returns an int. 6606instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6607 predicate(UsePopCountInstruction); 6608 match(Set dst (PopCountL (LoadL mem))); 6609 effect(KILL cr); 6610 6611 format %{ "popcnt $dst, $mem" %} 6612 ins_encode %{ 6613 __ popcntq($dst$$Register, $mem$$Address); 6614 %} 6615 ins_pipe(ialu_reg); 6616%} 6617 6618 6619//----------MemBar Instructions----------------------------------------------- 6620// Memory barrier flavors 6621 6622instruct membar_acquire() 6623%{ 6624 match(MemBarAcquire); 6625 match(LoadFence); 6626 ins_cost(0); 6627 6628 size(0); 6629 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6630 ins_encode(); 6631 ins_pipe(empty); 6632%} 6633 6634instruct membar_acquire_lock() 6635%{ 6636 match(MemBarAcquireLock); 6637 ins_cost(0); 6638 6639 size(0); 6640 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6641 ins_encode(); 6642 ins_pipe(empty); 6643%} 6644 6645instruct membar_release() 6646%{ 6647 match(MemBarRelease); 6648 match(StoreFence); 6649 ins_cost(0); 6650 6651 size(0); 6652 format %{ "MEMBAR-release ! (empty encoding)" %} 6653 ins_encode(); 6654 ins_pipe(empty); 6655%} 6656 6657instruct membar_release_lock() 6658%{ 6659 match(MemBarReleaseLock); 6660 ins_cost(0); 6661 6662 size(0); 6663 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6664 ins_encode(); 6665 ins_pipe(empty); 6666%} 6667 6668instruct membar_volatile(rFlagsReg cr) %{ 6669 match(MemBarVolatile); 6670 effect(KILL cr); 6671 ins_cost(400); 6672 6673 format %{ 6674 $$template 6675 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6676 %} 6677 ins_encode %{ 6678 __ membar(Assembler::StoreLoad); 6679 %} 6680 ins_pipe(pipe_slow); 6681%} 6682 6683instruct unnecessary_membar_volatile() 6684%{ 6685 match(MemBarVolatile); 6686 predicate(Matcher::post_store_load_barrier(n)); 6687 ins_cost(0); 6688 6689 size(0); 6690 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6691 ins_encode(); 6692 ins_pipe(empty); 6693%} 6694 6695instruct membar_storestore() %{ 6696 match(MemBarStoreStore); 6697 ins_cost(0); 6698 6699 size(0); 6700 format %{ "MEMBAR-storestore (empty encoding)" %} 6701 ins_encode( ); 6702 ins_pipe(empty); 6703%} 6704 6705//----------Move Instructions-------------------------------------------------- 6706 6707instruct castX2P(rRegP dst, rRegL src) 6708%{ 6709 match(Set dst (CastX2P src)); 6710 6711 format %{ "movq $dst, $src\t# long->ptr" %} 6712 ins_encode %{ 6713 if ($dst$$reg != $src$$reg) { 6714 __ movptr($dst$$Register, $src$$Register); 6715 } 6716 %} 6717 ins_pipe(ialu_reg_reg); // XXX 6718%} 6719 6720instruct castP2X(rRegL dst, rRegP src) 6721%{ 6722 match(Set dst (CastP2X src)); 6723 6724 format %{ "movq $dst, $src\t# ptr -> long" %} 6725 ins_encode %{ 6726 if ($dst$$reg != $src$$reg) { 6727 __ movptr($dst$$Register, $src$$Register); 6728 } 6729 %} 6730 ins_pipe(ialu_reg_reg); // XXX 6731%} 6732 6733// Convert oop into int for vectors alignment masking 6734instruct convP2I(rRegI dst, rRegP src) 6735%{ 6736 match(Set dst (ConvL2I (CastP2X src))); 6737 6738 format %{ "movl $dst, $src\t# ptr -> int" %} 6739 ins_encode %{ 6740 __ movl($dst$$Register, $src$$Register); 6741 %} 6742 ins_pipe(ialu_reg_reg); // XXX 6743%} 6744 6745// Convert compressed oop into int for vectors alignment masking 6746// in case of 32bit oops (heap < 4Gb). 6747instruct convN2I(rRegI dst, rRegN src) 6748%{ 6749 predicate(Universe::narrow_oop_shift() == 0); 6750 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6751 6752 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6753 ins_encode %{ 6754 __ movl($dst$$Register, $src$$Register); 6755 %} 6756 ins_pipe(ialu_reg_reg); // XXX 6757%} 6758 6759// Convert oop pointer into compressed form 6760instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6761 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6762 match(Set dst (EncodeP src)); 6763 effect(KILL cr); 6764 format %{ "encode_heap_oop $dst,$src" %} 6765 ins_encode %{ 6766 Register s = $src$$Register; 6767 Register d = $dst$$Register; 6768 if (s != d) { 6769 __ movq(d, s); 6770 } 6771 __ encode_heap_oop(d); 6772 %} 6773 ins_pipe(ialu_reg_long); 6774%} 6775 6776instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6777 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6778 match(Set dst (EncodeP src)); 6779 effect(KILL cr); 6780 format %{ "encode_heap_oop_not_null $dst,$src" %} 6781 ins_encode %{ 6782 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6783 %} 6784 ins_pipe(ialu_reg_long); 6785%} 6786 6787instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6788 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6789 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6790 match(Set dst (DecodeN src)); 6791 effect(KILL cr); 6792 format %{ "decode_heap_oop $dst,$src" %} 6793 ins_encode %{ 6794 Register s = $src$$Register; 6795 Register d = $dst$$Register; 6796 if (s != d) { 6797 __ movq(d, s); 6798 } 6799 __ decode_heap_oop(d); 6800 %} 6801 ins_pipe(ialu_reg_long); 6802%} 6803 6804instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6805 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6806 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6807 match(Set dst (DecodeN src)); 6808 effect(KILL cr); 6809 format %{ "decode_heap_oop_not_null $dst,$src" %} 6810 ins_encode %{ 6811 Register s = $src$$Register; 6812 Register d = $dst$$Register; 6813 if (s != d) { 6814 __ decode_heap_oop_not_null(d, s); 6815 } else { 6816 __ decode_heap_oop_not_null(d); 6817 } 6818 %} 6819 ins_pipe(ialu_reg_long); 6820%} 6821 6822instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6823 match(Set dst (EncodePKlass src)); 6824 effect(KILL cr); 6825 format %{ "encode_klass_not_null $dst,$src" %} 6826 ins_encode %{ 6827 __ encode_klass_not_null($dst$$Register, $src$$Register); 6828 %} 6829 ins_pipe(ialu_reg_long); 6830%} 6831 6832instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6833 match(Set dst (DecodeNKlass src)); 6834 effect(KILL cr); 6835 format %{ "decode_klass_not_null $dst,$src" %} 6836 ins_encode %{ 6837 Register s = $src$$Register; 6838 Register d = $dst$$Register; 6839 if (s != d) { 6840 __ decode_klass_not_null(d, s); 6841 } else { 6842 __ decode_klass_not_null(d); 6843 } 6844 %} 6845 ins_pipe(ialu_reg_long); 6846%} 6847 6848 6849//----------Conditional Move--------------------------------------------------- 6850// Jump 6851// dummy instruction for generating temp registers 6852instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6853 match(Jump (LShiftL switch_val shift)); 6854 ins_cost(350); 6855 predicate(false); 6856 effect(TEMP dest); 6857 6858 format %{ "leaq $dest, [$constantaddress]\n\t" 6859 "jmp [$dest + $switch_val << $shift]\n\t" %} 6860 ins_encode %{ 6861 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6862 // to do that and the compiler is using that register as one it can allocate. 6863 // So we build it all by hand. 6864 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6865 // ArrayAddress dispatch(table, index); 6866 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6867 __ lea($dest$$Register, $constantaddress); 6868 __ jmp(dispatch); 6869 %} 6870 ins_pipe(pipe_jmp); 6871%} 6872 6873instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6874 match(Jump (AddL (LShiftL switch_val shift) offset)); 6875 ins_cost(350); 6876 effect(TEMP dest); 6877 6878 format %{ "leaq $dest, [$constantaddress]\n\t" 6879 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6880 ins_encode %{ 6881 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6882 // to do that and the compiler is using that register as one it can allocate. 6883 // So we build it all by hand. 6884 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6885 // ArrayAddress dispatch(table, index); 6886 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6887 __ lea($dest$$Register, $constantaddress); 6888 __ jmp(dispatch); 6889 %} 6890 ins_pipe(pipe_jmp); 6891%} 6892 6893instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6894 match(Jump switch_val); 6895 ins_cost(350); 6896 effect(TEMP dest); 6897 6898 format %{ "leaq $dest, [$constantaddress]\n\t" 6899 "jmp [$dest + $switch_val]\n\t" %} 6900 ins_encode %{ 6901 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6902 // to do that and the compiler is using that register as one it can allocate. 6903 // So we build it all by hand. 6904 // Address index(noreg, switch_reg, Address::times_1); 6905 // ArrayAddress dispatch(table, index); 6906 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6907 __ lea($dest$$Register, $constantaddress); 6908 __ jmp(dispatch); 6909 %} 6910 ins_pipe(pipe_jmp); 6911%} 6912 6913// Conditional move 6914instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6915%{ 6916 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6917 6918 ins_cost(200); // XXX 6919 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6920 opcode(0x0F, 0x40); 6921 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6922 ins_pipe(pipe_cmov_reg); 6923%} 6924 6925instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6926 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6927 6928 ins_cost(200); // XXX 6929 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6930 opcode(0x0F, 0x40); 6931 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6932 ins_pipe(pipe_cmov_reg); 6933%} 6934 6935instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6936 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6937 ins_cost(200); 6938 expand %{ 6939 cmovI_regU(cop, cr, dst, src); 6940 %} 6941%} 6942 6943// Conditional move 6944instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6945 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6946 6947 ins_cost(250); // XXX 6948 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6949 opcode(0x0F, 0x40); 6950 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6951 ins_pipe(pipe_cmov_mem); 6952%} 6953 6954// Conditional move 6955instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6956%{ 6957 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6958 6959 ins_cost(250); // XXX 6960 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6961 opcode(0x0F, 0x40); 6962 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6963 ins_pipe(pipe_cmov_mem); 6964%} 6965 6966instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6967 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6968 ins_cost(250); 6969 expand %{ 6970 cmovI_memU(cop, cr, dst, src); 6971 %} 6972%} 6973 6974// Conditional move 6975instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6976%{ 6977 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6978 6979 ins_cost(200); // XXX 6980 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6981 opcode(0x0F, 0x40); 6982 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6983 ins_pipe(pipe_cmov_reg); 6984%} 6985 6986// Conditional move 6987instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6988%{ 6989 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6990 6991 ins_cost(200); // XXX 6992 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6993 opcode(0x0F, 0x40); 6994 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6995 ins_pipe(pipe_cmov_reg); 6996%} 6997 6998instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6999 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7000 ins_cost(200); 7001 expand %{ 7002 cmovN_regU(cop, cr, dst, src); 7003 %} 7004%} 7005 7006// Conditional move 7007instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7008%{ 7009 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7010 7011 ins_cost(200); // XXX 7012 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 7013 opcode(0x0F, 0x40); 7014 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7015 ins_pipe(pipe_cmov_reg); // XXX 7016%} 7017 7018// Conditional move 7019instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 7020%{ 7021 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7022 7023 ins_cost(200); // XXX 7024 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7025 opcode(0x0F, 0x40); 7026 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7027 ins_pipe(pipe_cmov_reg); // XXX 7028%} 7029 7030instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 7031 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7032 ins_cost(200); 7033 expand %{ 7034 cmovP_regU(cop, cr, dst, src); 7035 %} 7036%} 7037 7038// DISABLED: Requires the ADLC to emit a bottom_type call that 7039// correctly meets the two pointer arguments; one is an incoming 7040// register but the other is a memory operand. ALSO appears to 7041// be buggy with implicit null checks. 7042// 7043//// Conditional move 7044//instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7045//%{ 7046// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7047// ins_cost(250); 7048// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7049// opcode(0x0F,0x40); 7050// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7051// ins_pipe( pipe_cmov_mem ); 7052//%} 7053// 7054//// Conditional move 7055//instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7056//%{ 7057// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7058// ins_cost(250); 7059// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7060// opcode(0x0F,0x40); 7061// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7062// ins_pipe( pipe_cmov_mem ); 7063//%} 7064 7065instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7066%{ 7067 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7068 7069 ins_cost(200); // XXX 7070 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7071 opcode(0x0F, 0x40); 7072 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7073 ins_pipe(pipe_cmov_reg); // XXX 7074%} 7075 7076instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7077%{ 7078 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7079 7080 ins_cost(200); // XXX 7081 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7082 opcode(0x0F, 0x40); 7083 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7084 ins_pipe(pipe_cmov_mem); // XXX 7085%} 7086 7087instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7088%{ 7089 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7090 7091 ins_cost(200); // XXX 7092 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7093 opcode(0x0F, 0x40); 7094 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7095 ins_pipe(pipe_cmov_reg); // XXX 7096%} 7097 7098instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7099 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7100 ins_cost(200); 7101 expand %{ 7102 cmovL_regU(cop, cr, dst, src); 7103 %} 7104%} 7105 7106instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7107%{ 7108 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7109 7110 ins_cost(200); // XXX 7111 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7112 opcode(0x0F, 0x40); 7113 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7114 ins_pipe(pipe_cmov_mem); // XXX 7115%} 7116 7117instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7118 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7119 ins_cost(200); 7120 expand %{ 7121 cmovL_memU(cop, cr, dst, src); 7122 %} 7123%} 7124 7125instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7126%{ 7127 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7128 7129 ins_cost(200); // XXX 7130 format %{ "jn$cop skip\t# signed cmove float\n\t" 7131 "movss $dst, $src\n" 7132 "skip:" %} 7133 ins_encode %{ 7134 Label Lskip; 7135 // Invert sense of branch from sense of CMOV 7136 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7137 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7138 __ bind(Lskip); 7139 %} 7140 ins_pipe(pipe_slow); 7141%} 7142 7143// instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7144// %{ 7145// match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7146 7147// ins_cost(200); // XXX 7148// format %{ "jn$cop skip\t# signed cmove float\n\t" 7149// "movss $dst, $src\n" 7150// "skip:" %} 7151// ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7152// ins_pipe(pipe_slow); 7153// %} 7154 7155instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7156%{ 7157 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7158 7159 ins_cost(200); // XXX 7160 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7161 "movss $dst, $src\n" 7162 "skip:" %} 7163 ins_encode %{ 7164 Label Lskip; 7165 // Invert sense of branch from sense of CMOV 7166 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7167 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7168 __ bind(Lskip); 7169 %} 7170 ins_pipe(pipe_slow); 7171%} 7172 7173instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7174 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7175 ins_cost(200); 7176 expand %{ 7177 cmovF_regU(cop, cr, dst, src); 7178 %} 7179%} 7180 7181instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7182%{ 7183 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7184 7185 ins_cost(200); // XXX 7186 format %{ "jn$cop skip\t# signed cmove double\n\t" 7187 "movsd $dst, $src\n" 7188 "skip:" %} 7189 ins_encode %{ 7190 Label Lskip; 7191 // Invert sense of branch from sense of CMOV 7192 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7193 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7194 __ bind(Lskip); 7195 %} 7196 ins_pipe(pipe_slow); 7197%} 7198 7199instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7200%{ 7201 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7202 7203 ins_cost(200); // XXX 7204 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7205 "movsd $dst, $src\n" 7206 "skip:" %} 7207 ins_encode %{ 7208 Label Lskip; 7209 // Invert sense of branch from sense of CMOV 7210 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7211 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7212 __ bind(Lskip); 7213 %} 7214 ins_pipe(pipe_slow); 7215%} 7216 7217instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7218 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7219 ins_cost(200); 7220 expand %{ 7221 cmovD_regU(cop, cr, dst, src); 7222 %} 7223%} 7224 7225//----------Arithmetic Instructions-------------------------------------------- 7226//----------Addition Instructions---------------------------------------------- 7227 7228instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7229%{ 7230 match(Set dst (AddI dst src)); 7231 effect(KILL cr); 7232 7233 format %{ "addl $dst, $src\t# int" %} 7234 opcode(0x03); 7235 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7236 ins_pipe(ialu_reg_reg); 7237%} 7238 7239instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7240%{ 7241 match(Set dst (AddI dst src)); 7242 effect(KILL cr); 7243 7244 format %{ "addl $dst, $src\t# int" %} 7245 opcode(0x81, 0x00); /* /0 id */ 7246 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7247 ins_pipe( ialu_reg ); 7248%} 7249 7250instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7251%{ 7252 match(Set dst (AddI dst (LoadI src))); 7253 effect(KILL cr); 7254 7255 ins_cost(125); // XXX 7256 format %{ "addl $dst, $src\t# int" %} 7257 opcode(0x03); 7258 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7259 ins_pipe(ialu_reg_mem); 7260%} 7261 7262instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7263%{ 7264 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7265 effect(KILL cr); 7266 7267 ins_cost(150); // XXX 7268 format %{ "addl $dst, $src\t# int" %} 7269 opcode(0x01); /* Opcode 01 /r */ 7270 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7271 ins_pipe(ialu_mem_reg); 7272%} 7273 7274instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7275%{ 7276 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7277 effect(KILL cr); 7278 7279 ins_cost(125); // XXX 7280 format %{ "addl $dst, $src\t# int" %} 7281 opcode(0x81); /* Opcode 81 /0 id */ 7282 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7283 ins_pipe(ialu_mem_imm); 7284%} 7285 7286instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7287%{ 7288 predicate(UseIncDec); 7289 match(Set dst (AddI dst src)); 7290 effect(KILL cr); 7291 7292 format %{ "incl $dst\t# int" %} 7293 opcode(0xFF, 0x00); // FF /0 7294 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7295 ins_pipe(ialu_reg); 7296%} 7297 7298instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7299%{ 7300 predicate(UseIncDec); 7301 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7302 effect(KILL cr); 7303 7304 ins_cost(125); // XXX 7305 format %{ "incl $dst\t# int" %} 7306 opcode(0xFF); /* Opcode FF /0 */ 7307 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7308 ins_pipe(ialu_mem_imm); 7309%} 7310 7311// XXX why does that use AddI 7312instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7313%{ 7314 predicate(UseIncDec); 7315 match(Set dst (AddI dst src)); 7316 effect(KILL cr); 7317 7318 format %{ "decl $dst\t# int" %} 7319 opcode(0xFF, 0x01); // FF /1 7320 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7321 ins_pipe(ialu_reg); 7322%} 7323 7324// XXX why does that use AddI 7325instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7326%{ 7327 predicate(UseIncDec); 7328 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7329 effect(KILL cr); 7330 7331 ins_cost(125); // XXX 7332 format %{ "decl $dst\t# int" %} 7333 opcode(0xFF); /* Opcode FF /1 */ 7334 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7335 ins_pipe(ialu_mem_imm); 7336%} 7337 7338instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7339%{ 7340 match(Set dst (AddI src0 src1)); 7341 7342 ins_cost(110); 7343 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7344 opcode(0x8D); /* 0x8D /r */ 7345 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7346 ins_pipe(ialu_reg_reg); 7347%} 7348 7349instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7350%{ 7351 match(Set dst (AddL dst src)); 7352 effect(KILL cr); 7353 7354 format %{ "addq $dst, $src\t# long" %} 7355 opcode(0x03); 7356 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7357 ins_pipe(ialu_reg_reg); 7358%} 7359 7360instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7361%{ 7362 match(Set dst (AddL dst src)); 7363 effect(KILL cr); 7364 7365 format %{ "addq $dst, $src\t# long" %} 7366 opcode(0x81, 0x00); /* /0 id */ 7367 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7368 ins_pipe( ialu_reg ); 7369%} 7370 7371instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7372%{ 7373 match(Set dst (AddL dst (LoadL src))); 7374 effect(KILL cr); 7375 7376 ins_cost(125); // XXX 7377 format %{ "addq $dst, $src\t# long" %} 7378 opcode(0x03); 7379 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7380 ins_pipe(ialu_reg_mem); 7381%} 7382 7383instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7384%{ 7385 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7386 effect(KILL cr); 7387 7388 ins_cost(150); // XXX 7389 format %{ "addq $dst, $src\t# long" %} 7390 opcode(0x01); /* Opcode 01 /r */ 7391 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7392 ins_pipe(ialu_mem_reg); 7393%} 7394 7395instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7396%{ 7397 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7398 effect(KILL cr); 7399 7400 ins_cost(125); // XXX 7401 format %{ "addq $dst, $src\t# long" %} 7402 opcode(0x81); /* Opcode 81 /0 id */ 7403 ins_encode(REX_mem_wide(dst), 7404 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7405 ins_pipe(ialu_mem_imm); 7406%} 7407 7408instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7409%{ 7410 predicate(UseIncDec); 7411 match(Set dst (AddL dst src)); 7412 effect(KILL cr); 7413 7414 format %{ "incq $dst\t# long" %} 7415 opcode(0xFF, 0x00); // FF /0 7416 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7417 ins_pipe(ialu_reg); 7418%} 7419 7420instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7421%{ 7422 predicate(UseIncDec); 7423 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7424 effect(KILL cr); 7425 7426 ins_cost(125); // XXX 7427 format %{ "incq $dst\t# long" %} 7428 opcode(0xFF); /* Opcode FF /0 */ 7429 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7430 ins_pipe(ialu_mem_imm); 7431%} 7432 7433// XXX why does that use AddL 7434instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7435%{ 7436 predicate(UseIncDec); 7437 match(Set dst (AddL dst src)); 7438 effect(KILL cr); 7439 7440 format %{ "decq $dst\t# long" %} 7441 opcode(0xFF, 0x01); // FF /1 7442 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7443 ins_pipe(ialu_reg); 7444%} 7445 7446// XXX why does that use AddL 7447instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7448%{ 7449 predicate(UseIncDec); 7450 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7451 effect(KILL cr); 7452 7453 ins_cost(125); // XXX 7454 format %{ "decq $dst\t# long" %} 7455 opcode(0xFF); /* Opcode FF /1 */ 7456 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7457 ins_pipe(ialu_mem_imm); 7458%} 7459 7460instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7461%{ 7462 match(Set dst (AddL src0 src1)); 7463 7464 ins_cost(110); 7465 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7466 opcode(0x8D); /* 0x8D /r */ 7467 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7468 ins_pipe(ialu_reg_reg); 7469%} 7470 7471instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7472%{ 7473 match(Set dst (AddP dst src)); 7474 effect(KILL cr); 7475 7476 format %{ "addq $dst, $src\t# ptr" %} 7477 opcode(0x03); 7478 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7479 ins_pipe(ialu_reg_reg); 7480%} 7481 7482instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7483%{ 7484 match(Set dst (AddP dst src)); 7485 effect(KILL cr); 7486 7487 format %{ "addq $dst, $src\t# ptr" %} 7488 opcode(0x81, 0x00); /* /0 id */ 7489 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7490 ins_pipe( ialu_reg ); 7491%} 7492 7493// XXX addP mem ops ???? 7494 7495instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7496%{ 7497 match(Set dst (AddP src0 src1)); 7498 7499 ins_cost(110); 7500 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7501 opcode(0x8D); /* 0x8D /r */ 7502 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7503 ins_pipe(ialu_reg_reg); 7504%} 7505 7506instruct checkCastPP(rRegP dst) 7507%{ 7508 match(Set dst (CheckCastPP dst)); 7509 7510 size(0); 7511 format %{ "# checkcastPP of $dst" %} 7512 ins_encode(/* empty encoding */); 7513 ins_pipe(empty); 7514%} 7515 7516instruct castPP(rRegP dst) 7517%{ 7518 match(Set dst (CastPP dst)); 7519 7520 size(0); 7521 format %{ "# castPP of $dst" %} 7522 ins_encode(/* empty encoding */); 7523 ins_pipe(empty); 7524%} 7525 7526instruct castII(rRegI dst) 7527%{ 7528 match(Set dst (CastII dst)); 7529 7530 size(0); 7531 format %{ "# castII of $dst" %} 7532 ins_encode(/* empty encoding */); 7533 ins_cost(0); 7534 ins_pipe(empty); 7535%} 7536 7537// LoadP-locked same as a regular LoadP when used with compare-swap 7538instruct loadPLocked(rRegP dst, memory mem) 7539%{ 7540 match(Set dst (LoadPLocked mem)); 7541 7542 ins_cost(125); // XXX 7543 format %{ "movq $dst, $mem\t# ptr locked" %} 7544 opcode(0x8B); 7545 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7546 ins_pipe(ialu_reg_mem); // XXX 7547%} 7548 7549// Conditional-store of the updated heap-top. 7550// Used during allocation of the shared heap. 7551// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7552 7553instruct storePConditional(memory heap_top_ptr, 7554 rax_RegP oldval, rRegP newval, 7555 rFlagsReg cr) 7556%{ 7557 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7558 7559 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7560 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7561 opcode(0x0F, 0xB1); 7562 ins_encode(lock_prefix, 7563 REX_reg_mem_wide(newval, heap_top_ptr), 7564 OpcP, OpcS, 7565 reg_mem(newval, heap_top_ptr)); 7566 ins_pipe(pipe_cmpxchg); 7567%} 7568 7569// Conditional-store of an int value. 7570// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7571instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7572%{ 7573 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7574 effect(KILL oldval); 7575 7576 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7577 opcode(0x0F, 0xB1); 7578 ins_encode(lock_prefix, 7579 REX_reg_mem(newval, mem), 7580 OpcP, OpcS, 7581 reg_mem(newval, mem)); 7582 ins_pipe(pipe_cmpxchg); 7583%} 7584 7585// Conditional-store of a long value. 7586// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7587instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7588%{ 7589 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7590 effect(KILL oldval); 7591 7592 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7593 opcode(0x0F, 0xB1); 7594 ins_encode(lock_prefix, 7595 REX_reg_mem_wide(newval, mem), 7596 OpcP, OpcS, 7597 reg_mem(newval, mem)); 7598 ins_pipe(pipe_cmpxchg); 7599%} 7600 7601 7602// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7603instruct compareAndSwapP(rRegI res, 7604 memory mem_ptr, 7605 rax_RegP oldval, rRegP newval, 7606 rFlagsReg cr) 7607%{ 7608 predicate(VM_Version::supports_cx8()); 7609 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7610 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7611 effect(KILL cr, KILL oldval); 7612 7613 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7614 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7615 "sete $res\n\t" 7616 "movzbl $res, $res" %} 7617 opcode(0x0F, 0xB1); 7618 ins_encode(lock_prefix, 7619 REX_reg_mem_wide(newval, mem_ptr), 7620 OpcP, OpcS, 7621 reg_mem(newval, mem_ptr), 7622 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7623 REX_reg_breg(res, res), // movzbl 7624 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7625 ins_pipe( pipe_cmpxchg ); 7626%} 7627 7628instruct compareAndSwapL(rRegI res, 7629 memory mem_ptr, 7630 rax_RegL oldval, rRegL newval, 7631 rFlagsReg cr) 7632%{ 7633 predicate(VM_Version::supports_cx8()); 7634 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7635 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7636 effect(KILL cr, KILL oldval); 7637 7638 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7639 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7640 "sete $res\n\t" 7641 "movzbl $res, $res" %} 7642 opcode(0x0F, 0xB1); 7643 ins_encode(lock_prefix, 7644 REX_reg_mem_wide(newval, mem_ptr), 7645 OpcP, OpcS, 7646 reg_mem(newval, mem_ptr), 7647 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7648 REX_reg_breg(res, res), // movzbl 7649 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7650 ins_pipe( pipe_cmpxchg ); 7651%} 7652 7653instruct compareAndSwapI(rRegI res, 7654 memory mem_ptr, 7655 rax_RegI oldval, rRegI newval, 7656 rFlagsReg cr) 7657%{ 7658 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7659 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7660 effect(KILL cr, KILL oldval); 7661 7662 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7663 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7664 "sete $res\n\t" 7665 "movzbl $res, $res" %} 7666 opcode(0x0F, 0xB1); 7667 ins_encode(lock_prefix, 7668 REX_reg_mem(newval, mem_ptr), 7669 OpcP, OpcS, 7670 reg_mem(newval, mem_ptr), 7671 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7672 REX_reg_breg(res, res), // movzbl 7673 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7674 ins_pipe( pipe_cmpxchg ); 7675%} 7676 7677instruct compareAndSwapB(rRegI res, 7678 memory mem_ptr, 7679 rax_RegI oldval, rRegI newval, 7680 rFlagsReg cr) 7681%{ 7682 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7683 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7684 effect(KILL cr, KILL oldval); 7685 7686 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7687 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7688 "sete $res\n\t" 7689 "movzbl $res, $res" %} 7690 opcode(0x0F, 0xB0); 7691 ins_encode(lock_prefix, 7692 REX_breg_mem(newval, mem_ptr), 7693 OpcP, OpcS, 7694 reg_mem(newval, mem_ptr), 7695 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7696 REX_reg_breg(res, res), // movzbl 7697 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7698 ins_pipe( pipe_cmpxchg ); 7699%} 7700 7701instruct compareAndSwapS(rRegI res, 7702 memory mem_ptr, 7703 rax_RegI oldval, rRegI newval, 7704 rFlagsReg cr) 7705%{ 7706 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7707 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7708 effect(KILL cr, KILL oldval); 7709 7710 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7711 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7712 "sete $res\n\t" 7713 "movzbl $res, $res" %} 7714 opcode(0x0F, 0xB1); 7715 ins_encode(lock_prefix, 7716 SizePrefix, 7717 REX_reg_mem(newval, mem_ptr), 7718 OpcP, OpcS, 7719 reg_mem(newval, mem_ptr), 7720 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7721 REX_reg_breg(res, res), // movzbl 7722 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7723 ins_pipe( pipe_cmpxchg ); 7724%} 7725 7726instruct compareAndSwapN(rRegI res, 7727 memory mem_ptr, 7728 rax_RegN oldval, rRegN newval, 7729 rFlagsReg cr) %{ 7730 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7731 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7732 effect(KILL cr, KILL oldval); 7733 7734 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7735 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7736 "sete $res\n\t" 7737 "movzbl $res, $res" %} 7738 opcode(0x0F, 0xB1); 7739 ins_encode(lock_prefix, 7740 REX_reg_mem(newval, mem_ptr), 7741 OpcP, OpcS, 7742 reg_mem(newval, mem_ptr), 7743 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7744 REX_reg_breg(res, res), // movzbl 7745 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7746 ins_pipe( pipe_cmpxchg ); 7747%} 7748 7749instruct compareAndExchangeB( 7750 memory mem_ptr, 7751 rax_RegI oldval, rRegI newval, 7752 rFlagsReg cr) 7753%{ 7754 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7755 effect(KILL cr); 7756 7757 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7758 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7759 opcode(0x0F, 0xB0); 7760 ins_encode(lock_prefix, 7761 REX_breg_mem(newval, mem_ptr), 7762 OpcP, OpcS, 7763 reg_mem(newval, mem_ptr) // lock cmpxchg 7764 ); 7765 ins_pipe( pipe_cmpxchg ); 7766%} 7767 7768instruct compareAndExchangeS( 7769 memory mem_ptr, 7770 rax_RegI oldval, rRegI newval, 7771 rFlagsReg cr) 7772%{ 7773 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7774 effect(KILL cr); 7775 7776 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7777 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7778 opcode(0x0F, 0xB1); 7779 ins_encode(lock_prefix, 7780 SizePrefix, 7781 REX_reg_mem(newval, mem_ptr), 7782 OpcP, OpcS, 7783 reg_mem(newval, mem_ptr) // lock cmpxchg 7784 ); 7785 ins_pipe( pipe_cmpxchg ); 7786%} 7787 7788instruct compareAndExchangeI( 7789 memory mem_ptr, 7790 rax_RegI oldval, rRegI newval, 7791 rFlagsReg cr) 7792%{ 7793 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7794 effect(KILL cr); 7795 7796 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7797 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7798 opcode(0x0F, 0xB1); 7799 ins_encode(lock_prefix, 7800 REX_reg_mem(newval, mem_ptr), 7801 OpcP, OpcS, 7802 reg_mem(newval, mem_ptr) // lock cmpxchg 7803 ); 7804 ins_pipe( pipe_cmpxchg ); 7805%} 7806 7807instruct compareAndExchangeL( 7808 memory mem_ptr, 7809 rax_RegL oldval, rRegL newval, 7810 rFlagsReg cr) 7811%{ 7812 predicate(VM_Version::supports_cx8()); 7813 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7814 effect(KILL cr); 7815 7816 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7817 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7818 opcode(0x0F, 0xB1); 7819 ins_encode(lock_prefix, 7820 REX_reg_mem_wide(newval, mem_ptr), 7821 OpcP, OpcS, 7822 reg_mem(newval, mem_ptr) // lock cmpxchg 7823 ); 7824 ins_pipe( pipe_cmpxchg ); 7825%} 7826 7827instruct compareAndExchangeN( 7828 memory mem_ptr, 7829 rax_RegN oldval, rRegN newval, 7830 rFlagsReg cr) %{ 7831 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7832 effect(KILL cr); 7833 7834 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7835 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7836 opcode(0x0F, 0xB1); 7837 ins_encode(lock_prefix, 7838 REX_reg_mem(newval, mem_ptr), 7839 OpcP, OpcS, 7840 reg_mem(newval, mem_ptr) // lock cmpxchg 7841 ); 7842 ins_pipe( pipe_cmpxchg ); 7843%} 7844 7845instruct compareAndExchangeP( 7846 memory mem_ptr, 7847 rax_RegP oldval, rRegP newval, 7848 rFlagsReg cr) 7849%{ 7850 predicate(VM_Version::supports_cx8()); 7851 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7852 effect(KILL cr); 7853 7854 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7855 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7856 opcode(0x0F, 0xB1); 7857 ins_encode(lock_prefix, 7858 REX_reg_mem_wide(newval, mem_ptr), 7859 OpcP, OpcS, 7860 reg_mem(newval, mem_ptr) // lock cmpxchg 7861 ); 7862 ins_pipe( pipe_cmpxchg ); 7863%} 7864 7865instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7866 predicate(n->as_LoadStore()->result_not_used()); 7867 match(Set dummy (GetAndAddB mem add)); 7868 effect(KILL cr); 7869 format %{ "ADDB [$mem],$add" %} 7870 ins_encode %{ 7871 __ lock(); 7872 __ addb($mem$$Address, $add$$constant); 7873 %} 7874 ins_pipe( pipe_cmpxchg ); 7875%} 7876 7877instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 7878 match(Set newval (GetAndAddB mem newval)); 7879 effect(KILL cr); 7880 format %{ "XADDB [$mem],$newval" %} 7881 ins_encode %{ 7882 __ lock(); 7883 __ xaddb($mem$$Address, $newval$$Register); 7884 %} 7885 ins_pipe( pipe_cmpxchg ); 7886%} 7887 7888instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7889 predicate(n->as_LoadStore()->result_not_used()); 7890 match(Set dummy (GetAndAddS mem add)); 7891 effect(KILL cr); 7892 format %{ "ADDW [$mem],$add" %} 7893 ins_encode %{ 7894 __ lock(); 7895 __ addw($mem$$Address, $add$$constant); 7896 %} 7897 ins_pipe( pipe_cmpxchg ); 7898%} 7899 7900instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 7901 match(Set newval (GetAndAddS mem newval)); 7902 effect(KILL cr); 7903 format %{ "XADDW [$mem],$newval" %} 7904 ins_encode %{ 7905 __ lock(); 7906 __ xaddw($mem$$Address, $newval$$Register); 7907 %} 7908 ins_pipe( pipe_cmpxchg ); 7909%} 7910 7911instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7912 predicate(n->as_LoadStore()->result_not_used()); 7913 match(Set dummy (GetAndAddI mem add)); 7914 effect(KILL cr); 7915 format %{ "ADDL [$mem],$add" %} 7916 ins_encode %{ 7917 __ lock(); 7918 __ addl($mem$$Address, $add$$constant); 7919 %} 7920 ins_pipe( pipe_cmpxchg ); 7921%} 7922 7923instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7924 match(Set newval (GetAndAddI mem newval)); 7925 effect(KILL cr); 7926 format %{ "XADDL [$mem],$newval" %} 7927 ins_encode %{ 7928 __ lock(); 7929 __ xaddl($mem$$Address, $newval$$Register); 7930 %} 7931 ins_pipe( pipe_cmpxchg ); 7932%} 7933 7934instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7935 predicate(n->as_LoadStore()->result_not_used()); 7936 match(Set dummy (GetAndAddL mem add)); 7937 effect(KILL cr); 7938 format %{ "ADDQ [$mem],$add" %} 7939 ins_encode %{ 7940 __ lock(); 7941 __ addq($mem$$Address, $add$$constant); 7942 %} 7943 ins_pipe( pipe_cmpxchg ); 7944%} 7945 7946instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7947 match(Set newval (GetAndAddL mem newval)); 7948 effect(KILL cr); 7949 format %{ "XADDQ [$mem],$newval" %} 7950 ins_encode %{ 7951 __ lock(); 7952 __ xaddq($mem$$Address, $newval$$Register); 7953 %} 7954 ins_pipe( pipe_cmpxchg ); 7955%} 7956 7957instruct xchgB( memory mem, rRegI newval) %{ 7958 match(Set newval (GetAndSetB mem newval)); 7959 format %{ "XCHGB $newval,[$mem]" %} 7960 ins_encode %{ 7961 __ xchgb($newval$$Register, $mem$$Address); 7962 %} 7963 ins_pipe( pipe_cmpxchg ); 7964%} 7965 7966instruct xchgS( memory mem, rRegI newval) %{ 7967 match(Set newval (GetAndSetS mem newval)); 7968 format %{ "XCHGW $newval,[$mem]" %} 7969 ins_encode %{ 7970 __ xchgw($newval$$Register, $mem$$Address); 7971 %} 7972 ins_pipe( pipe_cmpxchg ); 7973%} 7974 7975instruct xchgI( memory mem, rRegI newval) %{ 7976 match(Set newval (GetAndSetI mem newval)); 7977 format %{ "XCHGL $newval,[$mem]" %} 7978 ins_encode %{ 7979 __ xchgl($newval$$Register, $mem$$Address); 7980 %} 7981 ins_pipe( pipe_cmpxchg ); 7982%} 7983 7984instruct xchgL( memory mem, rRegL newval) %{ 7985 match(Set newval (GetAndSetL mem newval)); 7986 format %{ "XCHGL $newval,[$mem]" %} 7987 ins_encode %{ 7988 __ xchgq($newval$$Register, $mem$$Address); 7989 %} 7990 ins_pipe( pipe_cmpxchg ); 7991%} 7992 7993instruct xchgP( memory mem, rRegP newval) %{ 7994 match(Set newval (GetAndSetP mem newval)); 7995 format %{ "XCHGQ $newval,[$mem]" %} 7996 ins_encode %{ 7997 __ xchgq($newval$$Register, $mem$$Address); 7998 %} 7999 ins_pipe( pipe_cmpxchg ); 8000%} 8001 8002instruct xchgN( memory mem, rRegN newval) %{ 8003 match(Set newval (GetAndSetN mem newval)); 8004 format %{ "XCHGL $newval,$mem]" %} 8005 ins_encode %{ 8006 __ xchgl($newval$$Register, $mem$$Address); 8007 %} 8008 ins_pipe( pipe_cmpxchg ); 8009%} 8010 8011//----------Subtraction Instructions------------------------------------------- 8012 8013// Integer Subtraction Instructions 8014instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8015%{ 8016 match(Set dst (SubI dst src)); 8017 effect(KILL cr); 8018 8019 format %{ "subl $dst, $src\t# int" %} 8020 opcode(0x2B); 8021 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8022 ins_pipe(ialu_reg_reg); 8023%} 8024 8025instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8026%{ 8027 match(Set dst (SubI dst src)); 8028 effect(KILL cr); 8029 8030 format %{ "subl $dst, $src\t# int" %} 8031 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8032 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8033 ins_pipe(ialu_reg); 8034%} 8035 8036instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8037%{ 8038 match(Set dst (SubI dst (LoadI src))); 8039 effect(KILL cr); 8040 8041 ins_cost(125); 8042 format %{ "subl $dst, $src\t# int" %} 8043 opcode(0x2B); 8044 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8045 ins_pipe(ialu_reg_mem); 8046%} 8047 8048instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8049%{ 8050 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8051 effect(KILL cr); 8052 8053 ins_cost(150); 8054 format %{ "subl $dst, $src\t# int" %} 8055 opcode(0x29); /* Opcode 29 /r */ 8056 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8057 ins_pipe(ialu_mem_reg); 8058%} 8059 8060instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8061%{ 8062 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8063 effect(KILL cr); 8064 8065 ins_cost(125); // XXX 8066 format %{ "subl $dst, $src\t# int" %} 8067 opcode(0x81); /* Opcode 81 /5 id */ 8068 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8069 ins_pipe(ialu_mem_imm); 8070%} 8071 8072instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8073%{ 8074 match(Set dst (SubL dst src)); 8075 effect(KILL cr); 8076 8077 format %{ "subq $dst, $src\t# long" %} 8078 opcode(0x2B); 8079 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8080 ins_pipe(ialu_reg_reg); 8081%} 8082 8083instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8084%{ 8085 match(Set dst (SubL dst src)); 8086 effect(KILL cr); 8087 8088 format %{ "subq $dst, $src\t# long" %} 8089 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8090 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8091 ins_pipe(ialu_reg); 8092%} 8093 8094instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8095%{ 8096 match(Set dst (SubL dst (LoadL src))); 8097 effect(KILL cr); 8098 8099 ins_cost(125); 8100 format %{ "subq $dst, $src\t# long" %} 8101 opcode(0x2B); 8102 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8103 ins_pipe(ialu_reg_mem); 8104%} 8105 8106instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8107%{ 8108 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8109 effect(KILL cr); 8110 8111 ins_cost(150); 8112 format %{ "subq $dst, $src\t# long" %} 8113 opcode(0x29); /* Opcode 29 /r */ 8114 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8115 ins_pipe(ialu_mem_reg); 8116%} 8117 8118instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8119%{ 8120 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8121 effect(KILL cr); 8122 8123 ins_cost(125); // XXX 8124 format %{ "subq $dst, $src\t# long" %} 8125 opcode(0x81); /* Opcode 81 /5 id */ 8126 ins_encode(REX_mem_wide(dst), 8127 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8128 ins_pipe(ialu_mem_imm); 8129%} 8130 8131// Subtract from a pointer 8132// XXX hmpf??? 8133instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8134%{ 8135 match(Set dst (AddP dst (SubI zero src))); 8136 effect(KILL cr); 8137 8138 format %{ "subq $dst, $src\t# ptr - int" %} 8139 opcode(0x2B); 8140 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8141 ins_pipe(ialu_reg_reg); 8142%} 8143 8144instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8145%{ 8146 match(Set dst (SubI zero dst)); 8147 effect(KILL cr); 8148 8149 format %{ "negl $dst\t# int" %} 8150 opcode(0xF7, 0x03); // Opcode F7 /3 8151 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8152 ins_pipe(ialu_reg); 8153%} 8154 8155instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8156%{ 8157 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8158 effect(KILL cr); 8159 8160 format %{ "negl $dst\t# int" %} 8161 opcode(0xF7, 0x03); // Opcode F7 /3 8162 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8163 ins_pipe(ialu_reg); 8164%} 8165 8166instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8167%{ 8168 match(Set dst (SubL zero dst)); 8169 effect(KILL cr); 8170 8171 format %{ "negq $dst\t# long" %} 8172 opcode(0xF7, 0x03); // Opcode F7 /3 8173 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8174 ins_pipe(ialu_reg); 8175%} 8176 8177instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8178%{ 8179 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8180 effect(KILL cr); 8181 8182 format %{ "negq $dst\t# long" %} 8183 opcode(0xF7, 0x03); // Opcode F7 /3 8184 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8185 ins_pipe(ialu_reg); 8186%} 8187 8188//----------Multiplication/Division Instructions------------------------------- 8189// Integer Multiplication Instructions 8190// Multiply Register 8191 8192instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8193%{ 8194 match(Set dst (MulI dst src)); 8195 effect(KILL cr); 8196 8197 ins_cost(300); 8198 format %{ "imull $dst, $src\t# int" %} 8199 opcode(0x0F, 0xAF); 8200 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8201 ins_pipe(ialu_reg_reg_alu0); 8202%} 8203 8204instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8205%{ 8206 match(Set dst (MulI src imm)); 8207 effect(KILL cr); 8208 8209 ins_cost(300); 8210 format %{ "imull $dst, $src, $imm\t# int" %} 8211 opcode(0x69); /* 69 /r id */ 8212 ins_encode(REX_reg_reg(dst, src), 8213 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8214 ins_pipe(ialu_reg_reg_alu0); 8215%} 8216 8217instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8218%{ 8219 match(Set dst (MulI dst (LoadI src))); 8220 effect(KILL cr); 8221 8222 ins_cost(350); 8223 format %{ "imull $dst, $src\t# int" %} 8224 opcode(0x0F, 0xAF); 8225 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8226 ins_pipe(ialu_reg_mem_alu0); 8227%} 8228 8229instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8230%{ 8231 match(Set dst (MulI (LoadI src) imm)); 8232 effect(KILL cr); 8233 8234 ins_cost(300); 8235 format %{ "imull $dst, $src, $imm\t# int" %} 8236 opcode(0x69); /* 69 /r id */ 8237 ins_encode(REX_reg_mem(dst, src), 8238 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8239 ins_pipe(ialu_reg_mem_alu0); 8240%} 8241 8242instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8243%{ 8244 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8245 effect(KILL cr, KILL src2); 8246 8247 expand %{ mulI_rReg(dst, src1, cr); 8248 mulI_rReg(src2, src3, cr); 8249 addI_rReg(dst, src2, cr); %} 8250%} 8251 8252instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8253%{ 8254 match(Set dst (MulL dst src)); 8255 effect(KILL cr); 8256 8257 ins_cost(300); 8258 format %{ "imulq $dst, $src\t# long" %} 8259 opcode(0x0F, 0xAF); 8260 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8261 ins_pipe(ialu_reg_reg_alu0); 8262%} 8263 8264instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8265%{ 8266 match(Set dst (MulL src imm)); 8267 effect(KILL cr); 8268 8269 ins_cost(300); 8270 format %{ "imulq $dst, $src, $imm\t# long" %} 8271 opcode(0x69); /* 69 /r id */ 8272 ins_encode(REX_reg_reg_wide(dst, src), 8273 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8274 ins_pipe(ialu_reg_reg_alu0); 8275%} 8276 8277instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8278%{ 8279 match(Set dst (MulL dst (LoadL src))); 8280 effect(KILL cr); 8281 8282 ins_cost(350); 8283 format %{ "imulq $dst, $src\t# long" %} 8284 opcode(0x0F, 0xAF); 8285 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8286 ins_pipe(ialu_reg_mem_alu0); 8287%} 8288 8289instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8290%{ 8291 match(Set dst (MulL (LoadL src) imm)); 8292 effect(KILL cr); 8293 8294 ins_cost(300); 8295 format %{ "imulq $dst, $src, $imm\t# long" %} 8296 opcode(0x69); /* 69 /r id */ 8297 ins_encode(REX_reg_mem_wide(dst, src), 8298 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8299 ins_pipe(ialu_reg_mem_alu0); 8300%} 8301 8302instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8303%{ 8304 match(Set dst (MulHiL src rax)); 8305 effect(USE_KILL rax, KILL cr); 8306 8307 ins_cost(300); 8308 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8309 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8310 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8311 ins_pipe(ialu_reg_reg_alu0); 8312%} 8313 8314instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8315 rFlagsReg cr) 8316%{ 8317 match(Set rax (DivI rax div)); 8318 effect(KILL rdx, KILL cr); 8319 8320 ins_cost(30*100+10*100); // XXX 8321 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8322 "jne,s normal\n\t" 8323 "xorl rdx, rdx\n\t" 8324 "cmpl $div, -1\n\t" 8325 "je,s done\n" 8326 "normal: cdql\n\t" 8327 "idivl $div\n" 8328 "done:" %} 8329 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8330 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8331 ins_pipe(ialu_reg_reg_alu0); 8332%} 8333 8334instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8335 rFlagsReg cr) 8336%{ 8337 match(Set rax (DivL rax div)); 8338 effect(KILL rdx, KILL cr); 8339 8340 ins_cost(30*100+10*100); // XXX 8341 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8342 "cmpq rax, rdx\n\t" 8343 "jne,s normal\n\t" 8344 "xorl rdx, rdx\n\t" 8345 "cmpq $div, -1\n\t" 8346 "je,s done\n" 8347 "normal: cdqq\n\t" 8348 "idivq $div\n" 8349 "done:" %} 8350 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8351 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8352 ins_pipe(ialu_reg_reg_alu0); 8353%} 8354 8355// Integer DIVMOD with Register, both quotient and mod results 8356instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8357 rFlagsReg cr) 8358%{ 8359 match(DivModI rax div); 8360 effect(KILL cr); 8361 8362 ins_cost(30*100+10*100); // XXX 8363 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8364 "jne,s normal\n\t" 8365 "xorl rdx, rdx\n\t" 8366 "cmpl $div, -1\n\t" 8367 "je,s done\n" 8368 "normal: cdql\n\t" 8369 "idivl $div\n" 8370 "done:" %} 8371 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8372 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8373 ins_pipe(pipe_slow); 8374%} 8375 8376// Long DIVMOD with Register, both quotient and mod results 8377instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8378 rFlagsReg cr) 8379%{ 8380 match(DivModL rax div); 8381 effect(KILL cr); 8382 8383 ins_cost(30*100+10*100); // XXX 8384 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8385 "cmpq rax, rdx\n\t" 8386 "jne,s normal\n\t" 8387 "xorl rdx, rdx\n\t" 8388 "cmpq $div, -1\n\t" 8389 "je,s done\n" 8390 "normal: cdqq\n\t" 8391 "idivq $div\n" 8392 "done:" %} 8393 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8394 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8395 ins_pipe(pipe_slow); 8396%} 8397 8398//----------- DivL-By-Constant-Expansions-------------------------------------- 8399// DivI cases are handled by the compiler 8400 8401// Magic constant, reciprocal of 10 8402instruct loadConL_0x6666666666666667(rRegL dst) 8403%{ 8404 effect(DEF dst); 8405 8406 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8407 ins_encode(load_immL(dst, 0x6666666666666667)); 8408 ins_pipe(ialu_reg); 8409%} 8410 8411instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8412%{ 8413 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8414 8415 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8416 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8417 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8418 ins_pipe(ialu_reg_reg_alu0); 8419%} 8420 8421instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8422%{ 8423 effect(USE_DEF dst, KILL cr); 8424 8425 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8426 opcode(0xC1, 0x7); /* C1 /7 ib */ 8427 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8428 ins_pipe(ialu_reg); 8429%} 8430 8431instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8432%{ 8433 effect(USE_DEF dst, KILL cr); 8434 8435 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8436 opcode(0xC1, 0x7); /* C1 /7 ib */ 8437 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8438 ins_pipe(ialu_reg); 8439%} 8440 8441instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8442%{ 8443 match(Set dst (DivL src div)); 8444 8445 ins_cost((5+8)*100); 8446 expand %{ 8447 rax_RegL rax; // Killed temp 8448 rFlagsReg cr; // Killed 8449 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8450 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8451 sarL_rReg_63(src, cr); // sarq src, 63 8452 sarL_rReg_2(dst, cr); // sarq rdx, 2 8453 subL_rReg(dst, src, cr); // subl rdx, src 8454 %} 8455%} 8456 8457//----------------------------------------------------------------------------- 8458 8459instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8460 rFlagsReg cr) 8461%{ 8462 match(Set rdx (ModI rax div)); 8463 effect(KILL rax, KILL cr); 8464 8465 ins_cost(300); // XXX 8466 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8467 "jne,s normal\n\t" 8468 "xorl rdx, rdx\n\t" 8469 "cmpl $div, -1\n\t" 8470 "je,s done\n" 8471 "normal: cdql\n\t" 8472 "idivl $div\n" 8473 "done:" %} 8474 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8475 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8476 ins_pipe(ialu_reg_reg_alu0); 8477%} 8478 8479instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8480 rFlagsReg cr) 8481%{ 8482 match(Set rdx (ModL rax div)); 8483 effect(KILL rax, KILL cr); 8484 8485 ins_cost(300); // XXX 8486 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8487 "cmpq rax, rdx\n\t" 8488 "jne,s normal\n\t" 8489 "xorl rdx, rdx\n\t" 8490 "cmpq $div, -1\n\t" 8491 "je,s done\n" 8492 "normal: cdqq\n\t" 8493 "idivq $div\n" 8494 "done:" %} 8495 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8496 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8497 ins_pipe(ialu_reg_reg_alu0); 8498%} 8499 8500// Integer Shift Instructions 8501// Shift Left by one 8502instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8503%{ 8504 match(Set dst (LShiftI dst shift)); 8505 effect(KILL cr); 8506 8507 format %{ "sall $dst, $shift" %} 8508 opcode(0xD1, 0x4); /* D1 /4 */ 8509 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8510 ins_pipe(ialu_reg); 8511%} 8512 8513// Shift Left by one 8514instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8515%{ 8516 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8517 effect(KILL cr); 8518 8519 format %{ "sall $dst, $shift\t" %} 8520 opcode(0xD1, 0x4); /* D1 /4 */ 8521 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8522 ins_pipe(ialu_mem_imm); 8523%} 8524 8525// Shift Left by 8-bit immediate 8526instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8527%{ 8528 match(Set dst (LShiftI dst shift)); 8529 effect(KILL cr); 8530 8531 format %{ "sall $dst, $shift" %} 8532 opcode(0xC1, 0x4); /* C1 /4 ib */ 8533 ins_encode(reg_opc_imm(dst, shift)); 8534 ins_pipe(ialu_reg); 8535%} 8536 8537// Shift Left by 8-bit immediate 8538instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8539%{ 8540 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8541 effect(KILL cr); 8542 8543 format %{ "sall $dst, $shift" %} 8544 opcode(0xC1, 0x4); /* C1 /4 ib */ 8545 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8546 ins_pipe(ialu_mem_imm); 8547%} 8548 8549// Shift Left by variable 8550instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8551%{ 8552 match(Set dst (LShiftI dst shift)); 8553 effect(KILL cr); 8554 8555 format %{ "sall $dst, $shift" %} 8556 opcode(0xD3, 0x4); /* D3 /4 */ 8557 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8558 ins_pipe(ialu_reg_reg); 8559%} 8560 8561// Shift Left by variable 8562instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8563%{ 8564 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8565 effect(KILL cr); 8566 8567 format %{ "sall $dst, $shift" %} 8568 opcode(0xD3, 0x4); /* D3 /4 */ 8569 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8570 ins_pipe(ialu_mem_reg); 8571%} 8572 8573// Arithmetic shift right by one 8574instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8575%{ 8576 match(Set dst (RShiftI dst shift)); 8577 effect(KILL cr); 8578 8579 format %{ "sarl $dst, $shift" %} 8580 opcode(0xD1, 0x7); /* D1 /7 */ 8581 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8582 ins_pipe(ialu_reg); 8583%} 8584 8585// Arithmetic shift right by one 8586instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8587%{ 8588 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8589 effect(KILL cr); 8590 8591 format %{ "sarl $dst, $shift" %} 8592 opcode(0xD1, 0x7); /* D1 /7 */ 8593 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8594 ins_pipe(ialu_mem_imm); 8595%} 8596 8597// Arithmetic Shift Right by 8-bit immediate 8598instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8599%{ 8600 match(Set dst (RShiftI dst shift)); 8601 effect(KILL cr); 8602 8603 format %{ "sarl $dst, $shift" %} 8604 opcode(0xC1, 0x7); /* C1 /7 ib */ 8605 ins_encode(reg_opc_imm(dst, shift)); 8606 ins_pipe(ialu_mem_imm); 8607%} 8608 8609// Arithmetic Shift Right by 8-bit immediate 8610instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8611%{ 8612 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8613 effect(KILL cr); 8614 8615 format %{ "sarl $dst, $shift" %} 8616 opcode(0xC1, 0x7); /* C1 /7 ib */ 8617 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8618 ins_pipe(ialu_mem_imm); 8619%} 8620 8621// Arithmetic Shift Right by variable 8622instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8623%{ 8624 match(Set dst (RShiftI dst shift)); 8625 effect(KILL cr); 8626 8627 format %{ "sarl $dst, $shift" %} 8628 opcode(0xD3, 0x7); /* D3 /7 */ 8629 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8630 ins_pipe(ialu_reg_reg); 8631%} 8632 8633// Arithmetic Shift Right by variable 8634instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8635%{ 8636 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8637 effect(KILL cr); 8638 8639 format %{ "sarl $dst, $shift" %} 8640 opcode(0xD3, 0x7); /* D3 /7 */ 8641 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8642 ins_pipe(ialu_mem_reg); 8643%} 8644 8645// Logical shift right by one 8646instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8647%{ 8648 match(Set dst (URShiftI dst shift)); 8649 effect(KILL cr); 8650 8651 format %{ "shrl $dst, $shift" %} 8652 opcode(0xD1, 0x5); /* D1 /5 */ 8653 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8654 ins_pipe(ialu_reg); 8655%} 8656 8657// Logical shift right by one 8658instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8659%{ 8660 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8661 effect(KILL cr); 8662 8663 format %{ "shrl $dst, $shift" %} 8664 opcode(0xD1, 0x5); /* D1 /5 */ 8665 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8666 ins_pipe(ialu_mem_imm); 8667%} 8668 8669// Logical Shift Right by 8-bit immediate 8670instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8671%{ 8672 match(Set dst (URShiftI dst shift)); 8673 effect(KILL cr); 8674 8675 format %{ "shrl $dst, $shift" %} 8676 opcode(0xC1, 0x5); /* C1 /5 ib */ 8677 ins_encode(reg_opc_imm(dst, shift)); 8678 ins_pipe(ialu_reg); 8679%} 8680 8681// Logical Shift Right by 8-bit immediate 8682instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8683%{ 8684 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8685 effect(KILL cr); 8686 8687 format %{ "shrl $dst, $shift" %} 8688 opcode(0xC1, 0x5); /* C1 /5 ib */ 8689 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8690 ins_pipe(ialu_mem_imm); 8691%} 8692 8693// Logical Shift Right by variable 8694instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8695%{ 8696 match(Set dst (URShiftI dst shift)); 8697 effect(KILL cr); 8698 8699 format %{ "shrl $dst, $shift" %} 8700 opcode(0xD3, 0x5); /* D3 /5 */ 8701 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8702 ins_pipe(ialu_reg_reg); 8703%} 8704 8705// Logical Shift Right by variable 8706instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8707%{ 8708 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8709 effect(KILL cr); 8710 8711 format %{ "shrl $dst, $shift" %} 8712 opcode(0xD3, 0x5); /* D3 /5 */ 8713 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8714 ins_pipe(ialu_mem_reg); 8715%} 8716 8717// Long Shift Instructions 8718// Shift Left by one 8719instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8720%{ 8721 match(Set dst (LShiftL dst shift)); 8722 effect(KILL cr); 8723 8724 format %{ "salq $dst, $shift" %} 8725 opcode(0xD1, 0x4); /* D1 /4 */ 8726 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8727 ins_pipe(ialu_reg); 8728%} 8729 8730// Shift Left by one 8731instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8732%{ 8733 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8734 effect(KILL cr); 8735 8736 format %{ "salq $dst, $shift" %} 8737 opcode(0xD1, 0x4); /* D1 /4 */ 8738 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8739 ins_pipe(ialu_mem_imm); 8740%} 8741 8742// Shift Left by 8-bit immediate 8743instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8744%{ 8745 match(Set dst (LShiftL dst shift)); 8746 effect(KILL cr); 8747 8748 format %{ "salq $dst, $shift" %} 8749 opcode(0xC1, 0x4); /* C1 /4 ib */ 8750 ins_encode(reg_opc_imm_wide(dst, shift)); 8751 ins_pipe(ialu_reg); 8752%} 8753 8754// Shift Left by 8-bit immediate 8755instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8756%{ 8757 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8758 effect(KILL cr); 8759 8760 format %{ "salq $dst, $shift" %} 8761 opcode(0xC1, 0x4); /* C1 /4 ib */ 8762 ins_encode(REX_mem_wide(dst), OpcP, 8763 RM_opc_mem(secondary, dst), Con8or32(shift)); 8764 ins_pipe(ialu_mem_imm); 8765%} 8766 8767// Shift Left by variable 8768instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8769%{ 8770 match(Set dst (LShiftL dst shift)); 8771 effect(KILL cr); 8772 8773 format %{ "salq $dst, $shift" %} 8774 opcode(0xD3, 0x4); /* D3 /4 */ 8775 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8776 ins_pipe(ialu_reg_reg); 8777%} 8778 8779// Shift Left by variable 8780instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8781%{ 8782 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8783 effect(KILL cr); 8784 8785 format %{ "salq $dst, $shift" %} 8786 opcode(0xD3, 0x4); /* D3 /4 */ 8787 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8788 ins_pipe(ialu_mem_reg); 8789%} 8790 8791// Arithmetic shift right by one 8792instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8793%{ 8794 match(Set dst (RShiftL dst shift)); 8795 effect(KILL cr); 8796 8797 format %{ "sarq $dst, $shift" %} 8798 opcode(0xD1, 0x7); /* D1 /7 */ 8799 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8800 ins_pipe(ialu_reg); 8801%} 8802 8803// Arithmetic shift right by one 8804instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8805%{ 8806 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8807 effect(KILL cr); 8808 8809 format %{ "sarq $dst, $shift" %} 8810 opcode(0xD1, 0x7); /* D1 /7 */ 8811 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8812 ins_pipe(ialu_mem_imm); 8813%} 8814 8815// Arithmetic Shift Right by 8-bit immediate 8816instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8817%{ 8818 match(Set dst (RShiftL dst shift)); 8819 effect(KILL cr); 8820 8821 format %{ "sarq $dst, $shift" %} 8822 opcode(0xC1, 0x7); /* C1 /7 ib */ 8823 ins_encode(reg_opc_imm_wide(dst, shift)); 8824 ins_pipe(ialu_mem_imm); 8825%} 8826 8827// Arithmetic Shift Right by 8-bit immediate 8828instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8829%{ 8830 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8831 effect(KILL cr); 8832 8833 format %{ "sarq $dst, $shift" %} 8834 opcode(0xC1, 0x7); /* C1 /7 ib */ 8835 ins_encode(REX_mem_wide(dst), OpcP, 8836 RM_opc_mem(secondary, dst), Con8or32(shift)); 8837 ins_pipe(ialu_mem_imm); 8838%} 8839 8840// Arithmetic Shift Right by variable 8841instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8842%{ 8843 match(Set dst (RShiftL dst shift)); 8844 effect(KILL cr); 8845 8846 format %{ "sarq $dst, $shift" %} 8847 opcode(0xD3, 0x7); /* D3 /7 */ 8848 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8849 ins_pipe(ialu_reg_reg); 8850%} 8851 8852// Arithmetic Shift Right by variable 8853instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8854%{ 8855 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8856 effect(KILL cr); 8857 8858 format %{ "sarq $dst, $shift" %} 8859 opcode(0xD3, 0x7); /* D3 /7 */ 8860 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8861 ins_pipe(ialu_mem_reg); 8862%} 8863 8864// Logical shift right by one 8865instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8866%{ 8867 match(Set dst (URShiftL dst shift)); 8868 effect(KILL cr); 8869 8870 format %{ "shrq $dst, $shift" %} 8871 opcode(0xD1, 0x5); /* D1 /5 */ 8872 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8873 ins_pipe(ialu_reg); 8874%} 8875 8876// Logical shift right by one 8877instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8878%{ 8879 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8880 effect(KILL cr); 8881 8882 format %{ "shrq $dst, $shift" %} 8883 opcode(0xD1, 0x5); /* D1 /5 */ 8884 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8885 ins_pipe(ialu_mem_imm); 8886%} 8887 8888// Logical Shift Right by 8-bit immediate 8889instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8890%{ 8891 match(Set dst (URShiftL dst shift)); 8892 effect(KILL cr); 8893 8894 format %{ "shrq $dst, $shift" %} 8895 opcode(0xC1, 0x5); /* C1 /5 ib */ 8896 ins_encode(reg_opc_imm_wide(dst, shift)); 8897 ins_pipe(ialu_reg); 8898%} 8899 8900 8901// Logical Shift Right by 8-bit immediate 8902instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8903%{ 8904 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8905 effect(KILL cr); 8906 8907 format %{ "shrq $dst, $shift" %} 8908 opcode(0xC1, 0x5); /* C1 /5 ib */ 8909 ins_encode(REX_mem_wide(dst), OpcP, 8910 RM_opc_mem(secondary, dst), Con8or32(shift)); 8911 ins_pipe(ialu_mem_imm); 8912%} 8913 8914// Logical Shift Right by variable 8915instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8916%{ 8917 match(Set dst (URShiftL dst shift)); 8918 effect(KILL cr); 8919 8920 format %{ "shrq $dst, $shift" %} 8921 opcode(0xD3, 0x5); /* D3 /5 */ 8922 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8923 ins_pipe(ialu_reg_reg); 8924%} 8925 8926// Logical Shift Right by variable 8927instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8928%{ 8929 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8930 effect(KILL cr); 8931 8932 format %{ "shrq $dst, $shift" %} 8933 opcode(0xD3, 0x5); /* D3 /5 */ 8934 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8935 ins_pipe(ialu_mem_reg); 8936%} 8937 8938// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8939// This idiom is used by the compiler for the i2b bytecode. 8940instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8941%{ 8942 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8943 8944 format %{ "movsbl $dst, $src\t# i2b" %} 8945 opcode(0x0F, 0xBE); 8946 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8947 ins_pipe(ialu_reg_reg); 8948%} 8949 8950// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8951// This idiom is used by the compiler the i2s bytecode. 8952instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8953%{ 8954 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8955 8956 format %{ "movswl $dst, $src\t# i2s" %} 8957 opcode(0x0F, 0xBF); 8958 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8959 ins_pipe(ialu_reg_reg); 8960%} 8961 8962// ROL/ROR instructions 8963 8964// ROL expand 8965instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8966 effect(KILL cr, USE_DEF dst); 8967 8968 format %{ "roll $dst" %} 8969 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8970 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8971 ins_pipe(ialu_reg); 8972%} 8973 8974instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8975 effect(USE_DEF dst, USE shift, KILL cr); 8976 8977 format %{ "roll $dst, $shift" %} 8978 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8979 ins_encode( reg_opc_imm(dst, shift) ); 8980 ins_pipe(ialu_reg); 8981%} 8982 8983instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8984%{ 8985 effect(USE_DEF dst, USE shift, KILL cr); 8986 8987 format %{ "roll $dst, $shift" %} 8988 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8989 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8990 ins_pipe(ialu_reg_reg); 8991%} 8992// end of ROL expand 8993 8994// Rotate Left by one 8995instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8996%{ 8997 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8998 8999 expand %{ 9000 rolI_rReg_imm1(dst, cr); 9001 %} 9002%} 9003 9004// Rotate Left by 8-bit immediate 9005instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9006%{ 9007 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9008 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9009 9010 expand %{ 9011 rolI_rReg_imm8(dst, lshift, cr); 9012 %} 9013%} 9014 9015// Rotate Left by variable 9016instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9017%{ 9018 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9019 9020 expand %{ 9021 rolI_rReg_CL(dst, shift, cr); 9022 %} 9023%} 9024 9025// Rotate Left by variable 9026instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9027%{ 9028 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9029 9030 expand %{ 9031 rolI_rReg_CL(dst, shift, cr); 9032 %} 9033%} 9034 9035// ROR expand 9036instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9037%{ 9038 effect(USE_DEF dst, KILL cr); 9039 9040 format %{ "rorl $dst" %} 9041 opcode(0xD1, 0x1); /* D1 /1 */ 9042 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9043 ins_pipe(ialu_reg); 9044%} 9045 9046instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9047%{ 9048 effect(USE_DEF dst, USE shift, KILL cr); 9049 9050 format %{ "rorl $dst, $shift" %} 9051 opcode(0xC1, 0x1); /* C1 /1 ib */ 9052 ins_encode(reg_opc_imm(dst, shift)); 9053 ins_pipe(ialu_reg); 9054%} 9055 9056instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9057%{ 9058 effect(USE_DEF dst, USE shift, KILL cr); 9059 9060 format %{ "rorl $dst, $shift" %} 9061 opcode(0xD3, 0x1); /* D3 /1 */ 9062 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9063 ins_pipe(ialu_reg_reg); 9064%} 9065// end of ROR expand 9066 9067// Rotate Right by one 9068instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9069%{ 9070 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9071 9072 expand %{ 9073 rorI_rReg_imm1(dst, cr); 9074 %} 9075%} 9076 9077// Rotate Right by 8-bit immediate 9078instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9079%{ 9080 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9081 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9082 9083 expand %{ 9084 rorI_rReg_imm8(dst, rshift, cr); 9085 %} 9086%} 9087 9088// Rotate Right by variable 9089instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9090%{ 9091 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9092 9093 expand %{ 9094 rorI_rReg_CL(dst, shift, cr); 9095 %} 9096%} 9097 9098// Rotate Right by variable 9099instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9100%{ 9101 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9102 9103 expand %{ 9104 rorI_rReg_CL(dst, shift, cr); 9105 %} 9106%} 9107 9108// for long rotate 9109// ROL expand 9110instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9111 effect(USE_DEF dst, KILL cr); 9112 9113 format %{ "rolq $dst" %} 9114 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9115 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9116 ins_pipe(ialu_reg); 9117%} 9118 9119instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9120 effect(USE_DEF dst, USE shift, KILL cr); 9121 9122 format %{ "rolq $dst, $shift" %} 9123 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9124 ins_encode( reg_opc_imm_wide(dst, shift) ); 9125 ins_pipe(ialu_reg); 9126%} 9127 9128instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9129%{ 9130 effect(USE_DEF dst, USE shift, KILL cr); 9131 9132 format %{ "rolq $dst, $shift" %} 9133 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9134 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9135 ins_pipe(ialu_reg_reg); 9136%} 9137// end of ROL expand 9138 9139// Rotate Left by one 9140instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9141%{ 9142 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9143 9144 expand %{ 9145 rolL_rReg_imm1(dst, cr); 9146 %} 9147%} 9148 9149// Rotate Left by 8-bit immediate 9150instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9151%{ 9152 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9153 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9154 9155 expand %{ 9156 rolL_rReg_imm8(dst, lshift, cr); 9157 %} 9158%} 9159 9160// Rotate Left by variable 9161instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9162%{ 9163 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9164 9165 expand %{ 9166 rolL_rReg_CL(dst, shift, cr); 9167 %} 9168%} 9169 9170// Rotate Left by variable 9171instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9172%{ 9173 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9174 9175 expand %{ 9176 rolL_rReg_CL(dst, shift, cr); 9177 %} 9178%} 9179 9180// ROR expand 9181instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9182%{ 9183 effect(USE_DEF dst, KILL cr); 9184 9185 format %{ "rorq $dst" %} 9186 opcode(0xD1, 0x1); /* D1 /1 */ 9187 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9188 ins_pipe(ialu_reg); 9189%} 9190 9191instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9192%{ 9193 effect(USE_DEF dst, USE shift, KILL cr); 9194 9195 format %{ "rorq $dst, $shift" %} 9196 opcode(0xC1, 0x1); /* C1 /1 ib */ 9197 ins_encode(reg_opc_imm_wide(dst, shift)); 9198 ins_pipe(ialu_reg); 9199%} 9200 9201instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9202%{ 9203 effect(USE_DEF dst, USE shift, KILL cr); 9204 9205 format %{ "rorq $dst, $shift" %} 9206 opcode(0xD3, 0x1); /* D3 /1 */ 9207 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9208 ins_pipe(ialu_reg_reg); 9209%} 9210// end of ROR expand 9211 9212// Rotate Right by one 9213instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9214%{ 9215 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9216 9217 expand %{ 9218 rorL_rReg_imm1(dst, cr); 9219 %} 9220%} 9221 9222// Rotate Right by 8-bit immediate 9223instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9224%{ 9225 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9226 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9227 9228 expand %{ 9229 rorL_rReg_imm8(dst, rshift, cr); 9230 %} 9231%} 9232 9233// Rotate Right by variable 9234instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9235%{ 9236 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9237 9238 expand %{ 9239 rorL_rReg_CL(dst, shift, cr); 9240 %} 9241%} 9242 9243// Rotate Right by variable 9244instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9245%{ 9246 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9247 9248 expand %{ 9249 rorL_rReg_CL(dst, shift, cr); 9250 %} 9251%} 9252 9253// Logical Instructions 9254 9255// Integer Logical Instructions 9256 9257// And Instructions 9258// And Register with Register 9259instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9260%{ 9261 match(Set dst (AndI dst src)); 9262 effect(KILL cr); 9263 9264 format %{ "andl $dst, $src\t# int" %} 9265 opcode(0x23); 9266 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9267 ins_pipe(ialu_reg_reg); 9268%} 9269 9270// And Register with Immediate 255 9271instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9272%{ 9273 match(Set dst (AndI dst src)); 9274 9275 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9276 opcode(0x0F, 0xB6); 9277 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9278 ins_pipe(ialu_reg); 9279%} 9280 9281// And Register with Immediate 255 and promote to long 9282instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9283%{ 9284 match(Set dst (ConvI2L (AndI src mask))); 9285 9286 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9287 opcode(0x0F, 0xB6); 9288 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9289 ins_pipe(ialu_reg); 9290%} 9291 9292// And Register with Immediate 65535 9293instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9294%{ 9295 match(Set dst (AndI dst src)); 9296 9297 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9298 opcode(0x0F, 0xB7); 9299 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9300 ins_pipe(ialu_reg); 9301%} 9302 9303// And Register with Immediate 65535 and promote to long 9304instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9305%{ 9306 match(Set dst (ConvI2L (AndI src mask))); 9307 9308 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9309 opcode(0x0F, 0xB7); 9310 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9311 ins_pipe(ialu_reg); 9312%} 9313 9314// And Register with Immediate 9315instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9316%{ 9317 match(Set dst (AndI dst src)); 9318 effect(KILL cr); 9319 9320 format %{ "andl $dst, $src\t# int" %} 9321 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9322 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9323 ins_pipe(ialu_reg); 9324%} 9325 9326// And Register with Memory 9327instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9328%{ 9329 match(Set dst (AndI dst (LoadI src))); 9330 effect(KILL cr); 9331 9332 ins_cost(125); 9333 format %{ "andl $dst, $src\t# int" %} 9334 opcode(0x23); 9335 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9336 ins_pipe(ialu_reg_mem); 9337%} 9338 9339// And Memory with Register 9340instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9341%{ 9342 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 9343 effect(KILL cr); 9344 9345 ins_cost(150); 9346 format %{ "andb $dst, $src\t# byte" %} 9347 opcode(0x20); 9348 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9349 ins_pipe(ialu_mem_reg); 9350%} 9351 9352instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9353%{ 9354 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9355 effect(KILL cr); 9356 9357 ins_cost(150); 9358 format %{ "andl $dst, $src\t# int" %} 9359 opcode(0x21); /* Opcode 21 /r */ 9360 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9361 ins_pipe(ialu_mem_reg); 9362%} 9363 9364// And Memory with Immediate 9365instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9366%{ 9367 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9368 effect(KILL cr); 9369 9370 ins_cost(125); 9371 format %{ "andl $dst, $src\t# int" %} 9372 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9373 ins_encode(REX_mem(dst), OpcSE(src), 9374 RM_opc_mem(secondary, dst), Con8or32(src)); 9375 ins_pipe(ialu_mem_imm); 9376%} 9377 9378// BMI1 instructions 9379instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9380 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9381 predicate(UseBMI1Instructions); 9382 effect(KILL cr); 9383 9384 ins_cost(125); 9385 format %{ "andnl $dst, $src1, $src2" %} 9386 9387 ins_encode %{ 9388 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9389 %} 9390 ins_pipe(ialu_reg_mem); 9391%} 9392 9393instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9394 match(Set dst (AndI (XorI src1 minus_1) src2)); 9395 predicate(UseBMI1Instructions); 9396 effect(KILL cr); 9397 9398 format %{ "andnl $dst, $src1, $src2" %} 9399 9400 ins_encode %{ 9401 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9402 %} 9403 ins_pipe(ialu_reg); 9404%} 9405 9406instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9407 match(Set dst (AndI (SubI imm_zero src) src)); 9408 predicate(UseBMI1Instructions); 9409 effect(KILL cr); 9410 9411 format %{ "blsil $dst, $src" %} 9412 9413 ins_encode %{ 9414 __ blsil($dst$$Register, $src$$Register); 9415 %} 9416 ins_pipe(ialu_reg); 9417%} 9418 9419instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9420 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9421 predicate(UseBMI1Instructions); 9422 effect(KILL cr); 9423 9424 ins_cost(125); 9425 format %{ "blsil $dst, $src" %} 9426 9427 ins_encode %{ 9428 __ blsil($dst$$Register, $src$$Address); 9429 %} 9430 ins_pipe(ialu_reg_mem); 9431%} 9432 9433instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9434%{ 9435 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9436 predicate(UseBMI1Instructions); 9437 effect(KILL cr); 9438 9439 ins_cost(125); 9440 format %{ "blsmskl $dst, $src" %} 9441 9442 ins_encode %{ 9443 __ blsmskl($dst$$Register, $src$$Address); 9444 %} 9445 ins_pipe(ialu_reg_mem); 9446%} 9447 9448instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9449%{ 9450 match(Set dst (XorI (AddI src minus_1) src)); 9451 predicate(UseBMI1Instructions); 9452 effect(KILL cr); 9453 9454 format %{ "blsmskl $dst, $src" %} 9455 9456 ins_encode %{ 9457 __ blsmskl($dst$$Register, $src$$Register); 9458 %} 9459 9460 ins_pipe(ialu_reg); 9461%} 9462 9463instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9464%{ 9465 match(Set dst (AndI (AddI src minus_1) src) ); 9466 predicate(UseBMI1Instructions); 9467 effect(KILL cr); 9468 9469 format %{ "blsrl $dst, $src" %} 9470 9471 ins_encode %{ 9472 __ blsrl($dst$$Register, $src$$Register); 9473 %} 9474 9475 ins_pipe(ialu_reg_mem); 9476%} 9477 9478instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9479%{ 9480 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9481 predicate(UseBMI1Instructions); 9482 effect(KILL cr); 9483 9484 ins_cost(125); 9485 format %{ "blsrl $dst, $src" %} 9486 9487 ins_encode %{ 9488 __ blsrl($dst$$Register, $src$$Address); 9489 %} 9490 9491 ins_pipe(ialu_reg); 9492%} 9493 9494// Or Instructions 9495// Or Register with Register 9496instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9497%{ 9498 match(Set dst (OrI dst src)); 9499 effect(KILL cr); 9500 9501 format %{ "orl $dst, $src\t# int" %} 9502 opcode(0x0B); 9503 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9504 ins_pipe(ialu_reg_reg); 9505%} 9506 9507// Or Register with Immediate 9508instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9509%{ 9510 match(Set dst (OrI dst src)); 9511 effect(KILL cr); 9512 9513 format %{ "orl $dst, $src\t# int" %} 9514 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9515 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9516 ins_pipe(ialu_reg); 9517%} 9518 9519// Or Register with Memory 9520instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9521%{ 9522 match(Set dst (OrI dst (LoadI src))); 9523 effect(KILL cr); 9524 9525 ins_cost(125); 9526 format %{ "orl $dst, $src\t# int" %} 9527 opcode(0x0B); 9528 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9529 ins_pipe(ialu_reg_mem); 9530%} 9531 9532// Or Memory with Register 9533instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9534%{ 9535 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9536 effect(KILL cr); 9537 9538 ins_cost(150); 9539 format %{ "orb $dst, $src\t# byte" %} 9540 opcode(0x08); 9541 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9542 ins_pipe(ialu_mem_reg); 9543%} 9544 9545instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9546%{ 9547 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9548 effect(KILL cr); 9549 9550 ins_cost(150); 9551 format %{ "orl $dst, $src\t# int" %} 9552 opcode(0x09); /* Opcode 09 /r */ 9553 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9554 ins_pipe(ialu_mem_reg); 9555%} 9556 9557// Or Memory with Immediate 9558instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9559%{ 9560 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9561 effect(KILL cr); 9562 9563 ins_cost(125); 9564 format %{ "orl $dst, $src\t# int" %} 9565 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9566 ins_encode(REX_mem(dst), OpcSE(src), 9567 RM_opc_mem(secondary, dst), Con8or32(src)); 9568 ins_pipe(ialu_mem_imm); 9569%} 9570 9571// Xor Instructions 9572// Xor Register with Register 9573instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9574%{ 9575 match(Set dst (XorI dst src)); 9576 effect(KILL cr); 9577 9578 format %{ "xorl $dst, $src\t# int" %} 9579 opcode(0x33); 9580 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9581 ins_pipe(ialu_reg_reg); 9582%} 9583 9584// Xor Register with Immediate -1 9585instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9586 match(Set dst (XorI dst imm)); 9587 9588 format %{ "not $dst" %} 9589 ins_encode %{ 9590 __ notl($dst$$Register); 9591 %} 9592 ins_pipe(ialu_reg); 9593%} 9594 9595// Xor Register with Immediate 9596instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9597%{ 9598 match(Set dst (XorI dst src)); 9599 effect(KILL cr); 9600 9601 format %{ "xorl $dst, $src\t# int" %} 9602 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9603 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9604 ins_pipe(ialu_reg); 9605%} 9606 9607// Xor Register with Memory 9608instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9609%{ 9610 match(Set dst (XorI dst (LoadI src))); 9611 effect(KILL cr); 9612 9613 ins_cost(125); 9614 format %{ "xorl $dst, $src\t# int" %} 9615 opcode(0x33); 9616 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9617 ins_pipe(ialu_reg_mem); 9618%} 9619 9620// Xor Memory with Register 9621instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9622%{ 9623 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9624 effect(KILL cr); 9625 9626 ins_cost(150); 9627 format %{ "xorb $dst, $src\t# byte" %} 9628 opcode(0x30); 9629 ins_encode(REX_breg_mem(src, dst), OpcP, reg_mem(src, dst)); 9630 ins_pipe(ialu_mem_reg); 9631%} 9632 9633instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9634%{ 9635 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9636 effect(KILL cr); 9637 9638 ins_cost(150); 9639 format %{ "xorl $dst, $src\t# int" %} 9640 opcode(0x31); /* Opcode 31 /r */ 9641 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9642 ins_pipe(ialu_mem_reg); 9643%} 9644 9645// Xor Memory with Immediate 9646instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9647%{ 9648 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9649 effect(KILL cr); 9650 9651 ins_cost(125); 9652 format %{ "xorl $dst, $src\t# int" %} 9653 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9654 ins_encode(REX_mem(dst), OpcSE(src), 9655 RM_opc_mem(secondary, dst), Con8or32(src)); 9656 ins_pipe(ialu_mem_imm); 9657%} 9658 9659 9660// Long Logical Instructions 9661 9662// And Instructions 9663// And Register with Register 9664instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9665%{ 9666 match(Set dst (AndL dst src)); 9667 effect(KILL cr); 9668 9669 format %{ "andq $dst, $src\t# long" %} 9670 opcode(0x23); 9671 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9672 ins_pipe(ialu_reg_reg); 9673%} 9674 9675// And Register with Immediate 255 9676instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9677%{ 9678 match(Set dst (AndL dst src)); 9679 9680 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9681 opcode(0x0F, 0xB6); 9682 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9683 ins_pipe(ialu_reg); 9684%} 9685 9686// And Register with Immediate 65535 9687instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9688%{ 9689 match(Set dst (AndL dst src)); 9690 9691 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9692 opcode(0x0F, 0xB7); 9693 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9694 ins_pipe(ialu_reg); 9695%} 9696 9697// And Register with Immediate 9698instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9699%{ 9700 match(Set dst (AndL dst src)); 9701 effect(KILL cr); 9702 9703 format %{ "andq $dst, $src\t# long" %} 9704 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9705 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9706 ins_pipe(ialu_reg); 9707%} 9708 9709// And Register with Memory 9710instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9711%{ 9712 match(Set dst (AndL dst (LoadL src))); 9713 effect(KILL cr); 9714 9715 ins_cost(125); 9716 format %{ "andq $dst, $src\t# long" %} 9717 opcode(0x23); 9718 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9719 ins_pipe(ialu_reg_mem); 9720%} 9721 9722// And Memory with Register 9723instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9724%{ 9725 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9726 effect(KILL cr); 9727 9728 ins_cost(150); 9729 format %{ "andq $dst, $src\t# long" %} 9730 opcode(0x21); /* Opcode 21 /r */ 9731 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9732 ins_pipe(ialu_mem_reg); 9733%} 9734 9735// And Memory with Immediate 9736instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9737%{ 9738 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9739 effect(KILL cr); 9740 9741 ins_cost(125); 9742 format %{ "andq $dst, $src\t# long" %} 9743 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9744 ins_encode(REX_mem_wide(dst), OpcSE(src), 9745 RM_opc_mem(secondary, dst), Con8or32(src)); 9746 ins_pipe(ialu_mem_imm); 9747%} 9748 9749// BMI1 instructions 9750instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9751 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9752 predicate(UseBMI1Instructions); 9753 effect(KILL cr); 9754 9755 ins_cost(125); 9756 format %{ "andnq $dst, $src1, $src2" %} 9757 9758 ins_encode %{ 9759 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9760 %} 9761 ins_pipe(ialu_reg_mem); 9762%} 9763 9764instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9765 match(Set dst (AndL (XorL src1 minus_1) src2)); 9766 predicate(UseBMI1Instructions); 9767 effect(KILL cr); 9768 9769 format %{ "andnq $dst, $src1, $src2" %} 9770 9771 ins_encode %{ 9772 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9773 %} 9774 ins_pipe(ialu_reg_mem); 9775%} 9776 9777instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9778 match(Set dst (AndL (SubL imm_zero src) src)); 9779 predicate(UseBMI1Instructions); 9780 effect(KILL cr); 9781 9782 format %{ "blsiq $dst, $src" %} 9783 9784 ins_encode %{ 9785 __ blsiq($dst$$Register, $src$$Register); 9786 %} 9787 ins_pipe(ialu_reg); 9788%} 9789 9790instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9791 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9792 predicate(UseBMI1Instructions); 9793 effect(KILL cr); 9794 9795 ins_cost(125); 9796 format %{ "blsiq $dst, $src" %} 9797 9798 ins_encode %{ 9799 __ blsiq($dst$$Register, $src$$Address); 9800 %} 9801 ins_pipe(ialu_reg_mem); 9802%} 9803 9804instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9805%{ 9806 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9807 predicate(UseBMI1Instructions); 9808 effect(KILL cr); 9809 9810 ins_cost(125); 9811 format %{ "blsmskq $dst, $src" %} 9812 9813 ins_encode %{ 9814 __ blsmskq($dst$$Register, $src$$Address); 9815 %} 9816 ins_pipe(ialu_reg_mem); 9817%} 9818 9819instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9820%{ 9821 match(Set dst (XorL (AddL src minus_1) src)); 9822 predicate(UseBMI1Instructions); 9823 effect(KILL cr); 9824 9825 format %{ "blsmskq $dst, $src" %} 9826 9827 ins_encode %{ 9828 __ blsmskq($dst$$Register, $src$$Register); 9829 %} 9830 9831 ins_pipe(ialu_reg); 9832%} 9833 9834instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9835%{ 9836 match(Set dst (AndL (AddL src minus_1) src) ); 9837 predicate(UseBMI1Instructions); 9838 effect(KILL cr); 9839 9840 format %{ "blsrq $dst, $src" %} 9841 9842 ins_encode %{ 9843 __ blsrq($dst$$Register, $src$$Register); 9844 %} 9845 9846 ins_pipe(ialu_reg); 9847%} 9848 9849instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9850%{ 9851 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9852 predicate(UseBMI1Instructions); 9853 effect(KILL cr); 9854 9855 ins_cost(125); 9856 format %{ "blsrq $dst, $src" %} 9857 9858 ins_encode %{ 9859 __ blsrq($dst$$Register, $src$$Address); 9860 %} 9861 9862 ins_pipe(ialu_reg); 9863%} 9864 9865// Or Instructions 9866// Or Register with Register 9867instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9868%{ 9869 match(Set dst (OrL dst src)); 9870 effect(KILL cr); 9871 9872 format %{ "orq $dst, $src\t# long" %} 9873 opcode(0x0B); 9874 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9875 ins_pipe(ialu_reg_reg); 9876%} 9877 9878// Use any_RegP to match R15 (TLS register) without spilling. 9879instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9880 match(Set dst (OrL dst (CastP2X src))); 9881 effect(KILL cr); 9882 9883 format %{ "orq $dst, $src\t# long" %} 9884 opcode(0x0B); 9885 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9886 ins_pipe(ialu_reg_reg); 9887%} 9888 9889 9890// Or Register with Immediate 9891instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9892%{ 9893 match(Set dst (OrL dst src)); 9894 effect(KILL cr); 9895 9896 format %{ "orq $dst, $src\t# long" %} 9897 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9898 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9899 ins_pipe(ialu_reg); 9900%} 9901 9902// Or Register with Memory 9903instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9904%{ 9905 match(Set dst (OrL dst (LoadL src))); 9906 effect(KILL cr); 9907 9908 ins_cost(125); 9909 format %{ "orq $dst, $src\t# long" %} 9910 opcode(0x0B); 9911 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9912 ins_pipe(ialu_reg_mem); 9913%} 9914 9915// Or Memory with Register 9916instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9917%{ 9918 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9919 effect(KILL cr); 9920 9921 ins_cost(150); 9922 format %{ "orq $dst, $src\t# long" %} 9923 opcode(0x09); /* Opcode 09 /r */ 9924 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9925 ins_pipe(ialu_mem_reg); 9926%} 9927 9928// Or Memory with Immediate 9929instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9930%{ 9931 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9932 effect(KILL cr); 9933 9934 ins_cost(125); 9935 format %{ "orq $dst, $src\t# long" %} 9936 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9937 ins_encode(REX_mem_wide(dst), OpcSE(src), 9938 RM_opc_mem(secondary, dst), Con8or32(src)); 9939 ins_pipe(ialu_mem_imm); 9940%} 9941 9942// Xor Instructions 9943// Xor Register with Register 9944instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9945%{ 9946 match(Set dst (XorL dst src)); 9947 effect(KILL cr); 9948 9949 format %{ "xorq $dst, $src\t# long" %} 9950 opcode(0x33); 9951 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9952 ins_pipe(ialu_reg_reg); 9953%} 9954 9955// Xor Register with Immediate -1 9956instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9957 match(Set dst (XorL dst imm)); 9958 9959 format %{ "notq $dst" %} 9960 ins_encode %{ 9961 __ notq($dst$$Register); 9962 %} 9963 ins_pipe(ialu_reg); 9964%} 9965 9966// Xor Register with Immediate 9967instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9968%{ 9969 match(Set dst (XorL dst src)); 9970 effect(KILL cr); 9971 9972 format %{ "xorq $dst, $src\t# long" %} 9973 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9974 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9975 ins_pipe(ialu_reg); 9976%} 9977 9978// Xor Register with Memory 9979instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9980%{ 9981 match(Set dst (XorL dst (LoadL src))); 9982 effect(KILL cr); 9983 9984 ins_cost(125); 9985 format %{ "xorq $dst, $src\t# long" %} 9986 opcode(0x33); 9987 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9988 ins_pipe(ialu_reg_mem); 9989%} 9990 9991// Xor Memory with Register 9992instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9993%{ 9994 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9995 effect(KILL cr); 9996 9997 ins_cost(150); 9998 format %{ "xorq $dst, $src\t# long" %} 9999 opcode(0x31); /* Opcode 31 /r */ 10000 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10001 ins_pipe(ialu_mem_reg); 10002%} 10003 10004// Xor Memory with Immediate 10005instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10006%{ 10007 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10008 effect(KILL cr); 10009 10010 ins_cost(125); 10011 format %{ "xorq $dst, $src\t# long" %} 10012 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 10013 ins_encode(REX_mem_wide(dst), OpcSE(src), 10014 RM_opc_mem(secondary, dst), Con8or32(src)); 10015 ins_pipe(ialu_mem_imm); 10016%} 10017 10018// Convert Int to Boolean 10019instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 10020%{ 10021 match(Set dst (Conv2B src)); 10022 effect(KILL cr); 10023 10024 format %{ "testl $src, $src\t# ci2b\n\t" 10025 "setnz $dst\n\t" 10026 "movzbl $dst, $dst" %} 10027 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10028 setNZ_reg(dst), 10029 REX_reg_breg(dst, dst), // movzbl 10030 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10031 ins_pipe(pipe_slow); // XXX 10032%} 10033 10034// Convert Pointer to Boolean 10035instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10036%{ 10037 match(Set dst (Conv2B src)); 10038 effect(KILL cr); 10039 10040 format %{ "testq $src, $src\t# cp2b\n\t" 10041 "setnz $dst\n\t" 10042 "movzbl $dst, $dst" %} 10043 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10044 setNZ_reg(dst), 10045 REX_reg_breg(dst, dst), // movzbl 10046 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10047 ins_pipe(pipe_slow); // XXX 10048%} 10049 10050instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10051%{ 10052 match(Set dst (CmpLTMask p q)); 10053 effect(KILL cr); 10054 10055 ins_cost(400); 10056 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10057 "setlt $dst\n\t" 10058 "movzbl $dst, $dst\n\t" 10059 "negl $dst" %} 10060 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10061 setLT_reg(dst), 10062 REX_reg_breg(dst, dst), // movzbl 10063 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10064 neg_reg(dst)); 10065 ins_pipe(pipe_slow); 10066%} 10067 10068instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10069%{ 10070 match(Set dst (CmpLTMask dst zero)); 10071 effect(KILL cr); 10072 10073 ins_cost(100); 10074 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10075 ins_encode %{ 10076 __ sarl($dst$$Register, 31); 10077 %} 10078 ins_pipe(ialu_reg); 10079%} 10080 10081/* Better to save a register than avoid a branch */ 10082instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10083%{ 10084 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10085 effect(KILL cr); 10086 ins_cost(300); 10087 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10088 "jge done\n\t" 10089 "addl $p,$y\n" 10090 "done: " %} 10091 ins_encode %{ 10092 Register Rp = $p$$Register; 10093 Register Rq = $q$$Register; 10094 Register Ry = $y$$Register; 10095 Label done; 10096 __ subl(Rp, Rq); 10097 __ jccb(Assembler::greaterEqual, done); 10098 __ addl(Rp, Ry); 10099 __ bind(done); 10100 %} 10101 ins_pipe(pipe_cmplt); 10102%} 10103 10104/* Better to save a register than avoid a branch */ 10105instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10106%{ 10107 match(Set y (AndI (CmpLTMask p q) y)); 10108 effect(KILL cr); 10109 10110 ins_cost(300); 10111 10112 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10113 "jlt done\n\t" 10114 "xorl $y, $y\n" 10115 "done: " %} 10116 ins_encode %{ 10117 Register Rp = $p$$Register; 10118 Register Rq = $q$$Register; 10119 Register Ry = $y$$Register; 10120 Label done; 10121 __ cmpl(Rp, Rq); 10122 __ jccb(Assembler::less, done); 10123 __ xorl(Ry, Ry); 10124 __ bind(done); 10125 %} 10126 ins_pipe(pipe_cmplt); 10127%} 10128 10129 10130//---------- FP Instructions------------------------------------------------ 10131 10132instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10133%{ 10134 match(Set cr (CmpF src1 src2)); 10135 10136 ins_cost(145); 10137 format %{ "ucomiss $src1, $src2\n\t" 10138 "jnp,s exit\n\t" 10139 "pushfq\t# saw NaN, set CF\n\t" 10140 "andq [rsp], #0xffffff2b\n\t" 10141 "popfq\n" 10142 "exit:" %} 10143 ins_encode %{ 10144 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10145 emit_cmpfp_fixup(_masm); 10146 %} 10147 ins_pipe(pipe_slow); 10148%} 10149 10150instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10151 match(Set cr (CmpF src1 src2)); 10152 10153 ins_cost(100); 10154 format %{ "ucomiss $src1, $src2" %} 10155 ins_encode %{ 10156 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10157 %} 10158 ins_pipe(pipe_slow); 10159%} 10160 10161instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10162%{ 10163 match(Set cr (CmpF src1 (LoadF src2))); 10164 10165 ins_cost(145); 10166 format %{ "ucomiss $src1, $src2\n\t" 10167 "jnp,s exit\n\t" 10168 "pushfq\t# saw NaN, set CF\n\t" 10169 "andq [rsp], #0xffffff2b\n\t" 10170 "popfq\n" 10171 "exit:" %} 10172 ins_encode %{ 10173 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10174 emit_cmpfp_fixup(_masm); 10175 %} 10176 ins_pipe(pipe_slow); 10177%} 10178 10179instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10180 match(Set cr (CmpF src1 (LoadF src2))); 10181 10182 ins_cost(100); 10183 format %{ "ucomiss $src1, $src2" %} 10184 ins_encode %{ 10185 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10186 %} 10187 ins_pipe(pipe_slow); 10188%} 10189 10190instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10191 match(Set cr (CmpF src con)); 10192 10193 ins_cost(145); 10194 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10195 "jnp,s exit\n\t" 10196 "pushfq\t# saw NaN, set CF\n\t" 10197 "andq [rsp], #0xffffff2b\n\t" 10198 "popfq\n" 10199 "exit:" %} 10200 ins_encode %{ 10201 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10202 emit_cmpfp_fixup(_masm); 10203 %} 10204 ins_pipe(pipe_slow); 10205%} 10206 10207instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10208 match(Set cr (CmpF src con)); 10209 ins_cost(100); 10210 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10211 ins_encode %{ 10212 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10213 %} 10214 ins_pipe(pipe_slow); 10215%} 10216 10217instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10218%{ 10219 match(Set cr (CmpD src1 src2)); 10220 10221 ins_cost(145); 10222 format %{ "ucomisd $src1, $src2\n\t" 10223 "jnp,s exit\n\t" 10224 "pushfq\t# saw NaN, set CF\n\t" 10225 "andq [rsp], #0xffffff2b\n\t" 10226 "popfq\n" 10227 "exit:" %} 10228 ins_encode %{ 10229 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10230 emit_cmpfp_fixup(_masm); 10231 %} 10232 ins_pipe(pipe_slow); 10233%} 10234 10235instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10236 match(Set cr (CmpD src1 src2)); 10237 10238 ins_cost(100); 10239 format %{ "ucomisd $src1, $src2 test" %} 10240 ins_encode %{ 10241 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10242 %} 10243 ins_pipe(pipe_slow); 10244%} 10245 10246instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10247%{ 10248 match(Set cr (CmpD src1 (LoadD src2))); 10249 10250 ins_cost(145); 10251 format %{ "ucomisd $src1, $src2\n\t" 10252 "jnp,s exit\n\t" 10253 "pushfq\t# saw NaN, set CF\n\t" 10254 "andq [rsp], #0xffffff2b\n\t" 10255 "popfq\n" 10256 "exit:" %} 10257 ins_encode %{ 10258 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10259 emit_cmpfp_fixup(_masm); 10260 %} 10261 ins_pipe(pipe_slow); 10262%} 10263 10264instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10265 match(Set cr (CmpD src1 (LoadD src2))); 10266 10267 ins_cost(100); 10268 format %{ "ucomisd $src1, $src2" %} 10269 ins_encode %{ 10270 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10271 %} 10272 ins_pipe(pipe_slow); 10273%} 10274 10275instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10276 match(Set cr (CmpD src con)); 10277 10278 ins_cost(145); 10279 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10280 "jnp,s exit\n\t" 10281 "pushfq\t# saw NaN, set CF\n\t" 10282 "andq [rsp], #0xffffff2b\n\t" 10283 "popfq\n" 10284 "exit:" %} 10285 ins_encode %{ 10286 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10287 emit_cmpfp_fixup(_masm); 10288 %} 10289 ins_pipe(pipe_slow); 10290%} 10291 10292instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10293 match(Set cr (CmpD src con)); 10294 ins_cost(100); 10295 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10296 ins_encode %{ 10297 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10298 %} 10299 ins_pipe(pipe_slow); 10300%} 10301 10302// Compare into -1,0,1 10303instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10304%{ 10305 match(Set dst (CmpF3 src1 src2)); 10306 effect(KILL cr); 10307 10308 ins_cost(275); 10309 format %{ "ucomiss $src1, $src2\n\t" 10310 "movl $dst, #-1\n\t" 10311 "jp,s done\n\t" 10312 "jb,s done\n\t" 10313 "setne $dst\n\t" 10314 "movzbl $dst, $dst\n" 10315 "done:" %} 10316 ins_encode %{ 10317 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10318 emit_cmpfp3(_masm, $dst$$Register); 10319 %} 10320 ins_pipe(pipe_slow); 10321%} 10322 10323// Compare into -1,0,1 10324instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10325%{ 10326 match(Set dst (CmpF3 src1 (LoadF src2))); 10327 effect(KILL cr); 10328 10329 ins_cost(275); 10330 format %{ "ucomiss $src1, $src2\n\t" 10331 "movl $dst, #-1\n\t" 10332 "jp,s done\n\t" 10333 "jb,s done\n\t" 10334 "setne $dst\n\t" 10335 "movzbl $dst, $dst\n" 10336 "done:" %} 10337 ins_encode %{ 10338 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10339 emit_cmpfp3(_masm, $dst$$Register); 10340 %} 10341 ins_pipe(pipe_slow); 10342%} 10343 10344// Compare into -1,0,1 10345instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10346 match(Set dst (CmpF3 src con)); 10347 effect(KILL cr); 10348 10349 ins_cost(275); 10350 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10351 "movl $dst, #-1\n\t" 10352 "jp,s done\n\t" 10353 "jb,s done\n\t" 10354 "setne $dst\n\t" 10355 "movzbl $dst, $dst\n" 10356 "done:" %} 10357 ins_encode %{ 10358 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10359 emit_cmpfp3(_masm, $dst$$Register); 10360 %} 10361 ins_pipe(pipe_slow); 10362%} 10363 10364// Compare into -1,0,1 10365instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10366%{ 10367 match(Set dst (CmpD3 src1 src2)); 10368 effect(KILL cr); 10369 10370 ins_cost(275); 10371 format %{ "ucomisd $src1, $src2\n\t" 10372 "movl $dst, #-1\n\t" 10373 "jp,s done\n\t" 10374 "jb,s done\n\t" 10375 "setne $dst\n\t" 10376 "movzbl $dst, $dst\n" 10377 "done:" %} 10378 ins_encode %{ 10379 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10380 emit_cmpfp3(_masm, $dst$$Register); 10381 %} 10382 ins_pipe(pipe_slow); 10383%} 10384 10385// Compare into -1,0,1 10386instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10387%{ 10388 match(Set dst (CmpD3 src1 (LoadD src2))); 10389 effect(KILL cr); 10390 10391 ins_cost(275); 10392 format %{ "ucomisd $src1, $src2\n\t" 10393 "movl $dst, #-1\n\t" 10394 "jp,s done\n\t" 10395 "jb,s done\n\t" 10396 "setne $dst\n\t" 10397 "movzbl $dst, $dst\n" 10398 "done:" %} 10399 ins_encode %{ 10400 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10401 emit_cmpfp3(_masm, $dst$$Register); 10402 %} 10403 ins_pipe(pipe_slow); 10404%} 10405 10406// Compare into -1,0,1 10407instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10408 match(Set dst (CmpD3 src con)); 10409 effect(KILL cr); 10410 10411 ins_cost(275); 10412 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10413 "movl $dst, #-1\n\t" 10414 "jp,s done\n\t" 10415 "jb,s done\n\t" 10416 "setne $dst\n\t" 10417 "movzbl $dst, $dst\n" 10418 "done:" %} 10419 ins_encode %{ 10420 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10421 emit_cmpfp3(_masm, $dst$$Register); 10422 %} 10423 ins_pipe(pipe_slow); 10424%} 10425 10426//----------Arithmetic Conversion Instructions--------------------------------- 10427 10428instruct roundFloat_nop(regF dst) 10429%{ 10430 match(Set dst (RoundFloat dst)); 10431 10432 ins_cost(0); 10433 ins_encode(); 10434 ins_pipe(empty); 10435%} 10436 10437instruct roundDouble_nop(regD dst) 10438%{ 10439 match(Set dst (RoundDouble dst)); 10440 10441 ins_cost(0); 10442 ins_encode(); 10443 ins_pipe(empty); 10444%} 10445 10446instruct convF2D_reg_reg(regD dst, regF src) 10447%{ 10448 match(Set dst (ConvF2D src)); 10449 10450 format %{ "cvtss2sd $dst, $src" %} 10451 ins_encode %{ 10452 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10453 %} 10454 ins_pipe(pipe_slow); // XXX 10455%} 10456 10457instruct convF2D_reg_mem(regD dst, memory src) 10458%{ 10459 match(Set dst (ConvF2D (LoadF src))); 10460 10461 format %{ "cvtss2sd $dst, $src" %} 10462 ins_encode %{ 10463 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10464 %} 10465 ins_pipe(pipe_slow); // XXX 10466%} 10467 10468instruct convD2F_reg_reg(regF dst, regD src) 10469%{ 10470 match(Set dst (ConvD2F src)); 10471 10472 format %{ "cvtsd2ss $dst, $src" %} 10473 ins_encode %{ 10474 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10475 %} 10476 ins_pipe(pipe_slow); // XXX 10477%} 10478 10479instruct convD2F_reg_mem(regF dst, memory src) 10480%{ 10481 match(Set dst (ConvD2F (LoadD src))); 10482 10483 format %{ "cvtsd2ss $dst, $src" %} 10484 ins_encode %{ 10485 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10486 %} 10487 ins_pipe(pipe_slow); // XXX 10488%} 10489 10490// XXX do mem variants 10491instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10492%{ 10493 match(Set dst (ConvF2I src)); 10494 effect(KILL cr); 10495 10496 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10497 "cmpl $dst, #0x80000000\n\t" 10498 "jne,s done\n\t" 10499 "subq rsp, #8\n\t" 10500 "movss [rsp], $src\n\t" 10501 "call f2i_fixup\n\t" 10502 "popq $dst\n" 10503 "done: "%} 10504 ins_encode %{ 10505 Label done; 10506 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10507 __ cmpl($dst$$Register, 0x80000000); 10508 __ jccb(Assembler::notEqual, done); 10509 __ subptr(rsp, 8); 10510 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10511 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10512 __ pop($dst$$Register); 10513 __ bind(done); 10514 %} 10515 ins_pipe(pipe_slow); 10516%} 10517 10518instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10519%{ 10520 match(Set dst (ConvF2L src)); 10521 effect(KILL cr); 10522 10523 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10524 "cmpq $dst, [0x8000000000000000]\n\t" 10525 "jne,s done\n\t" 10526 "subq rsp, #8\n\t" 10527 "movss [rsp], $src\n\t" 10528 "call f2l_fixup\n\t" 10529 "popq $dst\n" 10530 "done: "%} 10531 ins_encode %{ 10532 Label done; 10533 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10534 __ cmp64($dst$$Register, 10535 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10536 __ jccb(Assembler::notEqual, done); 10537 __ subptr(rsp, 8); 10538 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10539 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10540 __ pop($dst$$Register); 10541 __ bind(done); 10542 %} 10543 ins_pipe(pipe_slow); 10544%} 10545 10546instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10547%{ 10548 match(Set dst (ConvD2I src)); 10549 effect(KILL cr); 10550 10551 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10552 "cmpl $dst, #0x80000000\n\t" 10553 "jne,s done\n\t" 10554 "subq rsp, #8\n\t" 10555 "movsd [rsp], $src\n\t" 10556 "call d2i_fixup\n\t" 10557 "popq $dst\n" 10558 "done: "%} 10559 ins_encode %{ 10560 Label done; 10561 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10562 __ cmpl($dst$$Register, 0x80000000); 10563 __ jccb(Assembler::notEqual, done); 10564 __ subptr(rsp, 8); 10565 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10566 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10567 __ pop($dst$$Register); 10568 __ bind(done); 10569 %} 10570 ins_pipe(pipe_slow); 10571%} 10572 10573instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10574%{ 10575 match(Set dst (ConvD2L src)); 10576 effect(KILL cr); 10577 10578 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10579 "cmpq $dst, [0x8000000000000000]\n\t" 10580 "jne,s done\n\t" 10581 "subq rsp, #8\n\t" 10582 "movsd [rsp], $src\n\t" 10583 "call d2l_fixup\n\t" 10584 "popq $dst\n" 10585 "done: "%} 10586 ins_encode %{ 10587 Label done; 10588 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10589 __ cmp64($dst$$Register, 10590 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10591 __ jccb(Assembler::notEqual, done); 10592 __ subptr(rsp, 8); 10593 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10594 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10595 __ pop($dst$$Register); 10596 __ bind(done); 10597 %} 10598 ins_pipe(pipe_slow); 10599%} 10600 10601instruct convI2F_reg_reg(regF dst, rRegI src) 10602%{ 10603 predicate(!UseXmmI2F); 10604 match(Set dst (ConvI2F src)); 10605 10606 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10607 ins_encode %{ 10608 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10609 %} 10610 ins_pipe(pipe_slow); // XXX 10611%} 10612 10613instruct convI2F_reg_mem(regF dst, memory src) 10614%{ 10615 match(Set dst (ConvI2F (LoadI src))); 10616 10617 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10618 ins_encode %{ 10619 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10620 %} 10621 ins_pipe(pipe_slow); // XXX 10622%} 10623 10624instruct convI2D_reg_reg(regD dst, rRegI src) 10625%{ 10626 predicate(!UseXmmI2D); 10627 match(Set dst (ConvI2D src)); 10628 10629 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10630 ins_encode %{ 10631 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10632 %} 10633 ins_pipe(pipe_slow); // XXX 10634%} 10635 10636instruct convI2D_reg_mem(regD dst, memory src) 10637%{ 10638 match(Set dst (ConvI2D (LoadI src))); 10639 10640 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10641 ins_encode %{ 10642 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10643 %} 10644 ins_pipe(pipe_slow); // XXX 10645%} 10646 10647instruct convXI2F_reg(regF dst, rRegI src) 10648%{ 10649 predicate(UseXmmI2F); 10650 match(Set dst (ConvI2F src)); 10651 10652 format %{ "movdl $dst, $src\n\t" 10653 "cvtdq2psl $dst, $dst\t# i2f" %} 10654 ins_encode %{ 10655 __ movdl($dst$$XMMRegister, $src$$Register); 10656 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10657 %} 10658 ins_pipe(pipe_slow); // XXX 10659%} 10660 10661instruct convXI2D_reg(regD dst, rRegI src) 10662%{ 10663 predicate(UseXmmI2D); 10664 match(Set dst (ConvI2D src)); 10665 10666 format %{ "movdl $dst, $src\n\t" 10667 "cvtdq2pdl $dst, $dst\t# i2d" %} 10668 ins_encode %{ 10669 __ movdl($dst$$XMMRegister, $src$$Register); 10670 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10671 %} 10672 ins_pipe(pipe_slow); // XXX 10673%} 10674 10675instruct convL2F_reg_reg(regF dst, rRegL src) 10676%{ 10677 match(Set dst (ConvL2F src)); 10678 10679 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10680 ins_encode %{ 10681 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10682 %} 10683 ins_pipe(pipe_slow); // XXX 10684%} 10685 10686instruct convL2F_reg_mem(regF dst, memory src) 10687%{ 10688 match(Set dst (ConvL2F (LoadL src))); 10689 10690 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10691 ins_encode %{ 10692 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10693 %} 10694 ins_pipe(pipe_slow); // XXX 10695%} 10696 10697instruct convL2D_reg_reg(regD dst, rRegL src) 10698%{ 10699 match(Set dst (ConvL2D src)); 10700 10701 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10702 ins_encode %{ 10703 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10704 %} 10705 ins_pipe(pipe_slow); // XXX 10706%} 10707 10708instruct convL2D_reg_mem(regD dst, memory src) 10709%{ 10710 match(Set dst (ConvL2D (LoadL src))); 10711 10712 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10713 ins_encode %{ 10714 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10715 %} 10716 ins_pipe(pipe_slow); // XXX 10717%} 10718 10719instruct convI2L_reg_reg(rRegL dst, rRegI src) 10720%{ 10721 match(Set dst (ConvI2L src)); 10722 10723 ins_cost(125); 10724 format %{ "movslq $dst, $src\t# i2l" %} 10725 ins_encode %{ 10726 __ movslq($dst$$Register, $src$$Register); 10727 %} 10728 ins_pipe(ialu_reg_reg); 10729%} 10730 10731// instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10732// %{ 10733// match(Set dst (ConvI2L src)); 10734// // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10735// // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10736// predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10737// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10738// ((const TypeNode*) n)->type()->is_long()->_lo == 10739// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10740 10741// format %{ "movl $dst, $src\t# unsigned i2l" %} 10742// ins_encode(enc_copy(dst, src)); 10743// // opcode(0x63); // needs REX.W 10744// // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10745// ins_pipe(ialu_reg_reg); 10746// %} 10747 10748// Zero-extend convert int to long 10749instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10750%{ 10751 match(Set dst (AndL (ConvI2L src) mask)); 10752 10753 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10754 ins_encode %{ 10755 if ($dst$$reg != $src$$reg) { 10756 __ movl($dst$$Register, $src$$Register); 10757 } 10758 %} 10759 ins_pipe(ialu_reg_reg); 10760%} 10761 10762// Zero-extend convert int to long 10763instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10764%{ 10765 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10766 10767 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10768 ins_encode %{ 10769 __ movl($dst$$Register, $src$$Address); 10770 %} 10771 ins_pipe(ialu_reg_mem); 10772%} 10773 10774instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10775%{ 10776 match(Set dst (AndL src mask)); 10777 10778 format %{ "movl $dst, $src\t# zero-extend long" %} 10779 ins_encode %{ 10780 __ movl($dst$$Register, $src$$Register); 10781 %} 10782 ins_pipe(ialu_reg_reg); 10783%} 10784 10785instruct convL2I_reg_reg(rRegI dst, rRegL src) 10786%{ 10787 match(Set dst (ConvL2I src)); 10788 10789 format %{ "movl $dst, $src\t# l2i" %} 10790 ins_encode %{ 10791 __ movl($dst$$Register, $src$$Register); 10792 %} 10793 ins_pipe(ialu_reg_reg); 10794%} 10795 10796 10797instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10798 match(Set dst (MoveF2I src)); 10799 effect(DEF dst, USE src); 10800 10801 ins_cost(125); 10802 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10803 ins_encode %{ 10804 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10805 %} 10806 ins_pipe(ialu_reg_mem); 10807%} 10808 10809instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10810 match(Set dst (MoveI2F src)); 10811 effect(DEF dst, USE src); 10812 10813 ins_cost(125); 10814 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10815 ins_encode %{ 10816 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10817 %} 10818 ins_pipe(pipe_slow); 10819%} 10820 10821instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10822 match(Set dst (MoveD2L src)); 10823 effect(DEF dst, USE src); 10824 10825 ins_cost(125); 10826 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10827 ins_encode %{ 10828 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10829 %} 10830 ins_pipe(ialu_reg_mem); 10831%} 10832 10833instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10834 predicate(!UseXmmLoadAndClearUpper); 10835 match(Set dst (MoveL2D src)); 10836 effect(DEF dst, USE src); 10837 10838 ins_cost(125); 10839 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10840 ins_encode %{ 10841 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10842 %} 10843 ins_pipe(pipe_slow); 10844%} 10845 10846instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10847 predicate(UseXmmLoadAndClearUpper); 10848 match(Set dst (MoveL2D src)); 10849 effect(DEF dst, USE src); 10850 10851 ins_cost(125); 10852 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10853 ins_encode %{ 10854 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10855 %} 10856 ins_pipe(pipe_slow); 10857%} 10858 10859 10860instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10861 match(Set dst (MoveF2I src)); 10862 effect(DEF dst, USE src); 10863 10864 ins_cost(95); // XXX 10865 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10866 ins_encode %{ 10867 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10868 %} 10869 ins_pipe(pipe_slow); 10870%} 10871 10872instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10873 match(Set dst (MoveI2F src)); 10874 effect(DEF dst, USE src); 10875 10876 ins_cost(100); 10877 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10878 ins_encode %{ 10879 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10880 %} 10881 ins_pipe( ialu_mem_reg ); 10882%} 10883 10884instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10885 match(Set dst (MoveD2L src)); 10886 effect(DEF dst, USE src); 10887 10888 ins_cost(95); // XXX 10889 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10890 ins_encode %{ 10891 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10892 %} 10893 ins_pipe(pipe_slow); 10894%} 10895 10896instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10897 match(Set dst (MoveL2D src)); 10898 effect(DEF dst, USE src); 10899 10900 ins_cost(100); 10901 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10902 ins_encode %{ 10903 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10904 %} 10905 ins_pipe(ialu_mem_reg); 10906%} 10907 10908instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10909 match(Set dst (MoveF2I src)); 10910 effect(DEF dst, USE src); 10911 ins_cost(85); 10912 format %{ "movd $dst,$src\t# MoveF2I" %} 10913 ins_encode %{ 10914 __ movdl($dst$$Register, $src$$XMMRegister); 10915 %} 10916 ins_pipe( pipe_slow ); 10917%} 10918 10919instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10920 match(Set dst (MoveD2L src)); 10921 effect(DEF dst, USE src); 10922 ins_cost(85); 10923 format %{ "movd $dst,$src\t# MoveD2L" %} 10924 ins_encode %{ 10925 __ movdq($dst$$Register, $src$$XMMRegister); 10926 %} 10927 ins_pipe( pipe_slow ); 10928%} 10929 10930instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10931 match(Set dst (MoveI2F src)); 10932 effect(DEF dst, USE src); 10933 ins_cost(100); 10934 format %{ "movd $dst,$src\t# MoveI2F" %} 10935 ins_encode %{ 10936 __ movdl($dst$$XMMRegister, $src$$Register); 10937 %} 10938 ins_pipe( pipe_slow ); 10939%} 10940 10941instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10942 match(Set dst (MoveL2D src)); 10943 effect(DEF dst, USE src); 10944 ins_cost(100); 10945 format %{ "movd $dst,$src\t# MoveL2D" %} 10946 ins_encode %{ 10947 __ movdq($dst$$XMMRegister, $src$$Register); 10948 %} 10949 ins_pipe( pipe_slow ); 10950%} 10951 10952 10953// ======================================================================= 10954// fast clearing of an array 10955instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 10956 Universe dummy, rFlagsReg cr) 10957%{ 10958 predicate(!((ClearArrayNode*)n)->is_large()); 10959 match(Set dummy (ClearArray cnt base)); 10960 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 10961 10962 format %{ $$template 10963 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10964 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10965 $$emit$$"jg LARGE\n\t" 10966 $$emit$$"dec rcx\n\t" 10967 $$emit$$"js DONE\t# Zero length\n\t" 10968 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10969 $$emit$$"dec rcx\n\t" 10970 $$emit$$"jge LOOP\n\t" 10971 $$emit$$"jmp DONE\n\t" 10972 $$emit$$"# LARGE:\n\t" 10973 if (UseFastStosb) { 10974 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10975 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10976 } else if (UseXMMForObjInit) { 10977 $$emit$$"mov rdi,rax\n\t" 10978 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10979 $$emit$$"jmpq L_zero_64_bytes\n\t" 10980 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10981 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10982 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10983 $$emit$$"add 0x40,rax\n\t" 10984 $$emit$$"# L_zero_64_bytes:\n\t" 10985 $$emit$$"sub 0x8,rcx\n\t" 10986 $$emit$$"jge L_loop\n\t" 10987 $$emit$$"add 0x4,rcx\n\t" 10988 $$emit$$"jl L_tail\n\t" 10989 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10990 $$emit$$"add 0x20,rax\n\t" 10991 $$emit$$"sub 0x4,rcx\n\t" 10992 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10993 $$emit$$"add 0x4,rcx\n\t" 10994 $$emit$$"jle L_end\n\t" 10995 $$emit$$"dec rcx\n\t" 10996 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10997 $$emit$$"vmovq xmm0,(rax)\n\t" 10998 $$emit$$"add 0x8,rax\n\t" 10999 $$emit$$"dec rcx\n\t" 11000 $$emit$$"jge L_sloop\n\t" 11001 $$emit$$"# L_end:\n\t" 11002 } else { 11003 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 11004 } 11005 $$emit$$"# DONE" 11006 %} 11007 ins_encode %{ 11008 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11009 $tmp$$XMMRegister, false); 11010 %} 11011 ins_pipe(pipe_slow); 11012%} 11013 11014instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 11015 Universe dummy, rFlagsReg cr) 11016%{ 11017 predicate(((ClearArrayNode*)n)->is_large()); 11018 match(Set dummy (ClearArray cnt base)); 11019 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 11020 11021 format %{ $$template 11022 if (UseFastStosb) { 11023 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11024 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11025 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 11026 } else if (UseXMMForObjInit) { 11027 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 11028 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 11029 $$emit$$"jmpq L_zero_64_bytes\n\t" 11030 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11031 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11032 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11033 $$emit$$"add 0x40,rax\n\t" 11034 $$emit$$"# L_zero_64_bytes:\n\t" 11035 $$emit$$"sub 0x8,rcx\n\t" 11036 $$emit$$"jge L_loop\n\t" 11037 $$emit$$"add 0x4,rcx\n\t" 11038 $$emit$$"jl L_tail\n\t" 11039 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11040 $$emit$$"add 0x20,rax\n\t" 11041 $$emit$$"sub 0x4,rcx\n\t" 11042 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11043 $$emit$$"add 0x4,rcx\n\t" 11044 $$emit$$"jle L_end\n\t" 11045 $$emit$$"dec rcx\n\t" 11046 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11047 $$emit$$"vmovq xmm0,(rax)\n\t" 11048 $$emit$$"add 0x8,rax\n\t" 11049 $$emit$$"dec rcx\n\t" 11050 $$emit$$"jge L_sloop\n\t" 11051 $$emit$$"# L_end:\n\t" 11052 } else { 11053 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11054 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11055 } 11056 %} 11057 ins_encode %{ 11058 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11059 $tmp$$XMMRegister, true); 11060 %} 11061 ins_pipe(pipe_slow); 11062%} 11063 11064instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11065 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11066%{ 11067 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11068 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11069 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11070 11071 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11072 ins_encode %{ 11073 __ string_compare($str1$$Register, $str2$$Register, 11074 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11075 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11076 %} 11077 ins_pipe( pipe_slow ); 11078%} 11079 11080instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11081 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11082%{ 11083 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11084 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11085 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11086 11087 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11088 ins_encode %{ 11089 __ string_compare($str1$$Register, $str2$$Register, 11090 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11091 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11092 %} 11093 ins_pipe( pipe_slow ); 11094%} 11095 11096instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11097 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11098%{ 11099 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11100 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11101 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11102 11103 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11104 ins_encode %{ 11105 __ string_compare($str1$$Register, $str2$$Register, 11106 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11107 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11108 %} 11109 ins_pipe( pipe_slow ); 11110%} 11111 11112instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11113 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11114%{ 11115 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11116 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11117 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11118 11119 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11120 ins_encode %{ 11121 __ string_compare($str2$$Register, $str1$$Register, 11122 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11123 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11124 %} 11125 ins_pipe( pipe_slow ); 11126%} 11127 11128// fast search of substring with known size. 11129instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11130 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11131%{ 11132 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11133 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11134 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11135 11136 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11137 ins_encode %{ 11138 int icnt2 = (int)$int_cnt2$$constant; 11139 if (icnt2 >= 16) { 11140 // IndexOf for constant substrings with size >= 16 elements 11141 // which don't need to be loaded through stack. 11142 __ string_indexofC8($str1$$Register, $str2$$Register, 11143 $cnt1$$Register, $cnt2$$Register, 11144 icnt2, $result$$Register, 11145 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11146 } else { 11147 // Small strings are loaded through stack if they cross page boundary. 11148 __ string_indexof($str1$$Register, $str2$$Register, 11149 $cnt1$$Register, $cnt2$$Register, 11150 icnt2, $result$$Register, 11151 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11152 } 11153 %} 11154 ins_pipe( pipe_slow ); 11155%} 11156 11157// fast search of substring with known size. 11158instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11159 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11160%{ 11161 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11162 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11163 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11164 11165 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11166 ins_encode %{ 11167 int icnt2 = (int)$int_cnt2$$constant; 11168 if (icnt2 >= 8) { 11169 // IndexOf for constant substrings with size >= 8 elements 11170 // which don't need to be loaded through stack. 11171 __ string_indexofC8($str1$$Register, $str2$$Register, 11172 $cnt1$$Register, $cnt2$$Register, 11173 icnt2, $result$$Register, 11174 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11175 } else { 11176 // Small strings are loaded through stack if they cross page boundary. 11177 __ string_indexof($str1$$Register, $str2$$Register, 11178 $cnt1$$Register, $cnt2$$Register, 11179 icnt2, $result$$Register, 11180 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11181 } 11182 %} 11183 ins_pipe( pipe_slow ); 11184%} 11185 11186// fast search of substring with known size. 11187instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11188 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11189%{ 11190 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11191 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11192 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11193 11194 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11195 ins_encode %{ 11196 int icnt2 = (int)$int_cnt2$$constant; 11197 if (icnt2 >= 8) { 11198 // IndexOf for constant substrings with size >= 8 elements 11199 // which don't need to be loaded through stack. 11200 __ string_indexofC8($str1$$Register, $str2$$Register, 11201 $cnt1$$Register, $cnt2$$Register, 11202 icnt2, $result$$Register, 11203 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11204 } else { 11205 // Small strings are loaded through stack if they cross page boundary. 11206 __ string_indexof($str1$$Register, $str2$$Register, 11207 $cnt1$$Register, $cnt2$$Register, 11208 icnt2, $result$$Register, 11209 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11210 } 11211 %} 11212 ins_pipe( pipe_slow ); 11213%} 11214 11215instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11216 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11217%{ 11218 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11219 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11220 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11221 11222 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11223 ins_encode %{ 11224 __ string_indexof($str1$$Register, $str2$$Register, 11225 $cnt1$$Register, $cnt2$$Register, 11226 (-1), $result$$Register, 11227 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11228 %} 11229 ins_pipe( pipe_slow ); 11230%} 11231 11232instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11233 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11234%{ 11235 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11236 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11237 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11238 11239 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11240 ins_encode %{ 11241 __ string_indexof($str1$$Register, $str2$$Register, 11242 $cnt1$$Register, $cnt2$$Register, 11243 (-1), $result$$Register, 11244 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11245 %} 11246 ins_pipe( pipe_slow ); 11247%} 11248 11249instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11250 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11251%{ 11252 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11253 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11254 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11255 11256 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11257 ins_encode %{ 11258 __ string_indexof($str1$$Register, $str2$$Register, 11259 $cnt1$$Register, $cnt2$$Register, 11260 (-1), $result$$Register, 11261 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11262 %} 11263 ins_pipe( pipe_slow ); 11264%} 11265 11266instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11267 rbx_RegI result, legVecS vec1, legVecS vec2, legVecS vec3, rcx_RegI tmp, rFlagsReg cr) 11268%{ 11269 predicate(UseSSE42Intrinsics); 11270 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11271 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11272 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11273 ins_encode %{ 11274 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11275 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11276 %} 11277 ins_pipe( pipe_slow ); 11278%} 11279 11280// fast string equals 11281instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11282 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11283%{ 11284 match(Set result (StrEquals (Binary str1 str2) cnt)); 11285 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11286 11287 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11288 ins_encode %{ 11289 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11290 $cnt$$Register, $result$$Register, $tmp3$$Register, 11291 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11292 %} 11293 ins_pipe( pipe_slow ); 11294%} 11295 11296// fast array equals 11297instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11298 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11299%{ 11300 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11301 match(Set result (AryEq ary1 ary2)); 11302 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11303 11304 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11305 ins_encode %{ 11306 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11307 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11308 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11309 %} 11310 ins_pipe( pipe_slow ); 11311%} 11312 11313instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11314 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11315%{ 11316 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11317 match(Set result (AryEq ary1 ary2)); 11318 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11319 11320 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11321 ins_encode %{ 11322 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11323 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11324 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11325 %} 11326 ins_pipe( pipe_slow ); 11327%} 11328 11329instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11330 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11331%{ 11332 match(Set result (HasNegatives ary1 len)); 11333 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11334 11335 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11336 ins_encode %{ 11337 __ has_negatives($ary1$$Register, $len$$Register, 11338 $result$$Register, $tmp3$$Register, 11339 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11340 %} 11341 ins_pipe( pipe_slow ); 11342%} 11343 11344// fast char[] to byte[] compression 11345instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11346 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11347 match(Set result (StrCompressedCopy src (Binary dst len))); 11348 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11349 11350 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11351 ins_encode %{ 11352 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11353 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11354 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11355 %} 11356 ins_pipe( pipe_slow ); 11357%} 11358 11359// fast byte[] to char[] inflation 11360instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11361 legVecS tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11362 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11363 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11364 11365 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11366 ins_encode %{ 11367 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11368 $tmp1$$XMMRegister, $tmp2$$Register); 11369 %} 11370 ins_pipe( pipe_slow ); 11371%} 11372 11373// encode char[] to byte[] in ISO_8859_1 11374instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11375 legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11376 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11377 match(Set result (EncodeISOArray src (Binary dst len))); 11378 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11379 11380 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11381 ins_encode %{ 11382 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11383 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11384 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11385 %} 11386 ins_pipe( pipe_slow ); 11387%} 11388 11389//----------Overflow Math Instructions----------------------------------------- 11390 11391instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11392%{ 11393 match(Set cr (OverflowAddI op1 op2)); 11394 effect(DEF cr, USE_KILL op1, USE op2); 11395 11396 format %{ "addl $op1, $op2\t# overflow check int" %} 11397 11398 ins_encode %{ 11399 __ addl($op1$$Register, $op2$$Register); 11400 %} 11401 ins_pipe(ialu_reg_reg); 11402%} 11403 11404instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11405%{ 11406 match(Set cr (OverflowAddI op1 op2)); 11407 effect(DEF cr, USE_KILL op1, USE op2); 11408 11409 format %{ "addl $op1, $op2\t# overflow check int" %} 11410 11411 ins_encode %{ 11412 __ addl($op1$$Register, $op2$$constant); 11413 %} 11414 ins_pipe(ialu_reg_reg); 11415%} 11416 11417instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11418%{ 11419 match(Set cr (OverflowAddL op1 op2)); 11420 effect(DEF cr, USE_KILL op1, USE op2); 11421 11422 format %{ "addq $op1, $op2\t# overflow check long" %} 11423 ins_encode %{ 11424 __ addq($op1$$Register, $op2$$Register); 11425 %} 11426 ins_pipe(ialu_reg_reg); 11427%} 11428 11429instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11430%{ 11431 match(Set cr (OverflowAddL op1 op2)); 11432 effect(DEF cr, USE_KILL op1, USE op2); 11433 11434 format %{ "addq $op1, $op2\t# overflow check long" %} 11435 ins_encode %{ 11436 __ addq($op1$$Register, $op2$$constant); 11437 %} 11438 ins_pipe(ialu_reg_reg); 11439%} 11440 11441instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11442%{ 11443 match(Set cr (OverflowSubI op1 op2)); 11444 11445 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11446 ins_encode %{ 11447 __ cmpl($op1$$Register, $op2$$Register); 11448 %} 11449 ins_pipe(ialu_reg_reg); 11450%} 11451 11452instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11453%{ 11454 match(Set cr (OverflowSubI op1 op2)); 11455 11456 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11457 ins_encode %{ 11458 __ cmpl($op1$$Register, $op2$$constant); 11459 %} 11460 ins_pipe(ialu_reg_reg); 11461%} 11462 11463instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11464%{ 11465 match(Set cr (OverflowSubL op1 op2)); 11466 11467 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11468 ins_encode %{ 11469 __ cmpq($op1$$Register, $op2$$Register); 11470 %} 11471 ins_pipe(ialu_reg_reg); 11472%} 11473 11474instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11475%{ 11476 match(Set cr (OverflowSubL op1 op2)); 11477 11478 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11479 ins_encode %{ 11480 __ cmpq($op1$$Register, $op2$$constant); 11481 %} 11482 ins_pipe(ialu_reg_reg); 11483%} 11484 11485instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11486%{ 11487 match(Set cr (OverflowSubI zero op2)); 11488 effect(DEF cr, USE_KILL op2); 11489 11490 format %{ "negl $op2\t# overflow check int" %} 11491 ins_encode %{ 11492 __ negl($op2$$Register); 11493 %} 11494 ins_pipe(ialu_reg_reg); 11495%} 11496 11497instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11498%{ 11499 match(Set cr (OverflowSubL zero op2)); 11500 effect(DEF cr, USE_KILL op2); 11501 11502 format %{ "negq $op2\t# overflow check long" %} 11503 ins_encode %{ 11504 __ negq($op2$$Register); 11505 %} 11506 ins_pipe(ialu_reg_reg); 11507%} 11508 11509instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11510%{ 11511 match(Set cr (OverflowMulI op1 op2)); 11512 effect(DEF cr, USE_KILL op1, USE op2); 11513 11514 format %{ "imull $op1, $op2\t# overflow check int" %} 11515 ins_encode %{ 11516 __ imull($op1$$Register, $op2$$Register); 11517 %} 11518 ins_pipe(ialu_reg_reg_alu0); 11519%} 11520 11521instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11522%{ 11523 match(Set cr (OverflowMulI op1 op2)); 11524 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11525 11526 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11527 ins_encode %{ 11528 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11529 %} 11530 ins_pipe(ialu_reg_reg_alu0); 11531%} 11532 11533instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11534%{ 11535 match(Set cr (OverflowMulL op1 op2)); 11536 effect(DEF cr, USE_KILL op1, USE op2); 11537 11538 format %{ "imulq $op1, $op2\t# overflow check long" %} 11539 ins_encode %{ 11540 __ imulq($op1$$Register, $op2$$Register); 11541 %} 11542 ins_pipe(ialu_reg_reg_alu0); 11543%} 11544 11545instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11546%{ 11547 match(Set cr (OverflowMulL op1 op2)); 11548 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11549 11550 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11551 ins_encode %{ 11552 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11553 %} 11554 ins_pipe(ialu_reg_reg_alu0); 11555%} 11556 11557 11558//----------Control Flow Instructions------------------------------------------ 11559// Signed compare Instructions 11560 11561// XXX more variants!! 11562instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11563%{ 11564 match(Set cr (CmpI op1 op2)); 11565 effect(DEF cr, USE op1, USE op2); 11566 11567 format %{ "cmpl $op1, $op2" %} 11568 opcode(0x3B); /* Opcode 3B /r */ 11569 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11570 ins_pipe(ialu_cr_reg_reg); 11571%} 11572 11573instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11574%{ 11575 match(Set cr (CmpI op1 op2)); 11576 11577 format %{ "cmpl $op1, $op2" %} 11578 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11579 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11580 ins_pipe(ialu_cr_reg_imm); 11581%} 11582 11583instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11584%{ 11585 match(Set cr (CmpI op1 (LoadI op2))); 11586 11587 ins_cost(500); // XXX 11588 format %{ "cmpl $op1, $op2" %} 11589 opcode(0x3B); /* Opcode 3B /r */ 11590 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11591 ins_pipe(ialu_cr_reg_mem); 11592%} 11593 11594instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11595%{ 11596 match(Set cr (CmpI src zero)); 11597 11598 format %{ "testl $src, $src" %} 11599 opcode(0x85); 11600 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11601 ins_pipe(ialu_cr_reg_imm); 11602%} 11603 11604instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11605%{ 11606 match(Set cr (CmpI (AndI src con) zero)); 11607 11608 format %{ "testl $src, $con" %} 11609 opcode(0xF7, 0x00); 11610 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11611 ins_pipe(ialu_cr_reg_imm); 11612%} 11613 11614instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11615%{ 11616 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11617 11618 format %{ "testl $src, $mem" %} 11619 opcode(0x85); 11620 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11621 ins_pipe(ialu_cr_reg_mem); 11622%} 11623 11624// Unsigned compare Instructions; really, same as signed except they 11625// produce an rFlagsRegU instead of rFlagsReg. 11626instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11627%{ 11628 match(Set cr (CmpU op1 op2)); 11629 11630 format %{ "cmpl $op1, $op2\t# unsigned" %} 11631 opcode(0x3B); /* Opcode 3B /r */ 11632 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11633 ins_pipe(ialu_cr_reg_reg); 11634%} 11635 11636instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11637%{ 11638 match(Set cr (CmpU op1 op2)); 11639 11640 format %{ "cmpl $op1, $op2\t# unsigned" %} 11641 opcode(0x81,0x07); /* Opcode 81 /7 */ 11642 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11643 ins_pipe(ialu_cr_reg_imm); 11644%} 11645 11646instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11647%{ 11648 match(Set cr (CmpU op1 (LoadI op2))); 11649 11650 ins_cost(500); // XXX 11651 format %{ "cmpl $op1, $op2\t# unsigned" %} 11652 opcode(0x3B); /* Opcode 3B /r */ 11653 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11654 ins_pipe(ialu_cr_reg_mem); 11655%} 11656 11657// // // Cisc-spilled version of cmpU_rReg 11658// //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11659// //%{ 11660// // match(Set cr (CmpU (LoadI op1) op2)); 11661// // 11662// // format %{ "CMPu $op1,$op2" %} 11663// // ins_cost(500); 11664// // opcode(0x39); /* Opcode 39 /r */ 11665// // ins_encode( OpcP, reg_mem( op1, op2) ); 11666// //%} 11667 11668instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11669%{ 11670 match(Set cr (CmpU src zero)); 11671 11672 format %{ "testl $src, $src\t# unsigned" %} 11673 opcode(0x85); 11674 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11675 ins_pipe(ialu_cr_reg_imm); 11676%} 11677 11678instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11679%{ 11680 match(Set cr (CmpP op1 op2)); 11681 11682 format %{ "cmpq $op1, $op2\t# ptr" %} 11683 opcode(0x3B); /* Opcode 3B /r */ 11684 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11685 ins_pipe(ialu_cr_reg_reg); 11686%} 11687 11688instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11689%{ 11690 match(Set cr (CmpP op1 (LoadP op2))); 11691 11692 ins_cost(500); // XXX 11693 format %{ "cmpq $op1, $op2\t# ptr" %} 11694 opcode(0x3B); /* Opcode 3B /r */ 11695 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11696 ins_pipe(ialu_cr_reg_mem); 11697%} 11698 11699// // // Cisc-spilled version of cmpP_rReg 11700// //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11701// //%{ 11702// // match(Set cr (CmpP (LoadP op1) op2)); 11703// // 11704// // format %{ "CMPu $op1,$op2" %} 11705// // ins_cost(500); 11706// // opcode(0x39); /* Opcode 39 /r */ 11707// // ins_encode( OpcP, reg_mem( op1, op2) ); 11708// //%} 11709 11710// XXX this is generalized by compP_rReg_mem??? 11711// Compare raw pointer (used in out-of-heap check). 11712// Only works because non-oop pointers must be raw pointers 11713// and raw pointers have no anti-dependencies. 11714instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11715%{ 11716 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11717 match(Set cr (CmpP op1 (LoadP op2))); 11718 11719 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11720 opcode(0x3B); /* Opcode 3B /r */ 11721 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11722 ins_pipe(ialu_cr_reg_mem); 11723%} 11724 11725// This will generate a signed flags result. This should be OK since 11726// any compare to a zero should be eq/neq. 11727instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11728%{ 11729 match(Set cr (CmpP src zero)); 11730 11731 format %{ "testq $src, $src\t# ptr" %} 11732 opcode(0x85); 11733 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11734 ins_pipe(ialu_cr_reg_imm); 11735%} 11736 11737// This will generate a signed flags result. This should be OK since 11738// any compare to a zero should be eq/neq. 11739instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11740%{ 11741 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11742 match(Set cr (CmpP (LoadP op) zero)); 11743 11744 ins_cost(500); // XXX 11745 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11746 opcode(0xF7); /* Opcode F7 /0 */ 11747 ins_encode(REX_mem_wide(op), 11748 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11749 ins_pipe(ialu_cr_reg_imm); 11750%} 11751 11752instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11753%{ 11754 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 11755 match(Set cr (CmpP (LoadP mem) zero)); 11756 11757 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11758 ins_encode %{ 11759 __ cmpq(r12, $mem$$Address); 11760 %} 11761 ins_pipe(ialu_cr_reg_mem); 11762%} 11763 11764instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11765%{ 11766 match(Set cr (CmpN op1 op2)); 11767 11768 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11769 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11770 ins_pipe(ialu_cr_reg_reg); 11771%} 11772 11773instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11774%{ 11775 match(Set cr (CmpN src (LoadN mem))); 11776 11777 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11778 ins_encode %{ 11779 __ cmpl($src$$Register, $mem$$Address); 11780 %} 11781 ins_pipe(ialu_cr_reg_mem); 11782%} 11783 11784instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11785 match(Set cr (CmpN op1 op2)); 11786 11787 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11788 ins_encode %{ 11789 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11790 %} 11791 ins_pipe(ialu_cr_reg_imm); 11792%} 11793 11794instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11795%{ 11796 match(Set cr (CmpN src (LoadN mem))); 11797 11798 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11799 ins_encode %{ 11800 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11801 %} 11802 ins_pipe(ialu_cr_reg_mem); 11803%} 11804 11805instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11806 match(Set cr (CmpN op1 op2)); 11807 11808 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11809 ins_encode %{ 11810 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11811 %} 11812 ins_pipe(ialu_cr_reg_imm); 11813%} 11814 11815instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11816%{ 11817 match(Set cr (CmpN src (LoadNKlass mem))); 11818 11819 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11820 ins_encode %{ 11821 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11822 %} 11823 ins_pipe(ialu_cr_reg_mem); 11824%} 11825 11826instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11827 match(Set cr (CmpN src zero)); 11828 11829 format %{ "testl $src, $src\t# compressed ptr" %} 11830 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11831 ins_pipe(ialu_cr_reg_imm); 11832%} 11833 11834instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11835%{ 11836 predicate(Universe::narrow_oop_base() != NULL); 11837 match(Set cr (CmpN (LoadN mem) zero)); 11838 11839 ins_cost(500); // XXX 11840 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11841 ins_encode %{ 11842 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11843 %} 11844 ins_pipe(ialu_cr_reg_mem); 11845%} 11846 11847instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11848%{ 11849 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 11850 match(Set cr (CmpN (LoadN mem) zero)); 11851 11852 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11853 ins_encode %{ 11854 __ cmpl(r12, $mem$$Address); 11855 %} 11856 ins_pipe(ialu_cr_reg_mem); 11857%} 11858 11859// Yanked all unsigned pointer compare operations. 11860// Pointer compares are done with CmpP which is already unsigned. 11861 11862instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11863%{ 11864 match(Set cr (CmpL op1 op2)); 11865 11866 format %{ "cmpq $op1, $op2" %} 11867 opcode(0x3B); /* Opcode 3B /r */ 11868 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11869 ins_pipe(ialu_cr_reg_reg); 11870%} 11871 11872instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11873%{ 11874 match(Set cr (CmpL op1 op2)); 11875 11876 format %{ "cmpq $op1, $op2" %} 11877 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11878 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11879 ins_pipe(ialu_cr_reg_imm); 11880%} 11881 11882instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11883%{ 11884 match(Set cr (CmpL op1 (LoadL op2))); 11885 11886 format %{ "cmpq $op1, $op2" %} 11887 opcode(0x3B); /* Opcode 3B /r */ 11888 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11889 ins_pipe(ialu_cr_reg_mem); 11890%} 11891 11892instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11893%{ 11894 match(Set cr (CmpL src zero)); 11895 11896 format %{ "testq $src, $src" %} 11897 opcode(0x85); 11898 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11899 ins_pipe(ialu_cr_reg_imm); 11900%} 11901 11902instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11903%{ 11904 match(Set cr (CmpL (AndL src con) zero)); 11905 11906 format %{ "testq $src, $con\t# long" %} 11907 opcode(0xF7, 0x00); 11908 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11909 ins_pipe(ialu_cr_reg_imm); 11910%} 11911 11912instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11913%{ 11914 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11915 11916 format %{ "testq $src, $mem" %} 11917 opcode(0x85); 11918 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11919 ins_pipe(ialu_cr_reg_mem); 11920%} 11921 11922instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 11923%{ 11924 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 11925 11926 format %{ "testq $src, $mem" %} 11927 opcode(0x85); 11928 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11929 ins_pipe(ialu_cr_reg_mem); 11930%} 11931 11932// Manifest a CmpL result in an integer register. Very painful. 11933// This is the test to avoid. 11934instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11935%{ 11936 match(Set dst (CmpL3 src1 src2)); 11937 effect(KILL flags); 11938 11939 ins_cost(275); // XXX 11940 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11941 "movl $dst, -1\n\t" 11942 "jl,s done\n\t" 11943 "setne $dst\n\t" 11944 "movzbl $dst, $dst\n\t" 11945 "done:" %} 11946 ins_encode(cmpl3_flag(src1, src2, dst)); 11947 ins_pipe(pipe_slow); 11948%} 11949 11950// Unsigned long compare Instructions; really, same as signed long except they 11951// produce an rFlagsRegU instead of rFlagsReg. 11952instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 11953%{ 11954 match(Set cr (CmpUL op1 op2)); 11955 11956 format %{ "cmpq $op1, $op2\t# unsigned" %} 11957 opcode(0x3B); /* Opcode 3B /r */ 11958 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11959 ins_pipe(ialu_cr_reg_reg); 11960%} 11961 11962instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 11963%{ 11964 match(Set cr (CmpUL op1 op2)); 11965 11966 format %{ "cmpq $op1, $op2\t# unsigned" %} 11967 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11968 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11969 ins_pipe(ialu_cr_reg_imm); 11970%} 11971 11972instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 11973%{ 11974 match(Set cr (CmpUL op1 (LoadL op2))); 11975 11976 format %{ "cmpq $op1, $op2\t# unsigned" %} 11977 opcode(0x3B); /* Opcode 3B /r */ 11978 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11979 ins_pipe(ialu_cr_reg_mem); 11980%} 11981 11982instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 11983%{ 11984 match(Set cr (CmpUL src zero)); 11985 11986 format %{ "testq $src, $src\t# unsigned" %} 11987 opcode(0x85); 11988 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11989 ins_pipe(ialu_cr_reg_imm); 11990%} 11991 11992instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 11993%{ 11994 match(Set cr (CmpI (LoadB mem) imm)); 11995 11996 ins_cost(125); 11997 format %{ "cmpb $mem, $imm" %} 11998 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 11999 ins_pipe(ialu_cr_reg_mem); 12000%} 12001 12002instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU8 imm, immI0 zero) 12003%{ 12004 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 12005 12006 ins_cost(125); 12007 format %{ "testb $mem, $imm\t# ubyte" %} 12008 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12009 ins_pipe(ialu_cr_reg_mem); 12010%} 12011 12012instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 12013%{ 12014 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12015 12016 ins_cost(125); 12017 format %{ "testb $mem, $imm\t# byte" %} 12018 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12019 ins_pipe(ialu_cr_reg_mem); 12020%} 12021 12022//----------Max and Min-------------------------------------------------------- 12023// Min Instructions 12024 12025instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12026%{ 12027 effect(USE_DEF dst, USE src, USE cr); 12028 12029 format %{ "cmovlgt $dst, $src\t# min" %} 12030 opcode(0x0F, 0x4F); 12031 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12032 ins_pipe(pipe_cmov_reg); 12033%} 12034 12035 12036instruct minI_rReg(rRegI dst, rRegI src) 12037%{ 12038 match(Set dst (MinI dst src)); 12039 12040 ins_cost(200); 12041 expand %{ 12042 rFlagsReg cr; 12043 compI_rReg(cr, dst, src); 12044 cmovI_reg_g(dst, src, cr); 12045 %} 12046%} 12047 12048instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12049%{ 12050 effect(USE_DEF dst, USE src, USE cr); 12051 12052 format %{ "cmovllt $dst, $src\t# max" %} 12053 opcode(0x0F, 0x4C); 12054 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12055 ins_pipe(pipe_cmov_reg); 12056%} 12057 12058 12059instruct maxI_rReg(rRegI dst, rRegI src) 12060%{ 12061 match(Set dst (MaxI dst src)); 12062 12063 ins_cost(200); 12064 expand %{ 12065 rFlagsReg cr; 12066 compI_rReg(cr, dst, src); 12067 cmovI_reg_l(dst, src, cr); 12068 %} 12069%} 12070 12071// ============================================================================ 12072// Branch Instructions 12073 12074// Jump Direct - Label defines a relative address from JMP+1 12075instruct jmpDir(label labl) 12076%{ 12077 match(Goto); 12078 effect(USE labl); 12079 12080 ins_cost(300); 12081 format %{ "jmp $labl" %} 12082 size(5); 12083 ins_encode %{ 12084 Label* L = $labl$$label; 12085 __ jmp(*L, false); // Always long jump 12086 %} 12087 ins_pipe(pipe_jmp); 12088%} 12089 12090// Jump Direct Conditional - Label defines a relative address from Jcc+1 12091instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12092%{ 12093 match(If cop cr); 12094 effect(USE labl); 12095 12096 ins_cost(300); 12097 format %{ "j$cop $labl" %} 12098 size(6); 12099 ins_encode %{ 12100 Label* L = $labl$$label; 12101 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12102 %} 12103 ins_pipe(pipe_jcc); 12104%} 12105 12106// Jump Direct Conditional - Label defines a relative address from Jcc+1 12107instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12108%{ 12109 predicate(!n->has_vector_mask_set()); 12110 match(CountedLoopEnd cop cr); 12111 effect(USE labl); 12112 12113 ins_cost(300); 12114 format %{ "j$cop $labl\t# loop end" %} 12115 size(6); 12116 ins_encode %{ 12117 Label* L = $labl$$label; 12118 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12119 %} 12120 ins_pipe(pipe_jcc); 12121%} 12122 12123// Jump Direct Conditional - Label defines a relative address from Jcc+1 12124instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12125 predicate(!n->has_vector_mask_set()); 12126 match(CountedLoopEnd cop cmp); 12127 effect(USE labl); 12128 12129 ins_cost(300); 12130 format %{ "j$cop,u $labl\t# loop end" %} 12131 size(6); 12132 ins_encode %{ 12133 Label* L = $labl$$label; 12134 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12135 %} 12136 ins_pipe(pipe_jcc); 12137%} 12138 12139instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12140 predicate(!n->has_vector_mask_set()); 12141 match(CountedLoopEnd cop cmp); 12142 effect(USE labl); 12143 12144 ins_cost(200); 12145 format %{ "j$cop,u $labl\t# loop end" %} 12146 size(6); 12147 ins_encode %{ 12148 Label* L = $labl$$label; 12149 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12150 %} 12151 ins_pipe(pipe_jcc); 12152%} 12153 12154// mask version 12155// Jump Direct Conditional - Label defines a relative address from Jcc+1 12156instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12157%{ 12158 predicate(n->has_vector_mask_set()); 12159 match(CountedLoopEnd cop cr); 12160 effect(USE labl); 12161 12162 ins_cost(400); 12163 format %{ "j$cop $labl\t# loop end\n\t" 12164 "restorevectmask \t# vector mask restore for loops" %} 12165 size(10); 12166 ins_encode %{ 12167 Label* L = $labl$$label; 12168 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12169 __ restorevectmask(); 12170 %} 12171 ins_pipe(pipe_jcc); 12172%} 12173 12174// Jump Direct Conditional - Label defines a relative address from Jcc+1 12175instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12176 predicate(n->has_vector_mask_set()); 12177 match(CountedLoopEnd cop cmp); 12178 effect(USE labl); 12179 12180 ins_cost(400); 12181 format %{ "j$cop,u $labl\t# loop end\n\t" 12182 "restorevectmask \t# vector mask restore for loops" %} 12183 size(10); 12184 ins_encode %{ 12185 Label* L = $labl$$label; 12186 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12187 __ restorevectmask(); 12188 %} 12189 ins_pipe(pipe_jcc); 12190%} 12191 12192instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12193 predicate(n->has_vector_mask_set()); 12194 match(CountedLoopEnd cop cmp); 12195 effect(USE labl); 12196 12197 ins_cost(300); 12198 format %{ "j$cop,u $labl\t# loop end\n\t" 12199 "restorevectmask \t# vector mask restore for loops" %} 12200 size(10); 12201 ins_encode %{ 12202 Label* L = $labl$$label; 12203 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12204 __ restorevectmask(); 12205 %} 12206 ins_pipe(pipe_jcc); 12207%} 12208 12209// Jump Direct Conditional - using unsigned comparison 12210instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12211 match(If cop cmp); 12212 effect(USE labl); 12213 12214 ins_cost(300); 12215 format %{ "j$cop,u $labl" %} 12216 size(6); 12217 ins_encode %{ 12218 Label* L = $labl$$label; 12219 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12220 %} 12221 ins_pipe(pipe_jcc); 12222%} 12223 12224instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12225 match(If cop cmp); 12226 effect(USE labl); 12227 12228 ins_cost(200); 12229 format %{ "j$cop,u $labl" %} 12230 size(6); 12231 ins_encode %{ 12232 Label* L = $labl$$label; 12233 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12234 %} 12235 ins_pipe(pipe_jcc); 12236%} 12237 12238instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12239 match(If cop cmp); 12240 effect(USE labl); 12241 12242 ins_cost(200); 12243 format %{ $$template 12244 if ($cop$$cmpcode == Assembler::notEqual) { 12245 $$emit$$"jp,u $labl\n\t" 12246 $$emit$$"j$cop,u $labl" 12247 } else { 12248 $$emit$$"jp,u done\n\t" 12249 $$emit$$"j$cop,u $labl\n\t" 12250 $$emit$$"done:" 12251 } 12252 %} 12253 ins_encode %{ 12254 Label* l = $labl$$label; 12255 if ($cop$$cmpcode == Assembler::notEqual) { 12256 __ jcc(Assembler::parity, *l, false); 12257 __ jcc(Assembler::notEqual, *l, false); 12258 } else if ($cop$$cmpcode == Assembler::equal) { 12259 Label done; 12260 __ jccb(Assembler::parity, done); 12261 __ jcc(Assembler::equal, *l, false); 12262 __ bind(done); 12263 } else { 12264 ShouldNotReachHere(); 12265 } 12266 %} 12267 ins_pipe(pipe_jcc); 12268%} 12269 12270// ============================================================================ 12271// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12272// superklass array for an instance of the superklass. Set a hidden 12273// internal cache on a hit (cache is checked with exposed code in 12274// gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12275// encoding ALSO sets flags. 12276 12277instruct partialSubtypeCheck(rdi_RegP result, 12278 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12279 rFlagsReg cr) 12280%{ 12281 match(Set result (PartialSubtypeCheck sub super)); 12282 effect(KILL rcx, KILL cr); 12283 12284 ins_cost(1100); // slightly larger than the next version 12285 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12286 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12287 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12288 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12289 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12290 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12291 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12292 "miss:\t" %} 12293 12294 opcode(0x1); // Force a XOR of RDI 12295 ins_encode(enc_PartialSubtypeCheck()); 12296 ins_pipe(pipe_slow); 12297%} 12298 12299instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12300 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12301 immP0 zero, 12302 rdi_RegP result) 12303%{ 12304 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12305 effect(KILL rcx, KILL result); 12306 12307 ins_cost(1000); 12308 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12309 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12310 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12311 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12312 "jne,s miss\t\t# Missed: flags nz\n\t" 12313 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12314 "miss:\t" %} 12315 12316 opcode(0x0); // No need to XOR RDI 12317 ins_encode(enc_PartialSubtypeCheck()); 12318 ins_pipe(pipe_slow); 12319%} 12320 12321// ============================================================================ 12322// Branch Instructions -- short offset versions 12323// 12324// These instructions are used to replace jumps of a long offset (the default 12325// match) with jumps of a shorter offset. These instructions are all tagged 12326// with the ins_short_branch attribute, which causes the ADLC to suppress the 12327// match rules in general matching. Instead, the ADLC generates a conversion 12328// method in the MachNode which can be used to do in-place replacement of the 12329// long variant with the shorter variant. The compiler will determine if a 12330// branch can be taken by the is_short_branch_offset() predicate in the machine 12331// specific code section of the file. 12332 12333// Jump Direct - Label defines a relative address from JMP+1 12334instruct jmpDir_short(label labl) %{ 12335 match(Goto); 12336 effect(USE labl); 12337 12338 ins_cost(300); 12339 format %{ "jmp,s $labl" %} 12340 size(2); 12341 ins_encode %{ 12342 Label* L = $labl$$label; 12343 __ jmpb(*L); 12344 %} 12345 ins_pipe(pipe_jmp); 12346 ins_short_branch(1); 12347%} 12348 12349// Jump Direct Conditional - Label defines a relative address from Jcc+1 12350instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12351 match(If cop cr); 12352 effect(USE labl); 12353 12354 ins_cost(300); 12355 format %{ "j$cop,s $labl" %} 12356 size(2); 12357 ins_encode %{ 12358 Label* L = $labl$$label; 12359 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12360 %} 12361 ins_pipe(pipe_jcc); 12362 ins_short_branch(1); 12363%} 12364 12365// Jump Direct Conditional - Label defines a relative address from Jcc+1 12366instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12367 match(CountedLoopEnd cop cr); 12368 effect(USE labl); 12369 12370 ins_cost(300); 12371 format %{ "j$cop,s $labl\t# loop end" %} 12372 size(2); 12373 ins_encode %{ 12374 Label* L = $labl$$label; 12375 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12376 %} 12377 ins_pipe(pipe_jcc); 12378 ins_short_branch(1); 12379%} 12380 12381// Jump Direct Conditional - Label defines a relative address from Jcc+1 12382instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12383 match(CountedLoopEnd cop cmp); 12384 effect(USE labl); 12385 12386 ins_cost(300); 12387 format %{ "j$cop,us $labl\t# loop end" %} 12388 size(2); 12389 ins_encode %{ 12390 Label* L = $labl$$label; 12391 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12392 %} 12393 ins_pipe(pipe_jcc); 12394 ins_short_branch(1); 12395%} 12396 12397instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12398 match(CountedLoopEnd cop cmp); 12399 effect(USE labl); 12400 12401 ins_cost(300); 12402 format %{ "j$cop,us $labl\t# loop end" %} 12403 size(2); 12404 ins_encode %{ 12405 Label* L = $labl$$label; 12406 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12407 %} 12408 ins_pipe(pipe_jcc); 12409 ins_short_branch(1); 12410%} 12411 12412// Jump Direct Conditional - using unsigned comparison 12413instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12414 match(If cop cmp); 12415 effect(USE labl); 12416 12417 ins_cost(300); 12418 format %{ "j$cop,us $labl" %} 12419 size(2); 12420 ins_encode %{ 12421 Label* L = $labl$$label; 12422 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12423 %} 12424 ins_pipe(pipe_jcc); 12425 ins_short_branch(1); 12426%} 12427 12428instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12429 match(If cop cmp); 12430 effect(USE labl); 12431 12432 ins_cost(300); 12433 format %{ "j$cop,us $labl" %} 12434 size(2); 12435 ins_encode %{ 12436 Label* L = $labl$$label; 12437 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12438 %} 12439 ins_pipe(pipe_jcc); 12440 ins_short_branch(1); 12441%} 12442 12443instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12444 match(If cop cmp); 12445 effect(USE labl); 12446 12447 ins_cost(300); 12448 format %{ $$template 12449 if ($cop$$cmpcode == Assembler::notEqual) { 12450 $$emit$$"jp,u,s $labl\n\t" 12451 $$emit$$"j$cop,u,s $labl" 12452 } else { 12453 $$emit$$"jp,u,s done\n\t" 12454 $$emit$$"j$cop,u,s $labl\n\t" 12455 $$emit$$"done:" 12456 } 12457 %} 12458 size(4); 12459 ins_encode %{ 12460 Label* l = $labl$$label; 12461 if ($cop$$cmpcode == Assembler::notEqual) { 12462 __ jccb(Assembler::parity, *l); 12463 __ jccb(Assembler::notEqual, *l); 12464 } else if ($cop$$cmpcode == Assembler::equal) { 12465 Label done; 12466 __ jccb(Assembler::parity, done); 12467 __ jccb(Assembler::equal, *l); 12468 __ bind(done); 12469 } else { 12470 ShouldNotReachHere(); 12471 } 12472 %} 12473 ins_pipe(pipe_jcc); 12474 ins_short_branch(1); 12475%} 12476 12477// ============================================================================ 12478// inlined locking and unlocking 12479 12480instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12481 predicate(Compile::current()->use_rtm()); 12482 match(Set cr (FastLock object box)); 12483 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12484 ins_cost(300); 12485 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12486 ins_encode %{ 12487 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12488 $scr$$Register, $cx1$$Register, $cx2$$Register, 12489 _counters, _rtm_counters, _stack_rtm_counters, 12490 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12491 true, ra_->C->profile_rtm()); 12492 %} 12493 ins_pipe(pipe_slow); 12494%} 12495 12496instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12497 predicate(!Compile::current()->use_rtm()); 12498 match(Set cr (FastLock object box)); 12499 effect(TEMP tmp, TEMP scr, USE_KILL box); 12500 ins_cost(300); 12501 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12502 ins_encode %{ 12503 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12504 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12505 %} 12506 ins_pipe(pipe_slow); 12507%} 12508 12509instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12510 match(Set cr (FastUnlock object box)); 12511 effect(TEMP tmp, USE_KILL box); 12512 ins_cost(300); 12513 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12514 ins_encode %{ 12515 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12516 %} 12517 ins_pipe(pipe_slow); 12518%} 12519 12520 12521// ============================================================================ 12522// Safepoint Instructions 12523instruct safePoint_poll(rFlagsReg cr) 12524%{ 12525 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12526 match(SafePoint); 12527 effect(KILL cr); 12528 12529 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12530 "# Safepoint: poll for GC" %} 12531 ins_cost(125); 12532 ins_encode %{ 12533 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12534 __ testl(rax, addr); 12535 %} 12536 ins_pipe(ialu_reg_mem); 12537%} 12538 12539instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12540%{ 12541 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12542 match(SafePoint poll); 12543 effect(KILL cr, USE poll); 12544 12545 format %{ "testl rax, [$poll]\t" 12546 "# Safepoint: poll for GC" %} 12547 ins_cost(125); 12548 ins_encode %{ 12549 __ relocate(relocInfo::poll_type); 12550 __ testl(rax, Address($poll$$Register, 0)); 12551 %} 12552 ins_pipe(ialu_reg_mem); 12553%} 12554 12555instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12556%{ 12557 predicate(SafepointMechanism::uses_thread_local_poll()); 12558 match(SafePoint poll); 12559 effect(KILL cr, USE poll); 12560 12561 format %{ "testl rax, [$poll]\t" 12562 "# Safepoint: poll for GC" %} 12563 ins_cost(125); 12564 size(4); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12565 ins_encode %{ 12566 __ relocate(relocInfo::poll_type); 12567 address pre_pc = __ pc(); 12568 __ testl(rax, Address($poll$$Register, 0)); 12569 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12570 %} 12571 ins_pipe(ialu_reg_mem); 12572%} 12573 12574// ============================================================================ 12575// Procedure Call/Return Instructions 12576// Call Java Static Instruction 12577// Note: If this code changes, the corresponding ret_addr_offset() and 12578// compute_padding() functions will have to be adjusted. 12579instruct CallStaticJavaDirect(method meth) %{ 12580 match(CallStaticJava); 12581 effect(USE meth); 12582 12583 ins_cost(300); 12584 format %{ "call,static " %} 12585 opcode(0xE8); /* E8 cd */ 12586 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12587 ins_pipe(pipe_slow); 12588 ins_alignment(4); 12589%} 12590 12591// Call Java Dynamic Instruction 12592// Note: If this code changes, the corresponding ret_addr_offset() and 12593// compute_padding() functions will have to be adjusted. 12594instruct CallDynamicJavaDirect(method meth) 12595%{ 12596 match(CallDynamicJava); 12597 effect(USE meth); 12598 12599 ins_cost(300); 12600 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12601 "call,dynamic " %} 12602 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12603 ins_pipe(pipe_slow); 12604 ins_alignment(4); 12605%} 12606 12607// Call Runtime Instruction 12608instruct CallRuntimeDirect(method meth) 12609%{ 12610 match(CallRuntime); 12611 effect(USE meth); 12612 12613 ins_cost(300); 12614 format %{ "call,runtime " %} 12615 ins_encode(clear_avx, Java_To_Runtime(meth)); 12616 ins_pipe(pipe_slow); 12617%} 12618 12619// Call runtime without safepoint 12620instruct CallLeafDirect(method meth) 12621%{ 12622 match(CallLeaf); 12623 effect(USE meth); 12624 12625 ins_cost(300); 12626 format %{ "call_leaf,runtime " %} 12627 ins_encode(clear_avx, Java_To_Runtime(meth)); 12628 ins_pipe(pipe_slow); 12629%} 12630 12631// Call runtime without safepoint 12632instruct CallLeafNoFPDirect(method meth) 12633%{ 12634 match(CallLeafNoFP); 12635 effect(USE meth); 12636 12637 ins_cost(300); 12638 format %{ "call_leaf_nofp,runtime " %} 12639 ins_encode(clear_avx, Java_To_Runtime(meth)); 12640 ins_pipe(pipe_slow); 12641%} 12642 12643// Return Instruction 12644// Remove the return address & jump to it. 12645// Notice: We always emit a nop after a ret to make sure there is room 12646// for safepoint patching 12647instruct Ret() 12648%{ 12649 match(Return); 12650 12651 format %{ "ret" %} 12652 opcode(0xC3); 12653 ins_encode(OpcP); 12654 ins_pipe(pipe_jmp); 12655%} 12656 12657// Tail Call; Jump from runtime stub to Java code. 12658// Also known as an 'interprocedural jump'. 12659// Target of jump will eventually return to caller. 12660// TailJump below removes the return address. 12661instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12662%{ 12663 match(TailCall jump_target method_oop); 12664 12665 ins_cost(300); 12666 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12667 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12668 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12669 ins_pipe(pipe_jmp); 12670%} 12671 12672// Tail Jump; remove the return address; jump to target. 12673// TailCall above leaves the return address around. 12674instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12675%{ 12676 match(TailJump jump_target ex_oop); 12677 12678 ins_cost(300); 12679 format %{ "popq rdx\t# pop return address\n\t" 12680 "jmp $jump_target" %} 12681 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12682 ins_encode(Opcode(0x5a), // popq rdx 12683 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12684 ins_pipe(pipe_jmp); 12685%} 12686 12687// Create exception oop: created by stack-crawling runtime code. 12688// Created exception is now available to this handler, and is setup 12689// just prior to jumping to this handler. No code emitted. 12690instruct CreateException(rax_RegP ex_oop) 12691%{ 12692 match(Set ex_oop (CreateEx)); 12693 12694 size(0); 12695 // use the following format syntax 12696 format %{ "# exception oop is in rax; no code emitted" %} 12697 ins_encode(); 12698 ins_pipe(empty); 12699%} 12700 12701// Rethrow exception: 12702// The exception oop will come in the first argument position. 12703// Then JUMP (not call) to the rethrow stub code. 12704instruct RethrowException() 12705%{ 12706 match(Rethrow); 12707 12708 // use the following format syntax 12709 format %{ "jmp rethrow_stub" %} 12710 ins_encode(enc_rethrow); 12711 ins_pipe(pipe_jmp); 12712%} 12713 12714// 12715// Execute ZGC load barrier (strong) slow path 12716// 12717 12718// For XMM and YMM enabled processors 12719instruct loadBarrierSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12720 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12721 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12722 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12723 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12724 12725 match(Set dst (LoadBarrierSlowReg mem)); 12726 predicate(UseAVX <= 2); 12727 12728 effect(DEF dst, KILL cr, 12729 KILL x0, KILL x1, KILL x2, KILL x3, 12730 KILL x4, KILL x5, KILL x6, KILL x7, 12731 KILL x8, KILL x9, KILL x10, KILL x11, 12732 KILL x12, KILL x13, KILL x14, KILL x15); 12733 12734 format %{"LoadBarrierSlowRegXmmAndYmm $dst, $mem" %} 12735 ins_encode %{ 12736#if INCLUDE_ZGC 12737 Register d = $dst$$Register; 12738 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12739 12740 assert(d != r12, "Can't be R12!"); 12741 assert(d != r15, "Can't be R15!"); 12742 assert(d != rsp, "Can't be RSP!"); 12743 12744 __ lea(d, $mem$$Address); 12745 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12746#else 12747 ShouldNotReachHere(); 12748#endif 12749 %} 12750 ins_pipe(pipe_slow); 12751%} 12752 12753// For ZMM enabled processors 12754instruct loadBarrierSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12755 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12756 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12757 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12758 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12759 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12760 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12761 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12762 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12763 12764 match(Set dst (LoadBarrierSlowReg mem)); 12765 predicate(UseAVX == 3); 12766 12767 effect(DEF dst, KILL cr, 12768 KILL x0, KILL x1, KILL x2, KILL x3, 12769 KILL x4, KILL x5, KILL x6, KILL x7, 12770 KILL x8, KILL x9, KILL x10, KILL x11, 12771 KILL x12, KILL x13, KILL x14, KILL x15, 12772 KILL x16, KILL x17, KILL x18, KILL x19, 12773 KILL x20, KILL x21, KILL x22, KILL x23, 12774 KILL x24, KILL x25, KILL x26, KILL x27, 12775 KILL x28, KILL x29, KILL x30, KILL x31); 12776 12777 format %{"LoadBarrierSlowRegZmm $dst, $mem" %} 12778 ins_encode %{ 12779#if INCLUDE_ZGC 12780 Register d = $dst$$Register; 12781 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12782 12783 assert(d != r12, "Can't be R12!"); 12784 assert(d != r15, "Can't be R15!"); 12785 assert(d != rsp, "Can't be RSP!"); 12786 12787 __ lea(d, $mem$$Address); 12788 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12789#else 12790 ShouldNotReachHere(); 12791#endif 12792 %} 12793 ins_pipe(pipe_slow); 12794%} 12795 12796// 12797// Execute ZGC load barrier (weak) slow path 12798// 12799 12800// For XMM and YMM enabled processors 12801instruct loadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12802 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12803 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12804 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12805 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12806 12807 match(Set dst (LoadBarrierWeakSlowReg mem)); 12808 predicate(UseAVX <= 2); 12809 12810 effect(DEF dst, KILL cr, 12811 KILL x0, KILL x1, KILL x2, KILL x3, 12812 KILL x4, KILL x5, KILL x6, KILL x7, 12813 KILL x8, KILL x9, KILL x10, KILL x11, 12814 KILL x12, KILL x13, KILL x14, KILL x15); 12815 12816 format %{"LoadBarrierWeakSlowRegXmmAndYmm $dst, $mem" %} 12817 ins_encode %{ 12818#if INCLUDE_ZGC 12819 Register d = $dst$$Register; 12820 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12821 12822 assert(d != r12, "Can't be R12!"); 12823 assert(d != r15, "Can't be R15!"); 12824 assert(d != rsp, "Can't be RSP!"); 12825 12826 __ lea(d,$mem$$Address); 12827 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12828#else 12829 ShouldNotReachHere(); 12830#endif 12831 %} 12832 ins_pipe(pipe_slow); 12833%} 12834 12835// For ZMM enabled processors 12836instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 12837 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12838 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12839 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12840 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 12841 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 12842 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 12843 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 12844 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 12845 12846 match(Set dst (LoadBarrierWeakSlowReg mem)); 12847 predicate(UseAVX == 3); 12848 12849 effect(DEF dst, KILL cr, 12850 KILL x0, KILL x1, KILL x2, KILL x3, 12851 KILL x4, KILL x5, KILL x6, KILL x7, 12852 KILL x8, KILL x9, KILL x10, KILL x11, 12853 KILL x12, KILL x13, KILL x14, KILL x15, 12854 KILL x16, KILL x17, KILL x18, KILL x19, 12855 KILL x20, KILL x21, KILL x22, KILL x23, 12856 KILL x24, KILL x25, KILL x26, KILL x27, 12857 KILL x28, KILL x29, KILL x30, KILL x31); 12858 12859 format %{"LoadBarrierWeakSlowRegZmm $dst, $mem" %} 12860 ins_encode %{ 12861#if INCLUDE_ZGC 12862 Register d = $dst$$Register; 12863 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12864 12865 assert(d != r12, "Can't be R12!"); 12866 assert(d != r15, "Can't be R15!"); 12867 assert(d != rsp, "Can't be RSP!"); 12868 12869 __ lea(d,$mem$$Address); 12870 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 12871#else 12872 ShouldNotReachHere(); 12873#endif 12874 %} 12875 ins_pipe(pipe_slow); 12876%} 12877 12878// ============================================================================ 12879// This name is KNOWN by the ADLC and cannot be changed. 12880// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12881// for this guy. 12882instruct tlsLoadP(r15_RegP dst) %{ 12883 match(Set dst (ThreadLocal)); 12884 effect(DEF dst); 12885 12886 size(0); 12887 format %{ "# TLS is in R15" %} 12888 ins_encode( /*empty encoding*/ ); 12889 ins_pipe(ialu_reg_reg); 12890%} 12891 12892 12893//----------PEEPHOLE RULES----------------------------------------------------- 12894// These must follow all instruction definitions as they use the names 12895// defined in the instructions definitions. 12896// 12897// peepmatch ( root_instr_name [preceding_instruction]* ); 12898// 12899// peepconstraint %{ 12900// (instruction_number.operand_name relational_op instruction_number.operand_name 12901// [, ...] ); 12902// // instruction numbers are zero-based using left to right order in peepmatch 12903// 12904// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12905// // provide an instruction_number.operand_name for each operand that appears 12906// // in the replacement instruction's match rule 12907// 12908// ---------VM FLAGS--------------------------------------------------------- 12909// 12910// All peephole optimizations can be turned off using -XX:-OptoPeephole 12911// 12912// Each peephole rule is given an identifying number starting with zero and 12913// increasing by one in the order seen by the parser. An individual peephole 12914// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12915// on the command-line. 12916// 12917// ---------CURRENT LIMITATIONS---------------------------------------------- 12918// 12919// Only match adjacent instructions in same basic block 12920// Only equality constraints 12921// Only constraints between operands, not (0.dest_reg == RAX_enc) 12922// Only one replacement instruction 12923// 12924// ---------EXAMPLE---------------------------------------------------------- 12925// 12926// // pertinent parts of existing instructions in architecture description 12927// instruct movI(rRegI dst, rRegI src) 12928// %{ 12929// match(Set dst (CopyI src)); 12930// %} 12931// 12932// instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12933// %{ 12934// match(Set dst (AddI dst src)); 12935// effect(KILL cr); 12936// %} 12937// 12938// // Change (inc mov) to lea 12939// peephole %{ 12940// // increment preceeded by register-register move 12941// peepmatch ( incI_rReg movI ); 12942// // require that the destination register of the increment 12943// // match the destination register of the move 12944// peepconstraint ( 0.dst == 1.dst ); 12945// // construct a replacement instruction that sets 12946// // the destination to ( move's source register + one ) 12947// peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12948// %} 12949// 12950 12951// Implementation no longer uses movX instructions since 12952// machine-independent system no longer uses CopyX nodes. 12953// 12954// peephole 12955// %{ 12956// peepmatch (incI_rReg movI); 12957// peepconstraint (0.dst == 1.dst); 12958// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12959// %} 12960 12961// peephole 12962// %{ 12963// peepmatch (decI_rReg movI); 12964// peepconstraint (0.dst == 1.dst); 12965// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12966// %} 12967 12968// peephole 12969// %{ 12970// peepmatch (addI_rReg_imm movI); 12971// peepconstraint (0.dst == 1.dst); 12972// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12973// %} 12974 12975// peephole 12976// %{ 12977// peepmatch (incL_rReg movL); 12978// peepconstraint (0.dst == 1.dst); 12979// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12980// %} 12981 12982// peephole 12983// %{ 12984// peepmatch (decL_rReg movL); 12985// peepconstraint (0.dst == 1.dst); 12986// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12987// %} 12988 12989// peephole 12990// %{ 12991// peepmatch (addL_rReg_imm movL); 12992// peepconstraint (0.dst == 1.dst); 12993// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12994// %} 12995 12996// peephole 12997// %{ 12998// peepmatch (addP_rReg_imm movP); 12999// peepconstraint (0.dst == 1.dst); 13000// peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 13001// %} 13002 13003// // Change load of spilled value to only a spill 13004// instruct storeI(memory mem, rRegI src) 13005// %{ 13006// match(Set mem (StoreI mem src)); 13007// %} 13008// 13009// instruct loadI(rRegI dst, memory mem) 13010// %{ 13011// match(Set dst (LoadI mem)); 13012// %} 13013// 13014 13015peephole 13016%{ 13017 peepmatch (loadI storeI); 13018 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13019 peepreplace (storeI(1.mem 1.mem 1.src)); 13020%} 13021 13022peephole 13023%{ 13024 peepmatch (loadL storeL); 13025 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13026 peepreplace (storeL(1.mem 1.mem 1.src)); 13027%} 13028 13029//----------SMARTSPILL RULES--------------------------------------------------- 13030// These must follow all instruction definitions as they use the names 13031// defined in the instructions definitions. 13032