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