1 // 2 // Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // XMM registers. 128-bit registers or 4 words each, labeled (a)-d. 135 // Word a in each register holds a Float, words ab hold a Double. We 136 // currently do not use the SIMD capabilities, so registers cd are 137 // unused at the moment. 138 // XMM8-XMM15 must be encoded with REX. 139 // Linux ABI: No register preserved across function calls 140 // XMM0-XMM7 might hold parameters 141 // Windows ABI: XMM6-XMM15 preserved across function calls 142 // XMM0-XMM3 might hold parameters 143 144 reg_def XMM0 (SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()); 145 reg_def XMM0_H (SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next()); 146 147 reg_def XMM1 (SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()); 148 reg_def XMM1_H (SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next()); 149 150 reg_def XMM2 (SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()); 151 reg_def XMM2_H (SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next()); 152 153 reg_def XMM3 (SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()); 154 reg_def XMM3_H (SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next()); 155 156 reg_def XMM4 (SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()); 157 reg_def XMM4_H (SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next()); 158 159 reg_def XMM5 (SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()); 160 reg_def XMM5_H (SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next()); 161 162 #ifdef _WIN64 163 164 reg_def XMM6 (SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()); 165 reg_def XMM6_H (SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next()); 166 167 reg_def XMM7 (SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()); 168 reg_def XMM7_H (SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next()); 169 170 reg_def XMM8 (SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()); 171 reg_def XMM8_H (SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next()); 172 173 reg_def XMM9 (SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()); 174 reg_def XMM9_H (SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next()); 175 176 reg_def XMM10 (SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()); 177 reg_def XMM10_H(SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next()); 178 179 reg_def XMM11 (SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()); 180 reg_def XMM11_H(SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next()); 181 182 reg_def XMM12 (SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()); 183 reg_def XMM12_H(SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next()); 184 185 reg_def XMM13 (SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()); 186 reg_def XMM13_H(SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next()); 187 188 reg_def XMM14 (SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()); 189 reg_def XMM14_H(SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next()); 190 191 reg_def XMM15 (SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()); 192 reg_def XMM15_H(SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next()); 193 194 #else 195 196 reg_def XMM6 (SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()); 197 reg_def XMM6_H (SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next()); 198 199 reg_def XMM7 (SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()); 200 reg_def XMM7_H (SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next()); 201 202 reg_def XMM8 (SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()); 203 reg_def XMM8_H (SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next()); 204 205 reg_def XMM9 (SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()); 206 reg_def XMM9_H (SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next()); 207 208 reg_def XMM10 (SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()); 209 reg_def XMM10_H(SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next()); 210 211 reg_def XMM11 (SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()); 212 reg_def XMM11_H(SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next()); 213 214 reg_def XMM12 (SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()); 215 reg_def XMM12_H(SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next()); 216 217 reg_def XMM13 (SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()); 218 reg_def XMM13_H(SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next()); 219 220 reg_def XMM14 (SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()); 221 reg_def XMM14_H(SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next()); 222 223 reg_def XMM15 (SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()); 224 reg_def XMM15_H(SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next()); 225 226 #endif // _WIN64 227 228 reg_def RFLAGS(SOC, SOC, 0, 16, VMRegImpl::Bad()); 229 230 // Specify priority of register selection within phases of register 231 // allocation. Highest priority is first. A useful heuristic is to 232 // give registers a low priority when they are required by machine 233 // instructions, like EAX and EDX on I486, and choose no-save registers 234 // before save-on-call, & save-on-call before save-on-entry. Registers 235 // which participate in fixed calling sequences should come last. 236 // Registers which are used as pairs must fall on an even boundary. 237 238 alloc_class chunk0(R10, R10_H, 239 R11, R11_H, 240 R8, R8_H, 241 R9, R9_H, 242 R12, R12_H, 243 RCX, RCX_H, 244 RBX, RBX_H, 245 RDI, RDI_H, 246 RDX, RDX_H, 247 RSI, RSI_H, 248 RAX, RAX_H, 249 RBP, RBP_H, 250 R13, R13_H, 251 R14, R14_H, 252 R15, R15_H, 253 RSP, RSP_H); 254 255 // XXX probably use 8-15 first on Linux 256 alloc_class chunk1(XMM0, XMM0_H, 257 XMM1, XMM1_H, 258 XMM2, XMM2_H, 259 XMM3, XMM3_H, 260 XMM4, XMM4_H, 261 XMM5, XMM5_H, 262 XMM6, XMM6_H, 263 XMM7, XMM7_H, 264 XMM8, XMM8_H, 265 XMM9, XMM9_H, 266 XMM10, XMM10_H, 267 XMM11, XMM11_H, 268 XMM12, XMM12_H, 269 XMM13, XMM13_H, 270 XMM14, XMM14_H, 271 XMM15, XMM15_H); 272 273 alloc_class chunk2(RFLAGS); 274 275 276 //----------Architecture Description Register Classes-------------------------- 277 // Several register classes are automatically defined based upon information in 278 // this architecture description. 279 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 280 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 281 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 282 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 283 // 284 285 // Class for all pointer registers (including RSP) 286 reg_class any_reg(RAX, RAX_H, 287 RDX, RDX_H, 288 RBP, RBP_H, 289 RDI, RDI_H, 290 RSI, RSI_H, 291 RCX, RCX_H, 292 RBX, RBX_H, 293 RSP, RSP_H, 294 R8, R8_H, 295 R9, R9_H, 296 R10, R10_H, 297 R11, R11_H, 298 R12, R12_H, 299 R13, R13_H, 300 R14, R14_H, 301 R15, R15_H); 302 303 // Class for all pointer registers except RSP 304 reg_class ptr_reg(RAX, RAX_H, 305 RDX, RDX_H, 306 RBP, RBP_H, 307 RDI, RDI_H, 308 RSI, RSI_H, 309 RCX, RCX_H, 310 RBX, RBX_H, 311 R8, R8_H, 312 R9, R9_H, 313 R10, R10_H, 314 R11, R11_H, 315 R13, R13_H, 316 R14, R14_H); 317 318 // Class for all pointer registers except RAX and RSP 319 reg_class ptr_no_rax_reg(RDX, RDX_H, 320 RBP, RBP_H, 321 RDI, RDI_H, 322 RSI, RSI_H, 323 RCX, RCX_H, 324 RBX, RBX_H, 325 R8, R8_H, 326 R9, R9_H, 327 R10, R10_H, 328 R11, R11_H, 329 R13, R13_H, 330 R14, R14_H); 331 332 reg_class ptr_no_rbp_reg(RDX, RDX_H, 333 RAX, RAX_H, 334 RDI, RDI_H, 335 RSI, RSI_H, 336 RCX, RCX_H, 337 RBX, RBX_H, 338 R8, R8_H, 339 R9, R9_H, 340 R10, R10_H, 341 R11, R11_H, 342 R13, R13_H, 343 R14, R14_H); 344 345 // Class for all pointer registers except RAX, RBX and RSP 346 reg_class ptr_no_rax_rbx_reg(RDX, RDX_H, 347 RBP, RBP_H, 348 RDI, RDI_H, 349 RSI, RSI_H, 350 RCX, RCX_H, 351 R8, R8_H, 352 R9, R9_H, 353 R10, R10_H, 354 R11, R11_H, 355 R13, R13_H, 356 R14, R14_H); 357 358 // Singleton class for RAX pointer register 359 reg_class ptr_rax_reg(RAX, RAX_H); 360 361 // Singleton class for RBX pointer register 362 reg_class ptr_rbx_reg(RBX, RBX_H); 363 364 // Singleton class for RSI pointer register 365 reg_class ptr_rsi_reg(RSI, RSI_H); 366 367 // Singleton class for RDI pointer register 368 reg_class ptr_rdi_reg(RDI, RDI_H); 369 370 // Singleton class for RBP pointer register 371 reg_class ptr_rbp_reg(RBP, RBP_H); 372 373 // Singleton class for stack pointer 374 reg_class ptr_rsp_reg(RSP, RSP_H); 375 376 // Singleton class for TLS pointer 377 reg_class ptr_r15_reg(R15, R15_H); 378 379 // Class for all long registers (except RSP) 380 reg_class long_reg(RAX, RAX_H, 381 RDX, RDX_H, 382 RBP, RBP_H, 383 RDI, RDI_H, 384 RSI, RSI_H, 385 RCX, RCX_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 except RAX, RDX (and RSP) 395 reg_class long_no_rax_rdx_reg(RBP, RBP_H, 396 RDI, RDI_H, 397 RSI, RSI_H, 398 RCX, RCX_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 // Class for all long registers except RCX (and RSP) 408 reg_class long_no_rcx_reg(RBP, RBP_H, 409 RDI, RDI_H, 410 RSI, RSI_H, 411 RAX, RAX_H, 412 RDX, RDX_H, 413 RBX, RBX_H, 414 R8, R8_H, 415 R9, R9_H, 416 R10, R10_H, 417 R11, R11_H, 418 R13, R13_H, 419 R14, R14_H); 420 421 // Class for all long registers except RAX (and RSP) 422 reg_class long_no_rax_reg(RBP, RBP_H, 423 RDX, RDX_H, 424 RDI, RDI_H, 425 RSI, RSI_H, 426 RCX, RCX_H, 427 RBX, RBX_H, 428 R8, R8_H, 429 R9, R9_H, 430 R10, R10_H, 431 R11, R11_H, 432 R13, R13_H, 433 R14, R14_H); 434 435 // Singleton class for RAX long register 436 reg_class long_rax_reg(RAX, RAX_H); 437 438 // Singleton class for RCX long register 439 reg_class long_rcx_reg(RCX, RCX_H); 440 441 // Singleton class for RDX long register 442 reg_class long_rdx_reg(RDX, RDX_H); 443 444 // Class for all int registers (except RSP) 445 reg_class int_reg(RAX, 446 RDX, 447 RBP, 448 RDI, 449 RSI, 450 RCX, 451 RBX, 452 R8, 453 R9, 454 R10, 455 R11, 456 R13, 457 R14); 458 459 // Class for all int registers except RCX (and RSP) 460 reg_class int_no_rcx_reg(RAX, 461 RDX, 462 RBP, 463 RDI, 464 RSI, 465 RBX, 466 R8, 467 R9, 468 R10, 469 R11, 470 R13, 471 R14); 472 473 // Class for all int registers except RAX, RDX (and RSP) 474 reg_class int_no_rax_rdx_reg(RBP, 475 RDI, 476 RSI, 477 RCX, 478 RBX, 479 R8, 480 R9, 481 R10, 482 R11, 483 R13, 484 R14); 485 486 // Singleton class for RAX int register 487 reg_class int_rax_reg(RAX); 488 489 // Singleton class for RBX int register 490 reg_class int_rbx_reg(RBX); 491 492 // Singleton class for RCX int register 493 reg_class int_rcx_reg(RCX); 494 495 // Singleton class for RCX int register 496 reg_class int_rdx_reg(RDX); 497 498 // Singleton class for RCX int register 499 reg_class int_rdi_reg(RDI); 500 501 // Singleton class for instruction pointer 502 // reg_class ip_reg(RIP); 503 504 // Singleton class for condition codes 505 reg_class int_flags(RFLAGS); 506 507 // Class for all float registers 508 reg_class float_reg(XMM0, 509 XMM1, 510 XMM2, 511 XMM3, 512 XMM4, 513 XMM5, 514 XMM6, 515 XMM7, 516 XMM8, 517 XMM9, 518 XMM10, 519 XMM11, 520 XMM12, 521 XMM13, 522 XMM14, 523 XMM15); 524 525 // Class for all double registers 526 reg_class double_reg(XMM0, XMM0_H, 527 XMM1, XMM1_H, 528 XMM2, XMM2_H, 529 XMM3, XMM3_H, 530 XMM4, XMM4_H, 531 XMM5, XMM5_H, 532 XMM6, XMM6_H, 533 XMM7, XMM7_H, 534 XMM8, XMM8_H, 535 XMM9, XMM9_H, 536 XMM10, XMM10_H, 537 XMM11, XMM11_H, 538 XMM12, XMM12_H, 539 XMM13, XMM13_H, 540 XMM14, XMM14_H, 541 XMM15, XMM15_H); 542 %} 543 544 545 //----------SOURCE BLOCK------------------------------------------------------- 546 // This is a block of C++ code which provides values, functions, and 547 // definitions necessary in the rest of the architecture description 548 source %{ 549 #define RELOC_IMM64 Assembler::imm_operand 550 #define RELOC_DISP32 Assembler::disp32_operand 551 552 #define __ _masm. 553 554 static int preserve_SP_size() { 555 return 3; // rex.w, op, rm(reg/reg) 556 } 557 558 // !!!!! Special hack to get all types of calls to specify the byte offset 559 // from the start of the call to the point where the return address 560 // will point. 561 int MachCallStaticJavaNode::ret_addr_offset() 562 { 563 int offset = 5; // 5 bytes from start of call to where return address points 564 if (_method_handle_invoke) 565 offset += preserve_SP_size(); 566 return offset; 567 } 568 569 int MachCallDynamicJavaNode::ret_addr_offset() 570 { 571 return 15; // 15 bytes from start of call to where return address points 572 } 573 574 // In os_cpu .ad file 575 // int MachCallRuntimeNode::ret_addr_offset() 576 577 // Indicate if the safepoint node needs the polling page as an input, 578 // it does if the polling page is more than disp32 away. 579 bool SafePointNode::needs_polling_address_input() 580 { 581 return Assembler::is_polling_page_far(); 582 } 583 584 // 585 // Compute padding required for nodes which need alignment 586 // 587 588 // The address of the call instruction needs to be 4-byte aligned to 589 // ensure that it does not span a cache line so that it can be patched. 590 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 591 { 592 current_offset += 1; // skip call opcode byte 593 return round_to(current_offset, alignment_required()) - current_offset; 594 } 595 596 // The address of the call instruction needs to be 4-byte aligned to 597 // ensure that it does not span a cache line so that it can be patched. 598 int CallStaticJavaHandleNode::compute_padding(int current_offset) const 599 { 600 current_offset += preserve_SP_size(); // skip mov rbp, rsp 601 current_offset += 1; // skip call opcode byte 602 return round_to(current_offset, alignment_required()) - current_offset; 603 } 604 605 // The address of the call instruction needs to be 4-byte aligned to 606 // ensure that it does not span a cache line so that it can be patched. 607 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 608 { 609 current_offset += 11; // skip movq instruction + call opcode byte 610 return round_to(current_offset, alignment_required()) - current_offset; 611 } 612 613 // EMIT_RM() 614 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 615 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 616 cbuf.insts()->emit_int8(c); 617 } 618 619 // EMIT_CC() 620 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 621 unsigned char c = (unsigned char) (f1 | f2); 622 cbuf.insts()->emit_int8(c); 623 } 624 625 // EMIT_OPCODE() 626 void emit_opcode(CodeBuffer &cbuf, int code) { 627 cbuf.insts()->emit_int8((unsigned char) code); 628 } 629 630 // EMIT_OPCODE() w/ relocation information 631 void emit_opcode(CodeBuffer &cbuf, 632 int code, relocInfo::relocType reloc, int offset, int format) 633 { 634 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 635 emit_opcode(cbuf, code); 636 } 637 638 // EMIT_D8() 639 void emit_d8(CodeBuffer &cbuf, int d8) { 640 cbuf.insts()->emit_int8((unsigned char) d8); 641 } 642 643 // EMIT_D16() 644 void emit_d16(CodeBuffer &cbuf, int d16) { 645 cbuf.insts()->emit_int16(d16); 646 } 647 648 // EMIT_D32() 649 void emit_d32(CodeBuffer &cbuf, int d32) { 650 cbuf.insts()->emit_int32(d32); 651 } 652 653 // EMIT_D64() 654 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 655 cbuf.insts()->emit_int64(d64); 656 } 657 658 // emit 32 bit value and construct relocation entry from relocInfo::relocType 659 void emit_d32_reloc(CodeBuffer& cbuf, 660 int d32, 661 relocInfo::relocType reloc, 662 int format) 663 { 664 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 665 cbuf.relocate(cbuf.insts_mark(), reloc, format); 666 cbuf.insts()->emit_int32(d32); 667 } 668 669 // emit 32 bit value and construct relocation entry from RelocationHolder 670 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 671 #ifdef ASSERT 672 if (rspec.reloc()->type() == relocInfo::oop_type && 673 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 674 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 675 } 676 #endif 677 cbuf.relocate(cbuf.insts_mark(), rspec, format); 678 cbuf.insts()->emit_int32(d32); 679 } 680 681 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 682 address next_ip = cbuf.insts_end() + 4; 683 emit_d32_reloc(cbuf, (int) (addr - next_ip), 684 external_word_Relocation::spec(addr), 685 RELOC_DISP32); 686 } 687 688 689 // emit 64 bit value and construct relocation entry from relocInfo::relocType 690 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 691 cbuf.relocate(cbuf.insts_mark(), reloc, format); 692 cbuf.insts()->emit_int64(d64); 693 } 694 695 // emit 64 bit value and construct relocation entry from RelocationHolder 696 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 697 #ifdef ASSERT 698 if (rspec.reloc()->type() == relocInfo::oop_type && 699 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 700 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()), 701 "cannot embed scavengable oops in code"); 702 } 703 #endif 704 cbuf.relocate(cbuf.insts_mark(), rspec, format); 705 cbuf.insts()->emit_int64(d64); 706 } 707 708 // Access stack slot for load or store 709 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 710 { 711 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 712 if (-0x80 <= disp && disp < 0x80) { 713 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 714 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 715 emit_d8(cbuf, disp); // Displacement // R/M byte 716 } else { 717 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 718 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 719 emit_d32(cbuf, disp); // Displacement // R/M byte 720 } 721 } 722 723 // rRegI ereg, memory mem) %{ // emit_reg_mem 724 void encode_RegMem(CodeBuffer &cbuf, 725 int reg, 726 int base, int index, int scale, int disp, bool disp_is_oop) 727 { 728 assert(!disp_is_oop, "cannot have disp"); 729 int regenc = reg & 7; 730 int baseenc = base & 7; 731 int indexenc = index & 7; 732 733 // There is no index & no scale, use form without SIB byte 734 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 735 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 736 if (disp == 0 && base != RBP_enc && base != R13_enc) { 737 emit_rm(cbuf, 0x0, regenc, baseenc); // * 738 } else if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { 739 // If 8-bit displacement, mode 0x1 740 emit_rm(cbuf, 0x1, regenc, baseenc); // * 741 emit_d8(cbuf, disp); 742 } else { 743 // If 32-bit displacement 744 if (base == -1) { // Special flag for absolute address 745 emit_rm(cbuf, 0x0, regenc, 0x5); // * 746 if (disp_is_oop) { 747 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 748 } else { 749 emit_d32(cbuf, disp); 750 } 751 } else { 752 // Normal base + offset 753 emit_rm(cbuf, 0x2, regenc, baseenc); // * 754 if (disp_is_oop) { 755 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 756 } else { 757 emit_d32(cbuf, disp); 758 } 759 } 760 } 761 } else { 762 // Else, encode with the SIB byte 763 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 764 if (disp == 0 && base != RBP_enc && base != R13_enc) { 765 // If no displacement 766 emit_rm(cbuf, 0x0, regenc, 0x4); // * 767 emit_rm(cbuf, scale, indexenc, baseenc); 768 } else { 769 if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { 770 // If 8-bit displacement, mode 0x1 771 emit_rm(cbuf, 0x1, regenc, 0x4); // * 772 emit_rm(cbuf, scale, indexenc, baseenc); 773 emit_d8(cbuf, disp); 774 } else { 775 // If 32-bit displacement 776 if (base == 0x04 ) { 777 emit_rm(cbuf, 0x2, regenc, 0x4); 778 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 779 } else { 780 emit_rm(cbuf, 0x2, regenc, 0x4); 781 emit_rm(cbuf, scale, indexenc, baseenc); // * 782 } 783 if (disp_is_oop) { 784 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 785 } else { 786 emit_d32(cbuf, disp); 787 } 788 } 789 } 790 } 791 } 792 793 // This could be in MacroAssembler but it's fairly C2 specific 794 void emit_cmpfp_fixup(MacroAssembler& _masm) { 795 Label exit; 796 __ jccb(Assembler::noParity, exit); 797 __ pushf(); 798 // 799 // comiss/ucomiss instructions set ZF,PF,CF flags and 800 // zero OF,AF,SF for NaN values. 801 // Fixup flags by zeroing ZF,PF so that compare of NaN 802 // values returns 'less than' result (CF is set). 803 // Leave the rest of flags unchanged. 804 // 805 // 7 6 5 4 3 2 1 0 806 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 807 // 0 0 1 0 1 0 1 1 (0x2B) 808 // 809 __ andq(Address(rsp, 0), 0xffffff2b); 810 __ popf(); 811 __ bind(exit); 812 } 813 814 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 815 Label done; 816 __ movl(dst, -1); 817 __ jcc(Assembler::parity, done); 818 __ jcc(Assembler::below, done); 819 __ setb(Assembler::notEqual, dst); 820 __ movzbl(dst, dst); 821 __ bind(done); 822 } 823 824 825 //============================================================================= 826 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 827 828 int Compile::ConstantTable::calculate_table_base_offset() const { 829 return 0; // absolute addressing, no offset 830 } 831 832 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 833 // Empty encoding 834 } 835 836 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 837 return 0; 838 } 839 840 #ifndef PRODUCT 841 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 842 st->print("# MachConstantBaseNode (empty encoding)"); 843 } 844 #endif 845 846 847 //============================================================================= 848 #ifndef PRODUCT 849 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 850 Compile* C = ra_->C; 851 852 int framesize = C->frame_slots() << LogBytesPerInt; 853 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 854 // Remove wordSize for return addr which is already pushed. 855 framesize -= wordSize; 856 857 if (C->need_stack_bang(framesize)) { 858 framesize -= wordSize; 859 st->print("# stack bang"); 860 st->print("\n\t"); 861 st->print("pushq rbp\t# Save rbp"); 862 if (framesize) { 863 st->print("\n\t"); 864 st->print("subq rsp, #%d\t# Create frame",framesize); 865 } 866 } else { 867 st->print("subq rsp, #%d\t# Create frame",framesize); 868 st->print("\n\t"); 869 framesize -= wordSize; 870 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 871 } 872 873 if (VerifyStackAtCalls) { 874 st->print("\n\t"); 875 framesize -= wordSize; 876 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 877 #ifdef ASSERT 878 st->print("\n\t"); 879 st->print("# stack alignment check"); 880 #endif 881 } 882 st->cr(); 883 } 884 #endif 885 886 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 887 Compile* C = ra_->C; 888 MacroAssembler _masm(&cbuf); 889 890 int framesize = C->frame_slots() << LogBytesPerInt; 891 892 __ verified_entry(framesize, C->need_stack_bang(framesize), false); 893 894 C->set_frame_complete(cbuf.insts_size()); 895 896 if (C->has_mach_constant_base_node()) { 897 // NOTE: We set the table base offset here because users might be 898 // emitted before MachConstantBaseNode. 899 Compile::ConstantTable& constant_table = C->constant_table(); 900 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 901 } 902 } 903 904 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 905 { 906 return MachNode::size(ra_); // too many variables; just compute it 907 // the hard way 908 } 909 910 int MachPrologNode::reloc() const 911 { 912 return 0; // a large enough number 913 } 914 915 //============================================================================= 916 #ifndef PRODUCT 917 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 918 { 919 Compile* C = ra_->C; 920 int framesize = C->frame_slots() << LogBytesPerInt; 921 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 922 // Remove word for return adr already pushed 923 // and RBP 924 framesize -= 2*wordSize; 925 926 if (framesize) { 927 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 928 st->print("\t"); 929 } 930 931 st->print_cr("popq rbp"); 932 if (do_polling() && C->is_method_compilation()) { 933 st->print("\t"); 934 if (Assembler::is_polling_page_far()) { 935 st->print_cr("movq rscratch1, #polling_page_address\n\t" 936 "testl rax, [rscratch1]\t" 937 "# Safepoint: poll for GC"); 938 } else { 939 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 940 "# Safepoint: poll for GC"); 941 } 942 } 943 } 944 #endif 945 946 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 947 { 948 Compile* C = ra_->C; 949 int framesize = C->frame_slots() << LogBytesPerInt; 950 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 951 // Remove word for return adr already pushed 952 // and RBP 953 framesize -= 2*wordSize; 954 955 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 956 957 if (framesize) { 958 emit_opcode(cbuf, Assembler::REX_W); 959 if (framesize < 0x80) { 960 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 961 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 962 emit_d8(cbuf, framesize); 963 } else { 964 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 965 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 966 emit_d32(cbuf, framesize); 967 } 968 } 969 970 // popq rbp 971 emit_opcode(cbuf, 0x58 | RBP_enc); 972 973 if (do_polling() && C->is_method_compilation()) { 974 MacroAssembler _masm(&cbuf); 975 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 976 if (Assembler::is_polling_page_far()) { 977 __ lea(rscratch1, polling_page); 978 __ relocate(relocInfo::poll_return_type); 979 __ testl(rax, Address(rscratch1, 0)); 980 } else { 981 __ testl(rax, polling_page); 982 } 983 } 984 } 985 986 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 987 { 988 return MachNode::size(ra_); // too many variables; just compute it 989 // the hard way 990 } 991 992 int MachEpilogNode::reloc() const 993 { 994 return 2; // a large enough number 995 } 996 997 const Pipeline* MachEpilogNode::pipeline() const 998 { 999 return MachNode::pipeline_class(); 1000 } 1001 1002 int MachEpilogNode::safepoint_offset() const 1003 { 1004 return 0; 1005 } 1006 1007 //============================================================================= 1008 1009 enum RC { 1010 rc_bad, 1011 rc_int, 1012 rc_float, 1013 rc_stack 1014 }; 1015 1016 static enum RC rc_class(OptoReg::Name reg) 1017 { 1018 if( !OptoReg::is_valid(reg) ) return rc_bad; 1019 1020 if (OptoReg::is_stack(reg)) return rc_stack; 1021 1022 VMReg r = OptoReg::as_VMReg(reg); 1023 1024 if (r->is_Register()) return rc_int; 1025 1026 assert(r->is_XMMRegister(), "must be"); 1027 return rc_float; 1028 } 1029 1030 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1031 PhaseRegAlloc* ra_, 1032 bool do_size, 1033 outputStream* st) const 1034 { 1035 1036 // Get registers to move 1037 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1038 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1039 OptoReg::Name dst_second = ra_->get_reg_second(this); 1040 OptoReg::Name dst_first = ra_->get_reg_first(this); 1041 1042 enum RC src_second_rc = rc_class(src_second); 1043 enum RC src_first_rc = rc_class(src_first); 1044 enum RC dst_second_rc = rc_class(dst_second); 1045 enum RC dst_first_rc = rc_class(dst_first); 1046 1047 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1048 "must move at least 1 register" ); 1049 1050 if (src_first == dst_first && src_second == dst_second) { 1051 // Self copy, no move 1052 return 0; 1053 } else if (src_first_rc == rc_stack) { 1054 // mem -> 1055 if (dst_first_rc == rc_stack) { 1056 // mem -> mem 1057 assert(src_second != dst_first, "overlap"); 1058 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1059 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1060 // 64-bit 1061 int src_offset = ra_->reg2offset(src_first); 1062 int dst_offset = ra_->reg2offset(dst_first); 1063 if (cbuf) { 1064 emit_opcode(*cbuf, 0xFF); 1065 encode_RegMem(*cbuf, RSI_enc, RSP_enc, 0x4, 0, src_offset, false); 1066 1067 emit_opcode(*cbuf, 0x8F); 1068 encode_RegMem(*cbuf, RAX_enc, RSP_enc, 0x4, 0, dst_offset, false); 1069 1070 #ifndef PRODUCT 1071 } else if (!do_size) { 1072 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1073 "popq [rsp + #%d]", 1074 src_offset, 1075 dst_offset); 1076 #endif 1077 } 1078 return 1079 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + 1080 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)); 1081 } else { 1082 // 32-bit 1083 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1084 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1085 // No pushl/popl, so: 1086 int src_offset = ra_->reg2offset(src_first); 1087 int dst_offset = ra_->reg2offset(dst_first); 1088 if (cbuf) { 1089 emit_opcode(*cbuf, Assembler::REX_W); 1090 emit_opcode(*cbuf, 0x89); 1091 emit_opcode(*cbuf, 0x44); 1092 emit_opcode(*cbuf, 0x24); 1093 emit_opcode(*cbuf, 0xF8); 1094 1095 emit_opcode(*cbuf, 0x8B); 1096 encode_RegMem(*cbuf, 1097 RAX_enc, 1098 RSP_enc, 0x4, 0, src_offset, 1099 false); 1100 1101 emit_opcode(*cbuf, 0x89); 1102 encode_RegMem(*cbuf, 1103 RAX_enc, 1104 RSP_enc, 0x4, 0, dst_offset, 1105 false); 1106 1107 emit_opcode(*cbuf, Assembler::REX_W); 1108 emit_opcode(*cbuf, 0x8B); 1109 emit_opcode(*cbuf, 0x44); 1110 emit_opcode(*cbuf, 0x24); 1111 emit_opcode(*cbuf, 0xF8); 1112 1113 #ifndef PRODUCT 1114 } else if (!do_size) { 1115 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1116 "movl rax, [rsp + #%d]\n\t" 1117 "movl [rsp + #%d], rax\n\t" 1118 "movq rax, [rsp - #8]", 1119 src_offset, 1120 dst_offset); 1121 #endif 1122 } 1123 return 1124 5 + // movq 1125 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + // movl 1126 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)) + // movl 1127 5; // movq 1128 } 1129 } else if (dst_first_rc == rc_int) { 1130 // mem -> gpr 1131 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1132 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1133 // 64-bit 1134 int offset = ra_->reg2offset(src_first); 1135 if (cbuf) { 1136 if (Matcher::_regEncode[dst_first] < 8) { 1137 emit_opcode(*cbuf, Assembler::REX_W); 1138 } else { 1139 emit_opcode(*cbuf, Assembler::REX_WR); 1140 } 1141 emit_opcode(*cbuf, 0x8B); 1142 encode_RegMem(*cbuf, 1143 Matcher::_regEncode[dst_first], 1144 RSP_enc, 0x4, 0, offset, 1145 false); 1146 #ifndef PRODUCT 1147 } else if (!do_size) { 1148 st->print("movq %s, [rsp + #%d]\t# spill", 1149 Matcher::regName[dst_first], 1150 offset); 1151 #endif 1152 } 1153 return 1154 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX 1155 } else { 1156 // 32-bit 1157 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1158 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1159 int offset = ra_->reg2offset(src_first); 1160 if (cbuf) { 1161 if (Matcher::_regEncode[dst_first] >= 8) { 1162 emit_opcode(*cbuf, Assembler::REX_R); 1163 } 1164 emit_opcode(*cbuf, 0x8B); 1165 encode_RegMem(*cbuf, 1166 Matcher::_regEncode[dst_first], 1167 RSP_enc, 0x4, 0, offset, 1168 false); 1169 #ifndef PRODUCT 1170 } else if (!do_size) { 1171 st->print("movl %s, [rsp + #%d]\t# spill", 1172 Matcher::regName[dst_first], 1173 offset); 1174 #endif 1175 } 1176 return 1177 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1178 ((Matcher::_regEncode[dst_first] < 8) 1179 ? 3 1180 : 4); // REX 1181 } 1182 } else if (dst_first_rc == rc_float) { 1183 // mem-> xmm 1184 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1185 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1186 // 64-bit 1187 int offset = ra_->reg2offset(src_first); 1188 if (cbuf) { 1189 MacroAssembler _masm(cbuf); 1190 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1191 #ifndef PRODUCT 1192 } else if (!do_size) { 1193 st->print("%s %s, [rsp + #%d]\t# spill", 1194 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1195 Matcher::regName[dst_first], 1196 offset); 1197 #endif 1198 } 1199 return 1200 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1201 ((Matcher::_regEncode[dst_first] >= 8) 1202 ? 6 1203 : (5 + ((UseAVX>0)?1:0))); // REX 1204 } else { 1205 // 32-bit 1206 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1207 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1208 int offset = ra_->reg2offset(src_first); 1209 if (cbuf) { 1210 MacroAssembler _masm(cbuf); 1211 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1212 #ifndef PRODUCT 1213 } else if (!do_size) { 1214 st->print("movss %s, [rsp + #%d]\t# spill", 1215 Matcher::regName[dst_first], 1216 offset); 1217 #endif 1218 } 1219 return 1220 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1221 ((Matcher::_regEncode[dst_first] >= 8) 1222 ? 6 1223 : (5 + ((UseAVX>0)?1:0))); // REX 1224 } 1225 } 1226 } else if (src_first_rc == rc_int) { 1227 // gpr -> 1228 if (dst_first_rc == rc_stack) { 1229 // gpr -> mem 1230 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1231 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1232 // 64-bit 1233 int offset = ra_->reg2offset(dst_first); 1234 if (cbuf) { 1235 if (Matcher::_regEncode[src_first] < 8) { 1236 emit_opcode(*cbuf, Assembler::REX_W); 1237 } else { 1238 emit_opcode(*cbuf, Assembler::REX_WR); 1239 } 1240 emit_opcode(*cbuf, 0x89); 1241 encode_RegMem(*cbuf, 1242 Matcher::_regEncode[src_first], 1243 RSP_enc, 0x4, 0, offset, 1244 false); 1245 #ifndef PRODUCT 1246 } else if (!do_size) { 1247 st->print("movq [rsp + #%d], %s\t# spill", 1248 offset, 1249 Matcher::regName[src_first]); 1250 #endif 1251 } 1252 return ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX 1253 } else { 1254 // 32-bit 1255 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1256 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1257 int offset = ra_->reg2offset(dst_first); 1258 if (cbuf) { 1259 if (Matcher::_regEncode[src_first] >= 8) { 1260 emit_opcode(*cbuf, Assembler::REX_R); 1261 } 1262 emit_opcode(*cbuf, 0x89); 1263 encode_RegMem(*cbuf, 1264 Matcher::_regEncode[src_first], 1265 RSP_enc, 0x4, 0, offset, 1266 false); 1267 #ifndef PRODUCT 1268 } else if (!do_size) { 1269 st->print("movl [rsp + #%d], %s\t# spill", 1270 offset, 1271 Matcher::regName[src_first]); 1272 #endif 1273 } 1274 return 1275 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1276 ((Matcher::_regEncode[src_first] < 8) 1277 ? 3 1278 : 4); // REX 1279 } 1280 } else if (dst_first_rc == rc_int) { 1281 // gpr -> gpr 1282 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1283 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1284 // 64-bit 1285 if (cbuf) { 1286 if (Matcher::_regEncode[dst_first] < 8) { 1287 if (Matcher::_regEncode[src_first] < 8) { 1288 emit_opcode(*cbuf, Assembler::REX_W); 1289 } else { 1290 emit_opcode(*cbuf, Assembler::REX_WB); 1291 } 1292 } else { 1293 if (Matcher::_regEncode[src_first] < 8) { 1294 emit_opcode(*cbuf, Assembler::REX_WR); 1295 } else { 1296 emit_opcode(*cbuf, Assembler::REX_WRB); 1297 } 1298 } 1299 emit_opcode(*cbuf, 0x8B); 1300 emit_rm(*cbuf, 0x3, 1301 Matcher::_regEncode[dst_first] & 7, 1302 Matcher::_regEncode[src_first] & 7); 1303 #ifndef PRODUCT 1304 } else if (!do_size) { 1305 st->print("movq %s, %s\t# spill", 1306 Matcher::regName[dst_first], 1307 Matcher::regName[src_first]); 1308 #endif 1309 } 1310 return 3; // REX 1311 } else { 1312 // 32-bit 1313 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1314 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1315 if (cbuf) { 1316 if (Matcher::_regEncode[dst_first] < 8) { 1317 if (Matcher::_regEncode[src_first] >= 8) { 1318 emit_opcode(*cbuf, Assembler::REX_B); 1319 } 1320 } else { 1321 if (Matcher::_regEncode[src_first] < 8) { 1322 emit_opcode(*cbuf, Assembler::REX_R); 1323 } else { 1324 emit_opcode(*cbuf, Assembler::REX_RB); 1325 } 1326 } 1327 emit_opcode(*cbuf, 0x8B); 1328 emit_rm(*cbuf, 0x3, 1329 Matcher::_regEncode[dst_first] & 7, 1330 Matcher::_regEncode[src_first] & 7); 1331 #ifndef PRODUCT 1332 } else if (!do_size) { 1333 st->print("movl %s, %s\t# spill", 1334 Matcher::regName[dst_first], 1335 Matcher::regName[src_first]); 1336 #endif 1337 } 1338 return 1339 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1340 ? 2 1341 : 3; // REX 1342 } 1343 } else if (dst_first_rc == rc_float) { 1344 // gpr -> xmm 1345 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1346 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1347 // 64-bit 1348 if (cbuf) { 1349 MacroAssembler _masm(cbuf); 1350 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1351 #ifndef PRODUCT 1352 } else if (!do_size) { 1353 st->print("movdq %s, %s\t# spill", 1354 Matcher::regName[dst_first], 1355 Matcher::regName[src_first]); 1356 #endif 1357 } 1358 return 5; // REX 1359 } else { 1360 // 32-bit 1361 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1362 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1363 if (cbuf) { 1364 MacroAssembler _masm(cbuf); 1365 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1366 #ifndef PRODUCT 1367 } else if (!do_size) { 1368 st->print("movdl %s, %s\t# spill", 1369 Matcher::regName[dst_first], 1370 Matcher::regName[src_first]); 1371 #endif 1372 } 1373 return 1374 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) 1375 ? 5 1376 : (4 + ((UseAVX>0)?1:0)); // REX 1377 } 1378 } 1379 } else if (src_first_rc == rc_float) { 1380 // xmm -> 1381 if (dst_first_rc == rc_stack) { 1382 // xmm -> mem 1383 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1384 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1385 // 64-bit 1386 int offset = ra_->reg2offset(dst_first); 1387 if (cbuf) { 1388 MacroAssembler _masm(cbuf); 1389 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1390 #ifndef PRODUCT 1391 } else if (!do_size) { 1392 st->print("movsd [rsp + #%d], %s\t# spill", 1393 offset, 1394 Matcher::regName[src_first]); 1395 #endif 1396 } 1397 return 1398 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1399 ((Matcher::_regEncode[src_first] >= 8) 1400 ? 6 1401 : (5 + ((UseAVX>0)?1:0))); // REX 1402 } else { 1403 // 32-bit 1404 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1405 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1406 int offset = ra_->reg2offset(dst_first); 1407 if (cbuf) { 1408 MacroAssembler _masm(cbuf); 1409 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1410 #ifndef PRODUCT 1411 } else if (!do_size) { 1412 st->print("movss [rsp + #%d], %s\t# spill", 1413 offset, 1414 Matcher::regName[src_first]); 1415 #endif 1416 } 1417 return 1418 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1419 ((Matcher::_regEncode[src_first] >=8) 1420 ? 6 1421 : (5 + ((UseAVX>0)?1:0))); // REX 1422 } 1423 } else if (dst_first_rc == rc_int) { 1424 // xmm -> gpr 1425 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1426 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1427 // 64-bit 1428 if (cbuf) { 1429 MacroAssembler _masm(cbuf); 1430 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1431 #ifndef PRODUCT 1432 } else if (!do_size) { 1433 st->print("movdq %s, %s\t# spill", 1434 Matcher::regName[dst_first], 1435 Matcher::regName[src_first]); 1436 #endif 1437 } 1438 return 5; // REX 1439 } else { 1440 // 32-bit 1441 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1442 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1443 if (cbuf) { 1444 MacroAssembler _masm(cbuf); 1445 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1446 #ifndef PRODUCT 1447 } else if (!do_size) { 1448 st->print("movdl %s, %s\t# spill", 1449 Matcher::regName[dst_first], 1450 Matcher::regName[src_first]); 1451 #endif 1452 } 1453 return 1454 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) 1455 ? 5 1456 : (4 + ((UseAVX>0)?1:0)); // REX 1457 } 1458 } else if (dst_first_rc == rc_float) { 1459 // xmm -> xmm 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 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1466 #ifndef PRODUCT 1467 } else if (!do_size) { 1468 st->print("%s %s, %s\t# spill", 1469 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1470 Matcher::regName[dst_first], 1471 Matcher::regName[src_first]); 1472 #endif 1473 } 1474 return 1475 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) 1476 ? 5 1477 : (4 + ((UseAVX>0)?1:0)); // REX 1478 } else { 1479 // 32-bit 1480 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1481 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1482 if (cbuf) { 1483 MacroAssembler _masm(cbuf); 1484 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1485 #ifndef PRODUCT 1486 } else if (!do_size) { 1487 st->print("%s %s, %s\t# spill", 1488 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1489 Matcher::regName[dst_first], 1490 Matcher::regName[src_first]); 1491 #endif 1492 } 1493 return ((UseAVX>0) ? 5: 1494 ((Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) 1495 ? (UseXmmRegToRegMoveAll ? 4 : 5) 1496 : (UseXmmRegToRegMoveAll ? 3 : 4))); // REX 1497 } 1498 } 1499 } 1500 1501 assert(0," foo "); 1502 Unimplemented(); 1503 1504 return 0; 1505 } 1506 1507 #ifndef PRODUCT 1508 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const 1509 { 1510 implementation(NULL, ra_, false, st); 1511 } 1512 #endif 1513 1514 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const 1515 { 1516 implementation(&cbuf, ra_, false, NULL); 1517 } 1518 1519 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const 1520 { 1521 return implementation(NULL, ra_, true, NULL); 1522 } 1523 1524 //============================================================================= 1525 #ifndef PRODUCT 1526 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1527 { 1528 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1529 int reg = ra_->get_reg_first(this); 1530 st->print("leaq %s, [rsp + #%d]\t# box lock", 1531 Matcher::regName[reg], offset); 1532 } 1533 #endif 1534 1535 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1536 { 1537 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1538 int reg = ra_->get_encode(this); 1539 if (offset >= 0x80) { 1540 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1541 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1542 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1543 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1544 emit_d32(cbuf, offset); 1545 } else { 1546 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1547 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1548 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1549 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1550 emit_d8(cbuf, offset); 1551 } 1552 } 1553 1554 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1555 { 1556 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1557 return (offset < 0x80) ? 5 : 8; // REX 1558 } 1559 1560 //============================================================================= 1561 1562 // emit call stub, compiled java to interpreter 1563 void emit_java_to_interp(CodeBuffer& cbuf) 1564 { 1565 // Stub is fixed up when the corresponding call is converted from 1566 // calling compiled code to calling interpreted code. 1567 // movq rbx, 0 1568 // jmp -5 # to self 1569 1570 address mark = cbuf.insts_mark(); // get mark within main instrs section 1571 1572 // Note that the code buffer's insts_mark is always relative to insts. 1573 // That's why we must use the macroassembler to generate a stub. 1574 MacroAssembler _masm(&cbuf); 1575 1576 address base = 1577 __ start_a_stub(Compile::MAX_stubs_size); 1578 if (base == NULL) return; // CodeBuffer::expand failed 1579 // static stub relocation stores the instruction address of the call 1580 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); 1581 // static stub relocation also tags the methodOop in the code-stream. 1582 __ movoop(rbx, (jobject) NULL); // method is zapped till fixup time 1583 // This is recognized as unresolved by relocs/nativeinst/ic code 1584 __ jump(RuntimeAddress(__ pc())); 1585 1586 // Update current stubs pointer and restore insts_end. 1587 __ end_a_stub(); 1588 } 1589 1590 // size of call stub, compiled java to interpretor 1591 uint size_java_to_interp() 1592 { 1593 return 15; // movq (1+1+8); jmp (1+4) 1594 } 1595 1596 // relocation entries for call stub, compiled java to interpretor 1597 uint reloc_java_to_interp() 1598 { 1599 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call 1600 } 1601 1602 //============================================================================= 1603 #ifndef PRODUCT 1604 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1605 { 1606 if (UseCompressedOops) { 1607 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1608 if (Universe::narrow_oop_shift() != 0) { 1609 st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1"); 1610 } 1611 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1612 } else { 1613 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1614 "# Inline cache check"); 1615 } 1616 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1617 st->print_cr("\tnop\t# nops to align entry point"); 1618 } 1619 #endif 1620 1621 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1622 { 1623 MacroAssembler masm(&cbuf); 1624 uint insts_size = cbuf.insts_size(); 1625 if (UseCompressedOops) { 1626 masm.load_klass(rscratch1, j_rarg0); 1627 masm.cmpptr(rax, rscratch1); 1628 } else { 1629 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1630 } 1631 1632 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1633 1634 /* WARNING these NOPs are critical so that verified entry point is properly 1635 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1636 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1637 if (OptoBreakpoint) { 1638 // Leave space for int3 1639 nops_cnt -= 1; 1640 } 1641 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1642 if (nops_cnt > 0) 1643 masm.nop(nops_cnt); 1644 } 1645 1646 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1647 { 1648 return MachNode::size(ra_); // too many variables; just compute it 1649 // the hard way 1650 } 1651 1652 1653 //============================================================================= 1654 uint size_exception_handler() 1655 { 1656 // NativeCall instruction size is the same as NativeJump. 1657 // Note that this value is also credited (in output.cpp) to 1658 // the size of the code section. 1659 return NativeJump::instruction_size; 1660 } 1661 1662 // Emit exception handler code. 1663 int emit_exception_handler(CodeBuffer& cbuf) 1664 { 1665 1666 // Note that the code buffer's insts_mark is always relative to insts. 1667 // That's why we must use the macroassembler to generate a handler. 1668 MacroAssembler _masm(&cbuf); 1669 address base = 1670 __ start_a_stub(size_exception_handler()); 1671 if (base == NULL) return 0; // CodeBuffer::expand failed 1672 int offset = __ offset(); 1673 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1674 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1675 __ end_a_stub(); 1676 return offset; 1677 } 1678 1679 uint size_deopt_handler() 1680 { 1681 // three 5 byte instructions 1682 return 15; 1683 } 1684 1685 // Emit deopt handler code. 1686 int emit_deopt_handler(CodeBuffer& cbuf) 1687 { 1688 1689 // Note that the code buffer's insts_mark is always relative to insts. 1690 // That's why we must use the macroassembler to generate a handler. 1691 MacroAssembler _masm(&cbuf); 1692 address base = 1693 __ start_a_stub(size_deopt_handler()); 1694 if (base == NULL) return 0; // CodeBuffer::expand failed 1695 int offset = __ offset(); 1696 address the_pc = (address) __ pc(); 1697 Label next; 1698 // push a "the_pc" on the stack without destroying any registers 1699 // as they all may be live. 1700 1701 // push address of "next" 1702 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 1703 __ bind(next); 1704 // adjust it so it matches "the_pc" 1705 __ subptr(Address(rsp, 0), __ offset() - offset); 1706 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1707 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1708 __ end_a_stub(); 1709 return offset; 1710 } 1711 1712 1713 const bool Matcher::match_rule_supported(int opcode) { 1714 if (!has_match_rule(opcode)) 1715 return false; 1716 1717 return true; // Per default match rules are supported. 1718 } 1719 1720 int Matcher::regnum_to_fpu_offset(int regnum) 1721 { 1722 return regnum - 32; // The FP registers are in the second chunk 1723 } 1724 1725 // This is UltraSparc specific, true just means we have fast l2f conversion 1726 const bool Matcher::convL2FSupported(void) { 1727 return true; 1728 } 1729 1730 // Vector width in bytes 1731 const uint Matcher::vector_width_in_bytes(void) { 1732 return 8; 1733 } 1734 1735 // Vector ideal reg 1736 const uint Matcher::vector_ideal_reg(void) { 1737 return Op_RegD; 1738 } 1739 1740 // Is this branch offset short enough that a short branch can be used? 1741 // 1742 // NOTE: If the platform does not provide any short branch variants, then 1743 // this method should return false for offset 0. 1744 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1745 // The passed offset is relative to address of the branch. 1746 // On 86 a branch displacement is calculated relative to address 1747 // of a next instruction. 1748 offset -= br_size; 1749 1750 // the short version of jmpConUCF2 contains multiple branches, 1751 // making the reach slightly less 1752 if (rule == jmpConUCF2_rule) 1753 return (-126 <= offset && offset <= 125); 1754 return (-128 <= offset && offset <= 127); 1755 } 1756 1757 const bool Matcher::isSimpleConstant64(jlong value) { 1758 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1759 //return value == (int) value; // Cf. storeImmL and immL32. 1760 1761 // Probably always true, even if a temp register is required. 1762 return true; 1763 } 1764 1765 // The ecx parameter to rep stosq for the ClearArray node is in words. 1766 const bool Matcher::init_array_count_is_in_bytes = false; 1767 1768 // Threshold size for cleararray. 1769 const int Matcher::init_array_short_size = 8 * BytesPerLong; 1770 1771 // No additional cost for CMOVL. 1772 const int Matcher::long_cmove_cost() { return 0; } 1773 1774 // No CMOVF/CMOVD with SSE2 1775 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1776 1777 // Should the Matcher clone shifts on addressing modes, expecting them 1778 // to be subsumed into complex addressing expressions or compute them 1779 // into registers? True for Intel but false for most RISCs 1780 const bool Matcher::clone_shift_expressions = true; 1781 1782 // Do we need to mask the count passed to shift instructions or does 1783 // the cpu only look at the lower 5/6 bits anyway? 1784 const bool Matcher::need_masked_shift_count = false; 1785 1786 bool Matcher::narrow_oop_use_complex_address() { 1787 assert(UseCompressedOops, "only for compressed oops code"); 1788 return (LogMinObjAlignmentInBytes <= 3); 1789 } 1790 1791 // Is it better to copy float constants, or load them directly from 1792 // memory? Intel can load a float constant from a direct address, 1793 // requiring no extra registers. Most RISCs will have to materialize 1794 // an address into a register first, so they would do better to copy 1795 // the constant from stack. 1796 const bool Matcher::rematerialize_float_constants = true; // XXX 1797 1798 // If CPU can load and store mis-aligned doubles directly then no 1799 // fixup is needed. Else we split the double into 2 integer pieces 1800 // and move it piece-by-piece. Only happens when passing doubles into 1801 // C code as the Java calling convention forces doubles to be aligned. 1802 const bool Matcher::misaligned_doubles_ok = true; 1803 1804 // No-op on amd64 1805 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1806 1807 // Advertise here if the CPU requires explicit rounding operations to 1808 // implement the UseStrictFP mode. 1809 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1810 1811 // Are floats conerted to double when stored to stack during deoptimization? 1812 // On x64 it is stored without convertion so we can use normal access. 1813 bool Matcher::float_in_double() { return false; } 1814 1815 // Do ints take an entire long register or just half? 1816 const bool Matcher::int_in_long = true; 1817 1818 // Return whether or not this register is ever used as an argument. 1819 // This function is used on startup to build the trampoline stubs in 1820 // generateOptoStub. Registers not mentioned will be killed by the VM 1821 // call in the trampoline, and arguments in those registers not be 1822 // available to the callee. 1823 bool Matcher::can_be_java_arg(int reg) 1824 { 1825 return 1826 reg == RDI_num || reg == RDI_H_num || 1827 reg == RSI_num || reg == RSI_H_num || 1828 reg == RDX_num || reg == RDX_H_num || 1829 reg == RCX_num || reg == RCX_H_num || 1830 reg == R8_num || reg == R8_H_num || 1831 reg == R9_num || reg == R9_H_num || 1832 reg == R12_num || reg == R12_H_num || 1833 reg == XMM0_num || reg == XMM0_H_num || 1834 reg == XMM1_num || reg == XMM1_H_num || 1835 reg == XMM2_num || reg == XMM2_H_num || 1836 reg == XMM3_num || reg == XMM3_H_num || 1837 reg == XMM4_num || reg == XMM4_H_num || 1838 reg == XMM5_num || reg == XMM5_H_num || 1839 reg == XMM6_num || reg == XMM6_H_num || 1840 reg == XMM7_num || reg == XMM7_H_num; 1841 } 1842 1843 bool Matcher::is_spillable_arg(int reg) 1844 { 1845 return can_be_java_arg(reg); 1846 } 1847 1848 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1849 // In 64 bit mode a code which use multiply when 1850 // devisor is constant is faster than hardware 1851 // DIV instruction (it uses MulHiL). 1852 return false; 1853 } 1854 1855 // Register for DIVI projection of divmodI 1856 RegMask Matcher::divI_proj_mask() { 1857 return INT_RAX_REG_mask(); 1858 } 1859 1860 // Register for MODI projection of divmodI 1861 RegMask Matcher::modI_proj_mask() { 1862 return INT_RDX_REG_mask(); 1863 } 1864 1865 // Register for DIVL projection of divmodL 1866 RegMask Matcher::divL_proj_mask() { 1867 return LONG_RAX_REG_mask(); 1868 } 1869 1870 // Register for MODL projection of divmodL 1871 RegMask Matcher::modL_proj_mask() { 1872 return LONG_RDX_REG_mask(); 1873 } 1874 1875 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1876 return PTR_RBP_REG_mask(); 1877 } 1878 1879 static Address build_address(int b, int i, int s, int d) { 1880 Register index = as_Register(i); 1881 Address::ScaleFactor scale = (Address::ScaleFactor)s; 1882 if (index == rsp) { 1883 index = noreg; 1884 scale = Address::no_scale; 1885 } 1886 Address addr(as_Register(b), index, scale, d); 1887 return addr; 1888 } 1889 1890 %} 1891 1892 //----------ENCODING BLOCK----------------------------------------------------- 1893 // This block specifies the encoding classes used by the compiler to 1894 // output byte streams. Encoding classes are parameterized macros 1895 // used by Machine Instruction Nodes in order to generate the bit 1896 // encoding of the instruction. Operands specify their base encoding 1897 // interface with the interface keyword. There are currently 1898 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1899 // COND_INTER. REG_INTER causes an operand to generate a function 1900 // which returns its register number when queried. CONST_INTER causes 1901 // an operand to generate a function which returns the value of the 1902 // constant when queried. MEMORY_INTER causes an operand to generate 1903 // four functions which return the Base Register, the Index Register, 1904 // the Scale Value, and the Offset Value of the operand when queried. 1905 // COND_INTER causes an operand to generate six functions which return 1906 // the encoding code (ie - encoding bits for the instruction) 1907 // associated with each basic boolean condition for a conditional 1908 // instruction. 1909 // 1910 // Instructions specify two basic values for encoding. Again, a 1911 // function is available to check if the constant displacement is an 1912 // oop. They use the ins_encode keyword to specify their encoding 1913 // classes (which must be a sequence of enc_class names, and their 1914 // parameters, specified in the encoding block), and they use the 1915 // opcode keyword to specify, in order, their primary, secondary, and 1916 // tertiary opcode. Only the opcode sections which a particular 1917 // instruction needs for encoding need to be specified. 1918 encode %{ 1919 // Build emit functions for each basic byte or larger field in the 1920 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1921 // from C++ code in the enc_class source block. Emit functions will 1922 // live in the main source block for now. In future, we can 1923 // generalize this by adding a syntax that specifies the sizes of 1924 // fields in an order, so that the adlc can build the emit functions 1925 // automagically 1926 1927 // Emit primary opcode 1928 enc_class OpcP 1929 %{ 1930 emit_opcode(cbuf, $primary); 1931 %} 1932 1933 // Emit secondary opcode 1934 enc_class OpcS 1935 %{ 1936 emit_opcode(cbuf, $secondary); 1937 %} 1938 1939 // Emit tertiary opcode 1940 enc_class OpcT 1941 %{ 1942 emit_opcode(cbuf, $tertiary); 1943 %} 1944 1945 // Emit opcode directly 1946 enc_class Opcode(immI d8) 1947 %{ 1948 emit_opcode(cbuf, $d8$$constant); 1949 %} 1950 1951 // Emit size prefix 1952 enc_class SizePrefix 1953 %{ 1954 emit_opcode(cbuf, 0x66); 1955 %} 1956 1957 enc_class reg(rRegI reg) 1958 %{ 1959 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1960 %} 1961 1962 enc_class reg_reg(rRegI dst, rRegI src) 1963 %{ 1964 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1965 %} 1966 1967 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1968 %{ 1969 emit_opcode(cbuf, $opcode$$constant); 1970 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1971 %} 1972 1973 enc_class cdql_enc(no_rax_rdx_RegI div) 1974 %{ 1975 // Full implementation of Java idiv and irem; checks for 1976 // special case as described in JVM spec., p.243 & p.271. 1977 // 1978 // normal case special case 1979 // 1980 // input : rax: dividend min_int 1981 // reg: divisor -1 1982 // 1983 // output: rax: quotient (= rax idiv reg) min_int 1984 // rdx: remainder (= rax irem reg) 0 1985 // 1986 // Code sequnce: 1987 // 1988 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1989 // 5: 75 07/08 jne e <normal> 1990 // 7: 33 d2 xor %edx,%edx 1991 // [div >= 8 -> offset + 1] 1992 // [REX_B] 1993 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1994 // c: 74 03/04 je 11 <done> 1995 // 000000000000000e <normal>: 1996 // e: 99 cltd 1997 // [div >= 8 -> offset + 1] 1998 // [REX_B] 1999 // f: f7 f9 idiv $div 2000 // 0000000000000011 <done>: 2001 2002 // cmp $0x80000000,%eax 2003 emit_opcode(cbuf, 0x3d); 2004 emit_d8(cbuf, 0x00); 2005 emit_d8(cbuf, 0x00); 2006 emit_d8(cbuf, 0x00); 2007 emit_d8(cbuf, 0x80); 2008 2009 // jne e <normal> 2010 emit_opcode(cbuf, 0x75); 2011 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 2012 2013 // xor %edx,%edx 2014 emit_opcode(cbuf, 0x33); 2015 emit_d8(cbuf, 0xD2); 2016 2017 // cmp $0xffffffffffffffff,%ecx 2018 if ($div$$reg >= 8) { 2019 emit_opcode(cbuf, Assembler::REX_B); 2020 } 2021 emit_opcode(cbuf, 0x83); 2022 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2023 emit_d8(cbuf, 0xFF); 2024 2025 // je 11 <done> 2026 emit_opcode(cbuf, 0x74); 2027 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 2028 2029 // <normal> 2030 // cltd 2031 emit_opcode(cbuf, 0x99); 2032 2033 // idivl (note: must be emitted by the user of this rule) 2034 // <done> 2035 %} 2036 2037 enc_class cdqq_enc(no_rax_rdx_RegL div) 2038 %{ 2039 // Full implementation of Java ldiv and lrem; checks for 2040 // special case as described in JVM spec., p.243 & p.271. 2041 // 2042 // normal case special case 2043 // 2044 // input : rax: dividend min_long 2045 // reg: divisor -1 2046 // 2047 // output: rax: quotient (= rax idiv reg) min_long 2048 // rdx: remainder (= rax irem reg) 0 2049 // 2050 // Code sequnce: 2051 // 2052 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 2053 // 7: 00 00 80 2054 // a: 48 39 d0 cmp %rdx,%rax 2055 // d: 75 08 jne 17 <normal> 2056 // f: 33 d2 xor %edx,%edx 2057 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 2058 // 15: 74 05 je 1c <done> 2059 // 0000000000000017 <normal>: 2060 // 17: 48 99 cqto 2061 // 19: 48 f7 f9 idiv $div 2062 // 000000000000001c <done>: 2063 2064 // mov $0x8000000000000000,%rdx 2065 emit_opcode(cbuf, Assembler::REX_W); 2066 emit_opcode(cbuf, 0xBA); 2067 emit_d8(cbuf, 0x00); 2068 emit_d8(cbuf, 0x00); 2069 emit_d8(cbuf, 0x00); 2070 emit_d8(cbuf, 0x00); 2071 emit_d8(cbuf, 0x00); 2072 emit_d8(cbuf, 0x00); 2073 emit_d8(cbuf, 0x00); 2074 emit_d8(cbuf, 0x80); 2075 2076 // cmp %rdx,%rax 2077 emit_opcode(cbuf, Assembler::REX_W); 2078 emit_opcode(cbuf, 0x39); 2079 emit_d8(cbuf, 0xD0); 2080 2081 // jne 17 <normal> 2082 emit_opcode(cbuf, 0x75); 2083 emit_d8(cbuf, 0x08); 2084 2085 // xor %edx,%edx 2086 emit_opcode(cbuf, 0x33); 2087 emit_d8(cbuf, 0xD2); 2088 2089 // cmp $0xffffffffffffffff,$div 2090 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 2091 emit_opcode(cbuf, 0x83); 2092 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2093 emit_d8(cbuf, 0xFF); 2094 2095 // je 1e <done> 2096 emit_opcode(cbuf, 0x74); 2097 emit_d8(cbuf, 0x05); 2098 2099 // <normal> 2100 // cqto 2101 emit_opcode(cbuf, Assembler::REX_W); 2102 emit_opcode(cbuf, 0x99); 2103 2104 // idivq (note: must be emitted by the user of this rule) 2105 // <done> 2106 %} 2107 2108 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2109 enc_class OpcSE(immI imm) 2110 %{ 2111 // Emit primary opcode and set sign-extend bit 2112 // Check for 8-bit immediate, and set sign extend bit in opcode 2113 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2114 emit_opcode(cbuf, $primary | 0x02); 2115 } else { 2116 // 32-bit immediate 2117 emit_opcode(cbuf, $primary); 2118 } 2119 %} 2120 2121 enc_class OpcSErm(rRegI dst, immI imm) 2122 %{ 2123 // OpcSEr/m 2124 int dstenc = $dst$$reg; 2125 if (dstenc >= 8) { 2126 emit_opcode(cbuf, Assembler::REX_B); 2127 dstenc -= 8; 2128 } 2129 // Emit primary opcode and set sign-extend bit 2130 // Check for 8-bit immediate, and set sign extend bit in opcode 2131 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2132 emit_opcode(cbuf, $primary | 0x02); 2133 } else { 2134 // 32-bit immediate 2135 emit_opcode(cbuf, $primary); 2136 } 2137 // Emit r/m byte with secondary opcode, after primary opcode. 2138 emit_rm(cbuf, 0x3, $secondary, dstenc); 2139 %} 2140 2141 enc_class OpcSErm_wide(rRegL dst, immI imm) 2142 %{ 2143 // OpcSEr/m 2144 int dstenc = $dst$$reg; 2145 if (dstenc < 8) { 2146 emit_opcode(cbuf, Assembler::REX_W); 2147 } else { 2148 emit_opcode(cbuf, Assembler::REX_WB); 2149 dstenc -= 8; 2150 } 2151 // Emit primary opcode and set sign-extend bit 2152 // Check for 8-bit immediate, and set sign extend bit in opcode 2153 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2154 emit_opcode(cbuf, $primary | 0x02); 2155 } else { 2156 // 32-bit immediate 2157 emit_opcode(cbuf, $primary); 2158 } 2159 // Emit r/m byte with secondary opcode, after primary opcode. 2160 emit_rm(cbuf, 0x3, $secondary, dstenc); 2161 %} 2162 2163 enc_class Con8or32(immI imm) 2164 %{ 2165 // Check for 8-bit immediate, and set sign extend bit in opcode 2166 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2167 $$$emit8$imm$$constant; 2168 } else { 2169 // 32-bit immediate 2170 $$$emit32$imm$$constant; 2171 } 2172 %} 2173 2174 enc_class opc2_reg(rRegI dst) 2175 %{ 2176 // BSWAP 2177 emit_cc(cbuf, $secondary, $dst$$reg); 2178 %} 2179 2180 enc_class opc3_reg(rRegI dst) 2181 %{ 2182 // BSWAP 2183 emit_cc(cbuf, $tertiary, $dst$$reg); 2184 %} 2185 2186 enc_class reg_opc(rRegI div) 2187 %{ 2188 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2189 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2190 %} 2191 2192 enc_class enc_cmov(cmpOp cop) 2193 %{ 2194 // CMOV 2195 $$$emit8$primary; 2196 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2197 %} 2198 2199 enc_class enc_PartialSubtypeCheck() 2200 %{ 2201 Register Rrdi = as_Register(RDI_enc); // result register 2202 Register Rrax = as_Register(RAX_enc); // super class 2203 Register Rrcx = as_Register(RCX_enc); // killed 2204 Register Rrsi = as_Register(RSI_enc); // sub class 2205 Label miss; 2206 const bool set_cond_codes = true; 2207 2208 MacroAssembler _masm(&cbuf); 2209 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2210 NULL, &miss, 2211 /*set_cond_codes:*/ true); 2212 if ($primary) { 2213 __ xorptr(Rrdi, Rrdi); 2214 } 2215 __ bind(miss); 2216 %} 2217 2218 enc_class Java_To_Interpreter(method meth) 2219 %{ 2220 // CALL Java_To_Interpreter 2221 // This is the instruction starting address for relocation info. 2222 cbuf.set_insts_mark(); 2223 $$$emit8$primary; 2224 // CALL directly to the runtime 2225 emit_d32_reloc(cbuf, 2226 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2227 runtime_call_Relocation::spec(), 2228 RELOC_DISP32); 2229 %} 2230 2231 enc_class Java_Static_Call(method meth) 2232 %{ 2233 // JAVA STATIC CALL 2234 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2235 // determine who we intended to call. 2236 cbuf.set_insts_mark(); 2237 $$$emit8$primary; 2238 2239 if (!_method) { 2240 emit_d32_reloc(cbuf, 2241 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2242 runtime_call_Relocation::spec(), 2243 RELOC_DISP32); 2244 } else if (_optimized_virtual) { 2245 emit_d32_reloc(cbuf, 2246 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2247 opt_virtual_call_Relocation::spec(), 2248 RELOC_DISP32); 2249 } else { 2250 emit_d32_reloc(cbuf, 2251 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2252 static_call_Relocation::spec(), 2253 RELOC_DISP32); 2254 } 2255 if (_method) { 2256 // Emit stub for static call 2257 emit_java_to_interp(cbuf); 2258 } 2259 %} 2260 2261 enc_class Java_Dynamic_Call(method meth) 2262 %{ 2263 // JAVA DYNAMIC CALL 2264 // !!!!! 2265 // Generate "movq rax, -1", placeholder instruction to load oop-info 2266 // emit_call_dynamic_prologue( cbuf ); 2267 cbuf.set_insts_mark(); 2268 2269 // movq rax, -1 2270 emit_opcode(cbuf, Assembler::REX_W); 2271 emit_opcode(cbuf, 0xB8 | RAX_enc); 2272 emit_d64_reloc(cbuf, 2273 (int64_t) Universe::non_oop_word(), 2274 oop_Relocation::spec_for_immediate(), RELOC_IMM64); 2275 address virtual_call_oop_addr = cbuf.insts_mark(); 2276 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine 2277 // who we intended to call. 2278 cbuf.set_insts_mark(); 2279 $$$emit8$primary; 2280 emit_d32_reloc(cbuf, 2281 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2282 virtual_call_Relocation::spec(virtual_call_oop_addr), 2283 RELOC_DISP32); 2284 %} 2285 2286 enc_class Java_Compiled_Call(method meth) 2287 %{ 2288 // JAVA COMPILED CALL 2289 int disp = in_bytes(methodOopDesc:: from_compiled_offset()); 2290 2291 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2292 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2293 2294 // callq *disp(%rax) 2295 cbuf.set_insts_mark(); 2296 $$$emit8$primary; 2297 if (disp < 0x80) { 2298 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2299 emit_d8(cbuf, disp); // Displacement 2300 } else { 2301 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2302 emit_d32(cbuf, disp); // Displacement 2303 } 2304 %} 2305 2306 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2307 %{ 2308 // SAL, SAR, SHR 2309 int dstenc = $dst$$reg; 2310 if (dstenc >= 8) { 2311 emit_opcode(cbuf, Assembler::REX_B); 2312 dstenc -= 8; 2313 } 2314 $$$emit8$primary; 2315 emit_rm(cbuf, 0x3, $secondary, dstenc); 2316 $$$emit8$shift$$constant; 2317 %} 2318 2319 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2320 %{ 2321 // SAL, SAR, SHR 2322 int dstenc = $dst$$reg; 2323 if (dstenc < 8) { 2324 emit_opcode(cbuf, Assembler::REX_W); 2325 } else { 2326 emit_opcode(cbuf, Assembler::REX_WB); 2327 dstenc -= 8; 2328 } 2329 $$$emit8$primary; 2330 emit_rm(cbuf, 0x3, $secondary, dstenc); 2331 $$$emit8$shift$$constant; 2332 %} 2333 2334 enc_class load_immI(rRegI dst, immI src) 2335 %{ 2336 int dstenc = $dst$$reg; 2337 if (dstenc >= 8) { 2338 emit_opcode(cbuf, Assembler::REX_B); 2339 dstenc -= 8; 2340 } 2341 emit_opcode(cbuf, 0xB8 | dstenc); 2342 $$$emit32$src$$constant; 2343 %} 2344 2345 enc_class load_immL(rRegL dst, immL src) 2346 %{ 2347 int dstenc = $dst$$reg; 2348 if (dstenc < 8) { 2349 emit_opcode(cbuf, Assembler::REX_W); 2350 } else { 2351 emit_opcode(cbuf, Assembler::REX_WB); 2352 dstenc -= 8; 2353 } 2354 emit_opcode(cbuf, 0xB8 | dstenc); 2355 emit_d64(cbuf, $src$$constant); 2356 %} 2357 2358 enc_class load_immUL32(rRegL dst, immUL32 src) 2359 %{ 2360 // same as load_immI, but this time we care about zeroes in the high word 2361 int dstenc = $dst$$reg; 2362 if (dstenc >= 8) { 2363 emit_opcode(cbuf, Assembler::REX_B); 2364 dstenc -= 8; 2365 } 2366 emit_opcode(cbuf, 0xB8 | dstenc); 2367 $$$emit32$src$$constant; 2368 %} 2369 2370 enc_class load_immL32(rRegL dst, immL32 src) 2371 %{ 2372 int dstenc = $dst$$reg; 2373 if (dstenc < 8) { 2374 emit_opcode(cbuf, Assembler::REX_W); 2375 } else { 2376 emit_opcode(cbuf, Assembler::REX_WB); 2377 dstenc -= 8; 2378 } 2379 emit_opcode(cbuf, 0xC7); 2380 emit_rm(cbuf, 0x03, 0x00, dstenc); 2381 $$$emit32$src$$constant; 2382 %} 2383 2384 enc_class load_immP31(rRegP dst, immP32 src) 2385 %{ 2386 // same as load_immI, but this time we care about zeroes in the high word 2387 int dstenc = $dst$$reg; 2388 if (dstenc >= 8) { 2389 emit_opcode(cbuf, Assembler::REX_B); 2390 dstenc -= 8; 2391 } 2392 emit_opcode(cbuf, 0xB8 | dstenc); 2393 $$$emit32$src$$constant; 2394 %} 2395 2396 enc_class load_immP(rRegP dst, immP src) 2397 %{ 2398 int dstenc = $dst$$reg; 2399 if (dstenc < 8) { 2400 emit_opcode(cbuf, Assembler::REX_W); 2401 } else { 2402 emit_opcode(cbuf, Assembler::REX_WB); 2403 dstenc -= 8; 2404 } 2405 emit_opcode(cbuf, 0xB8 | dstenc); 2406 // This next line should be generated from ADLC 2407 if ($src->constant_is_oop()) { 2408 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64); 2409 } else { 2410 emit_d64(cbuf, $src$$constant); 2411 } 2412 %} 2413 2414 enc_class Con32(immI src) 2415 %{ 2416 // Output immediate 2417 $$$emit32$src$$constant; 2418 %} 2419 2420 enc_class Con64(immL src) 2421 %{ 2422 // Output immediate 2423 emit_d64($src$$constant); 2424 %} 2425 2426 enc_class Con32F_as_bits(immF src) 2427 %{ 2428 // Output Float immediate bits 2429 jfloat jf = $src$$constant; 2430 jint jf_as_bits = jint_cast(jf); 2431 emit_d32(cbuf, jf_as_bits); 2432 %} 2433 2434 enc_class Con16(immI src) 2435 %{ 2436 // Output immediate 2437 $$$emit16$src$$constant; 2438 %} 2439 2440 // How is this different from Con32??? XXX 2441 enc_class Con_d32(immI src) 2442 %{ 2443 emit_d32(cbuf,$src$$constant); 2444 %} 2445 2446 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2447 // Output immediate memory reference 2448 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2449 emit_d32(cbuf, 0x00); 2450 %} 2451 2452 enc_class lock_prefix() 2453 %{ 2454 if (os::is_MP()) { 2455 emit_opcode(cbuf, 0xF0); // lock 2456 } 2457 %} 2458 2459 enc_class REX_mem(memory mem) 2460 %{ 2461 if ($mem$$base >= 8) { 2462 if ($mem$$index < 8) { 2463 emit_opcode(cbuf, Assembler::REX_B); 2464 } else { 2465 emit_opcode(cbuf, Assembler::REX_XB); 2466 } 2467 } else { 2468 if ($mem$$index >= 8) { 2469 emit_opcode(cbuf, Assembler::REX_X); 2470 } 2471 } 2472 %} 2473 2474 enc_class REX_mem_wide(memory mem) 2475 %{ 2476 if ($mem$$base >= 8) { 2477 if ($mem$$index < 8) { 2478 emit_opcode(cbuf, Assembler::REX_WB); 2479 } else { 2480 emit_opcode(cbuf, Assembler::REX_WXB); 2481 } 2482 } else { 2483 if ($mem$$index < 8) { 2484 emit_opcode(cbuf, Assembler::REX_W); 2485 } else { 2486 emit_opcode(cbuf, Assembler::REX_WX); 2487 } 2488 } 2489 %} 2490 2491 // for byte regs 2492 enc_class REX_breg(rRegI reg) 2493 %{ 2494 if ($reg$$reg >= 4) { 2495 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2496 } 2497 %} 2498 2499 // for byte regs 2500 enc_class REX_reg_breg(rRegI dst, rRegI src) 2501 %{ 2502 if ($dst$$reg < 8) { 2503 if ($src$$reg >= 4) { 2504 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2505 } 2506 } else { 2507 if ($src$$reg < 8) { 2508 emit_opcode(cbuf, Assembler::REX_R); 2509 } else { 2510 emit_opcode(cbuf, Assembler::REX_RB); 2511 } 2512 } 2513 %} 2514 2515 // for byte regs 2516 enc_class REX_breg_mem(rRegI reg, memory mem) 2517 %{ 2518 if ($reg$$reg < 8) { 2519 if ($mem$$base < 8) { 2520 if ($mem$$index >= 8) { 2521 emit_opcode(cbuf, Assembler::REX_X); 2522 } else if ($reg$$reg >= 4) { 2523 emit_opcode(cbuf, Assembler::REX); 2524 } 2525 } else { 2526 if ($mem$$index < 8) { 2527 emit_opcode(cbuf, Assembler::REX_B); 2528 } else { 2529 emit_opcode(cbuf, Assembler::REX_XB); 2530 } 2531 } 2532 } else { 2533 if ($mem$$base < 8) { 2534 if ($mem$$index < 8) { 2535 emit_opcode(cbuf, Assembler::REX_R); 2536 } else { 2537 emit_opcode(cbuf, Assembler::REX_RX); 2538 } 2539 } else { 2540 if ($mem$$index < 8) { 2541 emit_opcode(cbuf, Assembler::REX_RB); 2542 } else { 2543 emit_opcode(cbuf, Assembler::REX_RXB); 2544 } 2545 } 2546 } 2547 %} 2548 2549 enc_class REX_reg(rRegI reg) 2550 %{ 2551 if ($reg$$reg >= 8) { 2552 emit_opcode(cbuf, Assembler::REX_B); 2553 } 2554 %} 2555 2556 enc_class REX_reg_wide(rRegI reg) 2557 %{ 2558 if ($reg$$reg < 8) { 2559 emit_opcode(cbuf, Assembler::REX_W); 2560 } else { 2561 emit_opcode(cbuf, Assembler::REX_WB); 2562 } 2563 %} 2564 2565 enc_class REX_reg_reg(rRegI dst, rRegI src) 2566 %{ 2567 if ($dst$$reg < 8) { 2568 if ($src$$reg >= 8) { 2569 emit_opcode(cbuf, Assembler::REX_B); 2570 } 2571 } else { 2572 if ($src$$reg < 8) { 2573 emit_opcode(cbuf, Assembler::REX_R); 2574 } else { 2575 emit_opcode(cbuf, Assembler::REX_RB); 2576 } 2577 } 2578 %} 2579 2580 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2581 %{ 2582 if ($dst$$reg < 8) { 2583 if ($src$$reg < 8) { 2584 emit_opcode(cbuf, Assembler::REX_W); 2585 } else { 2586 emit_opcode(cbuf, Assembler::REX_WB); 2587 } 2588 } else { 2589 if ($src$$reg < 8) { 2590 emit_opcode(cbuf, Assembler::REX_WR); 2591 } else { 2592 emit_opcode(cbuf, Assembler::REX_WRB); 2593 } 2594 } 2595 %} 2596 2597 enc_class REX_reg_mem(rRegI reg, memory mem) 2598 %{ 2599 if ($reg$$reg < 8) { 2600 if ($mem$$base < 8) { 2601 if ($mem$$index >= 8) { 2602 emit_opcode(cbuf, Assembler::REX_X); 2603 } 2604 } else { 2605 if ($mem$$index < 8) { 2606 emit_opcode(cbuf, Assembler::REX_B); 2607 } else { 2608 emit_opcode(cbuf, Assembler::REX_XB); 2609 } 2610 } 2611 } else { 2612 if ($mem$$base < 8) { 2613 if ($mem$$index < 8) { 2614 emit_opcode(cbuf, Assembler::REX_R); 2615 } else { 2616 emit_opcode(cbuf, Assembler::REX_RX); 2617 } 2618 } else { 2619 if ($mem$$index < 8) { 2620 emit_opcode(cbuf, Assembler::REX_RB); 2621 } else { 2622 emit_opcode(cbuf, Assembler::REX_RXB); 2623 } 2624 } 2625 } 2626 %} 2627 2628 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2629 %{ 2630 if ($reg$$reg < 8) { 2631 if ($mem$$base < 8) { 2632 if ($mem$$index < 8) { 2633 emit_opcode(cbuf, Assembler::REX_W); 2634 } else { 2635 emit_opcode(cbuf, Assembler::REX_WX); 2636 } 2637 } else { 2638 if ($mem$$index < 8) { 2639 emit_opcode(cbuf, Assembler::REX_WB); 2640 } else { 2641 emit_opcode(cbuf, Assembler::REX_WXB); 2642 } 2643 } 2644 } else { 2645 if ($mem$$base < 8) { 2646 if ($mem$$index < 8) { 2647 emit_opcode(cbuf, Assembler::REX_WR); 2648 } else { 2649 emit_opcode(cbuf, Assembler::REX_WRX); 2650 } 2651 } else { 2652 if ($mem$$index < 8) { 2653 emit_opcode(cbuf, Assembler::REX_WRB); 2654 } else { 2655 emit_opcode(cbuf, Assembler::REX_WRXB); 2656 } 2657 } 2658 } 2659 %} 2660 2661 enc_class reg_mem(rRegI ereg, memory mem) 2662 %{ 2663 // High registers handle in encode_RegMem 2664 int reg = $ereg$$reg; 2665 int base = $mem$$base; 2666 int index = $mem$$index; 2667 int scale = $mem$$scale; 2668 int disp = $mem$$disp; 2669 bool disp_is_oop = $mem->disp_is_oop(); 2670 2671 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_is_oop); 2672 %} 2673 2674 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2675 %{ 2676 int rm_byte_opcode = $rm_opcode$$constant; 2677 2678 // High registers handle in encode_RegMem 2679 int base = $mem$$base; 2680 int index = $mem$$index; 2681 int scale = $mem$$scale; 2682 int displace = $mem$$disp; 2683 2684 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when 2685 // working with static 2686 // globals 2687 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2688 disp_is_oop); 2689 %} 2690 2691 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2692 %{ 2693 int reg_encoding = $dst$$reg; 2694 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2695 int index = 0x04; // 0x04 indicates no index 2696 int scale = 0x00; // 0x00 indicates no scale 2697 int displace = $src1$$constant; // 0x00 indicates no displacement 2698 bool disp_is_oop = false; 2699 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2700 disp_is_oop); 2701 %} 2702 2703 enc_class neg_reg(rRegI dst) 2704 %{ 2705 int dstenc = $dst$$reg; 2706 if (dstenc >= 8) { 2707 emit_opcode(cbuf, Assembler::REX_B); 2708 dstenc -= 8; 2709 } 2710 // NEG $dst 2711 emit_opcode(cbuf, 0xF7); 2712 emit_rm(cbuf, 0x3, 0x03, dstenc); 2713 %} 2714 2715 enc_class neg_reg_wide(rRegI dst) 2716 %{ 2717 int dstenc = $dst$$reg; 2718 if (dstenc < 8) { 2719 emit_opcode(cbuf, Assembler::REX_W); 2720 } else { 2721 emit_opcode(cbuf, Assembler::REX_WB); 2722 dstenc -= 8; 2723 } 2724 // NEG $dst 2725 emit_opcode(cbuf, 0xF7); 2726 emit_rm(cbuf, 0x3, 0x03, dstenc); 2727 %} 2728 2729 enc_class setLT_reg(rRegI dst) 2730 %{ 2731 int dstenc = $dst$$reg; 2732 if (dstenc >= 8) { 2733 emit_opcode(cbuf, Assembler::REX_B); 2734 dstenc -= 8; 2735 } else if (dstenc >= 4) { 2736 emit_opcode(cbuf, Assembler::REX); 2737 } 2738 // SETLT $dst 2739 emit_opcode(cbuf, 0x0F); 2740 emit_opcode(cbuf, 0x9C); 2741 emit_rm(cbuf, 0x3, 0x0, dstenc); 2742 %} 2743 2744 enc_class setNZ_reg(rRegI dst) 2745 %{ 2746 int dstenc = $dst$$reg; 2747 if (dstenc >= 8) { 2748 emit_opcode(cbuf, Assembler::REX_B); 2749 dstenc -= 8; 2750 } else if (dstenc >= 4) { 2751 emit_opcode(cbuf, Assembler::REX); 2752 } 2753 // SETNZ $dst 2754 emit_opcode(cbuf, 0x0F); 2755 emit_opcode(cbuf, 0x95); 2756 emit_rm(cbuf, 0x3, 0x0, dstenc); 2757 %} 2758 2759 2760 // Compare the lonogs and set -1, 0, or 1 into dst 2761 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2762 %{ 2763 int src1enc = $src1$$reg; 2764 int src2enc = $src2$$reg; 2765 int dstenc = $dst$$reg; 2766 2767 // cmpq $src1, $src2 2768 if (src1enc < 8) { 2769 if (src2enc < 8) { 2770 emit_opcode(cbuf, Assembler::REX_W); 2771 } else { 2772 emit_opcode(cbuf, Assembler::REX_WB); 2773 } 2774 } else { 2775 if (src2enc < 8) { 2776 emit_opcode(cbuf, Assembler::REX_WR); 2777 } else { 2778 emit_opcode(cbuf, Assembler::REX_WRB); 2779 } 2780 } 2781 emit_opcode(cbuf, 0x3B); 2782 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2783 2784 // movl $dst, -1 2785 if (dstenc >= 8) { 2786 emit_opcode(cbuf, Assembler::REX_B); 2787 } 2788 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2789 emit_d32(cbuf, -1); 2790 2791 // jl,s done 2792 emit_opcode(cbuf, 0x7C); 2793 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2794 2795 // setne $dst 2796 if (dstenc >= 4) { 2797 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2798 } 2799 emit_opcode(cbuf, 0x0F); 2800 emit_opcode(cbuf, 0x95); 2801 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2802 2803 // movzbl $dst, $dst 2804 if (dstenc >= 4) { 2805 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2806 } 2807 emit_opcode(cbuf, 0x0F); 2808 emit_opcode(cbuf, 0xB6); 2809 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2810 %} 2811 2812 enc_class Push_ResultXD(regD dst) %{ 2813 MacroAssembler _masm(&cbuf); 2814 __ fstp_d(Address(rsp, 0)); 2815 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2816 __ addptr(rsp, 8); 2817 %} 2818 2819 enc_class Push_SrcXD(regD src) %{ 2820 MacroAssembler _masm(&cbuf); 2821 __ subptr(rsp, 8); 2822 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2823 __ fld_d(Address(rsp, 0)); 2824 %} 2825 2826 2827 // obj: object to lock 2828 // box: box address (header location) -- killed 2829 // tmp: rax -- killed 2830 // scr: rbx -- killed 2831 // 2832 // What follows is a direct transliteration of fast_lock() and fast_unlock() 2833 // from i486.ad. See that file for comments. 2834 // TODO: where possible switch from movq (r, 0) to movl(r,0) and 2835 // use the shorter encoding. (Movl clears the high-order 32-bits). 2836 2837 2838 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr) 2839 %{ 2840 Register objReg = as_Register((int)$obj$$reg); 2841 Register boxReg = as_Register((int)$box$$reg); 2842 Register tmpReg = as_Register($tmp$$reg); 2843 Register scrReg = as_Register($scr$$reg); 2844 MacroAssembler masm(&cbuf); 2845 2846 // Verify uniqueness of register assignments -- necessary but not sufficient 2847 assert (objReg != boxReg && objReg != tmpReg && 2848 objReg != scrReg && tmpReg != scrReg, "invariant") ; 2849 2850 if (_counters != NULL) { 2851 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 2852 } 2853 if (EmitSync & 1) { 2854 // Without cast to int32_t a movptr will destroy r10 which is typically obj 2855 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 2856 masm.cmpptr(rsp, (int32_t)NULL_WORD) ; 2857 } else 2858 if (EmitSync & 2) { 2859 Label DONE_LABEL; 2860 if (UseBiasedLocking) { 2861 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 2862 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 2863 } 2864 // QQQ was movl... 2865 masm.movptr(tmpReg, 0x1); 2866 masm.orptr(tmpReg, Address(objReg, 0)); 2867 masm.movptr(Address(boxReg, 0), tmpReg); 2868 if (os::is_MP()) { 2869 masm.lock(); 2870 } 2871 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 2872 masm.jcc(Assembler::equal, DONE_LABEL); 2873 2874 // Recursive locking 2875 masm.subptr(tmpReg, rsp); 2876 masm.andptr(tmpReg, 7 - os::vm_page_size()); 2877 masm.movptr(Address(boxReg, 0), tmpReg); 2878 2879 masm.bind(DONE_LABEL); 2880 masm.nop(); // avoid branch to branch 2881 } else { 2882 Label DONE_LABEL, IsInflated, Egress; 2883 2884 masm.movptr(tmpReg, Address(objReg, 0)) ; 2885 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased 2886 masm.jcc (Assembler::notZero, IsInflated) ; 2887 2888 // it's stack-locked, biased or neutral 2889 // TODO: optimize markword triage order to reduce the number of 2890 // conditional branches in the most common cases. 2891 // Beware -- there's a subtle invariant that fetch of the markword 2892 // at [FETCH], below, will never observe a biased encoding (*101b). 2893 // If this invariant is not held we'll suffer exclusion (safety) failure. 2894 2895 if (UseBiasedLocking && !UseOptoBiasInlining) { 2896 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); 2897 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 2898 } 2899 2900 // was q will it destroy high? 2901 masm.orl (tmpReg, 1) ; 2902 masm.movptr(Address(boxReg, 0), tmpReg) ; 2903 if (os::is_MP()) { masm.lock(); } 2904 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 2905 if (_counters != NULL) { 2906 masm.cond_inc32(Assembler::equal, 2907 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 2908 } 2909 masm.jcc (Assembler::equal, DONE_LABEL); 2910 2911 // Recursive locking 2912 masm.subptr(tmpReg, rsp); 2913 masm.andptr(tmpReg, 7 - os::vm_page_size()); 2914 masm.movptr(Address(boxReg, 0), tmpReg); 2915 if (_counters != NULL) { 2916 masm.cond_inc32(Assembler::equal, 2917 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 2918 } 2919 masm.jmp (DONE_LABEL) ; 2920 2921 masm.bind (IsInflated) ; 2922 // It's inflated 2923 2924 // TODO: someday avoid the ST-before-CAS penalty by 2925 // relocating (deferring) the following ST. 2926 // We should also think about trying a CAS without having 2927 // fetched _owner. If the CAS is successful we may 2928 // avoid an RTO->RTS upgrade on the $line. 2929 // Without cast to int32_t a movptr will destroy r10 which is typically obj 2930 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 2931 2932 masm.mov (boxReg, tmpReg) ; 2933 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2934 masm.testptr(tmpReg, tmpReg) ; 2935 masm.jcc (Assembler::notZero, DONE_LABEL) ; 2936 2937 // It's inflated and appears unlocked 2938 if (os::is_MP()) { masm.lock(); } 2939 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2940 // Intentional fall-through into DONE_LABEL ... 2941 2942 masm.bind (DONE_LABEL) ; 2943 masm.nop () ; // avoid jmp to jmp 2944 } 2945 %} 2946 2947 // obj: object to unlock 2948 // box: box address (displaced header location), killed 2949 // RBX: killed tmp; cannot be obj nor box 2950 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp) 2951 %{ 2952 2953 Register objReg = as_Register($obj$$reg); 2954 Register boxReg = as_Register($box$$reg); 2955 Register tmpReg = as_Register($tmp$$reg); 2956 MacroAssembler masm(&cbuf); 2957 2958 if (EmitSync & 4) { 2959 masm.cmpptr(rsp, 0) ; 2960 } else 2961 if (EmitSync & 8) { 2962 Label DONE_LABEL; 2963 if (UseBiasedLocking) { 2964 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 2965 } 2966 2967 // Check whether the displaced header is 0 2968 //(=> recursive unlock) 2969 masm.movptr(tmpReg, Address(boxReg, 0)); 2970 masm.testptr(tmpReg, tmpReg); 2971 masm.jcc(Assembler::zero, DONE_LABEL); 2972 2973 // If not recursive lock, reset the header to displaced header 2974 if (os::is_MP()) { 2975 masm.lock(); 2976 } 2977 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 2978 masm.bind(DONE_LABEL); 2979 masm.nop(); // avoid branch to branch 2980 } else { 2981 Label DONE_LABEL, Stacked, CheckSucc ; 2982 2983 if (UseBiasedLocking && !UseOptoBiasInlining) { 2984 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 2985 } 2986 2987 masm.movptr(tmpReg, Address(objReg, 0)) ; 2988 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; 2989 masm.jcc (Assembler::zero, DONE_LABEL) ; 2990 masm.testl (tmpReg, 0x02) ; 2991 masm.jcc (Assembler::zero, Stacked) ; 2992 2993 // It's inflated 2994 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2995 masm.xorptr(boxReg, r15_thread) ; 2996 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 2997 masm.jcc (Assembler::notZero, DONE_LABEL) ; 2998 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 2999 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 3000 masm.jcc (Assembler::notZero, CheckSucc) ; 3001 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3002 masm.jmp (DONE_LABEL) ; 3003 3004 if ((EmitSync & 65536) == 0) { 3005 Label LSuccess, LGoSlowPath ; 3006 masm.bind (CheckSucc) ; 3007 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3008 masm.jcc (Assembler::zero, LGoSlowPath) ; 3009 3010 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the 3011 // the explicit ST;MEMBAR combination, but masm doesn't currently support 3012 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc 3013 // are all faster when the write buffer is populated. 3014 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3015 if (os::is_MP()) { 3016 masm.lock () ; masm.addl (Address(rsp, 0), 0) ; 3017 } 3018 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3019 masm.jcc (Assembler::notZero, LSuccess) ; 3020 3021 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX 3022 if (os::is_MP()) { masm.lock(); } 3023 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3024 masm.jcc (Assembler::notEqual, LSuccess) ; 3025 // Intentional fall-through into slow-path 3026 3027 masm.bind (LGoSlowPath) ; 3028 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure 3029 masm.jmp (DONE_LABEL) ; 3030 3031 masm.bind (LSuccess) ; 3032 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success 3033 masm.jmp (DONE_LABEL) ; 3034 } 3035 3036 masm.bind (Stacked) ; 3037 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch 3038 if (os::is_MP()) { masm.lock(); } 3039 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3040 3041 if (EmitSync & 65536) { 3042 masm.bind (CheckSucc) ; 3043 } 3044 masm.bind(DONE_LABEL); 3045 if (EmitSync & 32768) { 3046 masm.nop(); // avoid branch to branch 3047 } 3048 } 3049 %} 3050 3051 3052 enc_class enc_rethrow() 3053 %{ 3054 cbuf.set_insts_mark(); 3055 emit_opcode(cbuf, 0xE9); // jmp entry 3056 emit_d32_reloc(cbuf, 3057 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 3058 runtime_call_Relocation::spec(), 3059 RELOC_DISP32); 3060 %} 3061 3062 %} 3063 3064 3065 3066 //----------FRAME-------------------------------------------------------------- 3067 // Definition of frame structure and management information. 3068 // 3069 // S T A C K L A Y O U T Allocators stack-slot number 3070 // | (to get allocators register number 3071 // G Owned by | | v add OptoReg::stack0()) 3072 // r CALLER | | 3073 // o | +--------+ pad to even-align allocators stack-slot 3074 // w V | pad0 | numbers; owned by CALLER 3075 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3076 // h ^ | in | 5 3077 // | | args | 4 Holes in incoming args owned by SELF 3078 // | | | | 3 3079 // | | +--------+ 3080 // V | | old out| Empty on Intel, window on Sparc 3081 // | old |preserve| Must be even aligned. 3082 // | SP-+--------+----> Matcher::_old_SP, even aligned 3083 // | | in | 3 area for Intel ret address 3084 // Owned by |preserve| Empty on Sparc. 3085 // SELF +--------+ 3086 // | | pad2 | 2 pad to align old SP 3087 // | +--------+ 1 3088 // | | locks | 0 3089 // | +--------+----> OptoReg::stack0(), even aligned 3090 // | | pad1 | 11 pad to align new SP 3091 // | +--------+ 3092 // | | | 10 3093 // | | spills | 9 spills 3094 // V | | 8 (pad0 slot for callee) 3095 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3096 // ^ | out | 7 3097 // | | args | 6 Holes in outgoing args owned by CALLEE 3098 // Owned by +--------+ 3099 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3100 // | new |preserve| Must be even-aligned. 3101 // | SP-+--------+----> Matcher::_new_SP, even aligned 3102 // | | | 3103 // 3104 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3105 // known from SELF's arguments and the Java calling convention. 3106 // Region 6-7 is determined per call site. 3107 // Note 2: If the calling convention leaves holes in the incoming argument 3108 // area, those holes are owned by SELF. Holes in the outgoing area 3109 // are owned by the CALLEE. Holes should not be nessecary in the 3110 // incoming area, as the Java calling convention is completely under 3111 // the control of the AD file. Doubles can be sorted and packed to 3112 // avoid holes. Holes in the outgoing arguments may be nessecary for 3113 // varargs C calling conventions. 3114 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3115 // even aligned with pad0 as needed. 3116 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3117 // region 6-11 is even aligned; it may be padded out more so that 3118 // the region from SP to FP meets the minimum stack alignment. 3119 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3120 // alignment. Region 11, pad1, may be dynamically extended so that 3121 // SP meets the minimum alignment. 3122 3123 frame 3124 %{ 3125 // What direction does stack grow in (assumed to be same for C & Java) 3126 stack_direction(TOWARDS_LOW); 3127 3128 // These three registers define part of the calling convention 3129 // between compiled code and the interpreter. 3130 inline_cache_reg(RAX); // Inline Cache Register 3131 interpreter_method_oop_reg(RBX); // Method Oop Register when 3132 // calling interpreter 3133 3134 // Optional: name the operand used by cisc-spilling to access 3135 // [stack_pointer + offset] 3136 cisc_spilling_operand_name(indOffset32); 3137 3138 // Number of stack slots consumed by locking an object 3139 sync_stack_slots(2); 3140 3141 // Compiled code's Frame Pointer 3142 frame_pointer(RSP); 3143 3144 // Interpreter stores its frame pointer in a register which is 3145 // stored to the stack by I2CAdaptors. 3146 // I2CAdaptors convert from interpreted java to compiled java. 3147 interpreter_frame_pointer(RBP); 3148 3149 // Stack alignment requirement 3150 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3151 3152 // Number of stack slots between incoming argument block and the start of 3153 // a new frame. The PROLOG must add this many slots to the stack. The 3154 // EPILOG must remove this many slots. amd64 needs two slots for 3155 // return address. 3156 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 3157 3158 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3159 // for calls to C. Supports the var-args backing area for register parms. 3160 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3161 3162 // The after-PROLOG location of the return address. Location of 3163 // return address specifies a type (REG or STACK) and a number 3164 // representing the register number (i.e. - use a register name) or 3165 // stack slot. 3166 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3167 // Otherwise, it is above the locks and verification slot and alignment word 3168 return_addr(STACK - 2 + 3169 round_to((Compile::current()->in_preserve_stack_slots() + 3170 Compile::current()->fixed_slots()), 3171 stack_alignment_in_slots())); 3172 3173 // Body of function which returns an integer array locating 3174 // arguments either in registers or in stack slots. Passed an array 3175 // of ideal registers called "sig" and a "length" count. Stack-slot 3176 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3177 // arguments for a CALLEE. Incoming stack arguments are 3178 // automatically biased by the preserve_stack_slots field above. 3179 3180 calling_convention 3181 %{ 3182 // No difference between ingoing/outgoing just pass false 3183 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3184 %} 3185 3186 c_calling_convention 3187 %{ 3188 // This is obviously always outgoing 3189 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); 3190 %} 3191 3192 // Location of compiled Java return values. Same as C for now. 3193 return_value 3194 %{ 3195 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3196 "only return normal values"); 3197 3198 static const int lo[Op_RegL + 1] = { 3199 0, 3200 0, 3201 RAX_num, // Op_RegN 3202 RAX_num, // Op_RegI 3203 RAX_num, // Op_RegP 3204 XMM0_num, // Op_RegF 3205 XMM0_num, // Op_RegD 3206 RAX_num // Op_RegL 3207 }; 3208 static const int hi[Op_RegL + 1] = { 3209 0, 3210 0, 3211 OptoReg::Bad, // Op_RegN 3212 OptoReg::Bad, // Op_RegI 3213 RAX_H_num, // Op_RegP 3214 OptoReg::Bad, // Op_RegF 3215 XMM0_H_num, // Op_RegD 3216 RAX_H_num // Op_RegL 3217 }; 3218 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 1, "missing type"); 3219 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3220 %} 3221 %} 3222 3223 //----------ATTRIBUTES--------------------------------------------------------- 3224 //----------Operand Attributes------------------------------------------------- 3225 op_attrib op_cost(0); // Required cost attribute 3226 3227 //----------Instruction Attributes--------------------------------------------- 3228 ins_attrib ins_cost(100); // Required cost attribute 3229 ins_attrib ins_size(8); // Required size attribute (in bits) 3230 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3231 // a non-matching short branch variant 3232 // of some long branch? 3233 ins_attrib ins_alignment(1); // Required alignment attribute (must 3234 // be a power of 2) specifies the 3235 // alignment that some part of the 3236 // instruction (not necessarily the 3237 // start) requires. If > 1, a 3238 // compute_padding() function must be 3239 // provided for the instruction 3240 3241 //----------OPERANDS----------------------------------------------------------- 3242 // Operand definitions must precede instruction definitions for correct parsing 3243 // in the ADLC because operands constitute user defined types which are used in 3244 // instruction definitions. 3245 3246 //----------Simple Operands---------------------------------------------------- 3247 // Immediate Operands 3248 // Integer Immediate 3249 operand immI() 3250 %{ 3251 match(ConI); 3252 3253 op_cost(10); 3254 format %{ %} 3255 interface(CONST_INTER); 3256 %} 3257 3258 // Constant for test vs zero 3259 operand immI0() 3260 %{ 3261 predicate(n->get_int() == 0); 3262 match(ConI); 3263 3264 op_cost(0); 3265 format %{ %} 3266 interface(CONST_INTER); 3267 %} 3268 3269 // Constant for increment 3270 operand immI1() 3271 %{ 3272 predicate(n->get_int() == 1); 3273 match(ConI); 3274 3275 op_cost(0); 3276 format %{ %} 3277 interface(CONST_INTER); 3278 %} 3279 3280 // Constant for decrement 3281 operand immI_M1() 3282 %{ 3283 predicate(n->get_int() == -1); 3284 match(ConI); 3285 3286 op_cost(0); 3287 format %{ %} 3288 interface(CONST_INTER); 3289 %} 3290 3291 // Valid scale values for addressing modes 3292 operand immI2() 3293 %{ 3294 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3295 match(ConI); 3296 3297 format %{ %} 3298 interface(CONST_INTER); 3299 %} 3300 3301 operand immI8() 3302 %{ 3303 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 3304 match(ConI); 3305 3306 op_cost(5); 3307 format %{ %} 3308 interface(CONST_INTER); 3309 %} 3310 3311 operand immI16() 3312 %{ 3313 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 3314 match(ConI); 3315 3316 op_cost(10); 3317 format %{ %} 3318 interface(CONST_INTER); 3319 %} 3320 3321 // Constant for long shifts 3322 operand immI_32() 3323 %{ 3324 predicate( n->get_int() == 32 ); 3325 match(ConI); 3326 3327 op_cost(0); 3328 format %{ %} 3329 interface(CONST_INTER); 3330 %} 3331 3332 // Constant for long shifts 3333 operand immI_64() 3334 %{ 3335 predicate( n->get_int() == 64 ); 3336 match(ConI); 3337 3338 op_cost(0); 3339 format %{ %} 3340 interface(CONST_INTER); 3341 %} 3342 3343 // Pointer Immediate 3344 operand immP() 3345 %{ 3346 match(ConP); 3347 3348 op_cost(10); 3349 format %{ %} 3350 interface(CONST_INTER); 3351 %} 3352 3353 // NULL Pointer Immediate 3354 operand immP0() 3355 %{ 3356 predicate(n->get_ptr() == 0); 3357 match(ConP); 3358 3359 op_cost(5); 3360 format %{ %} 3361 interface(CONST_INTER); 3362 %} 3363 3364 operand immP_poll() %{ 3365 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page()); 3366 match(ConP); 3367 3368 // formats are generated automatically for constants and base registers 3369 format %{ %} 3370 interface(CONST_INTER); 3371 %} 3372 3373 // Pointer Immediate 3374 operand immN() %{ 3375 match(ConN); 3376 3377 op_cost(10); 3378 format %{ %} 3379 interface(CONST_INTER); 3380 %} 3381 3382 // NULL Pointer Immediate 3383 operand immN0() %{ 3384 predicate(n->get_narrowcon() == 0); 3385 match(ConN); 3386 3387 op_cost(5); 3388 format %{ %} 3389 interface(CONST_INTER); 3390 %} 3391 3392 operand immP31() 3393 %{ 3394 predicate(!n->as_Type()->type()->isa_oopptr() 3395 && (n->get_ptr() >> 31) == 0); 3396 match(ConP); 3397 3398 op_cost(5); 3399 format %{ %} 3400 interface(CONST_INTER); 3401 %} 3402 3403 3404 // Long Immediate 3405 operand immL() 3406 %{ 3407 match(ConL); 3408 3409 op_cost(20); 3410 format %{ %} 3411 interface(CONST_INTER); 3412 %} 3413 3414 // Long Immediate 8-bit 3415 operand immL8() 3416 %{ 3417 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3418 match(ConL); 3419 3420 op_cost(5); 3421 format %{ %} 3422 interface(CONST_INTER); 3423 %} 3424 3425 // Long Immediate 32-bit unsigned 3426 operand immUL32() 3427 %{ 3428 predicate(n->get_long() == (unsigned int) (n->get_long())); 3429 match(ConL); 3430 3431 op_cost(10); 3432 format %{ %} 3433 interface(CONST_INTER); 3434 %} 3435 3436 // Long Immediate 32-bit signed 3437 operand immL32() 3438 %{ 3439 predicate(n->get_long() == (int) (n->get_long())); 3440 match(ConL); 3441 3442 op_cost(15); 3443 format %{ %} 3444 interface(CONST_INTER); 3445 %} 3446 3447 // Long Immediate zero 3448 operand immL0() 3449 %{ 3450 predicate(n->get_long() == 0L); 3451 match(ConL); 3452 3453 op_cost(10); 3454 format %{ %} 3455 interface(CONST_INTER); 3456 %} 3457 3458 // Constant for increment 3459 operand immL1() 3460 %{ 3461 predicate(n->get_long() == 1); 3462 match(ConL); 3463 3464 format %{ %} 3465 interface(CONST_INTER); 3466 %} 3467 3468 // Constant for decrement 3469 operand immL_M1() 3470 %{ 3471 predicate(n->get_long() == -1); 3472 match(ConL); 3473 3474 format %{ %} 3475 interface(CONST_INTER); 3476 %} 3477 3478 // Long Immediate: the value 10 3479 operand immL10() 3480 %{ 3481 predicate(n->get_long() == 10); 3482 match(ConL); 3483 3484 format %{ %} 3485 interface(CONST_INTER); 3486 %} 3487 3488 // Long immediate from 0 to 127. 3489 // Used for a shorter form of long mul by 10. 3490 operand immL_127() 3491 %{ 3492 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3493 match(ConL); 3494 3495 op_cost(10); 3496 format %{ %} 3497 interface(CONST_INTER); 3498 %} 3499 3500 // Long Immediate: low 32-bit mask 3501 operand immL_32bits() 3502 %{ 3503 predicate(n->get_long() == 0xFFFFFFFFL); 3504 match(ConL); 3505 op_cost(20); 3506 3507 format %{ %} 3508 interface(CONST_INTER); 3509 %} 3510 3511 // Float Immediate zero 3512 operand immF0() 3513 %{ 3514 predicate(jint_cast(n->getf()) == 0); 3515 match(ConF); 3516 3517 op_cost(5); 3518 format %{ %} 3519 interface(CONST_INTER); 3520 %} 3521 3522 // Float Immediate 3523 operand immF() 3524 %{ 3525 match(ConF); 3526 3527 op_cost(15); 3528 format %{ %} 3529 interface(CONST_INTER); 3530 %} 3531 3532 // Double Immediate zero 3533 operand immD0() 3534 %{ 3535 predicate(jlong_cast(n->getd()) == 0); 3536 match(ConD); 3537 3538 op_cost(5); 3539 format %{ %} 3540 interface(CONST_INTER); 3541 %} 3542 3543 // Double Immediate 3544 operand immD() 3545 %{ 3546 match(ConD); 3547 3548 op_cost(15); 3549 format %{ %} 3550 interface(CONST_INTER); 3551 %} 3552 3553 // Immediates for special shifts (sign extend) 3554 3555 // Constants for increment 3556 operand immI_16() 3557 %{ 3558 predicate(n->get_int() == 16); 3559 match(ConI); 3560 3561 format %{ %} 3562 interface(CONST_INTER); 3563 %} 3564 3565 operand immI_24() 3566 %{ 3567 predicate(n->get_int() == 24); 3568 match(ConI); 3569 3570 format %{ %} 3571 interface(CONST_INTER); 3572 %} 3573 3574 // Constant for byte-wide masking 3575 operand immI_255() 3576 %{ 3577 predicate(n->get_int() == 255); 3578 match(ConI); 3579 3580 format %{ %} 3581 interface(CONST_INTER); 3582 %} 3583 3584 // Constant for short-wide masking 3585 operand immI_65535() 3586 %{ 3587 predicate(n->get_int() == 65535); 3588 match(ConI); 3589 3590 format %{ %} 3591 interface(CONST_INTER); 3592 %} 3593 3594 // Constant for byte-wide masking 3595 operand immL_255() 3596 %{ 3597 predicate(n->get_long() == 255); 3598 match(ConL); 3599 3600 format %{ %} 3601 interface(CONST_INTER); 3602 %} 3603 3604 // Constant for short-wide masking 3605 operand immL_65535() 3606 %{ 3607 predicate(n->get_long() == 65535); 3608 match(ConL); 3609 3610 format %{ %} 3611 interface(CONST_INTER); 3612 %} 3613 3614 // Register Operands 3615 // Integer Register 3616 operand rRegI() 3617 %{ 3618 constraint(ALLOC_IN_RC(int_reg)); 3619 match(RegI); 3620 3621 match(rax_RegI); 3622 match(rbx_RegI); 3623 match(rcx_RegI); 3624 match(rdx_RegI); 3625 match(rdi_RegI); 3626 3627 format %{ %} 3628 interface(REG_INTER); 3629 %} 3630 3631 // Special Registers 3632 operand rax_RegI() 3633 %{ 3634 constraint(ALLOC_IN_RC(int_rax_reg)); 3635 match(RegI); 3636 match(rRegI); 3637 3638 format %{ "RAX" %} 3639 interface(REG_INTER); 3640 %} 3641 3642 // Special Registers 3643 operand rbx_RegI() 3644 %{ 3645 constraint(ALLOC_IN_RC(int_rbx_reg)); 3646 match(RegI); 3647 match(rRegI); 3648 3649 format %{ "RBX" %} 3650 interface(REG_INTER); 3651 %} 3652 3653 operand rcx_RegI() 3654 %{ 3655 constraint(ALLOC_IN_RC(int_rcx_reg)); 3656 match(RegI); 3657 match(rRegI); 3658 3659 format %{ "RCX" %} 3660 interface(REG_INTER); 3661 %} 3662 3663 operand rdx_RegI() 3664 %{ 3665 constraint(ALLOC_IN_RC(int_rdx_reg)); 3666 match(RegI); 3667 match(rRegI); 3668 3669 format %{ "RDX" %} 3670 interface(REG_INTER); 3671 %} 3672 3673 operand rdi_RegI() 3674 %{ 3675 constraint(ALLOC_IN_RC(int_rdi_reg)); 3676 match(RegI); 3677 match(rRegI); 3678 3679 format %{ "RDI" %} 3680 interface(REG_INTER); 3681 %} 3682 3683 operand no_rcx_RegI() 3684 %{ 3685 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3686 match(RegI); 3687 match(rax_RegI); 3688 match(rbx_RegI); 3689 match(rdx_RegI); 3690 match(rdi_RegI); 3691 3692 format %{ %} 3693 interface(REG_INTER); 3694 %} 3695 3696 operand no_rax_rdx_RegI() 3697 %{ 3698 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3699 match(RegI); 3700 match(rbx_RegI); 3701 match(rcx_RegI); 3702 match(rdi_RegI); 3703 3704 format %{ %} 3705 interface(REG_INTER); 3706 %} 3707 3708 // Pointer Register 3709 operand any_RegP() 3710 %{ 3711 constraint(ALLOC_IN_RC(any_reg)); 3712 match(RegP); 3713 match(rax_RegP); 3714 match(rbx_RegP); 3715 match(rdi_RegP); 3716 match(rsi_RegP); 3717 match(rbp_RegP); 3718 match(r15_RegP); 3719 match(rRegP); 3720 3721 format %{ %} 3722 interface(REG_INTER); 3723 %} 3724 3725 operand rRegP() 3726 %{ 3727 constraint(ALLOC_IN_RC(ptr_reg)); 3728 match(RegP); 3729 match(rax_RegP); 3730 match(rbx_RegP); 3731 match(rdi_RegP); 3732 match(rsi_RegP); 3733 match(rbp_RegP); 3734 match(r15_RegP); // See Q&A below about r15_RegP. 3735 3736 format %{ %} 3737 interface(REG_INTER); 3738 %} 3739 3740 operand rRegN() %{ 3741 constraint(ALLOC_IN_RC(int_reg)); 3742 match(RegN); 3743 3744 format %{ %} 3745 interface(REG_INTER); 3746 %} 3747 3748 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3749 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3750 // It's fine for an instruction input which expects rRegP to match a r15_RegP. 3751 // The output of an instruction is controlled by the allocator, which respects 3752 // register class masks, not match rules. Unless an instruction mentions 3753 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3754 // by the allocator as an input. 3755 3756 operand no_rax_RegP() 3757 %{ 3758 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3759 match(RegP); 3760 match(rbx_RegP); 3761 match(rsi_RegP); 3762 match(rdi_RegP); 3763 3764 format %{ %} 3765 interface(REG_INTER); 3766 %} 3767 3768 operand no_rbp_RegP() 3769 %{ 3770 constraint(ALLOC_IN_RC(ptr_no_rbp_reg)); 3771 match(RegP); 3772 match(rbx_RegP); 3773 match(rsi_RegP); 3774 match(rdi_RegP); 3775 3776 format %{ %} 3777 interface(REG_INTER); 3778 %} 3779 3780 operand no_rax_rbx_RegP() 3781 %{ 3782 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3783 match(RegP); 3784 match(rsi_RegP); 3785 match(rdi_RegP); 3786 3787 format %{ %} 3788 interface(REG_INTER); 3789 %} 3790 3791 // Special Registers 3792 // Return a pointer value 3793 operand rax_RegP() 3794 %{ 3795 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3796 match(RegP); 3797 match(rRegP); 3798 3799 format %{ %} 3800 interface(REG_INTER); 3801 %} 3802 3803 // Special Registers 3804 // Return a compressed pointer value 3805 operand rax_RegN() 3806 %{ 3807 constraint(ALLOC_IN_RC(int_rax_reg)); 3808 match(RegN); 3809 match(rRegN); 3810 3811 format %{ %} 3812 interface(REG_INTER); 3813 %} 3814 3815 // Used in AtomicAdd 3816 operand rbx_RegP() 3817 %{ 3818 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3819 match(RegP); 3820 match(rRegP); 3821 3822 format %{ %} 3823 interface(REG_INTER); 3824 %} 3825 3826 operand rsi_RegP() 3827 %{ 3828 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3829 match(RegP); 3830 match(rRegP); 3831 3832 format %{ %} 3833 interface(REG_INTER); 3834 %} 3835 3836 // Used in rep stosq 3837 operand rdi_RegP() 3838 %{ 3839 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3840 match(RegP); 3841 match(rRegP); 3842 3843 format %{ %} 3844 interface(REG_INTER); 3845 %} 3846 3847 operand rbp_RegP() 3848 %{ 3849 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 3850 match(RegP); 3851 match(rRegP); 3852 3853 format %{ %} 3854 interface(REG_INTER); 3855 %} 3856 3857 operand r15_RegP() 3858 %{ 3859 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3860 match(RegP); 3861 match(rRegP); 3862 3863 format %{ %} 3864 interface(REG_INTER); 3865 %} 3866 3867 operand rRegL() 3868 %{ 3869 constraint(ALLOC_IN_RC(long_reg)); 3870 match(RegL); 3871 match(rax_RegL); 3872 match(rdx_RegL); 3873 3874 format %{ %} 3875 interface(REG_INTER); 3876 %} 3877 3878 // Special Registers 3879 operand no_rax_rdx_RegL() 3880 %{ 3881 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3882 match(RegL); 3883 match(rRegL); 3884 3885 format %{ %} 3886 interface(REG_INTER); 3887 %} 3888 3889 operand no_rax_RegL() 3890 %{ 3891 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3892 match(RegL); 3893 match(rRegL); 3894 match(rdx_RegL); 3895 3896 format %{ %} 3897 interface(REG_INTER); 3898 %} 3899 3900 operand no_rcx_RegL() 3901 %{ 3902 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3903 match(RegL); 3904 match(rRegL); 3905 3906 format %{ %} 3907 interface(REG_INTER); 3908 %} 3909 3910 operand rax_RegL() 3911 %{ 3912 constraint(ALLOC_IN_RC(long_rax_reg)); 3913 match(RegL); 3914 match(rRegL); 3915 3916 format %{ "RAX" %} 3917 interface(REG_INTER); 3918 %} 3919 3920 operand rcx_RegL() 3921 %{ 3922 constraint(ALLOC_IN_RC(long_rcx_reg)); 3923 match(RegL); 3924 match(rRegL); 3925 3926 format %{ %} 3927 interface(REG_INTER); 3928 %} 3929 3930 operand rdx_RegL() 3931 %{ 3932 constraint(ALLOC_IN_RC(long_rdx_reg)); 3933 match(RegL); 3934 match(rRegL); 3935 3936 format %{ %} 3937 interface(REG_INTER); 3938 %} 3939 3940 // Flags register, used as output of compare instructions 3941 operand rFlagsReg() 3942 %{ 3943 constraint(ALLOC_IN_RC(int_flags)); 3944 match(RegFlags); 3945 3946 format %{ "RFLAGS" %} 3947 interface(REG_INTER); 3948 %} 3949 3950 // Flags register, used as output of FLOATING POINT compare instructions 3951 operand rFlagsRegU() 3952 %{ 3953 constraint(ALLOC_IN_RC(int_flags)); 3954 match(RegFlags); 3955 3956 format %{ "RFLAGS_U" %} 3957 interface(REG_INTER); 3958 %} 3959 3960 operand rFlagsRegUCF() %{ 3961 constraint(ALLOC_IN_RC(int_flags)); 3962 match(RegFlags); 3963 predicate(false); 3964 3965 format %{ "RFLAGS_U_CF" %} 3966 interface(REG_INTER); 3967 %} 3968 3969 // Float register operands 3970 operand regF() 3971 %{ 3972 constraint(ALLOC_IN_RC(float_reg)); 3973 match(RegF); 3974 3975 format %{ %} 3976 interface(REG_INTER); 3977 %} 3978 3979 // Double register operands 3980 operand regD() 3981 %{ 3982 constraint(ALLOC_IN_RC(double_reg)); 3983 match(RegD); 3984 3985 format %{ %} 3986 interface(REG_INTER); 3987 %} 3988 3989 3990 //----------Memory Operands---------------------------------------------------- 3991 // Direct Memory Operand 3992 // operand direct(immP addr) 3993 // %{ 3994 // match(addr); 3995 3996 // format %{ "[$addr]" %} 3997 // interface(MEMORY_INTER) %{ 3998 // base(0xFFFFFFFF); 3999 // index(0x4); 4000 // scale(0x0); 4001 // disp($addr); 4002 // %} 4003 // %} 4004 4005 // Indirect Memory Operand 4006 operand indirect(any_RegP reg) 4007 %{ 4008 constraint(ALLOC_IN_RC(ptr_reg)); 4009 match(reg); 4010 4011 format %{ "[$reg]" %} 4012 interface(MEMORY_INTER) %{ 4013 base($reg); 4014 index(0x4); 4015 scale(0x0); 4016 disp(0x0); 4017 %} 4018 %} 4019 4020 // Indirect Memory Plus Short Offset Operand 4021 operand indOffset8(any_RegP reg, immL8 off) 4022 %{ 4023 constraint(ALLOC_IN_RC(ptr_reg)); 4024 match(AddP reg off); 4025 4026 format %{ "[$reg + $off (8-bit)]" %} 4027 interface(MEMORY_INTER) %{ 4028 base($reg); 4029 index(0x4); 4030 scale(0x0); 4031 disp($off); 4032 %} 4033 %} 4034 4035 // Indirect Memory Plus Long Offset Operand 4036 operand indOffset32(any_RegP reg, immL32 off) 4037 %{ 4038 constraint(ALLOC_IN_RC(ptr_reg)); 4039 match(AddP reg off); 4040 4041 format %{ "[$reg + $off (32-bit)]" %} 4042 interface(MEMORY_INTER) %{ 4043 base($reg); 4044 index(0x4); 4045 scale(0x0); 4046 disp($off); 4047 %} 4048 %} 4049 4050 // Indirect Memory Plus Index Register Plus Offset Operand 4051 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 4052 %{ 4053 constraint(ALLOC_IN_RC(ptr_reg)); 4054 match(AddP (AddP reg lreg) off); 4055 4056 op_cost(10); 4057 format %{"[$reg + $off + $lreg]" %} 4058 interface(MEMORY_INTER) %{ 4059 base($reg); 4060 index($lreg); 4061 scale(0x0); 4062 disp($off); 4063 %} 4064 %} 4065 4066 // Indirect Memory Plus Index Register Plus Offset Operand 4067 operand indIndex(any_RegP reg, rRegL lreg) 4068 %{ 4069 constraint(ALLOC_IN_RC(ptr_reg)); 4070 match(AddP reg lreg); 4071 4072 op_cost(10); 4073 format %{"[$reg + $lreg]" %} 4074 interface(MEMORY_INTER) %{ 4075 base($reg); 4076 index($lreg); 4077 scale(0x0); 4078 disp(0x0); 4079 %} 4080 %} 4081 4082 // Indirect Memory Times Scale Plus Index Register 4083 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 4084 %{ 4085 constraint(ALLOC_IN_RC(ptr_reg)); 4086 match(AddP reg (LShiftL lreg scale)); 4087 4088 op_cost(10); 4089 format %{"[$reg + $lreg << $scale]" %} 4090 interface(MEMORY_INTER) %{ 4091 base($reg); 4092 index($lreg); 4093 scale($scale); 4094 disp(0x0); 4095 %} 4096 %} 4097 4098 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4099 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 4100 %{ 4101 constraint(ALLOC_IN_RC(ptr_reg)); 4102 match(AddP (AddP reg (LShiftL lreg scale)) off); 4103 4104 op_cost(10); 4105 format %{"[$reg + $off + $lreg << $scale]" %} 4106 interface(MEMORY_INTER) %{ 4107 base($reg); 4108 index($lreg); 4109 scale($scale); 4110 disp($off); 4111 %} 4112 %} 4113 4114 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4115 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 4116 %{ 4117 constraint(ALLOC_IN_RC(ptr_reg)); 4118 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4119 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 4120 4121 op_cost(10); 4122 format %{"[$reg + $off + $idx << $scale]" %} 4123 interface(MEMORY_INTER) %{ 4124 base($reg); 4125 index($idx); 4126 scale($scale); 4127 disp($off); 4128 %} 4129 %} 4130 4131 // Indirect Narrow Oop Plus Offset Operand 4132 // Note: x86 architecture doesn't support "scale * index + offset" without a base 4133 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 4134 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 4135 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 4136 constraint(ALLOC_IN_RC(ptr_reg)); 4137 match(AddP (DecodeN reg) off); 4138 4139 op_cost(10); 4140 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 4141 interface(MEMORY_INTER) %{ 4142 base(0xc); // R12 4143 index($reg); 4144 scale(0x3); 4145 disp($off); 4146 %} 4147 %} 4148 4149 // Indirect Memory Operand 4150 operand indirectNarrow(rRegN reg) 4151 %{ 4152 predicate(Universe::narrow_oop_shift() == 0); 4153 constraint(ALLOC_IN_RC(ptr_reg)); 4154 match(DecodeN reg); 4155 4156 format %{ "[$reg]" %} 4157 interface(MEMORY_INTER) %{ 4158 base($reg); 4159 index(0x4); 4160 scale(0x0); 4161 disp(0x0); 4162 %} 4163 %} 4164 4165 // Indirect Memory Plus Short Offset Operand 4166 operand indOffset8Narrow(rRegN reg, immL8 off) 4167 %{ 4168 predicate(Universe::narrow_oop_shift() == 0); 4169 constraint(ALLOC_IN_RC(ptr_reg)); 4170 match(AddP (DecodeN reg) off); 4171 4172 format %{ "[$reg + $off (8-bit)]" %} 4173 interface(MEMORY_INTER) %{ 4174 base($reg); 4175 index(0x4); 4176 scale(0x0); 4177 disp($off); 4178 %} 4179 %} 4180 4181 // Indirect Memory Plus Long Offset Operand 4182 operand indOffset32Narrow(rRegN reg, immL32 off) 4183 %{ 4184 predicate(Universe::narrow_oop_shift() == 0); 4185 constraint(ALLOC_IN_RC(ptr_reg)); 4186 match(AddP (DecodeN reg) off); 4187 4188 format %{ "[$reg + $off (32-bit)]" %} 4189 interface(MEMORY_INTER) %{ 4190 base($reg); 4191 index(0x4); 4192 scale(0x0); 4193 disp($off); 4194 %} 4195 %} 4196 4197 // Indirect Memory Plus Index Register Plus Offset Operand 4198 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 4199 %{ 4200 predicate(Universe::narrow_oop_shift() == 0); 4201 constraint(ALLOC_IN_RC(ptr_reg)); 4202 match(AddP (AddP (DecodeN reg) lreg) off); 4203 4204 op_cost(10); 4205 format %{"[$reg + $off + $lreg]" %} 4206 interface(MEMORY_INTER) %{ 4207 base($reg); 4208 index($lreg); 4209 scale(0x0); 4210 disp($off); 4211 %} 4212 %} 4213 4214 // Indirect Memory Plus Index Register Plus Offset Operand 4215 operand indIndexNarrow(rRegN reg, rRegL lreg) 4216 %{ 4217 predicate(Universe::narrow_oop_shift() == 0); 4218 constraint(ALLOC_IN_RC(ptr_reg)); 4219 match(AddP (DecodeN reg) lreg); 4220 4221 op_cost(10); 4222 format %{"[$reg + $lreg]" %} 4223 interface(MEMORY_INTER) %{ 4224 base($reg); 4225 index($lreg); 4226 scale(0x0); 4227 disp(0x0); 4228 %} 4229 %} 4230 4231 // Indirect Memory Times Scale Plus Index Register 4232 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4233 %{ 4234 predicate(Universe::narrow_oop_shift() == 0); 4235 constraint(ALLOC_IN_RC(ptr_reg)); 4236 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4237 4238 op_cost(10); 4239 format %{"[$reg + $lreg << $scale]" %} 4240 interface(MEMORY_INTER) %{ 4241 base($reg); 4242 index($lreg); 4243 scale($scale); 4244 disp(0x0); 4245 %} 4246 %} 4247 4248 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4249 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4250 %{ 4251 predicate(Universe::narrow_oop_shift() == 0); 4252 constraint(ALLOC_IN_RC(ptr_reg)); 4253 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4254 4255 op_cost(10); 4256 format %{"[$reg + $off + $lreg << $scale]" %} 4257 interface(MEMORY_INTER) %{ 4258 base($reg); 4259 index($lreg); 4260 scale($scale); 4261 disp($off); 4262 %} 4263 %} 4264 4265 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4266 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4267 %{ 4268 constraint(ALLOC_IN_RC(ptr_reg)); 4269 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4270 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4271 4272 op_cost(10); 4273 format %{"[$reg + $off + $idx << $scale]" %} 4274 interface(MEMORY_INTER) %{ 4275 base($reg); 4276 index($idx); 4277 scale($scale); 4278 disp($off); 4279 %} 4280 %} 4281 4282 4283 //----------Special Memory Operands-------------------------------------------- 4284 // Stack Slot Operand - This operand is used for loading and storing temporary 4285 // values on the stack where a match requires a value to 4286 // flow through memory. 4287 operand stackSlotP(sRegP reg) 4288 %{ 4289 constraint(ALLOC_IN_RC(stack_slots)); 4290 // No match rule because this operand is only generated in matching 4291 4292 format %{ "[$reg]" %} 4293 interface(MEMORY_INTER) %{ 4294 base(0x4); // RSP 4295 index(0x4); // No Index 4296 scale(0x0); // No Scale 4297 disp($reg); // Stack Offset 4298 %} 4299 %} 4300 4301 operand stackSlotI(sRegI reg) 4302 %{ 4303 constraint(ALLOC_IN_RC(stack_slots)); 4304 // No match rule because this operand is only generated in matching 4305 4306 format %{ "[$reg]" %} 4307 interface(MEMORY_INTER) %{ 4308 base(0x4); // RSP 4309 index(0x4); // No Index 4310 scale(0x0); // No Scale 4311 disp($reg); // Stack Offset 4312 %} 4313 %} 4314 4315 operand stackSlotF(sRegF reg) 4316 %{ 4317 constraint(ALLOC_IN_RC(stack_slots)); 4318 // No match rule because this operand is only generated in matching 4319 4320 format %{ "[$reg]" %} 4321 interface(MEMORY_INTER) %{ 4322 base(0x4); // RSP 4323 index(0x4); // No Index 4324 scale(0x0); // No Scale 4325 disp($reg); // Stack Offset 4326 %} 4327 %} 4328 4329 operand stackSlotD(sRegD reg) 4330 %{ 4331 constraint(ALLOC_IN_RC(stack_slots)); 4332 // No match rule because this operand is only generated in matching 4333 4334 format %{ "[$reg]" %} 4335 interface(MEMORY_INTER) %{ 4336 base(0x4); // RSP 4337 index(0x4); // No Index 4338 scale(0x0); // No Scale 4339 disp($reg); // Stack Offset 4340 %} 4341 %} 4342 operand stackSlotL(sRegL reg) 4343 %{ 4344 constraint(ALLOC_IN_RC(stack_slots)); 4345 // No match rule because this operand is only generated in matching 4346 4347 format %{ "[$reg]" %} 4348 interface(MEMORY_INTER) %{ 4349 base(0x4); // RSP 4350 index(0x4); // No Index 4351 scale(0x0); // No Scale 4352 disp($reg); // Stack Offset 4353 %} 4354 %} 4355 4356 //----------Conditional Branch Operands---------------------------------------- 4357 // Comparison Op - This is the operation of the comparison, and is limited to 4358 // the following set of codes: 4359 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4360 // 4361 // Other attributes of the comparison, such as unsignedness, are specified 4362 // by the comparison instruction that sets a condition code flags register. 4363 // That result is represented by a flags operand whose subtype is appropriate 4364 // to the unsignedness (etc.) of the comparison. 4365 // 4366 // Later, the instruction which matches both the Comparison Op (a Bool) and 4367 // the flags (produced by the Cmp) specifies the coding of the comparison op 4368 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4369 4370 // Comparision Code 4371 operand cmpOp() 4372 %{ 4373 match(Bool); 4374 4375 format %{ "" %} 4376 interface(COND_INTER) %{ 4377 equal(0x4, "e"); 4378 not_equal(0x5, "ne"); 4379 less(0xC, "l"); 4380 greater_equal(0xD, "ge"); 4381 less_equal(0xE, "le"); 4382 greater(0xF, "g"); 4383 %} 4384 %} 4385 4386 // Comparison Code, unsigned compare. Used by FP also, with 4387 // C2 (unordered) turned into GT or LT already. The other bits 4388 // C0 and C3 are turned into Carry & Zero flags. 4389 operand cmpOpU() 4390 %{ 4391 match(Bool); 4392 4393 format %{ "" %} 4394 interface(COND_INTER) %{ 4395 equal(0x4, "e"); 4396 not_equal(0x5, "ne"); 4397 less(0x2, "b"); 4398 greater_equal(0x3, "nb"); 4399 less_equal(0x6, "be"); 4400 greater(0x7, "nbe"); 4401 %} 4402 %} 4403 4404 4405 // Floating comparisons that don't require any fixup for the unordered case 4406 operand cmpOpUCF() %{ 4407 match(Bool); 4408 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4409 n->as_Bool()->_test._test == BoolTest::ge || 4410 n->as_Bool()->_test._test == BoolTest::le || 4411 n->as_Bool()->_test._test == BoolTest::gt); 4412 format %{ "" %} 4413 interface(COND_INTER) %{ 4414 equal(0x4, "e"); 4415 not_equal(0x5, "ne"); 4416 less(0x2, "b"); 4417 greater_equal(0x3, "nb"); 4418 less_equal(0x6, "be"); 4419 greater(0x7, "nbe"); 4420 %} 4421 %} 4422 4423 4424 // Floating comparisons that can be fixed up with extra conditional jumps 4425 operand cmpOpUCF2() %{ 4426 match(Bool); 4427 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4428 n->as_Bool()->_test._test == BoolTest::eq); 4429 format %{ "" %} 4430 interface(COND_INTER) %{ 4431 equal(0x4, "e"); 4432 not_equal(0x5, "ne"); 4433 less(0x2, "b"); 4434 greater_equal(0x3, "nb"); 4435 less_equal(0x6, "be"); 4436 greater(0x7, "nbe"); 4437 %} 4438 %} 4439 4440 4441 //----------OPERAND CLASSES---------------------------------------------------- 4442 // Operand Classes are groups of operands that are used as to simplify 4443 // instruction definitions by not requiring the AD writer to specify separate 4444 // instructions for every form of operand when the instruction accepts 4445 // multiple operand types with the same basic encoding and format. The classic 4446 // case of this is memory operands. 4447 4448 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4449 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, 4450 indCompressedOopOffset, 4451 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4452 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4453 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow); 4454 4455 //----------PIPELINE----------------------------------------------------------- 4456 // Rules which define the behavior of the target architectures pipeline. 4457 pipeline %{ 4458 4459 //----------ATTRIBUTES--------------------------------------------------------- 4460 attributes %{ 4461 variable_size_instructions; // Fixed size instructions 4462 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4463 instruction_unit_size = 1; // An instruction is 1 bytes long 4464 instruction_fetch_unit_size = 16; // The processor fetches one line 4465 instruction_fetch_units = 1; // of 16 bytes 4466 4467 // List of nop instructions 4468 nops( MachNop ); 4469 %} 4470 4471 //----------RESOURCES---------------------------------------------------------- 4472 // Resources are the functional units available to the machine 4473 4474 // Generic P2/P3 pipeline 4475 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4476 // 3 instructions decoded per cycle. 4477 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4478 // 3 ALU op, only ALU0 handles mul instructions. 4479 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4480 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4481 BR, FPU, 4482 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4483 4484 //----------PIPELINE DESCRIPTION----------------------------------------------- 4485 // Pipeline Description specifies the stages in the machine's pipeline 4486 4487 // Generic P2/P3 pipeline 4488 pipe_desc(S0, S1, S2, S3, S4, S5); 4489 4490 //----------PIPELINE CLASSES--------------------------------------------------- 4491 // Pipeline Classes describe the stages in which input and output are 4492 // referenced by the hardware pipeline. 4493 4494 // Naming convention: ialu or fpu 4495 // Then: _reg 4496 // Then: _reg if there is a 2nd register 4497 // Then: _long if it's a pair of instructions implementing a long 4498 // Then: _fat if it requires the big decoder 4499 // Or: _mem if it requires the big decoder and a memory unit. 4500 4501 // Integer ALU reg operation 4502 pipe_class ialu_reg(rRegI dst) 4503 %{ 4504 single_instruction; 4505 dst : S4(write); 4506 dst : S3(read); 4507 DECODE : S0; // any decoder 4508 ALU : S3; // any alu 4509 %} 4510 4511 // Long ALU reg operation 4512 pipe_class ialu_reg_long(rRegL dst) 4513 %{ 4514 instruction_count(2); 4515 dst : S4(write); 4516 dst : S3(read); 4517 DECODE : S0(2); // any 2 decoders 4518 ALU : S3(2); // both alus 4519 %} 4520 4521 // Integer ALU reg operation using big decoder 4522 pipe_class ialu_reg_fat(rRegI dst) 4523 %{ 4524 single_instruction; 4525 dst : S4(write); 4526 dst : S3(read); 4527 D0 : S0; // big decoder only 4528 ALU : S3; // any alu 4529 %} 4530 4531 // Long ALU reg operation using big decoder 4532 pipe_class ialu_reg_long_fat(rRegL dst) 4533 %{ 4534 instruction_count(2); 4535 dst : S4(write); 4536 dst : S3(read); 4537 D0 : S0(2); // big decoder only; twice 4538 ALU : S3(2); // any 2 alus 4539 %} 4540 4541 // Integer ALU reg-reg operation 4542 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4543 %{ 4544 single_instruction; 4545 dst : S4(write); 4546 src : S3(read); 4547 DECODE : S0; // any decoder 4548 ALU : S3; // any alu 4549 %} 4550 4551 // Long ALU reg-reg operation 4552 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4553 %{ 4554 instruction_count(2); 4555 dst : S4(write); 4556 src : S3(read); 4557 DECODE : S0(2); // any 2 decoders 4558 ALU : S3(2); // both alus 4559 %} 4560 4561 // Integer ALU reg-reg operation 4562 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4563 %{ 4564 single_instruction; 4565 dst : S4(write); 4566 src : S3(read); 4567 D0 : S0; // big decoder only 4568 ALU : S3; // any alu 4569 %} 4570 4571 // Long ALU reg-reg operation 4572 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4573 %{ 4574 instruction_count(2); 4575 dst : S4(write); 4576 src : S3(read); 4577 D0 : S0(2); // big decoder only; twice 4578 ALU : S3(2); // both alus 4579 %} 4580 4581 // Integer ALU reg-mem operation 4582 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4583 %{ 4584 single_instruction; 4585 dst : S5(write); 4586 mem : S3(read); 4587 D0 : S0; // big decoder only 4588 ALU : S4; // any alu 4589 MEM : S3; // any mem 4590 %} 4591 4592 // Integer mem operation (prefetch) 4593 pipe_class ialu_mem(memory mem) 4594 %{ 4595 single_instruction; 4596 mem : S3(read); 4597 D0 : S0; // big decoder only 4598 MEM : S3; // any mem 4599 %} 4600 4601 // Integer Store to Memory 4602 pipe_class ialu_mem_reg(memory mem, rRegI src) 4603 %{ 4604 single_instruction; 4605 mem : S3(read); 4606 src : S5(read); 4607 D0 : S0; // big decoder only 4608 ALU : S4; // any alu 4609 MEM : S3; 4610 %} 4611 4612 // // Long Store to Memory 4613 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4614 // %{ 4615 // instruction_count(2); 4616 // mem : S3(read); 4617 // src : S5(read); 4618 // D0 : S0(2); // big decoder only; twice 4619 // ALU : S4(2); // any 2 alus 4620 // MEM : S3(2); // Both mems 4621 // %} 4622 4623 // Integer Store to Memory 4624 pipe_class ialu_mem_imm(memory mem) 4625 %{ 4626 single_instruction; 4627 mem : S3(read); 4628 D0 : S0; // big decoder only 4629 ALU : S4; // any alu 4630 MEM : S3; 4631 %} 4632 4633 // Integer ALU0 reg-reg operation 4634 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4635 %{ 4636 single_instruction; 4637 dst : S4(write); 4638 src : S3(read); 4639 D0 : S0; // Big decoder only 4640 ALU0 : S3; // only alu0 4641 %} 4642 4643 // Integer ALU0 reg-mem operation 4644 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4645 %{ 4646 single_instruction; 4647 dst : S5(write); 4648 mem : S3(read); 4649 D0 : S0; // big decoder only 4650 ALU0 : S4; // ALU0 only 4651 MEM : S3; // any mem 4652 %} 4653 4654 // Integer ALU reg-reg operation 4655 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4656 %{ 4657 single_instruction; 4658 cr : S4(write); 4659 src1 : S3(read); 4660 src2 : S3(read); 4661 DECODE : S0; // any decoder 4662 ALU : S3; // any alu 4663 %} 4664 4665 // Integer ALU reg-imm operation 4666 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4667 %{ 4668 single_instruction; 4669 cr : S4(write); 4670 src1 : S3(read); 4671 DECODE : S0; // any decoder 4672 ALU : S3; // any alu 4673 %} 4674 4675 // Integer ALU reg-mem operation 4676 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4677 %{ 4678 single_instruction; 4679 cr : S4(write); 4680 src1 : S3(read); 4681 src2 : S3(read); 4682 D0 : S0; // big decoder only 4683 ALU : S4; // any alu 4684 MEM : S3; 4685 %} 4686 4687 // Conditional move reg-reg 4688 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4689 %{ 4690 instruction_count(4); 4691 y : S4(read); 4692 q : S3(read); 4693 p : S3(read); 4694 DECODE : S0(4); // any decoder 4695 %} 4696 4697 // Conditional move reg-reg 4698 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4699 %{ 4700 single_instruction; 4701 dst : S4(write); 4702 src : S3(read); 4703 cr : S3(read); 4704 DECODE : S0; // any decoder 4705 %} 4706 4707 // Conditional move reg-mem 4708 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4709 %{ 4710 single_instruction; 4711 dst : S4(write); 4712 src : S3(read); 4713 cr : S3(read); 4714 DECODE : S0; // any decoder 4715 MEM : S3; 4716 %} 4717 4718 // Conditional move reg-reg long 4719 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4720 %{ 4721 single_instruction; 4722 dst : S4(write); 4723 src : S3(read); 4724 cr : S3(read); 4725 DECODE : S0(2); // any 2 decoders 4726 %} 4727 4728 // XXX 4729 // // Conditional move double reg-reg 4730 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4731 // %{ 4732 // single_instruction; 4733 // dst : S4(write); 4734 // src : S3(read); 4735 // cr : S3(read); 4736 // DECODE : S0; // any decoder 4737 // %} 4738 4739 // Float reg-reg operation 4740 pipe_class fpu_reg(regD dst) 4741 %{ 4742 instruction_count(2); 4743 dst : S3(read); 4744 DECODE : S0(2); // any 2 decoders 4745 FPU : S3; 4746 %} 4747 4748 // Float reg-reg operation 4749 pipe_class fpu_reg_reg(regD dst, regD src) 4750 %{ 4751 instruction_count(2); 4752 dst : S4(write); 4753 src : S3(read); 4754 DECODE : S0(2); // any 2 decoders 4755 FPU : S3; 4756 %} 4757 4758 // Float reg-reg operation 4759 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4760 %{ 4761 instruction_count(3); 4762 dst : S4(write); 4763 src1 : S3(read); 4764 src2 : S3(read); 4765 DECODE : S0(3); // any 3 decoders 4766 FPU : S3(2); 4767 %} 4768 4769 // Float reg-reg operation 4770 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4771 %{ 4772 instruction_count(4); 4773 dst : S4(write); 4774 src1 : S3(read); 4775 src2 : S3(read); 4776 src3 : S3(read); 4777 DECODE : S0(4); // any 3 decoders 4778 FPU : S3(2); 4779 %} 4780 4781 // Float reg-reg operation 4782 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4783 %{ 4784 instruction_count(4); 4785 dst : S4(write); 4786 src1 : S3(read); 4787 src2 : S3(read); 4788 src3 : S3(read); 4789 DECODE : S1(3); // any 3 decoders 4790 D0 : S0; // Big decoder only 4791 FPU : S3(2); 4792 MEM : S3; 4793 %} 4794 4795 // Float reg-mem operation 4796 pipe_class fpu_reg_mem(regD dst, memory mem) 4797 %{ 4798 instruction_count(2); 4799 dst : S5(write); 4800 mem : S3(read); 4801 D0 : S0; // big decoder only 4802 DECODE : S1; // any decoder for FPU POP 4803 FPU : S4; 4804 MEM : S3; // any mem 4805 %} 4806 4807 // Float reg-mem operation 4808 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4809 %{ 4810 instruction_count(3); 4811 dst : S5(write); 4812 src1 : S3(read); 4813 mem : S3(read); 4814 D0 : S0; // big decoder only 4815 DECODE : S1(2); // any decoder for FPU POP 4816 FPU : S4; 4817 MEM : S3; // any mem 4818 %} 4819 4820 // Float mem-reg operation 4821 pipe_class fpu_mem_reg(memory mem, regD src) 4822 %{ 4823 instruction_count(2); 4824 src : S5(read); 4825 mem : S3(read); 4826 DECODE : S0; // any decoder for FPU PUSH 4827 D0 : S1; // big decoder only 4828 FPU : S4; 4829 MEM : S3; // any mem 4830 %} 4831 4832 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4833 %{ 4834 instruction_count(3); 4835 src1 : S3(read); 4836 src2 : S3(read); 4837 mem : S3(read); 4838 DECODE : S0(2); // any decoder for FPU PUSH 4839 D0 : S1; // big decoder only 4840 FPU : S4; 4841 MEM : S3; // any mem 4842 %} 4843 4844 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4845 %{ 4846 instruction_count(3); 4847 src1 : S3(read); 4848 src2 : S3(read); 4849 mem : S4(read); 4850 DECODE : S0; // any decoder for FPU PUSH 4851 D0 : S0(2); // big decoder only 4852 FPU : S4; 4853 MEM : S3(2); // any mem 4854 %} 4855 4856 pipe_class fpu_mem_mem(memory dst, memory src1) 4857 %{ 4858 instruction_count(2); 4859 src1 : S3(read); 4860 dst : S4(read); 4861 D0 : S0(2); // big decoder only 4862 MEM : S3(2); // any mem 4863 %} 4864 4865 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4866 %{ 4867 instruction_count(3); 4868 src1 : S3(read); 4869 src2 : S3(read); 4870 dst : S4(read); 4871 D0 : S0(3); // big decoder only 4872 FPU : S4; 4873 MEM : S3(3); // any mem 4874 %} 4875 4876 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4877 %{ 4878 instruction_count(3); 4879 src1 : S4(read); 4880 mem : S4(read); 4881 DECODE : S0; // any decoder for FPU PUSH 4882 D0 : S0(2); // big decoder only 4883 FPU : S4; 4884 MEM : S3(2); // any mem 4885 %} 4886 4887 // Float load constant 4888 pipe_class fpu_reg_con(regD dst) 4889 %{ 4890 instruction_count(2); 4891 dst : S5(write); 4892 D0 : S0; // big decoder only for the load 4893 DECODE : S1; // any decoder for FPU POP 4894 FPU : S4; 4895 MEM : S3; // any mem 4896 %} 4897 4898 // Float load constant 4899 pipe_class fpu_reg_reg_con(regD dst, regD src) 4900 %{ 4901 instruction_count(3); 4902 dst : S5(write); 4903 src : S3(read); 4904 D0 : S0; // big decoder only for the load 4905 DECODE : S1(2); // any decoder for FPU POP 4906 FPU : S4; 4907 MEM : S3; // any mem 4908 %} 4909 4910 // UnConditional branch 4911 pipe_class pipe_jmp(label labl) 4912 %{ 4913 single_instruction; 4914 BR : S3; 4915 %} 4916 4917 // Conditional branch 4918 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4919 %{ 4920 single_instruction; 4921 cr : S1(read); 4922 BR : S3; 4923 %} 4924 4925 // Allocation idiom 4926 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4927 %{ 4928 instruction_count(1); force_serialization; 4929 fixed_latency(6); 4930 heap_ptr : S3(read); 4931 DECODE : S0(3); 4932 D0 : S2; 4933 MEM : S3; 4934 ALU : S3(2); 4935 dst : S5(write); 4936 BR : S5; 4937 %} 4938 4939 // Generic big/slow expanded idiom 4940 pipe_class pipe_slow() 4941 %{ 4942 instruction_count(10); multiple_bundles; force_serialization; 4943 fixed_latency(100); 4944 D0 : S0(2); 4945 MEM : S3(2); 4946 %} 4947 4948 // The real do-nothing guy 4949 pipe_class empty() 4950 %{ 4951 instruction_count(0); 4952 %} 4953 4954 // Define the class for the Nop node 4955 define 4956 %{ 4957 MachNop = empty; 4958 %} 4959 4960 %} 4961 4962 //----------INSTRUCTIONS------------------------------------------------------- 4963 // 4964 // match -- States which machine-independent subtree may be replaced 4965 // by this instruction. 4966 // ins_cost -- The estimated cost of this instruction is used by instruction 4967 // selection to identify a minimum cost tree of machine 4968 // instructions that matches a tree of machine-independent 4969 // instructions. 4970 // format -- A string providing the disassembly for this instruction. 4971 // The value of an instruction's operand may be inserted 4972 // by referring to it with a '$' prefix. 4973 // opcode -- Three instruction opcodes may be provided. These are referred 4974 // to within an encode class as $primary, $secondary, and $tertiary 4975 // rrspectively. The primary opcode is commonly used to 4976 // indicate the type of machine instruction, while secondary 4977 // and tertiary are often used for prefix options or addressing 4978 // modes. 4979 // ins_encode -- A list of encode classes with parameters. The encode class 4980 // name must have been defined in an 'enc_class' specification 4981 // in the encode section of the architecture description. 4982 4983 4984 //----------Load/Store/Move Instructions--------------------------------------- 4985 //----------Load Instructions-------------------------------------------------- 4986 4987 // Load Byte (8 bit signed) 4988 instruct loadB(rRegI dst, memory mem) 4989 %{ 4990 match(Set dst (LoadB mem)); 4991 4992 ins_cost(125); 4993 format %{ "movsbl $dst, $mem\t# byte" %} 4994 4995 ins_encode %{ 4996 __ movsbl($dst$$Register, $mem$$Address); 4997 %} 4998 4999 ins_pipe(ialu_reg_mem); 5000 %} 5001 5002 // Load Byte (8 bit signed) into Long Register 5003 instruct loadB2L(rRegL dst, memory mem) 5004 %{ 5005 match(Set dst (ConvI2L (LoadB mem))); 5006 5007 ins_cost(125); 5008 format %{ "movsbq $dst, $mem\t# byte -> long" %} 5009 5010 ins_encode %{ 5011 __ movsbq($dst$$Register, $mem$$Address); 5012 %} 5013 5014 ins_pipe(ialu_reg_mem); 5015 %} 5016 5017 // Load Unsigned Byte (8 bit UNsigned) 5018 instruct loadUB(rRegI dst, memory mem) 5019 %{ 5020 match(Set dst (LoadUB mem)); 5021 5022 ins_cost(125); 5023 format %{ "movzbl $dst, $mem\t# ubyte" %} 5024 5025 ins_encode %{ 5026 __ movzbl($dst$$Register, $mem$$Address); 5027 %} 5028 5029 ins_pipe(ialu_reg_mem); 5030 %} 5031 5032 // Load Unsigned Byte (8 bit UNsigned) into Long Register 5033 instruct loadUB2L(rRegL dst, memory mem) 5034 %{ 5035 match(Set dst (ConvI2L (LoadUB mem))); 5036 5037 ins_cost(125); 5038 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 5039 5040 ins_encode %{ 5041 __ movzbq($dst$$Register, $mem$$Address); 5042 %} 5043 5044 ins_pipe(ialu_reg_mem); 5045 %} 5046 5047 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register 5048 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ 5049 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5050 effect(KILL cr); 5051 5052 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" 5053 "andl $dst, $mask" %} 5054 ins_encode %{ 5055 Register Rdst = $dst$$Register; 5056 __ movzbq(Rdst, $mem$$Address); 5057 __ andl(Rdst, $mask$$constant); 5058 %} 5059 ins_pipe(ialu_reg_mem); 5060 %} 5061 5062 // Load Short (16 bit signed) 5063 instruct loadS(rRegI dst, memory mem) 5064 %{ 5065 match(Set dst (LoadS mem)); 5066 5067 ins_cost(125); 5068 format %{ "movswl $dst, $mem\t# short" %} 5069 5070 ins_encode %{ 5071 __ movswl($dst$$Register, $mem$$Address); 5072 %} 5073 5074 ins_pipe(ialu_reg_mem); 5075 %} 5076 5077 // Load Short (16 bit signed) to Byte (8 bit signed) 5078 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5079 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5080 5081 ins_cost(125); 5082 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5083 ins_encode %{ 5084 __ movsbl($dst$$Register, $mem$$Address); 5085 %} 5086 ins_pipe(ialu_reg_mem); 5087 %} 5088 5089 // Load Short (16 bit signed) into Long Register 5090 instruct loadS2L(rRegL dst, memory mem) 5091 %{ 5092 match(Set dst (ConvI2L (LoadS mem))); 5093 5094 ins_cost(125); 5095 format %{ "movswq $dst, $mem\t# short -> long" %} 5096 5097 ins_encode %{ 5098 __ movswq($dst$$Register, $mem$$Address); 5099 %} 5100 5101 ins_pipe(ialu_reg_mem); 5102 %} 5103 5104 // Load Unsigned Short/Char (16 bit UNsigned) 5105 instruct loadUS(rRegI dst, memory mem) 5106 %{ 5107 match(Set dst (LoadUS mem)); 5108 5109 ins_cost(125); 5110 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5111 5112 ins_encode %{ 5113 __ movzwl($dst$$Register, $mem$$Address); 5114 %} 5115 5116 ins_pipe(ialu_reg_mem); 5117 %} 5118 5119 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5120 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5121 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5122 5123 ins_cost(125); 5124 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5125 ins_encode %{ 5126 __ movsbl($dst$$Register, $mem$$Address); 5127 %} 5128 ins_pipe(ialu_reg_mem); 5129 %} 5130 5131 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5132 instruct loadUS2L(rRegL dst, memory mem) 5133 %{ 5134 match(Set dst (ConvI2L (LoadUS mem))); 5135 5136 ins_cost(125); 5137 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5138 5139 ins_encode %{ 5140 __ movzwq($dst$$Register, $mem$$Address); 5141 %} 5142 5143 ins_pipe(ialu_reg_mem); 5144 %} 5145 5146 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5147 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5148 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5149 5150 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5151 ins_encode %{ 5152 __ movzbq($dst$$Register, $mem$$Address); 5153 %} 5154 ins_pipe(ialu_reg_mem); 5155 %} 5156 5157 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register 5158 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ 5159 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5160 effect(KILL cr); 5161 5162 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" 5163 "andl $dst, $mask" %} 5164 ins_encode %{ 5165 Register Rdst = $dst$$Register; 5166 __ movzwq(Rdst, $mem$$Address); 5167 __ andl(Rdst, $mask$$constant); 5168 %} 5169 ins_pipe(ialu_reg_mem); 5170 %} 5171 5172 // Load Integer 5173 instruct loadI(rRegI dst, memory mem) 5174 %{ 5175 match(Set dst (LoadI mem)); 5176 5177 ins_cost(125); 5178 format %{ "movl $dst, $mem\t# int" %} 5179 5180 ins_encode %{ 5181 __ movl($dst$$Register, $mem$$Address); 5182 %} 5183 5184 ins_pipe(ialu_reg_mem); 5185 %} 5186 5187 // Load Integer (32 bit signed) to Byte (8 bit signed) 5188 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5189 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5190 5191 ins_cost(125); 5192 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5193 ins_encode %{ 5194 __ movsbl($dst$$Register, $mem$$Address); 5195 %} 5196 ins_pipe(ialu_reg_mem); 5197 %} 5198 5199 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5200 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5201 match(Set dst (AndI (LoadI mem) mask)); 5202 5203 ins_cost(125); 5204 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5205 ins_encode %{ 5206 __ movzbl($dst$$Register, $mem$$Address); 5207 %} 5208 ins_pipe(ialu_reg_mem); 5209 %} 5210 5211 // Load Integer (32 bit signed) to Short (16 bit signed) 5212 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5213 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5214 5215 ins_cost(125); 5216 format %{ "movswl $dst, $mem\t# int -> short" %} 5217 ins_encode %{ 5218 __ movswl($dst$$Register, $mem$$Address); 5219 %} 5220 ins_pipe(ialu_reg_mem); 5221 %} 5222 5223 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5224 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5225 match(Set dst (AndI (LoadI mem) mask)); 5226 5227 ins_cost(125); 5228 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5229 ins_encode %{ 5230 __ movzwl($dst$$Register, $mem$$Address); 5231 %} 5232 ins_pipe(ialu_reg_mem); 5233 %} 5234 5235 // Load Integer into Long Register 5236 instruct loadI2L(rRegL dst, memory mem) 5237 %{ 5238 match(Set dst (ConvI2L (LoadI mem))); 5239 5240 ins_cost(125); 5241 format %{ "movslq $dst, $mem\t# int -> long" %} 5242 5243 ins_encode %{ 5244 __ movslq($dst$$Register, $mem$$Address); 5245 %} 5246 5247 ins_pipe(ialu_reg_mem); 5248 %} 5249 5250 // Load Integer with mask 0xFF into Long Register 5251 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5252 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5253 5254 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5255 ins_encode %{ 5256 __ movzbq($dst$$Register, $mem$$Address); 5257 %} 5258 ins_pipe(ialu_reg_mem); 5259 %} 5260 5261 // Load Integer with mask 0xFFFF into Long Register 5262 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5263 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5264 5265 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5266 ins_encode %{ 5267 __ movzwq($dst$$Register, $mem$$Address); 5268 %} 5269 ins_pipe(ialu_reg_mem); 5270 %} 5271 5272 // Load Integer with a 32-bit mask into Long Register 5273 instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5274 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5275 effect(KILL cr); 5276 5277 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t" 5278 "andl $dst, $mask" %} 5279 ins_encode %{ 5280 Register Rdst = $dst$$Register; 5281 __ movl(Rdst, $mem$$Address); 5282 __ andl(Rdst, $mask$$constant); 5283 %} 5284 ins_pipe(ialu_reg_mem); 5285 %} 5286 5287 // Load Unsigned Integer into Long Register 5288 instruct loadUI2L(rRegL dst, memory mem) 5289 %{ 5290 match(Set dst (LoadUI2L mem)); 5291 5292 ins_cost(125); 5293 format %{ "movl $dst, $mem\t# uint -> long" %} 5294 5295 ins_encode %{ 5296 __ movl($dst$$Register, $mem$$Address); 5297 %} 5298 5299 ins_pipe(ialu_reg_mem); 5300 %} 5301 5302 // Load Long 5303 instruct loadL(rRegL dst, memory mem) 5304 %{ 5305 match(Set dst (LoadL mem)); 5306 5307 ins_cost(125); 5308 format %{ "movq $dst, $mem\t# long" %} 5309 5310 ins_encode %{ 5311 __ movq($dst$$Register, $mem$$Address); 5312 %} 5313 5314 ins_pipe(ialu_reg_mem); // XXX 5315 %} 5316 5317 // Load Range 5318 instruct loadRange(rRegI dst, memory mem) 5319 %{ 5320 match(Set dst (LoadRange mem)); 5321 5322 ins_cost(125); // XXX 5323 format %{ "movl $dst, $mem\t# range" %} 5324 opcode(0x8B); 5325 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5326 ins_pipe(ialu_reg_mem); 5327 %} 5328 5329 // Load Pointer 5330 instruct loadP(rRegP dst, memory mem) 5331 %{ 5332 match(Set dst (LoadP mem)); 5333 5334 ins_cost(125); // XXX 5335 format %{ "movq $dst, $mem\t# ptr" %} 5336 opcode(0x8B); 5337 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5338 ins_pipe(ialu_reg_mem); // XXX 5339 %} 5340 5341 // Load Compressed Pointer 5342 instruct loadN(rRegN dst, memory mem) 5343 %{ 5344 match(Set dst (LoadN mem)); 5345 5346 ins_cost(125); // XXX 5347 format %{ "movl $dst, $mem\t# compressed ptr" %} 5348 ins_encode %{ 5349 __ movl($dst$$Register, $mem$$Address); 5350 %} 5351 ins_pipe(ialu_reg_mem); // XXX 5352 %} 5353 5354 5355 // Load Klass Pointer 5356 instruct loadKlass(rRegP dst, memory mem) 5357 %{ 5358 match(Set dst (LoadKlass mem)); 5359 5360 ins_cost(125); // XXX 5361 format %{ "movq $dst, $mem\t# class" %} 5362 opcode(0x8B); 5363 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5364 ins_pipe(ialu_reg_mem); // XXX 5365 %} 5366 5367 // Load narrow Klass Pointer 5368 instruct loadNKlass(rRegN dst, memory mem) 5369 %{ 5370 match(Set dst (LoadNKlass mem)); 5371 5372 ins_cost(125); // XXX 5373 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5374 ins_encode %{ 5375 __ movl($dst$$Register, $mem$$Address); 5376 %} 5377 ins_pipe(ialu_reg_mem); // XXX 5378 %} 5379 5380 // Load Float 5381 instruct loadF(regF dst, memory mem) 5382 %{ 5383 match(Set dst (LoadF mem)); 5384 5385 ins_cost(145); // XXX 5386 format %{ "movss $dst, $mem\t# float" %} 5387 ins_encode %{ 5388 __ movflt($dst$$XMMRegister, $mem$$Address); 5389 %} 5390 ins_pipe(pipe_slow); // XXX 5391 %} 5392 5393 // Load Double 5394 instruct loadD_partial(regD dst, memory mem) 5395 %{ 5396 predicate(!UseXmmLoadAndClearUpper); 5397 match(Set dst (LoadD mem)); 5398 5399 ins_cost(145); // XXX 5400 format %{ "movlpd $dst, $mem\t# double" %} 5401 ins_encode %{ 5402 __ movdbl($dst$$XMMRegister, $mem$$Address); 5403 %} 5404 ins_pipe(pipe_slow); // XXX 5405 %} 5406 5407 instruct loadD(regD dst, memory mem) 5408 %{ 5409 predicate(UseXmmLoadAndClearUpper); 5410 match(Set dst (LoadD mem)); 5411 5412 ins_cost(145); // XXX 5413 format %{ "movsd $dst, $mem\t# double" %} 5414 ins_encode %{ 5415 __ movdbl($dst$$XMMRegister, $mem$$Address); 5416 %} 5417 ins_pipe(pipe_slow); // XXX 5418 %} 5419 5420 // Load Aligned Packed Byte to XMM register 5421 instruct loadA8B(regD dst, memory mem) %{ 5422 match(Set dst (Load8B mem)); 5423 ins_cost(125); 5424 format %{ "MOVQ $dst,$mem\t! packed8B" %} 5425 ins_encode %{ 5426 __ movq($dst$$XMMRegister, $mem$$Address); 5427 %} 5428 ins_pipe( pipe_slow ); 5429 %} 5430 5431 // Load Aligned Packed Short to XMM register 5432 instruct loadA4S(regD dst, memory mem) %{ 5433 match(Set dst (Load4S mem)); 5434 ins_cost(125); 5435 format %{ "MOVQ $dst,$mem\t! packed4S" %} 5436 ins_encode %{ 5437 __ movq($dst$$XMMRegister, $mem$$Address); 5438 %} 5439 ins_pipe( pipe_slow ); 5440 %} 5441 5442 // Load Aligned Packed Char to XMM register 5443 instruct loadA4C(regD dst, memory mem) %{ 5444 match(Set dst (Load4C mem)); 5445 ins_cost(125); 5446 format %{ "MOVQ $dst,$mem\t! packed4C" %} 5447 ins_encode %{ 5448 __ movq($dst$$XMMRegister, $mem$$Address); 5449 %} 5450 ins_pipe( pipe_slow ); 5451 %} 5452 5453 // Load Aligned Packed Integer to XMM register 5454 instruct load2IU(regD dst, memory mem) %{ 5455 match(Set dst (Load2I mem)); 5456 ins_cost(125); 5457 format %{ "MOVQ $dst,$mem\t! packed2I" %} 5458 ins_encode %{ 5459 __ movq($dst$$XMMRegister, $mem$$Address); 5460 %} 5461 ins_pipe( pipe_slow ); 5462 %} 5463 5464 // Load Aligned Packed Single to XMM 5465 instruct loadA2F(regD dst, memory mem) %{ 5466 match(Set dst (Load2F mem)); 5467 ins_cost(125); 5468 format %{ "MOVQ $dst,$mem\t! packed2F" %} 5469 ins_encode %{ 5470 __ movq($dst$$XMMRegister, $mem$$Address); 5471 %} 5472 ins_pipe( pipe_slow ); 5473 %} 5474 5475 // Load Effective Address 5476 instruct leaP8(rRegP dst, indOffset8 mem) 5477 %{ 5478 match(Set dst mem); 5479 5480 ins_cost(110); // XXX 5481 format %{ "leaq $dst, $mem\t# ptr 8" %} 5482 opcode(0x8D); 5483 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5484 ins_pipe(ialu_reg_reg_fat); 5485 %} 5486 5487 instruct leaP32(rRegP dst, indOffset32 mem) 5488 %{ 5489 match(Set dst mem); 5490 5491 ins_cost(110); 5492 format %{ "leaq $dst, $mem\t# ptr 32" %} 5493 opcode(0x8D); 5494 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5495 ins_pipe(ialu_reg_reg_fat); 5496 %} 5497 5498 // instruct leaPIdx(rRegP dst, indIndex mem) 5499 // %{ 5500 // match(Set dst mem); 5501 5502 // ins_cost(110); 5503 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5504 // opcode(0x8D); 5505 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5506 // ins_pipe(ialu_reg_reg_fat); 5507 // %} 5508 5509 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5510 %{ 5511 match(Set dst mem); 5512 5513 ins_cost(110); 5514 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5515 opcode(0x8D); 5516 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5517 ins_pipe(ialu_reg_reg_fat); 5518 %} 5519 5520 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5521 %{ 5522 match(Set dst mem); 5523 5524 ins_cost(110); 5525 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5526 opcode(0x8D); 5527 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5528 ins_pipe(ialu_reg_reg_fat); 5529 %} 5530 5531 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5532 %{ 5533 match(Set dst mem); 5534 5535 ins_cost(110); 5536 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5537 opcode(0x8D); 5538 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5539 ins_pipe(ialu_reg_reg_fat); 5540 %} 5541 5542 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5543 %{ 5544 match(Set dst mem); 5545 5546 ins_cost(110); 5547 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5548 opcode(0x8D); 5549 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5550 ins_pipe(ialu_reg_reg_fat); 5551 %} 5552 5553 // Load Effective Address which uses Narrow (32-bits) oop 5554 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5555 %{ 5556 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5557 match(Set dst mem); 5558 5559 ins_cost(110); 5560 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5561 opcode(0x8D); 5562 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5563 ins_pipe(ialu_reg_reg_fat); 5564 %} 5565 5566 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5567 %{ 5568 predicate(Universe::narrow_oop_shift() == 0); 5569 match(Set dst mem); 5570 5571 ins_cost(110); // XXX 5572 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5573 opcode(0x8D); 5574 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5575 ins_pipe(ialu_reg_reg_fat); 5576 %} 5577 5578 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5579 %{ 5580 predicate(Universe::narrow_oop_shift() == 0); 5581 match(Set dst mem); 5582 5583 ins_cost(110); 5584 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5585 opcode(0x8D); 5586 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5587 ins_pipe(ialu_reg_reg_fat); 5588 %} 5589 5590 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5591 %{ 5592 predicate(Universe::narrow_oop_shift() == 0); 5593 match(Set dst mem); 5594 5595 ins_cost(110); 5596 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5597 opcode(0x8D); 5598 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5599 ins_pipe(ialu_reg_reg_fat); 5600 %} 5601 5602 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5603 %{ 5604 predicate(Universe::narrow_oop_shift() == 0); 5605 match(Set dst mem); 5606 5607 ins_cost(110); 5608 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5609 opcode(0x8D); 5610 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5611 ins_pipe(ialu_reg_reg_fat); 5612 %} 5613 5614 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5615 %{ 5616 predicate(Universe::narrow_oop_shift() == 0); 5617 match(Set dst mem); 5618 5619 ins_cost(110); 5620 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5621 opcode(0x8D); 5622 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5623 ins_pipe(ialu_reg_reg_fat); 5624 %} 5625 5626 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5627 %{ 5628 predicate(Universe::narrow_oop_shift() == 0); 5629 match(Set dst mem); 5630 5631 ins_cost(110); 5632 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5633 opcode(0x8D); 5634 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5635 ins_pipe(ialu_reg_reg_fat); 5636 %} 5637 5638 instruct loadConI(rRegI dst, immI src) 5639 %{ 5640 match(Set dst src); 5641 5642 format %{ "movl $dst, $src\t# int" %} 5643 ins_encode(load_immI(dst, src)); 5644 ins_pipe(ialu_reg_fat); // XXX 5645 %} 5646 5647 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5648 %{ 5649 match(Set dst src); 5650 effect(KILL cr); 5651 5652 ins_cost(50); 5653 format %{ "xorl $dst, $dst\t# int" %} 5654 opcode(0x33); /* + rd */ 5655 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5656 ins_pipe(ialu_reg); 5657 %} 5658 5659 instruct loadConL(rRegL dst, immL src) 5660 %{ 5661 match(Set dst src); 5662 5663 ins_cost(150); 5664 format %{ "movq $dst, $src\t# long" %} 5665 ins_encode(load_immL(dst, src)); 5666 ins_pipe(ialu_reg); 5667 %} 5668 5669 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5670 %{ 5671 match(Set dst src); 5672 effect(KILL cr); 5673 5674 ins_cost(50); 5675 format %{ "xorl $dst, $dst\t# long" %} 5676 opcode(0x33); /* + rd */ 5677 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5678 ins_pipe(ialu_reg); // XXX 5679 %} 5680 5681 instruct loadConUL32(rRegL dst, immUL32 src) 5682 %{ 5683 match(Set dst src); 5684 5685 ins_cost(60); 5686 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5687 ins_encode(load_immUL32(dst, src)); 5688 ins_pipe(ialu_reg); 5689 %} 5690 5691 instruct loadConL32(rRegL dst, immL32 src) 5692 %{ 5693 match(Set dst src); 5694 5695 ins_cost(70); 5696 format %{ "movq $dst, $src\t# long (32-bit)" %} 5697 ins_encode(load_immL32(dst, src)); 5698 ins_pipe(ialu_reg); 5699 %} 5700 5701 instruct loadConP(rRegP dst, immP con) %{ 5702 match(Set dst con); 5703 5704 format %{ "movq $dst, $con\t# ptr" %} 5705 ins_encode(load_immP(dst, con)); 5706 ins_pipe(ialu_reg_fat); // XXX 5707 %} 5708 5709 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5710 %{ 5711 match(Set dst src); 5712 effect(KILL cr); 5713 5714 ins_cost(50); 5715 format %{ "xorl $dst, $dst\t# ptr" %} 5716 opcode(0x33); /* + rd */ 5717 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5718 ins_pipe(ialu_reg); 5719 %} 5720 5721 instruct loadConP_poll(rRegP dst, immP_poll src) %{ 5722 match(Set dst src); 5723 format %{ "movq $dst, $src\t!ptr" %} 5724 ins_encode %{ 5725 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type); 5726 __ lea($dst$$Register, polling_page); 5727 %} 5728 ins_pipe(ialu_reg_fat); 5729 %} 5730 5731 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5732 %{ 5733 match(Set dst src); 5734 effect(KILL cr); 5735 5736 ins_cost(60); 5737 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5738 ins_encode(load_immP31(dst, src)); 5739 ins_pipe(ialu_reg); 5740 %} 5741 5742 instruct loadConF(regF dst, immF con) %{ 5743 match(Set dst con); 5744 ins_cost(125); 5745 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5746 ins_encode %{ 5747 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5748 %} 5749 ins_pipe(pipe_slow); 5750 %} 5751 5752 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5753 match(Set dst src); 5754 effect(KILL cr); 5755 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5756 ins_encode %{ 5757 __ xorq($dst$$Register, $dst$$Register); 5758 %} 5759 ins_pipe(ialu_reg); 5760 %} 5761 5762 instruct loadConN(rRegN dst, immN src) %{ 5763 match(Set dst src); 5764 5765 ins_cost(125); 5766 format %{ "movl $dst, $src\t# compressed ptr" %} 5767 ins_encode %{ 5768 address con = (address)$src$$constant; 5769 if (con == NULL) { 5770 ShouldNotReachHere(); 5771 } else { 5772 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5773 } 5774 %} 5775 ins_pipe(ialu_reg_fat); // XXX 5776 %} 5777 5778 instruct loadConF0(regF dst, immF0 src) 5779 %{ 5780 match(Set dst src); 5781 ins_cost(100); 5782 5783 format %{ "xorps $dst, $dst\t# float 0.0" %} 5784 ins_encode %{ 5785 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5786 %} 5787 ins_pipe(pipe_slow); 5788 %} 5789 5790 // Use the same format since predicate() can not be used here. 5791 instruct loadConD(regD dst, immD con) %{ 5792 match(Set dst con); 5793 ins_cost(125); 5794 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5795 ins_encode %{ 5796 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5797 %} 5798 ins_pipe(pipe_slow); 5799 %} 5800 5801 instruct loadConD0(regD dst, immD0 src) 5802 %{ 5803 match(Set dst src); 5804 ins_cost(100); 5805 5806 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5807 ins_encode %{ 5808 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5809 %} 5810 ins_pipe(pipe_slow); 5811 %} 5812 5813 instruct loadSSI(rRegI dst, stackSlotI src) 5814 %{ 5815 match(Set dst src); 5816 5817 ins_cost(125); 5818 format %{ "movl $dst, $src\t# int stk" %} 5819 opcode(0x8B); 5820 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5821 ins_pipe(ialu_reg_mem); 5822 %} 5823 5824 instruct loadSSL(rRegL dst, stackSlotL src) 5825 %{ 5826 match(Set dst src); 5827 5828 ins_cost(125); 5829 format %{ "movq $dst, $src\t# long stk" %} 5830 opcode(0x8B); 5831 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5832 ins_pipe(ialu_reg_mem); 5833 %} 5834 5835 instruct loadSSP(rRegP dst, stackSlotP src) 5836 %{ 5837 match(Set dst src); 5838 5839 ins_cost(125); 5840 format %{ "movq $dst, $src\t# ptr stk" %} 5841 opcode(0x8B); 5842 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5843 ins_pipe(ialu_reg_mem); 5844 %} 5845 5846 instruct loadSSF(regF dst, stackSlotF src) 5847 %{ 5848 match(Set dst src); 5849 5850 ins_cost(125); 5851 format %{ "movss $dst, $src\t# float stk" %} 5852 ins_encode %{ 5853 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5854 %} 5855 ins_pipe(pipe_slow); // XXX 5856 %} 5857 5858 // Use the same format since predicate() can not be used here. 5859 instruct loadSSD(regD dst, stackSlotD src) 5860 %{ 5861 match(Set dst src); 5862 5863 ins_cost(125); 5864 format %{ "movsd $dst, $src\t# double stk" %} 5865 ins_encode %{ 5866 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5867 %} 5868 ins_pipe(pipe_slow); // XXX 5869 %} 5870 5871 // Prefetch instructions. 5872 // Must be safe to execute with invalid address (cannot fault). 5873 5874 instruct prefetchr( memory mem ) %{ 5875 predicate(ReadPrefetchInstr==3); 5876 match(PrefetchRead mem); 5877 ins_cost(125); 5878 5879 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} 5880 ins_encode %{ 5881 __ prefetchr($mem$$Address); 5882 %} 5883 ins_pipe(ialu_mem); 5884 %} 5885 5886 instruct prefetchrNTA( memory mem ) %{ 5887 predicate(ReadPrefetchInstr==0); 5888 match(PrefetchRead mem); 5889 ins_cost(125); 5890 5891 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} 5892 ins_encode %{ 5893 __ prefetchnta($mem$$Address); 5894 %} 5895 ins_pipe(ialu_mem); 5896 %} 5897 5898 instruct prefetchrT0( memory mem ) %{ 5899 predicate(ReadPrefetchInstr==1); 5900 match(PrefetchRead mem); 5901 ins_cost(125); 5902 5903 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} 5904 ins_encode %{ 5905 __ prefetcht0($mem$$Address); 5906 %} 5907 ins_pipe(ialu_mem); 5908 %} 5909 5910 instruct prefetchrT2( memory mem ) %{ 5911 predicate(ReadPrefetchInstr==2); 5912 match(PrefetchRead mem); 5913 ins_cost(125); 5914 5915 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} 5916 ins_encode %{ 5917 __ prefetcht2($mem$$Address); 5918 %} 5919 ins_pipe(ialu_mem); 5920 %} 5921 5922 instruct prefetchwNTA( memory mem ) %{ 5923 match(PrefetchWrite mem); 5924 ins_cost(125); 5925 5926 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} 5927 ins_encode %{ 5928 __ prefetchnta($mem$$Address); 5929 %} 5930 ins_pipe(ialu_mem); 5931 %} 5932 5933 // Prefetch instructions for allocation. 5934 5935 instruct prefetchAlloc( memory mem ) %{ 5936 predicate(AllocatePrefetchInstr==3); 5937 match(PrefetchAllocation mem); 5938 ins_cost(125); 5939 5940 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5941 ins_encode %{ 5942 __ prefetchw($mem$$Address); 5943 %} 5944 ins_pipe(ialu_mem); 5945 %} 5946 5947 instruct prefetchAllocNTA( memory mem ) %{ 5948 predicate(AllocatePrefetchInstr==0); 5949 match(PrefetchAllocation mem); 5950 ins_cost(125); 5951 5952 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5953 ins_encode %{ 5954 __ prefetchnta($mem$$Address); 5955 %} 5956 ins_pipe(ialu_mem); 5957 %} 5958 5959 instruct prefetchAllocT0( memory mem ) %{ 5960 predicate(AllocatePrefetchInstr==1); 5961 match(PrefetchAllocation mem); 5962 ins_cost(125); 5963 5964 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5965 ins_encode %{ 5966 __ prefetcht0($mem$$Address); 5967 %} 5968 ins_pipe(ialu_mem); 5969 %} 5970 5971 instruct prefetchAllocT2( memory mem ) %{ 5972 predicate(AllocatePrefetchInstr==2); 5973 match(PrefetchAllocation mem); 5974 ins_cost(125); 5975 5976 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5977 ins_encode %{ 5978 __ prefetcht2($mem$$Address); 5979 %} 5980 ins_pipe(ialu_mem); 5981 %} 5982 5983 //----------Store Instructions------------------------------------------------- 5984 5985 // Store Byte 5986 instruct storeB(memory mem, rRegI src) 5987 %{ 5988 match(Set mem (StoreB mem src)); 5989 5990 ins_cost(125); // XXX 5991 format %{ "movb $mem, $src\t# byte" %} 5992 opcode(0x88); 5993 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5994 ins_pipe(ialu_mem_reg); 5995 %} 5996 5997 // Store Char/Short 5998 instruct storeC(memory mem, rRegI src) 5999 %{ 6000 match(Set mem (StoreC mem src)); 6001 6002 ins_cost(125); // XXX 6003 format %{ "movw $mem, $src\t# char/short" %} 6004 opcode(0x89); 6005 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6006 ins_pipe(ialu_mem_reg); 6007 %} 6008 6009 // Store Integer 6010 instruct storeI(memory mem, rRegI src) 6011 %{ 6012 match(Set mem (StoreI mem src)); 6013 6014 ins_cost(125); // XXX 6015 format %{ "movl $mem, $src\t# int" %} 6016 opcode(0x89); 6017 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6018 ins_pipe(ialu_mem_reg); 6019 %} 6020 6021 // Store Long 6022 instruct storeL(memory mem, rRegL src) 6023 %{ 6024 match(Set mem (StoreL mem src)); 6025 6026 ins_cost(125); // XXX 6027 format %{ "movq $mem, $src\t# long" %} 6028 opcode(0x89); 6029 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6030 ins_pipe(ialu_mem_reg); // XXX 6031 %} 6032 6033 // Store Pointer 6034 instruct storeP(memory mem, any_RegP src) 6035 %{ 6036 match(Set mem (StoreP mem src)); 6037 6038 ins_cost(125); // XXX 6039 format %{ "movq $mem, $src\t# ptr" %} 6040 opcode(0x89); 6041 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6042 ins_pipe(ialu_mem_reg); 6043 %} 6044 6045 instruct storeImmP0(memory mem, immP0 zero) 6046 %{ 6047 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6048 match(Set mem (StoreP mem zero)); 6049 6050 ins_cost(125); // XXX 6051 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 6052 ins_encode %{ 6053 __ movq($mem$$Address, r12); 6054 %} 6055 ins_pipe(ialu_mem_reg); 6056 %} 6057 6058 // Store NULL Pointer, mark word, or other simple pointer constant. 6059 instruct storeImmP(memory mem, immP31 src) 6060 %{ 6061 match(Set mem (StoreP mem src)); 6062 6063 ins_cost(150); // XXX 6064 format %{ "movq $mem, $src\t# ptr" %} 6065 opcode(0xC7); /* C7 /0 */ 6066 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6067 ins_pipe(ialu_mem_imm); 6068 %} 6069 6070 // Store Compressed Pointer 6071 instruct storeN(memory mem, rRegN src) 6072 %{ 6073 match(Set mem (StoreN mem src)); 6074 6075 ins_cost(125); // XXX 6076 format %{ "movl $mem, $src\t# compressed ptr" %} 6077 ins_encode %{ 6078 __ movl($mem$$Address, $src$$Register); 6079 %} 6080 ins_pipe(ialu_mem_reg); 6081 %} 6082 6083 instruct storeImmN0(memory mem, immN0 zero) 6084 %{ 6085 predicate(Universe::narrow_oop_base() == NULL); 6086 match(Set mem (StoreN mem zero)); 6087 6088 ins_cost(125); // XXX 6089 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6090 ins_encode %{ 6091 __ movl($mem$$Address, r12); 6092 %} 6093 ins_pipe(ialu_mem_reg); 6094 %} 6095 6096 instruct storeImmN(memory mem, immN src) 6097 %{ 6098 match(Set mem (StoreN mem src)); 6099 6100 ins_cost(150); // XXX 6101 format %{ "movl $mem, $src\t# compressed ptr" %} 6102 ins_encode %{ 6103 address con = (address)$src$$constant; 6104 if (con == NULL) { 6105 __ movl($mem$$Address, (int32_t)0); 6106 } else { 6107 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6108 } 6109 %} 6110 ins_pipe(ialu_mem_imm); 6111 %} 6112 6113 // Store Integer Immediate 6114 instruct storeImmI0(memory mem, immI0 zero) 6115 %{ 6116 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6117 match(Set mem (StoreI mem zero)); 6118 6119 ins_cost(125); // XXX 6120 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6121 ins_encode %{ 6122 __ movl($mem$$Address, r12); 6123 %} 6124 ins_pipe(ialu_mem_reg); 6125 %} 6126 6127 instruct storeImmI(memory mem, immI src) 6128 %{ 6129 match(Set mem (StoreI mem src)); 6130 6131 ins_cost(150); 6132 format %{ "movl $mem, $src\t# int" %} 6133 opcode(0xC7); /* C7 /0 */ 6134 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6135 ins_pipe(ialu_mem_imm); 6136 %} 6137 6138 // Store Long Immediate 6139 instruct storeImmL0(memory mem, immL0 zero) 6140 %{ 6141 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6142 match(Set mem (StoreL mem zero)); 6143 6144 ins_cost(125); // XXX 6145 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6146 ins_encode %{ 6147 __ movq($mem$$Address, r12); 6148 %} 6149 ins_pipe(ialu_mem_reg); 6150 %} 6151 6152 instruct storeImmL(memory mem, immL32 src) 6153 %{ 6154 match(Set mem (StoreL mem src)); 6155 6156 ins_cost(150); 6157 format %{ "movq $mem, $src\t# long" %} 6158 opcode(0xC7); /* C7 /0 */ 6159 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6160 ins_pipe(ialu_mem_imm); 6161 %} 6162 6163 // Store Short/Char Immediate 6164 instruct storeImmC0(memory mem, immI0 zero) 6165 %{ 6166 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6167 match(Set mem (StoreC mem zero)); 6168 6169 ins_cost(125); // XXX 6170 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6171 ins_encode %{ 6172 __ movw($mem$$Address, r12); 6173 %} 6174 ins_pipe(ialu_mem_reg); 6175 %} 6176 6177 instruct storeImmI16(memory mem, immI16 src) 6178 %{ 6179 predicate(UseStoreImmI16); 6180 match(Set mem (StoreC mem src)); 6181 6182 ins_cost(150); 6183 format %{ "movw $mem, $src\t# short/char" %} 6184 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6185 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6186 ins_pipe(ialu_mem_imm); 6187 %} 6188 6189 // Store Byte Immediate 6190 instruct storeImmB0(memory mem, immI0 zero) 6191 %{ 6192 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6193 match(Set mem (StoreB mem zero)); 6194 6195 ins_cost(125); // XXX 6196 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6197 ins_encode %{ 6198 __ movb($mem$$Address, r12); 6199 %} 6200 ins_pipe(ialu_mem_reg); 6201 %} 6202 6203 instruct storeImmB(memory mem, immI8 src) 6204 %{ 6205 match(Set mem (StoreB mem src)); 6206 6207 ins_cost(150); // XXX 6208 format %{ "movb $mem, $src\t# byte" %} 6209 opcode(0xC6); /* C6 /0 */ 6210 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6211 ins_pipe(ialu_mem_imm); 6212 %} 6213 6214 // Store Aligned Packed Byte XMM register to memory 6215 instruct storeA8B(memory mem, regD src) %{ 6216 match(Set mem (Store8B mem src)); 6217 ins_cost(145); 6218 format %{ "MOVQ $mem,$src\t! packed8B" %} 6219 ins_encode %{ 6220 __ movq($mem$$Address, $src$$XMMRegister); 6221 %} 6222 ins_pipe( pipe_slow ); 6223 %} 6224 6225 // Store Aligned Packed Char/Short XMM register to memory 6226 instruct storeA4C(memory mem, regD src) %{ 6227 match(Set mem (Store4C mem src)); 6228 ins_cost(145); 6229 format %{ "MOVQ $mem,$src\t! packed4C" %} 6230 ins_encode %{ 6231 __ movq($mem$$Address, $src$$XMMRegister); 6232 %} 6233 ins_pipe( pipe_slow ); 6234 %} 6235 6236 // Store Aligned Packed Integer XMM register to memory 6237 instruct storeA2I(memory mem, regD src) %{ 6238 match(Set mem (Store2I mem src)); 6239 ins_cost(145); 6240 format %{ "MOVQ $mem,$src\t! packed2I" %} 6241 ins_encode %{ 6242 __ movq($mem$$Address, $src$$XMMRegister); 6243 %} 6244 ins_pipe( pipe_slow ); 6245 %} 6246 6247 // Store CMS card-mark Immediate 6248 instruct storeImmCM0_reg(memory mem, immI0 zero) 6249 %{ 6250 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6251 match(Set mem (StoreCM mem zero)); 6252 6253 ins_cost(125); // XXX 6254 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6255 ins_encode %{ 6256 __ movb($mem$$Address, r12); 6257 %} 6258 ins_pipe(ialu_mem_reg); 6259 %} 6260 6261 instruct storeImmCM0(memory mem, immI0 src) 6262 %{ 6263 match(Set mem (StoreCM mem src)); 6264 6265 ins_cost(150); // XXX 6266 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6267 opcode(0xC6); /* C6 /0 */ 6268 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6269 ins_pipe(ialu_mem_imm); 6270 %} 6271 6272 // Store Aligned Packed Single Float XMM register to memory 6273 instruct storeA2F(memory mem, regD src) %{ 6274 match(Set mem (Store2F mem src)); 6275 ins_cost(145); 6276 format %{ "MOVQ $mem,$src\t! packed2F" %} 6277 ins_encode %{ 6278 __ movq($mem$$Address, $src$$XMMRegister); 6279 %} 6280 ins_pipe( pipe_slow ); 6281 %} 6282 6283 // Store Float 6284 instruct storeF(memory mem, regF src) 6285 %{ 6286 match(Set mem (StoreF mem src)); 6287 6288 ins_cost(95); // XXX 6289 format %{ "movss $mem, $src\t# float" %} 6290 ins_encode %{ 6291 __ movflt($mem$$Address, $src$$XMMRegister); 6292 %} 6293 ins_pipe(pipe_slow); // XXX 6294 %} 6295 6296 // Store immediate Float value (it is faster than store from XMM register) 6297 instruct storeF0(memory mem, immF0 zero) 6298 %{ 6299 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6300 match(Set mem (StoreF mem zero)); 6301 6302 ins_cost(25); // XXX 6303 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6304 ins_encode %{ 6305 __ movl($mem$$Address, r12); 6306 %} 6307 ins_pipe(ialu_mem_reg); 6308 %} 6309 6310 instruct storeF_imm(memory mem, immF src) 6311 %{ 6312 match(Set mem (StoreF mem src)); 6313 6314 ins_cost(50); 6315 format %{ "movl $mem, $src\t# float" %} 6316 opcode(0xC7); /* C7 /0 */ 6317 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6318 ins_pipe(ialu_mem_imm); 6319 %} 6320 6321 // Store Double 6322 instruct storeD(memory mem, regD src) 6323 %{ 6324 match(Set mem (StoreD mem src)); 6325 6326 ins_cost(95); // XXX 6327 format %{ "movsd $mem, $src\t# double" %} 6328 ins_encode %{ 6329 __ movdbl($mem$$Address, $src$$XMMRegister); 6330 %} 6331 ins_pipe(pipe_slow); // XXX 6332 %} 6333 6334 // Store immediate double 0.0 (it is faster than store from XMM register) 6335 instruct storeD0_imm(memory mem, immD0 src) 6336 %{ 6337 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6338 match(Set mem (StoreD mem src)); 6339 6340 ins_cost(50); 6341 format %{ "movq $mem, $src\t# double 0." %} 6342 opcode(0xC7); /* C7 /0 */ 6343 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6344 ins_pipe(ialu_mem_imm); 6345 %} 6346 6347 instruct storeD0(memory mem, immD0 zero) 6348 %{ 6349 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6350 match(Set mem (StoreD mem zero)); 6351 6352 ins_cost(25); // XXX 6353 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6354 ins_encode %{ 6355 __ movq($mem$$Address, r12); 6356 %} 6357 ins_pipe(ialu_mem_reg); 6358 %} 6359 6360 instruct storeSSI(stackSlotI dst, rRegI src) 6361 %{ 6362 match(Set dst src); 6363 6364 ins_cost(100); 6365 format %{ "movl $dst, $src\t# int stk" %} 6366 opcode(0x89); 6367 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6368 ins_pipe( ialu_mem_reg ); 6369 %} 6370 6371 instruct storeSSL(stackSlotL dst, rRegL src) 6372 %{ 6373 match(Set dst src); 6374 6375 ins_cost(100); 6376 format %{ "movq $dst, $src\t# long stk" %} 6377 opcode(0x89); 6378 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6379 ins_pipe(ialu_mem_reg); 6380 %} 6381 6382 instruct storeSSP(stackSlotP dst, rRegP src) 6383 %{ 6384 match(Set dst src); 6385 6386 ins_cost(100); 6387 format %{ "movq $dst, $src\t# ptr stk" %} 6388 opcode(0x89); 6389 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6390 ins_pipe(ialu_mem_reg); 6391 %} 6392 6393 instruct storeSSF(stackSlotF dst, regF src) 6394 %{ 6395 match(Set dst src); 6396 6397 ins_cost(95); // XXX 6398 format %{ "movss $dst, $src\t# float stk" %} 6399 ins_encode %{ 6400 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6401 %} 6402 ins_pipe(pipe_slow); // XXX 6403 %} 6404 6405 instruct storeSSD(stackSlotD dst, regD src) 6406 %{ 6407 match(Set dst src); 6408 6409 ins_cost(95); // XXX 6410 format %{ "movsd $dst, $src\t# double stk" %} 6411 ins_encode %{ 6412 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6413 %} 6414 ins_pipe(pipe_slow); // XXX 6415 %} 6416 6417 //----------BSWAP Instructions------------------------------------------------- 6418 instruct bytes_reverse_int(rRegI dst) %{ 6419 match(Set dst (ReverseBytesI dst)); 6420 6421 format %{ "bswapl $dst" %} 6422 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6423 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6424 ins_pipe( ialu_reg ); 6425 %} 6426 6427 instruct bytes_reverse_long(rRegL dst) %{ 6428 match(Set dst (ReverseBytesL dst)); 6429 6430 format %{ "bswapq $dst" %} 6431 6432 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6433 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6434 ins_pipe( ialu_reg); 6435 %} 6436 6437 instruct bytes_reverse_unsigned_short(rRegI dst) %{ 6438 match(Set dst (ReverseBytesUS dst)); 6439 6440 format %{ "bswapl $dst\n\t" 6441 "shrl $dst,16\n\t" %} 6442 ins_encode %{ 6443 __ bswapl($dst$$Register); 6444 __ shrl($dst$$Register, 16); 6445 %} 6446 ins_pipe( ialu_reg ); 6447 %} 6448 6449 instruct bytes_reverse_short(rRegI dst) %{ 6450 match(Set dst (ReverseBytesS dst)); 6451 6452 format %{ "bswapl $dst\n\t" 6453 "sar $dst,16\n\t" %} 6454 ins_encode %{ 6455 __ bswapl($dst$$Register); 6456 __ sarl($dst$$Register, 16); 6457 %} 6458 ins_pipe( ialu_reg ); 6459 %} 6460 6461 //---------- Zeros Count Instructions ------------------------------------------ 6462 6463 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6464 predicate(UseCountLeadingZerosInstruction); 6465 match(Set dst (CountLeadingZerosI src)); 6466 effect(KILL cr); 6467 6468 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6469 ins_encode %{ 6470 __ lzcntl($dst$$Register, $src$$Register); 6471 %} 6472 ins_pipe(ialu_reg); 6473 %} 6474 6475 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6476 predicate(!UseCountLeadingZerosInstruction); 6477 match(Set dst (CountLeadingZerosI src)); 6478 effect(KILL cr); 6479 6480 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6481 "jnz skip\n\t" 6482 "movl $dst, -1\n" 6483 "skip:\n\t" 6484 "negl $dst\n\t" 6485 "addl $dst, 31" %} 6486 ins_encode %{ 6487 Register Rdst = $dst$$Register; 6488 Register Rsrc = $src$$Register; 6489 Label skip; 6490 __ bsrl(Rdst, Rsrc); 6491 __ jccb(Assembler::notZero, skip); 6492 __ movl(Rdst, -1); 6493 __ bind(skip); 6494 __ negl(Rdst); 6495 __ addl(Rdst, BitsPerInt - 1); 6496 %} 6497 ins_pipe(ialu_reg); 6498 %} 6499 6500 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6501 predicate(UseCountLeadingZerosInstruction); 6502 match(Set dst (CountLeadingZerosL src)); 6503 effect(KILL cr); 6504 6505 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6506 ins_encode %{ 6507 __ lzcntq($dst$$Register, $src$$Register); 6508 %} 6509 ins_pipe(ialu_reg); 6510 %} 6511 6512 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6513 predicate(!UseCountLeadingZerosInstruction); 6514 match(Set dst (CountLeadingZerosL src)); 6515 effect(KILL cr); 6516 6517 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6518 "jnz skip\n\t" 6519 "movl $dst, -1\n" 6520 "skip:\n\t" 6521 "negl $dst\n\t" 6522 "addl $dst, 63" %} 6523 ins_encode %{ 6524 Register Rdst = $dst$$Register; 6525 Register Rsrc = $src$$Register; 6526 Label skip; 6527 __ bsrq(Rdst, Rsrc); 6528 __ jccb(Assembler::notZero, skip); 6529 __ movl(Rdst, -1); 6530 __ bind(skip); 6531 __ negl(Rdst); 6532 __ addl(Rdst, BitsPerLong - 1); 6533 %} 6534 ins_pipe(ialu_reg); 6535 %} 6536 6537 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6538 match(Set dst (CountTrailingZerosI src)); 6539 effect(KILL cr); 6540 6541 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6542 "jnz done\n\t" 6543 "movl $dst, 32\n" 6544 "done:" %} 6545 ins_encode %{ 6546 Register Rdst = $dst$$Register; 6547 Label done; 6548 __ bsfl(Rdst, $src$$Register); 6549 __ jccb(Assembler::notZero, done); 6550 __ movl(Rdst, BitsPerInt); 6551 __ bind(done); 6552 %} 6553 ins_pipe(ialu_reg); 6554 %} 6555 6556 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6557 match(Set dst (CountTrailingZerosL src)); 6558 effect(KILL cr); 6559 6560 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6561 "jnz done\n\t" 6562 "movl $dst, 64\n" 6563 "done:" %} 6564 ins_encode %{ 6565 Register Rdst = $dst$$Register; 6566 Label done; 6567 __ bsfq(Rdst, $src$$Register); 6568 __ jccb(Assembler::notZero, done); 6569 __ movl(Rdst, BitsPerLong); 6570 __ bind(done); 6571 %} 6572 ins_pipe(ialu_reg); 6573 %} 6574 6575 6576 //---------- Population Count Instructions ------------------------------------- 6577 6578 instruct popCountI(rRegI dst, rRegI src) %{ 6579 predicate(UsePopCountInstruction); 6580 match(Set dst (PopCountI src)); 6581 6582 format %{ "popcnt $dst, $src" %} 6583 ins_encode %{ 6584 __ popcntl($dst$$Register, $src$$Register); 6585 %} 6586 ins_pipe(ialu_reg); 6587 %} 6588 6589 instruct popCountI_mem(rRegI dst, memory mem) %{ 6590 predicate(UsePopCountInstruction); 6591 match(Set dst (PopCountI (LoadI mem))); 6592 6593 format %{ "popcnt $dst, $mem" %} 6594 ins_encode %{ 6595 __ popcntl($dst$$Register, $mem$$Address); 6596 %} 6597 ins_pipe(ialu_reg); 6598 %} 6599 6600 // Note: Long.bitCount(long) returns an int. 6601 instruct popCountL(rRegI dst, rRegL src) %{ 6602 predicate(UsePopCountInstruction); 6603 match(Set dst (PopCountL src)); 6604 6605 format %{ "popcnt $dst, $src" %} 6606 ins_encode %{ 6607 __ popcntq($dst$$Register, $src$$Register); 6608 %} 6609 ins_pipe(ialu_reg); 6610 %} 6611 6612 // Note: Long.bitCount(long) returns an int. 6613 instruct popCountL_mem(rRegI dst, memory mem) %{ 6614 predicate(UsePopCountInstruction); 6615 match(Set dst (PopCountL (LoadL mem))); 6616 6617 format %{ "popcnt $dst, $mem" %} 6618 ins_encode %{ 6619 __ popcntq($dst$$Register, $mem$$Address); 6620 %} 6621 ins_pipe(ialu_reg); 6622 %} 6623 6624 6625 //----------MemBar Instructions----------------------------------------------- 6626 // Memory barrier flavors 6627 6628 instruct membar_acquire() 6629 %{ 6630 match(MemBarAcquire); 6631 ins_cost(0); 6632 6633 size(0); 6634 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6635 ins_encode(); 6636 ins_pipe(empty); 6637 %} 6638 6639 instruct membar_acquire_lock() 6640 %{ 6641 match(MemBarAcquireLock); 6642 ins_cost(0); 6643 6644 size(0); 6645 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6646 ins_encode(); 6647 ins_pipe(empty); 6648 %} 6649 6650 instruct membar_release() 6651 %{ 6652 match(MemBarRelease); 6653 ins_cost(0); 6654 6655 size(0); 6656 format %{ "MEMBAR-release ! (empty encoding)" %} 6657 ins_encode(); 6658 ins_pipe(empty); 6659 %} 6660 6661 instruct membar_release_lock() 6662 %{ 6663 match(MemBarReleaseLock); 6664 ins_cost(0); 6665 6666 size(0); 6667 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6668 ins_encode(); 6669 ins_pipe(empty); 6670 %} 6671 6672 instruct membar_volatile(rFlagsReg cr) %{ 6673 match(MemBarVolatile); 6674 effect(KILL cr); 6675 ins_cost(400); 6676 6677 format %{ 6678 $$template 6679 if (os::is_MP()) { 6680 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6681 } else { 6682 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6683 } 6684 %} 6685 ins_encode %{ 6686 __ membar(Assembler::StoreLoad); 6687 %} 6688 ins_pipe(pipe_slow); 6689 %} 6690 6691 instruct unnecessary_membar_volatile() 6692 %{ 6693 match(MemBarVolatile); 6694 predicate(Matcher::post_store_load_barrier(n)); 6695 ins_cost(0); 6696 6697 size(0); 6698 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6699 ins_encode(); 6700 ins_pipe(empty); 6701 %} 6702 6703 instruct membar_storestore() %{ 6704 match(MemBarStoreStore); 6705 ins_cost(0); 6706 6707 size(0); 6708 format %{ "MEMBAR-storestore (empty encoding)" %} 6709 ins_encode( ); 6710 ins_pipe(empty); 6711 %} 6712 6713 //----------Move Instructions-------------------------------------------------- 6714 6715 instruct castX2P(rRegP dst, rRegL src) 6716 %{ 6717 match(Set dst (CastX2P src)); 6718 6719 format %{ "movq $dst, $src\t# long->ptr" %} 6720 ins_encode %{ 6721 if ($dst$$reg != $src$$reg) { 6722 __ movptr($dst$$Register, $src$$Register); 6723 } 6724 %} 6725 ins_pipe(ialu_reg_reg); // XXX 6726 %} 6727 6728 instruct castP2X(rRegL dst, rRegP src) 6729 %{ 6730 match(Set dst (CastP2X src)); 6731 6732 format %{ "movq $dst, $src\t# ptr -> long" %} 6733 ins_encode %{ 6734 if ($dst$$reg != $src$$reg) { 6735 __ movptr($dst$$Register, $src$$Register); 6736 } 6737 %} 6738 ins_pipe(ialu_reg_reg); // XXX 6739 %} 6740 6741 6742 // Convert oop pointer into compressed form 6743 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6744 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6745 match(Set dst (EncodeP src)); 6746 effect(KILL cr); 6747 format %{ "encode_heap_oop $dst,$src" %} 6748 ins_encode %{ 6749 Register s = $src$$Register; 6750 Register d = $dst$$Register; 6751 if (s != d) { 6752 __ movq(d, s); 6753 } 6754 __ encode_heap_oop(d); 6755 %} 6756 ins_pipe(ialu_reg_long); 6757 %} 6758 6759 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6760 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6761 match(Set dst (EncodeP src)); 6762 effect(KILL cr); 6763 format %{ "encode_heap_oop_not_null $dst,$src" %} 6764 ins_encode %{ 6765 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6766 %} 6767 ins_pipe(ialu_reg_long); 6768 %} 6769 6770 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6771 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6772 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant); 6773 match(Set dst (DecodeN src)); 6774 effect(KILL cr); 6775 format %{ "decode_heap_oop $dst,$src" %} 6776 ins_encode %{ 6777 Register s = $src$$Register; 6778 Register d = $dst$$Register; 6779 if (s != d) { 6780 __ movq(d, s); 6781 } 6782 __ decode_heap_oop(d); 6783 %} 6784 ins_pipe(ialu_reg_long); 6785 %} 6786 6787 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6788 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6789 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); 6790 match(Set dst (DecodeN src)); 6791 effect(KILL cr); 6792 format %{ "decode_heap_oop_not_null $dst,$src" %} 6793 ins_encode %{ 6794 Register s = $src$$Register; 6795 Register d = $dst$$Register; 6796 if (s != d) { 6797 __ decode_heap_oop_not_null(d, s); 6798 } else { 6799 __ decode_heap_oop_not_null(d); 6800 } 6801 %} 6802 ins_pipe(ialu_reg_long); 6803 %} 6804 6805 6806 //----------Conditional Move--------------------------------------------------- 6807 // Jump 6808 // dummy instruction for generating temp registers 6809 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6810 match(Jump (LShiftL switch_val shift)); 6811 ins_cost(350); 6812 predicate(false); 6813 effect(TEMP dest); 6814 6815 format %{ "leaq $dest, [$constantaddress]\n\t" 6816 "jmp [$dest + $switch_val << $shift]\n\t" %} 6817 ins_encode %{ 6818 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6819 // to do that and the compiler is using that register as one it can allocate. 6820 // So we build it all by hand. 6821 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6822 // ArrayAddress dispatch(table, index); 6823 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6824 __ lea($dest$$Register, $constantaddress); 6825 __ jmp(dispatch); 6826 %} 6827 ins_pipe(pipe_jmp); 6828 %} 6829 6830 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6831 match(Jump (AddL (LShiftL switch_val shift) offset)); 6832 ins_cost(350); 6833 effect(TEMP dest); 6834 6835 format %{ "leaq $dest, [$constantaddress]\n\t" 6836 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6837 ins_encode %{ 6838 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6839 // to do that and the compiler is using that register as one it can allocate. 6840 // So we build it all by hand. 6841 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6842 // ArrayAddress dispatch(table, index); 6843 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6844 __ lea($dest$$Register, $constantaddress); 6845 __ jmp(dispatch); 6846 %} 6847 ins_pipe(pipe_jmp); 6848 %} 6849 6850 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6851 match(Jump switch_val); 6852 ins_cost(350); 6853 effect(TEMP dest); 6854 6855 format %{ "leaq $dest, [$constantaddress]\n\t" 6856 "jmp [$dest + $switch_val]\n\t" %} 6857 ins_encode %{ 6858 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6859 // to do that and the compiler is using that register as one it can allocate. 6860 // So we build it all by hand. 6861 // Address index(noreg, switch_reg, Address::times_1); 6862 // ArrayAddress dispatch(table, index); 6863 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6864 __ lea($dest$$Register, $constantaddress); 6865 __ jmp(dispatch); 6866 %} 6867 ins_pipe(pipe_jmp); 6868 %} 6869 6870 // Conditional move 6871 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6872 %{ 6873 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6874 6875 ins_cost(200); // XXX 6876 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6877 opcode(0x0F, 0x40); 6878 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6879 ins_pipe(pipe_cmov_reg); 6880 %} 6881 6882 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6883 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6884 6885 ins_cost(200); // XXX 6886 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6887 opcode(0x0F, 0x40); 6888 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6889 ins_pipe(pipe_cmov_reg); 6890 %} 6891 6892 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6893 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6894 ins_cost(200); 6895 expand %{ 6896 cmovI_regU(cop, cr, dst, src); 6897 %} 6898 %} 6899 6900 // Conditional move 6901 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6902 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6903 6904 ins_cost(250); // XXX 6905 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6906 opcode(0x0F, 0x40); 6907 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6908 ins_pipe(pipe_cmov_mem); 6909 %} 6910 6911 // Conditional move 6912 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6913 %{ 6914 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6915 6916 ins_cost(250); // XXX 6917 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6918 opcode(0x0F, 0x40); 6919 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6920 ins_pipe(pipe_cmov_mem); 6921 %} 6922 6923 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6924 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6925 ins_cost(250); 6926 expand %{ 6927 cmovI_memU(cop, cr, dst, src); 6928 %} 6929 %} 6930 6931 // Conditional move 6932 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6933 %{ 6934 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6935 6936 ins_cost(200); // XXX 6937 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6938 opcode(0x0F, 0x40); 6939 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6940 ins_pipe(pipe_cmov_reg); 6941 %} 6942 6943 // Conditional move 6944 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6945 %{ 6946 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6947 6948 ins_cost(200); // XXX 6949 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6950 opcode(0x0F, 0x40); 6951 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6952 ins_pipe(pipe_cmov_reg); 6953 %} 6954 6955 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6956 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6957 ins_cost(200); 6958 expand %{ 6959 cmovN_regU(cop, cr, dst, src); 6960 %} 6961 %} 6962 6963 // Conditional move 6964 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6965 %{ 6966 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6967 6968 ins_cost(200); // XXX 6969 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6970 opcode(0x0F, 0x40); 6971 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6972 ins_pipe(pipe_cmov_reg); // XXX 6973 %} 6974 6975 // Conditional move 6976 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6977 %{ 6978 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6979 6980 ins_cost(200); // XXX 6981 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6982 opcode(0x0F, 0x40); 6983 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6984 ins_pipe(pipe_cmov_reg); // XXX 6985 %} 6986 6987 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6988 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6989 ins_cost(200); 6990 expand %{ 6991 cmovP_regU(cop, cr, dst, src); 6992 %} 6993 %} 6994 6995 // DISABLED: Requires the ADLC to emit a bottom_type call that 6996 // correctly meets the two pointer arguments; one is an incoming 6997 // register but the other is a memory operand. ALSO appears to 6998 // be buggy with implicit null checks. 6999 // 7000 //// Conditional move 7001 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7002 //%{ 7003 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7004 // ins_cost(250); 7005 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7006 // opcode(0x0F,0x40); 7007 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7008 // ins_pipe( pipe_cmov_mem ); 7009 //%} 7010 // 7011 //// Conditional move 7012 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7013 //%{ 7014 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7015 // ins_cost(250); 7016 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7017 // opcode(0x0F,0x40); 7018 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7019 // ins_pipe( pipe_cmov_mem ); 7020 //%} 7021 7022 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7023 %{ 7024 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7025 7026 ins_cost(200); // XXX 7027 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7028 opcode(0x0F, 0x40); 7029 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7030 ins_pipe(pipe_cmov_reg); // XXX 7031 %} 7032 7033 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7034 %{ 7035 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7036 7037 ins_cost(200); // XXX 7038 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7039 opcode(0x0F, 0x40); 7040 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7041 ins_pipe(pipe_cmov_mem); // XXX 7042 %} 7043 7044 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7045 %{ 7046 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7047 7048 ins_cost(200); // XXX 7049 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7050 opcode(0x0F, 0x40); 7051 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7052 ins_pipe(pipe_cmov_reg); // XXX 7053 %} 7054 7055 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7056 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7057 ins_cost(200); 7058 expand %{ 7059 cmovL_regU(cop, cr, dst, src); 7060 %} 7061 %} 7062 7063 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7064 %{ 7065 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7066 7067 ins_cost(200); // XXX 7068 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7069 opcode(0x0F, 0x40); 7070 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7071 ins_pipe(pipe_cmov_mem); // XXX 7072 %} 7073 7074 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7075 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7076 ins_cost(200); 7077 expand %{ 7078 cmovL_memU(cop, cr, dst, src); 7079 %} 7080 %} 7081 7082 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7083 %{ 7084 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7085 7086 ins_cost(200); // XXX 7087 format %{ "jn$cop skip\t# signed cmove float\n\t" 7088 "movss $dst, $src\n" 7089 "skip:" %} 7090 ins_encode %{ 7091 Label Lskip; 7092 // Invert sense of branch from sense of CMOV 7093 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7094 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7095 __ bind(Lskip); 7096 %} 7097 ins_pipe(pipe_slow); 7098 %} 7099 7100 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7101 // %{ 7102 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7103 7104 // ins_cost(200); // XXX 7105 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7106 // "movss $dst, $src\n" 7107 // "skip:" %} 7108 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7109 // ins_pipe(pipe_slow); 7110 // %} 7111 7112 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7113 %{ 7114 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7115 7116 ins_cost(200); // XXX 7117 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7118 "movss $dst, $src\n" 7119 "skip:" %} 7120 ins_encode %{ 7121 Label Lskip; 7122 // Invert sense of branch from sense of CMOV 7123 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7124 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7125 __ bind(Lskip); 7126 %} 7127 ins_pipe(pipe_slow); 7128 %} 7129 7130 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7131 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7132 ins_cost(200); 7133 expand %{ 7134 cmovF_regU(cop, cr, dst, src); 7135 %} 7136 %} 7137 7138 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7139 %{ 7140 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7141 7142 ins_cost(200); // XXX 7143 format %{ "jn$cop skip\t# signed cmove double\n\t" 7144 "movsd $dst, $src\n" 7145 "skip:" %} 7146 ins_encode %{ 7147 Label Lskip; 7148 // Invert sense of branch from sense of CMOV 7149 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7150 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7151 __ bind(Lskip); 7152 %} 7153 ins_pipe(pipe_slow); 7154 %} 7155 7156 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7157 %{ 7158 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7159 7160 ins_cost(200); // XXX 7161 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7162 "movsd $dst, $src\n" 7163 "skip:" %} 7164 ins_encode %{ 7165 Label Lskip; 7166 // Invert sense of branch from sense of CMOV 7167 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7168 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7169 __ bind(Lskip); 7170 %} 7171 ins_pipe(pipe_slow); 7172 %} 7173 7174 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7175 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7176 ins_cost(200); 7177 expand %{ 7178 cmovD_regU(cop, cr, dst, src); 7179 %} 7180 %} 7181 7182 //----------Arithmetic Instructions-------------------------------------------- 7183 //----------Addition Instructions---------------------------------------------- 7184 7185 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7186 %{ 7187 match(Set dst (AddI dst src)); 7188 effect(KILL cr); 7189 7190 format %{ "addl $dst, $src\t# int" %} 7191 opcode(0x03); 7192 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7193 ins_pipe(ialu_reg_reg); 7194 %} 7195 7196 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7197 %{ 7198 match(Set dst (AddI dst src)); 7199 effect(KILL cr); 7200 7201 format %{ "addl $dst, $src\t# int" %} 7202 opcode(0x81, 0x00); /* /0 id */ 7203 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7204 ins_pipe( ialu_reg ); 7205 %} 7206 7207 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7208 %{ 7209 match(Set dst (AddI dst (LoadI src))); 7210 effect(KILL cr); 7211 7212 ins_cost(125); // XXX 7213 format %{ "addl $dst, $src\t# int" %} 7214 opcode(0x03); 7215 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7216 ins_pipe(ialu_reg_mem); 7217 %} 7218 7219 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7220 %{ 7221 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7222 effect(KILL cr); 7223 7224 ins_cost(150); // XXX 7225 format %{ "addl $dst, $src\t# int" %} 7226 opcode(0x01); /* Opcode 01 /r */ 7227 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7228 ins_pipe(ialu_mem_reg); 7229 %} 7230 7231 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7232 %{ 7233 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7234 effect(KILL cr); 7235 7236 ins_cost(125); // XXX 7237 format %{ "addl $dst, $src\t# int" %} 7238 opcode(0x81); /* Opcode 81 /0 id */ 7239 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7240 ins_pipe(ialu_mem_imm); 7241 %} 7242 7243 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7244 %{ 7245 predicate(UseIncDec); 7246 match(Set dst (AddI dst src)); 7247 effect(KILL cr); 7248 7249 format %{ "incl $dst\t# int" %} 7250 opcode(0xFF, 0x00); // FF /0 7251 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7252 ins_pipe(ialu_reg); 7253 %} 7254 7255 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7256 %{ 7257 predicate(UseIncDec); 7258 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7259 effect(KILL cr); 7260 7261 ins_cost(125); // XXX 7262 format %{ "incl $dst\t# int" %} 7263 opcode(0xFF); /* Opcode FF /0 */ 7264 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7265 ins_pipe(ialu_mem_imm); 7266 %} 7267 7268 // XXX why does that use AddI 7269 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7270 %{ 7271 predicate(UseIncDec); 7272 match(Set dst (AddI dst src)); 7273 effect(KILL cr); 7274 7275 format %{ "decl $dst\t# int" %} 7276 opcode(0xFF, 0x01); // FF /1 7277 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7278 ins_pipe(ialu_reg); 7279 %} 7280 7281 // XXX why does that use AddI 7282 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7283 %{ 7284 predicate(UseIncDec); 7285 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7286 effect(KILL cr); 7287 7288 ins_cost(125); // XXX 7289 format %{ "decl $dst\t# int" %} 7290 opcode(0xFF); /* Opcode FF /1 */ 7291 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7292 ins_pipe(ialu_mem_imm); 7293 %} 7294 7295 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7296 %{ 7297 match(Set dst (AddI src0 src1)); 7298 7299 ins_cost(110); 7300 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7301 opcode(0x8D); /* 0x8D /r */ 7302 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7303 ins_pipe(ialu_reg_reg); 7304 %} 7305 7306 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7307 %{ 7308 match(Set dst (AddL dst src)); 7309 effect(KILL cr); 7310 7311 format %{ "addq $dst, $src\t# long" %} 7312 opcode(0x03); 7313 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7314 ins_pipe(ialu_reg_reg); 7315 %} 7316 7317 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7318 %{ 7319 match(Set dst (AddL dst src)); 7320 effect(KILL cr); 7321 7322 format %{ "addq $dst, $src\t# long" %} 7323 opcode(0x81, 0x00); /* /0 id */ 7324 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7325 ins_pipe( ialu_reg ); 7326 %} 7327 7328 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7329 %{ 7330 match(Set dst (AddL dst (LoadL src))); 7331 effect(KILL cr); 7332 7333 ins_cost(125); // XXX 7334 format %{ "addq $dst, $src\t# long" %} 7335 opcode(0x03); 7336 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7337 ins_pipe(ialu_reg_mem); 7338 %} 7339 7340 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7341 %{ 7342 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7343 effect(KILL cr); 7344 7345 ins_cost(150); // XXX 7346 format %{ "addq $dst, $src\t# long" %} 7347 opcode(0x01); /* Opcode 01 /r */ 7348 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7349 ins_pipe(ialu_mem_reg); 7350 %} 7351 7352 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7353 %{ 7354 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7355 effect(KILL cr); 7356 7357 ins_cost(125); // XXX 7358 format %{ "addq $dst, $src\t# long" %} 7359 opcode(0x81); /* Opcode 81 /0 id */ 7360 ins_encode(REX_mem_wide(dst), 7361 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7362 ins_pipe(ialu_mem_imm); 7363 %} 7364 7365 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7366 %{ 7367 predicate(UseIncDec); 7368 match(Set dst (AddL dst src)); 7369 effect(KILL cr); 7370 7371 format %{ "incq $dst\t# long" %} 7372 opcode(0xFF, 0x00); // FF /0 7373 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7374 ins_pipe(ialu_reg); 7375 %} 7376 7377 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7378 %{ 7379 predicate(UseIncDec); 7380 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7381 effect(KILL cr); 7382 7383 ins_cost(125); // XXX 7384 format %{ "incq $dst\t# long" %} 7385 opcode(0xFF); /* Opcode FF /0 */ 7386 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7387 ins_pipe(ialu_mem_imm); 7388 %} 7389 7390 // XXX why does that use AddL 7391 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7392 %{ 7393 predicate(UseIncDec); 7394 match(Set dst (AddL dst src)); 7395 effect(KILL cr); 7396 7397 format %{ "decq $dst\t# long" %} 7398 opcode(0xFF, 0x01); // FF /1 7399 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7400 ins_pipe(ialu_reg); 7401 %} 7402 7403 // XXX why does that use AddL 7404 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7405 %{ 7406 predicate(UseIncDec); 7407 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7408 effect(KILL cr); 7409 7410 ins_cost(125); // XXX 7411 format %{ "decq $dst\t# long" %} 7412 opcode(0xFF); /* Opcode FF /1 */ 7413 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7414 ins_pipe(ialu_mem_imm); 7415 %} 7416 7417 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7418 %{ 7419 match(Set dst (AddL src0 src1)); 7420 7421 ins_cost(110); 7422 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7423 opcode(0x8D); /* 0x8D /r */ 7424 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7425 ins_pipe(ialu_reg_reg); 7426 %} 7427 7428 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7429 %{ 7430 match(Set dst (AddP dst src)); 7431 effect(KILL cr); 7432 7433 format %{ "addq $dst, $src\t# ptr" %} 7434 opcode(0x03); 7435 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7436 ins_pipe(ialu_reg_reg); 7437 %} 7438 7439 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7440 %{ 7441 match(Set dst (AddP dst src)); 7442 effect(KILL cr); 7443 7444 format %{ "addq $dst, $src\t# ptr" %} 7445 opcode(0x81, 0x00); /* /0 id */ 7446 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7447 ins_pipe( ialu_reg ); 7448 %} 7449 7450 // XXX addP mem ops ???? 7451 7452 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7453 %{ 7454 match(Set dst (AddP src0 src1)); 7455 7456 ins_cost(110); 7457 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7458 opcode(0x8D); /* 0x8D /r */ 7459 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7460 ins_pipe(ialu_reg_reg); 7461 %} 7462 7463 instruct checkCastPP(rRegP dst) 7464 %{ 7465 match(Set dst (CheckCastPP dst)); 7466 7467 size(0); 7468 format %{ "# checkcastPP of $dst" %} 7469 ins_encode(/* empty encoding */); 7470 ins_pipe(empty); 7471 %} 7472 7473 instruct castPP(rRegP dst) 7474 %{ 7475 match(Set dst (CastPP dst)); 7476 7477 size(0); 7478 format %{ "# castPP of $dst" %} 7479 ins_encode(/* empty encoding */); 7480 ins_pipe(empty); 7481 %} 7482 7483 instruct castII(rRegI dst) 7484 %{ 7485 match(Set dst (CastII dst)); 7486 7487 size(0); 7488 format %{ "# castII of $dst" %} 7489 ins_encode(/* empty encoding */); 7490 ins_cost(0); 7491 ins_pipe(empty); 7492 %} 7493 7494 // LoadP-locked same as a regular LoadP when used with compare-swap 7495 instruct loadPLocked(rRegP dst, memory mem) 7496 %{ 7497 match(Set dst (LoadPLocked mem)); 7498 7499 ins_cost(125); // XXX 7500 format %{ "movq $dst, $mem\t# ptr locked" %} 7501 opcode(0x8B); 7502 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7503 ins_pipe(ialu_reg_mem); // XXX 7504 %} 7505 7506 // LoadL-locked - same as a regular LoadL when used with compare-swap 7507 instruct loadLLocked(rRegL dst, memory mem) 7508 %{ 7509 match(Set dst (LoadLLocked mem)); 7510 7511 ins_cost(125); // XXX 7512 format %{ "movq $dst, $mem\t# long locked" %} 7513 opcode(0x8B); 7514 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7515 ins_pipe(ialu_reg_mem); // XXX 7516 %} 7517 7518 // Conditional-store of the updated heap-top. 7519 // Used during allocation of the shared heap. 7520 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7521 7522 instruct storePConditional(memory heap_top_ptr, 7523 rax_RegP oldval, rRegP newval, 7524 rFlagsReg cr) 7525 %{ 7526 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7527 7528 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7529 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7530 opcode(0x0F, 0xB1); 7531 ins_encode(lock_prefix, 7532 REX_reg_mem_wide(newval, heap_top_ptr), 7533 OpcP, OpcS, 7534 reg_mem(newval, heap_top_ptr)); 7535 ins_pipe(pipe_cmpxchg); 7536 %} 7537 7538 // Conditional-store of an int value. 7539 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7540 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7541 %{ 7542 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7543 effect(KILL oldval); 7544 7545 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7546 opcode(0x0F, 0xB1); 7547 ins_encode(lock_prefix, 7548 REX_reg_mem(newval, mem), 7549 OpcP, OpcS, 7550 reg_mem(newval, mem)); 7551 ins_pipe(pipe_cmpxchg); 7552 %} 7553 7554 // Conditional-store of a long value. 7555 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7556 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7557 %{ 7558 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7559 effect(KILL oldval); 7560 7561 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7562 opcode(0x0F, 0xB1); 7563 ins_encode(lock_prefix, 7564 REX_reg_mem_wide(newval, mem), 7565 OpcP, OpcS, 7566 reg_mem(newval, mem)); 7567 ins_pipe(pipe_cmpxchg); 7568 %} 7569 7570 7571 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7572 instruct compareAndSwapP(rRegI res, 7573 memory mem_ptr, 7574 rax_RegP oldval, rRegP newval, 7575 rFlagsReg cr) 7576 %{ 7577 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7578 effect(KILL cr, KILL oldval); 7579 7580 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7581 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7582 "sete $res\n\t" 7583 "movzbl $res, $res" %} 7584 opcode(0x0F, 0xB1); 7585 ins_encode(lock_prefix, 7586 REX_reg_mem_wide(newval, mem_ptr), 7587 OpcP, OpcS, 7588 reg_mem(newval, mem_ptr), 7589 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7590 REX_reg_breg(res, res), // movzbl 7591 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7592 ins_pipe( pipe_cmpxchg ); 7593 %} 7594 7595 instruct compareAndSwapL(rRegI res, 7596 memory mem_ptr, 7597 rax_RegL oldval, rRegL newval, 7598 rFlagsReg cr) 7599 %{ 7600 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7601 effect(KILL cr, KILL oldval); 7602 7603 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7604 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7605 "sete $res\n\t" 7606 "movzbl $res, $res" %} 7607 opcode(0x0F, 0xB1); 7608 ins_encode(lock_prefix, 7609 REX_reg_mem_wide(newval, mem_ptr), 7610 OpcP, OpcS, 7611 reg_mem(newval, mem_ptr), 7612 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7613 REX_reg_breg(res, res), // movzbl 7614 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7615 ins_pipe( pipe_cmpxchg ); 7616 %} 7617 7618 instruct compareAndSwapI(rRegI res, 7619 memory mem_ptr, 7620 rax_RegI oldval, rRegI newval, 7621 rFlagsReg cr) 7622 %{ 7623 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7624 effect(KILL cr, KILL oldval); 7625 7626 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7627 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7628 "sete $res\n\t" 7629 "movzbl $res, $res" %} 7630 opcode(0x0F, 0xB1); 7631 ins_encode(lock_prefix, 7632 REX_reg_mem(newval, mem_ptr), 7633 OpcP, OpcS, 7634 reg_mem(newval, mem_ptr), 7635 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7636 REX_reg_breg(res, res), // movzbl 7637 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7638 ins_pipe( pipe_cmpxchg ); 7639 %} 7640 7641 7642 instruct compareAndSwapN(rRegI res, 7643 memory mem_ptr, 7644 rax_RegN oldval, rRegN newval, 7645 rFlagsReg cr) %{ 7646 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7647 effect(KILL cr, KILL oldval); 7648 7649 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7650 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7651 "sete $res\n\t" 7652 "movzbl $res, $res" %} 7653 opcode(0x0F, 0xB1); 7654 ins_encode(lock_prefix, 7655 REX_reg_mem(newval, mem_ptr), 7656 OpcP, OpcS, 7657 reg_mem(newval, mem_ptr), 7658 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7659 REX_reg_breg(res, res), // movzbl 7660 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7661 ins_pipe( pipe_cmpxchg ); 7662 %} 7663 7664 //----------Subtraction Instructions------------------------------------------- 7665 7666 // Integer Subtraction Instructions 7667 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7668 %{ 7669 match(Set dst (SubI dst src)); 7670 effect(KILL cr); 7671 7672 format %{ "subl $dst, $src\t# int" %} 7673 opcode(0x2B); 7674 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7675 ins_pipe(ialu_reg_reg); 7676 %} 7677 7678 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7679 %{ 7680 match(Set dst (SubI dst src)); 7681 effect(KILL cr); 7682 7683 format %{ "subl $dst, $src\t# int" %} 7684 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7685 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7686 ins_pipe(ialu_reg); 7687 %} 7688 7689 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7690 %{ 7691 match(Set dst (SubI dst (LoadI src))); 7692 effect(KILL cr); 7693 7694 ins_cost(125); 7695 format %{ "subl $dst, $src\t# int" %} 7696 opcode(0x2B); 7697 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7698 ins_pipe(ialu_reg_mem); 7699 %} 7700 7701 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7702 %{ 7703 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7704 effect(KILL cr); 7705 7706 ins_cost(150); 7707 format %{ "subl $dst, $src\t# int" %} 7708 opcode(0x29); /* Opcode 29 /r */ 7709 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7710 ins_pipe(ialu_mem_reg); 7711 %} 7712 7713 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7714 %{ 7715 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7716 effect(KILL cr); 7717 7718 ins_cost(125); // XXX 7719 format %{ "subl $dst, $src\t# int" %} 7720 opcode(0x81); /* Opcode 81 /5 id */ 7721 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7722 ins_pipe(ialu_mem_imm); 7723 %} 7724 7725 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7726 %{ 7727 match(Set dst (SubL dst src)); 7728 effect(KILL cr); 7729 7730 format %{ "subq $dst, $src\t# long" %} 7731 opcode(0x2B); 7732 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7733 ins_pipe(ialu_reg_reg); 7734 %} 7735 7736 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7737 %{ 7738 match(Set dst (SubL dst src)); 7739 effect(KILL cr); 7740 7741 format %{ "subq $dst, $src\t# long" %} 7742 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7743 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7744 ins_pipe(ialu_reg); 7745 %} 7746 7747 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7748 %{ 7749 match(Set dst (SubL dst (LoadL src))); 7750 effect(KILL cr); 7751 7752 ins_cost(125); 7753 format %{ "subq $dst, $src\t# long" %} 7754 opcode(0x2B); 7755 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7756 ins_pipe(ialu_reg_mem); 7757 %} 7758 7759 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7760 %{ 7761 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7762 effect(KILL cr); 7763 7764 ins_cost(150); 7765 format %{ "subq $dst, $src\t# long" %} 7766 opcode(0x29); /* Opcode 29 /r */ 7767 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7768 ins_pipe(ialu_mem_reg); 7769 %} 7770 7771 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7772 %{ 7773 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7774 effect(KILL cr); 7775 7776 ins_cost(125); // XXX 7777 format %{ "subq $dst, $src\t# long" %} 7778 opcode(0x81); /* Opcode 81 /5 id */ 7779 ins_encode(REX_mem_wide(dst), 7780 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7781 ins_pipe(ialu_mem_imm); 7782 %} 7783 7784 // Subtract from a pointer 7785 // XXX hmpf??? 7786 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7787 %{ 7788 match(Set dst (AddP dst (SubI zero src))); 7789 effect(KILL cr); 7790 7791 format %{ "subq $dst, $src\t# ptr - int" %} 7792 opcode(0x2B); 7793 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7794 ins_pipe(ialu_reg_reg); 7795 %} 7796 7797 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7798 %{ 7799 match(Set dst (SubI zero dst)); 7800 effect(KILL cr); 7801 7802 format %{ "negl $dst\t# int" %} 7803 opcode(0xF7, 0x03); // Opcode F7 /3 7804 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7805 ins_pipe(ialu_reg); 7806 %} 7807 7808 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7809 %{ 7810 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7811 effect(KILL cr); 7812 7813 format %{ "negl $dst\t# int" %} 7814 opcode(0xF7, 0x03); // Opcode F7 /3 7815 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7816 ins_pipe(ialu_reg); 7817 %} 7818 7819 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7820 %{ 7821 match(Set dst (SubL zero dst)); 7822 effect(KILL cr); 7823 7824 format %{ "negq $dst\t# long" %} 7825 opcode(0xF7, 0x03); // Opcode F7 /3 7826 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7827 ins_pipe(ialu_reg); 7828 %} 7829 7830 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7831 %{ 7832 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7833 effect(KILL cr); 7834 7835 format %{ "negq $dst\t# long" %} 7836 opcode(0xF7, 0x03); // Opcode F7 /3 7837 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7838 ins_pipe(ialu_reg); 7839 %} 7840 7841 7842 //----------Multiplication/Division Instructions------------------------------- 7843 // Integer Multiplication Instructions 7844 // Multiply Register 7845 7846 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7847 %{ 7848 match(Set dst (MulI dst src)); 7849 effect(KILL cr); 7850 7851 ins_cost(300); 7852 format %{ "imull $dst, $src\t# int" %} 7853 opcode(0x0F, 0xAF); 7854 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7855 ins_pipe(ialu_reg_reg_alu0); 7856 %} 7857 7858 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7859 %{ 7860 match(Set dst (MulI src imm)); 7861 effect(KILL cr); 7862 7863 ins_cost(300); 7864 format %{ "imull $dst, $src, $imm\t# int" %} 7865 opcode(0x69); /* 69 /r id */ 7866 ins_encode(REX_reg_reg(dst, src), 7867 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7868 ins_pipe(ialu_reg_reg_alu0); 7869 %} 7870 7871 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7872 %{ 7873 match(Set dst (MulI dst (LoadI src))); 7874 effect(KILL cr); 7875 7876 ins_cost(350); 7877 format %{ "imull $dst, $src\t# int" %} 7878 opcode(0x0F, 0xAF); 7879 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7880 ins_pipe(ialu_reg_mem_alu0); 7881 %} 7882 7883 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7884 %{ 7885 match(Set dst (MulI (LoadI src) imm)); 7886 effect(KILL cr); 7887 7888 ins_cost(300); 7889 format %{ "imull $dst, $src, $imm\t# int" %} 7890 opcode(0x69); /* 69 /r id */ 7891 ins_encode(REX_reg_mem(dst, src), 7892 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7893 ins_pipe(ialu_reg_mem_alu0); 7894 %} 7895 7896 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7897 %{ 7898 match(Set dst (MulL dst src)); 7899 effect(KILL cr); 7900 7901 ins_cost(300); 7902 format %{ "imulq $dst, $src\t# long" %} 7903 opcode(0x0F, 0xAF); 7904 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7905 ins_pipe(ialu_reg_reg_alu0); 7906 %} 7907 7908 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7909 %{ 7910 match(Set dst (MulL src imm)); 7911 effect(KILL cr); 7912 7913 ins_cost(300); 7914 format %{ "imulq $dst, $src, $imm\t# long" %} 7915 opcode(0x69); /* 69 /r id */ 7916 ins_encode(REX_reg_reg_wide(dst, src), 7917 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7918 ins_pipe(ialu_reg_reg_alu0); 7919 %} 7920 7921 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7922 %{ 7923 match(Set dst (MulL dst (LoadL src))); 7924 effect(KILL cr); 7925 7926 ins_cost(350); 7927 format %{ "imulq $dst, $src\t# long" %} 7928 opcode(0x0F, 0xAF); 7929 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7930 ins_pipe(ialu_reg_mem_alu0); 7931 %} 7932 7933 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7934 %{ 7935 match(Set dst (MulL (LoadL src) imm)); 7936 effect(KILL cr); 7937 7938 ins_cost(300); 7939 format %{ "imulq $dst, $src, $imm\t# long" %} 7940 opcode(0x69); /* 69 /r id */ 7941 ins_encode(REX_reg_mem_wide(dst, src), 7942 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7943 ins_pipe(ialu_reg_mem_alu0); 7944 %} 7945 7946 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7947 %{ 7948 match(Set dst (MulHiL src rax)); 7949 effect(USE_KILL rax, KILL cr); 7950 7951 ins_cost(300); 7952 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7953 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7954 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7955 ins_pipe(ialu_reg_reg_alu0); 7956 %} 7957 7958 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7959 rFlagsReg cr) 7960 %{ 7961 match(Set rax (DivI rax div)); 7962 effect(KILL rdx, KILL cr); 7963 7964 ins_cost(30*100+10*100); // XXX 7965 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7966 "jne,s normal\n\t" 7967 "xorl rdx, rdx\n\t" 7968 "cmpl $div, -1\n\t" 7969 "je,s done\n" 7970 "normal: cdql\n\t" 7971 "idivl $div\n" 7972 "done:" %} 7973 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7974 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7975 ins_pipe(ialu_reg_reg_alu0); 7976 %} 7977 7978 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7979 rFlagsReg cr) 7980 %{ 7981 match(Set rax (DivL rax div)); 7982 effect(KILL rdx, KILL cr); 7983 7984 ins_cost(30*100+10*100); // XXX 7985 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7986 "cmpq rax, rdx\n\t" 7987 "jne,s normal\n\t" 7988 "xorl rdx, rdx\n\t" 7989 "cmpq $div, -1\n\t" 7990 "je,s done\n" 7991 "normal: cdqq\n\t" 7992 "idivq $div\n" 7993 "done:" %} 7994 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7995 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7996 ins_pipe(ialu_reg_reg_alu0); 7997 %} 7998 7999 // Integer DIVMOD with Register, both quotient and mod results 8000 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8001 rFlagsReg cr) 8002 %{ 8003 match(DivModI rax div); 8004 effect(KILL cr); 8005 8006 ins_cost(30*100+10*100); // XXX 8007 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8008 "jne,s normal\n\t" 8009 "xorl rdx, rdx\n\t" 8010 "cmpl $div, -1\n\t" 8011 "je,s done\n" 8012 "normal: cdql\n\t" 8013 "idivl $div\n" 8014 "done:" %} 8015 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8016 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8017 ins_pipe(pipe_slow); 8018 %} 8019 8020 // Long DIVMOD with Register, both quotient and mod results 8021 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8022 rFlagsReg cr) 8023 %{ 8024 match(DivModL rax div); 8025 effect(KILL cr); 8026 8027 ins_cost(30*100+10*100); // XXX 8028 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8029 "cmpq rax, rdx\n\t" 8030 "jne,s normal\n\t" 8031 "xorl rdx, rdx\n\t" 8032 "cmpq $div, -1\n\t" 8033 "je,s done\n" 8034 "normal: cdqq\n\t" 8035 "idivq $div\n" 8036 "done:" %} 8037 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8038 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8039 ins_pipe(pipe_slow); 8040 %} 8041 8042 //----------- DivL-By-Constant-Expansions-------------------------------------- 8043 // DivI cases are handled by the compiler 8044 8045 // Magic constant, reciprocal of 10 8046 instruct loadConL_0x6666666666666667(rRegL dst) 8047 %{ 8048 effect(DEF dst); 8049 8050 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8051 ins_encode(load_immL(dst, 0x6666666666666667)); 8052 ins_pipe(ialu_reg); 8053 %} 8054 8055 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8056 %{ 8057 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8058 8059 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8060 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8061 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8062 ins_pipe(ialu_reg_reg_alu0); 8063 %} 8064 8065 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8066 %{ 8067 effect(USE_DEF dst, KILL cr); 8068 8069 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8070 opcode(0xC1, 0x7); /* C1 /7 ib */ 8071 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8072 ins_pipe(ialu_reg); 8073 %} 8074 8075 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8076 %{ 8077 effect(USE_DEF dst, KILL cr); 8078 8079 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8080 opcode(0xC1, 0x7); /* C1 /7 ib */ 8081 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8082 ins_pipe(ialu_reg); 8083 %} 8084 8085 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8086 %{ 8087 match(Set dst (DivL src div)); 8088 8089 ins_cost((5+8)*100); 8090 expand %{ 8091 rax_RegL rax; // Killed temp 8092 rFlagsReg cr; // Killed 8093 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8094 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8095 sarL_rReg_63(src, cr); // sarq src, 63 8096 sarL_rReg_2(dst, cr); // sarq rdx, 2 8097 subL_rReg(dst, src, cr); // subl rdx, src 8098 %} 8099 %} 8100 8101 //----------------------------------------------------------------------------- 8102 8103 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8104 rFlagsReg cr) 8105 %{ 8106 match(Set rdx (ModI rax div)); 8107 effect(KILL rax, KILL cr); 8108 8109 ins_cost(300); // XXX 8110 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8111 "jne,s normal\n\t" 8112 "xorl rdx, rdx\n\t" 8113 "cmpl $div, -1\n\t" 8114 "je,s done\n" 8115 "normal: cdql\n\t" 8116 "idivl $div\n" 8117 "done:" %} 8118 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8119 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8120 ins_pipe(ialu_reg_reg_alu0); 8121 %} 8122 8123 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8124 rFlagsReg cr) 8125 %{ 8126 match(Set rdx (ModL rax div)); 8127 effect(KILL rax, KILL cr); 8128 8129 ins_cost(300); // XXX 8130 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8131 "cmpq rax, rdx\n\t" 8132 "jne,s normal\n\t" 8133 "xorl rdx, rdx\n\t" 8134 "cmpq $div, -1\n\t" 8135 "je,s done\n" 8136 "normal: cdqq\n\t" 8137 "idivq $div\n" 8138 "done:" %} 8139 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8140 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8141 ins_pipe(ialu_reg_reg_alu0); 8142 %} 8143 8144 // Integer Shift Instructions 8145 // Shift Left by one 8146 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8147 %{ 8148 match(Set dst (LShiftI dst shift)); 8149 effect(KILL cr); 8150 8151 format %{ "sall $dst, $shift" %} 8152 opcode(0xD1, 0x4); /* D1 /4 */ 8153 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8154 ins_pipe(ialu_reg); 8155 %} 8156 8157 // Shift Left by one 8158 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8159 %{ 8160 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8161 effect(KILL cr); 8162 8163 format %{ "sall $dst, $shift\t" %} 8164 opcode(0xD1, 0x4); /* D1 /4 */ 8165 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8166 ins_pipe(ialu_mem_imm); 8167 %} 8168 8169 // Shift Left by 8-bit immediate 8170 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8171 %{ 8172 match(Set dst (LShiftI dst shift)); 8173 effect(KILL cr); 8174 8175 format %{ "sall $dst, $shift" %} 8176 opcode(0xC1, 0x4); /* C1 /4 ib */ 8177 ins_encode(reg_opc_imm(dst, shift)); 8178 ins_pipe(ialu_reg); 8179 %} 8180 8181 // Shift Left by 8-bit immediate 8182 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8183 %{ 8184 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8185 effect(KILL cr); 8186 8187 format %{ "sall $dst, $shift" %} 8188 opcode(0xC1, 0x4); /* C1 /4 ib */ 8189 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8190 ins_pipe(ialu_mem_imm); 8191 %} 8192 8193 // Shift Left by variable 8194 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8195 %{ 8196 match(Set dst (LShiftI dst shift)); 8197 effect(KILL cr); 8198 8199 format %{ "sall $dst, $shift" %} 8200 opcode(0xD3, 0x4); /* D3 /4 */ 8201 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8202 ins_pipe(ialu_reg_reg); 8203 %} 8204 8205 // Shift Left by variable 8206 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8207 %{ 8208 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8209 effect(KILL cr); 8210 8211 format %{ "sall $dst, $shift" %} 8212 opcode(0xD3, 0x4); /* D3 /4 */ 8213 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8214 ins_pipe(ialu_mem_reg); 8215 %} 8216 8217 // Arithmetic shift right by one 8218 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8219 %{ 8220 match(Set dst (RShiftI dst shift)); 8221 effect(KILL cr); 8222 8223 format %{ "sarl $dst, $shift" %} 8224 opcode(0xD1, 0x7); /* D1 /7 */ 8225 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8226 ins_pipe(ialu_reg); 8227 %} 8228 8229 // Arithmetic shift right by one 8230 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8231 %{ 8232 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8233 effect(KILL cr); 8234 8235 format %{ "sarl $dst, $shift" %} 8236 opcode(0xD1, 0x7); /* D1 /7 */ 8237 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8238 ins_pipe(ialu_mem_imm); 8239 %} 8240 8241 // Arithmetic Shift Right by 8-bit immediate 8242 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8243 %{ 8244 match(Set dst (RShiftI dst shift)); 8245 effect(KILL cr); 8246 8247 format %{ "sarl $dst, $shift" %} 8248 opcode(0xC1, 0x7); /* C1 /7 ib */ 8249 ins_encode(reg_opc_imm(dst, shift)); 8250 ins_pipe(ialu_mem_imm); 8251 %} 8252 8253 // Arithmetic Shift Right by 8-bit immediate 8254 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8255 %{ 8256 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8257 effect(KILL cr); 8258 8259 format %{ "sarl $dst, $shift" %} 8260 opcode(0xC1, 0x7); /* C1 /7 ib */ 8261 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8262 ins_pipe(ialu_mem_imm); 8263 %} 8264 8265 // Arithmetic Shift Right by variable 8266 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8267 %{ 8268 match(Set dst (RShiftI dst shift)); 8269 effect(KILL cr); 8270 8271 format %{ "sarl $dst, $shift" %} 8272 opcode(0xD3, 0x7); /* D3 /7 */ 8273 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8274 ins_pipe(ialu_reg_reg); 8275 %} 8276 8277 // Arithmetic Shift Right by variable 8278 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8279 %{ 8280 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8281 effect(KILL cr); 8282 8283 format %{ "sarl $dst, $shift" %} 8284 opcode(0xD3, 0x7); /* D3 /7 */ 8285 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8286 ins_pipe(ialu_mem_reg); 8287 %} 8288 8289 // Logical shift right by one 8290 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8291 %{ 8292 match(Set dst (URShiftI dst shift)); 8293 effect(KILL cr); 8294 8295 format %{ "shrl $dst, $shift" %} 8296 opcode(0xD1, 0x5); /* D1 /5 */ 8297 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8298 ins_pipe(ialu_reg); 8299 %} 8300 8301 // Logical shift right by one 8302 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8303 %{ 8304 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8305 effect(KILL cr); 8306 8307 format %{ "shrl $dst, $shift" %} 8308 opcode(0xD1, 0x5); /* D1 /5 */ 8309 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8310 ins_pipe(ialu_mem_imm); 8311 %} 8312 8313 // Logical Shift Right by 8-bit immediate 8314 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8315 %{ 8316 match(Set dst (URShiftI dst shift)); 8317 effect(KILL cr); 8318 8319 format %{ "shrl $dst, $shift" %} 8320 opcode(0xC1, 0x5); /* C1 /5 ib */ 8321 ins_encode(reg_opc_imm(dst, shift)); 8322 ins_pipe(ialu_reg); 8323 %} 8324 8325 // Logical Shift Right by 8-bit immediate 8326 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8327 %{ 8328 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8329 effect(KILL cr); 8330 8331 format %{ "shrl $dst, $shift" %} 8332 opcode(0xC1, 0x5); /* C1 /5 ib */ 8333 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8334 ins_pipe(ialu_mem_imm); 8335 %} 8336 8337 // Logical Shift Right by variable 8338 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8339 %{ 8340 match(Set dst (URShiftI dst shift)); 8341 effect(KILL cr); 8342 8343 format %{ "shrl $dst, $shift" %} 8344 opcode(0xD3, 0x5); /* D3 /5 */ 8345 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8346 ins_pipe(ialu_reg_reg); 8347 %} 8348 8349 // Logical Shift Right by variable 8350 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8351 %{ 8352 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8353 effect(KILL cr); 8354 8355 format %{ "shrl $dst, $shift" %} 8356 opcode(0xD3, 0x5); /* D3 /5 */ 8357 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8358 ins_pipe(ialu_mem_reg); 8359 %} 8360 8361 // Long Shift Instructions 8362 // Shift Left by one 8363 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8364 %{ 8365 match(Set dst (LShiftL dst shift)); 8366 effect(KILL cr); 8367 8368 format %{ "salq $dst, $shift" %} 8369 opcode(0xD1, 0x4); /* D1 /4 */ 8370 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8371 ins_pipe(ialu_reg); 8372 %} 8373 8374 // Shift Left by one 8375 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8376 %{ 8377 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8378 effect(KILL cr); 8379 8380 format %{ "salq $dst, $shift" %} 8381 opcode(0xD1, 0x4); /* D1 /4 */ 8382 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8383 ins_pipe(ialu_mem_imm); 8384 %} 8385 8386 // Shift Left by 8-bit immediate 8387 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8388 %{ 8389 match(Set dst (LShiftL dst shift)); 8390 effect(KILL cr); 8391 8392 format %{ "salq $dst, $shift" %} 8393 opcode(0xC1, 0x4); /* C1 /4 ib */ 8394 ins_encode(reg_opc_imm_wide(dst, shift)); 8395 ins_pipe(ialu_reg); 8396 %} 8397 8398 // Shift Left by 8-bit immediate 8399 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8400 %{ 8401 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8402 effect(KILL cr); 8403 8404 format %{ "salq $dst, $shift" %} 8405 opcode(0xC1, 0x4); /* C1 /4 ib */ 8406 ins_encode(REX_mem_wide(dst), OpcP, 8407 RM_opc_mem(secondary, dst), Con8or32(shift)); 8408 ins_pipe(ialu_mem_imm); 8409 %} 8410 8411 // Shift Left by variable 8412 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8413 %{ 8414 match(Set dst (LShiftL dst shift)); 8415 effect(KILL cr); 8416 8417 format %{ "salq $dst, $shift" %} 8418 opcode(0xD3, 0x4); /* D3 /4 */ 8419 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8420 ins_pipe(ialu_reg_reg); 8421 %} 8422 8423 // Shift Left by variable 8424 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8425 %{ 8426 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8427 effect(KILL cr); 8428 8429 format %{ "salq $dst, $shift" %} 8430 opcode(0xD3, 0x4); /* D3 /4 */ 8431 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8432 ins_pipe(ialu_mem_reg); 8433 %} 8434 8435 // Arithmetic shift right by one 8436 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8437 %{ 8438 match(Set dst (RShiftL dst shift)); 8439 effect(KILL cr); 8440 8441 format %{ "sarq $dst, $shift" %} 8442 opcode(0xD1, 0x7); /* D1 /7 */ 8443 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8444 ins_pipe(ialu_reg); 8445 %} 8446 8447 // Arithmetic shift right by one 8448 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8449 %{ 8450 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8451 effect(KILL cr); 8452 8453 format %{ "sarq $dst, $shift" %} 8454 opcode(0xD1, 0x7); /* D1 /7 */ 8455 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8456 ins_pipe(ialu_mem_imm); 8457 %} 8458 8459 // Arithmetic Shift Right by 8-bit immediate 8460 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8461 %{ 8462 match(Set dst (RShiftL dst shift)); 8463 effect(KILL cr); 8464 8465 format %{ "sarq $dst, $shift" %} 8466 opcode(0xC1, 0x7); /* C1 /7 ib */ 8467 ins_encode(reg_opc_imm_wide(dst, shift)); 8468 ins_pipe(ialu_mem_imm); 8469 %} 8470 8471 // Arithmetic Shift Right by 8-bit immediate 8472 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8473 %{ 8474 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8475 effect(KILL cr); 8476 8477 format %{ "sarq $dst, $shift" %} 8478 opcode(0xC1, 0x7); /* C1 /7 ib */ 8479 ins_encode(REX_mem_wide(dst), OpcP, 8480 RM_opc_mem(secondary, dst), Con8or32(shift)); 8481 ins_pipe(ialu_mem_imm); 8482 %} 8483 8484 // Arithmetic Shift Right by variable 8485 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8486 %{ 8487 match(Set dst (RShiftL dst shift)); 8488 effect(KILL cr); 8489 8490 format %{ "sarq $dst, $shift" %} 8491 opcode(0xD3, 0x7); /* D3 /7 */ 8492 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8493 ins_pipe(ialu_reg_reg); 8494 %} 8495 8496 // Arithmetic Shift Right by variable 8497 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8498 %{ 8499 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8500 effect(KILL cr); 8501 8502 format %{ "sarq $dst, $shift" %} 8503 opcode(0xD3, 0x7); /* D3 /7 */ 8504 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8505 ins_pipe(ialu_mem_reg); 8506 %} 8507 8508 // Logical shift right by one 8509 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8510 %{ 8511 match(Set dst (URShiftL dst shift)); 8512 effect(KILL cr); 8513 8514 format %{ "shrq $dst, $shift" %} 8515 opcode(0xD1, 0x5); /* D1 /5 */ 8516 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8517 ins_pipe(ialu_reg); 8518 %} 8519 8520 // Logical shift right by one 8521 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8522 %{ 8523 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8524 effect(KILL cr); 8525 8526 format %{ "shrq $dst, $shift" %} 8527 opcode(0xD1, 0x5); /* D1 /5 */ 8528 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8529 ins_pipe(ialu_mem_imm); 8530 %} 8531 8532 // Logical Shift Right by 8-bit immediate 8533 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8534 %{ 8535 match(Set dst (URShiftL dst shift)); 8536 effect(KILL cr); 8537 8538 format %{ "shrq $dst, $shift" %} 8539 opcode(0xC1, 0x5); /* C1 /5 ib */ 8540 ins_encode(reg_opc_imm_wide(dst, shift)); 8541 ins_pipe(ialu_reg); 8542 %} 8543 8544 8545 // Logical Shift Right by 8-bit immediate 8546 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8547 %{ 8548 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8549 effect(KILL cr); 8550 8551 format %{ "shrq $dst, $shift" %} 8552 opcode(0xC1, 0x5); /* C1 /5 ib */ 8553 ins_encode(REX_mem_wide(dst), OpcP, 8554 RM_opc_mem(secondary, dst), Con8or32(shift)); 8555 ins_pipe(ialu_mem_imm); 8556 %} 8557 8558 // Logical Shift Right by variable 8559 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8560 %{ 8561 match(Set dst (URShiftL dst shift)); 8562 effect(KILL cr); 8563 8564 format %{ "shrq $dst, $shift" %} 8565 opcode(0xD3, 0x5); /* D3 /5 */ 8566 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8567 ins_pipe(ialu_reg_reg); 8568 %} 8569 8570 // Logical Shift Right by variable 8571 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8572 %{ 8573 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8574 effect(KILL cr); 8575 8576 format %{ "shrq $dst, $shift" %} 8577 opcode(0xD3, 0x5); /* D3 /5 */ 8578 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8579 ins_pipe(ialu_mem_reg); 8580 %} 8581 8582 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8583 // This idiom is used by the compiler for the i2b bytecode. 8584 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8585 %{ 8586 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8587 8588 format %{ "movsbl $dst, $src\t# i2b" %} 8589 opcode(0x0F, 0xBE); 8590 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8591 ins_pipe(ialu_reg_reg); 8592 %} 8593 8594 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8595 // This idiom is used by the compiler the i2s bytecode. 8596 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8597 %{ 8598 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8599 8600 format %{ "movswl $dst, $src\t# i2s" %} 8601 opcode(0x0F, 0xBF); 8602 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8603 ins_pipe(ialu_reg_reg); 8604 %} 8605 8606 // ROL/ROR instructions 8607 8608 // ROL expand 8609 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8610 effect(KILL cr, USE_DEF dst); 8611 8612 format %{ "roll $dst" %} 8613 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8614 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8615 ins_pipe(ialu_reg); 8616 %} 8617 8618 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8619 effect(USE_DEF dst, USE shift, KILL cr); 8620 8621 format %{ "roll $dst, $shift" %} 8622 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8623 ins_encode( reg_opc_imm(dst, shift) ); 8624 ins_pipe(ialu_reg); 8625 %} 8626 8627 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8628 %{ 8629 effect(USE_DEF dst, USE shift, KILL cr); 8630 8631 format %{ "roll $dst, $shift" %} 8632 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8633 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8634 ins_pipe(ialu_reg_reg); 8635 %} 8636 // end of ROL expand 8637 8638 // Rotate Left by one 8639 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8640 %{ 8641 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8642 8643 expand %{ 8644 rolI_rReg_imm1(dst, cr); 8645 %} 8646 %} 8647 8648 // Rotate Left by 8-bit immediate 8649 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8650 %{ 8651 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8652 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8653 8654 expand %{ 8655 rolI_rReg_imm8(dst, lshift, cr); 8656 %} 8657 %} 8658 8659 // Rotate Left by variable 8660 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8661 %{ 8662 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8663 8664 expand %{ 8665 rolI_rReg_CL(dst, shift, cr); 8666 %} 8667 %} 8668 8669 // Rotate Left by variable 8670 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8671 %{ 8672 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8673 8674 expand %{ 8675 rolI_rReg_CL(dst, shift, cr); 8676 %} 8677 %} 8678 8679 // ROR expand 8680 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8681 %{ 8682 effect(USE_DEF dst, KILL cr); 8683 8684 format %{ "rorl $dst" %} 8685 opcode(0xD1, 0x1); /* D1 /1 */ 8686 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8687 ins_pipe(ialu_reg); 8688 %} 8689 8690 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8691 %{ 8692 effect(USE_DEF dst, USE shift, KILL cr); 8693 8694 format %{ "rorl $dst, $shift" %} 8695 opcode(0xC1, 0x1); /* C1 /1 ib */ 8696 ins_encode(reg_opc_imm(dst, shift)); 8697 ins_pipe(ialu_reg); 8698 %} 8699 8700 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8701 %{ 8702 effect(USE_DEF dst, USE shift, KILL cr); 8703 8704 format %{ "rorl $dst, $shift" %} 8705 opcode(0xD3, 0x1); /* D3 /1 */ 8706 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8707 ins_pipe(ialu_reg_reg); 8708 %} 8709 // end of ROR expand 8710 8711 // Rotate Right by one 8712 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8713 %{ 8714 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8715 8716 expand %{ 8717 rorI_rReg_imm1(dst, cr); 8718 %} 8719 %} 8720 8721 // Rotate Right by 8-bit immediate 8722 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8723 %{ 8724 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8725 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8726 8727 expand %{ 8728 rorI_rReg_imm8(dst, rshift, cr); 8729 %} 8730 %} 8731 8732 // Rotate Right by variable 8733 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8734 %{ 8735 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8736 8737 expand %{ 8738 rorI_rReg_CL(dst, shift, cr); 8739 %} 8740 %} 8741 8742 // Rotate Right by variable 8743 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8744 %{ 8745 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8746 8747 expand %{ 8748 rorI_rReg_CL(dst, shift, cr); 8749 %} 8750 %} 8751 8752 // for long rotate 8753 // ROL expand 8754 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8755 effect(USE_DEF dst, KILL cr); 8756 8757 format %{ "rolq $dst" %} 8758 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8759 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8760 ins_pipe(ialu_reg); 8761 %} 8762 8763 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8764 effect(USE_DEF dst, USE shift, KILL cr); 8765 8766 format %{ "rolq $dst, $shift" %} 8767 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8768 ins_encode( reg_opc_imm_wide(dst, shift) ); 8769 ins_pipe(ialu_reg); 8770 %} 8771 8772 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8773 %{ 8774 effect(USE_DEF dst, USE shift, KILL cr); 8775 8776 format %{ "rolq $dst, $shift" %} 8777 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8778 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8779 ins_pipe(ialu_reg_reg); 8780 %} 8781 // end of ROL expand 8782 8783 // Rotate Left by one 8784 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8785 %{ 8786 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8787 8788 expand %{ 8789 rolL_rReg_imm1(dst, cr); 8790 %} 8791 %} 8792 8793 // Rotate Left by 8-bit immediate 8794 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8795 %{ 8796 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8797 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8798 8799 expand %{ 8800 rolL_rReg_imm8(dst, lshift, cr); 8801 %} 8802 %} 8803 8804 // Rotate Left by variable 8805 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8806 %{ 8807 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8808 8809 expand %{ 8810 rolL_rReg_CL(dst, shift, cr); 8811 %} 8812 %} 8813 8814 // Rotate Left by variable 8815 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8816 %{ 8817 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8818 8819 expand %{ 8820 rolL_rReg_CL(dst, shift, cr); 8821 %} 8822 %} 8823 8824 // ROR expand 8825 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8826 %{ 8827 effect(USE_DEF dst, KILL cr); 8828 8829 format %{ "rorq $dst" %} 8830 opcode(0xD1, 0x1); /* D1 /1 */ 8831 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8832 ins_pipe(ialu_reg); 8833 %} 8834 8835 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8836 %{ 8837 effect(USE_DEF dst, USE shift, KILL cr); 8838 8839 format %{ "rorq $dst, $shift" %} 8840 opcode(0xC1, 0x1); /* C1 /1 ib */ 8841 ins_encode(reg_opc_imm_wide(dst, shift)); 8842 ins_pipe(ialu_reg); 8843 %} 8844 8845 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8846 %{ 8847 effect(USE_DEF dst, USE shift, KILL cr); 8848 8849 format %{ "rorq $dst, $shift" %} 8850 opcode(0xD3, 0x1); /* D3 /1 */ 8851 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8852 ins_pipe(ialu_reg_reg); 8853 %} 8854 // end of ROR expand 8855 8856 // Rotate Right by one 8857 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8858 %{ 8859 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8860 8861 expand %{ 8862 rorL_rReg_imm1(dst, cr); 8863 %} 8864 %} 8865 8866 // Rotate Right by 8-bit immediate 8867 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8868 %{ 8869 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8870 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8871 8872 expand %{ 8873 rorL_rReg_imm8(dst, rshift, cr); 8874 %} 8875 %} 8876 8877 // Rotate Right by variable 8878 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8879 %{ 8880 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8881 8882 expand %{ 8883 rorL_rReg_CL(dst, shift, cr); 8884 %} 8885 %} 8886 8887 // Rotate Right by variable 8888 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8889 %{ 8890 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8891 8892 expand %{ 8893 rorL_rReg_CL(dst, shift, cr); 8894 %} 8895 %} 8896 8897 // Logical Instructions 8898 8899 // Integer Logical Instructions 8900 8901 // And Instructions 8902 // And Register with Register 8903 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8904 %{ 8905 match(Set dst (AndI dst src)); 8906 effect(KILL cr); 8907 8908 format %{ "andl $dst, $src\t# int" %} 8909 opcode(0x23); 8910 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8911 ins_pipe(ialu_reg_reg); 8912 %} 8913 8914 // And Register with Immediate 255 8915 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 8916 %{ 8917 match(Set dst (AndI dst src)); 8918 8919 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 8920 opcode(0x0F, 0xB6); 8921 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8922 ins_pipe(ialu_reg); 8923 %} 8924 8925 // And Register with Immediate 255 and promote to long 8926 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8927 %{ 8928 match(Set dst (ConvI2L (AndI src mask))); 8929 8930 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8931 opcode(0x0F, 0xB6); 8932 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8933 ins_pipe(ialu_reg); 8934 %} 8935 8936 // And Register with Immediate 65535 8937 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 8938 %{ 8939 match(Set dst (AndI dst src)); 8940 8941 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 8942 opcode(0x0F, 0xB7); 8943 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8944 ins_pipe(ialu_reg); 8945 %} 8946 8947 // And Register with Immediate 65535 and promote to long 8948 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8949 %{ 8950 match(Set dst (ConvI2L (AndI src mask))); 8951 8952 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8953 opcode(0x0F, 0xB7); 8954 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8955 ins_pipe(ialu_reg); 8956 %} 8957 8958 // And Register with Immediate 8959 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8960 %{ 8961 match(Set dst (AndI dst src)); 8962 effect(KILL cr); 8963 8964 format %{ "andl $dst, $src\t# int" %} 8965 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8966 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8967 ins_pipe(ialu_reg); 8968 %} 8969 8970 // And Register with Memory 8971 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8972 %{ 8973 match(Set dst (AndI dst (LoadI src))); 8974 effect(KILL cr); 8975 8976 ins_cost(125); 8977 format %{ "andl $dst, $src\t# int" %} 8978 opcode(0x23); 8979 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8980 ins_pipe(ialu_reg_mem); 8981 %} 8982 8983 // And Memory with Register 8984 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8985 %{ 8986 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8987 effect(KILL cr); 8988 8989 ins_cost(150); 8990 format %{ "andl $dst, $src\t# int" %} 8991 opcode(0x21); /* Opcode 21 /r */ 8992 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8993 ins_pipe(ialu_mem_reg); 8994 %} 8995 8996 // And Memory with Immediate 8997 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8998 %{ 8999 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9000 effect(KILL cr); 9001 9002 ins_cost(125); 9003 format %{ "andl $dst, $src\t# int" %} 9004 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9005 ins_encode(REX_mem(dst), OpcSE(src), 9006 RM_opc_mem(secondary, dst), Con8or32(src)); 9007 ins_pipe(ialu_mem_imm); 9008 %} 9009 9010 // Or Instructions 9011 // Or Register with Register 9012 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9013 %{ 9014 match(Set dst (OrI dst src)); 9015 effect(KILL cr); 9016 9017 format %{ "orl $dst, $src\t# int" %} 9018 opcode(0x0B); 9019 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9020 ins_pipe(ialu_reg_reg); 9021 %} 9022 9023 // Or Register with Immediate 9024 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9025 %{ 9026 match(Set dst (OrI dst src)); 9027 effect(KILL cr); 9028 9029 format %{ "orl $dst, $src\t# int" %} 9030 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9031 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9032 ins_pipe(ialu_reg); 9033 %} 9034 9035 // Or Register with Memory 9036 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9037 %{ 9038 match(Set dst (OrI dst (LoadI src))); 9039 effect(KILL cr); 9040 9041 ins_cost(125); 9042 format %{ "orl $dst, $src\t# int" %} 9043 opcode(0x0B); 9044 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9045 ins_pipe(ialu_reg_mem); 9046 %} 9047 9048 // Or Memory with Register 9049 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9050 %{ 9051 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9052 effect(KILL cr); 9053 9054 ins_cost(150); 9055 format %{ "orl $dst, $src\t# int" %} 9056 opcode(0x09); /* Opcode 09 /r */ 9057 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9058 ins_pipe(ialu_mem_reg); 9059 %} 9060 9061 // Or Memory with Immediate 9062 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9063 %{ 9064 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9065 effect(KILL cr); 9066 9067 ins_cost(125); 9068 format %{ "orl $dst, $src\t# int" %} 9069 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9070 ins_encode(REX_mem(dst), OpcSE(src), 9071 RM_opc_mem(secondary, dst), Con8or32(src)); 9072 ins_pipe(ialu_mem_imm); 9073 %} 9074 9075 // Xor Instructions 9076 // Xor Register with Register 9077 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9078 %{ 9079 match(Set dst (XorI dst src)); 9080 effect(KILL cr); 9081 9082 format %{ "xorl $dst, $src\t# int" %} 9083 opcode(0x33); 9084 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9085 ins_pipe(ialu_reg_reg); 9086 %} 9087 9088 // Xor Register with Immediate -1 9089 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9090 match(Set dst (XorI dst imm)); 9091 9092 format %{ "not $dst" %} 9093 ins_encode %{ 9094 __ notl($dst$$Register); 9095 %} 9096 ins_pipe(ialu_reg); 9097 %} 9098 9099 // Xor Register with Immediate 9100 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9101 %{ 9102 match(Set dst (XorI dst src)); 9103 effect(KILL cr); 9104 9105 format %{ "xorl $dst, $src\t# int" %} 9106 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9107 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9108 ins_pipe(ialu_reg); 9109 %} 9110 9111 // Xor Register with Memory 9112 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9113 %{ 9114 match(Set dst (XorI dst (LoadI src))); 9115 effect(KILL cr); 9116 9117 ins_cost(125); 9118 format %{ "xorl $dst, $src\t# int" %} 9119 opcode(0x33); 9120 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9121 ins_pipe(ialu_reg_mem); 9122 %} 9123 9124 // Xor Memory with Register 9125 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9126 %{ 9127 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9128 effect(KILL cr); 9129 9130 ins_cost(150); 9131 format %{ "xorl $dst, $src\t# int" %} 9132 opcode(0x31); /* Opcode 31 /r */ 9133 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9134 ins_pipe(ialu_mem_reg); 9135 %} 9136 9137 // Xor Memory with Immediate 9138 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9139 %{ 9140 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9141 effect(KILL cr); 9142 9143 ins_cost(125); 9144 format %{ "xorl $dst, $src\t# int" %} 9145 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9146 ins_encode(REX_mem(dst), OpcSE(src), 9147 RM_opc_mem(secondary, dst), Con8or32(src)); 9148 ins_pipe(ialu_mem_imm); 9149 %} 9150 9151 9152 // Long Logical Instructions 9153 9154 // And Instructions 9155 // And Register with Register 9156 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9157 %{ 9158 match(Set dst (AndL dst src)); 9159 effect(KILL cr); 9160 9161 format %{ "andq $dst, $src\t# long" %} 9162 opcode(0x23); 9163 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9164 ins_pipe(ialu_reg_reg); 9165 %} 9166 9167 // And Register with Immediate 255 9168 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9169 %{ 9170 match(Set dst (AndL dst src)); 9171 9172 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9173 opcode(0x0F, 0xB6); 9174 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9175 ins_pipe(ialu_reg); 9176 %} 9177 9178 // And Register with Immediate 65535 9179 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9180 %{ 9181 match(Set dst (AndL dst src)); 9182 9183 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9184 opcode(0x0F, 0xB7); 9185 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9186 ins_pipe(ialu_reg); 9187 %} 9188 9189 // And Register with Immediate 9190 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9191 %{ 9192 match(Set dst (AndL dst src)); 9193 effect(KILL cr); 9194 9195 format %{ "andq $dst, $src\t# long" %} 9196 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9197 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9198 ins_pipe(ialu_reg); 9199 %} 9200 9201 // And Register with Memory 9202 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9203 %{ 9204 match(Set dst (AndL dst (LoadL src))); 9205 effect(KILL cr); 9206 9207 ins_cost(125); 9208 format %{ "andq $dst, $src\t# long" %} 9209 opcode(0x23); 9210 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9211 ins_pipe(ialu_reg_mem); 9212 %} 9213 9214 // And Memory with Register 9215 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9216 %{ 9217 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9218 effect(KILL cr); 9219 9220 ins_cost(150); 9221 format %{ "andq $dst, $src\t# long" %} 9222 opcode(0x21); /* Opcode 21 /r */ 9223 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9224 ins_pipe(ialu_mem_reg); 9225 %} 9226 9227 // And Memory with Immediate 9228 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9229 %{ 9230 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9231 effect(KILL cr); 9232 9233 ins_cost(125); 9234 format %{ "andq $dst, $src\t# long" %} 9235 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9236 ins_encode(REX_mem_wide(dst), OpcSE(src), 9237 RM_opc_mem(secondary, dst), Con8or32(src)); 9238 ins_pipe(ialu_mem_imm); 9239 %} 9240 9241 // Or Instructions 9242 // Or Register with Register 9243 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9244 %{ 9245 match(Set dst (OrL dst src)); 9246 effect(KILL cr); 9247 9248 format %{ "orq $dst, $src\t# long" %} 9249 opcode(0x0B); 9250 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9251 ins_pipe(ialu_reg_reg); 9252 %} 9253 9254 // Use any_RegP to match R15 (TLS register) without spilling. 9255 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9256 match(Set dst (OrL dst (CastP2X src))); 9257 effect(KILL cr); 9258 9259 format %{ "orq $dst, $src\t# long" %} 9260 opcode(0x0B); 9261 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9262 ins_pipe(ialu_reg_reg); 9263 %} 9264 9265 9266 // Or Register with Immediate 9267 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9268 %{ 9269 match(Set dst (OrL dst src)); 9270 effect(KILL cr); 9271 9272 format %{ "orq $dst, $src\t# long" %} 9273 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9274 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9275 ins_pipe(ialu_reg); 9276 %} 9277 9278 // Or Register with Memory 9279 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9280 %{ 9281 match(Set dst (OrL dst (LoadL src))); 9282 effect(KILL cr); 9283 9284 ins_cost(125); 9285 format %{ "orq $dst, $src\t# long" %} 9286 opcode(0x0B); 9287 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9288 ins_pipe(ialu_reg_mem); 9289 %} 9290 9291 // Or Memory with Register 9292 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9293 %{ 9294 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9295 effect(KILL cr); 9296 9297 ins_cost(150); 9298 format %{ "orq $dst, $src\t# long" %} 9299 opcode(0x09); /* Opcode 09 /r */ 9300 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9301 ins_pipe(ialu_mem_reg); 9302 %} 9303 9304 // Or Memory with Immediate 9305 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9306 %{ 9307 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9308 effect(KILL cr); 9309 9310 ins_cost(125); 9311 format %{ "orq $dst, $src\t# long" %} 9312 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9313 ins_encode(REX_mem_wide(dst), OpcSE(src), 9314 RM_opc_mem(secondary, dst), Con8or32(src)); 9315 ins_pipe(ialu_mem_imm); 9316 %} 9317 9318 // Xor Instructions 9319 // Xor Register with Register 9320 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9321 %{ 9322 match(Set dst (XorL dst src)); 9323 effect(KILL cr); 9324 9325 format %{ "xorq $dst, $src\t# long" %} 9326 opcode(0x33); 9327 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9328 ins_pipe(ialu_reg_reg); 9329 %} 9330 9331 // Xor Register with Immediate -1 9332 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9333 match(Set dst (XorL dst imm)); 9334 9335 format %{ "notq $dst" %} 9336 ins_encode %{ 9337 __ notq($dst$$Register); 9338 %} 9339 ins_pipe(ialu_reg); 9340 %} 9341 9342 // Xor Register with Immediate 9343 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9344 %{ 9345 match(Set dst (XorL dst src)); 9346 effect(KILL cr); 9347 9348 format %{ "xorq $dst, $src\t# long" %} 9349 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9350 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9351 ins_pipe(ialu_reg); 9352 %} 9353 9354 // Xor Register with Memory 9355 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9356 %{ 9357 match(Set dst (XorL dst (LoadL src))); 9358 effect(KILL cr); 9359 9360 ins_cost(125); 9361 format %{ "xorq $dst, $src\t# long" %} 9362 opcode(0x33); 9363 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9364 ins_pipe(ialu_reg_mem); 9365 %} 9366 9367 // Xor Memory with Register 9368 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9369 %{ 9370 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9371 effect(KILL cr); 9372 9373 ins_cost(150); 9374 format %{ "xorq $dst, $src\t# long" %} 9375 opcode(0x31); /* Opcode 31 /r */ 9376 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9377 ins_pipe(ialu_mem_reg); 9378 %} 9379 9380 // Xor Memory with Immediate 9381 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9382 %{ 9383 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9384 effect(KILL cr); 9385 9386 ins_cost(125); 9387 format %{ "xorq $dst, $src\t# long" %} 9388 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9389 ins_encode(REX_mem_wide(dst), OpcSE(src), 9390 RM_opc_mem(secondary, dst), Con8or32(src)); 9391 ins_pipe(ialu_mem_imm); 9392 %} 9393 9394 // Convert Int to Boolean 9395 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9396 %{ 9397 match(Set dst (Conv2B src)); 9398 effect(KILL cr); 9399 9400 format %{ "testl $src, $src\t# ci2b\n\t" 9401 "setnz $dst\n\t" 9402 "movzbl $dst, $dst" %} 9403 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9404 setNZ_reg(dst), 9405 REX_reg_breg(dst, dst), // movzbl 9406 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9407 ins_pipe(pipe_slow); // XXX 9408 %} 9409 9410 // Convert Pointer to Boolean 9411 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9412 %{ 9413 match(Set dst (Conv2B src)); 9414 effect(KILL cr); 9415 9416 format %{ "testq $src, $src\t# cp2b\n\t" 9417 "setnz $dst\n\t" 9418 "movzbl $dst, $dst" %} 9419 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9420 setNZ_reg(dst), 9421 REX_reg_breg(dst, dst), // movzbl 9422 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9423 ins_pipe(pipe_slow); // XXX 9424 %} 9425 9426 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9427 %{ 9428 match(Set dst (CmpLTMask p q)); 9429 effect(KILL cr); 9430 9431 ins_cost(400); // XXX 9432 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9433 "setlt $dst\n\t" 9434 "movzbl $dst, $dst\n\t" 9435 "negl $dst" %} 9436 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9437 setLT_reg(dst), 9438 REX_reg_breg(dst, dst), // movzbl 9439 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9440 neg_reg(dst)); 9441 ins_pipe(pipe_slow); 9442 %} 9443 9444 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9445 %{ 9446 match(Set dst (CmpLTMask dst zero)); 9447 effect(KILL cr); 9448 9449 ins_cost(100); // XXX 9450 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9451 opcode(0xC1, 0x7); /* C1 /7 ib */ 9452 ins_encode(reg_opc_imm(dst, 0x1F)); 9453 ins_pipe(ialu_reg); 9454 %} 9455 9456 9457 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr) 9458 %{ 9459 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9460 effect(TEMP tmp, KILL cr); 9461 9462 ins_cost(400); // XXX 9463 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t" 9464 "sbbl $tmp, $tmp\n\t" 9465 "andl $tmp, $y\n\t" 9466 "addl $p, $tmp" %} 9467 ins_encode %{ 9468 Register Rp = $p$$Register; 9469 Register Rq = $q$$Register; 9470 Register Ry = $y$$Register; 9471 Register Rt = $tmp$$Register; 9472 __ subl(Rp, Rq); 9473 __ sbbl(Rt, Rt); 9474 __ andl(Rt, Ry); 9475 __ addl(Rp, Rt); 9476 %} 9477 ins_pipe(pipe_cmplt); 9478 %} 9479 9480 //---------- FP Instructions------------------------------------------------ 9481 9482 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9483 %{ 9484 match(Set cr (CmpF src1 src2)); 9485 9486 ins_cost(145); 9487 format %{ "ucomiss $src1, $src2\n\t" 9488 "jnp,s exit\n\t" 9489 "pushfq\t# saw NaN, set CF\n\t" 9490 "andq [rsp], #0xffffff2b\n\t" 9491 "popfq\n" 9492 "exit:" %} 9493 ins_encode %{ 9494 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9495 emit_cmpfp_fixup(_masm); 9496 %} 9497 ins_pipe(pipe_slow); 9498 %} 9499 9500 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9501 match(Set cr (CmpF src1 src2)); 9502 9503 ins_cost(100); 9504 format %{ "ucomiss $src1, $src2" %} 9505 ins_encode %{ 9506 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9507 %} 9508 ins_pipe(pipe_slow); 9509 %} 9510 9511 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9512 %{ 9513 match(Set cr (CmpF src1 (LoadF src2))); 9514 9515 ins_cost(145); 9516 format %{ "ucomiss $src1, $src2\n\t" 9517 "jnp,s exit\n\t" 9518 "pushfq\t# saw NaN, set CF\n\t" 9519 "andq [rsp], #0xffffff2b\n\t" 9520 "popfq\n" 9521 "exit:" %} 9522 ins_encode %{ 9523 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9524 emit_cmpfp_fixup(_masm); 9525 %} 9526 ins_pipe(pipe_slow); 9527 %} 9528 9529 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9530 match(Set cr (CmpF src1 (LoadF src2))); 9531 9532 ins_cost(100); 9533 format %{ "ucomiss $src1, $src2" %} 9534 ins_encode %{ 9535 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9536 %} 9537 ins_pipe(pipe_slow); 9538 %} 9539 9540 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9541 match(Set cr (CmpF src con)); 9542 9543 ins_cost(145); 9544 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9545 "jnp,s exit\n\t" 9546 "pushfq\t# saw NaN, set CF\n\t" 9547 "andq [rsp], #0xffffff2b\n\t" 9548 "popfq\n" 9549 "exit:" %} 9550 ins_encode %{ 9551 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9552 emit_cmpfp_fixup(_masm); 9553 %} 9554 ins_pipe(pipe_slow); 9555 %} 9556 9557 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9558 match(Set cr (CmpF src con)); 9559 ins_cost(100); 9560 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9561 ins_encode %{ 9562 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9563 %} 9564 ins_pipe(pipe_slow); 9565 %} 9566 9567 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9568 %{ 9569 match(Set cr (CmpD src1 src2)); 9570 9571 ins_cost(145); 9572 format %{ "ucomisd $src1, $src2\n\t" 9573 "jnp,s exit\n\t" 9574 "pushfq\t# saw NaN, set CF\n\t" 9575 "andq [rsp], #0xffffff2b\n\t" 9576 "popfq\n" 9577 "exit:" %} 9578 ins_encode %{ 9579 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9580 emit_cmpfp_fixup(_masm); 9581 %} 9582 ins_pipe(pipe_slow); 9583 %} 9584 9585 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9586 match(Set cr (CmpD src1 src2)); 9587 9588 ins_cost(100); 9589 format %{ "ucomisd $src1, $src2 test" %} 9590 ins_encode %{ 9591 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9592 %} 9593 ins_pipe(pipe_slow); 9594 %} 9595 9596 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9597 %{ 9598 match(Set cr (CmpD src1 (LoadD src2))); 9599 9600 ins_cost(145); 9601 format %{ "ucomisd $src1, $src2\n\t" 9602 "jnp,s exit\n\t" 9603 "pushfq\t# saw NaN, set CF\n\t" 9604 "andq [rsp], #0xffffff2b\n\t" 9605 "popfq\n" 9606 "exit:" %} 9607 ins_encode %{ 9608 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9609 emit_cmpfp_fixup(_masm); 9610 %} 9611 ins_pipe(pipe_slow); 9612 %} 9613 9614 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9615 match(Set cr (CmpD src1 (LoadD src2))); 9616 9617 ins_cost(100); 9618 format %{ "ucomisd $src1, $src2" %} 9619 ins_encode %{ 9620 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9621 %} 9622 ins_pipe(pipe_slow); 9623 %} 9624 9625 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9626 match(Set cr (CmpD src con)); 9627 9628 ins_cost(145); 9629 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9630 "jnp,s exit\n\t" 9631 "pushfq\t# saw NaN, set CF\n\t" 9632 "andq [rsp], #0xffffff2b\n\t" 9633 "popfq\n" 9634 "exit:" %} 9635 ins_encode %{ 9636 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9637 emit_cmpfp_fixup(_masm); 9638 %} 9639 ins_pipe(pipe_slow); 9640 %} 9641 9642 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9643 match(Set cr (CmpD src con)); 9644 ins_cost(100); 9645 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9646 ins_encode %{ 9647 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9648 %} 9649 ins_pipe(pipe_slow); 9650 %} 9651 9652 // Compare into -1,0,1 9653 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9654 %{ 9655 match(Set dst (CmpF3 src1 src2)); 9656 effect(KILL cr); 9657 9658 ins_cost(275); 9659 format %{ "ucomiss $src1, $src2\n\t" 9660 "movl $dst, #-1\n\t" 9661 "jp,s done\n\t" 9662 "jb,s done\n\t" 9663 "setne $dst\n\t" 9664 "movzbl $dst, $dst\n" 9665 "done:" %} 9666 ins_encode %{ 9667 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9668 emit_cmpfp3(_masm, $dst$$Register); 9669 %} 9670 ins_pipe(pipe_slow); 9671 %} 9672 9673 // Compare into -1,0,1 9674 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9675 %{ 9676 match(Set dst (CmpF3 src1 (LoadF src2))); 9677 effect(KILL cr); 9678 9679 ins_cost(275); 9680 format %{ "ucomiss $src1, $src2\n\t" 9681 "movl $dst, #-1\n\t" 9682 "jp,s done\n\t" 9683 "jb,s done\n\t" 9684 "setne $dst\n\t" 9685 "movzbl $dst, $dst\n" 9686 "done:" %} 9687 ins_encode %{ 9688 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9689 emit_cmpfp3(_masm, $dst$$Register); 9690 %} 9691 ins_pipe(pipe_slow); 9692 %} 9693 9694 // Compare into -1,0,1 9695 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9696 match(Set dst (CmpF3 src con)); 9697 effect(KILL cr); 9698 9699 ins_cost(275); 9700 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9701 "movl $dst, #-1\n\t" 9702 "jp,s done\n\t" 9703 "jb,s done\n\t" 9704 "setne $dst\n\t" 9705 "movzbl $dst, $dst\n" 9706 "done:" %} 9707 ins_encode %{ 9708 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9709 emit_cmpfp3(_masm, $dst$$Register); 9710 %} 9711 ins_pipe(pipe_slow); 9712 %} 9713 9714 // Compare into -1,0,1 9715 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9716 %{ 9717 match(Set dst (CmpD3 src1 src2)); 9718 effect(KILL cr); 9719 9720 ins_cost(275); 9721 format %{ "ucomisd $src1, $src2\n\t" 9722 "movl $dst, #-1\n\t" 9723 "jp,s done\n\t" 9724 "jb,s done\n\t" 9725 "setne $dst\n\t" 9726 "movzbl $dst, $dst\n" 9727 "done:" %} 9728 ins_encode %{ 9729 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9730 emit_cmpfp3(_masm, $dst$$Register); 9731 %} 9732 ins_pipe(pipe_slow); 9733 %} 9734 9735 // Compare into -1,0,1 9736 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9737 %{ 9738 match(Set dst (CmpD3 src1 (LoadD src2))); 9739 effect(KILL cr); 9740 9741 ins_cost(275); 9742 format %{ "ucomisd $src1, $src2\n\t" 9743 "movl $dst, #-1\n\t" 9744 "jp,s done\n\t" 9745 "jb,s done\n\t" 9746 "setne $dst\n\t" 9747 "movzbl $dst, $dst\n" 9748 "done:" %} 9749 ins_encode %{ 9750 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9751 emit_cmpfp3(_masm, $dst$$Register); 9752 %} 9753 ins_pipe(pipe_slow); 9754 %} 9755 9756 // Compare into -1,0,1 9757 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9758 match(Set dst (CmpD3 src con)); 9759 effect(KILL cr); 9760 9761 ins_cost(275); 9762 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9763 "movl $dst, #-1\n\t" 9764 "jp,s done\n\t" 9765 "jb,s done\n\t" 9766 "setne $dst\n\t" 9767 "movzbl $dst, $dst\n" 9768 "done:" %} 9769 ins_encode %{ 9770 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9771 emit_cmpfp3(_masm, $dst$$Register); 9772 %} 9773 ins_pipe(pipe_slow); 9774 %} 9775 9776 // -----------Trig and Trancendental Instructions------------------------------ 9777 instruct cosD_reg(regD dst) %{ 9778 match(Set dst (CosD dst)); 9779 9780 format %{ "dcos $dst\n\t" %} 9781 opcode(0xD9, 0xFF); 9782 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9783 ins_pipe( pipe_slow ); 9784 %} 9785 9786 instruct sinD_reg(regD dst) %{ 9787 match(Set dst (SinD dst)); 9788 9789 format %{ "dsin $dst\n\t" %} 9790 opcode(0xD9, 0xFE); 9791 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9792 ins_pipe( pipe_slow ); 9793 %} 9794 9795 instruct tanD_reg(regD dst) %{ 9796 match(Set dst (TanD dst)); 9797 9798 format %{ "dtan $dst\n\t" %} 9799 ins_encode( Push_SrcXD(dst), 9800 Opcode(0xD9), Opcode(0xF2), //fptan 9801 Opcode(0xDD), Opcode(0xD8), //fstp st 9802 Push_ResultXD(dst) ); 9803 ins_pipe( pipe_slow ); 9804 %} 9805 9806 instruct log10D_reg(regD dst) %{ 9807 // The source and result Double operands in XMM registers 9808 match(Set dst (Log10D dst)); 9809 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 9810 // fyl2x ; compute log_10(2) * log_2(x) 9811 format %{ "fldlg2\t\t\t#Log10\n\t" 9812 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 9813 %} 9814 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 9815 Push_SrcXD(dst), 9816 Opcode(0xD9), Opcode(0xF1), // fyl2x 9817 Push_ResultXD(dst)); 9818 9819 ins_pipe( pipe_slow ); 9820 %} 9821 9822 instruct logD_reg(regD dst) %{ 9823 // The source and result Double operands in XMM registers 9824 match(Set dst (LogD dst)); 9825 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 9826 // fyl2x ; compute log_e(2) * log_2(x) 9827 format %{ "fldln2\t\t\t#Log_e\n\t" 9828 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 9829 %} 9830 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 9831 Push_SrcXD(dst), 9832 Opcode(0xD9), Opcode(0xF1), // fyl2x 9833 Push_ResultXD(dst)); 9834 ins_pipe( pipe_slow ); 9835 %} 9836 9837 9838 9839 //----------Arithmetic Conversion Instructions--------------------------------- 9840 9841 instruct roundFloat_nop(regF dst) 9842 %{ 9843 match(Set dst (RoundFloat dst)); 9844 9845 ins_cost(0); 9846 ins_encode(); 9847 ins_pipe(empty); 9848 %} 9849 9850 instruct roundDouble_nop(regD dst) 9851 %{ 9852 match(Set dst (RoundDouble dst)); 9853 9854 ins_cost(0); 9855 ins_encode(); 9856 ins_pipe(empty); 9857 %} 9858 9859 instruct convF2D_reg_reg(regD dst, regF src) 9860 %{ 9861 match(Set dst (ConvF2D src)); 9862 9863 format %{ "cvtss2sd $dst, $src" %} 9864 ins_encode %{ 9865 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 9866 %} 9867 ins_pipe(pipe_slow); // XXX 9868 %} 9869 9870 instruct convF2D_reg_mem(regD dst, memory src) 9871 %{ 9872 match(Set dst (ConvF2D (LoadF src))); 9873 9874 format %{ "cvtss2sd $dst, $src" %} 9875 ins_encode %{ 9876 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 9877 %} 9878 ins_pipe(pipe_slow); // XXX 9879 %} 9880 9881 instruct convD2F_reg_reg(regF dst, regD src) 9882 %{ 9883 match(Set dst (ConvD2F src)); 9884 9885 format %{ "cvtsd2ss $dst, $src" %} 9886 ins_encode %{ 9887 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 9888 %} 9889 ins_pipe(pipe_slow); // XXX 9890 %} 9891 9892 instruct convD2F_reg_mem(regF dst, memory src) 9893 %{ 9894 match(Set dst (ConvD2F (LoadD src))); 9895 9896 format %{ "cvtsd2ss $dst, $src" %} 9897 ins_encode %{ 9898 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 9899 %} 9900 ins_pipe(pipe_slow); // XXX 9901 %} 9902 9903 // XXX do mem variants 9904 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9905 %{ 9906 match(Set dst (ConvF2I src)); 9907 effect(KILL cr); 9908 9909 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 9910 "cmpl $dst, #0x80000000\n\t" 9911 "jne,s done\n\t" 9912 "subq rsp, #8\n\t" 9913 "movss [rsp], $src\n\t" 9914 "call f2i_fixup\n\t" 9915 "popq $dst\n" 9916 "done: "%} 9917 ins_encode %{ 9918 Label done; 9919 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 9920 __ cmpl($dst$$Register, 0x80000000); 9921 __ jccb(Assembler::notEqual, done); 9922 __ subptr(rsp, 8); 9923 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9924 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 9925 __ pop($dst$$Register); 9926 __ bind(done); 9927 %} 9928 ins_pipe(pipe_slow); 9929 %} 9930 9931 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 9932 %{ 9933 match(Set dst (ConvF2L src)); 9934 effect(KILL cr); 9935 9936 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 9937 "cmpq $dst, [0x8000000000000000]\n\t" 9938 "jne,s done\n\t" 9939 "subq rsp, #8\n\t" 9940 "movss [rsp], $src\n\t" 9941 "call f2l_fixup\n\t" 9942 "popq $dst\n" 9943 "done: "%} 9944 ins_encode %{ 9945 Label done; 9946 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 9947 __ cmp64($dst$$Register, 9948 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 9949 __ jccb(Assembler::notEqual, done); 9950 __ subptr(rsp, 8); 9951 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9952 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 9953 __ pop($dst$$Register); 9954 __ bind(done); 9955 %} 9956 ins_pipe(pipe_slow); 9957 %} 9958 9959 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 9960 %{ 9961 match(Set dst (ConvD2I src)); 9962 effect(KILL cr); 9963 9964 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 9965 "cmpl $dst, #0x80000000\n\t" 9966 "jne,s done\n\t" 9967 "subq rsp, #8\n\t" 9968 "movsd [rsp], $src\n\t" 9969 "call d2i_fixup\n\t" 9970 "popq $dst\n" 9971 "done: "%} 9972 ins_encode %{ 9973 Label done; 9974 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 9975 __ cmpl($dst$$Register, 0x80000000); 9976 __ jccb(Assembler::notEqual, done); 9977 __ subptr(rsp, 8); 9978 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9979 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 9980 __ pop($dst$$Register); 9981 __ bind(done); 9982 %} 9983 ins_pipe(pipe_slow); 9984 %} 9985 9986 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 9987 %{ 9988 match(Set dst (ConvD2L src)); 9989 effect(KILL cr); 9990 9991 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 9992 "cmpq $dst, [0x8000000000000000]\n\t" 9993 "jne,s done\n\t" 9994 "subq rsp, #8\n\t" 9995 "movsd [rsp], $src\n\t" 9996 "call d2l_fixup\n\t" 9997 "popq $dst\n" 9998 "done: "%} 9999 ins_encode %{ 10000 Label done; 10001 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10002 __ cmp64($dst$$Register, 10003 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10004 __ jccb(Assembler::notEqual, done); 10005 __ subptr(rsp, 8); 10006 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10007 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10008 __ pop($dst$$Register); 10009 __ bind(done); 10010 %} 10011 ins_pipe(pipe_slow); 10012 %} 10013 10014 instruct convI2F_reg_reg(regF dst, rRegI src) 10015 %{ 10016 predicate(!UseXmmI2F); 10017 match(Set dst (ConvI2F src)); 10018 10019 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10020 ins_encode %{ 10021 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10022 %} 10023 ins_pipe(pipe_slow); // XXX 10024 %} 10025 10026 instruct convI2F_reg_mem(regF dst, memory src) 10027 %{ 10028 match(Set dst (ConvI2F (LoadI src))); 10029 10030 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10031 ins_encode %{ 10032 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10033 %} 10034 ins_pipe(pipe_slow); // XXX 10035 %} 10036 10037 instruct convI2D_reg_reg(regD dst, rRegI src) 10038 %{ 10039 predicate(!UseXmmI2D); 10040 match(Set dst (ConvI2D src)); 10041 10042 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10043 ins_encode %{ 10044 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10045 %} 10046 ins_pipe(pipe_slow); // XXX 10047 %} 10048 10049 instruct convI2D_reg_mem(regD dst, memory src) 10050 %{ 10051 match(Set dst (ConvI2D (LoadI src))); 10052 10053 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10054 ins_encode %{ 10055 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10056 %} 10057 ins_pipe(pipe_slow); // XXX 10058 %} 10059 10060 instruct convXI2F_reg(regF dst, rRegI src) 10061 %{ 10062 predicate(UseXmmI2F); 10063 match(Set dst (ConvI2F src)); 10064 10065 format %{ "movdl $dst, $src\n\t" 10066 "cvtdq2psl $dst, $dst\t# i2f" %} 10067 ins_encode %{ 10068 __ movdl($dst$$XMMRegister, $src$$Register); 10069 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10070 %} 10071 ins_pipe(pipe_slow); // XXX 10072 %} 10073 10074 instruct convXI2D_reg(regD dst, rRegI src) 10075 %{ 10076 predicate(UseXmmI2D); 10077 match(Set dst (ConvI2D src)); 10078 10079 format %{ "movdl $dst, $src\n\t" 10080 "cvtdq2pdl $dst, $dst\t# i2d" %} 10081 ins_encode %{ 10082 __ movdl($dst$$XMMRegister, $src$$Register); 10083 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10084 %} 10085 ins_pipe(pipe_slow); // XXX 10086 %} 10087 10088 instruct convL2F_reg_reg(regF dst, rRegL src) 10089 %{ 10090 match(Set dst (ConvL2F src)); 10091 10092 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10093 ins_encode %{ 10094 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10095 %} 10096 ins_pipe(pipe_slow); // XXX 10097 %} 10098 10099 instruct convL2F_reg_mem(regF dst, memory src) 10100 %{ 10101 match(Set dst (ConvL2F (LoadL src))); 10102 10103 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10104 ins_encode %{ 10105 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10106 %} 10107 ins_pipe(pipe_slow); // XXX 10108 %} 10109 10110 instruct convL2D_reg_reg(regD dst, rRegL src) 10111 %{ 10112 match(Set dst (ConvL2D src)); 10113 10114 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10115 ins_encode %{ 10116 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10117 %} 10118 ins_pipe(pipe_slow); // XXX 10119 %} 10120 10121 instruct convL2D_reg_mem(regD dst, memory src) 10122 %{ 10123 match(Set dst (ConvL2D (LoadL src))); 10124 10125 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10126 ins_encode %{ 10127 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10128 %} 10129 ins_pipe(pipe_slow); // XXX 10130 %} 10131 10132 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10133 %{ 10134 match(Set dst (ConvI2L src)); 10135 10136 ins_cost(125); 10137 format %{ "movslq $dst, $src\t# i2l" %} 10138 ins_encode %{ 10139 __ movslq($dst$$Register, $src$$Register); 10140 %} 10141 ins_pipe(ialu_reg_reg); 10142 %} 10143 10144 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10145 // %{ 10146 // match(Set dst (ConvI2L src)); 10147 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10148 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10149 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10150 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10151 // ((const TypeNode*) n)->type()->is_long()->_lo == 10152 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10153 10154 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10155 // ins_encode(enc_copy(dst, src)); 10156 // // opcode(0x63); // needs REX.W 10157 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10158 // ins_pipe(ialu_reg_reg); 10159 // %} 10160 10161 // Zero-extend convert int to long 10162 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10163 %{ 10164 match(Set dst (AndL (ConvI2L src) mask)); 10165 10166 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10167 ins_encode %{ 10168 if ($dst$$reg != $src$$reg) { 10169 __ movl($dst$$Register, $src$$Register); 10170 } 10171 %} 10172 ins_pipe(ialu_reg_reg); 10173 %} 10174 10175 // Zero-extend convert int to long 10176 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10177 %{ 10178 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10179 10180 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10181 ins_encode %{ 10182 __ movl($dst$$Register, $src$$Address); 10183 %} 10184 ins_pipe(ialu_reg_mem); 10185 %} 10186 10187 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10188 %{ 10189 match(Set dst (AndL src mask)); 10190 10191 format %{ "movl $dst, $src\t# zero-extend long" %} 10192 ins_encode %{ 10193 __ movl($dst$$Register, $src$$Register); 10194 %} 10195 ins_pipe(ialu_reg_reg); 10196 %} 10197 10198 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10199 %{ 10200 match(Set dst (ConvL2I src)); 10201 10202 format %{ "movl $dst, $src\t# l2i" %} 10203 ins_encode %{ 10204 __ movl($dst$$Register, $src$$Register); 10205 %} 10206 ins_pipe(ialu_reg_reg); 10207 %} 10208 10209 10210 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10211 match(Set dst (MoveF2I src)); 10212 effect(DEF dst, USE src); 10213 10214 ins_cost(125); 10215 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10216 ins_encode %{ 10217 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10218 %} 10219 ins_pipe(ialu_reg_mem); 10220 %} 10221 10222 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10223 match(Set dst (MoveI2F src)); 10224 effect(DEF dst, USE src); 10225 10226 ins_cost(125); 10227 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10228 ins_encode %{ 10229 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10230 %} 10231 ins_pipe(pipe_slow); 10232 %} 10233 10234 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10235 match(Set dst (MoveD2L src)); 10236 effect(DEF dst, USE src); 10237 10238 ins_cost(125); 10239 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10240 ins_encode %{ 10241 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10242 %} 10243 ins_pipe(ialu_reg_mem); 10244 %} 10245 10246 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10247 predicate(!UseXmmLoadAndClearUpper); 10248 match(Set dst (MoveL2D src)); 10249 effect(DEF dst, USE src); 10250 10251 ins_cost(125); 10252 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10253 ins_encode %{ 10254 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10255 %} 10256 ins_pipe(pipe_slow); 10257 %} 10258 10259 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10260 predicate(UseXmmLoadAndClearUpper); 10261 match(Set dst (MoveL2D src)); 10262 effect(DEF dst, USE src); 10263 10264 ins_cost(125); 10265 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10266 ins_encode %{ 10267 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10268 %} 10269 ins_pipe(pipe_slow); 10270 %} 10271 10272 10273 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10274 match(Set dst (MoveF2I src)); 10275 effect(DEF dst, USE src); 10276 10277 ins_cost(95); // XXX 10278 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10279 ins_encode %{ 10280 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10281 %} 10282 ins_pipe(pipe_slow); 10283 %} 10284 10285 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10286 match(Set dst (MoveI2F src)); 10287 effect(DEF dst, USE src); 10288 10289 ins_cost(100); 10290 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10291 ins_encode %{ 10292 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10293 %} 10294 ins_pipe( ialu_mem_reg ); 10295 %} 10296 10297 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10298 match(Set dst (MoveD2L src)); 10299 effect(DEF dst, USE src); 10300 10301 ins_cost(95); // XXX 10302 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10303 ins_encode %{ 10304 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10305 %} 10306 ins_pipe(pipe_slow); 10307 %} 10308 10309 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10310 match(Set dst (MoveL2D src)); 10311 effect(DEF dst, USE src); 10312 10313 ins_cost(100); 10314 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10315 ins_encode %{ 10316 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10317 %} 10318 ins_pipe(ialu_mem_reg); 10319 %} 10320 10321 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10322 match(Set dst (MoveF2I src)); 10323 effect(DEF dst, USE src); 10324 ins_cost(85); 10325 format %{ "movd $dst,$src\t# MoveF2I" %} 10326 ins_encode %{ 10327 __ movdl($dst$$Register, $src$$XMMRegister); 10328 %} 10329 ins_pipe( pipe_slow ); 10330 %} 10331 10332 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10333 match(Set dst (MoveD2L src)); 10334 effect(DEF dst, USE src); 10335 ins_cost(85); 10336 format %{ "movd $dst,$src\t# MoveD2L" %} 10337 ins_encode %{ 10338 __ movdq($dst$$Register, $src$$XMMRegister); 10339 %} 10340 ins_pipe( pipe_slow ); 10341 %} 10342 10343 // The next instructions have long latency and use Int unit. Set high cost. 10344 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10345 match(Set dst (MoveI2F src)); 10346 effect(DEF dst, USE src); 10347 ins_cost(300); 10348 format %{ "movd $dst,$src\t# MoveI2F" %} 10349 ins_encode %{ 10350 __ movdl($dst$$XMMRegister, $src$$Register); 10351 %} 10352 ins_pipe( pipe_slow ); 10353 %} 10354 10355 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10356 match(Set dst (MoveL2D src)); 10357 effect(DEF dst, USE src); 10358 ins_cost(300); 10359 format %{ "movd $dst,$src\t# MoveL2D" %} 10360 ins_encode %{ 10361 __ movdq($dst$$XMMRegister, $src$$Register); 10362 %} 10363 ins_pipe( pipe_slow ); 10364 %} 10365 10366 // Replicate scalar to packed byte (1 byte) values in xmm 10367 instruct Repl8B_reg(regD dst, regD src) %{ 10368 match(Set dst (Replicate8B src)); 10369 format %{ "MOVDQA $dst,$src\n\t" 10370 "PUNPCKLBW $dst,$dst\n\t" 10371 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 10372 ins_encode %{ 10373 if ($dst$$reg != $src$$reg) { 10374 __ movdqa($dst$$XMMRegister, $src$$XMMRegister); 10375 } 10376 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister); 10377 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); 10378 %} 10379 ins_pipe( pipe_slow ); 10380 %} 10381 10382 // Replicate scalar to packed byte (1 byte) values in xmm 10383 instruct Repl8B_rRegI(regD dst, rRegI src) %{ 10384 match(Set dst (Replicate8B src)); 10385 format %{ "MOVD $dst,$src\n\t" 10386 "PUNPCKLBW $dst,$dst\n\t" 10387 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 10388 ins_encode %{ 10389 __ movdl($dst$$XMMRegister, $src$$Register); 10390 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister); 10391 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); 10392 %} 10393 ins_pipe( pipe_slow ); 10394 %} 10395 10396 // Replicate scalar zero to packed byte (1 byte) values in xmm 10397 instruct Repl8B_immI0(regD dst, immI0 zero) %{ 10398 match(Set dst (Replicate8B zero)); 10399 format %{ "PXOR $dst,$dst\t! replicate8B" %} 10400 ins_encode %{ 10401 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10402 %} 10403 ins_pipe( fpu_reg_reg ); 10404 %} 10405 10406 // Replicate scalar to packed shore (2 byte) values in xmm 10407 instruct Repl4S_reg(regD dst, regD src) %{ 10408 match(Set dst (Replicate4S src)); 10409 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %} 10410 ins_encode %{ 10411 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00); 10412 %} 10413 ins_pipe( fpu_reg_reg ); 10414 %} 10415 10416 // Replicate scalar to packed shore (2 byte) values in xmm 10417 instruct Repl4S_rRegI(regD dst, rRegI src) %{ 10418 match(Set dst (Replicate4S src)); 10419 format %{ "MOVD $dst,$src\n\t" 10420 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %} 10421 ins_encode %{ 10422 __ movdl($dst$$XMMRegister, $src$$Register); 10423 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); 10424 %} 10425 ins_pipe( fpu_reg_reg ); 10426 %} 10427 10428 // Replicate scalar zero to packed short (2 byte) values in xmm 10429 instruct Repl4S_immI0(regD dst, immI0 zero) %{ 10430 match(Set dst (Replicate4S zero)); 10431 format %{ "PXOR $dst,$dst\t! replicate4S" %} 10432 ins_encode %{ 10433 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10434 %} 10435 ins_pipe( fpu_reg_reg ); 10436 %} 10437 10438 // Replicate scalar to packed char (2 byte) values in xmm 10439 instruct Repl4C_reg(regD dst, regD src) %{ 10440 match(Set dst (Replicate4C src)); 10441 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %} 10442 ins_encode %{ 10443 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00); 10444 %} 10445 ins_pipe( fpu_reg_reg ); 10446 %} 10447 10448 // Replicate scalar to packed char (2 byte) values in xmm 10449 instruct Repl4C_rRegI(regD dst, rRegI src) %{ 10450 match(Set dst (Replicate4C src)); 10451 format %{ "MOVD $dst,$src\n\t" 10452 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %} 10453 ins_encode %{ 10454 __ movdl($dst$$XMMRegister, $src$$Register); 10455 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); 10456 %} 10457 ins_pipe( fpu_reg_reg ); 10458 %} 10459 10460 // Replicate scalar zero to packed char (2 byte) values in xmm 10461 instruct Repl4C_immI0(regD dst, immI0 zero) %{ 10462 match(Set dst (Replicate4C zero)); 10463 format %{ "PXOR $dst,$dst\t! replicate4C" %} 10464 ins_encode %{ 10465 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10466 %} 10467 ins_pipe( fpu_reg_reg ); 10468 %} 10469 10470 // Replicate scalar to packed integer (4 byte) values in xmm 10471 instruct Repl2I_reg(regD dst, regD src) %{ 10472 match(Set dst (Replicate2I src)); 10473 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %} 10474 ins_encode %{ 10475 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00); 10476 %} 10477 ins_pipe( fpu_reg_reg ); 10478 %} 10479 10480 // Replicate scalar to packed integer (4 byte) values in xmm 10481 instruct Repl2I_rRegI(regD dst, rRegI src) %{ 10482 match(Set dst (Replicate2I src)); 10483 format %{ "MOVD $dst,$src\n\t" 10484 "PSHUFD $dst,$dst,0x00\t! replicate2I" %} 10485 ins_encode %{ 10486 __ movdl($dst$$XMMRegister, $src$$Register); 10487 __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00); 10488 %} 10489 ins_pipe( fpu_reg_reg ); 10490 %} 10491 10492 // Replicate scalar zero to packed integer (2 byte) values in xmm 10493 instruct Repl2I_immI0(regD dst, immI0 zero) %{ 10494 match(Set dst (Replicate2I zero)); 10495 format %{ "PXOR $dst,$dst\t! replicate2I" %} 10496 ins_encode %{ 10497 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10498 %} 10499 ins_pipe( fpu_reg_reg ); 10500 %} 10501 10502 // Replicate scalar to packed single precision floating point values in xmm 10503 instruct Repl2F_reg(regD dst, regD src) %{ 10504 match(Set dst (Replicate2F src)); 10505 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 10506 ins_encode %{ 10507 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0); 10508 %} 10509 ins_pipe( fpu_reg_reg ); 10510 %} 10511 10512 // Replicate scalar to packed single precision floating point values in xmm 10513 instruct Repl2F_regF(regD dst, regF src) %{ 10514 match(Set dst (Replicate2F src)); 10515 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 10516 ins_encode %{ 10517 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0); 10518 %} 10519 ins_pipe( fpu_reg_reg ); 10520 %} 10521 10522 // Replicate scalar to packed single precision floating point values in xmm 10523 instruct Repl2F_immF0(regD dst, immF0 zero) %{ 10524 match(Set dst (Replicate2F zero)); 10525 format %{ "PXOR $dst,$dst\t! replicate2F" %} 10526 ins_encode %{ 10527 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10528 %} 10529 ins_pipe( fpu_reg_reg ); 10530 %} 10531 10532 10533 // ======================================================================= 10534 // fast clearing of an array 10535 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10536 rFlagsReg cr) 10537 %{ 10538 match(Set dummy (ClearArray cnt base)); 10539 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10540 10541 format %{ "xorl rax, rax\t# ClearArray:\n\t" 10542 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 10543 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax 10544 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos 10545 ins_pipe(pipe_slow); 10546 %} 10547 10548 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10549 rax_RegI result, regD tmp1, rFlagsReg cr) 10550 %{ 10551 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10552 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10553 10554 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10555 ins_encode %{ 10556 __ string_compare($str1$$Register, $str2$$Register, 10557 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10558 $tmp1$$XMMRegister); 10559 %} 10560 ins_pipe( pipe_slow ); 10561 %} 10562 10563 // fast search of substring with known size. 10564 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10565 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10566 %{ 10567 predicate(UseSSE42Intrinsics); 10568 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10569 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10570 10571 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10572 ins_encode %{ 10573 int icnt2 = (int)$int_cnt2$$constant; 10574 if (icnt2 >= 8) { 10575 // IndexOf for constant substrings with size >= 8 elements 10576 // which don't need to be loaded through stack. 10577 __ string_indexofC8($str1$$Register, $str2$$Register, 10578 $cnt1$$Register, $cnt2$$Register, 10579 icnt2, $result$$Register, 10580 $vec$$XMMRegister, $tmp$$Register); 10581 } else { 10582 // Small strings are loaded through stack if they cross page boundary. 10583 __ string_indexof($str1$$Register, $str2$$Register, 10584 $cnt1$$Register, $cnt2$$Register, 10585 icnt2, $result$$Register, 10586 $vec$$XMMRegister, $tmp$$Register); 10587 } 10588 %} 10589 ins_pipe( pipe_slow ); 10590 %} 10591 10592 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10593 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10594 %{ 10595 predicate(UseSSE42Intrinsics); 10596 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10597 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10598 10599 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10600 ins_encode %{ 10601 __ string_indexof($str1$$Register, $str2$$Register, 10602 $cnt1$$Register, $cnt2$$Register, 10603 (-1), $result$$Register, 10604 $vec$$XMMRegister, $tmp$$Register); 10605 %} 10606 ins_pipe( pipe_slow ); 10607 %} 10608 10609 // fast string equals 10610 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10611 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10612 %{ 10613 match(Set result (StrEquals (Binary str1 str2) cnt)); 10614 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10615 10616 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10617 ins_encode %{ 10618 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 10619 $cnt$$Register, $result$$Register, $tmp3$$Register, 10620 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10621 %} 10622 ins_pipe( pipe_slow ); 10623 %} 10624 10625 // fast array equals 10626 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10627 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10628 %{ 10629 match(Set result (AryEq ary1 ary2)); 10630 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10631 //ins_cost(300); 10632 10633 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10634 ins_encode %{ 10635 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 10636 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10637 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10638 %} 10639 ins_pipe( pipe_slow ); 10640 %} 10641 10642 //----------Control Flow Instructions------------------------------------------ 10643 // Signed compare Instructions 10644 10645 // XXX more variants!! 10646 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10647 %{ 10648 match(Set cr (CmpI op1 op2)); 10649 effect(DEF cr, USE op1, USE op2); 10650 10651 format %{ "cmpl $op1, $op2" %} 10652 opcode(0x3B); /* Opcode 3B /r */ 10653 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10654 ins_pipe(ialu_cr_reg_reg); 10655 %} 10656 10657 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10658 %{ 10659 match(Set cr (CmpI op1 op2)); 10660 10661 format %{ "cmpl $op1, $op2" %} 10662 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10663 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10664 ins_pipe(ialu_cr_reg_imm); 10665 %} 10666 10667 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 10668 %{ 10669 match(Set cr (CmpI op1 (LoadI op2))); 10670 10671 ins_cost(500); // XXX 10672 format %{ "cmpl $op1, $op2" %} 10673 opcode(0x3B); /* Opcode 3B /r */ 10674 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10675 ins_pipe(ialu_cr_reg_mem); 10676 %} 10677 10678 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 10679 %{ 10680 match(Set cr (CmpI src zero)); 10681 10682 format %{ "testl $src, $src" %} 10683 opcode(0x85); 10684 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10685 ins_pipe(ialu_cr_reg_imm); 10686 %} 10687 10688 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 10689 %{ 10690 match(Set cr (CmpI (AndI src con) zero)); 10691 10692 format %{ "testl $src, $con" %} 10693 opcode(0xF7, 0x00); 10694 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 10695 ins_pipe(ialu_cr_reg_imm); 10696 %} 10697 10698 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 10699 %{ 10700 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 10701 10702 format %{ "testl $src, $mem" %} 10703 opcode(0x85); 10704 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 10705 ins_pipe(ialu_cr_reg_mem); 10706 %} 10707 10708 // Unsigned compare Instructions; really, same as signed except they 10709 // produce an rFlagsRegU instead of rFlagsReg. 10710 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 10711 %{ 10712 match(Set cr (CmpU op1 op2)); 10713 10714 format %{ "cmpl $op1, $op2\t# unsigned" %} 10715 opcode(0x3B); /* Opcode 3B /r */ 10716 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10717 ins_pipe(ialu_cr_reg_reg); 10718 %} 10719 10720 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 10721 %{ 10722 match(Set cr (CmpU op1 op2)); 10723 10724 format %{ "cmpl $op1, $op2\t# unsigned" %} 10725 opcode(0x81,0x07); /* Opcode 81 /7 */ 10726 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10727 ins_pipe(ialu_cr_reg_imm); 10728 %} 10729 10730 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 10731 %{ 10732 match(Set cr (CmpU op1 (LoadI op2))); 10733 10734 ins_cost(500); // XXX 10735 format %{ "cmpl $op1, $op2\t# unsigned" %} 10736 opcode(0x3B); /* Opcode 3B /r */ 10737 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10738 ins_pipe(ialu_cr_reg_mem); 10739 %} 10740 10741 // // // Cisc-spilled version of cmpU_rReg 10742 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 10743 // //%{ 10744 // // match(Set cr (CmpU (LoadI op1) op2)); 10745 // // 10746 // // format %{ "CMPu $op1,$op2" %} 10747 // // ins_cost(500); 10748 // // opcode(0x39); /* Opcode 39 /r */ 10749 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10750 // //%} 10751 10752 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 10753 %{ 10754 match(Set cr (CmpU src zero)); 10755 10756 format %{ "testl $src, $src\t# unsigned" %} 10757 opcode(0x85); 10758 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10759 ins_pipe(ialu_cr_reg_imm); 10760 %} 10761 10762 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 10763 %{ 10764 match(Set cr (CmpP op1 op2)); 10765 10766 format %{ "cmpq $op1, $op2\t# ptr" %} 10767 opcode(0x3B); /* Opcode 3B /r */ 10768 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10769 ins_pipe(ialu_cr_reg_reg); 10770 %} 10771 10772 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 10773 %{ 10774 match(Set cr (CmpP op1 (LoadP op2))); 10775 10776 ins_cost(500); // XXX 10777 format %{ "cmpq $op1, $op2\t# ptr" %} 10778 opcode(0x3B); /* Opcode 3B /r */ 10779 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10780 ins_pipe(ialu_cr_reg_mem); 10781 %} 10782 10783 // // // Cisc-spilled version of cmpP_rReg 10784 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 10785 // //%{ 10786 // // match(Set cr (CmpP (LoadP op1) op2)); 10787 // // 10788 // // format %{ "CMPu $op1,$op2" %} 10789 // // ins_cost(500); 10790 // // opcode(0x39); /* Opcode 39 /r */ 10791 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10792 // //%} 10793 10794 // XXX this is generalized by compP_rReg_mem??? 10795 // Compare raw pointer (used in out-of-heap check). 10796 // Only works because non-oop pointers must be raw pointers 10797 // and raw pointers have no anti-dependencies. 10798 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 10799 %{ 10800 predicate(!n->in(2)->in(2)->bottom_type()->isa_oop_ptr()); 10801 match(Set cr (CmpP op1 (LoadP op2))); 10802 10803 format %{ "cmpq $op1, $op2\t# raw ptr" %} 10804 opcode(0x3B); /* Opcode 3B /r */ 10805 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10806 ins_pipe(ialu_cr_reg_mem); 10807 %} 10808 10809 // This will generate a signed flags result. This should be OK since 10810 // any compare to a zero should be eq/neq. 10811 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 10812 %{ 10813 match(Set cr (CmpP src zero)); 10814 10815 format %{ "testq $src, $src\t# ptr" %} 10816 opcode(0x85); 10817 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10818 ins_pipe(ialu_cr_reg_imm); 10819 %} 10820 10821 // This will generate a signed flags result. This should be OK since 10822 // any compare to a zero should be eq/neq. 10823 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 10824 %{ 10825 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 10826 match(Set cr (CmpP (LoadP op) zero)); 10827 10828 ins_cost(500); // XXX 10829 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 10830 opcode(0xF7); /* Opcode F7 /0 */ 10831 ins_encode(REX_mem_wide(op), 10832 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 10833 ins_pipe(ialu_cr_reg_imm); 10834 %} 10835 10836 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 10837 %{ 10838 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 10839 match(Set cr (CmpP (LoadP mem) zero)); 10840 10841 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 10842 ins_encode %{ 10843 __ cmpq(r12, $mem$$Address); 10844 %} 10845 ins_pipe(ialu_cr_reg_mem); 10846 %} 10847 10848 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 10849 %{ 10850 match(Set cr (CmpN op1 op2)); 10851 10852 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10853 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 10854 ins_pipe(ialu_cr_reg_reg); 10855 %} 10856 10857 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 10858 %{ 10859 match(Set cr (CmpN src (LoadN mem))); 10860 10861 format %{ "cmpl $src, $mem\t# compressed ptr" %} 10862 ins_encode %{ 10863 __ cmpl($src$$Register, $mem$$Address); 10864 %} 10865 ins_pipe(ialu_cr_reg_mem); 10866 %} 10867 10868 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 10869 match(Set cr (CmpN op1 op2)); 10870 10871 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10872 ins_encode %{ 10873 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 10874 %} 10875 ins_pipe(ialu_cr_reg_imm); 10876 %} 10877 10878 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 10879 %{ 10880 match(Set cr (CmpN src (LoadN mem))); 10881 10882 format %{ "cmpl $mem, $src\t# compressed ptr" %} 10883 ins_encode %{ 10884 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 10885 %} 10886 ins_pipe(ialu_cr_reg_mem); 10887 %} 10888 10889 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 10890 match(Set cr (CmpN src zero)); 10891 10892 format %{ "testl $src, $src\t# compressed ptr" %} 10893 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 10894 ins_pipe(ialu_cr_reg_imm); 10895 %} 10896 10897 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 10898 %{ 10899 predicate(Universe::narrow_oop_base() != NULL); 10900 match(Set cr (CmpN (LoadN mem) zero)); 10901 10902 ins_cost(500); // XXX 10903 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 10904 ins_encode %{ 10905 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 10906 %} 10907 ins_pipe(ialu_cr_reg_mem); 10908 %} 10909 10910 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 10911 %{ 10912 predicate(Universe::narrow_oop_base() == NULL); 10913 match(Set cr (CmpN (LoadN mem) zero)); 10914 10915 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 10916 ins_encode %{ 10917 __ cmpl(r12, $mem$$Address); 10918 %} 10919 ins_pipe(ialu_cr_reg_mem); 10920 %} 10921 10922 // Yanked all unsigned pointer compare operations. 10923 // Pointer compares are done with CmpP which is already unsigned. 10924 10925 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10926 %{ 10927 match(Set cr (CmpL op1 op2)); 10928 10929 format %{ "cmpq $op1, $op2" %} 10930 opcode(0x3B); /* Opcode 3B /r */ 10931 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10932 ins_pipe(ialu_cr_reg_reg); 10933 %} 10934 10935 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10936 %{ 10937 match(Set cr (CmpL op1 op2)); 10938 10939 format %{ "cmpq $op1, $op2" %} 10940 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10941 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 10942 ins_pipe(ialu_cr_reg_imm); 10943 %} 10944 10945 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 10946 %{ 10947 match(Set cr (CmpL op1 (LoadL op2))); 10948 10949 format %{ "cmpq $op1, $op2" %} 10950 opcode(0x3B); /* Opcode 3B /r */ 10951 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10952 ins_pipe(ialu_cr_reg_mem); 10953 %} 10954 10955 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 10956 %{ 10957 match(Set cr (CmpL src zero)); 10958 10959 format %{ "testq $src, $src" %} 10960 opcode(0x85); 10961 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10962 ins_pipe(ialu_cr_reg_imm); 10963 %} 10964 10965 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 10966 %{ 10967 match(Set cr (CmpL (AndL src con) zero)); 10968 10969 format %{ "testq $src, $con\t# long" %} 10970 opcode(0xF7, 0x00); 10971 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 10972 ins_pipe(ialu_cr_reg_imm); 10973 %} 10974 10975 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 10976 %{ 10977 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 10978 10979 format %{ "testq $src, $mem" %} 10980 opcode(0x85); 10981 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 10982 ins_pipe(ialu_cr_reg_mem); 10983 %} 10984 10985 // Manifest a CmpL result in an integer register. Very painful. 10986 // This is the test to avoid. 10987 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 10988 %{ 10989 match(Set dst (CmpL3 src1 src2)); 10990 effect(KILL flags); 10991 10992 ins_cost(275); // XXX 10993 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 10994 "movl $dst, -1\n\t" 10995 "jl,s done\n\t" 10996 "setne $dst\n\t" 10997 "movzbl $dst, $dst\n\t" 10998 "done:" %} 10999 ins_encode(cmpl3_flag(src1, src2, dst)); 11000 ins_pipe(pipe_slow); 11001 %} 11002 11003 //----------Max and Min-------------------------------------------------------- 11004 // Min Instructions 11005 11006 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11007 %{ 11008 effect(USE_DEF dst, USE src, USE cr); 11009 11010 format %{ "cmovlgt $dst, $src\t# min" %} 11011 opcode(0x0F, 0x4F); 11012 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11013 ins_pipe(pipe_cmov_reg); 11014 %} 11015 11016 11017 instruct minI_rReg(rRegI dst, rRegI src) 11018 %{ 11019 match(Set dst (MinI dst src)); 11020 11021 ins_cost(200); 11022 expand %{ 11023 rFlagsReg cr; 11024 compI_rReg(cr, dst, src); 11025 cmovI_reg_g(dst, src, cr); 11026 %} 11027 %} 11028 11029 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11030 %{ 11031 effect(USE_DEF dst, USE src, USE cr); 11032 11033 format %{ "cmovllt $dst, $src\t# max" %} 11034 opcode(0x0F, 0x4C); 11035 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11036 ins_pipe(pipe_cmov_reg); 11037 %} 11038 11039 11040 instruct maxI_rReg(rRegI dst, rRegI src) 11041 %{ 11042 match(Set dst (MaxI dst src)); 11043 11044 ins_cost(200); 11045 expand %{ 11046 rFlagsReg cr; 11047 compI_rReg(cr, dst, src); 11048 cmovI_reg_l(dst, src, cr); 11049 %} 11050 %} 11051 11052 // ============================================================================ 11053 // Branch Instructions 11054 11055 // Jump Direct - Label defines a relative address from JMP+1 11056 instruct jmpDir(label labl) 11057 %{ 11058 match(Goto); 11059 effect(USE labl); 11060 11061 ins_cost(300); 11062 format %{ "jmp $labl" %} 11063 size(5); 11064 ins_encode %{ 11065 Label* L = $labl$$label; 11066 __ jmp(*L, false); // Always long jump 11067 %} 11068 ins_pipe(pipe_jmp); 11069 %} 11070 11071 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11072 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11073 %{ 11074 match(If cop cr); 11075 effect(USE labl); 11076 11077 ins_cost(300); 11078 format %{ "j$cop $labl" %} 11079 size(6); 11080 ins_encode %{ 11081 Label* L = $labl$$label; 11082 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11083 %} 11084 ins_pipe(pipe_jcc); 11085 %} 11086 11087 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11088 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11089 %{ 11090 match(CountedLoopEnd cop cr); 11091 effect(USE labl); 11092 11093 ins_cost(300); 11094 format %{ "j$cop $labl\t# loop end" %} 11095 size(6); 11096 ins_encode %{ 11097 Label* L = $labl$$label; 11098 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11099 %} 11100 ins_pipe(pipe_jcc); 11101 %} 11102 11103 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11104 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11105 match(CountedLoopEnd cop cmp); 11106 effect(USE labl); 11107 11108 ins_cost(300); 11109 format %{ "j$cop,u $labl\t# loop end" %} 11110 size(6); 11111 ins_encode %{ 11112 Label* L = $labl$$label; 11113 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11114 %} 11115 ins_pipe(pipe_jcc); 11116 %} 11117 11118 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11119 match(CountedLoopEnd cop cmp); 11120 effect(USE labl); 11121 11122 ins_cost(200); 11123 format %{ "j$cop,u $labl\t# loop end" %} 11124 size(6); 11125 ins_encode %{ 11126 Label* L = $labl$$label; 11127 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11128 %} 11129 ins_pipe(pipe_jcc); 11130 %} 11131 11132 // Jump Direct Conditional - using unsigned comparison 11133 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11134 match(If cop cmp); 11135 effect(USE labl); 11136 11137 ins_cost(300); 11138 format %{ "j$cop,u $labl" %} 11139 size(6); 11140 ins_encode %{ 11141 Label* L = $labl$$label; 11142 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11143 %} 11144 ins_pipe(pipe_jcc); 11145 %} 11146 11147 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11148 match(If cop cmp); 11149 effect(USE labl); 11150 11151 ins_cost(200); 11152 format %{ "j$cop,u $labl" %} 11153 size(6); 11154 ins_encode %{ 11155 Label* L = $labl$$label; 11156 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11157 %} 11158 ins_pipe(pipe_jcc); 11159 %} 11160 11161 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11162 match(If cop cmp); 11163 effect(USE labl); 11164 11165 ins_cost(200); 11166 format %{ $$template 11167 if ($cop$$cmpcode == Assembler::notEqual) { 11168 $$emit$$"jp,u $labl\n\t" 11169 $$emit$$"j$cop,u $labl" 11170 } else { 11171 $$emit$$"jp,u done\n\t" 11172 $$emit$$"j$cop,u $labl\n\t" 11173 $$emit$$"done:" 11174 } 11175 %} 11176 ins_encode %{ 11177 Label* l = $labl$$label; 11178 if ($cop$$cmpcode == Assembler::notEqual) { 11179 __ jcc(Assembler::parity, *l, false); 11180 __ jcc(Assembler::notEqual, *l, false); 11181 } else if ($cop$$cmpcode == Assembler::equal) { 11182 Label done; 11183 __ jccb(Assembler::parity, done); 11184 __ jcc(Assembler::equal, *l, false); 11185 __ bind(done); 11186 } else { 11187 ShouldNotReachHere(); 11188 } 11189 %} 11190 ins_pipe(pipe_jcc); 11191 %} 11192 11193 // ============================================================================ 11194 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11195 // superklass array for an instance of the superklass. Set a hidden 11196 // internal cache on a hit (cache is checked with exposed code in 11197 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11198 // encoding ALSO sets flags. 11199 11200 instruct partialSubtypeCheck(rdi_RegP result, 11201 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11202 rFlagsReg cr) 11203 %{ 11204 match(Set result (PartialSubtypeCheck sub super)); 11205 effect(KILL rcx, KILL cr); 11206 11207 ins_cost(1100); // slightly larger than the next version 11208 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11209 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 11210 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 11211 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11212 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11213 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11214 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11215 "miss:\t" %} 11216 11217 opcode(0x1); // Force a XOR of RDI 11218 ins_encode(enc_PartialSubtypeCheck()); 11219 ins_pipe(pipe_slow); 11220 %} 11221 11222 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11223 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11224 immP0 zero, 11225 rdi_RegP result) 11226 %{ 11227 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11228 effect(KILL rcx, KILL result); 11229 11230 ins_cost(1000); 11231 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11232 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 11233 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 11234 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11235 "jne,s miss\t\t# Missed: flags nz\n\t" 11236 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11237 "miss:\t" %} 11238 11239 opcode(0x0); // No need to XOR RDI 11240 ins_encode(enc_PartialSubtypeCheck()); 11241 ins_pipe(pipe_slow); 11242 %} 11243 11244 // ============================================================================ 11245 // Branch Instructions -- short offset versions 11246 // 11247 // These instructions are used to replace jumps of a long offset (the default 11248 // match) with jumps of a shorter offset. These instructions are all tagged 11249 // with the ins_short_branch attribute, which causes the ADLC to suppress the 11250 // match rules in general matching. Instead, the ADLC generates a conversion 11251 // method in the MachNode which can be used to do in-place replacement of the 11252 // long variant with the shorter variant. The compiler will determine if a 11253 // branch can be taken by the is_short_branch_offset() predicate in the machine 11254 // specific code section of the file. 11255 11256 // Jump Direct - Label defines a relative address from JMP+1 11257 instruct jmpDir_short(label labl) %{ 11258 match(Goto); 11259 effect(USE labl); 11260 11261 ins_cost(300); 11262 format %{ "jmp,s $labl" %} 11263 size(2); 11264 ins_encode %{ 11265 Label* L = $labl$$label; 11266 __ jmpb(*L); 11267 %} 11268 ins_pipe(pipe_jmp); 11269 ins_short_branch(1); 11270 %} 11271 11272 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11273 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11274 match(If cop cr); 11275 effect(USE labl); 11276 11277 ins_cost(300); 11278 format %{ "j$cop,s $labl" %} 11279 size(2); 11280 ins_encode %{ 11281 Label* L = $labl$$label; 11282 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11283 %} 11284 ins_pipe(pipe_jcc); 11285 ins_short_branch(1); 11286 %} 11287 11288 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11289 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11290 match(CountedLoopEnd cop cr); 11291 effect(USE labl); 11292 11293 ins_cost(300); 11294 format %{ "j$cop,s $labl\t# loop end" %} 11295 size(2); 11296 ins_encode %{ 11297 Label* L = $labl$$label; 11298 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11299 %} 11300 ins_pipe(pipe_jcc); 11301 ins_short_branch(1); 11302 %} 11303 11304 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11305 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11306 match(CountedLoopEnd cop cmp); 11307 effect(USE labl); 11308 11309 ins_cost(300); 11310 format %{ "j$cop,us $labl\t# loop end" %} 11311 size(2); 11312 ins_encode %{ 11313 Label* L = $labl$$label; 11314 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11315 %} 11316 ins_pipe(pipe_jcc); 11317 ins_short_branch(1); 11318 %} 11319 11320 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11321 match(CountedLoopEnd cop cmp); 11322 effect(USE labl); 11323 11324 ins_cost(300); 11325 format %{ "j$cop,us $labl\t# loop end" %} 11326 size(2); 11327 ins_encode %{ 11328 Label* L = $labl$$label; 11329 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11330 %} 11331 ins_pipe(pipe_jcc); 11332 ins_short_branch(1); 11333 %} 11334 11335 // Jump Direct Conditional - using unsigned comparison 11336 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11337 match(If cop cmp); 11338 effect(USE labl); 11339 11340 ins_cost(300); 11341 format %{ "j$cop,us $labl" %} 11342 size(2); 11343 ins_encode %{ 11344 Label* L = $labl$$label; 11345 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11346 %} 11347 ins_pipe(pipe_jcc); 11348 ins_short_branch(1); 11349 %} 11350 11351 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11352 match(If cop cmp); 11353 effect(USE labl); 11354 11355 ins_cost(300); 11356 format %{ "j$cop,us $labl" %} 11357 size(2); 11358 ins_encode %{ 11359 Label* L = $labl$$label; 11360 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11361 %} 11362 ins_pipe(pipe_jcc); 11363 ins_short_branch(1); 11364 %} 11365 11366 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11367 match(If cop cmp); 11368 effect(USE labl); 11369 11370 ins_cost(300); 11371 format %{ $$template 11372 if ($cop$$cmpcode == Assembler::notEqual) { 11373 $$emit$$"jp,u,s $labl\n\t" 11374 $$emit$$"j$cop,u,s $labl" 11375 } else { 11376 $$emit$$"jp,u,s done\n\t" 11377 $$emit$$"j$cop,u,s $labl\n\t" 11378 $$emit$$"done:" 11379 } 11380 %} 11381 size(4); 11382 ins_encode %{ 11383 Label* l = $labl$$label; 11384 if ($cop$$cmpcode == Assembler::notEqual) { 11385 __ jccb(Assembler::parity, *l); 11386 __ jccb(Assembler::notEqual, *l); 11387 } else if ($cop$$cmpcode == Assembler::equal) { 11388 Label done; 11389 __ jccb(Assembler::parity, done); 11390 __ jccb(Assembler::equal, *l); 11391 __ bind(done); 11392 } else { 11393 ShouldNotReachHere(); 11394 } 11395 %} 11396 ins_pipe(pipe_jcc); 11397 ins_short_branch(1); 11398 %} 11399 11400 // ============================================================================ 11401 // inlined locking and unlocking 11402 11403 instruct cmpFastLock(rFlagsReg cr, 11404 rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) 11405 %{ 11406 match(Set cr (FastLock object box)); 11407 effect(TEMP tmp, TEMP scr, USE_KILL box); 11408 11409 ins_cost(300); 11410 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 11411 ins_encode(Fast_Lock(object, box, tmp, scr)); 11412 ins_pipe(pipe_slow); 11413 %} 11414 11415 instruct cmpFastUnlock(rFlagsReg cr, 11416 rRegP object, rax_RegP box, rRegP tmp) 11417 %{ 11418 match(Set cr (FastUnlock object box)); 11419 effect(TEMP tmp, USE_KILL box); 11420 11421 ins_cost(300); 11422 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 11423 ins_encode(Fast_Unlock(object, box, tmp)); 11424 ins_pipe(pipe_slow); 11425 %} 11426 11427 11428 // ============================================================================ 11429 // Safepoint Instructions 11430 instruct safePoint_poll(rFlagsReg cr) 11431 %{ 11432 predicate(!Assembler::is_polling_page_far()); 11433 match(SafePoint); 11434 effect(KILL cr); 11435 11436 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 11437 "# Safepoint: poll for GC" %} 11438 ins_cost(125); 11439 ins_encode %{ 11440 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 11441 __ testl(rax, addr); 11442 %} 11443 ins_pipe(ialu_reg_mem); 11444 %} 11445 11446 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 11447 %{ 11448 predicate(Assembler::is_polling_page_far()); 11449 match(SafePoint poll); 11450 effect(KILL cr, USE poll); 11451 11452 format %{ "testl rax, [$poll]\t" 11453 "# Safepoint: poll for GC" %} 11454 ins_cost(125); 11455 ins_encode %{ 11456 __ relocate(relocInfo::poll_type); 11457 __ testl(rax, Address($poll$$Register, 0)); 11458 %} 11459 ins_pipe(ialu_reg_mem); 11460 %} 11461 11462 // ============================================================================ 11463 // Procedure Call/Return Instructions 11464 // Call Java Static Instruction 11465 // Note: If this code changes, the corresponding ret_addr_offset() and 11466 // compute_padding() functions will have to be adjusted. 11467 instruct CallStaticJavaDirect(method meth) %{ 11468 match(CallStaticJava); 11469 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11470 effect(USE meth); 11471 11472 ins_cost(300); 11473 format %{ "call,static " %} 11474 opcode(0xE8); /* E8 cd */ 11475 ins_encode(Java_Static_Call(meth), call_epilog); 11476 ins_pipe(pipe_slow); 11477 ins_alignment(4); 11478 %} 11479 11480 // Call Java Static Instruction (method handle version) 11481 // Note: If this code changes, the corresponding ret_addr_offset() and 11482 // compute_padding() functions will have to be adjusted. 11483 instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{ 11484 match(CallStaticJava); 11485 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11486 effect(USE meth); 11487 // RBP is saved by all callees (for interpreter stack correction). 11488 // We use it here for a similar purpose, in {preserve,restore}_SP. 11489 11490 ins_cost(300); 11491 format %{ "call,static/MethodHandle " %} 11492 opcode(0xE8); /* E8 cd */ 11493 ins_encode(preserve_SP, 11494 Java_Static_Call(meth), 11495 restore_SP, 11496 call_epilog); 11497 ins_pipe(pipe_slow); 11498 ins_alignment(4); 11499 %} 11500 11501 // Call Java Dynamic Instruction 11502 // Note: If this code changes, the corresponding ret_addr_offset() and 11503 // compute_padding() functions will have to be adjusted. 11504 instruct CallDynamicJavaDirect(method meth) 11505 %{ 11506 match(CallDynamicJava); 11507 effect(USE meth); 11508 11509 ins_cost(300); 11510 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11511 "call,dynamic " %} 11512 opcode(0xE8); /* E8 cd */ 11513 ins_encode(Java_Dynamic_Call(meth), call_epilog); 11514 ins_pipe(pipe_slow); 11515 ins_alignment(4); 11516 %} 11517 11518 // Call Runtime Instruction 11519 instruct CallRuntimeDirect(method meth) 11520 %{ 11521 match(CallRuntime); 11522 effect(USE meth); 11523 11524 ins_cost(300); 11525 format %{ "call,runtime " %} 11526 opcode(0xE8); /* E8 cd */ 11527 ins_encode(Java_To_Runtime(meth)); 11528 ins_pipe(pipe_slow); 11529 %} 11530 11531 // Call runtime without safepoint 11532 instruct CallLeafDirect(method meth) 11533 %{ 11534 match(CallLeaf); 11535 effect(USE meth); 11536 11537 ins_cost(300); 11538 format %{ "call_leaf,runtime " %} 11539 opcode(0xE8); /* E8 cd */ 11540 ins_encode(Java_To_Runtime(meth)); 11541 ins_pipe(pipe_slow); 11542 %} 11543 11544 // Call runtime without safepoint 11545 instruct CallLeafNoFPDirect(method meth) 11546 %{ 11547 match(CallLeafNoFP); 11548 effect(USE meth); 11549 11550 ins_cost(300); 11551 format %{ "call_leaf_nofp,runtime " %} 11552 opcode(0xE8); /* E8 cd */ 11553 ins_encode(Java_To_Runtime(meth)); 11554 ins_pipe(pipe_slow); 11555 %} 11556 11557 // Return Instruction 11558 // Remove the return address & jump to it. 11559 // Notice: We always emit a nop after a ret to make sure there is room 11560 // for safepoint patching 11561 instruct Ret() 11562 %{ 11563 match(Return); 11564 11565 format %{ "ret" %} 11566 opcode(0xC3); 11567 ins_encode(OpcP); 11568 ins_pipe(pipe_jmp); 11569 %} 11570 11571 // Tail Call; Jump from runtime stub to Java code. 11572 // Also known as an 'interprocedural jump'. 11573 // Target of jump will eventually return to caller. 11574 // TailJump below removes the return address. 11575 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 11576 %{ 11577 match(TailCall jump_target method_oop); 11578 11579 ins_cost(300); 11580 format %{ "jmp $jump_target\t# rbx holds method oop" %} 11581 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11582 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11583 ins_pipe(pipe_jmp); 11584 %} 11585 11586 // Tail Jump; remove the return address; jump to target. 11587 // TailCall above leaves the return address around. 11588 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 11589 %{ 11590 match(TailJump jump_target ex_oop); 11591 11592 ins_cost(300); 11593 format %{ "popq rdx\t# pop return address\n\t" 11594 "jmp $jump_target" %} 11595 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11596 ins_encode(Opcode(0x5a), // popq rdx 11597 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11598 ins_pipe(pipe_jmp); 11599 %} 11600 11601 // Create exception oop: created by stack-crawling runtime code. 11602 // Created exception is now available to this handler, and is setup 11603 // just prior to jumping to this handler. No code emitted. 11604 instruct CreateException(rax_RegP ex_oop) 11605 %{ 11606 match(Set ex_oop (CreateEx)); 11607 11608 size(0); 11609 // use the following format syntax 11610 format %{ "# exception oop is in rax; no code emitted" %} 11611 ins_encode(); 11612 ins_pipe(empty); 11613 %} 11614 11615 // Rethrow exception: 11616 // The exception oop will come in the first argument position. 11617 // Then JUMP (not call) to the rethrow stub code. 11618 instruct RethrowException() 11619 %{ 11620 match(Rethrow); 11621 11622 // use the following format syntax 11623 format %{ "jmp rethrow_stub" %} 11624 ins_encode(enc_rethrow); 11625 ins_pipe(pipe_jmp); 11626 %} 11627 11628 11629 // ============================================================================ 11630 // This name is KNOWN by the ADLC and cannot be changed. 11631 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 11632 // for this guy. 11633 instruct tlsLoadP(r15_RegP dst) %{ 11634 match(Set dst (ThreadLocal)); 11635 effect(DEF dst); 11636 11637 size(0); 11638 format %{ "# TLS is in R15" %} 11639 ins_encode( /*empty encoding*/ ); 11640 ins_pipe(ialu_reg_reg); 11641 %} 11642 11643 11644 //----------PEEPHOLE RULES----------------------------------------------------- 11645 // These must follow all instruction definitions as they use the names 11646 // defined in the instructions definitions. 11647 // 11648 // peepmatch ( root_instr_name [preceding_instruction]* ); 11649 // 11650 // peepconstraint %{ 11651 // (instruction_number.operand_name relational_op instruction_number.operand_name 11652 // [, ...] ); 11653 // // instruction numbers are zero-based using left to right order in peepmatch 11654 // 11655 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 11656 // // provide an instruction_number.operand_name for each operand that appears 11657 // // in the replacement instruction's match rule 11658 // 11659 // ---------VM FLAGS--------------------------------------------------------- 11660 // 11661 // All peephole optimizations can be turned off using -XX:-OptoPeephole 11662 // 11663 // Each peephole rule is given an identifying number starting with zero and 11664 // increasing by one in the order seen by the parser. An individual peephole 11665 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 11666 // on the command-line. 11667 // 11668 // ---------CURRENT LIMITATIONS---------------------------------------------- 11669 // 11670 // Only match adjacent instructions in same basic block 11671 // Only equality constraints 11672 // Only constraints between operands, not (0.dest_reg == RAX_enc) 11673 // Only one replacement instruction 11674 // 11675 // ---------EXAMPLE---------------------------------------------------------- 11676 // 11677 // // pertinent parts of existing instructions in architecture description 11678 // instruct movI(rRegI dst, rRegI src) 11679 // %{ 11680 // match(Set dst (CopyI src)); 11681 // %} 11682 // 11683 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 11684 // %{ 11685 // match(Set dst (AddI dst src)); 11686 // effect(KILL cr); 11687 // %} 11688 // 11689 // // Change (inc mov) to lea 11690 // peephole %{ 11691 // // increment preceeded by register-register move 11692 // peepmatch ( incI_rReg movI ); 11693 // // require that the destination register of the increment 11694 // // match the destination register of the move 11695 // peepconstraint ( 0.dst == 1.dst ); 11696 // // construct a replacement instruction that sets 11697 // // the destination to ( move's source register + one ) 11698 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 11699 // %} 11700 // 11701 11702 // Implementation no longer uses movX instructions since 11703 // machine-independent system no longer uses CopyX nodes. 11704 // 11705 // peephole 11706 // %{ 11707 // peepmatch (incI_rReg movI); 11708 // peepconstraint (0.dst == 1.dst); 11709 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11710 // %} 11711 11712 // peephole 11713 // %{ 11714 // peepmatch (decI_rReg movI); 11715 // peepconstraint (0.dst == 1.dst); 11716 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11717 // %} 11718 11719 // peephole 11720 // %{ 11721 // peepmatch (addI_rReg_imm movI); 11722 // peepconstraint (0.dst == 1.dst); 11723 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11724 // %} 11725 11726 // peephole 11727 // %{ 11728 // peepmatch (incL_rReg movL); 11729 // peepconstraint (0.dst == 1.dst); 11730 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11731 // %} 11732 11733 // peephole 11734 // %{ 11735 // peepmatch (decL_rReg movL); 11736 // peepconstraint (0.dst == 1.dst); 11737 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11738 // %} 11739 11740 // peephole 11741 // %{ 11742 // peepmatch (addL_rReg_imm movL); 11743 // peepconstraint (0.dst == 1.dst); 11744 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11745 // %} 11746 11747 // peephole 11748 // %{ 11749 // peepmatch (addP_rReg_imm movP); 11750 // peepconstraint (0.dst == 1.dst); 11751 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 11752 // %} 11753 11754 // // Change load of spilled value to only a spill 11755 // instruct storeI(memory mem, rRegI src) 11756 // %{ 11757 // match(Set mem (StoreI mem src)); 11758 // %} 11759 // 11760 // instruct loadI(rRegI dst, memory mem) 11761 // %{ 11762 // match(Set dst (LoadI mem)); 11763 // %} 11764 // 11765 11766 peephole 11767 %{ 11768 peepmatch (loadI storeI); 11769 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11770 peepreplace (storeI(1.mem 1.mem 1.src)); 11771 %} 11772 11773 peephole 11774 %{ 11775 peepmatch (loadL storeL); 11776 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11777 peepreplace (storeL(1.mem 1.mem 1.src)); 11778 %} 11779 11780 //----------SMARTSPILL RULES--------------------------------------------------- 11781 // These must follow all instruction definitions as they use the names 11782 // defined in the instructions definitions.