1 // 2 // Copyright (c) 2003, 2011, 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 LP64_ONLY(1 +) 2; // [rex,] 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 #ifndef PRODUCT 614 void MachBreakpointNode::format(PhaseRegAlloc*, outputStream* st) const 615 { 616 st->print("INT3"); 617 } 618 #endif 619 620 // EMIT_RM() 621 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 622 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 623 cbuf.insts()->emit_int8(c); 624 } 625 626 // EMIT_CC() 627 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 628 unsigned char c = (unsigned char) (f1 | f2); 629 cbuf.insts()->emit_int8(c); 630 } 631 632 // EMIT_OPCODE() 633 void emit_opcode(CodeBuffer &cbuf, int code) { 634 cbuf.insts()->emit_int8((unsigned char) code); 635 } 636 637 // EMIT_OPCODE() w/ relocation information 638 void emit_opcode(CodeBuffer &cbuf, 639 int code, relocInfo::relocType reloc, int offset, int format) 640 { 641 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 642 emit_opcode(cbuf, code); 643 } 644 645 // EMIT_D8() 646 void emit_d8(CodeBuffer &cbuf, int d8) { 647 cbuf.insts()->emit_int8((unsigned char) d8); 648 } 649 650 // EMIT_D16() 651 void emit_d16(CodeBuffer &cbuf, int d16) { 652 cbuf.insts()->emit_int16(d16); 653 } 654 655 // EMIT_D32() 656 void emit_d32(CodeBuffer &cbuf, int d32) { 657 cbuf.insts()->emit_int32(d32); 658 } 659 660 // EMIT_D64() 661 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 662 cbuf.insts()->emit_int64(d64); 663 } 664 665 // emit 32 bit value and construct relocation entry from relocInfo::relocType 666 void emit_d32_reloc(CodeBuffer& cbuf, 667 int d32, 668 relocInfo::relocType reloc, 669 int format) 670 { 671 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 672 cbuf.relocate(cbuf.insts_mark(), reloc, format); 673 cbuf.insts()->emit_int32(d32); 674 } 675 676 // emit 32 bit value and construct relocation entry from RelocationHolder 677 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 678 #ifdef ASSERT 679 if (rspec.reloc()->type() == relocInfo::oop_type && 680 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 681 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 682 } 683 #endif 684 cbuf.relocate(cbuf.insts_mark(), rspec, format); 685 cbuf.insts()->emit_int32(d32); 686 } 687 688 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 689 address next_ip = cbuf.insts_end() + 4; 690 emit_d32_reloc(cbuf, (int) (addr - next_ip), 691 external_word_Relocation::spec(addr), 692 RELOC_DISP32); 693 } 694 695 696 // emit 64 bit value and construct relocation entry from relocInfo::relocType 697 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 698 cbuf.relocate(cbuf.insts_mark(), reloc, format); 699 cbuf.insts()->emit_int64(d64); 700 } 701 702 // emit 64 bit value and construct relocation entry from RelocationHolder 703 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 704 #ifdef ASSERT 705 if (rspec.reloc()->type() == relocInfo::oop_type && 706 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 707 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()), 708 "cannot embed scavengable oops in code"); 709 } 710 #endif 711 cbuf.relocate(cbuf.insts_mark(), rspec, format); 712 cbuf.insts()->emit_int64(d64); 713 } 714 715 // Access stack slot for load or store 716 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 717 { 718 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 719 if (-0x80 <= disp && disp < 0x80) { 720 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 721 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 722 emit_d8(cbuf, disp); // Displacement // R/M byte 723 } else { 724 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 725 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 726 emit_d32(cbuf, disp); // Displacement // R/M byte 727 } 728 } 729 730 // rRegI ereg, memory mem) %{ // emit_reg_mem 731 void encode_RegMem(CodeBuffer &cbuf, 732 int reg, 733 int base, int index, int scale, int disp, bool disp_is_oop) 734 { 735 assert(!disp_is_oop, "cannot have disp"); 736 int regenc = reg & 7; 737 int baseenc = base & 7; 738 int indexenc = index & 7; 739 740 // There is no index & no scale, use form without SIB byte 741 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 742 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 743 if (disp == 0 && base != RBP_enc && base != R13_enc) { 744 emit_rm(cbuf, 0x0, regenc, baseenc); // * 745 } else if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { 746 // If 8-bit displacement, mode 0x1 747 emit_rm(cbuf, 0x1, regenc, baseenc); // * 748 emit_d8(cbuf, disp); 749 } else { 750 // If 32-bit displacement 751 if (base == -1) { // Special flag for absolute address 752 emit_rm(cbuf, 0x0, regenc, 0x5); // * 753 if (disp_is_oop) { 754 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 755 } else { 756 emit_d32(cbuf, disp); 757 } 758 } else { 759 // Normal base + offset 760 emit_rm(cbuf, 0x2, regenc, baseenc); // * 761 if (disp_is_oop) { 762 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 763 } else { 764 emit_d32(cbuf, disp); 765 } 766 } 767 } 768 } else { 769 // Else, encode with the SIB byte 770 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 771 if (disp == 0 && base != RBP_enc && base != R13_enc) { 772 // If no displacement 773 emit_rm(cbuf, 0x0, regenc, 0x4); // * 774 emit_rm(cbuf, scale, indexenc, baseenc); 775 } else { 776 if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { 777 // If 8-bit displacement, mode 0x1 778 emit_rm(cbuf, 0x1, regenc, 0x4); // * 779 emit_rm(cbuf, scale, indexenc, baseenc); 780 emit_d8(cbuf, disp); 781 } else { 782 // If 32-bit displacement 783 if (base == 0x04 ) { 784 emit_rm(cbuf, 0x2, regenc, 0x4); 785 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 786 } else { 787 emit_rm(cbuf, 0x2, regenc, 0x4); 788 emit_rm(cbuf, scale, indexenc, baseenc); // * 789 } 790 if (disp_is_oop) { 791 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 792 } else { 793 emit_d32(cbuf, disp); 794 } 795 } 796 } 797 } 798 } 799 800 void encode_copy(CodeBuffer &cbuf, int dstenc, int srcenc) 801 { 802 if (dstenc != srcenc) { 803 if (dstenc < 8) { 804 if (srcenc >= 8) { 805 emit_opcode(cbuf, Assembler::REX_B); 806 srcenc -= 8; 807 } 808 } else { 809 if (srcenc < 8) { 810 emit_opcode(cbuf, Assembler::REX_R); 811 } else { 812 emit_opcode(cbuf, Assembler::REX_RB); 813 srcenc -= 8; 814 } 815 dstenc -= 8; 816 } 817 818 emit_opcode(cbuf, 0x8B); 819 emit_rm(cbuf, 0x3, dstenc, srcenc); 820 } 821 } 822 823 void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) { 824 if( dst_encoding == src_encoding ) { 825 // reg-reg copy, use an empty encoding 826 } else { 827 MacroAssembler _masm(&cbuf); 828 829 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding)); 830 } 831 } 832 833 // This could be in MacroAssembler but it's fairly C2 specific 834 void emit_cmpfp_fixup(MacroAssembler& _masm) { 835 Label exit; 836 __ jccb(Assembler::noParity, exit); 837 __ pushf(); 838 __ andq(Address(rsp, 0), 0xffffff2b); 839 __ popf(); 840 __ bind(exit); 841 __ nop(); // (target for branch to avoid branch to branch) 842 } 843 844 845 //============================================================================= 846 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 847 848 int Compile::ConstantTable::calculate_table_base_offset() const { 849 return 0; // absolute addressing, no offset 850 } 851 852 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 853 // Empty encoding 854 } 855 856 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 857 return 0; 858 } 859 860 #ifndef PRODUCT 861 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 862 st->print("# MachConstantBaseNode (empty encoding)"); 863 } 864 #endif 865 866 867 //============================================================================= 868 #ifndef PRODUCT 869 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const 870 { 871 Compile* C = ra_->C; 872 873 int framesize = C->frame_slots() << LogBytesPerInt; 874 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 875 // Remove wordSize for return adr already pushed 876 // and another for the RBP we are going to save 877 framesize -= 2*wordSize; 878 bool need_nop = true; 879 880 // Calls to C2R adapters often do not accept exceptional returns. 881 // We require that their callers must bang for them. But be 882 // careful, because some VM calls (such as call site linkage) can 883 // use several kilobytes of stack. But the stack safety zone should 884 // account for that. See bugs 4446381, 4468289, 4497237. 885 if (C->need_stack_bang(framesize)) { 886 st->print_cr("# stack bang"); st->print("\t"); 887 need_nop = false; 888 } 889 st->print_cr("pushq rbp"); st->print("\t"); 890 891 if (VerifyStackAtCalls) { 892 // Majik cookie to verify stack depth 893 st->print_cr("pushq 0xffffffffbadb100d" 894 "\t# Majik cookie for stack depth check"); 895 st->print("\t"); 896 framesize -= wordSize; // Remove 2 for cookie 897 need_nop = false; 898 } 899 900 if (framesize) { 901 st->print("subq rsp, #%d\t# Create frame", framesize); 902 if (framesize < 0x80 && need_nop) { 903 st->print("\n\tnop\t# nop for patch_verified_entry"); 904 } 905 } 906 } 907 #endif 908 909 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const 910 { 911 Compile* C = ra_->C; 912 913 // WARNING: Initial instruction MUST be 5 bytes or longer so that 914 // NativeJump::patch_verified_entry will be able to patch out the entry 915 // code safely. The fldcw is ok at 6 bytes, the push to verify stack 916 // depth is ok at 5 bytes, the frame allocation can be either 3 or 917 // 6 bytes. So if we don't do the fldcw or the push then we must 918 // use the 6 byte frame allocation even if we have no frame. :-( 919 // If method sets FPU control word do it now 920 921 int framesize = C->frame_slots() << LogBytesPerInt; 922 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 923 // Remove wordSize for return adr already pushed 924 // and another for the RBP we are going to save 925 framesize -= 2*wordSize; 926 bool need_nop = true; 927 928 // Calls to C2R adapters often do not accept exceptional returns. 929 // We require that their callers must bang for them. But be 930 // careful, because some VM calls (such as call site linkage) can 931 // use several kilobytes of stack. But the stack safety zone should 932 // account for that. See bugs 4446381, 4468289, 4497237. 933 if (C->need_stack_bang(framesize)) { 934 MacroAssembler masm(&cbuf); 935 masm.generate_stack_overflow_check(framesize); 936 need_nop = false; 937 } 938 939 // We always push rbp so that on return to interpreter rbp will be 940 // restored correctly and we can correct the stack. 941 emit_opcode(cbuf, 0x50 | RBP_enc); 942 943 if (VerifyStackAtCalls) { 944 // Majik cookie to verify stack depth 945 emit_opcode(cbuf, 0x68); // pushq (sign-extended) 0xbadb100d 946 emit_d32(cbuf, 0xbadb100d); 947 framesize -= wordSize; // Remove 2 for cookie 948 need_nop = false; 949 } 950 951 if (framesize) { 952 emit_opcode(cbuf, Assembler::REX_W); 953 if (framesize < 0x80) { 954 emit_opcode(cbuf, 0x83); // sub SP,#framesize 955 emit_rm(cbuf, 0x3, 0x05, RSP_enc); 956 emit_d8(cbuf, framesize); 957 if (need_nop) { 958 emit_opcode(cbuf, 0x90); // nop 959 } 960 } else { 961 emit_opcode(cbuf, 0x81); // sub SP,#framesize 962 emit_rm(cbuf, 0x3, 0x05, RSP_enc); 963 emit_d32(cbuf, framesize); 964 } 965 } 966 967 C->set_frame_complete(cbuf.insts_size()); 968 969 #ifdef ASSERT 970 if (VerifyStackAtCalls) { 971 Label L; 972 MacroAssembler masm(&cbuf); 973 masm.push(rax); 974 masm.mov(rax, rsp); 975 masm.andptr(rax, StackAlignmentInBytes-1); 976 masm.cmpptr(rax, StackAlignmentInBytes-wordSize); 977 masm.pop(rax); 978 masm.jcc(Assembler::equal, L); 979 masm.stop("Stack is not properly aligned!"); 980 masm.bind(L); 981 } 982 #endif 983 984 if (C->has_mach_constant_base_node()) { 985 // NOTE: We set the table base offset here because users might be 986 // emitted before MachConstantBaseNode. 987 Compile::ConstantTable& constant_table = C->constant_table(); 988 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 989 } 990 } 991 992 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 993 { 994 return MachNode::size(ra_); // too many variables; just compute it 995 // the hard way 996 } 997 998 int MachPrologNode::reloc() const 999 { 1000 return 0; // a large enough number 1001 } 1002 1003 //============================================================================= 1004 #ifndef PRODUCT 1005 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1006 { 1007 Compile* C = ra_->C; 1008 int framesize = C->frame_slots() << LogBytesPerInt; 1009 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 1010 // Remove word for return adr already pushed 1011 // and RBP 1012 framesize -= 2*wordSize; 1013 1014 if (framesize) { 1015 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 1016 st->print("\t"); 1017 } 1018 1019 st->print_cr("popq rbp"); 1020 if (do_polling() && C->is_method_compilation()) { 1021 st->print("\t"); 1022 if (Assembler::is_polling_page_far()) { 1023 st->print_cr("movq rscratch1, #polling_page_address\n\t" 1024 "testl rax, [rscratch1]\t" 1025 "# Safepoint: poll for GC"); 1026 } else { 1027 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 1028 "# Safepoint: poll for GC"); 1029 } 1030 } 1031 } 1032 #endif 1033 1034 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1035 { 1036 Compile* C = ra_->C; 1037 int framesize = C->frame_slots() << LogBytesPerInt; 1038 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 1039 // Remove word for return adr already pushed 1040 // and RBP 1041 framesize -= 2*wordSize; 1042 1043 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 1044 1045 if (framesize) { 1046 emit_opcode(cbuf, Assembler::REX_W); 1047 if (framesize < 0x80) { 1048 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 1049 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1050 emit_d8(cbuf, framesize); 1051 } else { 1052 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 1053 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1054 emit_d32(cbuf, framesize); 1055 } 1056 } 1057 1058 // popq rbp 1059 emit_opcode(cbuf, 0x58 | RBP_enc); 1060 1061 if (do_polling() && C->is_method_compilation()) { 1062 MacroAssembler _masm(&cbuf); 1063 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1064 if (Assembler::is_polling_page_far()) { 1065 __ lea(rscratch1, polling_page); 1066 __ relocate(relocInfo::poll_return_type); 1067 __ testl(rax, Address(rscratch1, 0)); 1068 } else { 1069 __ testl(rax, polling_page); 1070 } 1071 } 1072 } 1073 1074 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1075 { 1076 return MachNode::size(ra_); // too many variables; just compute it 1077 // the hard way 1078 } 1079 1080 int MachEpilogNode::reloc() const 1081 { 1082 return 2; // a large enough number 1083 } 1084 1085 const Pipeline* MachEpilogNode::pipeline() const 1086 { 1087 return MachNode::pipeline_class(); 1088 } 1089 1090 int MachEpilogNode::safepoint_offset() const 1091 { 1092 return 0; 1093 } 1094 1095 //============================================================================= 1096 1097 enum RC { 1098 rc_bad, 1099 rc_int, 1100 rc_float, 1101 rc_stack 1102 }; 1103 1104 static enum RC rc_class(OptoReg::Name reg) 1105 { 1106 if( !OptoReg::is_valid(reg) ) return rc_bad; 1107 1108 if (OptoReg::is_stack(reg)) return rc_stack; 1109 1110 VMReg r = OptoReg::as_VMReg(reg); 1111 1112 if (r->is_Register()) return rc_int; 1113 1114 assert(r->is_XMMRegister(), "must be"); 1115 return rc_float; 1116 } 1117 1118 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1119 PhaseRegAlloc* ra_, 1120 bool do_size, 1121 outputStream* st) const 1122 { 1123 1124 // Get registers to move 1125 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1126 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1127 OptoReg::Name dst_second = ra_->get_reg_second(this); 1128 OptoReg::Name dst_first = ra_->get_reg_first(this); 1129 1130 enum RC src_second_rc = rc_class(src_second); 1131 enum RC src_first_rc = rc_class(src_first); 1132 enum RC dst_second_rc = rc_class(dst_second); 1133 enum RC dst_first_rc = rc_class(dst_first); 1134 1135 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1136 "must move at least 1 register" ); 1137 1138 if (src_first == dst_first && src_second == dst_second) { 1139 // Self copy, no move 1140 return 0; 1141 } else if (src_first_rc == rc_stack) { 1142 // mem -> 1143 if (dst_first_rc == rc_stack) { 1144 // mem -> mem 1145 assert(src_second != dst_first, "overlap"); 1146 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1147 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1148 // 64-bit 1149 int src_offset = ra_->reg2offset(src_first); 1150 int dst_offset = ra_->reg2offset(dst_first); 1151 if (cbuf) { 1152 emit_opcode(*cbuf, 0xFF); 1153 encode_RegMem(*cbuf, RSI_enc, RSP_enc, 0x4, 0, src_offset, false); 1154 1155 emit_opcode(*cbuf, 0x8F); 1156 encode_RegMem(*cbuf, RAX_enc, RSP_enc, 0x4, 0, dst_offset, false); 1157 1158 #ifndef PRODUCT 1159 } else if (!do_size) { 1160 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1161 "popq [rsp + #%d]", 1162 src_offset, 1163 dst_offset); 1164 #endif 1165 } 1166 return 1167 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + 1168 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)); 1169 } else { 1170 // 32-bit 1171 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1172 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1173 // No pushl/popl, so: 1174 int src_offset = ra_->reg2offset(src_first); 1175 int dst_offset = ra_->reg2offset(dst_first); 1176 if (cbuf) { 1177 emit_opcode(*cbuf, Assembler::REX_W); 1178 emit_opcode(*cbuf, 0x89); 1179 emit_opcode(*cbuf, 0x44); 1180 emit_opcode(*cbuf, 0x24); 1181 emit_opcode(*cbuf, 0xF8); 1182 1183 emit_opcode(*cbuf, 0x8B); 1184 encode_RegMem(*cbuf, 1185 RAX_enc, 1186 RSP_enc, 0x4, 0, src_offset, 1187 false); 1188 1189 emit_opcode(*cbuf, 0x89); 1190 encode_RegMem(*cbuf, 1191 RAX_enc, 1192 RSP_enc, 0x4, 0, dst_offset, 1193 false); 1194 1195 emit_opcode(*cbuf, Assembler::REX_W); 1196 emit_opcode(*cbuf, 0x8B); 1197 emit_opcode(*cbuf, 0x44); 1198 emit_opcode(*cbuf, 0x24); 1199 emit_opcode(*cbuf, 0xF8); 1200 1201 #ifndef PRODUCT 1202 } else if (!do_size) { 1203 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1204 "movl rax, [rsp + #%d]\n\t" 1205 "movl [rsp + #%d], rax\n\t" 1206 "movq rax, [rsp - #8]", 1207 src_offset, 1208 dst_offset); 1209 #endif 1210 } 1211 return 1212 5 + // movq 1213 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + // movl 1214 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)) + // movl 1215 5; // movq 1216 } 1217 } else if (dst_first_rc == rc_int) { 1218 // mem -> gpr 1219 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1220 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1221 // 64-bit 1222 int offset = ra_->reg2offset(src_first); 1223 if (cbuf) { 1224 if (Matcher::_regEncode[dst_first] < 8) { 1225 emit_opcode(*cbuf, Assembler::REX_W); 1226 } else { 1227 emit_opcode(*cbuf, Assembler::REX_WR); 1228 } 1229 emit_opcode(*cbuf, 0x8B); 1230 encode_RegMem(*cbuf, 1231 Matcher::_regEncode[dst_first], 1232 RSP_enc, 0x4, 0, offset, 1233 false); 1234 #ifndef PRODUCT 1235 } else if (!do_size) { 1236 st->print("movq %s, [rsp + #%d]\t# spill", 1237 Matcher::regName[dst_first], 1238 offset); 1239 #endif 1240 } 1241 return 1242 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX 1243 } else { 1244 // 32-bit 1245 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1246 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1247 int offset = ra_->reg2offset(src_first); 1248 if (cbuf) { 1249 if (Matcher::_regEncode[dst_first] >= 8) { 1250 emit_opcode(*cbuf, Assembler::REX_R); 1251 } 1252 emit_opcode(*cbuf, 0x8B); 1253 encode_RegMem(*cbuf, 1254 Matcher::_regEncode[dst_first], 1255 RSP_enc, 0x4, 0, offset, 1256 false); 1257 #ifndef PRODUCT 1258 } else if (!do_size) { 1259 st->print("movl %s, [rsp + #%d]\t# spill", 1260 Matcher::regName[dst_first], 1261 offset); 1262 #endif 1263 } 1264 return 1265 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1266 ((Matcher::_regEncode[dst_first] < 8) 1267 ? 3 1268 : 4); // REX 1269 } 1270 } else if (dst_first_rc == rc_float) { 1271 // mem-> xmm 1272 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1273 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1274 // 64-bit 1275 int offset = ra_->reg2offset(src_first); 1276 if (cbuf) { 1277 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 1278 if (Matcher::_regEncode[dst_first] >= 8) { 1279 emit_opcode(*cbuf, Assembler::REX_R); 1280 } 1281 emit_opcode(*cbuf, 0x0F); 1282 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12); 1283 encode_RegMem(*cbuf, 1284 Matcher::_regEncode[dst_first], 1285 RSP_enc, 0x4, 0, offset, 1286 false); 1287 #ifndef PRODUCT 1288 } else if (!do_size) { 1289 st->print("%s %s, [rsp + #%d]\t# spill", 1290 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1291 Matcher::regName[dst_first], 1292 offset); 1293 #endif 1294 } 1295 return 1296 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1297 ((Matcher::_regEncode[dst_first] < 8) 1298 ? 5 1299 : 6); // REX 1300 } else { 1301 // 32-bit 1302 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1303 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1304 int offset = ra_->reg2offset(src_first); 1305 if (cbuf) { 1306 emit_opcode(*cbuf, 0xF3); 1307 if (Matcher::_regEncode[dst_first] >= 8) { 1308 emit_opcode(*cbuf, Assembler::REX_R); 1309 } 1310 emit_opcode(*cbuf, 0x0F); 1311 emit_opcode(*cbuf, 0x10); 1312 encode_RegMem(*cbuf, 1313 Matcher::_regEncode[dst_first], 1314 RSP_enc, 0x4, 0, offset, 1315 false); 1316 #ifndef PRODUCT 1317 } else if (!do_size) { 1318 st->print("movss %s, [rsp + #%d]\t# spill", 1319 Matcher::regName[dst_first], 1320 offset); 1321 #endif 1322 } 1323 return 1324 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1325 ((Matcher::_regEncode[dst_first] < 8) 1326 ? 5 1327 : 6); // REX 1328 } 1329 } 1330 } else if (src_first_rc == rc_int) { 1331 // gpr -> 1332 if (dst_first_rc == rc_stack) { 1333 // gpr -> mem 1334 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1335 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1336 // 64-bit 1337 int offset = ra_->reg2offset(dst_first); 1338 if (cbuf) { 1339 if (Matcher::_regEncode[src_first] < 8) { 1340 emit_opcode(*cbuf, Assembler::REX_W); 1341 } else { 1342 emit_opcode(*cbuf, Assembler::REX_WR); 1343 } 1344 emit_opcode(*cbuf, 0x89); 1345 encode_RegMem(*cbuf, 1346 Matcher::_regEncode[src_first], 1347 RSP_enc, 0x4, 0, offset, 1348 false); 1349 #ifndef PRODUCT 1350 } else if (!do_size) { 1351 st->print("movq [rsp + #%d], %s\t# spill", 1352 offset, 1353 Matcher::regName[src_first]); 1354 #endif 1355 } 1356 return ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX 1357 } else { 1358 // 32-bit 1359 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1360 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1361 int offset = ra_->reg2offset(dst_first); 1362 if (cbuf) { 1363 if (Matcher::_regEncode[src_first] >= 8) { 1364 emit_opcode(*cbuf, Assembler::REX_R); 1365 } 1366 emit_opcode(*cbuf, 0x89); 1367 encode_RegMem(*cbuf, 1368 Matcher::_regEncode[src_first], 1369 RSP_enc, 0x4, 0, offset, 1370 false); 1371 #ifndef PRODUCT 1372 } else if (!do_size) { 1373 st->print("movl [rsp + #%d], %s\t# spill", 1374 offset, 1375 Matcher::regName[src_first]); 1376 #endif 1377 } 1378 return 1379 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1380 ((Matcher::_regEncode[src_first] < 8) 1381 ? 3 1382 : 4); // REX 1383 } 1384 } else if (dst_first_rc == rc_int) { 1385 // gpr -> gpr 1386 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1387 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1388 // 64-bit 1389 if (cbuf) { 1390 if (Matcher::_regEncode[dst_first] < 8) { 1391 if (Matcher::_regEncode[src_first] < 8) { 1392 emit_opcode(*cbuf, Assembler::REX_W); 1393 } else { 1394 emit_opcode(*cbuf, Assembler::REX_WB); 1395 } 1396 } else { 1397 if (Matcher::_regEncode[src_first] < 8) { 1398 emit_opcode(*cbuf, Assembler::REX_WR); 1399 } else { 1400 emit_opcode(*cbuf, Assembler::REX_WRB); 1401 } 1402 } 1403 emit_opcode(*cbuf, 0x8B); 1404 emit_rm(*cbuf, 0x3, 1405 Matcher::_regEncode[dst_first] & 7, 1406 Matcher::_regEncode[src_first] & 7); 1407 #ifndef PRODUCT 1408 } else if (!do_size) { 1409 st->print("movq %s, %s\t# spill", 1410 Matcher::regName[dst_first], 1411 Matcher::regName[src_first]); 1412 #endif 1413 } 1414 return 3; // REX 1415 } else { 1416 // 32-bit 1417 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1418 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1419 if (cbuf) { 1420 if (Matcher::_regEncode[dst_first] < 8) { 1421 if (Matcher::_regEncode[src_first] >= 8) { 1422 emit_opcode(*cbuf, Assembler::REX_B); 1423 } 1424 } else { 1425 if (Matcher::_regEncode[src_first] < 8) { 1426 emit_opcode(*cbuf, Assembler::REX_R); 1427 } else { 1428 emit_opcode(*cbuf, Assembler::REX_RB); 1429 } 1430 } 1431 emit_opcode(*cbuf, 0x8B); 1432 emit_rm(*cbuf, 0x3, 1433 Matcher::_regEncode[dst_first] & 7, 1434 Matcher::_regEncode[src_first] & 7); 1435 #ifndef PRODUCT 1436 } else if (!do_size) { 1437 st->print("movl %s, %s\t# spill", 1438 Matcher::regName[dst_first], 1439 Matcher::regName[src_first]); 1440 #endif 1441 } 1442 return 1443 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1444 ? 2 1445 : 3; // REX 1446 } 1447 } else if (dst_first_rc == rc_float) { 1448 // gpr -> xmm 1449 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1450 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1451 // 64-bit 1452 if (cbuf) { 1453 emit_opcode(*cbuf, 0x66); 1454 if (Matcher::_regEncode[dst_first] < 8) { 1455 if (Matcher::_regEncode[src_first] < 8) { 1456 emit_opcode(*cbuf, Assembler::REX_W); 1457 } else { 1458 emit_opcode(*cbuf, Assembler::REX_WB); 1459 } 1460 } else { 1461 if (Matcher::_regEncode[src_first] < 8) { 1462 emit_opcode(*cbuf, Assembler::REX_WR); 1463 } else { 1464 emit_opcode(*cbuf, Assembler::REX_WRB); 1465 } 1466 } 1467 emit_opcode(*cbuf, 0x0F); 1468 emit_opcode(*cbuf, 0x6E); 1469 emit_rm(*cbuf, 0x3, 1470 Matcher::_regEncode[dst_first] & 7, 1471 Matcher::_regEncode[src_first] & 7); 1472 #ifndef PRODUCT 1473 } else if (!do_size) { 1474 st->print("movdq %s, %s\t# spill", 1475 Matcher::regName[dst_first], 1476 Matcher::regName[src_first]); 1477 #endif 1478 } 1479 return 5; // REX 1480 } else { 1481 // 32-bit 1482 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1483 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1484 if (cbuf) { 1485 emit_opcode(*cbuf, 0x66); 1486 if (Matcher::_regEncode[dst_first] < 8) { 1487 if (Matcher::_regEncode[src_first] >= 8) { 1488 emit_opcode(*cbuf, Assembler::REX_B); 1489 } 1490 } else { 1491 if (Matcher::_regEncode[src_first] < 8) { 1492 emit_opcode(*cbuf, Assembler::REX_R); 1493 } else { 1494 emit_opcode(*cbuf, Assembler::REX_RB); 1495 } 1496 } 1497 emit_opcode(*cbuf, 0x0F); 1498 emit_opcode(*cbuf, 0x6E); 1499 emit_rm(*cbuf, 0x3, 1500 Matcher::_regEncode[dst_first] & 7, 1501 Matcher::_regEncode[src_first] & 7); 1502 #ifndef PRODUCT 1503 } else if (!do_size) { 1504 st->print("movdl %s, %s\t# spill", 1505 Matcher::regName[dst_first], 1506 Matcher::regName[src_first]); 1507 #endif 1508 } 1509 return 1510 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1511 ? 4 1512 : 5; // REX 1513 } 1514 } 1515 } else if (src_first_rc == rc_float) { 1516 // xmm -> 1517 if (dst_first_rc == rc_stack) { 1518 // xmm -> mem 1519 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1520 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1521 // 64-bit 1522 int offset = ra_->reg2offset(dst_first); 1523 if (cbuf) { 1524 emit_opcode(*cbuf, 0xF2); 1525 if (Matcher::_regEncode[src_first] >= 8) { 1526 emit_opcode(*cbuf, Assembler::REX_R); 1527 } 1528 emit_opcode(*cbuf, 0x0F); 1529 emit_opcode(*cbuf, 0x11); 1530 encode_RegMem(*cbuf, 1531 Matcher::_regEncode[src_first], 1532 RSP_enc, 0x4, 0, offset, 1533 false); 1534 #ifndef PRODUCT 1535 } else if (!do_size) { 1536 st->print("movsd [rsp + #%d], %s\t# spill", 1537 offset, 1538 Matcher::regName[src_first]); 1539 #endif 1540 } 1541 return 1542 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1543 ((Matcher::_regEncode[src_first] < 8) 1544 ? 5 1545 : 6); // REX 1546 } else { 1547 // 32-bit 1548 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1549 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1550 int offset = ra_->reg2offset(dst_first); 1551 if (cbuf) { 1552 emit_opcode(*cbuf, 0xF3); 1553 if (Matcher::_regEncode[src_first] >= 8) { 1554 emit_opcode(*cbuf, Assembler::REX_R); 1555 } 1556 emit_opcode(*cbuf, 0x0F); 1557 emit_opcode(*cbuf, 0x11); 1558 encode_RegMem(*cbuf, 1559 Matcher::_regEncode[src_first], 1560 RSP_enc, 0x4, 0, offset, 1561 false); 1562 #ifndef PRODUCT 1563 } else if (!do_size) { 1564 st->print("movss [rsp + #%d], %s\t# spill", 1565 offset, 1566 Matcher::regName[src_first]); 1567 #endif 1568 } 1569 return 1570 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1571 ((Matcher::_regEncode[src_first] < 8) 1572 ? 5 1573 : 6); // REX 1574 } 1575 } else if (dst_first_rc == rc_int) { 1576 // xmm -> gpr 1577 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1578 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1579 // 64-bit 1580 if (cbuf) { 1581 emit_opcode(*cbuf, 0x66); 1582 if (Matcher::_regEncode[dst_first] < 8) { 1583 if (Matcher::_regEncode[src_first] < 8) { 1584 emit_opcode(*cbuf, Assembler::REX_W); 1585 } else { 1586 emit_opcode(*cbuf, Assembler::REX_WR); // attention! 1587 } 1588 } else { 1589 if (Matcher::_regEncode[src_first] < 8) { 1590 emit_opcode(*cbuf, Assembler::REX_WB); // attention! 1591 } else { 1592 emit_opcode(*cbuf, Assembler::REX_WRB); 1593 } 1594 } 1595 emit_opcode(*cbuf, 0x0F); 1596 emit_opcode(*cbuf, 0x7E); 1597 emit_rm(*cbuf, 0x3, 1598 Matcher::_regEncode[src_first] & 7, 1599 Matcher::_regEncode[dst_first] & 7); 1600 #ifndef PRODUCT 1601 } else if (!do_size) { 1602 st->print("movdq %s, %s\t# spill", 1603 Matcher::regName[dst_first], 1604 Matcher::regName[src_first]); 1605 #endif 1606 } 1607 return 5; // REX 1608 } else { 1609 // 32-bit 1610 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1611 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1612 if (cbuf) { 1613 emit_opcode(*cbuf, 0x66); 1614 if (Matcher::_regEncode[dst_first] < 8) { 1615 if (Matcher::_regEncode[src_first] >= 8) { 1616 emit_opcode(*cbuf, Assembler::REX_R); // attention! 1617 } 1618 } else { 1619 if (Matcher::_regEncode[src_first] < 8) { 1620 emit_opcode(*cbuf, Assembler::REX_B); // attention! 1621 } else { 1622 emit_opcode(*cbuf, Assembler::REX_RB); 1623 } 1624 } 1625 emit_opcode(*cbuf, 0x0F); 1626 emit_opcode(*cbuf, 0x7E); 1627 emit_rm(*cbuf, 0x3, 1628 Matcher::_regEncode[src_first] & 7, 1629 Matcher::_regEncode[dst_first] & 7); 1630 #ifndef PRODUCT 1631 } else if (!do_size) { 1632 st->print("movdl %s, %s\t# spill", 1633 Matcher::regName[dst_first], 1634 Matcher::regName[src_first]); 1635 #endif 1636 } 1637 return 1638 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1639 ? 4 1640 : 5; // REX 1641 } 1642 } else if (dst_first_rc == rc_float) { 1643 // xmm -> xmm 1644 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1645 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1646 // 64-bit 1647 if (cbuf) { 1648 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2); 1649 if (Matcher::_regEncode[dst_first] < 8) { 1650 if (Matcher::_regEncode[src_first] >= 8) { 1651 emit_opcode(*cbuf, Assembler::REX_B); 1652 } 1653 } else { 1654 if (Matcher::_regEncode[src_first] < 8) { 1655 emit_opcode(*cbuf, Assembler::REX_R); 1656 } else { 1657 emit_opcode(*cbuf, Assembler::REX_RB); 1658 } 1659 } 1660 emit_opcode(*cbuf, 0x0F); 1661 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 1662 emit_rm(*cbuf, 0x3, 1663 Matcher::_regEncode[dst_first] & 7, 1664 Matcher::_regEncode[src_first] & 7); 1665 #ifndef PRODUCT 1666 } else if (!do_size) { 1667 st->print("%s %s, %s\t# spill", 1668 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1669 Matcher::regName[dst_first], 1670 Matcher::regName[src_first]); 1671 #endif 1672 } 1673 return 1674 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1675 ? 4 1676 : 5; // REX 1677 } else { 1678 // 32-bit 1679 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1680 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1681 if (cbuf) { 1682 if (!UseXmmRegToRegMoveAll) 1683 emit_opcode(*cbuf, 0xF3); 1684 if (Matcher::_regEncode[dst_first] < 8) { 1685 if (Matcher::_regEncode[src_first] >= 8) { 1686 emit_opcode(*cbuf, Assembler::REX_B); 1687 } 1688 } else { 1689 if (Matcher::_regEncode[src_first] < 8) { 1690 emit_opcode(*cbuf, Assembler::REX_R); 1691 } else { 1692 emit_opcode(*cbuf, Assembler::REX_RB); 1693 } 1694 } 1695 emit_opcode(*cbuf, 0x0F); 1696 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 1697 emit_rm(*cbuf, 0x3, 1698 Matcher::_regEncode[dst_first] & 7, 1699 Matcher::_regEncode[src_first] & 7); 1700 #ifndef PRODUCT 1701 } else if (!do_size) { 1702 st->print("%s %s, %s\t# spill", 1703 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1704 Matcher::regName[dst_first], 1705 Matcher::regName[src_first]); 1706 #endif 1707 } 1708 return 1709 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1710 ? (UseXmmRegToRegMoveAll ? 3 : 4) 1711 : (UseXmmRegToRegMoveAll ? 4 : 5); // REX 1712 } 1713 } 1714 } 1715 1716 assert(0," foo "); 1717 Unimplemented(); 1718 1719 return 0; 1720 } 1721 1722 #ifndef PRODUCT 1723 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const 1724 { 1725 implementation(NULL, ra_, false, st); 1726 } 1727 #endif 1728 1729 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const 1730 { 1731 implementation(&cbuf, ra_, false, NULL); 1732 } 1733 1734 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const 1735 { 1736 return implementation(NULL, ra_, true, NULL); 1737 } 1738 1739 //============================================================================= 1740 #ifndef PRODUCT 1741 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const 1742 { 1743 st->print("nop \t# %d bytes pad for loops and calls", _count); 1744 } 1745 #endif 1746 1747 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const 1748 { 1749 MacroAssembler _masm(&cbuf); 1750 __ nop(_count); 1751 } 1752 1753 uint MachNopNode::size(PhaseRegAlloc*) const 1754 { 1755 return _count; 1756 } 1757 1758 1759 //============================================================================= 1760 #ifndef PRODUCT 1761 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1762 { 1763 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1764 int reg = ra_->get_reg_first(this); 1765 st->print("leaq %s, [rsp + #%d]\t# box lock", 1766 Matcher::regName[reg], offset); 1767 } 1768 #endif 1769 1770 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1771 { 1772 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1773 int reg = ra_->get_encode(this); 1774 if (offset >= 0x80) { 1775 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1776 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1777 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1778 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1779 emit_d32(cbuf, offset); 1780 } else { 1781 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1782 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1783 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1784 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1785 emit_d8(cbuf, offset); 1786 } 1787 } 1788 1789 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1790 { 1791 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1792 return (offset < 0x80) ? 5 : 8; // REX 1793 } 1794 1795 //============================================================================= 1796 1797 // emit call stub, compiled java to interpreter 1798 void emit_java_to_interp(CodeBuffer& cbuf) 1799 { 1800 // Stub is fixed up when the corresponding call is converted from 1801 // calling compiled code to calling interpreted code. 1802 // movq rbx, 0 1803 // jmp -5 # to self 1804 1805 address mark = cbuf.insts_mark(); // get mark within main instrs section 1806 1807 // Note that the code buffer's insts_mark is always relative to insts. 1808 // That's why we must use the macroassembler to generate a stub. 1809 MacroAssembler _masm(&cbuf); 1810 1811 address base = 1812 __ start_a_stub(Compile::MAX_stubs_size); 1813 if (base == NULL) return; // CodeBuffer::expand failed 1814 // static stub relocation stores the instruction address of the call 1815 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); 1816 // static stub relocation also tags the methodOop in the code-stream. 1817 __ movoop(rbx, (jobject) NULL); // method is zapped till fixup time 1818 // This is recognized as unresolved by relocs/nativeinst/ic code 1819 __ jump(RuntimeAddress(__ pc())); 1820 1821 // Update current stubs pointer and restore insts_end. 1822 __ end_a_stub(); 1823 } 1824 1825 // size of call stub, compiled java to interpretor 1826 uint size_java_to_interp() 1827 { 1828 return 15; // movq (1+1+8); jmp (1+4) 1829 } 1830 1831 // relocation entries for call stub, compiled java to interpretor 1832 uint reloc_java_to_interp() 1833 { 1834 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call 1835 } 1836 1837 //============================================================================= 1838 #ifndef PRODUCT 1839 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1840 { 1841 if (UseCompressedOops) { 1842 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1843 if (Universe::narrow_oop_shift() != 0) { 1844 st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1"); 1845 } 1846 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1847 } else { 1848 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1849 "# Inline cache check"); 1850 } 1851 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1852 st->print_cr("\tnop\t# nops to align entry point"); 1853 } 1854 #endif 1855 1856 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1857 { 1858 MacroAssembler masm(&cbuf); 1859 uint insts_size = cbuf.insts_size(); 1860 if (UseCompressedOops) { 1861 masm.load_klass(rscratch1, j_rarg0); 1862 masm.cmpptr(rax, rscratch1); 1863 } else { 1864 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1865 } 1866 1867 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1868 1869 /* WARNING these NOPs are critical so that verified entry point is properly 1870 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1871 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1872 if (OptoBreakpoint) { 1873 // Leave space for int3 1874 nops_cnt -= 1; 1875 } 1876 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1877 if (nops_cnt > 0) 1878 masm.nop(nops_cnt); 1879 } 1880 1881 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1882 { 1883 return MachNode::size(ra_); // too many variables; just compute it 1884 // the hard way 1885 } 1886 1887 1888 //============================================================================= 1889 uint size_exception_handler() 1890 { 1891 // NativeCall instruction size is the same as NativeJump. 1892 // Note that this value is also credited (in output.cpp) to 1893 // the size of the code section. 1894 return NativeJump::instruction_size; 1895 } 1896 1897 // Emit exception handler code. 1898 int emit_exception_handler(CodeBuffer& cbuf) 1899 { 1900 1901 // Note that the code buffer's insts_mark is always relative to insts. 1902 // That's why we must use the macroassembler to generate a handler. 1903 MacroAssembler _masm(&cbuf); 1904 address base = 1905 __ start_a_stub(size_exception_handler()); 1906 if (base == NULL) return 0; // CodeBuffer::expand failed 1907 int offset = __ offset(); 1908 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1909 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1910 __ end_a_stub(); 1911 return offset; 1912 } 1913 1914 uint size_deopt_handler() 1915 { 1916 // three 5 byte instructions 1917 return 15; 1918 } 1919 1920 // Emit deopt handler code. 1921 int emit_deopt_handler(CodeBuffer& cbuf) 1922 { 1923 1924 // Note that the code buffer's insts_mark is always relative to insts. 1925 // That's why we must use the macroassembler to generate a handler. 1926 MacroAssembler _masm(&cbuf); 1927 address base = 1928 __ start_a_stub(size_deopt_handler()); 1929 if (base == NULL) return 0; // CodeBuffer::expand failed 1930 int offset = __ offset(); 1931 address the_pc = (address) __ pc(); 1932 Label next; 1933 // push a "the_pc" on the stack without destroying any registers 1934 // as they all may be live. 1935 1936 // push address of "next" 1937 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 1938 __ bind(next); 1939 // adjust it so it matches "the_pc" 1940 __ subptr(Address(rsp, 0), __ offset() - offset); 1941 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1942 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1943 __ end_a_stub(); 1944 return offset; 1945 } 1946 1947 1948 const bool Matcher::match_rule_supported(int opcode) { 1949 if (!has_match_rule(opcode)) 1950 return false; 1951 1952 return true; // Per default match rules are supported. 1953 } 1954 1955 int Matcher::regnum_to_fpu_offset(int regnum) 1956 { 1957 return regnum - 32; // The FP registers are in the second chunk 1958 } 1959 1960 // This is UltraSparc specific, true just means we have fast l2f conversion 1961 const bool Matcher::convL2FSupported(void) { 1962 return true; 1963 } 1964 1965 // Vector width in bytes 1966 const uint Matcher::vector_width_in_bytes(void) { 1967 return 8; 1968 } 1969 1970 // Vector ideal reg 1971 const uint Matcher::vector_ideal_reg(void) { 1972 return Op_RegD; 1973 } 1974 1975 // Is this branch offset short enough that a short branch can be used? 1976 // 1977 // NOTE: If the platform does not provide any short branch variants, then 1978 // this method should return false for offset 0. 1979 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1980 // The passed offset is relative to address of the branch. 1981 // On 86 a branch displacement is calculated relative to address 1982 // of a next instruction. 1983 offset -= br_size; 1984 1985 // the short version of jmpConUCF2 contains multiple branches, 1986 // making the reach slightly less 1987 if (rule == jmpConUCF2_rule) 1988 return (-126 <= offset && offset <= 125); 1989 return (-128 <= offset && offset <= 127); 1990 } 1991 1992 const bool Matcher::isSimpleConstant64(jlong value) { 1993 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1994 //return value == (int) value; // Cf. storeImmL and immL32. 1995 1996 // Probably always true, even if a temp register is required. 1997 return true; 1998 } 1999 2000 // The ecx parameter to rep stosq for the ClearArray node is in words. 2001 const bool Matcher::init_array_count_is_in_bytes = false; 2002 2003 // Threshold size for cleararray. 2004 const int Matcher::init_array_short_size = 8 * BytesPerLong; 2005 2006 // No additional cost for CMOVL. 2007 const int Matcher::long_cmove_cost() { return 0; } 2008 2009 // No CMOVF/CMOVD with SSE2 2010 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2011 2012 // Should the Matcher clone shifts on addressing modes, expecting them 2013 // to be subsumed into complex addressing expressions or compute them 2014 // into registers? True for Intel but false for most RISCs 2015 const bool Matcher::clone_shift_expressions = true; 2016 2017 // Do we need to mask the count passed to shift instructions or does 2018 // the cpu only look at the lower 5/6 bits anyway? 2019 const bool Matcher::need_masked_shift_count = false; 2020 2021 bool Matcher::narrow_oop_use_complex_address() { 2022 assert(UseCompressedOops, "only for compressed oops code"); 2023 return (LogMinObjAlignmentInBytes <= 3); 2024 } 2025 2026 // Is it better to copy float constants, or load them directly from 2027 // memory? Intel can load a float constant from a direct address, 2028 // requiring no extra registers. Most RISCs will have to materialize 2029 // an address into a register first, so they would do better to copy 2030 // the constant from stack. 2031 const bool Matcher::rematerialize_float_constants = true; // XXX 2032 2033 // If CPU can load and store mis-aligned doubles directly then no 2034 // fixup is needed. Else we split the double into 2 integer pieces 2035 // and move it piece-by-piece. Only happens when passing doubles into 2036 // C code as the Java calling convention forces doubles to be aligned. 2037 const bool Matcher::misaligned_doubles_ok = true; 2038 2039 // No-op on amd64 2040 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 2041 2042 // Advertise here if the CPU requires explicit rounding operations to 2043 // implement the UseStrictFP mode. 2044 const bool Matcher::strict_fp_requires_explicit_rounding = true; 2045 2046 // Are floats conerted to double when stored to stack during deoptimization? 2047 // On x64 it is stored without convertion so we can use normal access. 2048 bool Matcher::float_in_double() { return false; } 2049 2050 // Do ints take an entire long register or just half? 2051 const bool Matcher::int_in_long = true; 2052 2053 // Return whether or not this register is ever used as an argument. 2054 // This function is used on startup to build the trampoline stubs in 2055 // generateOptoStub. Registers not mentioned will be killed by the VM 2056 // call in the trampoline, and arguments in those registers not be 2057 // available to the callee. 2058 bool Matcher::can_be_java_arg(int reg) 2059 { 2060 return 2061 reg == RDI_num || reg == RDI_H_num || 2062 reg == RSI_num || reg == RSI_H_num || 2063 reg == RDX_num || reg == RDX_H_num || 2064 reg == RCX_num || reg == RCX_H_num || 2065 reg == R8_num || reg == R8_H_num || 2066 reg == R9_num || reg == R9_H_num || 2067 reg == R12_num || reg == R12_H_num || 2068 reg == XMM0_num || reg == XMM0_H_num || 2069 reg == XMM1_num || reg == XMM1_H_num || 2070 reg == XMM2_num || reg == XMM2_H_num || 2071 reg == XMM3_num || reg == XMM3_H_num || 2072 reg == XMM4_num || reg == XMM4_H_num || 2073 reg == XMM5_num || reg == XMM5_H_num || 2074 reg == XMM6_num || reg == XMM6_H_num || 2075 reg == XMM7_num || reg == XMM7_H_num; 2076 } 2077 2078 bool Matcher::is_spillable_arg(int reg) 2079 { 2080 return can_be_java_arg(reg); 2081 } 2082 2083 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 2084 // In 64 bit mode a code which use multiply when 2085 // devisor is constant is faster than hardware 2086 // DIV instruction (it uses MulHiL). 2087 return false; 2088 } 2089 2090 // Register for DIVI projection of divmodI 2091 RegMask Matcher::divI_proj_mask() { 2092 return INT_RAX_REG_mask(); 2093 } 2094 2095 // Register for MODI projection of divmodI 2096 RegMask Matcher::modI_proj_mask() { 2097 return INT_RDX_REG_mask(); 2098 } 2099 2100 // Register for DIVL projection of divmodL 2101 RegMask Matcher::divL_proj_mask() { 2102 return LONG_RAX_REG_mask(); 2103 } 2104 2105 // Register for MODL projection of divmodL 2106 RegMask Matcher::modL_proj_mask() { 2107 return LONG_RDX_REG_mask(); 2108 } 2109 2110 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2111 return PTR_RBP_REG_mask(); 2112 } 2113 2114 static Address build_address(int b, int i, int s, int d) { 2115 Register index = as_Register(i); 2116 Address::ScaleFactor scale = (Address::ScaleFactor)s; 2117 if (index == rsp) { 2118 index = noreg; 2119 scale = Address::no_scale; 2120 } 2121 Address addr(as_Register(b), index, scale, d); 2122 return addr; 2123 } 2124 2125 %} 2126 2127 //----------ENCODING BLOCK----------------------------------------------------- 2128 // This block specifies the encoding classes used by the compiler to 2129 // output byte streams. Encoding classes are parameterized macros 2130 // used by Machine Instruction Nodes in order to generate the bit 2131 // encoding of the instruction. Operands specify their base encoding 2132 // interface with the interface keyword. There are currently 2133 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2134 // COND_INTER. REG_INTER causes an operand to generate a function 2135 // which returns its register number when queried. CONST_INTER causes 2136 // an operand to generate a function which returns the value of the 2137 // constant when queried. MEMORY_INTER causes an operand to generate 2138 // four functions which return the Base Register, the Index Register, 2139 // the Scale Value, and the Offset Value of the operand when queried. 2140 // COND_INTER causes an operand to generate six functions which return 2141 // the encoding code (ie - encoding bits for the instruction) 2142 // associated with each basic boolean condition for a conditional 2143 // instruction. 2144 // 2145 // Instructions specify two basic values for encoding. Again, a 2146 // function is available to check if the constant displacement is an 2147 // oop. They use the ins_encode keyword to specify their encoding 2148 // classes (which must be a sequence of enc_class names, and their 2149 // parameters, specified in the encoding block), and they use the 2150 // opcode keyword to specify, in order, their primary, secondary, and 2151 // tertiary opcode. Only the opcode sections which a particular 2152 // instruction needs for encoding need to be specified. 2153 encode %{ 2154 // Build emit functions for each basic byte or larger field in the 2155 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2156 // from C++ code in the enc_class source block. Emit functions will 2157 // live in the main source block for now. In future, we can 2158 // generalize this by adding a syntax that specifies the sizes of 2159 // fields in an order, so that the adlc can build the emit functions 2160 // automagically 2161 2162 // Emit primary opcode 2163 enc_class OpcP 2164 %{ 2165 emit_opcode(cbuf, $primary); 2166 %} 2167 2168 // Emit secondary opcode 2169 enc_class OpcS 2170 %{ 2171 emit_opcode(cbuf, $secondary); 2172 %} 2173 2174 // Emit tertiary opcode 2175 enc_class OpcT 2176 %{ 2177 emit_opcode(cbuf, $tertiary); 2178 %} 2179 2180 // Emit opcode directly 2181 enc_class Opcode(immI d8) 2182 %{ 2183 emit_opcode(cbuf, $d8$$constant); 2184 %} 2185 2186 // Emit size prefix 2187 enc_class SizePrefix 2188 %{ 2189 emit_opcode(cbuf, 0x66); 2190 %} 2191 2192 enc_class reg(rRegI reg) 2193 %{ 2194 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 2195 %} 2196 2197 enc_class reg_reg(rRegI dst, rRegI src) 2198 %{ 2199 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2200 %} 2201 2202 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 2203 %{ 2204 emit_opcode(cbuf, $opcode$$constant); 2205 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2206 %} 2207 2208 enc_class cmpfp_fixup() %{ 2209 MacroAssembler _masm(&cbuf); 2210 emit_cmpfp_fixup(_masm); 2211 %} 2212 2213 enc_class cmpfp3(rRegI dst) 2214 %{ 2215 int dstenc = $dst$$reg; 2216 2217 // movl $dst, -1 2218 if (dstenc >= 8) { 2219 emit_opcode(cbuf, Assembler::REX_B); 2220 } 2221 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2222 emit_d32(cbuf, -1); 2223 2224 // jp,s done 2225 emit_opcode(cbuf, 0x7A); 2226 emit_d8(cbuf, dstenc < 4 ? 0x08 : 0x0A); 2227 2228 // jb,s done 2229 emit_opcode(cbuf, 0x72); 2230 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2231 2232 // setne $dst 2233 if (dstenc >= 4) { 2234 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2235 } 2236 emit_opcode(cbuf, 0x0F); 2237 emit_opcode(cbuf, 0x95); 2238 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2239 2240 // movzbl $dst, $dst 2241 if (dstenc >= 4) { 2242 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2243 } 2244 emit_opcode(cbuf, 0x0F); 2245 emit_opcode(cbuf, 0xB6); 2246 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2247 %} 2248 2249 enc_class cdql_enc(no_rax_rdx_RegI div) 2250 %{ 2251 // Full implementation of Java idiv and irem; checks for 2252 // special case as described in JVM spec., p.243 & p.271. 2253 // 2254 // normal case special case 2255 // 2256 // input : rax: dividend min_int 2257 // reg: divisor -1 2258 // 2259 // output: rax: quotient (= rax idiv reg) min_int 2260 // rdx: remainder (= rax irem reg) 0 2261 // 2262 // Code sequnce: 2263 // 2264 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 2265 // 5: 75 07/08 jne e <normal> 2266 // 7: 33 d2 xor %edx,%edx 2267 // [div >= 8 -> offset + 1] 2268 // [REX_B] 2269 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 2270 // c: 74 03/04 je 11 <done> 2271 // 000000000000000e <normal>: 2272 // e: 99 cltd 2273 // [div >= 8 -> offset + 1] 2274 // [REX_B] 2275 // f: f7 f9 idiv $div 2276 // 0000000000000011 <done>: 2277 2278 // cmp $0x80000000,%eax 2279 emit_opcode(cbuf, 0x3d); 2280 emit_d8(cbuf, 0x00); 2281 emit_d8(cbuf, 0x00); 2282 emit_d8(cbuf, 0x00); 2283 emit_d8(cbuf, 0x80); 2284 2285 // jne e <normal> 2286 emit_opcode(cbuf, 0x75); 2287 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 2288 2289 // xor %edx,%edx 2290 emit_opcode(cbuf, 0x33); 2291 emit_d8(cbuf, 0xD2); 2292 2293 // cmp $0xffffffffffffffff,%ecx 2294 if ($div$$reg >= 8) { 2295 emit_opcode(cbuf, Assembler::REX_B); 2296 } 2297 emit_opcode(cbuf, 0x83); 2298 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2299 emit_d8(cbuf, 0xFF); 2300 2301 // je 11 <done> 2302 emit_opcode(cbuf, 0x74); 2303 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 2304 2305 // <normal> 2306 // cltd 2307 emit_opcode(cbuf, 0x99); 2308 2309 // idivl (note: must be emitted by the user of this rule) 2310 // <done> 2311 %} 2312 2313 enc_class cdqq_enc(no_rax_rdx_RegL div) 2314 %{ 2315 // Full implementation of Java ldiv and lrem; checks for 2316 // special case as described in JVM spec., p.243 & p.271. 2317 // 2318 // normal case special case 2319 // 2320 // input : rax: dividend min_long 2321 // reg: divisor -1 2322 // 2323 // output: rax: quotient (= rax idiv reg) min_long 2324 // rdx: remainder (= rax irem reg) 0 2325 // 2326 // Code sequnce: 2327 // 2328 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 2329 // 7: 00 00 80 2330 // a: 48 39 d0 cmp %rdx,%rax 2331 // d: 75 08 jne 17 <normal> 2332 // f: 33 d2 xor %edx,%edx 2333 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 2334 // 15: 74 05 je 1c <done> 2335 // 0000000000000017 <normal>: 2336 // 17: 48 99 cqto 2337 // 19: 48 f7 f9 idiv $div 2338 // 000000000000001c <done>: 2339 2340 // mov $0x8000000000000000,%rdx 2341 emit_opcode(cbuf, Assembler::REX_W); 2342 emit_opcode(cbuf, 0xBA); 2343 emit_d8(cbuf, 0x00); 2344 emit_d8(cbuf, 0x00); 2345 emit_d8(cbuf, 0x00); 2346 emit_d8(cbuf, 0x00); 2347 emit_d8(cbuf, 0x00); 2348 emit_d8(cbuf, 0x00); 2349 emit_d8(cbuf, 0x00); 2350 emit_d8(cbuf, 0x80); 2351 2352 // cmp %rdx,%rax 2353 emit_opcode(cbuf, Assembler::REX_W); 2354 emit_opcode(cbuf, 0x39); 2355 emit_d8(cbuf, 0xD0); 2356 2357 // jne 17 <normal> 2358 emit_opcode(cbuf, 0x75); 2359 emit_d8(cbuf, 0x08); 2360 2361 // xor %edx,%edx 2362 emit_opcode(cbuf, 0x33); 2363 emit_d8(cbuf, 0xD2); 2364 2365 // cmp $0xffffffffffffffff,$div 2366 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 2367 emit_opcode(cbuf, 0x83); 2368 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2369 emit_d8(cbuf, 0xFF); 2370 2371 // je 1e <done> 2372 emit_opcode(cbuf, 0x74); 2373 emit_d8(cbuf, 0x05); 2374 2375 // <normal> 2376 // cqto 2377 emit_opcode(cbuf, Assembler::REX_W); 2378 emit_opcode(cbuf, 0x99); 2379 2380 // idivq (note: must be emitted by the user of this rule) 2381 // <done> 2382 %} 2383 2384 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2385 enc_class OpcSE(immI imm) 2386 %{ 2387 // Emit primary opcode and set sign-extend bit 2388 // Check for 8-bit immediate, and set sign extend bit in opcode 2389 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2390 emit_opcode(cbuf, $primary | 0x02); 2391 } else { 2392 // 32-bit immediate 2393 emit_opcode(cbuf, $primary); 2394 } 2395 %} 2396 2397 enc_class OpcSErm(rRegI dst, immI imm) 2398 %{ 2399 // OpcSEr/m 2400 int dstenc = $dst$$reg; 2401 if (dstenc >= 8) { 2402 emit_opcode(cbuf, Assembler::REX_B); 2403 dstenc -= 8; 2404 } 2405 // Emit primary opcode and set sign-extend bit 2406 // Check for 8-bit immediate, and set sign extend bit in opcode 2407 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2408 emit_opcode(cbuf, $primary | 0x02); 2409 } else { 2410 // 32-bit immediate 2411 emit_opcode(cbuf, $primary); 2412 } 2413 // Emit r/m byte with secondary opcode, after primary opcode. 2414 emit_rm(cbuf, 0x3, $secondary, dstenc); 2415 %} 2416 2417 enc_class OpcSErm_wide(rRegL dst, immI imm) 2418 %{ 2419 // OpcSEr/m 2420 int dstenc = $dst$$reg; 2421 if (dstenc < 8) { 2422 emit_opcode(cbuf, Assembler::REX_W); 2423 } else { 2424 emit_opcode(cbuf, Assembler::REX_WB); 2425 dstenc -= 8; 2426 } 2427 // Emit primary opcode and set sign-extend bit 2428 // Check for 8-bit immediate, and set sign extend bit in opcode 2429 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2430 emit_opcode(cbuf, $primary | 0x02); 2431 } else { 2432 // 32-bit immediate 2433 emit_opcode(cbuf, $primary); 2434 } 2435 // Emit r/m byte with secondary opcode, after primary opcode. 2436 emit_rm(cbuf, 0x3, $secondary, dstenc); 2437 %} 2438 2439 enc_class Con8or32(immI imm) 2440 %{ 2441 // Check for 8-bit immediate, and set sign extend bit in opcode 2442 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2443 $$$emit8$imm$$constant; 2444 } else { 2445 // 32-bit immediate 2446 $$$emit32$imm$$constant; 2447 } 2448 %} 2449 2450 enc_class opc2_reg(rRegI dst) 2451 %{ 2452 // BSWAP 2453 emit_cc(cbuf, $secondary, $dst$$reg); 2454 %} 2455 2456 enc_class opc3_reg(rRegI dst) 2457 %{ 2458 // BSWAP 2459 emit_cc(cbuf, $tertiary, $dst$$reg); 2460 %} 2461 2462 enc_class reg_opc(rRegI div) 2463 %{ 2464 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2465 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2466 %} 2467 2468 enc_class enc_cmov(cmpOp cop) 2469 %{ 2470 // CMOV 2471 $$$emit8$primary; 2472 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2473 %} 2474 2475 enc_class enc_cmovf_branch(cmpOp cop, regF dst, regF src) 2476 %{ 2477 // Invert sense of branch from sense of cmov 2478 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1); 2479 emit_d8(cbuf, ($dst$$reg < 8 && $src$$reg < 8) 2480 ? (UseXmmRegToRegMoveAll ? 3 : 4) 2481 : (UseXmmRegToRegMoveAll ? 4 : 5) ); // REX 2482 // UseXmmRegToRegMoveAll ? movaps(dst, src) : movss(dst, src) 2483 if (!UseXmmRegToRegMoveAll) emit_opcode(cbuf, 0xF3); 2484 if ($dst$$reg < 8) { 2485 if ($src$$reg >= 8) { 2486 emit_opcode(cbuf, Assembler::REX_B); 2487 } 2488 } else { 2489 if ($src$$reg < 8) { 2490 emit_opcode(cbuf, Assembler::REX_R); 2491 } else { 2492 emit_opcode(cbuf, Assembler::REX_RB); 2493 } 2494 } 2495 emit_opcode(cbuf, 0x0F); 2496 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 2497 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2498 %} 2499 2500 enc_class enc_cmovd_branch(cmpOp cop, regD dst, regD src) 2501 %{ 2502 // Invert sense of branch from sense of cmov 2503 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1); 2504 emit_d8(cbuf, $dst$$reg < 8 && $src$$reg < 8 ? 4 : 5); // REX 2505 2506 // UseXmmRegToRegMoveAll ? movapd(dst, src) : movsd(dst, src) 2507 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2); 2508 if ($dst$$reg < 8) { 2509 if ($src$$reg >= 8) { 2510 emit_opcode(cbuf, Assembler::REX_B); 2511 } 2512 } else { 2513 if ($src$$reg < 8) { 2514 emit_opcode(cbuf, Assembler::REX_R); 2515 } else { 2516 emit_opcode(cbuf, Assembler::REX_RB); 2517 } 2518 } 2519 emit_opcode(cbuf, 0x0F); 2520 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 2521 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2522 %} 2523 2524 enc_class enc_PartialSubtypeCheck() 2525 %{ 2526 Register Rrdi = as_Register(RDI_enc); // result register 2527 Register Rrax = as_Register(RAX_enc); // super class 2528 Register Rrcx = as_Register(RCX_enc); // killed 2529 Register Rrsi = as_Register(RSI_enc); // sub class 2530 Label miss; 2531 const bool set_cond_codes = true; 2532 2533 MacroAssembler _masm(&cbuf); 2534 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2535 NULL, &miss, 2536 /*set_cond_codes:*/ true); 2537 if ($primary) { 2538 __ xorptr(Rrdi, Rrdi); 2539 } 2540 __ bind(miss); 2541 %} 2542 2543 enc_class Java_To_Interpreter(method meth) 2544 %{ 2545 // CALL Java_To_Interpreter 2546 // This is the instruction starting address for relocation info. 2547 cbuf.set_insts_mark(); 2548 $$$emit8$primary; 2549 // CALL directly to the runtime 2550 emit_d32_reloc(cbuf, 2551 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2552 runtime_call_Relocation::spec(), 2553 RELOC_DISP32); 2554 %} 2555 2556 enc_class preserve_SP %{ 2557 debug_only(int off0 = cbuf.insts_size()); 2558 MacroAssembler _masm(&cbuf); 2559 // RBP is preserved across all calls, even compiled calls. 2560 // Use it to preserve RSP in places where the callee might change the SP. 2561 __ movptr(rbp_mh_SP_save, rsp); 2562 debug_only(int off1 = cbuf.insts_size()); 2563 assert(off1 - off0 == preserve_SP_size(), "correct size prediction"); 2564 %} 2565 2566 enc_class restore_SP %{ 2567 MacroAssembler _masm(&cbuf); 2568 __ movptr(rsp, rbp_mh_SP_save); 2569 %} 2570 2571 enc_class Java_Static_Call(method meth) 2572 %{ 2573 // JAVA STATIC CALL 2574 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2575 // determine who we intended to call. 2576 cbuf.set_insts_mark(); 2577 $$$emit8$primary; 2578 2579 if (!_method) { 2580 emit_d32_reloc(cbuf, 2581 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2582 runtime_call_Relocation::spec(), 2583 RELOC_DISP32); 2584 } else if (_optimized_virtual) { 2585 emit_d32_reloc(cbuf, 2586 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2587 opt_virtual_call_Relocation::spec(), 2588 RELOC_DISP32); 2589 } else { 2590 emit_d32_reloc(cbuf, 2591 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2592 static_call_Relocation::spec(), 2593 RELOC_DISP32); 2594 } 2595 if (_method) { 2596 // Emit stub for static call 2597 emit_java_to_interp(cbuf); 2598 } 2599 %} 2600 2601 enc_class Java_Dynamic_Call(method meth) 2602 %{ 2603 // JAVA DYNAMIC CALL 2604 // !!!!! 2605 // Generate "movq rax, -1", placeholder instruction to load oop-info 2606 // emit_call_dynamic_prologue( cbuf ); 2607 cbuf.set_insts_mark(); 2608 2609 // movq rax, -1 2610 emit_opcode(cbuf, Assembler::REX_W); 2611 emit_opcode(cbuf, 0xB8 | RAX_enc); 2612 emit_d64_reloc(cbuf, 2613 (int64_t) Universe::non_oop_word(), 2614 oop_Relocation::spec_for_immediate(), RELOC_IMM64); 2615 address virtual_call_oop_addr = cbuf.insts_mark(); 2616 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine 2617 // who we intended to call. 2618 cbuf.set_insts_mark(); 2619 $$$emit8$primary; 2620 emit_d32_reloc(cbuf, 2621 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2622 virtual_call_Relocation::spec(virtual_call_oop_addr), 2623 RELOC_DISP32); 2624 %} 2625 2626 enc_class Java_Compiled_Call(method meth) 2627 %{ 2628 // JAVA COMPILED CALL 2629 int disp = in_bytes(methodOopDesc:: from_compiled_offset()); 2630 2631 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2632 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2633 2634 // callq *disp(%rax) 2635 cbuf.set_insts_mark(); 2636 $$$emit8$primary; 2637 if (disp < 0x80) { 2638 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2639 emit_d8(cbuf, disp); // Displacement 2640 } else { 2641 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2642 emit_d32(cbuf, disp); // Displacement 2643 } 2644 %} 2645 2646 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2647 %{ 2648 // SAL, SAR, SHR 2649 int dstenc = $dst$$reg; 2650 if (dstenc >= 8) { 2651 emit_opcode(cbuf, Assembler::REX_B); 2652 dstenc -= 8; 2653 } 2654 $$$emit8$primary; 2655 emit_rm(cbuf, 0x3, $secondary, dstenc); 2656 $$$emit8$shift$$constant; 2657 %} 2658 2659 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2660 %{ 2661 // SAL, SAR, SHR 2662 int dstenc = $dst$$reg; 2663 if (dstenc < 8) { 2664 emit_opcode(cbuf, Assembler::REX_W); 2665 } else { 2666 emit_opcode(cbuf, Assembler::REX_WB); 2667 dstenc -= 8; 2668 } 2669 $$$emit8$primary; 2670 emit_rm(cbuf, 0x3, $secondary, dstenc); 2671 $$$emit8$shift$$constant; 2672 %} 2673 2674 enc_class load_immI(rRegI dst, immI src) 2675 %{ 2676 int dstenc = $dst$$reg; 2677 if (dstenc >= 8) { 2678 emit_opcode(cbuf, Assembler::REX_B); 2679 dstenc -= 8; 2680 } 2681 emit_opcode(cbuf, 0xB8 | dstenc); 2682 $$$emit32$src$$constant; 2683 %} 2684 2685 enc_class load_immL(rRegL dst, immL src) 2686 %{ 2687 int dstenc = $dst$$reg; 2688 if (dstenc < 8) { 2689 emit_opcode(cbuf, Assembler::REX_W); 2690 } else { 2691 emit_opcode(cbuf, Assembler::REX_WB); 2692 dstenc -= 8; 2693 } 2694 emit_opcode(cbuf, 0xB8 | dstenc); 2695 emit_d64(cbuf, $src$$constant); 2696 %} 2697 2698 enc_class load_immUL32(rRegL dst, immUL32 src) 2699 %{ 2700 // same as load_immI, but this time we care about zeroes in the high word 2701 int dstenc = $dst$$reg; 2702 if (dstenc >= 8) { 2703 emit_opcode(cbuf, Assembler::REX_B); 2704 dstenc -= 8; 2705 } 2706 emit_opcode(cbuf, 0xB8 | dstenc); 2707 $$$emit32$src$$constant; 2708 %} 2709 2710 enc_class load_immL32(rRegL dst, immL32 src) 2711 %{ 2712 int dstenc = $dst$$reg; 2713 if (dstenc < 8) { 2714 emit_opcode(cbuf, Assembler::REX_W); 2715 } else { 2716 emit_opcode(cbuf, Assembler::REX_WB); 2717 dstenc -= 8; 2718 } 2719 emit_opcode(cbuf, 0xC7); 2720 emit_rm(cbuf, 0x03, 0x00, dstenc); 2721 $$$emit32$src$$constant; 2722 %} 2723 2724 enc_class load_immP31(rRegP dst, immP32 src) 2725 %{ 2726 // same as load_immI, but this time we care about zeroes in the high word 2727 int dstenc = $dst$$reg; 2728 if (dstenc >= 8) { 2729 emit_opcode(cbuf, Assembler::REX_B); 2730 dstenc -= 8; 2731 } 2732 emit_opcode(cbuf, 0xB8 | dstenc); 2733 $$$emit32$src$$constant; 2734 %} 2735 2736 enc_class load_immP(rRegP dst, immP src) 2737 %{ 2738 int dstenc = $dst$$reg; 2739 if (dstenc < 8) { 2740 emit_opcode(cbuf, Assembler::REX_W); 2741 } else { 2742 emit_opcode(cbuf, Assembler::REX_WB); 2743 dstenc -= 8; 2744 } 2745 emit_opcode(cbuf, 0xB8 | dstenc); 2746 // This next line should be generated from ADLC 2747 if ($src->constant_is_oop()) { 2748 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64); 2749 } else { 2750 emit_d64(cbuf, $src$$constant); 2751 } 2752 %} 2753 2754 // Encode a reg-reg copy. If it is useless, then empty encoding. 2755 enc_class enc_copy(rRegI dst, rRegI src) 2756 %{ 2757 encode_copy(cbuf, $dst$$reg, $src$$reg); 2758 %} 2759 2760 // Encode xmm reg-reg copy. If it is useless, then empty encoding. 2761 enc_class enc_CopyXD( RegD dst, RegD src ) %{ 2762 encode_CopyXD( cbuf, $dst$$reg, $src$$reg ); 2763 %} 2764 2765 enc_class enc_copy_always(rRegI dst, rRegI src) 2766 %{ 2767 int srcenc = $src$$reg; 2768 int dstenc = $dst$$reg; 2769 2770 if (dstenc < 8) { 2771 if (srcenc >= 8) { 2772 emit_opcode(cbuf, Assembler::REX_B); 2773 srcenc -= 8; 2774 } 2775 } else { 2776 if (srcenc < 8) { 2777 emit_opcode(cbuf, Assembler::REX_R); 2778 } else { 2779 emit_opcode(cbuf, Assembler::REX_RB); 2780 srcenc -= 8; 2781 } 2782 dstenc -= 8; 2783 } 2784 2785 emit_opcode(cbuf, 0x8B); 2786 emit_rm(cbuf, 0x3, dstenc, srcenc); 2787 %} 2788 2789 enc_class enc_copy_wide(rRegL dst, rRegL src) 2790 %{ 2791 int srcenc = $src$$reg; 2792 int dstenc = $dst$$reg; 2793 2794 if (dstenc != srcenc) { 2795 if (dstenc < 8) { 2796 if (srcenc < 8) { 2797 emit_opcode(cbuf, Assembler::REX_W); 2798 } else { 2799 emit_opcode(cbuf, Assembler::REX_WB); 2800 srcenc -= 8; 2801 } 2802 } else { 2803 if (srcenc < 8) { 2804 emit_opcode(cbuf, Assembler::REX_WR); 2805 } else { 2806 emit_opcode(cbuf, Assembler::REX_WRB); 2807 srcenc -= 8; 2808 } 2809 dstenc -= 8; 2810 } 2811 emit_opcode(cbuf, 0x8B); 2812 emit_rm(cbuf, 0x3, dstenc, srcenc); 2813 } 2814 %} 2815 2816 enc_class Con32(immI src) 2817 %{ 2818 // Output immediate 2819 $$$emit32$src$$constant; 2820 %} 2821 2822 enc_class Con64(immL src) 2823 %{ 2824 // Output immediate 2825 emit_d64($src$$constant); 2826 %} 2827 2828 enc_class Con32F_as_bits(immF src) 2829 %{ 2830 // Output Float immediate bits 2831 jfloat jf = $src$$constant; 2832 jint jf_as_bits = jint_cast(jf); 2833 emit_d32(cbuf, jf_as_bits); 2834 %} 2835 2836 enc_class Con16(immI src) 2837 %{ 2838 // Output immediate 2839 $$$emit16$src$$constant; 2840 %} 2841 2842 // How is this different from Con32??? XXX 2843 enc_class Con_d32(immI src) 2844 %{ 2845 emit_d32(cbuf,$src$$constant); 2846 %} 2847 2848 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2849 // Output immediate memory reference 2850 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2851 emit_d32(cbuf, 0x00); 2852 %} 2853 2854 enc_class lock_prefix() 2855 %{ 2856 if (os::is_MP()) { 2857 emit_opcode(cbuf, 0xF0); // lock 2858 } 2859 %} 2860 2861 enc_class REX_mem(memory mem) 2862 %{ 2863 if ($mem$$base >= 8) { 2864 if ($mem$$index < 8) { 2865 emit_opcode(cbuf, Assembler::REX_B); 2866 } else { 2867 emit_opcode(cbuf, Assembler::REX_XB); 2868 } 2869 } else { 2870 if ($mem$$index >= 8) { 2871 emit_opcode(cbuf, Assembler::REX_X); 2872 } 2873 } 2874 %} 2875 2876 enc_class REX_mem_wide(memory mem) 2877 %{ 2878 if ($mem$$base >= 8) { 2879 if ($mem$$index < 8) { 2880 emit_opcode(cbuf, Assembler::REX_WB); 2881 } else { 2882 emit_opcode(cbuf, Assembler::REX_WXB); 2883 } 2884 } else { 2885 if ($mem$$index < 8) { 2886 emit_opcode(cbuf, Assembler::REX_W); 2887 } else { 2888 emit_opcode(cbuf, Assembler::REX_WX); 2889 } 2890 } 2891 %} 2892 2893 // for byte regs 2894 enc_class REX_breg(rRegI reg) 2895 %{ 2896 if ($reg$$reg >= 4) { 2897 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2898 } 2899 %} 2900 2901 // for byte regs 2902 enc_class REX_reg_breg(rRegI dst, rRegI src) 2903 %{ 2904 if ($dst$$reg < 8) { 2905 if ($src$$reg >= 4) { 2906 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2907 } 2908 } else { 2909 if ($src$$reg < 8) { 2910 emit_opcode(cbuf, Assembler::REX_R); 2911 } else { 2912 emit_opcode(cbuf, Assembler::REX_RB); 2913 } 2914 } 2915 %} 2916 2917 // for byte regs 2918 enc_class REX_breg_mem(rRegI reg, memory mem) 2919 %{ 2920 if ($reg$$reg < 8) { 2921 if ($mem$$base < 8) { 2922 if ($mem$$index >= 8) { 2923 emit_opcode(cbuf, Assembler::REX_X); 2924 } else if ($reg$$reg >= 4) { 2925 emit_opcode(cbuf, Assembler::REX); 2926 } 2927 } else { 2928 if ($mem$$index < 8) { 2929 emit_opcode(cbuf, Assembler::REX_B); 2930 } else { 2931 emit_opcode(cbuf, Assembler::REX_XB); 2932 } 2933 } 2934 } else { 2935 if ($mem$$base < 8) { 2936 if ($mem$$index < 8) { 2937 emit_opcode(cbuf, Assembler::REX_R); 2938 } else { 2939 emit_opcode(cbuf, Assembler::REX_RX); 2940 } 2941 } else { 2942 if ($mem$$index < 8) { 2943 emit_opcode(cbuf, Assembler::REX_RB); 2944 } else { 2945 emit_opcode(cbuf, Assembler::REX_RXB); 2946 } 2947 } 2948 } 2949 %} 2950 2951 enc_class REX_reg(rRegI reg) 2952 %{ 2953 if ($reg$$reg >= 8) { 2954 emit_opcode(cbuf, Assembler::REX_B); 2955 } 2956 %} 2957 2958 enc_class REX_reg_wide(rRegI reg) 2959 %{ 2960 if ($reg$$reg < 8) { 2961 emit_opcode(cbuf, Assembler::REX_W); 2962 } else { 2963 emit_opcode(cbuf, Assembler::REX_WB); 2964 } 2965 %} 2966 2967 enc_class REX_reg_reg(rRegI dst, rRegI src) 2968 %{ 2969 if ($dst$$reg < 8) { 2970 if ($src$$reg >= 8) { 2971 emit_opcode(cbuf, Assembler::REX_B); 2972 } 2973 } else { 2974 if ($src$$reg < 8) { 2975 emit_opcode(cbuf, Assembler::REX_R); 2976 } else { 2977 emit_opcode(cbuf, Assembler::REX_RB); 2978 } 2979 } 2980 %} 2981 2982 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2983 %{ 2984 if ($dst$$reg < 8) { 2985 if ($src$$reg < 8) { 2986 emit_opcode(cbuf, Assembler::REX_W); 2987 } else { 2988 emit_opcode(cbuf, Assembler::REX_WB); 2989 } 2990 } else { 2991 if ($src$$reg < 8) { 2992 emit_opcode(cbuf, Assembler::REX_WR); 2993 } else { 2994 emit_opcode(cbuf, Assembler::REX_WRB); 2995 } 2996 } 2997 %} 2998 2999 enc_class REX_reg_mem(rRegI reg, memory mem) 3000 %{ 3001 if ($reg$$reg < 8) { 3002 if ($mem$$base < 8) { 3003 if ($mem$$index >= 8) { 3004 emit_opcode(cbuf, Assembler::REX_X); 3005 } 3006 } else { 3007 if ($mem$$index < 8) { 3008 emit_opcode(cbuf, Assembler::REX_B); 3009 } else { 3010 emit_opcode(cbuf, Assembler::REX_XB); 3011 } 3012 } 3013 } else { 3014 if ($mem$$base < 8) { 3015 if ($mem$$index < 8) { 3016 emit_opcode(cbuf, Assembler::REX_R); 3017 } else { 3018 emit_opcode(cbuf, Assembler::REX_RX); 3019 } 3020 } else { 3021 if ($mem$$index < 8) { 3022 emit_opcode(cbuf, Assembler::REX_RB); 3023 } else { 3024 emit_opcode(cbuf, Assembler::REX_RXB); 3025 } 3026 } 3027 } 3028 %} 3029 3030 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 3031 %{ 3032 if ($reg$$reg < 8) { 3033 if ($mem$$base < 8) { 3034 if ($mem$$index < 8) { 3035 emit_opcode(cbuf, Assembler::REX_W); 3036 } else { 3037 emit_opcode(cbuf, Assembler::REX_WX); 3038 } 3039 } else { 3040 if ($mem$$index < 8) { 3041 emit_opcode(cbuf, Assembler::REX_WB); 3042 } else { 3043 emit_opcode(cbuf, Assembler::REX_WXB); 3044 } 3045 } 3046 } else { 3047 if ($mem$$base < 8) { 3048 if ($mem$$index < 8) { 3049 emit_opcode(cbuf, Assembler::REX_WR); 3050 } else { 3051 emit_opcode(cbuf, Assembler::REX_WRX); 3052 } 3053 } else { 3054 if ($mem$$index < 8) { 3055 emit_opcode(cbuf, Assembler::REX_WRB); 3056 } else { 3057 emit_opcode(cbuf, Assembler::REX_WRXB); 3058 } 3059 } 3060 } 3061 %} 3062 3063 enc_class reg_mem(rRegI ereg, memory mem) 3064 %{ 3065 // High registers handle in encode_RegMem 3066 int reg = $ereg$$reg; 3067 int base = $mem$$base; 3068 int index = $mem$$index; 3069 int scale = $mem$$scale; 3070 int disp = $mem$$disp; 3071 bool disp_is_oop = $mem->disp_is_oop(); 3072 3073 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_is_oop); 3074 %} 3075 3076 enc_class RM_opc_mem(immI rm_opcode, memory mem) 3077 %{ 3078 int rm_byte_opcode = $rm_opcode$$constant; 3079 3080 // High registers handle in encode_RegMem 3081 int base = $mem$$base; 3082 int index = $mem$$index; 3083 int scale = $mem$$scale; 3084 int displace = $mem$$disp; 3085 3086 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when 3087 // working with static 3088 // globals 3089 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 3090 disp_is_oop); 3091 %} 3092 3093 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 3094 %{ 3095 int reg_encoding = $dst$$reg; 3096 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 3097 int index = 0x04; // 0x04 indicates no index 3098 int scale = 0x00; // 0x00 indicates no scale 3099 int displace = $src1$$constant; // 0x00 indicates no displacement 3100 bool disp_is_oop = false; 3101 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 3102 disp_is_oop); 3103 %} 3104 3105 enc_class neg_reg(rRegI dst) 3106 %{ 3107 int dstenc = $dst$$reg; 3108 if (dstenc >= 8) { 3109 emit_opcode(cbuf, Assembler::REX_B); 3110 dstenc -= 8; 3111 } 3112 // NEG $dst 3113 emit_opcode(cbuf, 0xF7); 3114 emit_rm(cbuf, 0x3, 0x03, dstenc); 3115 %} 3116 3117 enc_class neg_reg_wide(rRegI dst) 3118 %{ 3119 int dstenc = $dst$$reg; 3120 if (dstenc < 8) { 3121 emit_opcode(cbuf, Assembler::REX_W); 3122 } else { 3123 emit_opcode(cbuf, Assembler::REX_WB); 3124 dstenc -= 8; 3125 } 3126 // NEG $dst 3127 emit_opcode(cbuf, 0xF7); 3128 emit_rm(cbuf, 0x3, 0x03, dstenc); 3129 %} 3130 3131 enc_class setLT_reg(rRegI dst) 3132 %{ 3133 int dstenc = $dst$$reg; 3134 if (dstenc >= 8) { 3135 emit_opcode(cbuf, Assembler::REX_B); 3136 dstenc -= 8; 3137 } else if (dstenc >= 4) { 3138 emit_opcode(cbuf, Assembler::REX); 3139 } 3140 // SETLT $dst 3141 emit_opcode(cbuf, 0x0F); 3142 emit_opcode(cbuf, 0x9C); 3143 emit_rm(cbuf, 0x3, 0x0, dstenc); 3144 %} 3145 3146 enc_class setNZ_reg(rRegI dst) 3147 %{ 3148 int dstenc = $dst$$reg; 3149 if (dstenc >= 8) { 3150 emit_opcode(cbuf, Assembler::REX_B); 3151 dstenc -= 8; 3152 } else if (dstenc >= 4) { 3153 emit_opcode(cbuf, Assembler::REX); 3154 } 3155 // SETNZ $dst 3156 emit_opcode(cbuf, 0x0F); 3157 emit_opcode(cbuf, 0x95); 3158 emit_rm(cbuf, 0x3, 0x0, dstenc); 3159 %} 3160 3161 3162 // Compare the lonogs and set -1, 0, or 1 into dst 3163 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 3164 %{ 3165 int src1enc = $src1$$reg; 3166 int src2enc = $src2$$reg; 3167 int dstenc = $dst$$reg; 3168 3169 // cmpq $src1, $src2 3170 if (src1enc < 8) { 3171 if (src2enc < 8) { 3172 emit_opcode(cbuf, Assembler::REX_W); 3173 } else { 3174 emit_opcode(cbuf, Assembler::REX_WB); 3175 } 3176 } else { 3177 if (src2enc < 8) { 3178 emit_opcode(cbuf, Assembler::REX_WR); 3179 } else { 3180 emit_opcode(cbuf, Assembler::REX_WRB); 3181 } 3182 } 3183 emit_opcode(cbuf, 0x3B); 3184 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 3185 3186 // movl $dst, -1 3187 if (dstenc >= 8) { 3188 emit_opcode(cbuf, Assembler::REX_B); 3189 } 3190 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 3191 emit_d32(cbuf, -1); 3192 3193 // jl,s done 3194 emit_opcode(cbuf, 0x7C); 3195 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 3196 3197 // setne $dst 3198 if (dstenc >= 4) { 3199 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 3200 } 3201 emit_opcode(cbuf, 0x0F); 3202 emit_opcode(cbuf, 0x95); 3203 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 3204 3205 // movzbl $dst, $dst 3206 if (dstenc >= 4) { 3207 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 3208 } 3209 emit_opcode(cbuf, 0x0F); 3210 emit_opcode(cbuf, 0xB6); 3211 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 3212 %} 3213 3214 enc_class Push_ResultXD(regD dst) %{ 3215 int dstenc = $dst$$reg; 3216 3217 store_to_stackslot( cbuf, 0xDD, 0x03, 0 ); //FSTP [RSP] 3218 3219 // UseXmmLoadAndClearUpper ? movsd dst,[rsp] : movlpd dst,[rsp] 3220 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 3221 if (dstenc >= 8) { 3222 emit_opcode(cbuf, Assembler::REX_R); 3223 } 3224 emit_opcode (cbuf, 0x0F ); 3225 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12 ); 3226 encode_RegMem(cbuf, dstenc, RSP_enc, 0x4, 0, 0, false); 3227 3228 // add rsp,8 3229 emit_opcode(cbuf, Assembler::REX_W); 3230 emit_opcode(cbuf,0x83); 3231 emit_rm(cbuf,0x3, 0x0, RSP_enc); 3232 emit_d8(cbuf,0x08); 3233 %} 3234 3235 enc_class Push_SrcXD(regD src) %{ 3236 int srcenc = $src$$reg; 3237 3238 // subq rsp,#8 3239 emit_opcode(cbuf, Assembler::REX_W); 3240 emit_opcode(cbuf, 0x83); 3241 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3242 emit_d8(cbuf, 0x8); 3243 3244 // movsd [rsp],src 3245 emit_opcode(cbuf, 0xF2); 3246 if (srcenc >= 8) { 3247 emit_opcode(cbuf, Assembler::REX_R); 3248 } 3249 emit_opcode(cbuf, 0x0F); 3250 emit_opcode(cbuf, 0x11); 3251 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); 3252 3253 // fldd [rsp] 3254 emit_opcode(cbuf, 0x66); 3255 emit_opcode(cbuf, 0xDD); 3256 encode_RegMem(cbuf, 0x0, RSP_enc, 0x4, 0, 0, false); 3257 %} 3258 3259 3260 enc_class movq_ld(regD dst, memory mem) %{ 3261 MacroAssembler _masm(&cbuf); 3262 __ movq($dst$$XMMRegister, $mem$$Address); 3263 %} 3264 3265 enc_class movq_st(memory mem, regD src) %{ 3266 MacroAssembler _masm(&cbuf); 3267 __ movq($mem$$Address, $src$$XMMRegister); 3268 %} 3269 3270 enc_class pshufd_8x8(regF dst, regF src) %{ 3271 MacroAssembler _masm(&cbuf); 3272 3273 encode_CopyXD(cbuf, $dst$$reg, $src$$reg); 3274 __ punpcklbw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg)); 3275 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg), 0x00); 3276 %} 3277 3278 enc_class pshufd_4x16(regF dst, regF src) %{ 3279 MacroAssembler _masm(&cbuf); 3280 3281 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), 0x00); 3282 %} 3283 3284 enc_class pshufd(regD dst, regD src, int mode) %{ 3285 MacroAssembler _masm(&cbuf); 3286 3287 __ pshufd(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), $mode); 3288 %} 3289 3290 enc_class pxor(regD dst, regD src) %{ 3291 MacroAssembler _masm(&cbuf); 3292 3293 __ pxor(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg)); 3294 %} 3295 3296 enc_class mov_i2x(regD dst, rRegI src) %{ 3297 MacroAssembler _masm(&cbuf); 3298 3299 __ movdl(as_XMMRegister($dst$$reg), as_Register($src$$reg)); 3300 %} 3301 3302 // obj: object to lock 3303 // box: box address (header location) -- killed 3304 // tmp: rax -- killed 3305 // scr: rbx -- killed 3306 // 3307 // What follows is a direct transliteration of fast_lock() and fast_unlock() 3308 // from i486.ad. See that file for comments. 3309 // TODO: where possible switch from movq (r, 0) to movl(r,0) and 3310 // use the shorter encoding. (Movl clears the high-order 32-bits). 3311 3312 3313 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr) 3314 %{ 3315 Register objReg = as_Register((int)$obj$$reg); 3316 Register boxReg = as_Register((int)$box$$reg); 3317 Register tmpReg = as_Register($tmp$$reg); 3318 Register scrReg = as_Register($scr$$reg); 3319 MacroAssembler masm(&cbuf); 3320 3321 // Verify uniqueness of register assignments -- necessary but not sufficient 3322 assert (objReg != boxReg && objReg != tmpReg && 3323 objReg != scrReg && tmpReg != scrReg, "invariant") ; 3324 3325 if (_counters != NULL) { 3326 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 3327 } 3328 if (EmitSync & 1) { 3329 // Without cast to int32_t a movptr will destroy r10 which is typically obj 3330 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 3331 masm.cmpptr(rsp, (int32_t)NULL_WORD) ; 3332 } else 3333 if (EmitSync & 2) { 3334 Label DONE_LABEL; 3335 if (UseBiasedLocking) { 3336 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 3337 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 3338 } 3339 // QQQ was movl... 3340 masm.movptr(tmpReg, 0x1); 3341 masm.orptr(tmpReg, Address(objReg, 0)); 3342 masm.movptr(Address(boxReg, 0), tmpReg); 3343 if (os::is_MP()) { 3344 masm.lock(); 3345 } 3346 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3347 masm.jcc(Assembler::equal, DONE_LABEL); 3348 3349 // Recursive locking 3350 masm.subptr(tmpReg, rsp); 3351 masm.andptr(tmpReg, 7 - os::vm_page_size()); 3352 masm.movptr(Address(boxReg, 0), tmpReg); 3353 3354 masm.bind(DONE_LABEL); 3355 masm.nop(); // avoid branch to branch 3356 } else { 3357 Label DONE_LABEL, IsInflated, Egress; 3358 3359 masm.movptr(tmpReg, Address(objReg, 0)) ; 3360 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased 3361 masm.jcc (Assembler::notZero, IsInflated) ; 3362 3363 // it's stack-locked, biased or neutral 3364 // TODO: optimize markword triage order to reduce the number of 3365 // conditional branches in the most common cases. 3366 // Beware -- there's a subtle invariant that fetch of the markword 3367 // at [FETCH], below, will never observe a biased encoding (*101b). 3368 // If this invariant is not held we'll suffer exclusion (safety) failure. 3369 3370 if (UseBiasedLocking && !UseOptoBiasInlining) { 3371 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); 3372 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 3373 } 3374 3375 // was q will it destroy high? 3376 masm.orl (tmpReg, 1) ; 3377 masm.movptr(Address(boxReg, 0), tmpReg) ; 3378 if (os::is_MP()) { masm.lock(); } 3379 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3380 if (_counters != NULL) { 3381 masm.cond_inc32(Assembler::equal, 3382 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 3383 } 3384 masm.jcc (Assembler::equal, DONE_LABEL); 3385 3386 // Recursive locking 3387 masm.subptr(tmpReg, rsp); 3388 masm.andptr(tmpReg, 7 - os::vm_page_size()); 3389 masm.movptr(Address(boxReg, 0), tmpReg); 3390 if (_counters != NULL) { 3391 masm.cond_inc32(Assembler::equal, 3392 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 3393 } 3394 masm.jmp (DONE_LABEL) ; 3395 3396 masm.bind (IsInflated) ; 3397 // It's inflated 3398 3399 // TODO: someday avoid the ST-before-CAS penalty by 3400 // relocating (deferring) the following ST. 3401 // We should also think about trying a CAS without having 3402 // fetched _owner. If the CAS is successful we may 3403 // avoid an RTO->RTS upgrade on the $line. 3404 // Without cast to int32_t a movptr will destroy r10 which is typically obj 3405 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 3406 3407 masm.mov (boxReg, tmpReg) ; 3408 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3409 masm.testptr(tmpReg, tmpReg) ; 3410 masm.jcc (Assembler::notZero, DONE_LABEL) ; 3411 3412 // It's inflated and appears unlocked 3413 if (os::is_MP()) { masm.lock(); } 3414 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3415 // Intentional fall-through into DONE_LABEL ... 3416 3417 masm.bind (DONE_LABEL) ; 3418 masm.nop () ; // avoid jmp to jmp 3419 } 3420 %} 3421 3422 // obj: object to unlock 3423 // box: box address (displaced header location), killed 3424 // RBX: killed tmp; cannot be obj nor box 3425 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp) 3426 %{ 3427 3428 Register objReg = as_Register($obj$$reg); 3429 Register boxReg = as_Register($box$$reg); 3430 Register tmpReg = as_Register($tmp$$reg); 3431 MacroAssembler masm(&cbuf); 3432 3433 if (EmitSync & 4) { 3434 masm.cmpptr(rsp, 0) ; 3435 } else 3436 if (EmitSync & 8) { 3437 Label DONE_LABEL; 3438 if (UseBiasedLocking) { 3439 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3440 } 3441 3442 // Check whether the displaced header is 0 3443 //(=> recursive unlock) 3444 masm.movptr(tmpReg, Address(boxReg, 0)); 3445 masm.testptr(tmpReg, tmpReg); 3446 masm.jcc(Assembler::zero, DONE_LABEL); 3447 3448 // If not recursive lock, reset the header to displaced header 3449 if (os::is_MP()) { 3450 masm.lock(); 3451 } 3452 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3453 masm.bind(DONE_LABEL); 3454 masm.nop(); // avoid branch to branch 3455 } else { 3456 Label DONE_LABEL, Stacked, CheckSucc ; 3457 3458 if (UseBiasedLocking && !UseOptoBiasInlining) { 3459 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3460 } 3461 3462 masm.movptr(tmpReg, Address(objReg, 0)) ; 3463 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; 3464 masm.jcc (Assembler::zero, DONE_LABEL) ; 3465 masm.testl (tmpReg, 0x02) ; 3466 masm.jcc (Assembler::zero, Stacked) ; 3467 3468 // It's inflated 3469 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3470 masm.xorptr(boxReg, r15_thread) ; 3471 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 3472 masm.jcc (Assembler::notZero, DONE_LABEL) ; 3473 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 3474 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 3475 masm.jcc (Assembler::notZero, CheckSucc) ; 3476 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3477 masm.jmp (DONE_LABEL) ; 3478 3479 if ((EmitSync & 65536) == 0) { 3480 Label LSuccess, LGoSlowPath ; 3481 masm.bind (CheckSucc) ; 3482 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3483 masm.jcc (Assembler::zero, LGoSlowPath) ; 3484 3485 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the 3486 // the explicit ST;MEMBAR combination, but masm doesn't currently support 3487 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc 3488 // are all faster when the write buffer is populated. 3489 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3490 if (os::is_MP()) { 3491 masm.lock () ; masm.addl (Address(rsp, 0), 0) ; 3492 } 3493 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3494 masm.jcc (Assembler::notZero, LSuccess) ; 3495 3496 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX 3497 if (os::is_MP()) { masm.lock(); } 3498 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3499 masm.jcc (Assembler::notEqual, LSuccess) ; 3500 // Intentional fall-through into slow-path 3501 3502 masm.bind (LGoSlowPath) ; 3503 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure 3504 masm.jmp (DONE_LABEL) ; 3505 3506 masm.bind (LSuccess) ; 3507 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success 3508 masm.jmp (DONE_LABEL) ; 3509 } 3510 3511 masm.bind (Stacked) ; 3512 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch 3513 if (os::is_MP()) { masm.lock(); } 3514 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3515 3516 if (EmitSync & 65536) { 3517 masm.bind (CheckSucc) ; 3518 } 3519 masm.bind(DONE_LABEL); 3520 if (EmitSync & 32768) { 3521 masm.nop(); // avoid branch to branch 3522 } 3523 } 3524 %} 3525 3526 3527 enc_class enc_rethrow() 3528 %{ 3529 cbuf.set_insts_mark(); 3530 emit_opcode(cbuf, 0xE9); // jmp entry 3531 emit_d32_reloc(cbuf, 3532 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 3533 runtime_call_Relocation::spec(), 3534 RELOC_DISP32); 3535 %} 3536 3537 enc_class absF_encoding(regF dst) 3538 %{ 3539 int dstenc = $dst$$reg; 3540 address signmask_address = (address) StubRoutines::x86::float_sign_mask(); 3541 3542 cbuf.set_insts_mark(); 3543 if (dstenc >= 8) { 3544 emit_opcode(cbuf, Assembler::REX_R); 3545 dstenc -= 8; 3546 } 3547 // XXX reg_mem doesn't support RIP-relative addressing yet 3548 emit_opcode(cbuf, 0x0F); 3549 emit_opcode(cbuf, 0x54); 3550 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3551 emit_d32_reloc(cbuf, signmask_address); 3552 %} 3553 3554 enc_class absD_encoding(regD dst) 3555 %{ 3556 int dstenc = $dst$$reg; 3557 address signmask_address = (address) StubRoutines::x86::double_sign_mask(); 3558 3559 cbuf.set_insts_mark(); 3560 emit_opcode(cbuf, 0x66); 3561 if (dstenc >= 8) { 3562 emit_opcode(cbuf, Assembler::REX_R); 3563 dstenc -= 8; 3564 } 3565 // XXX reg_mem doesn't support RIP-relative addressing yet 3566 emit_opcode(cbuf, 0x0F); 3567 emit_opcode(cbuf, 0x54); 3568 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3569 emit_d32_reloc(cbuf, signmask_address); 3570 %} 3571 3572 enc_class negF_encoding(regF dst) 3573 %{ 3574 int dstenc = $dst$$reg; 3575 address signflip_address = (address) StubRoutines::x86::float_sign_flip(); 3576 3577 cbuf.set_insts_mark(); 3578 if (dstenc >= 8) { 3579 emit_opcode(cbuf, Assembler::REX_R); 3580 dstenc -= 8; 3581 } 3582 // XXX reg_mem doesn't support RIP-relative addressing yet 3583 emit_opcode(cbuf, 0x0F); 3584 emit_opcode(cbuf, 0x57); 3585 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3586 emit_d32_reloc(cbuf, signflip_address); 3587 %} 3588 3589 enc_class negD_encoding(regD dst) 3590 %{ 3591 int dstenc = $dst$$reg; 3592 address signflip_address = (address) StubRoutines::x86::double_sign_flip(); 3593 3594 cbuf.set_insts_mark(); 3595 emit_opcode(cbuf, 0x66); 3596 if (dstenc >= 8) { 3597 emit_opcode(cbuf, Assembler::REX_R); 3598 dstenc -= 8; 3599 } 3600 // XXX reg_mem doesn't support RIP-relative addressing yet 3601 emit_opcode(cbuf, 0x0F); 3602 emit_opcode(cbuf, 0x57); 3603 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3604 emit_d32_reloc(cbuf, signflip_address); 3605 %} 3606 3607 enc_class f2i_fixup(rRegI dst, regF src) 3608 %{ 3609 int dstenc = $dst$$reg; 3610 int srcenc = $src$$reg; 3611 3612 // cmpl $dst, #0x80000000 3613 if (dstenc >= 8) { 3614 emit_opcode(cbuf, Assembler::REX_B); 3615 } 3616 emit_opcode(cbuf, 0x81); 3617 emit_rm(cbuf, 0x3, 0x7, dstenc & 7); 3618 emit_d32(cbuf, 0x80000000); 3619 3620 // jne,s done 3621 emit_opcode(cbuf, 0x75); 3622 if (srcenc < 8 && dstenc < 8) { 3623 emit_d8(cbuf, 0xF); 3624 } else if (srcenc >= 8 && dstenc >= 8) { 3625 emit_d8(cbuf, 0x11); 3626 } else { 3627 emit_d8(cbuf, 0x10); 3628 } 3629 3630 // subq rsp, #8 3631 emit_opcode(cbuf, Assembler::REX_W); 3632 emit_opcode(cbuf, 0x83); 3633 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3634 emit_d8(cbuf, 8); 3635 3636 // movss [rsp], $src 3637 emit_opcode(cbuf, 0xF3); 3638 if (srcenc >= 8) { 3639 emit_opcode(cbuf, Assembler::REX_R); 3640 } 3641 emit_opcode(cbuf, 0x0F); 3642 emit_opcode(cbuf, 0x11); 3643 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 3644 3645 // call f2i_fixup 3646 cbuf.set_insts_mark(); 3647 emit_opcode(cbuf, 0xE8); 3648 emit_d32_reloc(cbuf, 3649 (int) 3650 (StubRoutines::x86::f2i_fixup() - cbuf.insts_end() - 4), 3651 runtime_call_Relocation::spec(), 3652 RELOC_DISP32); 3653 3654 // popq $dst 3655 if (dstenc >= 8) { 3656 emit_opcode(cbuf, Assembler::REX_B); 3657 } 3658 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 3659 3660 // done: 3661 %} 3662 3663 enc_class f2l_fixup(rRegL dst, regF src) 3664 %{ 3665 int dstenc = $dst$$reg; 3666 int srcenc = $src$$reg; 3667 address const_address = (address) StubRoutines::x86::double_sign_flip(); 3668 3669 // cmpq $dst, [0x8000000000000000] 3670 cbuf.set_insts_mark(); 3671 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR); 3672 emit_opcode(cbuf, 0x39); 3673 // XXX reg_mem doesn't support RIP-relative addressing yet 3674 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101 3675 emit_d32_reloc(cbuf, const_address); 3676 3677 3678 // jne,s done 3679 emit_opcode(cbuf, 0x75); 3680 if (srcenc < 8 && dstenc < 8) { 3681 emit_d8(cbuf, 0xF); 3682 } else if (srcenc >= 8 && dstenc >= 8) { 3683 emit_d8(cbuf, 0x11); 3684 } else { 3685 emit_d8(cbuf, 0x10); 3686 } 3687 3688 // subq rsp, #8 3689 emit_opcode(cbuf, Assembler::REX_W); 3690 emit_opcode(cbuf, 0x83); 3691 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3692 emit_d8(cbuf, 8); 3693 3694 // movss [rsp], $src 3695 emit_opcode(cbuf, 0xF3); 3696 if (srcenc >= 8) { 3697 emit_opcode(cbuf, Assembler::REX_R); 3698 } 3699 emit_opcode(cbuf, 0x0F); 3700 emit_opcode(cbuf, 0x11); 3701 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 3702 3703 // call f2l_fixup 3704 cbuf.set_insts_mark(); 3705 emit_opcode(cbuf, 0xE8); 3706 emit_d32_reloc(cbuf, 3707 (int) 3708 (StubRoutines::x86::f2l_fixup() - cbuf.insts_end() - 4), 3709 runtime_call_Relocation::spec(), 3710 RELOC_DISP32); 3711 3712 // popq $dst 3713 if (dstenc >= 8) { 3714 emit_opcode(cbuf, Assembler::REX_B); 3715 } 3716 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 3717 3718 // done: 3719 %} 3720 3721 enc_class d2i_fixup(rRegI dst, regD src) 3722 %{ 3723 int dstenc = $dst$$reg; 3724 int srcenc = $src$$reg; 3725 3726 // cmpl $dst, #0x80000000 3727 if (dstenc >= 8) { 3728 emit_opcode(cbuf, Assembler::REX_B); 3729 } 3730 emit_opcode(cbuf, 0x81); 3731 emit_rm(cbuf, 0x3, 0x7, dstenc & 7); 3732 emit_d32(cbuf, 0x80000000); 3733 3734 // jne,s done 3735 emit_opcode(cbuf, 0x75); 3736 if (srcenc < 8 && dstenc < 8) { 3737 emit_d8(cbuf, 0xF); 3738 } else if (srcenc >= 8 && dstenc >= 8) { 3739 emit_d8(cbuf, 0x11); 3740 } else { 3741 emit_d8(cbuf, 0x10); 3742 } 3743 3744 // subq rsp, #8 3745 emit_opcode(cbuf, Assembler::REX_W); 3746 emit_opcode(cbuf, 0x83); 3747 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3748 emit_d8(cbuf, 8); 3749 3750 // movsd [rsp], $src 3751 emit_opcode(cbuf, 0xF2); 3752 if (srcenc >= 8) { 3753 emit_opcode(cbuf, Assembler::REX_R); 3754 } 3755 emit_opcode(cbuf, 0x0F); 3756 emit_opcode(cbuf, 0x11); 3757 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 3758 3759 // call d2i_fixup 3760 cbuf.set_insts_mark(); 3761 emit_opcode(cbuf, 0xE8); 3762 emit_d32_reloc(cbuf, 3763 (int) 3764 (StubRoutines::x86::d2i_fixup() - cbuf.insts_end() - 4), 3765 runtime_call_Relocation::spec(), 3766 RELOC_DISP32); 3767 3768 // popq $dst 3769 if (dstenc >= 8) { 3770 emit_opcode(cbuf, Assembler::REX_B); 3771 } 3772 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 3773 3774 // done: 3775 %} 3776 3777 enc_class d2l_fixup(rRegL dst, regD src) 3778 %{ 3779 int dstenc = $dst$$reg; 3780 int srcenc = $src$$reg; 3781 address const_address = (address) StubRoutines::x86::double_sign_flip(); 3782 3783 // cmpq $dst, [0x8000000000000000] 3784 cbuf.set_insts_mark(); 3785 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR); 3786 emit_opcode(cbuf, 0x39); 3787 // XXX reg_mem doesn't support RIP-relative addressing yet 3788 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101 3789 emit_d32_reloc(cbuf, const_address); 3790 3791 3792 // jne,s done 3793 emit_opcode(cbuf, 0x75); 3794 if (srcenc < 8 && dstenc < 8) { 3795 emit_d8(cbuf, 0xF); 3796 } else if (srcenc >= 8 && dstenc >= 8) { 3797 emit_d8(cbuf, 0x11); 3798 } else { 3799 emit_d8(cbuf, 0x10); 3800 } 3801 3802 // subq rsp, #8 3803 emit_opcode(cbuf, Assembler::REX_W); 3804 emit_opcode(cbuf, 0x83); 3805 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3806 emit_d8(cbuf, 8); 3807 3808 // movsd [rsp], $src 3809 emit_opcode(cbuf, 0xF2); 3810 if (srcenc >= 8) { 3811 emit_opcode(cbuf, Assembler::REX_R); 3812 } 3813 emit_opcode(cbuf, 0x0F); 3814 emit_opcode(cbuf, 0x11); 3815 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 3816 3817 // call d2l_fixup 3818 cbuf.set_insts_mark(); 3819 emit_opcode(cbuf, 0xE8); 3820 emit_d32_reloc(cbuf, 3821 (int) 3822 (StubRoutines::x86::d2l_fixup() - cbuf.insts_end() - 4), 3823 runtime_call_Relocation::spec(), 3824 RELOC_DISP32); 3825 3826 // popq $dst 3827 if (dstenc >= 8) { 3828 emit_opcode(cbuf, Assembler::REX_B); 3829 } 3830 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 3831 3832 // done: 3833 %} 3834 %} 3835 3836 3837 3838 //----------FRAME-------------------------------------------------------------- 3839 // Definition of frame structure and management information. 3840 // 3841 // S T A C K L A Y O U T Allocators stack-slot number 3842 // | (to get allocators register number 3843 // G Owned by | | v add OptoReg::stack0()) 3844 // r CALLER | | 3845 // o | +--------+ pad to even-align allocators stack-slot 3846 // w V | pad0 | numbers; owned by CALLER 3847 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3848 // h ^ | in | 5 3849 // | | args | 4 Holes in incoming args owned by SELF 3850 // | | | | 3 3851 // | | +--------+ 3852 // V | | old out| Empty on Intel, window on Sparc 3853 // | old |preserve| Must be even aligned. 3854 // | SP-+--------+----> Matcher::_old_SP, even aligned 3855 // | | in | 3 area for Intel ret address 3856 // Owned by |preserve| Empty on Sparc. 3857 // SELF +--------+ 3858 // | | pad2 | 2 pad to align old SP 3859 // | +--------+ 1 3860 // | | locks | 0 3861 // | +--------+----> OptoReg::stack0(), even aligned 3862 // | | pad1 | 11 pad to align new SP 3863 // | +--------+ 3864 // | | | 10 3865 // | | spills | 9 spills 3866 // V | | 8 (pad0 slot for callee) 3867 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3868 // ^ | out | 7 3869 // | | args | 6 Holes in outgoing args owned by CALLEE 3870 // Owned by +--------+ 3871 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3872 // | new |preserve| Must be even-aligned. 3873 // | SP-+--------+----> Matcher::_new_SP, even aligned 3874 // | | | 3875 // 3876 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3877 // known from SELF's arguments and the Java calling convention. 3878 // Region 6-7 is determined per call site. 3879 // Note 2: If the calling convention leaves holes in the incoming argument 3880 // area, those holes are owned by SELF. Holes in the outgoing area 3881 // are owned by the CALLEE. Holes should not be nessecary in the 3882 // incoming area, as the Java calling convention is completely under 3883 // the control of the AD file. Doubles can be sorted and packed to 3884 // avoid holes. Holes in the outgoing arguments may be nessecary for 3885 // varargs C calling conventions. 3886 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3887 // even aligned with pad0 as needed. 3888 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3889 // region 6-11 is even aligned; it may be padded out more so that 3890 // the region from SP to FP meets the minimum stack alignment. 3891 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3892 // alignment. Region 11, pad1, may be dynamically extended so that 3893 // SP meets the minimum alignment. 3894 3895 frame 3896 %{ 3897 // What direction does stack grow in (assumed to be same for C & Java) 3898 stack_direction(TOWARDS_LOW); 3899 3900 // These three registers define part of the calling convention 3901 // between compiled code and the interpreter. 3902 inline_cache_reg(RAX); // Inline Cache Register 3903 interpreter_method_oop_reg(RBX); // Method Oop Register when 3904 // calling interpreter 3905 3906 // Optional: name the operand used by cisc-spilling to access 3907 // [stack_pointer + offset] 3908 cisc_spilling_operand_name(indOffset32); 3909 3910 // Number of stack slots consumed by locking an object 3911 sync_stack_slots(2); 3912 3913 // Compiled code's Frame Pointer 3914 frame_pointer(RSP); 3915 3916 // Interpreter stores its frame pointer in a register which is 3917 // stored to the stack by I2CAdaptors. 3918 // I2CAdaptors convert from interpreted java to compiled java. 3919 interpreter_frame_pointer(RBP); 3920 3921 // Stack alignment requirement 3922 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3923 3924 // Number of stack slots between incoming argument block and the start of 3925 // a new frame. The PROLOG must add this many slots to the stack. The 3926 // EPILOG must remove this many slots. amd64 needs two slots for 3927 // return address. 3928 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 3929 3930 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3931 // for calls to C. Supports the var-args backing area for register parms. 3932 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3933 3934 // The after-PROLOG location of the return address. Location of 3935 // return address specifies a type (REG or STACK) and a number 3936 // representing the register number (i.e. - use a register name) or 3937 // stack slot. 3938 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3939 // Otherwise, it is above the locks and verification slot and alignment word 3940 return_addr(STACK - 2 + 3941 round_to(2 + 2 * VerifyStackAtCalls + 3942 Compile::current()->fixed_slots(), 3943 WordsPerLong * 2)); 3944 3945 // Body of function which returns an integer array locating 3946 // arguments either in registers or in stack slots. Passed an array 3947 // of ideal registers called "sig" and a "length" count. Stack-slot 3948 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3949 // arguments for a CALLEE. Incoming stack arguments are 3950 // automatically biased by the preserve_stack_slots field above. 3951 3952 calling_convention 3953 %{ 3954 // No difference between ingoing/outgoing just pass false 3955 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3956 %} 3957 3958 c_calling_convention 3959 %{ 3960 // This is obviously always outgoing 3961 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); 3962 %} 3963 3964 // Location of compiled Java return values. Same as C for now. 3965 return_value 3966 %{ 3967 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3968 "only return normal values"); 3969 3970 static const int lo[Op_RegL + 1] = { 3971 0, 3972 0, 3973 RAX_num, // Op_RegN 3974 RAX_num, // Op_RegI 3975 RAX_num, // Op_RegP 3976 XMM0_num, // Op_RegF 3977 XMM0_num, // Op_RegD 3978 RAX_num // Op_RegL 3979 }; 3980 static const int hi[Op_RegL + 1] = { 3981 0, 3982 0, 3983 OptoReg::Bad, // Op_RegN 3984 OptoReg::Bad, // Op_RegI 3985 RAX_H_num, // Op_RegP 3986 OptoReg::Bad, // Op_RegF 3987 XMM0_H_num, // Op_RegD 3988 RAX_H_num // Op_RegL 3989 }; 3990 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 1, "missing type"); 3991 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3992 %} 3993 %} 3994 3995 //----------ATTRIBUTES--------------------------------------------------------- 3996 //----------Operand Attributes------------------------------------------------- 3997 op_attrib op_cost(0); // Required cost attribute 3998 3999 //----------Instruction Attributes--------------------------------------------- 4000 ins_attrib ins_cost(100); // Required cost attribute 4001 ins_attrib ins_size(8); // Required size attribute (in bits) 4002 ins_attrib ins_short_branch(0); // Required flag: is this instruction 4003 // a non-matching short branch variant 4004 // of some long branch? 4005 ins_attrib ins_alignment(1); // Required alignment attribute (must 4006 // be a power of 2) specifies the 4007 // alignment that some part of the 4008 // instruction (not necessarily the 4009 // start) requires. If > 1, a 4010 // compute_padding() function must be 4011 // provided for the instruction 4012 4013 //----------OPERANDS----------------------------------------------------------- 4014 // Operand definitions must precede instruction definitions for correct parsing 4015 // in the ADLC because operands constitute user defined types which are used in 4016 // instruction definitions. 4017 4018 //----------Simple Operands---------------------------------------------------- 4019 // Immediate Operands 4020 // Integer Immediate 4021 operand immI() 4022 %{ 4023 match(ConI); 4024 4025 op_cost(10); 4026 format %{ %} 4027 interface(CONST_INTER); 4028 %} 4029 4030 // Constant for test vs zero 4031 operand immI0() 4032 %{ 4033 predicate(n->get_int() == 0); 4034 match(ConI); 4035 4036 op_cost(0); 4037 format %{ %} 4038 interface(CONST_INTER); 4039 %} 4040 4041 // Constant for increment 4042 operand immI1() 4043 %{ 4044 predicate(n->get_int() == 1); 4045 match(ConI); 4046 4047 op_cost(0); 4048 format %{ %} 4049 interface(CONST_INTER); 4050 %} 4051 4052 // Constant for decrement 4053 operand immI_M1() 4054 %{ 4055 predicate(n->get_int() == -1); 4056 match(ConI); 4057 4058 op_cost(0); 4059 format %{ %} 4060 interface(CONST_INTER); 4061 %} 4062 4063 // Valid scale values for addressing modes 4064 operand immI2() 4065 %{ 4066 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4067 match(ConI); 4068 4069 format %{ %} 4070 interface(CONST_INTER); 4071 %} 4072 4073 operand immI8() 4074 %{ 4075 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 4076 match(ConI); 4077 4078 op_cost(5); 4079 format %{ %} 4080 interface(CONST_INTER); 4081 %} 4082 4083 operand immI16() 4084 %{ 4085 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 4086 match(ConI); 4087 4088 op_cost(10); 4089 format %{ %} 4090 interface(CONST_INTER); 4091 %} 4092 4093 // Constant for long shifts 4094 operand immI_32() 4095 %{ 4096 predicate( n->get_int() == 32 ); 4097 match(ConI); 4098 4099 op_cost(0); 4100 format %{ %} 4101 interface(CONST_INTER); 4102 %} 4103 4104 // Constant for long shifts 4105 operand immI_64() 4106 %{ 4107 predicate( n->get_int() == 64 ); 4108 match(ConI); 4109 4110 op_cost(0); 4111 format %{ %} 4112 interface(CONST_INTER); 4113 %} 4114 4115 // Pointer Immediate 4116 operand immP() 4117 %{ 4118 match(ConP); 4119 4120 op_cost(10); 4121 format %{ %} 4122 interface(CONST_INTER); 4123 %} 4124 4125 // NULL Pointer Immediate 4126 operand immP0() 4127 %{ 4128 predicate(n->get_ptr() == 0); 4129 match(ConP); 4130 4131 op_cost(5); 4132 format %{ %} 4133 interface(CONST_INTER); 4134 %} 4135 4136 operand immP_poll() %{ 4137 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page()); 4138 match(ConP); 4139 4140 // formats are generated automatically for constants and base registers 4141 format %{ %} 4142 interface(CONST_INTER); 4143 %} 4144 4145 // Pointer Immediate 4146 operand immN() %{ 4147 match(ConN); 4148 4149 op_cost(10); 4150 format %{ %} 4151 interface(CONST_INTER); 4152 %} 4153 4154 // NULL Pointer Immediate 4155 operand immN0() %{ 4156 predicate(n->get_narrowcon() == 0); 4157 match(ConN); 4158 4159 op_cost(5); 4160 format %{ %} 4161 interface(CONST_INTER); 4162 %} 4163 4164 operand immP31() 4165 %{ 4166 predicate(!n->as_Type()->type()->isa_oopptr() 4167 && (n->get_ptr() >> 31) == 0); 4168 match(ConP); 4169 4170 op_cost(5); 4171 format %{ %} 4172 interface(CONST_INTER); 4173 %} 4174 4175 4176 // Long Immediate 4177 operand immL() 4178 %{ 4179 match(ConL); 4180 4181 op_cost(20); 4182 format %{ %} 4183 interface(CONST_INTER); 4184 %} 4185 4186 // Long Immediate 8-bit 4187 operand immL8() 4188 %{ 4189 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 4190 match(ConL); 4191 4192 op_cost(5); 4193 format %{ %} 4194 interface(CONST_INTER); 4195 %} 4196 4197 // Long Immediate 32-bit unsigned 4198 operand immUL32() 4199 %{ 4200 predicate(n->get_long() == (unsigned int) (n->get_long())); 4201 match(ConL); 4202 4203 op_cost(10); 4204 format %{ %} 4205 interface(CONST_INTER); 4206 %} 4207 4208 // Long Immediate 32-bit signed 4209 operand immL32() 4210 %{ 4211 predicate(n->get_long() == (int) (n->get_long())); 4212 match(ConL); 4213 4214 op_cost(15); 4215 format %{ %} 4216 interface(CONST_INTER); 4217 %} 4218 4219 // Long Immediate zero 4220 operand immL0() 4221 %{ 4222 predicate(n->get_long() == 0L); 4223 match(ConL); 4224 4225 op_cost(10); 4226 format %{ %} 4227 interface(CONST_INTER); 4228 %} 4229 4230 // Constant for increment 4231 operand immL1() 4232 %{ 4233 predicate(n->get_long() == 1); 4234 match(ConL); 4235 4236 format %{ %} 4237 interface(CONST_INTER); 4238 %} 4239 4240 // Constant for decrement 4241 operand immL_M1() 4242 %{ 4243 predicate(n->get_long() == -1); 4244 match(ConL); 4245 4246 format %{ %} 4247 interface(CONST_INTER); 4248 %} 4249 4250 // Long Immediate: the value 10 4251 operand immL10() 4252 %{ 4253 predicate(n->get_long() == 10); 4254 match(ConL); 4255 4256 format %{ %} 4257 interface(CONST_INTER); 4258 %} 4259 4260 // Long immediate from 0 to 127. 4261 // Used for a shorter form of long mul by 10. 4262 operand immL_127() 4263 %{ 4264 predicate(0 <= n->get_long() && n->get_long() < 0x80); 4265 match(ConL); 4266 4267 op_cost(10); 4268 format %{ %} 4269 interface(CONST_INTER); 4270 %} 4271 4272 // Long Immediate: low 32-bit mask 4273 operand immL_32bits() 4274 %{ 4275 predicate(n->get_long() == 0xFFFFFFFFL); 4276 match(ConL); 4277 op_cost(20); 4278 4279 format %{ %} 4280 interface(CONST_INTER); 4281 %} 4282 4283 // Float Immediate zero 4284 operand immF0() 4285 %{ 4286 predicate(jint_cast(n->getf()) == 0); 4287 match(ConF); 4288 4289 op_cost(5); 4290 format %{ %} 4291 interface(CONST_INTER); 4292 %} 4293 4294 // Float Immediate 4295 operand immF() 4296 %{ 4297 match(ConF); 4298 4299 op_cost(15); 4300 format %{ %} 4301 interface(CONST_INTER); 4302 %} 4303 4304 // Double Immediate zero 4305 operand immD0() 4306 %{ 4307 predicate(jlong_cast(n->getd()) == 0); 4308 match(ConD); 4309 4310 op_cost(5); 4311 format %{ %} 4312 interface(CONST_INTER); 4313 %} 4314 4315 // Double Immediate 4316 operand immD() 4317 %{ 4318 match(ConD); 4319 4320 op_cost(15); 4321 format %{ %} 4322 interface(CONST_INTER); 4323 %} 4324 4325 // Immediates for special shifts (sign extend) 4326 4327 // Constants for increment 4328 operand immI_16() 4329 %{ 4330 predicate(n->get_int() == 16); 4331 match(ConI); 4332 4333 format %{ %} 4334 interface(CONST_INTER); 4335 %} 4336 4337 operand immI_24() 4338 %{ 4339 predicate(n->get_int() == 24); 4340 match(ConI); 4341 4342 format %{ %} 4343 interface(CONST_INTER); 4344 %} 4345 4346 // Constant for byte-wide masking 4347 operand immI_255() 4348 %{ 4349 predicate(n->get_int() == 255); 4350 match(ConI); 4351 4352 format %{ %} 4353 interface(CONST_INTER); 4354 %} 4355 4356 // Constant for short-wide masking 4357 operand immI_65535() 4358 %{ 4359 predicate(n->get_int() == 65535); 4360 match(ConI); 4361 4362 format %{ %} 4363 interface(CONST_INTER); 4364 %} 4365 4366 // Constant for byte-wide masking 4367 operand immL_255() 4368 %{ 4369 predicate(n->get_long() == 255); 4370 match(ConL); 4371 4372 format %{ %} 4373 interface(CONST_INTER); 4374 %} 4375 4376 // Constant for short-wide masking 4377 operand immL_65535() 4378 %{ 4379 predicate(n->get_long() == 65535); 4380 match(ConL); 4381 4382 format %{ %} 4383 interface(CONST_INTER); 4384 %} 4385 4386 // Register Operands 4387 // Integer Register 4388 operand rRegI() 4389 %{ 4390 constraint(ALLOC_IN_RC(int_reg)); 4391 match(RegI); 4392 4393 match(rax_RegI); 4394 match(rbx_RegI); 4395 match(rcx_RegI); 4396 match(rdx_RegI); 4397 match(rdi_RegI); 4398 4399 format %{ %} 4400 interface(REG_INTER); 4401 %} 4402 4403 // Special Registers 4404 operand rax_RegI() 4405 %{ 4406 constraint(ALLOC_IN_RC(int_rax_reg)); 4407 match(RegI); 4408 match(rRegI); 4409 4410 format %{ "RAX" %} 4411 interface(REG_INTER); 4412 %} 4413 4414 // Special Registers 4415 operand rbx_RegI() 4416 %{ 4417 constraint(ALLOC_IN_RC(int_rbx_reg)); 4418 match(RegI); 4419 match(rRegI); 4420 4421 format %{ "RBX" %} 4422 interface(REG_INTER); 4423 %} 4424 4425 operand rcx_RegI() 4426 %{ 4427 constraint(ALLOC_IN_RC(int_rcx_reg)); 4428 match(RegI); 4429 match(rRegI); 4430 4431 format %{ "RCX" %} 4432 interface(REG_INTER); 4433 %} 4434 4435 operand rdx_RegI() 4436 %{ 4437 constraint(ALLOC_IN_RC(int_rdx_reg)); 4438 match(RegI); 4439 match(rRegI); 4440 4441 format %{ "RDX" %} 4442 interface(REG_INTER); 4443 %} 4444 4445 operand rdi_RegI() 4446 %{ 4447 constraint(ALLOC_IN_RC(int_rdi_reg)); 4448 match(RegI); 4449 match(rRegI); 4450 4451 format %{ "RDI" %} 4452 interface(REG_INTER); 4453 %} 4454 4455 operand no_rcx_RegI() 4456 %{ 4457 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 4458 match(RegI); 4459 match(rax_RegI); 4460 match(rbx_RegI); 4461 match(rdx_RegI); 4462 match(rdi_RegI); 4463 4464 format %{ %} 4465 interface(REG_INTER); 4466 %} 4467 4468 operand no_rax_rdx_RegI() 4469 %{ 4470 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 4471 match(RegI); 4472 match(rbx_RegI); 4473 match(rcx_RegI); 4474 match(rdi_RegI); 4475 4476 format %{ %} 4477 interface(REG_INTER); 4478 %} 4479 4480 // Pointer Register 4481 operand any_RegP() 4482 %{ 4483 constraint(ALLOC_IN_RC(any_reg)); 4484 match(RegP); 4485 match(rax_RegP); 4486 match(rbx_RegP); 4487 match(rdi_RegP); 4488 match(rsi_RegP); 4489 match(rbp_RegP); 4490 match(r15_RegP); 4491 match(rRegP); 4492 4493 format %{ %} 4494 interface(REG_INTER); 4495 %} 4496 4497 operand rRegP() 4498 %{ 4499 constraint(ALLOC_IN_RC(ptr_reg)); 4500 match(RegP); 4501 match(rax_RegP); 4502 match(rbx_RegP); 4503 match(rdi_RegP); 4504 match(rsi_RegP); 4505 match(rbp_RegP); 4506 match(r15_RegP); // See Q&A below about r15_RegP. 4507 4508 format %{ %} 4509 interface(REG_INTER); 4510 %} 4511 4512 operand rRegN() %{ 4513 constraint(ALLOC_IN_RC(int_reg)); 4514 match(RegN); 4515 4516 format %{ %} 4517 interface(REG_INTER); 4518 %} 4519 4520 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 4521 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 4522 // It's fine for an instruction input which expects rRegP to match a r15_RegP. 4523 // The output of an instruction is controlled by the allocator, which respects 4524 // register class masks, not match rules. Unless an instruction mentions 4525 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 4526 // by the allocator as an input. 4527 4528 operand no_rax_RegP() 4529 %{ 4530 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 4531 match(RegP); 4532 match(rbx_RegP); 4533 match(rsi_RegP); 4534 match(rdi_RegP); 4535 4536 format %{ %} 4537 interface(REG_INTER); 4538 %} 4539 4540 operand no_rbp_RegP() 4541 %{ 4542 constraint(ALLOC_IN_RC(ptr_no_rbp_reg)); 4543 match(RegP); 4544 match(rbx_RegP); 4545 match(rsi_RegP); 4546 match(rdi_RegP); 4547 4548 format %{ %} 4549 interface(REG_INTER); 4550 %} 4551 4552 operand no_rax_rbx_RegP() 4553 %{ 4554 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 4555 match(RegP); 4556 match(rsi_RegP); 4557 match(rdi_RegP); 4558 4559 format %{ %} 4560 interface(REG_INTER); 4561 %} 4562 4563 // Special Registers 4564 // Return a pointer value 4565 operand rax_RegP() 4566 %{ 4567 constraint(ALLOC_IN_RC(ptr_rax_reg)); 4568 match(RegP); 4569 match(rRegP); 4570 4571 format %{ %} 4572 interface(REG_INTER); 4573 %} 4574 4575 // Special Registers 4576 // Return a compressed pointer value 4577 operand rax_RegN() 4578 %{ 4579 constraint(ALLOC_IN_RC(int_rax_reg)); 4580 match(RegN); 4581 match(rRegN); 4582 4583 format %{ %} 4584 interface(REG_INTER); 4585 %} 4586 4587 // Used in AtomicAdd 4588 operand rbx_RegP() 4589 %{ 4590 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 4591 match(RegP); 4592 match(rRegP); 4593 4594 format %{ %} 4595 interface(REG_INTER); 4596 %} 4597 4598 operand rsi_RegP() 4599 %{ 4600 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 4601 match(RegP); 4602 match(rRegP); 4603 4604 format %{ %} 4605 interface(REG_INTER); 4606 %} 4607 4608 // Used in rep stosq 4609 operand rdi_RegP() 4610 %{ 4611 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 4612 match(RegP); 4613 match(rRegP); 4614 4615 format %{ %} 4616 interface(REG_INTER); 4617 %} 4618 4619 operand rbp_RegP() 4620 %{ 4621 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 4622 match(RegP); 4623 match(rRegP); 4624 4625 format %{ %} 4626 interface(REG_INTER); 4627 %} 4628 4629 operand r15_RegP() 4630 %{ 4631 constraint(ALLOC_IN_RC(ptr_r15_reg)); 4632 match(RegP); 4633 match(rRegP); 4634 4635 format %{ %} 4636 interface(REG_INTER); 4637 %} 4638 4639 operand rRegL() 4640 %{ 4641 constraint(ALLOC_IN_RC(long_reg)); 4642 match(RegL); 4643 match(rax_RegL); 4644 match(rdx_RegL); 4645 4646 format %{ %} 4647 interface(REG_INTER); 4648 %} 4649 4650 // Special Registers 4651 operand no_rax_rdx_RegL() 4652 %{ 4653 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 4654 match(RegL); 4655 match(rRegL); 4656 4657 format %{ %} 4658 interface(REG_INTER); 4659 %} 4660 4661 operand no_rax_RegL() 4662 %{ 4663 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 4664 match(RegL); 4665 match(rRegL); 4666 match(rdx_RegL); 4667 4668 format %{ %} 4669 interface(REG_INTER); 4670 %} 4671 4672 operand no_rcx_RegL() 4673 %{ 4674 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 4675 match(RegL); 4676 match(rRegL); 4677 4678 format %{ %} 4679 interface(REG_INTER); 4680 %} 4681 4682 operand rax_RegL() 4683 %{ 4684 constraint(ALLOC_IN_RC(long_rax_reg)); 4685 match(RegL); 4686 match(rRegL); 4687 4688 format %{ "RAX" %} 4689 interface(REG_INTER); 4690 %} 4691 4692 operand rcx_RegL() 4693 %{ 4694 constraint(ALLOC_IN_RC(long_rcx_reg)); 4695 match(RegL); 4696 match(rRegL); 4697 4698 format %{ %} 4699 interface(REG_INTER); 4700 %} 4701 4702 operand rdx_RegL() 4703 %{ 4704 constraint(ALLOC_IN_RC(long_rdx_reg)); 4705 match(RegL); 4706 match(rRegL); 4707 4708 format %{ %} 4709 interface(REG_INTER); 4710 %} 4711 4712 // Flags register, used as output of compare instructions 4713 operand rFlagsReg() 4714 %{ 4715 constraint(ALLOC_IN_RC(int_flags)); 4716 match(RegFlags); 4717 4718 format %{ "RFLAGS" %} 4719 interface(REG_INTER); 4720 %} 4721 4722 // Flags register, used as output of FLOATING POINT compare instructions 4723 operand rFlagsRegU() 4724 %{ 4725 constraint(ALLOC_IN_RC(int_flags)); 4726 match(RegFlags); 4727 4728 format %{ "RFLAGS_U" %} 4729 interface(REG_INTER); 4730 %} 4731 4732 operand rFlagsRegUCF() %{ 4733 constraint(ALLOC_IN_RC(int_flags)); 4734 match(RegFlags); 4735 predicate(false); 4736 4737 format %{ "RFLAGS_U_CF" %} 4738 interface(REG_INTER); 4739 %} 4740 4741 // Float register operands 4742 operand regF() 4743 %{ 4744 constraint(ALLOC_IN_RC(float_reg)); 4745 match(RegF); 4746 4747 format %{ %} 4748 interface(REG_INTER); 4749 %} 4750 4751 // Double register operands 4752 operand regD() 4753 %{ 4754 constraint(ALLOC_IN_RC(double_reg)); 4755 match(RegD); 4756 4757 format %{ %} 4758 interface(REG_INTER); 4759 %} 4760 4761 4762 //----------Memory Operands---------------------------------------------------- 4763 // Direct Memory Operand 4764 // operand direct(immP addr) 4765 // %{ 4766 // match(addr); 4767 4768 // format %{ "[$addr]" %} 4769 // interface(MEMORY_INTER) %{ 4770 // base(0xFFFFFFFF); 4771 // index(0x4); 4772 // scale(0x0); 4773 // disp($addr); 4774 // %} 4775 // %} 4776 4777 // Indirect Memory Operand 4778 operand indirect(any_RegP reg) 4779 %{ 4780 constraint(ALLOC_IN_RC(ptr_reg)); 4781 match(reg); 4782 4783 format %{ "[$reg]" %} 4784 interface(MEMORY_INTER) %{ 4785 base($reg); 4786 index(0x4); 4787 scale(0x0); 4788 disp(0x0); 4789 %} 4790 %} 4791 4792 // Indirect Memory Plus Short Offset Operand 4793 operand indOffset8(any_RegP reg, immL8 off) 4794 %{ 4795 constraint(ALLOC_IN_RC(ptr_reg)); 4796 match(AddP reg off); 4797 4798 format %{ "[$reg + $off (8-bit)]" %} 4799 interface(MEMORY_INTER) %{ 4800 base($reg); 4801 index(0x4); 4802 scale(0x0); 4803 disp($off); 4804 %} 4805 %} 4806 4807 // Indirect Memory Plus Long Offset Operand 4808 operand indOffset32(any_RegP reg, immL32 off) 4809 %{ 4810 constraint(ALLOC_IN_RC(ptr_reg)); 4811 match(AddP reg off); 4812 4813 format %{ "[$reg + $off (32-bit)]" %} 4814 interface(MEMORY_INTER) %{ 4815 base($reg); 4816 index(0x4); 4817 scale(0x0); 4818 disp($off); 4819 %} 4820 %} 4821 4822 // Indirect Memory Plus Index Register Plus Offset Operand 4823 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 4824 %{ 4825 constraint(ALLOC_IN_RC(ptr_reg)); 4826 match(AddP (AddP reg lreg) off); 4827 4828 op_cost(10); 4829 format %{"[$reg + $off + $lreg]" %} 4830 interface(MEMORY_INTER) %{ 4831 base($reg); 4832 index($lreg); 4833 scale(0x0); 4834 disp($off); 4835 %} 4836 %} 4837 4838 // Indirect Memory Plus Index Register Plus Offset Operand 4839 operand indIndex(any_RegP reg, rRegL lreg) 4840 %{ 4841 constraint(ALLOC_IN_RC(ptr_reg)); 4842 match(AddP reg lreg); 4843 4844 op_cost(10); 4845 format %{"[$reg + $lreg]" %} 4846 interface(MEMORY_INTER) %{ 4847 base($reg); 4848 index($lreg); 4849 scale(0x0); 4850 disp(0x0); 4851 %} 4852 %} 4853 4854 // Indirect Memory Times Scale Plus Index Register 4855 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 4856 %{ 4857 constraint(ALLOC_IN_RC(ptr_reg)); 4858 match(AddP reg (LShiftL lreg scale)); 4859 4860 op_cost(10); 4861 format %{"[$reg + $lreg << $scale]" %} 4862 interface(MEMORY_INTER) %{ 4863 base($reg); 4864 index($lreg); 4865 scale($scale); 4866 disp(0x0); 4867 %} 4868 %} 4869 4870 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4871 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 4872 %{ 4873 constraint(ALLOC_IN_RC(ptr_reg)); 4874 match(AddP (AddP reg (LShiftL lreg scale)) off); 4875 4876 op_cost(10); 4877 format %{"[$reg + $off + $lreg << $scale]" %} 4878 interface(MEMORY_INTER) %{ 4879 base($reg); 4880 index($lreg); 4881 scale($scale); 4882 disp($off); 4883 %} 4884 %} 4885 4886 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4887 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 4888 %{ 4889 constraint(ALLOC_IN_RC(ptr_reg)); 4890 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4891 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 4892 4893 op_cost(10); 4894 format %{"[$reg + $off + $idx << $scale]" %} 4895 interface(MEMORY_INTER) %{ 4896 base($reg); 4897 index($idx); 4898 scale($scale); 4899 disp($off); 4900 %} 4901 %} 4902 4903 // Indirect Narrow Oop Plus Offset Operand 4904 // Note: x86 architecture doesn't support "scale * index + offset" without a base 4905 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 4906 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 4907 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 4908 constraint(ALLOC_IN_RC(ptr_reg)); 4909 match(AddP (DecodeN reg) off); 4910 4911 op_cost(10); 4912 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 4913 interface(MEMORY_INTER) %{ 4914 base(0xc); // R12 4915 index($reg); 4916 scale(0x3); 4917 disp($off); 4918 %} 4919 %} 4920 4921 // Indirect Memory Operand 4922 operand indirectNarrow(rRegN reg) 4923 %{ 4924 predicate(Universe::narrow_oop_shift() == 0); 4925 constraint(ALLOC_IN_RC(ptr_reg)); 4926 match(DecodeN reg); 4927 4928 format %{ "[$reg]" %} 4929 interface(MEMORY_INTER) %{ 4930 base($reg); 4931 index(0x4); 4932 scale(0x0); 4933 disp(0x0); 4934 %} 4935 %} 4936 4937 // Indirect Memory Plus Short Offset Operand 4938 operand indOffset8Narrow(rRegN reg, immL8 off) 4939 %{ 4940 predicate(Universe::narrow_oop_shift() == 0); 4941 constraint(ALLOC_IN_RC(ptr_reg)); 4942 match(AddP (DecodeN reg) off); 4943 4944 format %{ "[$reg + $off (8-bit)]" %} 4945 interface(MEMORY_INTER) %{ 4946 base($reg); 4947 index(0x4); 4948 scale(0x0); 4949 disp($off); 4950 %} 4951 %} 4952 4953 // Indirect Memory Plus Long Offset Operand 4954 operand indOffset32Narrow(rRegN reg, immL32 off) 4955 %{ 4956 predicate(Universe::narrow_oop_shift() == 0); 4957 constraint(ALLOC_IN_RC(ptr_reg)); 4958 match(AddP (DecodeN reg) off); 4959 4960 format %{ "[$reg + $off (32-bit)]" %} 4961 interface(MEMORY_INTER) %{ 4962 base($reg); 4963 index(0x4); 4964 scale(0x0); 4965 disp($off); 4966 %} 4967 %} 4968 4969 // Indirect Memory Plus Index Register Plus Offset Operand 4970 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 4971 %{ 4972 predicate(Universe::narrow_oop_shift() == 0); 4973 constraint(ALLOC_IN_RC(ptr_reg)); 4974 match(AddP (AddP (DecodeN reg) lreg) off); 4975 4976 op_cost(10); 4977 format %{"[$reg + $off + $lreg]" %} 4978 interface(MEMORY_INTER) %{ 4979 base($reg); 4980 index($lreg); 4981 scale(0x0); 4982 disp($off); 4983 %} 4984 %} 4985 4986 // Indirect Memory Plus Index Register Plus Offset Operand 4987 operand indIndexNarrow(rRegN reg, rRegL lreg) 4988 %{ 4989 predicate(Universe::narrow_oop_shift() == 0); 4990 constraint(ALLOC_IN_RC(ptr_reg)); 4991 match(AddP (DecodeN reg) lreg); 4992 4993 op_cost(10); 4994 format %{"[$reg + $lreg]" %} 4995 interface(MEMORY_INTER) %{ 4996 base($reg); 4997 index($lreg); 4998 scale(0x0); 4999 disp(0x0); 5000 %} 5001 %} 5002 5003 // Indirect Memory Times Scale Plus Index Register 5004 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 5005 %{ 5006 predicate(Universe::narrow_oop_shift() == 0); 5007 constraint(ALLOC_IN_RC(ptr_reg)); 5008 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5009 5010 op_cost(10); 5011 format %{"[$reg + $lreg << $scale]" %} 5012 interface(MEMORY_INTER) %{ 5013 base($reg); 5014 index($lreg); 5015 scale($scale); 5016 disp(0x0); 5017 %} 5018 %} 5019 5020 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 5021 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 5022 %{ 5023 predicate(Universe::narrow_oop_shift() == 0); 5024 constraint(ALLOC_IN_RC(ptr_reg)); 5025 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 5026 5027 op_cost(10); 5028 format %{"[$reg + $off + $lreg << $scale]" %} 5029 interface(MEMORY_INTER) %{ 5030 base($reg); 5031 index($lreg); 5032 scale($scale); 5033 disp($off); 5034 %} 5035 %} 5036 5037 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 5038 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 5039 %{ 5040 constraint(ALLOC_IN_RC(ptr_reg)); 5041 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 5042 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 5043 5044 op_cost(10); 5045 format %{"[$reg + $off + $idx << $scale]" %} 5046 interface(MEMORY_INTER) %{ 5047 base($reg); 5048 index($idx); 5049 scale($scale); 5050 disp($off); 5051 %} 5052 %} 5053 5054 5055 //----------Special Memory Operands-------------------------------------------- 5056 // Stack Slot Operand - This operand is used for loading and storing temporary 5057 // values on the stack where a match requires a value to 5058 // flow through memory. 5059 operand stackSlotP(sRegP reg) 5060 %{ 5061 constraint(ALLOC_IN_RC(stack_slots)); 5062 // No match rule because this operand is only generated in matching 5063 5064 format %{ "[$reg]" %} 5065 interface(MEMORY_INTER) %{ 5066 base(0x4); // RSP 5067 index(0x4); // No Index 5068 scale(0x0); // No Scale 5069 disp($reg); // Stack Offset 5070 %} 5071 %} 5072 5073 operand stackSlotI(sRegI reg) 5074 %{ 5075 constraint(ALLOC_IN_RC(stack_slots)); 5076 // No match rule because this operand is only generated in matching 5077 5078 format %{ "[$reg]" %} 5079 interface(MEMORY_INTER) %{ 5080 base(0x4); // RSP 5081 index(0x4); // No Index 5082 scale(0x0); // No Scale 5083 disp($reg); // Stack Offset 5084 %} 5085 %} 5086 5087 operand stackSlotF(sRegF reg) 5088 %{ 5089 constraint(ALLOC_IN_RC(stack_slots)); 5090 // No match rule because this operand is only generated in matching 5091 5092 format %{ "[$reg]" %} 5093 interface(MEMORY_INTER) %{ 5094 base(0x4); // RSP 5095 index(0x4); // No Index 5096 scale(0x0); // No Scale 5097 disp($reg); // Stack Offset 5098 %} 5099 %} 5100 5101 operand stackSlotD(sRegD reg) 5102 %{ 5103 constraint(ALLOC_IN_RC(stack_slots)); 5104 // No match rule because this operand is only generated in matching 5105 5106 format %{ "[$reg]" %} 5107 interface(MEMORY_INTER) %{ 5108 base(0x4); // RSP 5109 index(0x4); // No Index 5110 scale(0x0); // No Scale 5111 disp($reg); // Stack Offset 5112 %} 5113 %} 5114 operand stackSlotL(sRegL reg) 5115 %{ 5116 constraint(ALLOC_IN_RC(stack_slots)); 5117 // No match rule because this operand is only generated in matching 5118 5119 format %{ "[$reg]" %} 5120 interface(MEMORY_INTER) %{ 5121 base(0x4); // RSP 5122 index(0x4); // No Index 5123 scale(0x0); // No Scale 5124 disp($reg); // Stack Offset 5125 %} 5126 %} 5127 5128 //----------Conditional Branch Operands---------------------------------------- 5129 // Comparison Op - This is the operation of the comparison, and is limited to 5130 // the following set of codes: 5131 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5132 // 5133 // Other attributes of the comparison, such as unsignedness, are specified 5134 // by the comparison instruction that sets a condition code flags register. 5135 // That result is represented by a flags operand whose subtype is appropriate 5136 // to the unsignedness (etc.) of the comparison. 5137 // 5138 // Later, the instruction which matches both the Comparison Op (a Bool) and 5139 // the flags (produced by the Cmp) specifies the coding of the comparison op 5140 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5141 5142 // Comparision Code 5143 operand cmpOp() 5144 %{ 5145 match(Bool); 5146 5147 format %{ "" %} 5148 interface(COND_INTER) %{ 5149 equal(0x4, "e"); 5150 not_equal(0x5, "ne"); 5151 less(0xC, "l"); 5152 greater_equal(0xD, "ge"); 5153 less_equal(0xE, "le"); 5154 greater(0xF, "g"); 5155 %} 5156 %} 5157 5158 // Comparison Code, unsigned compare. Used by FP also, with 5159 // C2 (unordered) turned into GT or LT already. The other bits 5160 // C0 and C3 are turned into Carry & Zero flags. 5161 operand cmpOpU() 5162 %{ 5163 match(Bool); 5164 5165 format %{ "" %} 5166 interface(COND_INTER) %{ 5167 equal(0x4, "e"); 5168 not_equal(0x5, "ne"); 5169 less(0x2, "b"); 5170 greater_equal(0x3, "nb"); 5171 less_equal(0x6, "be"); 5172 greater(0x7, "nbe"); 5173 %} 5174 %} 5175 5176 5177 // Floating comparisons that don't require any fixup for the unordered case 5178 operand cmpOpUCF() %{ 5179 match(Bool); 5180 predicate(n->as_Bool()->_test._test == BoolTest::lt || 5181 n->as_Bool()->_test._test == BoolTest::ge || 5182 n->as_Bool()->_test._test == BoolTest::le || 5183 n->as_Bool()->_test._test == BoolTest::gt); 5184 format %{ "" %} 5185 interface(COND_INTER) %{ 5186 equal(0x4, "e"); 5187 not_equal(0x5, "ne"); 5188 less(0x2, "b"); 5189 greater_equal(0x3, "nb"); 5190 less_equal(0x6, "be"); 5191 greater(0x7, "nbe"); 5192 %} 5193 %} 5194 5195 5196 // Floating comparisons that can be fixed up with extra conditional jumps 5197 operand cmpOpUCF2() %{ 5198 match(Bool); 5199 predicate(n->as_Bool()->_test._test == BoolTest::ne || 5200 n->as_Bool()->_test._test == BoolTest::eq); 5201 format %{ "" %} 5202 interface(COND_INTER) %{ 5203 equal(0x4, "e"); 5204 not_equal(0x5, "ne"); 5205 less(0x2, "b"); 5206 greater_equal(0x3, "nb"); 5207 less_equal(0x6, "be"); 5208 greater(0x7, "nbe"); 5209 %} 5210 %} 5211 5212 5213 //----------OPERAND CLASSES---------------------------------------------------- 5214 // Operand Classes are groups of operands that are used as to simplify 5215 // instruction definitions by not requiring the AD writer to specify separate 5216 // instructions for every form of operand when the instruction accepts 5217 // multiple operand types with the same basic encoding and format. The classic 5218 // case of this is memory operands. 5219 5220 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 5221 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, 5222 indCompressedOopOffset, 5223 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 5224 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 5225 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow); 5226 5227 //----------PIPELINE----------------------------------------------------------- 5228 // Rules which define the behavior of the target architectures pipeline. 5229 pipeline %{ 5230 5231 //----------ATTRIBUTES--------------------------------------------------------- 5232 attributes %{ 5233 variable_size_instructions; // Fixed size instructions 5234 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 5235 instruction_unit_size = 1; // An instruction is 1 bytes long 5236 instruction_fetch_unit_size = 16; // The processor fetches one line 5237 instruction_fetch_units = 1; // of 16 bytes 5238 5239 // List of nop instructions 5240 nops( MachNop ); 5241 %} 5242 5243 //----------RESOURCES---------------------------------------------------------- 5244 // Resources are the functional units available to the machine 5245 5246 // Generic P2/P3 pipeline 5247 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 5248 // 3 instructions decoded per cycle. 5249 // 2 load/store ops per cycle, 1 branch, 1 FPU, 5250 // 3 ALU op, only ALU0 handles mul instructions. 5251 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 5252 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 5253 BR, FPU, 5254 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 5255 5256 //----------PIPELINE DESCRIPTION----------------------------------------------- 5257 // Pipeline Description specifies the stages in the machine's pipeline 5258 5259 // Generic P2/P3 pipeline 5260 pipe_desc(S0, S1, S2, S3, S4, S5); 5261 5262 //----------PIPELINE CLASSES--------------------------------------------------- 5263 // Pipeline Classes describe the stages in which input and output are 5264 // referenced by the hardware pipeline. 5265 5266 // Naming convention: ialu or fpu 5267 // Then: _reg 5268 // Then: _reg if there is a 2nd register 5269 // Then: _long if it's a pair of instructions implementing a long 5270 // Then: _fat if it requires the big decoder 5271 // Or: _mem if it requires the big decoder and a memory unit. 5272 5273 // Integer ALU reg operation 5274 pipe_class ialu_reg(rRegI dst) 5275 %{ 5276 single_instruction; 5277 dst : S4(write); 5278 dst : S3(read); 5279 DECODE : S0; // any decoder 5280 ALU : S3; // any alu 5281 %} 5282 5283 // Long ALU reg operation 5284 pipe_class ialu_reg_long(rRegL dst) 5285 %{ 5286 instruction_count(2); 5287 dst : S4(write); 5288 dst : S3(read); 5289 DECODE : S0(2); // any 2 decoders 5290 ALU : S3(2); // both alus 5291 %} 5292 5293 // Integer ALU reg operation using big decoder 5294 pipe_class ialu_reg_fat(rRegI dst) 5295 %{ 5296 single_instruction; 5297 dst : S4(write); 5298 dst : S3(read); 5299 D0 : S0; // big decoder only 5300 ALU : S3; // any alu 5301 %} 5302 5303 // Long ALU reg operation using big decoder 5304 pipe_class ialu_reg_long_fat(rRegL dst) 5305 %{ 5306 instruction_count(2); 5307 dst : S4(write); 5308 dst : S3(read); 5309 D0 : S0(2); // big decoder only; twice 5310 ALU : S3(2); // any 2 alus 5311 %} 5312 5313 // Integer ALU reg-reg operation 5314 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 5315 %{ 5316 single_instruction; 5317 dst : S4(write); 5318 src : S3(read); 5319 DECODE : S0; // any decoder 5320 ALU : S3; // any alu 5321 %} 5322 5323 // Long ALU reg-reg operation 5324 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 5325 %{ 5326 instruction_count(2); 5327 dst : S4(write); 5328 src : S3(read); 5329 DECODE : S0(2); // any 2 decoders 5330 ALU : S3(2); // both alus 5331 %} 5332 5333 // Integer ALU reg-reg operation 5334 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 5335 %{ 5336 single_instruction; 5337 dst : S4(write); 5338 src : S3(read); 5339 D0 : S0; // big decoder only 5340 ALU : S3; // any alu 5341 %} 5342 5343 // Long ALU reg-reg operation 5344 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 5345 %{ 5346 instruction_count(2); 5347 dst : S4(write); 5348 src : S3(read); 5349 D0 : S0(2); // big decoder only; twice 5350 ALU : S3(2); // both alus 5351 %} 5352 5353 // Integer ALU reg-mem operation 5354 pipe_class ialu_reg_mem(rRegI dst, memory mem) 5355 %{ 5356 single_instruction; 5357 dst : S5(write); 5358 mem : S3(read); 5359 D0 : S0; // big decoder only 5360 ALU : S4; // any alu 5361 MEM : S3; // any mem 5362 %} 5363 5364 // Integer mem operation (prefetch) 5365 pipe_class ialu_mem(memory mem) 5366 %{ 5367 single_instruction; 5368 mem : S3(read); 5369 D0 : S0; // big decoder only 5370 MEM : S3; // any mem 5371 %} 5372 5373 // Integer Store to Memory 5374 pipe_class ialu_mem_reg(memory mem, rRegI src) 5375 %{ 5376 single_instruction; 5377 mem : S3(read); 5378 src : S5(read); 5379 D0 : S0; // big decoder only 5380 ALU : S4; // any alu 5381 MEM : S3; 5382 %} 5383 5384 // // Long Store to Memory 5385 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 5386 // %{ 5387 // instruction_count(2); 5388 // mem : S3(read); 5389 // src : S5(read); 5390 // D0 : S0(2); // big decoder only; twice 5391 // ALU : S4(2); // any 2 alus 5392 // MEM : S3(2); // Both mems 5393 // %} 5394 5395 // Integer Store to Memory 5396 pipe_class ialu_mem_imm(memory mem) 5397 %{ 5398 single_instruction; 5399 mem : S3(read); 5400 D0 : S0; // big decoder only 5401 ALU : S4; // any alu 5402 MEM : S3; 5403 %} 5404 5405 // Integer ALU0 reg-reg operation 5406 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 5407 %{ 5408 single_instruction; 5409 dst : S4(write); 5410 src : S3(read); 5411 D0 : S0; // Big decoder only 5412 ALU0 : S3; // only alu0 5413 %} 5414 5415 // Integer ALU0 reg-mem operation 5416 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 5417 %{ 5418 single_instruction; 5419 dst : S5(write); 5420 mem : S3(read); 5421 D0 : S0; // big decoder only 5422 ALU0 : S4; // ALU0 only 5423 MEM : S3; // any mem 5424 %} 5425 5426 // Integer ALU reg-reg operation 5427 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 5428 %{ 5429 single_instruction; 5430 cr : S4(write); 5431 src1 : S3(read); 5432 src2 : S3(read); 5433 DECODE : S0; // any decoder 5434 ALU : S3; // any alu 5435 %} 5436 5437 // Integer ALU reg-imm operation 5438 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 5439 %{ 5440 single_instruction; 5441 cr : S4(write); 5442 src1 : S3(read); 5443 DECODE : S0; // any decoder 5444 ALU : S3; // any alu 5445 %} 5446 5447 // Integer ALU reg-mem operation 5448 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 5449 %{ 5450 single_instruction; 5451 cr : S4(write); 5452 src1 : S3(read); 5453 src2 : S3(read); 5454 D0 : S0; // big decoder only 5455 ALU : S4; // any alu 5456 MEM : S3; 5457 %} 5458 5459 // Conditional move reg-reg 5460 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 5461 %{ 5462 instruction_count(4); 5463 y : S4(read); 5464 q : S3(read); 5465 p : S3(read); 5466 DECODE : S0(4); // any decoder 5467 %} 5468 5469 // Conditional move reg-reg 5470 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 5471 %{ 5472 single_instruction; 5473 dst : S4(write); 5474 src : S3(read); 5475 cr : S3(read); 5476 DECODE : S0; // any decoder 5477 %} 5478 5479 // Conditional move reg-mem 5480 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 5481 %{ 5482 single_instruction; 5483 dst : S4(write); 5484 src : S3(read); 5485 cr : S3(read); 5486 DECODE : S0; // any decoder 5487 MEM : S3; 5488 %} 5489 5490 // Conditional move reg-reg long 5491 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 5492 %{ 5493 single_instruction; 5494 dst : S4(write); 5495 src : S3(read); 5496 cr : S3(read); 5497 DECODE : S0(2); // any 2 decoders 5498 %} 5499 5500 // XXX 5501 // // Conditional move double reg-reg 5502 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 5503 // %{ 5504 // single_instruction; 5505 // dst : S4(write); 5506 // src : S3(read); 5507 // cr : S3(read); 5508 // DECODE : S0; // any decoder 5509 // %} 5510 5511 // Float reg-reg operation 5512 pipe_class fpu_reg(regD dst) 5513 %{ 5514 instruction_count(2); 5515 dst : S3(read); 5516 DECODE : S0(2); // any 2 decoders 5517 FPU : S3; 5518 %} 5519 5520 // Float reg-reg operation 5521 pipe_class fpu_reg_reg(regD dst, regD src) 5522 %{ 5523 instruction_count(2); 5524 dst : S4(write); 5525 src : S3(read); 5526 DECODE : S0(2); // any 2 decoders 5527 FPU : S3; 5528 %} 5529 5530 // Float reg-reg operation 5531 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 5532 %{ 5533 instruction_count(3); 5534 dst : S4(write); 5535 src1 : S3(read); 5536 src2 : S3(read); 5537 DECODE : S0(3); // any 3 decoders 5538 FPU : S3(2); 5539 %} 5540 5541 // Float reg-reg operation 5542 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 5543 %{ 5544 instruction_count(4); 5545 dst : S4(write); 5546 src1 : S3(read); 5547 src2 : S3(read); 5548 src3 : S3(read); 5549 DECODE : S0(4); // any 3 decoders 5550 FPU : S3(2); 5551 %} 5552 5553 // Float reg-reg operation 5554 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 5555 %{ 5556 instruction_count(4); 5557 dst : S4(write); 5558 src1 : S3(read); 5559 src2 : S3(read); 5560 src3 : S3(read); 5561 DECODE : S1(3); // any 3 decoders 5562 D0 : S0; // Big decoder only 5563 FPU : S3(2); 5564 MEM : S3; 5565 %} 5566 5567 // Float reg-mem operation 5568 pipe_class fpu_reg_mem(regD dst, memory mem) 5569 %{ 5570 instruction_count(2); 5571 dst : S5(write); 5572 mem : S3(read); 5573 D0 : S0; // big decoder only 5574 DECODE : S1; // any decoder for FPU POP 5575 FPU : S4; 5576 MEM : S3; // any mem 5577 %} 5578 5579 // Float reg-mem operation 5580 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 5581 %{ 5582 instruction_count(3); 5583 dst : S5(write); 5584 src1 : S3(read); 5585 mem : S3(read); 5586 D0 : S0; // big decoder only 5587 DECODE : S1(2); // any decoder for FPU POP 5588 FPU : S4; 5589 MEM : S3; // any mem 5590 %} 5591 5592 // Float mem-reg operation 5593 pipe_class fpu_mem_reg(memory mem, regD src) 5594 %{ 5595 instruction_count(2); 5596 src : S5(read); 5597 mem : S3(read); 5598 DECODE : S0; // any decoder for FPU PUSH 5599 D0 : S1; // big decoder only 5600 FPU : S4; 5601 MEM : S3; // any mem 5602 %} 5603 5604 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 5605 %{ 5606 instruction_count(3); 5607 src1 : S3(read); 5608 src2 : S3(read); 5609 mem : S3(read); 5610 DECODE : S0(2); // any decoder for FPU PUSH 5611 D0 : S1; // big decoder only 5612 FPU : S4; 5613 MEM : S3; // any mem 5614 %} 5615 5616 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 5617 %{ 5618 instruction_count(3); 5619 src1 : S3(read); 5620 src2 : S3(read); 5621 mem : S4(read); 5622 DECODE : S0; // any decoder for FPU PUSH 5623 D0 : S0(2); // big decoder only 5624 FPU : S4; 5625 MEM : S3(2); // any mem 5626 %} 5627 5628 pipe_class fpu_mem_mem(memory dst, memory src1) 5629 %{ 5630 instruction_count(2); 5631 src1 : S3(read); 5632 dst : S4(read); 5633 D0 : S0(2); // big decoder only 5634 MEM : S3(2); // any mem 5635 %} 5636 5637 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 5638 %{ 5639 instruction_count(3); 5640 src1 : S3(read); 5641 src2 : S3(read); 5642 dst : S4(read); 5643 D0 : S0(3); // big decoder only 5644 FPU : S4; 5645 MEM : S3(3); // any mem 5646 %} 5647 5648 pipe_class fpu_mem_reg_con(memory mem, regD src1) 5649 %{ 5650 instruction_count(3); 5651 src1 : S4(read); 5652 mem : S4(read); 5653 DECODE : S0; // any decoder for FPU PUSH 5654 D0 : S0(2); // big decoder only 5655 FPU : S4; 5656 MEM : S3(2); // any mem 5657 %} 5658 5659 // Float load constant 5660 pipe_class fpu_reg_con(regD dst) 5661 %{ 5662 instruction_count(2); 5663 dst : S5(write); 5664 D0 : S0; // big decoder only for the load 5665 DECODE : S1; // any decoder for FPU POP 5666 FPU : S4; 5667 MEM : S3; // any mem 5668 %} 5669 5670 // Float load constant 5671 pipe_class fpu_reg_reg_con(regD dst, regD src) 5672 %{ 5673 instruction_count(3); 5674 dst : S5(write); 5675 src : S3(read); 5676 D0 : S0; // big decoder only for the load 5677 DECODE : S1(2); // any decoder for FPU POP 5678 FPU : S4; 5679 MEM : S3; // any mem 5680 %} 5681 5682 // UnConditional branch 5683 pipe_class pipe_jmp(label labl) 5684 %{ 5685 single_instruction; 5686 BR : S3; 5687 %} 5688 5689 // Conditional branch 5690 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 5691 %{ 5692 single_instruction; 5693 cr : S1(read); 5694 BR : S3; 5695 %} 5696 5697 // Allocation idiom 5698 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 5699 %{ 5700 instruction_count(1); force_serialization; 5701 fixed_latency(6); 5702 heap_ptr : S3(read); 5703 DECODE : S0(3); 5704 D0 : S2; 5705 MEM : S3; 5706 ALU : S3(2); 5707 dst : S5(write); 5708 BR : S5; 5709 %} 5710 5711 // Generic big/slow expanded idiom 5712 pipe_class pipe_slow() 5713 %{ 5714 instruction_count(10); multiple_bundles; force_serialization; 5715 fixed_latency(100); 5716 D0 : S0(2); 5717 MEM : S3(2); 5718 %} 5719 5720 // The real do-nothing guy 5721 pipe_class empty() 5722 %{ 5723 instruction_count(0); 5724 %} 5725 5726 // Define the class for the Nop node 5727 define 5728 %{ 5729 MachNop = empty; 5730 %} 5731 5732 %} 5733 5734 //----------INSTRUCTIONS------------------------------------------------------- 5735 // 5736 // match -- States which machine-independent subtree may be replaced 5737 // by this instruction. 5738 // ins_cost -- The estimated cost of this instruction is used by instruction 5739 // selection to identify a minimum cost tree of machine 5740 // instructions that matches a tree of machine-independent 5741 // instructions. 5742 // format -- A string providing the disassembly for this instruction. 5743 // The value of an instruction's operand may be inserted 5744 // by referring to it with a '$' prefix. 5745 // opcode -- Three instruction opcodes may be provided. These are referred 5746 // to within an encode class as $primary, $secondary, and $tertiary 5747 // rrspectively. The primary opcode is commonly used to 5748 // indicate the type of machine instruction, while secondary 5749 // and tertiary are often used for prefix options or addressing 5750 // modes. 5751 // ins_encode -- A list of encode classes with parameters. The encode class 5752 // name must have been defined in an 'enc_class' specification 5753 // in the encode section of the architecture description. 5754 5755 5756 //----------Load/Store/Move Instructions--------------------------------------- 5757 //----------Load Instructions-------------------------------------------------- 5758 5759 // Load Byte (8 bit signed) 5760 instruct loadB(rRegI dst, memory mem) 5761 %{ 5762 match(Set dst (LoadB mem)); 5763 5764 ins_cost(125); 5765 format %{ "movsbl $dst, $mem\t# byte" %} 5766 5767 ins_encode %{ 5768 __ movsbl($dst$$Register, $mem$$Address); 5769 %} 5770 5771 ins_pipe(ialu_reg_mem); 5772 %} 5773 5774 // Load Byte (8 bit signed) into Long Register 5775 instruct loadB2L(rRegL dst, memory mem) 5776 %{ 5777 match(Set dst (ConvI2L (LoadB mem))); 5778 5779 ins_cost(125); 5780 format %{ "movsbq $dst, $mem\t# byte -> long" %} 5781 5782 ins_encode %{ 5783 __ movsbq($dst$$Register, $mem$$Address); 5784 %} 5785 5786 ins_pipe(ialu_reg_mem); 5787 %} 5788 5789 // Load Unsigned Byte (8 bit UNsigned) 5790 instruct loadUB(rRegI dst, memory mem) 5791 %{ 5792 match(Set dst (LoadUB mem)); 5793 5794 ins_cost(125); 5795 format %{ "movzbl $dst, $mem\t# ubyte" %} 5796 5797 ins_encode %{ 5798 __ movzbl($dst$$Register, $mem$$Address); 5799 %} 5800 5801 ins_pipe(ialu_reg_mem); 5802 %} 5803 5804 // Load Unsigned Byte (8 bit UNsigned) into Long Register 5805 instruct loadUB2L(rRegL dst, memory mem) 5806 %{ 5807 match(Set dst (ConvI2L (LoadUB mem))); 5808 5809 ins_cost(125); 5810 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 5811 5812 ins_encode %{ 5813 __ movzbq($dst$$Register, $mem$$Address); 5814 %} 5815 5816 ins_pipe(ialu_reg_mem); 5817 %} 5818 5819 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register 5820 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ 5821 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5822 effect(KILL cr); 5823 5824 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" 5825 "andl $dst, $mask" %} 5826 ins_encode %{ 5827 Register Rdst = $dst$$Register; 5828 __ movzbq(Rdst, $mem$$Address); 5829 __ andl(Rdst, $mask$$constant); 5830 %} 5831 ins_pipe(ialu_reg_mem); 5832 %} 5833 5834 // Load Short (16 bit signed) 5835 instruct loadS(rRegI dst, memory mem) 5836 %{ 5837 match(Set dst (LoadS mem)); 5838 5839 ins_cost(125); 5840 format %{ "movswl $dst, $mem\t# short" %} 5841 5842 ins_encode %{ 5843 __ movswl($dst$$Register, $mem$$Address); 5844 %} 5845 5846 ins_pipe(ialu_reg_mem); 5847 %} 5848 5849 // Load Short (16 bit signed) to Byte (8 bit signed) 5850 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5851 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5852 5853 ins_cost(125); 5854 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5855 ins_encode %{ 5856 __ movsbl($dst$$Register, $mem$$Address); 5857 %} 5858 ins_pipe(ialu_reg_mem); 5859 %} 5860 5861 // Load Short (16 bit signed) into Long Register 5862 instruct loadS2L(rRegL dst, memory mem) 5863 %{ 5864 match(Set dst (ConvI2L (LoadS mem))); 5865 5866 ins_cost(125); 5867 format %{ "movswq $dst, $mem\t# short -> long" %} 5868 5869 ins_encode %{ 5870 __ movswq($dst$$Register, $mem$$Address); 5871 %} 5872 5873 ins_pipe(ialu_reg_mem); 5874 %} 5875 5876 // Load Unsigned Short/Char (16 bit UNsigned) 5877 instruct loadUS(rRegI dst, memory mem) 5878 %{ 5879 match(Set dst (LoadUS mem)); 5880 5881 ins_cost(125); 5882 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5883 5884 ins_encode %{ 5885 __ movzwl($dst$$Register, $mem$$Address); 5886 %} 5887 5888 ins_pipe(ialu_reg_mem); 5889 %} 5890 5891 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5892 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5893 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5894 5895 ins_cost(125); 5896 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5897 ins_encode %{ 5898 __ movsbl($dst$$Register, $mem$$Address); 5899 %} 5900 ins_pipe(ialu_reg_mem); 5901 %} 5902 5903 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5904 instruct loadUS2L(rRegL dst, memory mem) 5905 %{ 5906 match(Set dst (ConvI2L (LoadUS mem))); 5907 5908 ins_cost(125); 5909 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5910 5911 ins_encode %{ 5912 __ movzwq($dst$$Register, $mem$$Address); 5913 %} 5914 5915 ins_pipe(ialu_reg_mem); 5916 %} 5917 5918 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5919 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5920 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5921 5922 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5923 ins_encode %{ 5924 __ movzbq($dst$$Register, $mem$$Address); 5925 %} 5926 ins_pipe(ialu_reg_mem); 5927 %} 5928 5929 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register 5930 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ 5931 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5932 effect(KILL cr); 5933 5934 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" 5935 "andl $dst, $mask" %} 5936 ins_encode %{ 5937 Register Rdst = $dst$$Register; 5938 __ movzwq(Rdst, $mem$$Address); 5939 __ andl(Rdst, $mask$$constant); 5940 %} 5941 ins_pipe(ialu_reg_mem); 5942 %} 5943 5944 // Load Integer 5945 instruct loadI(rRegI dst, memory mem) 5946 %{ 5947 match(Set dst (LoadI mem)); 5948 5949 ins_cost(125); 5950 format %{ "movl $dst, $mem\t# int" %} 5951 5952 ins_encode %{ 5953 __ movl($dst$$Register, $mem$$Address); 5954 %} 5955 5956 ins_pipe(ialu_reg_mem); 5957 %} 5958 5959 // Load Integer (32 bit signed) to Byte (8 bit signed) 5960 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5961 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5962 5963 ins_cost(125); 5964 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5965 ins_encode %{ 5966 __ movsbl($dst$$Register, $mem$$Address); 5967 %} 5968 ins_pipe(ialu_reg_mem); 5969 %} 5970 5971 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5972 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5973 match(Set dst (AndI (LoadI mem) mask)); 5974 5975 ins_cost(125); 5976 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5977 ins_encode %{ 5978 __ movzbl($dst$$Register, $mem$$Address); 5979 %} 5980 ins_pipe(ialu_reg_mem); 5981 %} 5982 5983 // Load Integer (32 bit signed) to Short (16 bit signed) 5984 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5985 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5986 5987 ins_cost(125); 5988 format %{ "movswl $dst, $mem\t# int -> short" %} 5989 ins_encode %{ 5990 __ movswl($dst$$Register, $mem$$Address); 5991 %} 5992 ins_pipe(ialu_reg_mem); 5993 %} 5994 5995 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5996 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5997 match(Set dst (AndI (LoadI mem) mask)); 5998 5999 ins_cost(125); 6000 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 6001 ins_encode %{ 6002 __ movzwl($dst$$Register, $mem$$Address); 6003 %} 6004 ins_pipe(ialu_reg_mem); 6005 %} 6006 6007 // Load Integer into Long Register 6008 instruct loadI2L(rRegL dst, memory mem) 6009 %{ 6010 match(Set dst (ConvI2L (LoadI mem))); 6011 6012 ins_cost(125); 6013 format %{ "movslq $dst, $mem\t# int -> long" %} 6014 6015 ins_encode %{ 6016 __ movslq($dst$$Register, $mem$$Address); 6017 %} 6018 6019 ins_pipe(ialu_reg_mem); 6020 %} 6021 6022 // Load Integer with mask 0xFF into Long Register 6023 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 6024 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6025 6026 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 6027 ins_encode %{ 6028 __ movzbq($dst$$Register, $mem$$Address); 6029 %} 6030 ins_pipe(ialu_reg_mem); 6031 %} 6032 6033 // Load Integer with mask 0xFFFF into Long Register 6034 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 6035 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6036 6037 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 6038 ins_encode %{ 6039 __ movzwq($dst$$Register, $mem$$Address); 6040 %} 6041 ins_pipe(ialu_reg_mem); 6042 %} 6043 6044 // Load Integer with a 32-bit mask into Long Register 6045 instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 6046 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6047 effect(KILL cr); 6048 6049 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t" 6050 "andl $dst, $mask" %} 6051 ins_encode %{ 6052 Register Rdst = $dst$$Register; 6053 __ movl(Rdst, $mem$$Address); 6054 __ andl(Rdst, $mask$$constant); 6055 %} 6056 ins_pipe(ialu_reg_mem); 6057 %} 6058 6059 // Load Unsigned Integer into Long Register 6060 instruct loadUI2L(rRegL dst, memory mem) 6061 %{ 6062 match(Set dst (LoadUI2L mem)); 6063 6064 ins_cost(125); 6065 format %{ "movl $dst, $mem\t# uint -> long" %} 6066 6067 ins_encode %{ 6068 __ movl($dst$$Register, $mem$$Address); 6069 %} 6070 6071 ins_pipe(ialu_reg_mem); 6072 %} 6073 6074 // Load Long 6075 instruct loadL(rRegL dst, memory mem) 6076 %{ 6077 match(Set dst (LoadL mem)); 6078 6079 ins_cost(125); 6080 format %{ "movq $dst, $mem\t# long" %} 6081 6082 ins_encode %{ 6083 __ movq($dst$$Register, $mem$$Address); 6084 %} 6085 6086 ins_pipe(ialu_reg_mem); // XXX 6087 %} 6088 6089 // Load Range 6090 instruct loadRange(rRegI dst, memory mem) 6091 %{ 6092 match(Set dst (LoadRange mem)); 6093 6094 ins_cost(125); // XXX 6095 format %{ "movl $dst, $mem\t# range" %} 6096 opcode(0x8B); 6097 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 6098 ins_pipe(ialu_reg_mem); 6099 %} 6100 6101 // Load Pointer 6102 instruct loadP(rRegP dst, memory mem) 6103 %{ 6104 match(Set dst (LoadP mem)); 6105 6106 ins_cost(125); // XXX 6107 format %{ "movq $dst, $mem\t# ptr" %} 6108 opcode(0x8B); 6109 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6110 ins_pipe(ialu_reg_mem); // XXX 6111 %} 6112 6113 // Load Compressed Pointer 6114 instruct loadN(rRegN dst, memory mem) 6115 %{ 6116 match(Set dst (LoadN mem)); 6117 6118 ins_cost(125); // XXX 6119 format %{ "movl $dst, $mem\t# compressed ptr" %} 6120 ins_encode %{ 6121 __ movl($dst$$Register, $mem$$Address); 6122 %} 6123 ins_pipe(ialu_reg_mem); // XXX 6124 %} 6125 6126 6127 // Load Klass Pointer 6128 instruct loadKlass(rRegP dst, memory mem) 6129 %{ 6130 match(Set dst (LoadKlass mem)); 6131 6132 ins_cost(125); // XXX 6133 format %{ "movq $dst, $mem\t# class" %} 6134 opcode(0x8B); 6135 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6136 ins_pipe(ialu_reg_mem); // XXX 6137 %} 6138 6139 // Load narrow Klass Pointer 6140 instruct loadNKlass(rRegN dst, memory mem) 6141 %{ 6142 match(Set dst (LoadNKlass mem)); 6143 6144 ins_cost(125); // XXX 6145 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 6146 ins_encode %{ 6147 __ movl($dst$$Register, $mem$$Address); 6148 %} 6149 ins_pipe(ialu_reg_mem); // XXX 6150 %} 6151 6152 // Load Float 6153 instruct loadF(regF dst, memory mem) 6154 %{ 6155 match(Set dst (LoadF mem)); 6156 6157 ins_cost(145); // XXX 6158 format %{ "movss $dst, $mem\t# float" %} 6159 opcode(0xF3, 0x0F, 0x10); 6160 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 6161 ins_pipe(pipe_slow); // XXX 6162 %} 6163 6164 // Load Double 6165 instruct loadD_partial(regD dst, memory mem) 6166 %{ 6167 predicate(!UseXmmLoadAndClearUpper); 6168 match(Set dst (LoadD mem)); 6169 6170 ins_cost(145); // XXX 6171 format %{ "movlpd $dst, $mem\t# double" %} 6172 opcode(0x66, 0x0F, 0x12); 6173 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 6174 ins_pipe(pipe_slow); // XXX 6175 %} 6176 6177 instruct loadD(regD dst, memory mem) 6178 %{ 6179 predicate(UseXmmLoadAndClearUpper); 6180 match(Set dst (LoadD mem)); 6181 6182 ins_cost(145); // XXX 6183 format %{ "movsd $dst, $mem\t# double" %} 6184 opcode(0xF2, 0x0F, 0x10); 6185 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 6186 ins_pipe(pipe_slow); // XXX 6187 %} 6188 6189 // Load Aligned Packed Byte to XMM register 6190 instruct loadA8B(regD dst, memory mem) %{ 6191 match(Set dst (Load8B mem)); 6192 ins_cost(125); 6193 format %{ "MOVQ $dst,$mem\t! packed8B" %} 6194 ins_encode( movq_ld(dst, mem)); 6195 ins_pipe( pipe_slow ); 6196 %} 6197 6198 // Load Aligned Packed Short to XMM register 6199 instruct loadA4S(regD dst, memory mem) %{ 6200 match(Set dst (Load4S mem)); 6201 ins_cost(125); 6202 format %{ "MOVQ $dst,$mem\t! packed4S" %} 6203 ins_encode( movq_ld(dst, mem)); 6204 ins_pipe( pipe_slow ); 6205 %} 6206 6207 // Load Aligned Packed Char to XMM register 6208 instruct loadA4C(regD dst, memory mem) %{ 6209 match(Set dst (Load4C mem)); 6210 ins_cost(125); 6211 format %{ "MOVQ $dst,$mem\t! packed4C" %} 6212 ins_encode( movq_ld(dst, mem)); 6213 ins_pipe( pipe_slow ); 6214 %} 6215 6216 // Load Aligned Packed Integer to XMM register 6217 instruct load2IU(regD dst, memory mem) %{ 6218 match(Set dst (Load2I mem)); 6219 ins_cost(125); 6220 format %{ "MOVQ $dst,$mem\t! packed2I" %} 6221 ins_encode( movq_ld(dst, mem)); 6222 ins_pipe( pipe_slow ); 6223 %} 6224 6225 // Load Aligned Packed Single to XMM 6226 instruct loadA2F(regD dst, memory mem) %{ 6227 match(Set dst (Load2F mem)); 6228 ins_cost(145); 6229 format %{ "MOVQ $dst,$mem\t! packed2F" %} 6230 ins_encode( movq_ld(dst, mem)); 6231 ins_pipe( pipe_slow ); 6232 %} 6233 6234 // Load Effective Address 6235 instruct leaP8(rRegP dst, indOffset8 mem) 6236 %{ 6237 match(Set dst mem); 6238 6239 ins_cost(110); // XXX 6240 format %{ "leaq $dst, $mem\t# ptr 8" %} 6241 opcode(0x8D); 6242 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6243 ins_pipe(ialu_reg_reg_fat); 6244 %} 6245 6246 instruct leaP32(rRegP dst, indOffset32 mem) 6247 %{ 6248 match(Set dst mem); 6249 6250 ins_cost(110); 6251 format %{ "leaq $dst, $mem\t# ptr 32" %} 6252 opcode(0x8D); 6253 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6254 ins_pipe(ialu_reg_reg_fat); 6255 %} 6256 6257 // instruct leaPIdx(rRegP dst, indIndex mem) 6258 // %{ 6259 // match(Set dst mem); 6260 6261 // ins_cost(110); 6262 // format %{ "leaq $dst, $mem\t# ptr idx" %} 6263 // opcode(0x8D); 6264 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6265 // ins_pipe(ialu_reg_reg_fat); 6266 // %} 6267 6268 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 6269 %{ 6270 match(Set dst mem); 6271 6272 ins_cost(110); 6273 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 6274 opcode(0x8D); 6275 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6276 ins_pipe(ialu_reg_reg_fat); 6277 %} 6278 6279 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 6280 %{ 6281 match(Set dst mem); 6282 6283 ins_cost(110); 6284 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 6285 opcode(0x8D); 6286 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6287 ins_pipe(ialu_reg_reg_fat); 6288 %} 6289 6290 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 6291 %{ 6292 match(Set dst mem); 6293 6294 ins_cost(110); 6295 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 6296 opcode(0x8D); 6297 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6298 ins_pipe(ialu_reg_reg_fat); 6299 %} 6300 6301 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 6302 %{ 6303 match(Set dst mem); 6304 6305 ins_cost(110); 6306 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 6307 opcode(0x8D); 6308 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6309 ins_pipe(ialu_reg_reg_fat); 6310 %} 6311 6312 // Load Effective Address which uses Narrow (32-bits) oop 6313 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 6314 %{ 6315 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 6316 match(Set dst mem); 6317 6318 ins_cost(110); 6319 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 6320 opcode(0x8D); 6321 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6322 ins_pipe(ialu_reg_reg_fat); 6323 %} 6324 6325 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 6326 %{ 6327 predicate(Universe::narrow_oop_shift() == 0); 6328 match(Set dst mem); 6329 6330 ins_cost(110); // XXX 6331 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 6332 opcode(0x8D); 6333 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6334 ins_pipe(ialu_reg_reg_fat); 6335 %} 6336 6337 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 6338 %{ 6339 predicate(Universe::narrow_oop_shift() == 0); 6340 match(Set dst mem); 6341 6342 ins_cost(110); 6343 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 6344 opcode(0x8D); 6345 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6346 ins_pipe(ialu_reg_reg_fat); 6347 %} 6348 6349 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 6350 %{ 6351 predicate(Universe::narrow_oop_shift() == 0); 6352 match(Set dst mem); 6353 6354 ins_cost(110); 6355 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 6356 opcode(0x8D); 6357 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6358 ins_pipe(ialu_reg_reg_fat); 6359 %} 6360 6361 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 6362 %{ 6363 predicate(Universe::narrow_oop_shift() == 0); 6364 match(Set dst mem); 6365 6366 ins_cost(110); 6367 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 6368 opcode(0x8D); 6369 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6370 ins_pipe(ialu_reg_reg_fat); 6371 %} 6372 6373 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 6374 %{ 6375 predicate(Universe::narrow_oop_shift() == 0); 6376 match(Set dst mem); 6377 6378 ins_cost(110); 6379 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 6380 opcode(0x8D); 6381 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6382 ins_pipe(ialu_reg_reg_fat); 6383 %} 6384 6385 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 6386 %{ 6387 predicate(Universe::narrow_oop_shift() == 0); 6388 match(Set dst mem); 6389 6390 ins_cost(110); 6391 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 6392 opcode(0x8D); 6393 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6394 ins_pipe(ialu_reg_reg_fat); 6395 %} 6396 6397 instruct loadConI(rRegI dst, immI src) 6398 %{ 6399 match(Set dst src); 6400 6401 format %{ "movl $dst, $src\t# int" %} 6402 ins_encode(load_immI(dst, src)); 6403 ins_pipe(ialu_reg_fat); // XXX 6404 %} 6405 6406 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 6407 %{ 6408 match(Set dst src); 6409 effect(KILL cr); 6410 6411 ins_cost(50); 6412 format %{ "xorl $dst, $dst\t# int" %} 6413 opcode(0x33); /* + rd */ 6414 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 6415 ins_pipe(ialu_reg); 6416 %} 6417 6418 instruct loadConL(rRegL dst, immL src) 6419 %{ 6420 match(Set dst src); 6421 6422 ins_cost(150); 6423 format %{ "movq $dst, $src\t# long" %} 6424 ins_encode(load_immL(dst, src)); 6425 ins_pipe(ialu_reg); 6426 %} 6427 6428 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 6429 %{ 6430 match(Set dst src); 6431 effect(KILL cr); 6432 6433 ins_cost(50); 6434 format %{ "xorl $dst, $dst\t# long" %} 6435 opcode(0x33); /* + rd */ 6436 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 6437 ins_pipe(ialu_reg); // XXX 6438 %} 6439 6440 instruct loadConUL32(rRegL dst, immUL32 src) 6441 %{ 6442 match(Set dst src); 6443 6444 ins_cost(60); 6445 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 6446 ins_encode(load_immUL32(dst, src)); 6447 ins_pipe(ialu_reg); 6448 %} 6449 6450 instruct loadConL32(rRegL dst, immL32 src) 6451 %{ 6452 match(Set dst src); 6453 6454 ins_cost(70); 6455 format %{ "movq $dst, $src\t# long (32-bit)" %} 6456 ins_encode(load_immL32(dst, src)); 6457 ins_pipe(ialu_reg); 6458 %} 6459 6460 instruct loadConP(rRegP dst, immP con) %{ 6461 match(Set dst con); 6462 6463 format %{ "movq $dst, $con\t# ptr" %} 6464 ins_encode(load_immP(dst, con)); 6465 ins_pipe(ialu_reg_fat); // XXX 6466 %} 6467 6468 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 6469 %{ 6470 match(Set dst src); 6471 effect(KILL cr); 6472 6473 ins_cost(50); 6474 format %{ "xorl $dst, $dst\t# ptr" %} 6475 opcode(0x33); /* + rd */ 6476 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 6477 ins_pipe(ialu_reg); 6478 %} 6479 6480 instruct loadConP_poll(rRegP dst, immP_poll src) %{ 6481 match(Set dst src); 6482 format %{ "movq $dst, $src\t!ptr" %} 6483 ins_encode %{ 6484 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type); 6485 __ lea($dst$$Register, polling_page); 6486 %} 6487 ins_pipe(ialu_reg_fat); 6488 %} 6489 6490 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 6491 %{ 6492 match(Set dst src); 6493 effect(KILL cr); 6494 6495 ins_cost(60); 6496 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 6497 ins_encode(load_immP31(dst, src)); 6498 ins_pipe(ialu_reg); 6499 %} 6500 6501 instruct loadConF(regF dst, immF con) %{ 6502 match(Set dst con); 6503 ins_cost(125); 6504 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 6505 ins_encode %{ 6506 __ movflt($dst$$XMMRegister, $constantaddress($con)); 6507 %} 6508 ins_pipe(pipe_slow); 6509 %} 6510 6511 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 6512 match(Set dst src); 6513 effect(KILL cr); 6514 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 6515 ins_encode %{ 6516 __ xorq($dst$$Register, $dst$$Register); 6517 %} 6518 ins_pipe(ialu_reg); 6519 %} 6520 6521 instruct loadConN(rRegN dst, immN src) %{ 6522 match(Set dst src); 6523 6524 ins_cost(125); 6525 format %{ "movl $dst, $src\t# compressed ptr" %} 6526 ins_encode %{ 6527 address con = (address)$src$$constant; 6528 if (con == NULL) { 6529 ShouldNotReachHere(); 6530 } else { 6531 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 6532 } 6533 %} 6534 ins_pipe(ialu_reg_fat); // XXX 6535 %} 6536 6537 instruct loadConF0(regF dst, immF0 src) 6538 %{ 6539 match(Set dst src); 6540 ins_cost(100); 6541 6542 format %{ "xorps $dst, $dst\t# float 0.0" %} 6543 opcode(0x0F, 0x57); 6544 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 6545 ins_pipe(pipe_slow); 6546 %} 6547 6548 // Use the same format since predicate() can not be used here. 6549 instruct loadConD(regD dst, immD con) %{ 6550 match(Set dst con); 6551 ins_cost(125); 6552 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 6553 ins_encode %{ 6554 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 6555 %} 6556 ins_pipe(pipe_slow); 6557 %} 6558 6559 instruct loadConD0(regD dst, immD0 src) 6560 %{ 6561 match(Set dst src); 6562 ins_cost(100); 6563 6564 format %{ "xorpd $dst, $dst\t# double 0.0" %} 6565 opcode(0x66, 0x0F, 0x57); 6566 ins_encode(OpcP, REX_reg_reg(dst, dst), OpcS, OpcT, reg_reg(dst, dst)); 6567 ins_pipe(pipe_slow); 6568 %} 6569 6570 instruct loadSSI(rRegI dst, stackSlotI src) 6571 %{ 6572 match(Set dst src); 6573 6574 ins_cost(125); 6575 format %{ "movl $dst, $src\t# int stk" %} 6576 opcode(0x8B); 6577 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6578 ins_pipe(ialu_reg_mem); 6579 %} 6580 6581 instruct loadSSL(rRegL dst, stackSlotL src) 6582 %{ 6583 match(Set dst src); 6584 6585 ins_cost(125); 6586 format %{ "movq $dst, $src\t# long stk" %} 6587 opcode(0x8B); 6588 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6589 ins_pipe(ialu_reg_mem); 6590 %} 6591 6592 instruct loadSSP(rRegP dst, stackSlotP src) 6593 %{ 6594 match(Set dst src); 6595 6596 ins_cost(125); 6597 format %{ "movq $dst, $src\t# ptr stk" %} 6598 opcode(0x8B); 6599 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6600 ins_pipe(ialu_reg_mem); 6601 %} 6602 6603 instruct loadSSF(regF dst, stackSlotF src) 6604 %{ 6605 match(Set dst src); 6606 6607 ins_cost(125); 6608 format %{ "movss $dst, $src\t# float stk" %} 6609 opcode(0xF3, 0x0F, 0x10); 6610 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 6611 ins_pipe(pipe_slow); // XXX 6612 %} 6613 6614 // Use the same format since predicate() can not be used here. 6615 instruct loadSSD(regD dst, stackSlotD src) 6616 %{ 6617 match(Set dst src); 6618 6619 ins_cost(125); 6620 format %{ "movsd $dst, $src\t# double stk" %} 6621 ins_encode %{ 6622 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 6623 %} 6624 ins_pipe(pipe_slow); // XXX 6625 %} 6626 6627 // Prefetch instructions. 6628 // Must be safe to execute with invalid address (cannot fault). 6629 6630 instruct prefetchr( memory mem ) %{ 6631 predicate(ReadPrefetchInstr==3); 6632 match(PrefetchRead mem); 6633 ins_cost(125); 6634 6635 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} 6636 ins_encode %{ 6637 __ prefetchr($mem$$Address); 6638 %} 6639 ins_pipe(ialu_mem); 6640 %} 6641 6642 instruct prefetchrNTA( memory mem ) %{ 6643 predicate(ReadPrefetchInstr==0); 6644 match(PrefetchRead mem); 6645 ins_cost(125); 6646 6647 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} 6648 ins_encode %{ 6649 __ prefetchnta($mem$$Address); 6650 %} 6651 ins_pipe(ialu_mem); 6652 %} 6653 6654 instruct prefetchrT0( memory mem ) %{ 6655 predicate(ReadPrefetchInstr==1); 6656 match(PrefetchRead mem); 6657 ins_cost(125); 6658 6659 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} 6660 ins_encode %{ 6661 __ prefetcht0($mem$$Address); 6662 %} 6663 ins_pipe(ialu_mem); 6664 %} 6665 6666 instruct prefetchrT2( memory mem ) %{ 6667 predicate(ReadPrefetchInstr==2); 6668 match(PrefetchRead mem); 6669 ins_cost(125); 6670 6671 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} 6672 ins_encode %{ 6673 __ prefetcht2($mem$$Address); 6674 %} 6675 ins_pipe(ialu_mem); 6676 %} 6677 6678 instruct prefetchwNTA( memory mem ) %{ 6679 match(PrefetchWrite mem); 6680 ins_cost(125); 6681 6682 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} 6683 ins_encode %{ 6684 __ prefetchnta($mem$$Address); 6685 %} 6686 ins_pipe(ialu_mem); 6687 %} 6688 6689 // Prefetch instructions for allocation. 6690 6691 instruct prefetchAlloc( memory mem ) %{ 6692 predicate(AllocatePrefetchInstr==3); 6693 match(PrefetchAllocation mem); 6694 ins_cost(125); 6695 6696 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 6697 ins_encode %{ 6698 __ prefetchw($mem$$Address); 6699 %} 6700 ins_pipe(ialu_mem); 6701 %} 6702 6703 instruct prefetchAllocNTA( memory mem ) %{ 6704 predicate(AllocatePrefetchInstr==0); 6705 match(PrefetchAllocation mem); 6706 ins_cost(125); 6707 6708 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 6709 ins_encode %{ 6710 __ prefetchnta($mem$$Address); 6711 %} 6712 ins_pipe(ialu_mem); 6713 %} 6714 6715 instruct prefetchAllocT0( memory mem ) %{ 6716 predicate(AllocatePrefetchInstr==1); 6717 match(PrefetchAllocation mem); 6718 ins_cost(125); 6719 6720 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 6721 ins_encode %{ 6722 __ prefetcht0($mem$$Address); 6723 %} 6724 ins_pipe(ialu_mem); 6725 %} 6726 6727 instruct prefetchAllocT2( memory mem ) %{ 6728 predicate(AllocatePrefetchInstr==2); 6729 match(PrefetchAllocation mem); 6730 ins_cost(125); 6731 6732 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 6733 ins_encode %{ 6734 __ prefetcht2($mem$$Address); 6735 %} 6736 ins_pipe(ialu_mem); 6737 %} 6738 6739 //----------Store Instructions------------------------------------------------- 6740 6741 // Store Byte 6742 instruct storeB(memory mem, rRegI src) 6743 %{ 6744 match(Set mem (StoreB mem src)); 6745 6746 ins_cost(125); // XXX 6747 format %{ "movb $mem, $src\t# byte" %} 6748 opcode(0x88); 6749 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 6750 ins_pipe(ialu_mem_reg); 6751 %} 6752 6753 // Store Char/Short 6754 instruct storeC(memory mem, rRegI src) 6755 %{ 6756 match(Set mem (StoreC mem src)); 6757 6758 ins_cost(125); // XXX 6759 format %{ "movw $mem, $src\t# char/short" %} 6760 opcode(0x89); 6761 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6762 ins_pipe(ialu_mem_reg); 6763 %} 6764 6765 // Store Integer 6766 instruct storeI(memory mem, rRegI src) 6767 %{ 6768 match(Set mem (StoreI mem src)); 6769 6770 ins_cost(125); // XXX 6771 format %{ "movl $mem, $src\t# int" %} 6772 opcode(0x89); 6773 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6774 ins_pipe(ialu_mem_reg); 6775 %} 6776 6777 // Store Long 6778 instruct storeL(memory mem, rRegL src) 6779 %{ 6780 match(Set mem (StoreL mem src)); 6781 6782 ins_cost(125); // XXX 6783 format %{ "movq $mem, $src\t# long" %} 6784 opcode(0x89); 6785 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6786 ins_pipe(ialu_mem_reg); // XXX 6787 %} 6788 6789 // Store Pointer 6790 instruct storeP(memory mem, any_RegP src) 6791 %{ 6792 match(Set mem (StoreP mem src)); 6793 6794 ins_cost(125); // XXX 6795 format %{ "movq $mem, $src\t# ptr" %} 6796 opcode(0x89); 6797 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6798 ins_pipe(ialu_mem_reg); 6799 %} 6800 6801 instruct storeImmP0(memory mem, immP0 zero) 6802 %{ 6803 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6804 match(Set mem (StoreP mem zero)); 6805 6806 ins_cost(125); // XXX 6807 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 6808 ins_encode %{ 6809 __ movq($mem$$Address, r12); 6810 %} 6811 ins_pipe(ialu_mem_reg); 6812 %} 6813 6814 // Store NULL Pointer, mark word, or other simple pointer constant. 6815 instruct storeImmP(memory mem, immP31 src) 6816 %{ 6817 match(Set mem (StoreP mem src)); 6818 6819 ins_cost(150); // XXX 6820 format %{ "movq $mem, $src\t# ptr" %} 6821 opcode(0xC7); /* C7 /0 */ 6822 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6823 ins_pipe(ialu_mem_imm); 6824 %} 6825 6826 // Store Compressed Pointer 6827 instruct storeN(memory mem, rRegN src) 6828 %{ 6829 match(Set mem (StoreN mem src)); 6830 6831 ins_cost(125); // XXX 6832 format %{ "movl $mem, $src\t# compressed ptr" %} 6833 ins_encode %{ 6834 __ movl($mem$$Address, $src$$Register); 6835 %} 6836 ins_pipe(ialu_mem_reg); 6837 %} 6838 6839 instruct storeImmN0(memory mem, immN0 zero) 6840 %{ 6841 predicate(Universe::narrow_oop_base() == NULL); 6842 match(Set mem (StoreN mem zero)); 6843 6844 ins_cost(125); // XXX 6845 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6846 ins_encode %{ 6847 __ movl($mem$$Address, r12); 6848 %} 6849 ins_pipe(ialu_mem_reg); 6850 %} 6851 6852 instruct storeImmN(memory mem, immN src) 6853 %{ 6854 match(Set mem (StoreN mem src)); 6855 6856 ins_cost(150); // XXX 6857 format %{ "movl $mem, $src\t# compressed ptr" %} 6858 ins_encode %{ 6859 address con = (address)$src$$constant; 6860 if (con == NULL) { 6861 __ movl($mem$$Address, (int32_t)0); 6862 } else { 6863 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6864 } 6865 %} 6866 ins_pipe(ialu_mem_imm); 6867 %} 6868 6869 // Store Integer Immediate 6870 instruct storeImmI0(memory mem, immI0 zero) 6871 %{ 6872 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6873 match(Set mem (StoreI mem zero)); 6874 6875 ins_cost(125); // XXX 6876 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6877 ins_encode %{ 6878 __ movl($mem$$Address, r12); 6879 %} 6880 ins_pipe(ialu_mem_reg); 6881 %} 6882 6883 instruct storeImmI(memory mem, immI src) 6884 %{ 6885 match(Set mem (StoreI mem src)); 6886 6887 ins_cost(150); 6888 format %{ "movl $mem, $src\t# int" %} 6889 opcode(0xC7); /* C7 /0 */ 6890 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6891 ins_pipe(ialu_mem_imm); 6892 %} 6893 6894 // Store Long Immediate 6895 instruct storeImmL0(memory mem, immL0 zero) 6896 %{ 6897 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6898 match(Set mem (StoreL mem zero)); 6899 6900 ins_cost(125); // XXX 6901 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6902 ins_encode %{ 6903 __ movq($mem$$Address, r12); 6904 %} 6905 ins_pipe(ialu_mem_reg); 6906 %} 6907 6908 instruct storeImmL(memory mem, immL32 src) 6909 %{ 6910 match(Set mem (StoreL mem src)); 6911 6912 ins_cost(150); 6913 format %{ "movq $mem, $src\t# long" %} 6914 opcode(0xC7); /* C7 /0 */ 6915 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6916 ins_pipe(ialu_mem_imm); 6917 %} 6918 6919 // Store Short/Char Immediate 6920 instruct storeImmC0(memory mem, immI0 zero) 6921 %{ 6922 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6923 match(Set mem (StoreC mem zero)); 6924 6925 ins_cost(125); // XXX 6926 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6927 ins_encode %{ 6928 __ movw($mem$$Address, r12); 6929 %} 6930 ins_pipe(ialu_mem_reg); 6931 %} 6932 6933 instruct storeImmI16(memory mem, immI16 src) 6934 %{ 6935 predicate(UseStoreImmI16); 6936 match(Set mem (StoreC mem src)); 6937 6938 ins_cost(150); 6939 format %{ "movw $mem, $src\t# short/char" %} 6940 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6941 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6942 ins_pipe(ialu_mem_imm); 6943 %} 6944 6945 // Store Byte Immediate 6946 instruct storeImmB0(memory mem, immI0 zero) 6947 %{ 6948 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6949 match(Set mem (StoreB mem zero)); 6950 6951 ins_cost(125); // XXX 6952 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6953 ins_encode %{ 6954 __ movb($mem$$Address, r12); 6955 %} 6956 ins_pipe(ialu_mem_reg); 6957 %} 6958 6959 instruct storeImmB(memory mem, immI8 src) 6960 %{ 6961 match(Set mem (StoreB mem src)); 6962 6963 ins_cost(150); // XXX 6964 format %{ "movb $mem, $src\t# byte" %} 6965 opcode(0xC6); /* C6 /0 */ 6966 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6967 ins_pipe(ialu_mem_imm); 6968 %} 6969 6970 // Store Aligned Packed Byte XMM register to memory 6971 instruct storeA8B(memory mem, regD src) %{ 6972 match(Set mem (Store8B mem src)); 6973 ins_cost(145); 6974 format %{ "MOVQ $mem,$src\t! packed8B" %} 6975 ins_encode( movq_st(mem, src)); 6976 ins_pipe( pipe_slow ); 6977 %} 6978 6979 // Store Aligned Packed Char/Short XMM register to memory 6980 instruct storeA4C(memory mem, regD src) %{ 6981 match(Set mem (Store4C mem src)); 6982 ins_cost(145); 6983 format %{ "MOVQ $mem,$src\t! packed4C" %} 6984 ins_encode( movq_st(mem, src)); 6985 ins_pipe( pipe_slow ); 6986 %} 6987 6988 // Store Aligned Packed Integer XMM register to memory 6989 instruct storeA2I(memory mem, regD src) %{ 6990 match(Set mem (Store2I mem src)); 6991 ins_cost(145); 6992 format %{ "MOVQ $mem,$src\t! packed2I" %} 6993 ins_encode( movq_st(mem, src)); 6994 ins_pipe( pipe_slow ); 6995 %} 6996 6997 // Store CMS card-mark Immediate 6998 instruct storeImmCM0_reg(memory mem, immI0 zero) 6999 %{ 7000 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 7001 match(Set mem (StoreCM mem zero)); 7002 7003 ins_cost(125); // XXX 7004 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 7005 ins_encode %{ 7006 __ movb($mem$$Address, r12); 7007 %} 7008 ins_pipe(ialu_mem_reg); 7009 %} 7010 7011 instruct storeImmCM0(memory mem, immI0 src) 7012 %{ 7013 match(Set mem (StoreCM mem src)); 7014 7015 ins_cost(150); // XXX 7016 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 7017 opcode(0xC6); /* C6 /0 */ 7018 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 7019 ins_pipe(ialu_mem_imm); 7020 %} 7021 7022 // Store Aligned Packed Single Float XMM register to memory 7023 instruct storeA2F(memory mem, regD src) %{ 7024 match(Set mem (Store2F mem src)); 7025 ins_cost(145); 7026 format %{ "MOVQ $mem,$src\t! packed2F" %} 7027 ins_encode( movq_st(mem, src)); 7028 ins_pipe( pipe_slow ); 7029 %} 7030 7031 // Store Float 7032 instruct storeF(memory mem, regF src) 7033 %{ 7034 match(Set mem (StoreF mem src)); 7035 7036 ins_cost(95); // XXX 7037 format %{ "movss $mem, $src\t# float" %} 7038 opcode(0xF3, 0x0F, 0x11); 7039 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem)); 7040 ins_pipe(pipe_slow); // XXX 7041 %} 7042 7043 // Store immediate Float value (it is faster than store from XMM register) 7044 instruct storeF0(memory mem, immF0 zero) 7045 %{ 7046 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 7047 match(Set mem (StoreF mem zero)); 7048 7049 ins_cost(25); // XXX 7050 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 7051 ins_encode %{ 7052 __ movl($mem$$Address, r12); 7053 %} 7054 ins_pipe(ialu_mem_reg); 7055 %} 7056 7057 instruct storeF_imm(memory mem, immF src) 7058 %{ 7059 match(Set mem (StoreF mem src)); 7060 7061 ins_cost(50); 7062 format %{ "movl $mem, $src\t# float" %} 7063 opcode(0xC7); /* C7 /0 */ 7064 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 7065 ins_pipe(ialu_mem_imm); 7066 %} 7067 7068 // Store Double 7069 instruct storeD(memory mem, regD src) 7070 %{ 7071 match(Set mem (StoreD mem src)); 7072 7073 ins_cost(95); // XXX 7074 format %{ "movsd $mem, $src\t# double" %} 7075 opcode(0xF2, 0x0F, 0x11); 7076 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem)); 7077 ins_pipe(pipe_slow); // XXX 7078 %} 7079 7080 // Store immediate double 0.0 (it is faster than store from XMM register) 7081 instruct storeD0_imm(memory mem, immD0 src) 7082 %{ 7083 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 7084 match(Set mem (StoreD mem src)); 7085 7086 ins_cost(50); 7087 format %{ "movq $mem, $src\t# double 0." %} 7088 opcode(0xC7); /* C7 /0 */ 7089 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 7090 ins_pipe(ialu_mem_imm); 7091 %} 7092 7093 instruct storeD0(memory mem, immD0 zero) 7094 %{ 7095 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 7096 match(Set mem (StoreD mem zero)); 7097 7098 ins_cost(25); // XXX 7099 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 7100 ins_encode %{ 7101 __ movq($mem$$Address, r12); 7102 %} 7103 ins_pipe(ialu_mem_reg); 7104 %} 7105 7106 instruct storeSSI(stackSlotI dst, rRegI src) 7107 %{ 7108 match(Set dst src); 7109 7110 ins_cost(100); 7111 format %{ "movl $dst, $src\t# int stk" %} 7112 opcode(0x89); 7113 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7114 ins_pipe( ialu_mem_reg ); 7115 %} 7116 7117 instruct storeSSL(stackSlotL dst, rRegL src) 7118 %{ 7119 match(Set dst src); 7120 7121 ins_cost(100); 7122 format %{ "movq $dst, $src\t# long stk" %} 7123 opcode(0x89); 7124 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7125 ins_pipe(ialu_mem_reg); 7126 %} 7127 7128 instruct storeSSP(stackSlotP dst, rRegP src) 7129 %{ 7130 match(Set dst src); 7131 7132 ins_cost(100); 7133 format %{ "movq $dst, $src\t# ptr stk" %} 7134 opcode(0x89); 7135 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7136 ins_pipe(ialu_mem_reg); 7137 %} 7138 7139 instruct storeSSF(stackSlotF dst, regF src) 7140 %{ 7141 match(Set dst src); 7142 7143 ins_cost(95); // XXX 7144 format %{ "movss $dst, $src\t# float stk" %} 7145 opcode(0xF3, 0x0F, 0x11); 7146 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 7147 ins_pipe(pipe_slow); // XXX 7148 %} 7149 7150 instruct storeSSD(stackSlotD dst, regD src) 7151 %{ 7152 match(Set dst src); 7153 7154 ins_cost(95); // XXX 7155 format %{ "movsd $dst, $src\t# double stk" %} 7156 opcode(0xF2, 0x0F, 0x11); 7157 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 7158 ins_pipe(pipe_slow); // XXX 7159 %} 7160 7161 //----------BSWAP Instructions------------------------------------------------- 7162 instruct bytes_reverse_int(rRegI dst) %{ 7163 match(Set dst (ReverseBytesI dst)); 7164 7165 format %{ "bswapl $dst" %} 7166 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 7167 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 7168 ins_pipe( ialu_reg ); 7169 %} 7170 7171 instruct bytes_reverse_long(rRegL dst) %{ 7172 match(Set dst (ReverseBytesL dst)); 7173 7174 format %{ "bswapq $dst" %} 7175 7176 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 7177 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 7178 ins_pipe( ialu_reg); 7179 %} 7180 7181 instruct bytes_reverse_unsigned_short(rRegI dst) %{ 7182 match(Set dst (ReverseBytesUS dst)); 7183 7184 format %{ "bswapl $dst\n\t" 7185 "shrl $dst,16\n\t" %} 7186 ins_encode %{ 7187 __ bswapl($dst$$Register); 7188 __ shrl($dst$$Register, 16); 7189 %} 7190 ins_pipe( ialu_reg ); 7191 %} 7192 7193 instruct bytes_reverse_short(rRegI dst) %{ 7194 match(Set dst (ReverseBytesS dst)); 7195 7196 format %{ "bswapl $dst\n\t" 7197 "sar $dst,16\n\t" %} 7198 ins_encode %{ 7199 __ bswapl($dst$$Register); 7200 __ sarl($dst$$Register, 16); 7201 %} 7202 ins_pipe( ialu_reg ); 7203 %} 7204 7205 //---------- Zeros Count Instructions ------------------------------------------ 7206 7207 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 7208 predicate(UseCountLeadingZerosInstruction); 7209 match(Set dst (CountLeadingZerosI src)); 7210 effect(KILL cr); 7211 7212 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 7213 ins_encode %{ 7214 __ lzcntl($dst$$Register, $src$$Register); 7215 %} 7216 ins_pipe(ialu_reg); 7217 %} 7218 7219 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 7220 predicate(!UseCountLeadingZerosInstruction); 7221 match(Set dst (CountLeadingZerosI src)); 7222 effect(KILL cr); 7223 7224 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 7225 "jnz skip\n\t" 7226 "movl $dst, -1\n" 7227 "skip:\n\t" 7228 "negl $dst\n\t" 7229 "addl $dst, 31" %} 7230 ins_encode %{ 7231 Register Rdst = $dst$$Register; 7232 Register Rsrc = $src$$Register; 7233 Label skip; 7234 __ bsrl(Rdst, Rsrc); 7235 __ jccb(Assembler::notZero, skip); 7236 __ movl(Rdst, -1); 7237 __ bind(skip); 7238 __ negl(Rdst); 7239 __ addl(Rdst, BitsPerInt - 1); 7240 %} 7241 ins_pipe(ialu_reg); 7242 %} 7243 7244 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 7245 predicate(UseCountLeadingZerosInstruction); 7246 match(Set dst (CountLeadingZerosL src)); 7247 effect(KILL cr); 7248 7249 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 7250 ins_encode %{ 7251 __ lzcntq($dst$$Register, $src$$Register); 7252 %} 7253 ins_pipe(ialu_reg); 7254 %} 7255 7256 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 7257 predicate(!UseCountLeadingZerosInstruction); 7258 match(Set dst (CountLeadingZerosL src)); 7259 effect(KILL cr); 7260 7261 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 7262 "jnz skip\n\t" 7263 "movl $dst, -1\n" 7264 "skip:\n\t" 7265 "negl $dst\n\t" 7266 "addl $dst, 63" %} 7267 ins_encode %{ 7268 Register Rdst = $dst$$Register; 7269 Register Rsrc = $src$$Register; 7270 Label skip; 7271 __ bsrq(Rdst, Rsrc); 7272 __ jccb(Assembler::notZero, skip); 7273 __ movl(Rdst, -1); 7274 __ bind(skip); 7275 __ negl(Rdst); 7276 __ addl(Rdst, BitsPerLong - 1); 7277 %} 7278 ins_pipe(ialu_reg); 7279 %} 7280 7281 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 7282 match(Set dst (CountTrailingZerosI src)); 7283 effect(KILL cr); 7284 7285 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 7286 "jnz done\n\t" 7287 "movl $dst, 32\n" 7288 "done:" %} 7289 ins_encode %{ 7290 Register Rdst = $dst$$Register; 7291 Label done; 7292 __ bsfl(Rdst, $src$$Register); 7293 __ jccb(Assembler::notZero, done); 7294 __ movl(Rdst, BitsPerInt); 7295 __ bind(done); 7296 %} 7297 ins_pipe(ialu_reg); 7298 %} 7299 7300 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 7301 match(Set dst (CountTrailingZerosL src)); 7302 effect(KILL cr); 7303 7304 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 7305 "jnz done\n\t" 7306 "movl $dst, 64\n" 7307 "done:" %} 7308 ins_encode %{ 7309 Register Rdst = $dst$$Register; 7310 Label done; 7311 __ bsfq(Rdst, $src$$Register); 7312 __ jccb(Assembler::notZero, done); 7313 __ movl(Rdst, BitsPerLong); 7314 __ bind(done); 7315 %} 7316 ins_pipe(ialu_reg); 7317 %} 7318 7319 7320 //---------- Population Count Instructions ------------------------------------- 7321 7322 instruct popCountI(rRegI dst, rRegI src) %{ 7323 predicate(UsePopCountInstruction); 7324 match(Set dst (PopCountI src)); 7325 7326 format %{ "popcnt $dst, $src" %} 7327 ins_encode %{ 7328 __ popcntl($dst$$Register, $src$$Register); 7329 %} 7330 ins_pipe(ialu_reg); 7331 %} 7332 7333 instruct popCountI_mem(rRegI dst, memory mem) %{ 7334 predicate(UsePopCountInstruction); 7335 match(Set dst (PopCountI (LoadI mem))); 7336 7337 format %{ "popcnt $dst, $mem" %} 7338 ins_encode %{ 7339 __ popcntl($dst$$Register, $mem$$Address); 7340 %} 7341 ins_pipe(ialu_reg); 7342 %} 7343 7344 // Note: Long.bitCount(long) returns an int. 7345 instruct popCountL(rRegI dst, rRegL src) %{ 7346 predicate(UsePopCountInstruction); 7347 match(Set dst (PopCountL src)); 7348 7349 format %{ "popcnt $dst, $src" %} 7350 ins_encode %{ 7351 __ popcntq($dst$$Register, $src$$Register); 7352 %} 7353 ins_pipe(ialu_reg); 7354 %} 7355 7356 // Note: Long.bitCount(long) returns an int. 7357 instruct popCountL_mem(rRegI dst, memory mem) %{ 7358 predicate(UsePopCountInstruction); 7359 match(Set dst (PopCountL (LoadL mem))); 7360 7361 format %{ "popcnt $dst, $mem" %} 7362 ins_encode %{ 7363 __ popcntq($dst$$Register, $mem$$Address); 7364 %} 7365 ins_pipe(ialu_reg); 7366 %} 7367 7368 7369 //----------MemBar Instructions----------------------------------------------- 7370 // Memory barrier flavors 7371 7372 instruct membar_acquire() 7373 %{ 7374 match(MemBarAcquire); 7375 ins_cost(0); 7376 7377 size(0); 7378 format %{ "MEMBAR-acquire ! (empty encoding)" %} 7379 ins_encode(); 7380 ins_pipe(empty); 7381 %} 7382 7383 instruct membar_acquire_lock() 7384 %{ 7385 match(MemBarAcquireLock); 7386 ins_cost(0); 7387 7388 size(0); 7389 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 7390 ins_encode(); 7391 ins_pipe(empty); 7392 %} 7393 7394 instruct membar_release() 7395 %{ 7396 match(MemBarRelease); 7397 ins_cost(0); 7398 7399 size(0); 7400 format %{ "MEMBAR-release ! (empty encoding)" %} 7401 ins_encode(); 7402 ins_pipe(empty); 7403 %} 7404 7405 instruct membar_release_lock() 7406 %{ 7407 match(MemBarReleaseLock); 7408 ins_cost(0); 7409 7410 size(0); 7411 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 7412 ins_encode(); 7413 ins_pipe(empty); 7414 %} 7415 7416 instruct membar_volatile(rFlagsReg cr) %{ 7417 match(MemBarVolatile); 7418 effect(KILL cr); 7419 ins_cost(400); 7420 7421 format %{ 7422 $$template 7423 if (os::is_MP()) { 7424 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 7425 } else { 7426 $$emit$$"MEMBAR-volatile ! (empty encoding)" 7427 } 7428 %} 7429 ins_encode %{ 7430 __ membar(Assembler::StoreLoad); 7431 %} 7432 ins_pipe(pipe_slow); 7433 %} 7434 7435 instruct unnecessary_membar_volatile() 7436 %{ 7437 match(MemBarVolatile); 7438 predicate(Matcher::post_store_load_barrier(n)); 7439 ins_cost(0); 7440 7441 size(0); 7442 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 7443 ins_encode(); 7444 ins_pipe(empty); 7445 %} 7446 7447 instruct unnecessary_membar_storestore() %{ 7448 match(MemBarStoreStore); 7449 ins_cost(0); 7450 7451 size(0); 7452 format %{ "!MEMBAR-storestore (unnecessary so empty encoding)" %} 7453 ins_encode( ); 7454 ins_pipe(empty); 7455 %} 7456 7457 //----------Move Instructions-------------------------------------------------- 7458 7459 instruct castX2P(rRegP dst, rRegL src) 7460 %{ 7461 match(Set dst (CastX2P src)); 7462 7463 format %{ "movq $dst, $src\t# long->ptr" %} 7464 ins_encode(enc_copy_wide(dst, src)); 7465 ins_pipe(ialu_reg_reg); // XXX 7466 %} 7467 7468 instruct castP2X(rRegL dst, rRegP src) 7469 %{ 7470 match(Set dst (CastP2X src)); 7471 7472 format %{ "movq $dst, $src\t# ptr -> long" %} 7473 ins_encode(enc_copy_wide(dst, src)); 7474 ins_pipe(ialu_reg_reg); // XXX 7475 %} 7476 7477 7478 // Convert oop pointer into compressed form 7479 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 7480 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7481 match(Set dst (EncodeP src)); 7482 effect(KILL cr); 7483 format %{ "encode_heap_oop $dst,$src" %} 7484 ins_encode %{ 7485 Register s = $src$$Register; 7486 Register d = $dst$$Register; 7487 if (s != d) { 7488 __ movq(d, s); 7489 } 7490 __ encode_heap_oop(d); 7491 %} 7492 ins_pipe(ialu_reg_long); 7493 %} 7494 7495 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 7496 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7497 match(Set dst (EncodeP src)); 7498 effect(KILL cr); 7499 format %{ "encode_heap_oop_not_null $dst,$src" %} 7500 ins_encode %{ 7501 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7502 %} 7503 ins_pipe(ialu_reg_long); 7504 %} 7505 7506 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 7507 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7508 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant); 7509 match(Set dst (DecodeN src)); 7510 effect(KILL cr); 7511 format %{ "decode_heap_oop $dst,$src" %} 7512 ins_encode %{ 7513 Register s = $src$$Register; 7514 Register d = $dst$$Register; 7515 if (s != d) { 7516 __ movq(d, s); 7517 } 7518 __ decode_heap_oop(d); 7519 %} 7520 ins_pipe(ialu_reg_long); 7521 %} 7522 7523 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 7524 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7525 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); 7526 match(Set dst (DecodeN src)); 7527 effect(KILL cr); 7528 format %{ "decode_heap_oop_not_null $dst,$src" %} 7529 ins_encode %{ 7530 Register s = $src$$Register; 7531 Register d = $dst$$Register; 7532 if (s != d) { 7533 __ decode_heap_oop_not_null(d, s); 7534 } else { 7535 __ decode_heap_oop_not_null(d); 7536 } 7537 %} 7538 ins_pipe(ialu_reg_long); 7539 %} 7540 7541 7542 //----------Conditional Move--------------------------------------------------- 7543 // Jump 7544 // dummy instruction for generating temp registers 7545 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 7546 match(Jump (LShiftL switch_val shift)); 7547 ins_cost(350); 7548 predicate(false); 7549 effect(TEMP dest); 7550 7551 format %{ "leaq $dest, [$constantaddress]\n\t" 7552 "jmp [$dest + $switch_val << $shift]\n\t" %} 7553 ins_encode %{ 7554 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7555 // to do that and the compiler is using that register as one it can allocate. 7556 // So we build it all by hand. 7557 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 7558 // ArrayAddress dispatch(table, index); 7559 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 7560 __ lea($dest$$Register, $constantaddress); 7561 __ jmp(dispatch); 7562 %} 7563 ins_pipe(pipe_jmp); 7564 %} 7565 7566 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 7567 match(Jump (AddL (LShiftL switch_val shift) offset)); 7568 ins_cost(350); 7569 effect(TEMP dest); 7570 7571 format %{ "leaq $dest, [$constantaddress]\n\t" 7572 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 7573 ins_encode %{ 7574 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7575 // to do that and the compiler is using that register as one it can allocate. 7576 // So we build it all by hand. 7577 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7578 // ArrayAddress dispatch(table, index); 7579 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7580 __ lea($dest$$Register, $constantaddress); 7581 __ jmp(dispatch); 7582 %} 7583 ins_pipe(pipe_jmp); 7584 %} 7585 7586 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 7587 match(Jump switch_val); 7588 ins_cost(350); 7589 effect(TEMP dest); 7590 7591 format %{ "leaq $dest, [$constantaddress]\n\t" 7592 "jmp [$dest + $switch_val]\n\t" %} 7593 ins_encode %{ 7594 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7595 // to do that and the compiler is using that register as one it can allocate. 7596 // So we build it all by hand. 7597 // Address index(noreg, switch_reg, Address::times_1); 7598 // ArrayAddress dispatch(table, index); 7599 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 7600 __ lea($dest$$Register, $constantaddress); 7601 __ jmp(dispatch); 7602 %} 7603 ins_pipe(pipe_jmp); 7604 %} 7605 7606 // Conditional move 7607 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 7608 %{ 7609 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7610 7611 ins_cost(200); // XXX 7612 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7613 opcode(0x0F, 0x40); 7614 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7615 ins_pipe(pipe_cmov_reg); 7616 %} 7617 7618 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 7619 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7620 7621 ins_cost(200); // XXX 7622 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7623 opcode(0x0F, 0x40); 7624 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7625 ins_pipe(pipe_cmov_reg); 7626 %} 7627 7628 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 7629 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7630 ins_cost(200); 7631 expand %{ 7632 cmovI_regU(cop, cr, dst, src); 7633 %} 7634 %} 7635 7636 // Conditional move 7637 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 7638 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7639 7640 ins_cost(250); // XXX 7641 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7642 opcode(0x0F, 0x40); 7643 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7644 ins_pipe(pipe_cmov_mem); 7645 %} 7646 7647 // Conditional move 7648 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 7649 %{ 7650 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7651 7652 ins_cost(250); // XXX 7653 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7654 opcode(0x0F, 0x40); 7655 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7656 ins_pipe(pipe_cmov_mem); 7657 %} 7658 7659 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 7660 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7661 ins_cost(250); 7662 expand %{ 7663 cmovI_memU(cop, cr, dst, src); 7664 %} 7665 %} 7666 7667 // Conditional move 7668 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 7669 %{ 7670 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7671 7672 ins_cost(200); // XXX 7673 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 7674 opcode(0x0F, 0x40); 7675 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7676 ins_pipe(pipe_cmov_reg); 7677 %} 7678 7679 // Conditional move 7680 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 7681 %{ 7682 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7683 7684 ins_cost(200); // XXX 7685 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 7686 opcode(0x0F, 0x40); 7687 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7688 ins_pipe(pipe_cmov_reg); 7689 %} 7690 7691 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 7692 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7693 ins_cost(200); 7694 expand %{ 7695 cmovN_regU(cop, cr, dst, src); 7696 %} 7697 %} 7698 7699 // Conditional move 7700 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7701 %{ 7702 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7703 7704 ins_cost(200); // XXX 7705 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 7706 opcode(0x0F, 0x40); 7707 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7708 ins_pipe(pipe_cmov_reg); // XXX 7709 %} 7710 7711 // Conditional move 7712 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 7713 %{ 7714 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7715 7716 ins_cost(200); // XXX 7717 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7718 opcode(0x0F, 0x40); 7719 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7720 ins_pipe(pipe_cmov_reg); // XXX 7721 %} 7722 7723 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 7724 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7725 ins_cost(200); 7726 expand %{ 7727 cmovP_regU(cop, cr, dst, src); 7728 %} 7729 %} 7730 7731 // DISABLED: Requires the ADLC to emit a bottom_type call that 7732 // correctly meets the two pointer arguments; one is an incoming 7733 // register but the other is a memory operand. ALSO appears to 7734 // be buggy with implicit null checks. 7735 // 7736 //// Conditional move 7737 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7738 //%{ 7739 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7740 // ins_cost(250); 7741 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7742 // opcode(0x0F,0x40); 7743 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7744 // ins_pipe( pipe_cmov_mem ); 7745 //%} 7746 // 7747 //// Conditional move 7748 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7749 //%{ 7750 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7751 // ins_cost(250); 7752 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7753 // opcode(0x0F,0x40); 7754 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7755 // ins_pipe( pipe_cmov_mem ); 7756 //%} 7757 7758 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7759 %{ 7760 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7761 7762 ins_cost(200); // XXX 7763 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7764 opcode(0x0F, 0x40); 7765 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7766 ins_pipe(pipe_cmov_reg); // XXX 7767 %} 7768 7769 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7770 %{ 7771 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7772 7773 ins_cost(200); // XXX 7774 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7775 opcode(0x0F, 0x40); 7776 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7777 ins_pipe(pipe_cmov_mem); // XXX 7778 %} 7779 7780 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7781 %{ 7782 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7783 7784 ins_cost(200); // XXX 7785 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7786 opcode(0x0F, 0x40); 7787 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7788 ins_pipe(pipe_cmov_reg); // XXX 7789 %} 7790 7791 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7792 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7793 ins_cost(200); 7794 expand %{ 7795 cmovL_regU(cop, cr, dst, src); 7796 %} 7797 %} 7798 7799 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7800 %{ 7801 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7802 7803 ins_cost(200); // XXX 7804 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7805 opcode(0x0F, 0x40); 7806 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7807 ins_pipe(pipe_cmov_mem); // XXX 7808 %} 7809 7810 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7811 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7812 ins_cost(200); 7813 expand %{ 7814 cmovL_memU(cop, cr, dst, src); 7815 %} 7816 %} 7817 7818 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7819 %{ 7820 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7821 7822 ins_cost(200); // XXX 7823 format %{ "jn$cop skip\t# signed cmove float\n\t" 7824 "movss $dst, $src\n" 7825 "skip:" %} 7826 ins_encode(enc_cmovf_branch(cop, dst, src)); 7827 ins_pipe(pipe_slow); 7828 %} 7829 7830 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7831 // %{ 7832 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7833 7834 // ins_cost(200); // XXX 7835 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7836 // "movss $dst, $src\n" 7837 // "skip:" %} 7838 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7839 // ins_pipe(pipe_slow); 7840 // %} 7841 7842 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7843 %{ 7844 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7845 7846 ins_cost(200); // XXX 7847 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7848 "movss $dst, $src\n" 7849 "skip:" %} 7850 ins_encode(enc_cmovf_branch(cop, dst, src)); 7851 ins_pipe(pipe_slow); 7852 %} 7853 7854 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7855 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7856 ins_cost(200); 7857 expand %{ 7858 cmovF_regU(cop, cr, dst, src); 7859 %} 7860 %} 7861 7862 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7863 %{ 7864 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7865 7866 ins_cost(200); // XXX 7867 format %{ "jn$cop skip\t# signed cmove double\n\t" 7868 "movsd $dst, $src\n" 7869 "skip:" %} 7870 ins_encode(enc_cmovd_branch(cop, dst, src)); 7871 ins_pipe(pipe_slow); 7872 %} 7873 7874 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7875 %{ 7876 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7877 7878 ins_cost(200); // XXX 7879 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7880 "movsd $dst, $src\n" 7881 "skip:" %} 7882 ins_encode(enc_cmovd_branch(cop, dst, src)); 7883 ins_pipe(pipe_slow); 7884 %} 7885 7886 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7887 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7888 ins_cost(200); 7889 expand %{ 7890 cmovD_regU(cop, cr, dst, src); 7891 %} 7892 %} 7893 7894 //----------Arithmetic Instructions-------------------------------------------- 7895 //----------Addition Instructions---------------------------------------------- 7896 7897 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7898 %{ 7899 match(Set dst (AddI dst src)); 7900 effect(KILL cr); 7901 7902 format %{ "addl $dst, $src\t# int" %} 7903 opcode(0x03); 7904 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7905 ins_pipe(ialu_reg_reg); 7906 %} 7907 7908 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7909 %{ 7910 match(Set dst (AddI dst src)); 7911 effect(KILL cr); 7912 7913 format %{ "addl $dst, $src\t# int" %} 7914 opcode(0x81, 0x00); /* /0 id */ 7915 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7916 ins_pipe( ialu_reg ); 7917 %} 7918 7919 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7920 %{ 7921 match(Set dst (AddI dst (LoadI src))); 7922 effect(KILL cr); 7923 7924 ins_cost(125); // XXX 7925 format %{ "addl $dst, $src\t# int" %} 7926 opcode(0x03); 7927 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7928 ins_pipe(ialu_reg_mem); 7929 %} 7930 7931 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7932 %{ 7933 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7934 effect(KILL cr); 7935 7936 ins_cost(150); // XXX 7937 format %{ "addl $dst, $src\t# int" %} 7938 opcode(0x01); /* Opcode 01 /r */ 7939 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7940 ins_pipe(ialu_mem_reg); 7941 %} 7942 7943 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7944 %{ 7945 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7946 effect(KILL cr); 7947 7948 ins_cost(125); // XXX 7949 format %{ "addl $dst, $src\t# int" %} 7950 opcode(0x81); /* Opcode 81 /0 id */ 7951 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7952 ins_pipe(ialu_mem_imm); 7953 %} 7954 7955 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7956 %{ 7957 predicate(UseIncDec); 7958 match(Set dst (AddI dst src)); 7959 effect(KILL cr); 7960 7961 format %{ "incl $dst\t# int" %} 7962 opcode(0xFF, 0x00); // FF /0 7963 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7964 ins_pipe(ialu_reg); 7965 %} 7966 7967 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7968 %{ 7969 predicate(UseIncDec); 7970 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7971 effect(KILL cr); 7972 7973 ins_cost(125); // XXX 7974 format %{ "incl $dst\t# int" %} 7975 opcode(0xFF); /* Opcode FF /0 */ 7976 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7977 ins_pipe(ialu_mem_imm); 7978 %} 7979 7980 // XXX why does that use AddI 7981 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7982 %{ 7983 predicate(UseIncDec); 7984 match(Set dst (AddI dst src)); 7985 effect(KILL cr); 7986 7987 format %{ "decl $dst\t# int" %} 7988 opcode(0xFF, 0x01); // FF /1 7989 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7990 ins_pipe(ialu_reg); 7991 %} 7992 7993 // XXX why does that use AddI 7994 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7995 %{ 7996 predicate(UseIncDec); 7997 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7998 effect(KILL cr); 7999 8000 ins_cost(125); // XXX 8001 format %{ "decl $dst\t# int" %} 8002 opcode(0xFF); /* Opcode FF /1 */ 8003 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 8004 ins_pipe(ialu_mem_imm); 8005 %} 8006 8007 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 8008 %{ 8009 match(Set dst (AddI src0 src1)); 8010 8011 ins_cost(110); 8012 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 8013 opcode(0x8D); /* 0x8D /r */ 8014 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 8015 ins_pipe(ialu_reg_reg); 8016 %} 8017 8018 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8019 %{ 8020 match(Set dst (AddL dst src)); 8021 effect(KILL cr); 8022 8023 format %{ "addq $dst, $src\t# long" %} 8024 opcode(0x03); 8025 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8026 ins_pipe(ialu_reg_reg); 8027 %} 8028 8029 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 8030 %{ 8031 match(Set dst (AddL dst src)); 8032 effect(KILL cr); 8033 8034 format %{ "addq $dst, $src\t# long" %} 8035 opcode(0x81, 0x00); /* /0 id */ 8036 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8037 ins_pipe( ialu_reg ); 8038 %} 8039 8040 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8041 %{ 8042 match(Set dst (AddL dst (LoadL src))); 8043 effect(KILL cr); 8044 8045 ins_cost(125); // XXX 8046 format %{ "addq $dst, $src\t# long" %} 8047 opcode(0x03); 8048 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8049 ins_pipe(ialu_reg_mem); 8050 %} 8051 8052 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8053 %{ 8054 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 8055 effect(KILL cr); 8056 8057 ins_cost(150); // XXX 8058 format %{ "addq $dst, $src\t# long" %} 8059 opcode(0x01); /* Opcode 01 /r */ 8060 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8061 ins_pipe(ialu_mem_reg); 8062 %} 8063 8064 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8065 %{ 8066 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 8067 effect(KILL cr); 8068 8069 ins_cost(125); // XXX 8070 format %{ "addq $dst, $src\t# long" %} 8071 opcode(0x81); /* Opcode 81 /0 id */ 8072 ins_encode(REX_mem_wide(dst), 8073 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 8074 ins_pipe(ialu_mem_imm); 8075 %} 8076 8077 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 8078 %{ 8079 predicate(UseIncDec); 8080 match(Set dst (AddL dst src)); 8081 effect(KILL cr); 8082 8083 format %{ "incq $dst\t# long" %} 8084 opcode(0xFF, 0x00); // FF /0 8085 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8086 ins_pipe(ialu_reg); 8087 %} 8088 8089 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 8090 %{ 8091 predicate(UseIncDec); 8092 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 8093 effect(KILL cr); 8094 8095 ins_cost(125); // XXX 8096 format %{ "incq $dst\t# long" %} 8097 opcode(0xFF); /* Opcode FF /0 */ 8098 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 8099 ins_pipe(ialu_mem_imm); 8100 %} 8101 8102 // XXX why does that use AddL 8103 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 8104 %{ 8105 predicate(UseIncDec); 8106 match(Set dst (AddL dst src)); 8107 effect(KILL cr); 8108 8109 format %{ "decq $dst\t# long" %} 8110 opcode(0xFF, 0x01); // FF /1 8111 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8112 ins_pipe(ialu_reg); 8113 %} 8114 8115 // XXX why does that use AddL 8116 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 8117 %{ 8118 predicate(UseIncDec); 8119 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 8120 effect(KILL cr); 8121 8122 ins_cost(125); // XXX 8123 format %{ "decq $dst\t# long" %} 8124 opcode(0xFF); /* Opcode FF /1 */ 8125 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 8126 ins_pipe(ialu_mem_imm); 8127 %} 8128 8129 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 8130 %{ 8131 match(Set dst (AddL src0 src1)); 8132 8133 ins_cost(110); 8134 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 8135 opcode(0x8D); /* 0x8D /r */ 8136 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 8137 ins_pipe(ialu_reg_reg); 8138 %} 8139 8140 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 8141 %{ 8142 match(Set dst (AddP dst src)); 8143 effect(KILL cr); 8144 8145 format %{ "addq $dst, $src\t# ptr" %} 8146 opcode(0x03); 8147 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8148 ins_pipe(ialu_reg_reg); 8149 %} 8150 8151 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 8152 %{ 8153 match(Set dst (AddP dst src)); 8154 effect(KILL cr); 8155 8156 format %{ "addq $dst, $src\t# ptr" %} 8157 opcode(0x81, 0x00); /* /0 id */ 8158 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8159 ins_pipe( ialu_reg ); 8160 %} 8161 8162 // XXX addP mem ops ???? 8163 8164 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 8165 %{ 8166 match(Set dst (AddP src0 src1)); 8167 8168 ins_cost(110); 8169 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 8170 opcode(0x8D); /* 0x8D /r */ 8171 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 8172 ins_pipe(ialu_reg_reg); 8173 %} 8174 8175 instruct checkCastPP(rRegP dst) 8176 %{ 8177 match(Set dst (CheckCastPP dst)); 8178 8179 size(0); 8180 format %{ "# checkcastPP of $dst" %} 8181 ins_encode(/* empty encoding */); 8182 ins_pipe(empty); 8183 %} 8184 8185 instruct castPP(rRegP dst) 8186 %{ 8187 match(Set dst (CastPP dst)); 8188 8189 size(0); 8190 format %{ "# castPP of $dst" %} 8191 ins_encode(/* empty encoding */); 8192 ins_pipe(empty); 8193 %} 8194 8195 instruct castII(rRegI dst) 8196 %{ 8197 match(Set dst (CastII dst)); 8198 8199 size(0); 8200 format %{ "# castII of $dst" %} 8201 ins_encode(/* empty encoding */); 8202 ins_cost(0); 8203 ins_pipe(empty); 8204 %} 8205 8206 // LoadP-locked same as a regular LoadP when used with compare-swap 8207 instruct loadPLocked(rRegP dst, memory mem) 8208 %{ 8209 match(Set dst (LoadPLocked mem)); 8210 8211 ins_cost(125); // XXX 8212 format %{ "movq $dst, $mem\t# ptr locked" %} 8213 opcode(0x8B); 8214 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 8215 ins_pipe(ialu_reg_mem); // XXX 8216 %} 8217 8218 // LoadL-locked - same as a regular LoadL when used with compare-swap 8219 instruct loadLLocked(rRegL dst, memory mem) 8220 %{ 8221 match(Set dst (LoadLLocked mem)); 8222 8223 ins_cost(125); // XXX 8224 format %{ "movq $dst, $mem\t# long locked" %} 8225 opcode(0x8B); 8226 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 8227 ins_pipe(ialu_reg_mem); // XXX 8228 %} 8229 8230 // Conditional-store of the updated heap-top. 8231 // Used during allocation of the shared heap. 8232 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 8233 8234 instruct storePConditional(memory heap_top_ptr, 8235 rax_RegP oldval, rRegP newval, 8236 rFlagsReg cr) 8237 %{ 8238 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8239 8240 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 8241 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 8242 opcode(0x0F, 0xB1); 8243 ins_encode(lock_prefix, 8244 REX_reg_mem_wide(newval, heap_top_ptr), 8245 OpcP, OpcS, 8246 reg_mem(newval, heap_top_ptr)); 8247 ins_pipe(pipe_cmpxchg); 8248 %} 8249 8250 // Conditional-store of an int value. 8251 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 8252 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 8253 %{ 8254 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8255 effect(KILL oldval); 8256 8257 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 8258 opcode(0x0F, 0xB1); 8259 ins_encode(lock_prefix, 8260 REX_reg_mem(newval, mem), 8261 OpcP, OpcS, 8262 reg_mem(newval, mem)); 8263 ins_pipe(pipe_cmpxchg); 8264 %} 8265 8266 // Conditional-store of a long value. 8267 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 8268 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 8269 %{ 8270 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8271 effect(KILL oldval); 8272 8273 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 8274 opcode(0x0F, 0xB1); 8275 ins_encode(lock_prefix, 8276 REX_reg_mem_wide(newval, mem), 8277 OpcP, OpcS, 8278 reg_mem(newval, mem)); 8279 ins_pipe(pipe_cmpxchg); 8280 %} 8281 8282 8283 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 8284 instruct compareAndSwapP(rRegI res, 8285 memory mem_ptr, 8286 rax_RegP oldval, rRegP newval, 8287 rFlagsReg cr) 8288 %{ 8289 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 8290 effect(KILL cr, KILL oldval); 8291 8292 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8293 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 8294 "sete $res\n\t" 8295 "movzbl $res, $res" %} 8296 opcode(0x0F, 0xB1); 8297 ins_encode(lock_prefix, 8298 REX_reg_mem_wide(newval, mem_ptr), 8299 OpcP, OpcS, 8300 reg_mem(newval, mem_ptr), 8301 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 8302 REX_reg_breg(res, res), // movzbl 8303 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 8304 ins_pipe( pipe_cmpxchg ); 8305 %} 8306 8307 instruct compareAndSwapL(rRegI res, 8308 memory mem_ptr, 8309 rax_RegL oldval, rRegL newval, 8310 rFlagsReg cr) 8311 %{ 8312 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 8313 effect(KILL cr, KILL oldval); 8314 8315 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8316 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 8317 "sete $res\n\t" 8318 "movzbl $res, $res" %} 8319 opcode(0x0F, 0xB1); 8320 ins_encode(lock_prefix, 8321 REX_reg_mem_wide(newval, mem_ptr), 8322 OpcP, OpcS, 8323 reg_mem(newval, mem_ptr), 8324 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 8325 REX_reg_breg(res, res), // movzbl 8326 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 8327 ins_pipe( pipe_cmpxchg ); 8328 %} 8329 8330 instruct compareAndSwapI(rRegI res, 8331 memory mem_ptr, 8332 rax_RegI oldval, rRegI newval, 8333 rFlagsReg cr) 8334 %{ 8335 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 8336 effect(KILL cr, KILL oldval); 8337 8338 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8339 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 8340 "sete $res\n\t" 8341 "movzbl $res, $res" %} 8342 opcode(0x0F, 0xB1); 8343 ins_encode(lock_prefix, 8344 REX_reg_mem(newval, mem_ptr), 8345 OpcP, OpcS, 8346 reg_mem(newval, mem_ptr), 8347 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 8348 REX_reg_breg(res, res), // movzbl 8349 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 8350 ins_pipe( pipe_cmpxchg ); 8351 %} 8352 8353 8354 instruct compareAndSwapN(rRegI res, 8355 memory mem_ptr, 8356 rax_RegN oldval, rRegN newval, 8357 rFlagsReg cr) %{ 8358 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 8359 effect(KILL cr, KILL oldval); 8360 8361 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8362 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 8363 "sete $res\n\t" 8364 "movzbl $res, $res" %} 8365 opcode(0x0F, 0xB1); 8366 ins_encode(lock_prefix, 8367 REX_reg_mem(newval, mem_ptr), 8368 OpcP, OpcS, 8369 reg_mem(newval, mem_ptr), 8370 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 8371 REX_reg_breg(res, res), // movzbl 8372 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 8373 ins_pipe( pipe_cmpxchg ); 8374 %} 8375 8376 //----------Subtraction Instructions------------------------------------------- 8377 8378 // Integer Subtraction Instructions 8379 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8380 %{ 8381 match(Set dst (SubI dst src)); 8382 effect(KILL cr); 8383 8384 format %{ "subl $dst, $src\t# int" %} 8385 opcode(0x2B); 8386 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8387 ins_pipe(ialu_reg_reg); 8388 %} 8389 8390 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8391 %{ 8392 match(Set dst (SubI dst src)); 8393 effect(KILL cr); 8394 8395 format %{ "subl $dst, $src\t# int" %} 8396 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8397 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8398 ins_pipe(ialu_reg); 8399 %} 8400 8401 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8402 %{ 8403 match(Set dst (SubI dst (LoadI src))); 8404 effect(KILL cr); 8405 8406 ins_cost(125); 8407 format %{ "subl $dst, $src\t# int" %} 8408 opcode(0x2B); 8409 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8410 ins_pipe(ialu_reg_mem); 8411 %} 8412 8413 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8414 %{ 8415 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8416 effect(KILL cr); 8417 8418 ins_cost(150); 8419 format %{ "subl $dst, $src\t# int" %} 8420 opcode(0x29); /* Opcode 29 /r */ 8421 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8422 ins_pipe(ialu_mem_reg); 8423 %} 8424 8425 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8426 %{ 8427 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8428 effect(KILL cr); 8429 8430 ins_cost(125); // XXX 8431 format %{ "subl $dst, $src\t# int" %} 8432 opcode(0x81); /* Opcode 81 /5 id */ 8433 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8434 ins_pipe(ialu_mem_imm); 8435 %} 8436 8437 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8438 %{ 8439 match(Set dst (SubL dst src)); 8440 effect(KILL cr); 8441 8442 format %{ "subq $dst, $src\t# long" %} 8443 opcode(0x2B); 8444 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8445 ins_pipe(ialu_reg_reg); 8446 %} 8447 8448 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8449 %{ 8450 match(Set dst (SubL dst src)); 8451 effect(KILL cr); 8452 8453 format %{ "subq $dst, $src\t# long" %} 8454 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8455 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8456 ins_pipe(ialu_reg); 8457 %} 8458 8459 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8460 %{ 8461 match(Set dst (SubL dst (LoadL src))); 8462 effect(KILL cr); 8463 8464 ins_cost(125); 8465 format %{ "subq $dst, $src\t# long" %} 8466 opcode(0x2B); 8467 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8468 ins_pipe(ialu_reg_mem); 8469 %} 8470 8471 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8472 %{ 8473 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8474 effect(KILL cr); 8475 8476 ins_cost(150); 8477 format %{ "subq $dst, $src\t# long" %} 8478 opcode(0x29); /* Opcode 29 /r */ 8479 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8480 ins_pipe(ialu_mem_reg); 8481 %} 8482 8483 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8484 %{ 8485 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8486 effect(KILL cr); 8487 8488 ins_cost(125); // XXX 8489 format %{ "subq $dst, $src\t# long" %} 8490 opcode(0x81); /* Opcode 81 /5 id */ 8491 ins_encode(REX_mem_wide(dst), 8492 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8493 ins_pipe(ialu_mem_imm); 8494 %} 8495 8496 // Subtract from a pointer 8497 // XXX hmpf??? 8498 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8499 %{ 8500 match(Set dst (AddP dst (SubI zero src))); 8501 effect(KILL cr); 8502 8503 format %{ "subq $dst, $src\t# ptr - int" %} 8504 opcode(0x2B); 8505 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8506 ins_pipe(ialu_reg_reg); 8507 %} 8508 8509 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8510 %{ 8511 match(Set dst (SubI zero dst)); 8512 effect(KILL cr); 8513 8514 format %{ "negl $dst\t# int" %} 8515 opcode(0xF7, 0x03); // Opcode F7 /3 8516 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8517 ins_pipe(ialu_reg); 8518 %} 8519 8520 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8521 %{ 8522 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8523 effect(KILL cr); 8524 8525 format %{ "negl $dst\t# int" %} 8526 opcode(0xF7, 0x03); // Opcode F7 /3 8527 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8528 ins_pipe(ialu_reg); 8529 %} 8530 8531 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8532 %{ 8533 match(Set dst (SubL zero dst)); 8534 effect(KILL cr); 8535 8536 format %{ "negq $dst\t# long" %} 8537 opcode(0xF7, 0x03); // Opcode F7 /3 8538 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8539 ins_pipe(ialu_reg); 8540 %} 8541 8542 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8543 %{ 8544 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8545 effect(KILL cr); 8546 8547 format %{ "negq $dst\t# long" %} 8548 opcode(0xF7, 0x03); // Opcode F7 /3 8549 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8550 ins_pipe(ialu_reg); 8551 %} 8552 8553 8554 //----------Multiplication/Division Instructions------------------------------- 8555 // Integer Multiplication Instructions 8556 // Multiply Register 8557 8558 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8559 %{ 8560 match(Set dst (MulI dst src)); 8561 effect(KILL cr); 8562 8563 ins_cost(300); 8564 format %{ "imull $dst, $src\t# int" %} 8565 opcode(0x0F, 0xAF); 8566 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8567 ins_pipe(ialu_reg_reg_alu0); 8568 %} 8569 8570 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8571 %{ 8572 match(Set dst (MulI src imm)); 8573 effect(KILL cr); 8574 8575 ins_cost(300); 8576 format %{ "imull $dst, $src, $imm\t# int" %} 8577 opcode(0x69); /* 69 /r id */ 8578 ins_encode(REX_reg_reg(dst, src), 8579 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8580 ins_pipe(ialu_reg_reg_alu0); 8581 %} 8582 8583 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8584 %{ 8585 match(Set dst (MulI dst (LoadI src))); 8586 effect(KILL cr); 8587 8588 ins_cost(350); 8589 format %{ "imull $dst, $src\t# int" %} 8590 opcode(0x0F, 0xAF); 8591 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8592 ins_pipe(ialu_reg_mem_alu0); 8593 %} 8594 8595 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8596 %{ 8597 match(Set dst (MulI (LoadI src) imm)); 8598 effect(KILL cr); 8599 8600 ins_cost(300); 8601 format %{ "imull $dst, $src, $imm\t# int" %} 8602 opcode(0x69); /* 69 /r id */ 8603 ins_encode(REX_reg_mem(dst, src), 8604 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8605 ins_pipe(ialu_reg_mem_alu0); 8606 %} 8607 8608 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8609 %{ 8610 match(Set dst (MulL dst src)); 8611 effect(KILL cr); 8612 8613 ins_cost(300); 8614 format %{ "imulq $dst, $src\t# long" %} 8615 opcode(0x0F, 0xAF); 8616 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8617 ins_pipe(ialu_reg_reg_alu0); 8618 %} 8619 8620 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8621 %{ 8622 match(Set dst (MulL src imm)); 8623 effect(KILL cr); 8624 8625 ins_cost(300); 8626 format %{ "imulq $dst, $src, $imm\t# long" %} 8627 opcode(0x69); /* 69 /r id */ 8628 ins_encode(REX_reg_reg_wide(dst, src), 8629 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8630 ins_pipe(ialu_reg_reg_alu0); 8631 %} 8632 8633 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8634 %{ 8635 match(Set dst (MulL dst (LoadL src))); 8636 effect(KILL cr); 8637 8638 ins_cost(350); 8639 format %{ "imulq $dst, $src\t# long" %} 8640 opcode(0x0F, 0xAF); 8641 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8642 ins_pipe(ialu_reg_mem_alu0); 8643 %} 8644 8645 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8646 %{ 8647 match(Set dst (MulL (LoadL src) imm)); 8648 effect(KILL cr); 8649 8650 ins_cost(300); 8651 format %{ "imulq $dst, $src, $imm\t# long" %} 8652 opcode(0x69); /* 69 /r id */ 8653 ins_encode(REX_reg_mem_wide(dst, src), 8654 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8655 ins_pipe(ialu_reg_mem_alu0); 8656 %} 8657 8658 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8659 %{ 8660 match(Set dst (MulHiL src rax)); 8661 effect(USE_KILL rax, KILL cr); 8662 8663 ins_cost(300); 8664 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8665 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8666 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8667 ins_pipe(ialu_reg_reg_alu0); 8668 %} 8669 8670 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8671 rFlagsReg cr) 8672 %{ 8673 match(Set rax (DivI rax div)); 8674 effect(KILL rdx, KILL cr); 8675 8676 ins_cost(30*100+10*100); // XXX 8677 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8678 "jne,s normal\n\t" 8679 "xorl rdx, rdx\n\t" 8680 "cmpl $div, -1\n\t" 8681 "je,s done\n" 8682 "normal: cdql\n\t" 8683 "idivl $div\n" 8684 "done:" %} 8685 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8686 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8687 ins_pipe(ialu_reg_reg_alu0); 8688 %} 8689 8690 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8691 rFlagsReg cr) 8692 %{ 8693 match(Set rax (DivL rax div)); 8694 effect(KILL rdx, KILL cr); 8695 8696 ins_cost(30*100+10*100); // XXX 8697 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8698 "cmpq rax, rdx\n\t" 8699 "jne,s normal\n\t" 8700 "xorl rdx, rdx\n\t" 8701 "cmpq $div, -1\n\t" 8702 "je,s done\n" 8703 "normal: cdqq\n\t" 8704 "idivq $div\n" 8705 "done:" %} 8706 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8707 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8708 ins_pipe(ialu_reg_reg_alu0); 8709 %} 8710 8711 // Integer DIVMOD with Register, both quotient and mod results 8712 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8713 rFlagsReg cr) 8714 %{ 8715 match(DivModI rax div); 8716 effect(KILL cr); 8717 8718 ins_cost(30*100+10*100); // XXX 8719 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8720 "jne,s normal\n\t" 8721 "xorl rdx, rdx\n\t" 8722 "cmpl $div, -1\n\t" 8723 "je,s done\n" 8724 "normal: cdql\n\t" 8725 "idivl $div\n" 8726 "done:" %} 8727 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8728 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8729 ins_pipe(pipe_slow); 8730 %} 8731 8732 // Long DIVMOD with Register, both quotient and mod results 8733 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8734 rFlagsReg cr) 8735 %{ 8736 match(DivModL rax div); 8737 effect(KILL cr); 8738 8739 ins_cost(30*100+10*100); // XXX 8740 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8741 "cmpq rax, rdx\n\t" 8742 "jne,s normal\n\t" 8743 "xorl rdx, rdx\n\t" 8744 "cmpq $div, -1\n\t" 8745 "je,s done\n" 8746 "normal: cdqq\n\t" 8747 "idivq $div\n" 8748 "done:" %} 8749 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8750 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8751 ins_pipe(pipe_slow); 8752 %} 8753 8754 //----------- DivL-By-Constant-Expansions-------------------------------------- 8755 // DivI cases are handled by the compiler 8756 8757 // Magic constant, reciprocal of 10 8758 instruct loadConL_0x6666666666666667(rRegL dst) 8759 %{ 8760 effect(DEF dst); 8761 8762 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8763 ins_encode(load_immL(dst, 0x6666666666666667)); 8764 ins_pipe(ialu_reg); 8765 %} 8766 8767 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8768 %{ 8769 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8770 8771 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8772 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8773 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8774 ins_pipe(ialu_reg_reg_alu0); 8775 %} 8776 8777 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8778 %{ 8779 effect(USE_DEF dst, KILL cr); 8780 8781 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8782 opcode(0xC1, 0x7); /* C1 /7 ib */ 8783 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8784 ins_pipe(ialu_reg); 8785 %} 8786 8787 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8788 %{ 8789 effect(USE_DEF dst, KILL cr); 8790 8791 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8792 opcode(0xC1, 0x7); /* C1 /7 ib */ 8793 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8794 ins_pipe(ialu_reg); 8795 %} 8796 8797 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8798 %{ 8799 match(Set dst (DivL src div)); 8800 8801 ins_cost((5+8)*100); 8802 expand %{ 8803 rax_RegL rax; // Killed temp 8804 rFlagsReg cr; // Killed 8805 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8806 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8807 sarL_rReg_63(src, cr); // sarq src, 63 8808 sarL_rReg_2(dst, cr); // sarq rdx, 2 8809 subL_rReg(dst, src, cr); // subl rdx, src 8810 %} 8811 %} 8812 8813 //----------------------------------------------------------------------------- 8814 8815 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8816 rFlagsReg cr) 8817 %{ 8818 match(Set rdx (ModI rax div)); 8819 effect(KILL rax, KILL cr); 8820 8821 ins_cost(300); // XXX 8822 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8823 "jne,s normal\n\t" 8824 "xorl rdx, rdx\n\t" 8825 "cmpl $div, -1\n\t" 8826 "je,s done\n" 8827 "normal: cdql\n\t" 8828 "idivl $div\n" 8829 "done:" %} 8830 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8831 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8832 ins_pipe(ialu_reg_reg_alu0); 8833 %} 8834 8835 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8836 rFlagsReg cr) 8837 %{ 8838 match(Set rdx (ModL rax div)); 8839 effect(KILL rax, KILL cr); 8840 8841 ins_cost(300); // XXX 8842 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8843 "cmpq rax, rdx\n\t" 8844 "jne,s normal\n\t" 8845 "xorl rdx, rdx\n\t" 8846 "cmpq $div, -1\n\t" 8847 "je,s done\n" 8848 "normal: cdqq\n\t" 8849 "idivq $div\n" 8850 "done:" %} 8851 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8852 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8853 ins_pipe(ialu_reg_reg_alu0); 8854 %} 8855 8856 // Integer Shift Instructions 8857 // Shift Left by one 8858 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8859 %{ 8860 match(Set dst (LShiftI dst shift)); 8861 effect(KILL cr); 8862 8863 format %{ "sall $dst, $shift" %} 8864 opcode(0xD1, 0x4); /* D1 /4 */ 8865 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8866 ins_pipe(ialu_reg); 8867 %} 8868 8869 // Shift Left by one 8870 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8871 %{ 8872 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8873 effect(KILL cr); 8874 8875 format %{ "sall $dst, $shift\t" %} 8876 opcode(0xD1, 0x4); /* D1 /4 */ 8877 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8878 ins_pipe(ialu_mem_imm); 8879 %} 8880 8881 // Shift Left by 8-bit immediate 8882 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8883 %{ 8884 match(Set dst (LShiftI dst shift)); 8885 effect(KILL cr); 8886 8887 format %{ "sall $dst, $shift" %} 8888 opcode(0xC1, 0x4); /* C1 /4 ib */ 8889 ins_encode(reg_opc_imm(dst, shift)); 8890 ins_pipe(ialu_reg); 8891 %} 8892 8893 // Shift Left by 8-bit immediate 8894 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8895 %{ 8896 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8897 effect(KILL cr); 8898 8899 format %{ "sall $dst, $shift" %} 8900 opcode(0xC1, 0x4); /* C1 /4 ib */ 8901 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8902 ins_pipe(ialu_mem_imm); 8903 %} 8904 8905 // Shift Left by variable 8906 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8907 %{ 8908 match(Set dst (LShiftI dst shift)); 8909 effect(KILL cr); 8910 8911 format %{ "sall $dst, $shift" %} 8912 opcode(0xD3, 0x4); /* D3 /4 */ 8913 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8914 ins_pipe(ialu_reg_reg); 8915 %} 8916 8917 // Shift Left by variable 8918 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8919 %{ 8920 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8921 effect(KILL cr); 8922 8923 format %{ "sall $dst, $shift" %} 8924 opcode(0xD3, 0x4); /* D3 /4 */ 8925 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8926 ins_pipe(ialu_mem_reg); 8927 %} 8928 8929 // Arithmetic shift right by one 8930 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8931 %{ 8932 match(Set dst (RShiftI dst shift)); 8933 effect(KILL cr); 8934 8935 format %{ "sarl $dst, $shift" %} 8936 opcode(0xD1, 0x7); /* D1 /7 */ 8937 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8938 ins_pipe(ialu_reg); 8939 %} 8940 8941 // Arithmetic shift right by one 8942 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8943 %{ 8944 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8945 effect(KILL cr); 8946 8947 format %{ "sarl $dst, $shift" %} 8948 opcode(0xD1, 0x7); /* D1 /7 */ 8949 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8950 ins_pipe(ialu_mem_imm); 8951 %} 8952 8953 // Arithmetic Shift Right by 8-bit immediate 8954 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8955 %{ 8956 match(Set dst (RShiftI dst shift)); 8957 effect(KILL cr); 8958 8959 format %{ "sarl $dst, $shift" %} 8960 opcode(0xC1, 0x7); /* C1 /7 ib */ 8961 ins_encode(reg_opc_imm(dst, shift)); 8962 ins_pipe(ialu_mem_imm); 8963 %} 8964 8965 // Arithmetic Shift Right by 8-bit immediate 8966 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8967 %{ 8968 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8969 effect(KILL cr); 8970 8971 format %{ "sarl $dst, $shift" %} 8972 opcode(0xC1, 0x7); /* C1 /7 ib */ 8973 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8974 ins_pipe(ialu_mem_imm); 8975 %} 8976 8977 // Arithmetic Shift Right by variable 8978 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8979 %{ 8980 match(Set dst (RShiftI dst shift)); 8981 effect(KILL cr); 8982 8983 format %{ "sarl $dst, $shift" %} 8984 opcode(0xD3, 0x7); /* D3 /7 */ 8985 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8986 ins_pipe(ialu_reg_reg); 8987 %} 8988 8989 // Arithmetic Shift Right by variable 8990 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8991 %{ 8992 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8993 effect(KILL cr); 8994 8995 format %{ "sarl $dst, $shift" %} 8996 opcode(0xD3, 0x7); /* D3 /7 */ 8997 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8998 ins_pipe(ialu_mem_reg); 8999 %} 9000 9001 // Logical shift right by one 9002 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 9003 %{ 9004 match(Set dst (URShiftI dst shift)); 9005 effect(KILL cr); 9006 9007 format %{ "shrl $dst, $shift" %} 9008 opcode(0xD1, 0x5); /* D1 /5 */ 9009 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9010 ins_pipe(ialu_reg); 9011 %} 9012 9013 // Logical shift right by one 9014 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9015 %{ 9016 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9017 effect(KILL cr); 9018 9019 format %{ "shrl $dst, $shift" %} 9020 opcode(0xD1, 0x5); /* D1 /5 */ 9021 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 9022 ins_pipe(ialu_mem_imm); 9023 %} 9024 9025 // Logical Shift Right by 8-bit immediate 9026 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9027 %{ 9028 match(Set dst (URShiftI dst shift)); 9029 effect(KILL cr); 9030 9031 format %{ "shrl $dst, $shift" %} 9032 opcode(0xC1, 0x5); /* C1 /5 ib */ 9033 ins_encode(reg_opc_imm(dst, shift)); 9034 ins_pipe(ialu_reg); 9035 %} 9036 9037 // Logical Shift Right by 8-bit immediate 9038 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9039 %{ 9040 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9041 effect(KILL cr); 9042 9043 format %{ "shrl $dst, $shift" %} 9044 opcode(0xC1, 0x5); /* C1 /5 ib */ 9045 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 9046 ins_pipe(ialu_mem_imm); 9047 %} 9048 9049 // Logical Shift Right by variable 9050 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9051 %{ 9052 match(Set dst (URShiftI dst shift)); 9053 effect(KILL cr); 9054 9055 format %{ "shrl $dst, $shift" %} 9056 opcode(0xD3, 0x5); /* D3 /5 */ 9057 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9058 ins_pipe(ialu_reg_reg); 9059 %} 9060 9061 // Logical Shift Right by variable 9062 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9063 %{ 9064 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9065 effect(KILL cr); 9066 9067 format %{ "shrl $dst, $shift" %} 9068 opcode(0xD3, 0x5); /* D3 /5 */ 9069 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 9070 ins_pipe(ialu_mem_reg); 9071 %} 9072 9073 // Long Shift Instructions 9074 // Shift Left by one 9075 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9076 %{ 9077 match(Set dst (LShiftL dst shift)); 9078 effect(KILL cr); 9079 9080 format %{ "salq $dst, $shift" %} 9081 opcode(0xD1, 0x4); /* D1 /4 */ 9082 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9083 ins_pipe(ialu_reg); 9084 %} 9085 9086 // Shift Left by one 9087 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9088 %{ 9089 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9090 effect(KILL cr); 9091 9092 format %{ "salq $dst, $shift" %} 9093 opcode(0xD1, 0x4); /* D1 /4 */ 9094 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9095 ins_pipe(ialu_mem_imm); 9096 %} 9097 9098 // Shift Left by 8-bit immediate 9099 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9100 %{ 9101 match(Set dst (LShiftL dst shift)); 9102 effect(KILL cr); 9103 9104 format %{ "salq $dst, $shift" %} 9105 opcode(0xC1, 0x4); /* C1 /4 ib */ 9106 ins_encode(reg_opc_imm_wide(dst, shift)); 9107 ins_pipe(ialu_reg); 9108 %} 9109 9110 // Shift Left by 8-bit immediate 9111 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9112 %{ 9113 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9114 effect(KILL cr); 9115 9116 format %{ "salq $dst, $shift" %} 9117 opcode(0xC1, 0x4); /* C1 /4 ib */ 9118 ins_encode(REX_mem_wide(dst), OpcP, 9119 RM_opc_mem(secondary, dst), Con8or32(shift)); 9120 ins_pipe(ialu_mem_imm); 9121 %} 9122 9123 // Shift Left by variable 9124 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9125 %{ 9126 match(Set dst (LShiftL dst shift)); 9127 effect(KILL cr); 9128 9129 format %{ "salq $dst, $shift" %} 9130 opcode(0xD3, 0x4); /* D3 /4 */ 9131 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9132 ins_pipe(ialu_reg_reg); 9133 %} 9134 9135 // Shift Left by variable 9136 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9137 %{ 9138 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9139 effect(KILL cr); 9140 9141 format %{ "salq $dst, $shift" %} 9142 opcode(0xD3, 0x4); /* D3 /4 */ 9143 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9144 ins_pipe(ialu_mem_reg); 9145 %} 9146 9147 // Arithmetic shift right by one 9148 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9149 %{ 9150 match(Set dst (RShiftL dst shift)); 9151 effect(KILL cr); 9152 9153 format %{ "sarq $dst, $shift" %} 9154 opcode(0xD1, 0x7); /* D1 /7 */ 9155 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9156 ins_pipe(ialu_reg); 9157 %} 9158 9159 // Arithmetic shift right by one 9160 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9161 %{ 9162 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9163 effect(KILL cr); 9164 9165 format %{ "sarq $dst, $shift" %} 9166 opcode(0xD1, 0x7); /* D1 /7 */ 9167 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9168 ins_pipe(ialu_mem_imm); 9169 %} 9170 9171 // Arithmetic Shift Right by 8-bit immediate 9172 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9173 %{ 9174 match(Set dst (RShiftL dst shift)); 9175 effect(KILL cr); 9176 9177 format %{ "sarq $dst, $shift" %} 9178 opcode(0xC1, 0x7); /* C1 /7 ib */ 9179 ins_encode(reg_opc_imm_wide(dst, shift)); 9180 ins_pipe(ialu_mem_imm); 9181 %} 9182 9183 // Arithmetic Shift Right by 8-bit immediate 9184 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9185 %{ 9186 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9187 effect(KILL cr); 9188 9189 format %{ "sarq $dst, $shift" %} 9190 opcode(0xC1, 0x7); /* C1 /7 ib */ 9191 ins_encode(REX_mem_wide(dst), OpcP, 9192 RM_opc_mem(secondary, dst), Con8or32(shift)); 9193 ins_pipe(ialu_mem_imm); 9194 %} 9195 9196 // Arithmetic Shift Right by variable 9197 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9198 %{ 9199 match(Set dst (RShiftL dst shift)); 9200 effect(KILL cr); 9201 9202 format %{ "sarq $dst, $shift" %} 9203 opcode(0xD3, 0x7); /* D3 /7 */ 9204 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9205 ins_pipe(ialu_reg_reg); 9206 %} 9207 9208 // Arithmetic Shift Right by variable 9209 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9210 %{ 9211 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9212 effect(KILL cr); 9213 9214 format %{ "sarq $dst, $shift" %} 9215 opcode(0xD3, 0x7); /* D3 /7 */ 9216 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9217 ins_pipe(ialu_mem_reg); 9218 %} 9219 9220 // Logical shift right by one 9221 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9222 %{ 9223 match(Set dst (URShiftL dst shift)); 9224 effect(KILL cr); 9225 9226 format %{ "shrq $dst, $shift" %} 9227 opcode(0xD1, 0x5); /* D1 /5 */ 9228 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 9229 ins_pipe(ialu_reg); 9230 %} 9231 9232 // Logical shift right by one 9233 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9234 %{ 9235 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9236 effect(KILL cr); 9237 9238 format %{ "shrq $dst, $shift" %} 9239 opcode(0xD1, 0x5); /* D1 /5 */ 9240 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9241 ins_pipe(ialu_mem_imm); 9242 %} 9243 9244 // Logical Shift Right by 8-bit immediate 9245 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9246 %{ 9247 match(Set dst (URShiftL dst shift)); 9248 effect(KILL cr); 9249 9250 format %{ "shrq $dst, $shift" %} 9251 opcode(0xC1, 0x5); /* C1 /5 ib */ 9252 ins_encode(reg_opc_imm_wide(dst, shift)); 9253 ins_pipe(ialu_reg); 9254 %} 9255 9256 9257 // Logical Shift Right by 8-bit immediate 9258 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9259 %{ 9260 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9261 effect(KILL cr); 9262 9263 format %{ "shrq $dst, $shift" %} 9264 opcode(0xC1, 0x5); /* C1 /5 ib */ 9265 ins_encode(REX_mem_wide(dst), OpcP, 9266 RM_opc_mem(secondary, dst), Con8or32(shift)); 9267 ins_pipe(ialu_mem_imm); 9268 %} 9269 9270 // Logical Shift Right by variable 9271 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9272 %{ 9273 match(Set dst (URShiftL dst shift)); 9274 effect(KILL cr); 9275 9276 format %{ "shrq $dst, $shift" %} 9277 opcode(0xD3, 0x5); /* D3 /5 */ 9278 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9279 ins_pipe(ialu_reg_reg); 9280 %} 9281 9282 // Logical Shift Right by variable 9283 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9284 %{ 9285 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9286 effect(KILL cr); 9287 9288 format %{ "shrq $dst, $shift" %} 9289 opcode(0xD3, 0x5); /* D3 /5 */ 9290 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9291 ins_pipe(ialu_mem_reg); 9292 %} 9293 9294 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9295 // This idiom is used by the compiler for the i2b bytecode. 9296 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9297 %{ 9298 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9299 9300 format %{ "movsbl $dst, $src\t# i2b" %} 9301 opcode(0x0F, 0xBE); 9302 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9303 ins_pipe(ialu_reg_reg); 9304 %} 9305 9306 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9307 // This idiom is used by the compiler the i2s bytecode. 9308 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9309 %{ 9310 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9311 9312 format %{ "movswl $dst, $src\t# i2s" %} 9313 opcode(0x0F, 0xBF); 9314 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9315 ins_pipe(ialu_reg_reg); 9316 %} 9317 9318 // ROL/ROR instructions 9319 9320 // ROL expand 9321 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 9322 effect(KILL cr, USE_DEF dst); 9323 9324 format %{ "roll $dst" %} 9325 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9326 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9327 ins_pipe(ialu_reg); 9328 %} 9329 9330 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 9331 effect(USE_DEF dst, USE shift, KILL cr); 9332 9333 format %{ "roll $dst, $shift" %} 9334 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9335 ins_encode( reg_opc_imm(dst, shift) ); 9336 ins_pipe(ialu_reg); 9337 %} 9338 9339 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9340 %{ 9341 effect(USE_DEF dst, USE shift, KILL cr); 9342 9343 format %{ "roll $dst, $shift" %} 9344 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9345 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9346 ins_pipe(ialu_reg_reg); 9347 %} 9348 // end of ROL expand 9349 9350 // Rotate Left by one 9351 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9352 %{ 9353 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9354 9355 expand %{ 9356 rolI_rReg_imm1(dst, cr); 9357 %} 9358 %} 9359 9360 // Rotate Left by 8-bit immediate 9361 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9362 %{ 9363 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9364 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9365 9366 expand %{ 9367 rolI_rReg_imm8(dst, lshift, cr); 9368 %} 9369 %} 9370 9371 // Rotate Left by variable 9372 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9373 %{ 9374 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9375 9376 expand %{ 9377 rolI_rReg_CL(dst, shift, cr); 9378 %} 9379 %} 9380 9381 // Rotate Left by variable 9382 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9383 %{ 9384 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9385 9386 expand %{ 9387 rolI_rReg_CL(dst, shift, cr); 9388 %} 9389 %} 9390 9391 // ROR expand 9392 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9393 %{ 9394 effect(USE_DEF dst, KILL cr); 9395 9396 format %{ "rorl $dst" %} 9397 opcode(0xD1, 0x1); /* D1 /1 */ 9398 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9399 ins_pipe(ialu_reg); 9400 %} 9401 9402 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9403 %{ 9404 effect(USE_DEF dst, USE shift, KILL cr); 9405 9406 format %{ "rorl $dst, $shift" %} 9407 opcode(0xC1, 0x1); /* C1 /1 ib */ 9408 ins_encode(reg_opc_imm(dst, shift)); 9409 ins_pipe(ialu_reg); 9410 %} 9411 9412 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9413 %{ 9414 effect(USE_DEF dst, USE shift, KILL cr); 9415 9416 format %{ "rorl $dst, $shift" %} 9417 opcode(0xD3, 0x1); /* D3 /1 */ 9418 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9419 ins_pipe(ialu_reg_reg); 9420 %} 9421 // end of ROR expand 9422 9423 // Rotate Right by one 9424 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9425 %{ 9426 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9427 9428 expand %{ 9429 rorI_rReg_imm1(dst, cr); 9430 %} 9431 %} 9432 9433 // Rotate Right by 8-bit immediate 9434 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9435 %{ 9436 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9437 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9438 9439 expand %{ 9440 rorI_rReg_imm8(dst, rshift, cr); 9441 %} 9442 %} 9443 9444 // Rotate Right by variable 9445 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9446 %{ 9447 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9448 9449 expand %{ 9450 rorI_rReg_CL(dst, shift, cr); 9451 %} 9452 %} 9453 9454 // Rotate Right by variable 9455 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9456 %{ 9457 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9458 9459 expand %{ 9460 rorI_rReg_CL(dst, shift, cr); 9461 %} 9462 %} 9463 9464 // for long rotate 9465 // ROL expand 9466 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9467 effect(USE_DEF dst, KILL cr); 9468 9469 format %{ "rolq $dst" %} 9470 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9471 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9472 ins_pipe(ialu_reg); 9473 %} 9474 9475 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9476 effect(USE_DEF dst, USE shift, KILL cr); 9477 9478 format %{ "rolq $dst, $shift" %} 9479 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9480 ins_encode( reg_opc_imm_wide(dst, shift) ); 9481 ins_pipe(ialu_reg); 9482 %} 9483 9484 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9485 %{ 9486 effect(USE_DEF dst, USE shift, KILL cr); 9487 9488 format %{ "rolq $dst, $shift" %} 9489 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9490 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9491 ins_pipe(ialu_reg_reg); 9492 %} 9493 // end of ROL expand 9494 9495 // Rotate Left by one 9496 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9497 %{ 9498 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9499 9500 expand %{ 9501 rolL_rReg_imm1(dst, cr); 9502 %} 9503 %} 9504 9505 // Rotate Left by 8-bit immediate 9506 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9507 %{ 9508 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9509 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9510 9511 expand %{ 9512 rolL_rReg_imm8(dst, lshift, cr); 9513 %} 9514 %} 9515 9516 // Rotate Left by variable 9517 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9518 %{ 9519 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9520 9521 expand %{ 9522 rolL_rReg_CL(dst, shift, cr); 9523 %} 9524 %} 9525 9526 // Rotate Left by variable 9527 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9528 %{ 9529 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9530 9531 expand %{ 9532 rolL_rReg_CL(dst, shift, cr); 9533 %} 9534 %} 9535 9536 // ROR expand 9537 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9538 %{ 9539 effect(USE_DEF dst, KILL cr); 9540 9541 format %{ "rorq $dst" %} 9542 opcode(0xD1, 0x1); /* D1 /1 */ 9543 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9544 ins_pipe(ialu_reg); 9545 %} 9546 9547 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9548 %{ 9549 effect(USE_DEF dst, USE shift, KILL cr); 9550 9551 format %{ "rorq $dst, $shift" %} 9552 opcode(0xC1, 0x1); /* C1 /1 ib */ 9553 ins_encode(reg_opc_imm_wide(dst, shift)); 9554 ins_pipe(ialu_reg); 9555 %} 9556 9557 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9558 %{ 9559 effect(USE_DEF dst, USE shift, KILL cr); 9560 9561 format %{ "rorq $dst, $shift" %} 9562 opcode(0xD3, 0x1); /* D3 /1 */ 9563 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9564 ins_pipe(ialu_reg_reg); 9565 %} 9566 // end of ROR expand 9567 9568 // Rotate Right by one 9569 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9570 %{ 9571 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9572 9573 expand %{ 9574 rorL_rReg_imm1(dst, cr); 9575 %} 9576 %} 9577 9578 // Rotate Right by 8-bit immediate 9579 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9580 %{ 9581 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9582 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9583 9584 expand %{ 9585 rorL_rReg_imm8(dst, rshift, cr); 9586 %} 9587 %} 9588 9589 // Rotate Right by variable 9590 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9591 %{ 9592 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9593 9594 expand %{ 9595 rorL_rReg_CL(dst, shift, cr); 9596 %} 9597 %} 9598 9599 // Rotate Right by variable 9600 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9601 %{ 9602 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9603 9604 expand %{ 9605 rorL_rReg_CL(dst, shift, cr); 9606 %} 9607 %} 9608 9609 // Logical Instructions 9610 9611 // Integer Logical Instructions 9612 9613 // And Instructions 9614 // And Register with Register 9615 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9616 %{ 9617 match(Set dst (AndI dst src)); 9618 effect(KILL cr); 9619 9620 format %{ "andl $dst, $src\t# int" %} 9621 opcode(0x23); 9622 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9623 ins_pipe(ialu_reg_reg); 9624 %} 9625 9626 // And Register with Immediate 255 9627 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9628 %{ 9629 match(Set dst (AndI dst src)); 9630 9631 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9632 opcode(0x0F, 0xB6); 9633 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9634 ins_pipe(ialu_reg); 9635 %} 9636 9637 // And Register with Immediate 255 and promote to long 9638 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9639 %{ 9640 match(Set dst (ConvI2L (AndI src mask))); 9641 9642 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9643 opcode(0x0F, 0xB6); 9644 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9645 ins_pipe(ialu_reg); 9646 %} 9647 9648 // And Register with Immediate 65535 9649 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9650 %{ 9651 match(Set dst (AndI dst src)); 9652 9653 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9654 opcode(0x0F, 0xB7); 9655 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9656 ins_pipe(ialu_reg); 9657 %} 9658 9659 // And Register with Immediate 65535 and promote to long 9660 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9661 %{ 9662 match(Set dst (ConvI2L (AndI src mask))); 9663 9664 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9665 opcode(0x0F, 0xB7); 9666 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9667 ins_pipe(ialu_reg); 9668 %} 9669 9670 // And Register with Immediate 9671 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9672 %{ 9673 match(Set dst (AndI dst src)); 9674 effect(KILL cr); 9675 9676 format %{ "andl $dst, $src\t# int" %} 9677 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9678 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9679 ins_pipe(ialu_reg); 9680 %} 9681 9682 // And Register with Memory 9683 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9684 %{ 9685 match(Set dst (AndI dst (LoadI src))); 9686 effect(KILL cr); 9687 9688 ins_cost(125); 9689 format %{ "andl $dst, $src\t# int" %} 9690 opcode(0x23); 9691 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9692 ins_pipe(ialu_reg_mem); 9693 %} 9694 9695 // And Memory with Register 9696 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9697 %{ 9698 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9699 effect(KILL cr); 9700 9701 ins_cost(150); 9702 format %{ "andl $dst, $src\t# int" %} 9703 opcode(0x21); /* Opcode 21 /r */ 9704 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9705 ins_pipe(ialu_mem_reg); 9706 %} 9707 9708 // And Memory with Immediate 9709 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9710 %{ 9711 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9712 effect(KILL cr); 9713 9714 ins_cost(125); 9715 format %{ "andl $dst, $src\t# int" %} 9716 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9717 ins_encode(REX_mem(dst), OpcSE(src), 9718 RM_opc_mem(secondary, dst), Con8or32(src)); 9719 ins_pipe(ialu_mem_imm); 9720 %} 9721 9722 // Or Instructions 9723 // Or Register with Register 9724 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9725 %{ 9726 match(Set dst (OrI dst src)); 9727 effect(KILL cr); 9728 9729 format %{ "orl $dst, $src\t# int" %} 9730 opcode(0x0B); 9731 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9732 ins_pipe(ialu_reg_reg); 9733 %} 9734 9735 // Or Register with Immediate 9736 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9737 %{ 9738 match(Set dst (OrI dst src)); 9739 effect(KILL cr); 9740 9741 format %{ "orl $dst, $src\t# int" %} 9742 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9743 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9744 ins_pipe(ialu_reg); 9745 %} 9746 9747 // Or Register with Memory 9748 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9749 %{ 9750 match(Set dst (OrI dst (LoadI src))); 9751 effect(KILL cr); 9752 9753 ins_cost(125); 9754 format %{ "orl $dst, $src\t# int" %} 9755 opcode(0x0B); 9756 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9757 ins_pipe(ialu_reg_mem); 9758 %} 9759 9760 // Or Memory with Register 9761 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9762 %{ 9763 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9764 effect(KILL cr); 9765 9766 ins_cost(150); 9767 format %{ "orl $dst, $src\t# int" %} 9768 opcode(0x09); /* Opcode 09 /r */ 9769 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9770 ins_pipe(ialu_mem_reg); 9771 %} 9772 9773 // Or Memory with Immediate 9774 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9775 %{ 9776 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9777 effect(KILL cr); 9778 9779 ins_cost(125); 9780 format %{ "orl $dst, $src\t# int" %} 9781 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9782 ins_encode(REX_mem(dst), OpcSE(src), 9783 RM_opc_mem(secondary, dst), Con8or32(src)); 9784 ins_pipe(ialu_mem_imm); 9785 %} 9786 9787 // Xor Instructions 9788 // Xor Register with Register 9789 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9790 %{ 9791 match(Set dst (XorI dst src)); 9792 effect(KILL cr); 9793 9794 format %{ "xorl $dst, $src\t# int" %} 9795 opcode(0x33); 9796 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9797 ins_pipe(ialu_reg_reg); 9798 %} 9799 9800 // Xor Register with Immediate -1 9801 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9802 match(Set dst (XorI dst imm)); 9803 9804 format %{ "not $dst" %} 9805 ins_encode %{ 9806 __ notl($dst$$Register); 9807 %} 9808 ins_pipe(ialu_reg); 9809 %} 9810 9811 // Xor Register with Immediate 9812 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9813 %{ 9814 match(Set dst (XorI dst src)); 9815 effect(KILL cr); 9816 9817 format %{ "xorl $dst, $src\t# int" %} 9818 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9819 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9820 ins_pipe(ialu_reg); 9821 %} 9822 9823 // Xor Register with Memory 9824 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9825 %{ 9826 match(Set dst (XorI dst (LoadI src))); 9827 effect(KILL cr); 9828 9829 ins_cost(125); 9830 format %{ "xorl $dst, $src\t# int" %} 9831 opcode(0x33); 9832 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9833 ins_pipe(ialu_reg_mem); 9834 %} 9835 9836 // Xor Memory with Register 9837 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9838 %{ 9839 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9840 effect(KILL cr); 9841 9842 ins_cost(150); 9843 format %{ "xorl $dst, $src\t# int" %} 9844 opcode(0x31); /* Opcode 31 /r */ 9845 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9846 ins_pipe(ialu_mem_reg); 9847 %} 9848 9849 // Xor Memory with Immediate 9850 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9851 %{ 9852 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9853 effect(KILL cr); 9854 9855 ins_cost(125); 9856 format %{ "xorl $dst, $src\t# int" %} 9857 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9858 ins_encode(REX_mem(dst), OpcSE(src), 9859 RM_opc_mem(secondary, dst), Con8or32(src)); 9860 ins_pipe(ialu_mem_imm); 9861 %} 9862 9863 9864 // Long Logical Instructions 9865 9866 // And Instructions 9867 // And Register with Register 9868 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9869 %{ 9870 match(Set dst (AndL dst src)); 9871 effect(KILL cr); 9872 9873 format %{ "andq $dst, $src\t# long" %} 9874 opcode(0x23); 9875 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9876 ins_pipe(ialu_reg_reg); 9877 %} 9878 9879 // And Register with Immediate 255 9880 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9881 %{ 9882 match(Set dst (AndL dst src)); 9883 9884 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9885 opcode(0x0F, 0xB6); 9886 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9887 ins_pipe(ialu_reg); 9888 %} 9889 9890 // And Register with Immediate 65535 9891 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9892 %{ 9893 match(Set dst (AndL dst src)); 9894 9895 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9896 opcode(0x0F, 0xB7); 9897 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9898 ins_pipe(ialu_reg); 9899 %} 9900 9901 // And Register with Immediate 9902 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9903 %{ 9904 match(Set dst (AndL dst src)); 9905 effect(KILL cr); 9906 9907 format %{ "andq $dst, $src\t# long" %} 9908 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9909 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9910 ins_pipe(ialu_reg); 9911 %} 9912 9913 // And Register with Memory 9914 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9915 %{ 9916 match(Set dst (AndL dst (LoadL src))); 9917 effect(KILL cr); 9918 9919 ins_cost(125); 9920 format %{ "andq $dst, $src\t# long" %} 9921 opcode(0x23); 9922 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9923 ins_pipe(ialu_reg_mem); 9924 %} 9925 9926 // And Memory with Register 9927 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9928 %{ 9929 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9930 effect(KILL cr); 9931 9932 ins_cost(150); 9933 format %{ "andq $dst, $src\t# long" %} 9934 opcode(0x21); /* Opcode 21 /r */ 9935 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9936 ins_pipe(ialu_mem_reg); 9937 %} 9938 9939 // And Memory with Immediate 9940 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9941 %{ 9942 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9943 effect(KILL cr); 9944 9945 ins_cost(125); 9946 format %{ "andq $dst, $src\t# long" %} 9947 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9948 ins_encode(REX_mem_wide(dst), OpcSE(src), 9949 RM_opc_mem(secondary, dst), Con8or32(src)); 9950 ins_pipe(ialu_mem_imm); 9951 %} 9952 9953 // Or Instructions 9954 // Or Register with Register 9955 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9956 %{ 9957 match(Set dst (OrL dst src)); 9958 effect(KILL cr); 9959 9960 format %{ "orq $dst, $src\t# long" %} 9961 opcode(0x0B); 9962 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9963 ins_pipe(ialu_reg_reg); 9964 %} 9965 9966 // Use any_RegP to match R15 (TLS register) without spilling. 9967 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9968 match(Set dst (OrL dst (CastP2X src))); 9969 effect(KILL cr); 9970 9971 format %{ "orq $dst, $src\t# long" %} 9972 opcode(0x0B); 9973 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9974 ins_pipe(ialu_reg_reg); 9975 %} 9976 9977 9978 // Or Register with Immediate 9979 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9980 %{ 9981 match(Set dst (OrL dst src)); 9982 effect(KILL cr); 9983 9984 format %{ "orq $dst, $src\t# long" %} 9985 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9986 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9987 ins_pipe(ialu_reg); 9988 %} 9989 9990 // Or Register with Memory 9991 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9992 %{ 9993 match(Set dst (OrL dst (LoadL src))); 9994 effect(KILL cr); 9995 9996 ins_cost(125); 9997 format %{ "orq $dst, $src\t# long" %} 9998 opcode(0x0B); 9999 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10000 ins_pipe(ialu_reg_mem); 10001 %} 10002 10003 // Or Memory with Register 10004 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10005 %{ 10006 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10007 effect(KILL cr); 10008 10009 ins_cost(150); 10010 format %{ "orq $dst, $src\t# long" %} 10011 opcode(0x09); /* Opcode 09 /r */ 10012 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10013 ins_pipe(ialu_mem_reg); 10014 %} 10015 10016 // Or Memory with Immediate 10017 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10018 %{ 10019 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10020 effect(KILL cr); 10021 10022 ins_cost(125); 10023 format %{ "orq $dst, $src\t# long" %} 10024 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 10025 ins_encode(REX_mem_wide(dst), OpcSE(src), 10026 RM_opc_mem(secondary, dst), Con8or32(src)); 10027 ins_pipe(ialu_mem_imm); 10028 %} 10029 10030 // Xor Instructions 10031 // Xor Register with Register 10032 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10033 %{ 10034 match(Set dst (XorL dst src)); 10035 effect(KILL cr); 10036 10037 format %{ "xorq $dst, $src\t# long" %} 10038 opcode(0x33); 10039 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10040 ins_pipe(ialu_reg_reg); 10041 %} 10042 10043 // Xor Register with Immediate -1 10044 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 10045 match(Set dst (XorL dst imm)); 10046 10047 format %{ "notq $dst" %} 10048 ins_encode %{ 10049 __ notq($dst$$Register); 10050 %} 10051 ins_pipe(ialu_reg); 10052 %} 10053 10054 // Xor Register with Immediate 10055 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10056 %{ 10057 match(Set dst (XorL dst src)); 10058 effect(KILL cr); 10059 10060 format %{ "xorq $dst, $src\t# long" %} 10061 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 10062 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10063 ins_pipe(ialu_reg); 10064 %} 10065 10066 // Xor Register with Memory 10067 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10068 %{ 10069 match(Set dst (XorL dst (LoadL src))); 10070 effect(KILL cr); 10071 10072 ins_cost(125); 10073 format %{ "xorq $dst, $src\t# long" %} 10074 opcode(0x33); 10075 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10076 ins_pipe(ialu_reg_mem); 10077 %} 10078 10079 // Xor Memory with Register 10080 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10081 %{ 10082 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10083 effect(KILL cr); 10084 10085 ins_cost(150); 10086 format %{ "xorq $dst, $src\t# long" %} 10087 opcode(0x31); /* Opcode 31 /r */ 10088 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10089 ins_pipe(ialu_mem_reg); 10090 %} 10091 10092 // Xor Memory with Immediate 10093 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10094 %{ 10095 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10096 effect(KILL cr); 10097 10098 ins_cost(125); 10099 format %{ "xorq $dst, $src\t# long" %} 10100 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 10101 ins_encode(REX_mem_wide(dst), OpcSE(src), 10102 RM_opc_mem(secondary, dst), Con8or32(src)); 10103 ins_pipe(ialu_mem_imm); 10104 %} 10105 10106 // Convert Int to Boolean 10107 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 10108 %{ 10109 match(Set dst (Conv2B src)); 10110 effect(KILL cr); 10111 10112 format %{ "testl $src, $src\t# ci2b\n\t" 10113 "setnz $dst\n\t" 10114 "movzbl $dst, $dst" %} 10115 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10116 setNZ_reg(dst), 10117 REX_reg_breg(dst, dst), // movzbl 10118 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10119 ins_pipe(pipe_slow); // XXX 10120 %} 10121 10122 // Convert Pointer to Boolean 10123 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10124 %{ 10125 match(Set dst (Conv2B src)); 10126 effect(KILL cr); 10127 10128 format %{ "testq $src, $src\t# cp2b\n\t" 10129 "setnz $dst\n\t" 10130 "movzbl $dst, $dst" %} 10131 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10132 setNZ_reg(dst), 10133 REX_reg_breg(dst, dst), // movzbl 10134 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10135 ins_pipe(pipe_slow); // XXX 10136 %} 10137 10138 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10139 %{ 10140 match(Set dst (CmpLTMask p q)); 10141 effect(KILL cr); 10142 10143 ins_cost(400); // XXX 10144 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10145 "setlt $dst\n\t" 10146 "movzbl $dst, $dst\n\t" 10147 "negl $dst" %} 10148 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10149 setLT_reg(dst), 10150 REX_reg_breg(dst, dst), // movzbl 10151 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10152 neg_reg(dst)); 10153 ins_pipe(pipe_slow); 10154 %} 10155 10156 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10157 %{ 10158 match(Set dst (CmpLTMask dst zero)); 10159 effect(KILL cr); 10160 10161 ins_cost(100); // XXX 10162 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10163 opcode(0xC1, 0x7); /* C1 /7 ib */ 10164 ins_encode(reg_opc_imm(dst, 0x1F)); 10165 ins_pipe(ialu_reg); 10166 %} 10167 10168 10169 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr) 10170 %{ 10171 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10172 effect(TEMP tmp, KILL cr); 10173 10174 ins_cost(400); // XXX 10175 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t" 10176 "sbbl $tmp, $tmp\n\t" 10177 "andl $tmp, $y\n\t" 10178 "addl $p, $tmp" %} 10179 ins_encode %{ 10180 Register Rp = $p$$Register; 10181 Register Rq = $q$$Register; 10182 Register Ry = $y$$Register; 10183 Register Rt = $tmp$$Register; 10184 __ subl(Rp, Rq); 10185 __ sbbl(Rt, Rt); 10186 __ andl(Rt, Ry); 10187 __ addl(Rp, Rt); 10188 %} 10189 ins_pipe(pipe_cmplt); 10190 %} 10191 10192 //---------- FP Instructions------------------------------------------------ 10193 10194 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10195 %{ 10196 match(Set cr (CmpF src1 src2)); 10197 10198 ins_cost(145); 10199 format %{ "ucomiss $src1, $src2\n\t" 10200 "jnp,s exit\n\t" 10201 "pushfq\t# saw NaN, set CF\n\t" 10202 "andq [rsp], #0xffffff2b\n\t" 10203 "popfq\n" 10204 "exit: nop\t# avoid branch to branch" %} 10205 opcode(0x0F, 0x2E); 10206 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2), 10207 cmpfp_fixup); 10208 ins_pipe(pipe_slow); 10209 %} 10210 10211 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10212 match(Set cr (CmpF src1 src2)); 10213 10214 ins_cost(145); 10215 format %{ "ucomiss $src1, $src2" %} 10216 ins_encode %{ 10217 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10218 %} 10219 ins_pipe(pipe_slow); 10220 %} 10221 10222 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10223 %{ 10224 match(Set cr (CmpF src1 (LoadF src2))); 10225 10226 ins_cost(145); 10227 format %{ "ucomiss $src1, $src2\n\t" 10228 "jnp,s exit\n\t" 10229 "pushfq\t# saw NaN, set CF\n\t" 10230 "andq [rsp], #0xffffff2b\n\t" 10231 "popfq\n" 10232 "exit: nop\t# avoid branch to branch" %} 10233 opcode(0x0F, 0x2E); 10234 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2), 10235 cmpfp_fixup); 10236 ins_pipe(pipe_slow); 10237 %} 10238 10239 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10240 match(Set cr (CmpF src1 (LoadF src2))); 10241 10242 ins_cost(100); 10243 format %{ "ucomiss $src1, $src2" %} 10244 opcode(0x0F, 0x2E); 10245 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2)); 10246 ins_pipe(pipe_slow); 10247 %} 10248 10249 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10250 match(Set cr (CmpF src con)); 10251 10252 ins_cost(145); 10253 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10254 "jnp,s exit\n\t" 10255 "pushfq\t# saw NaN, set CF\n\t" 10256 "andq [rsp], #0xffffff2b\n\t" 10257 "popfq\n" 10258 "exit: nop\t# avoid branch to branch" %} 10259 ins_encode %{ 10260 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10261 emit_cmpfp_fixup(_masm); 10262 %} 10263 ins_pipe(pipe_slow); 10264 %} 10265 10266 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10267 match(Set cr (CmpF src con)); 10268 ins_cost(100); 10269 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10270 ins_encode %{ 10271 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10272 %} 10273 ins_pipe(pipe_slow); 10274 %} 10275 10276 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10277 %{ 10278 match(Set cr (CmpD src1 src2)); 10279 10280 ins_cost(145); 10281 format %{ "ucomisd $src1, $src2\n\t" 10282 "jnp,s exit\n\t" 10283 "pushfq\t# saw NaN, set CF\n\t" 10284 "andq [rsp], #0xffffff2b\n\t" 10285 "popfq\n" 10286 "exit: nop\t# avoid branch to branch" %} 10287 opcode(0x66, 0x0F, 0x2E); 10288 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2), 10289 cmpfp_fixup); 10290 ins_pipe(pipe_slow); 10291 %} 10292 10293 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10294 match(Set cr (CmpD src1 src2)); 10295 10296 ins_cost(100); 10297 format %{ "ucomisd $src1, $src2 test" %} 10298 ins_encode %{ 10299 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10300 %} 10301 ins_pipe(pipe_slow); 10302 %} 10303 10304 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10305 %{ 10306 match(Set cr (CmpD src1 (LoadD src2))); 10307 10308 ins_cost(145); 10309 format %{ "ucomisd $src1, $src2\n\t" 10310 "jnp,s exit\n\t" 10311 "pushfq\t# saw NaN, set CF\n\t" 10312 "andq [rsp], #0xffffff2b\n\t" 10313 "popfq\n" 10314 "exit: nop\t# avoid branch to branch" %} 10315 opcode(0x66, 0x0F, 0x2E); 10316 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2), 10317 cmpfp_fixup); 10318 ins_pipe(pipe_slow); 10319 %} 10320 10321 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10322 match(Set cr (CmpD src1 (LoadD src2))); 10323 10324 ins_cost(100); 10325 format %{ "ucomisd $src1, $src2" %} 10326 opcode(0x66, 0x0F, 0x2E); 10327 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2)); 10328 ins_pipe(pipe_slow); 10329 %} 10330 10331 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10332 match(Set cr (CmpD src con)); 10333 10334 ins_cost(145); 10335 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10336 "jnp,s exit\n\t" 10337 "pushfq\t# saw NaN, set CF\n\t" 10338 "andq [rsp], #0xffffff2b\n\t" 10339 "popfq\n" 10340 "exit: nop\t# avoid branch to branch" %} 10341 ins_encode %{ 10342 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10343 emit_cmpfp_fixup(_masm); 10344 %} 10345 ins_pipe(pipe_slow); 10346 %} 10347 10348 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10349 match(Set cr (CmpD src con)); 10350 ins_cost(100); 10351 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10352 ins_encode %{ 10353 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10354 %} 10355 ins_pipe(pipe_slow); 10356 %} 10357 10358 // Compare into -1,0,1 10359 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10360 %{ 10361 match(Set dst (CmpF3 src1 src2)); 10362 effect(KILL cr); 10363 10364 ins_cost(275); 10365 format %{ "ucomiss $src1, $src2\n\t" 10366 "movl $dst, #-1\n\t" 10367 "jp,s done\n\t" 10368 "jb,s done\n\t" 10369 "setne $dst\n\t" 10370 "movzbl $dst, $dst\n" 10371 "done:" %} 10372 10373 opcode(0x0F, 0x2E); 10374 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2), 10375 cmpfp3(dst)); 10376 ins_pipe(pipe_slow); 10377 %} 10378 10379 // Compare into -1,0,1 10380 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10381 %{ 10382 match(Set dst (CmpF3 src1 (LoadF src2))); 10383 effect(KILL cr); 10384 10385 ins_cost(275); 10386 format %{ "ucomiss $src1, $src2\n\t" 10387 "movl $dst, #-1\n\t" 10388 "jp,s done\n\t" 10389 "jb,s done\n\t" 10390 "setne $dst\n\t" 10391 "movzbl $dst, $dst\n" 10392 "done:" %} 10393 10394 opcode(0x0F, 0x2E); 10395 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2), 10396 cmpfp3(dst)); 10397 ins_pipe(pipe_slow); 10398 %} 10399 10400 // Compare into -1,0,1 10401 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10402 match(Set dst (CmpF3 src con)); 10403 effect(KILL cr); 10404 10405 ins_cost(275); 10406 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10407 "movl $dst, #-1\n\t" 10408 "jp,s done\n\t" 10409 "jb,s done\n\t" 10410 "setne $dst\n\t" 10411 "movzbl $dst, $dst\n" 10412 "done:" %} 10413 ins_encode %{ 10414 Label L_done; 10415 Register Rdst = $dst$$Register; 10416 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10417 __ movl(Rdst, -1); 10418 __ jcc(Assembler::parity, L_done); 10419 __ jcc(Assembler::below, L_done); 10420 __ setb(Assembler::notEqual, Rdst); 10421 __ movzbl(Rdst, Rdst); 10422 __ bind(L_done); 10423 %} 10424 ins_pipe(pipe_slow); 10425 %} 10426 10427 // Compare into -1,0,1 10428 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10429 %{ 10430 match(Set dst (CmpD3 src1 src2)); 10431 effect(KILL cr); 10432 10433 ins_cost(275); 10434 format %{ "ucomisd $src1, $src2\n\t" 10435 "movl $dst, #-1\n\t" 10436 "jp,s done\n\t" 10437 "jb,s done\n\t" 10438 "setne $dst\n\t" 10439 "movzbl $dst, $dst\n" 10440 "done:" %} 10441 10442 opcode(0x66, 0x0F, 0x2E); 10443 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2), 10444 cmpfp3(dst)); 10445 ins_pipe(pipe_slow); 10446 %} 10447 10448 // Compare into -1,0,1 10449 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10450 %{ 10451 match(Set dst (CmpD3 src1 (LoadD src2))); 10452 effect(KILL cr); 10453 10454 ins_cost(275); 10455 format %{ "ucomisd $src1, $src2\n\t" 10456 "movl $dst, #-1\n\t" 10457 "jp,s done\n\t" 10458 "jb,s done\n\t" 10459 "setne $dst\n\t" 10460 "movzbl $dst, $dst\n" 10461 "done:" %} 10462 10463 opcode(0x66, 0x0F, 0x2E); 10464 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2), 10465 cmpfp3(dst)); 10466 ins_pipe(pipe_slow); 10467 %} 10468 10469 // Compare into -1,0,1 10470 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10471 match(Set dst (CmpD3 src con)); 10472 effect(KILL cr); 10473 10474 ins_cost(275); 10475 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10476 "movl $dst, #-1\n\t" 10477 "jp,s done\n\t" 10478 "jb,s done\n\t" 10479 "setne $dst\n\t" 10480 "movzbl $dst, $dst\n" 10481 "done:" %} 10482 ins_encode %{ 10483 Register Rdst = $dst$$Register; 10484 Label L_done; 10485 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10486 __ movl(Rdst, -1); 10487 __ jcc(Assembler::parity, L_done); 10488 __ jcc(Assembler::below, L_done); 10489 __ setb(Assembler::notEqual, Rdst); 10490 __ movzbl(Rdst, Rdst); 10491 __ bind(L_done); 10492 %} 10493 ins_pipe(pipe_slow); 10494 %} 10495 10496 instruct addF_reg(regF dst, regF src) 10497 %{ 10498 match(Set dst (AddF dst src)); 10499 10500 format %{ "addss $dst, $src" %} 10501 ins_cost(150); // XXX 10502 opcode(0xF3, 0x0F, 0x58); 10503 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10504 ins_pipe(pipe_slow); 10505 %} 10506 10507 instruct addF_mem(regF dst, memory src) 10508 %{ 10509 match(Set dst (AddF dst (LoadF src))); 10510 10511 format %{ "addss $dst, $src" %} 10512 ins_cost(150); // XXX 10513 opcode(0xF3, 0x0F, 0x58); 10514 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10515 ins_pipe(pipe_slow); 10516 %} 10517 10518 instruct addF_imm(regF dst, immF con) %{ 10519 match(Set dst (AddF dst con)); 10520 format %{ "addss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 10521 ins_cost(150); // XXX 10522 ins_encode %{ 10523 __ addss($dst$$XMMRegister, $constantaddress($con)); 10524 %} 10525 ins_pipe(pipe_slow); 10526 %} 10527 10528 instruct addD_reg(regD dst, regD src) 10529 %{ 10530 match(Set dst (AddD dst src)); 10531 10532 format %{ "addsd $dst, $src" %} 10533 ins_cost(150); // XXX 10534 opcode(0xF2, 0x0F, 0x58); 10535 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10536 ins_pipe(pipe_slow); 10537 %} 10538 10539 instruct addD_mem(regD dst, memory src) 10540 %{ 10541 match(Set dst (AddD dst (LoadD src))); 10542 10543 format %{ "addsd $dst, $src" %} 10544 ins_cost(150); // XXX 10545 opcode(0xF2, 0x0F, 0x58); 10546 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10547 ins_pipe(pipe_slow); 10548 %} 10549 10550 instruct addD_imm(regD dst, immD con) %{ 10551 match(Set dst (AddD dst con)); 10552 format %{ "addsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 10553 ins_cost(150); // XXX 10554 ins_encode %{ 10555 __ addsd($dst$$XMMRegister, $constantaddress($con)); 10556 %} 10557 ins_pipe(pipe_slow); 10558 %} 10559 10560 instruct subF_reg(regF dst, regF src) 10561 %{ 10562 match(Set dst (SubF dst src)); 10563 10564 format %{ "subss $dst, $src" %} 10565 ins_cost(150); // XXX 10566 opcode(0xF3, 0x0F, 0x5C); 10567 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10568 ins_pipe(pipe_slow); 10569 %} 10570 10571 instruct subF_mem(regF dst, memory src) 10572 %{ 10573 match(Set dst (SubF dst (LoadF src))); 10574 10575 format %{ "subss $dst, $src" %} 10576 ins_cost(150); // XXX 10577 opcode(0xF3, 0x0F, 0x5C); 10578 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10579 ins_pipe(pipe_slow); 10580 %} 10581 10582 instruct subF_imm(regF dst, immF con) %{ 10583 match(Set dst (SubF dst con)); 10584 format %{ "subss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 10585 ins_cost(150); // XXX 10586 ins_encode %{ 10587 __ subss($dst$$XMMRegister, $constantaddress($con)); 10588 %} 10589 ins_pipe(pipe_slow); 10590 %} 10591 10592 instruct subD_reg(regD dst, regD src) 10593 %{ 10594 match(Set dst (SubD dst src)); 10595 10596 format %{ "subsd $dst, $src" %} 10597 ins_cost(150); // XXX 10598 opcode(0xF2, 0x0F, 0x5C); 10599 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10600 ins_pipe(pipe_slow); 10601 %} 10602 10603 instruct subD_mem(regD dst, memory src) 10604 %{ 10605 match(Set dst (SubD dst (LoadD src))); 10606 10607 format %{ "subsd $dst, $src" %} 10608 ins_cost(150); // XXX 10609 opcode(0xF2, 0x0F, 0x5C); 10610 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10611 ins_pipe(pipe_slow); 10612 %} 10613 10614 instruct subD_imm(regD dst, immD con) %{ 10615 match(Set dst (SubD dst con)); 10616 format %{ "subsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 10617 ins_cost(150); // XXX 10618 ins_encode %{ 10619 __ subsd($dst$$XMMRegister, $constantaddress($con)); 10620 %} 10621 ins_pipe(pipe_slow); 10622 %} 10623 10624 instruct mulF_reg(regF dst, regF src) 10625 %{ 10626 match(Set dst (MulF dst src)); 10627 10628 format %{ "mulss $dst, $src" %} 10629 ins_cost(150); // XXX 10630 opcode(0xF3, 0x0F, 0x59); 10631 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10632 ins_pipe(pipe_slow); 10633 %} 10634 10635 instruct mulF_mem(regF dst, memory src) 10636 %{ 10637 match(Set dst (MulF dst (LoadF src))); 10638 10639 format %{ "mulss $dst, $src" %} 10640 ins_cost(150); // XXX 10641 opcode(0xF3, 0x0F, 0x59); 10642 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10643 ins_pipe(pipe_slow); 10644 %} 10645 10646 instruct mulF_imm(regF dst, immF con) %{ 10647 match(Set dst (MulF dst con)); 10648 format %{ "mulss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 10649 ins_cost(150); // XXX 10650 ins_encode %{ 10651 __ mulss($dst$$XMMRegister, $constantaddress($con)); 10652 %} 10653 ins_pipe(pipe_slow); 10654 %} 10655 10656 instruct mulD_reg(regD dst, regD src) 10657 %{ 10658 match(Set dst (MulD dst src)); 10659 10660 format %{ "mulsd $dst, $src" %} 10661 ins_cost(150); // XXX 10662 opcode(0xF2, 0x0F, 0x59); 10663 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10664 ins_pipe(pipe_slow); 10665 %} 10666 10667 instruct mulD_mem(regD dst, memory src) 10668 %{ 10669 match(Set dst (MulD dst (LoadD src))); 10670 10671 format %{ "mulsd $dst, $src" %} 10672 ins_cost(150); // XXX 10673 opcode(0xF2, 0x0F, 0x59); 10674 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10675 ins_pipe(pipe_slow); 10676 %} 10677 10678 instruct mulD_imm(regD dst, immD con) %{ 10679 match(Set dst (MulD dst con)); 10680 format %{ "mulsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 10681 ins_cost(150); // XXX 10682 ins_encode %{ 10683 __ mulsd($dst$$XMMRegister, $constantaddress($con)); 10684 %} 10685 ins_pipe(pipe_slow); 10686 %} 10687 10688 instruct divF_reg(regF dst, regF src) 10689 %{ 10690 match(Set dst (DivF dst src)); 10691 10692 format %{ "divss $dst, $src" %} 10693 ins_cost(150); // XXX 10694 opcode(0xF3, 0x0F, 0x5E); 10695 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10696 ins_pipe(pipe_slow); 10697 %} 10698 10699 instruct divF_mem(regF dst, memory src) 10700 %{ 10701 match(Set dst (DivF dst (LoadF src))); 10702 10703 format %{ "divss $dst, $src" %} 10704 ins_cost(150); // XXX 10705 opcode(0xF3, 0x0F, 0x5E); 10706 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10707 ins_pipe(pipe_slow); 10708 %} 10709 10710 instruct divF_imm(regF dst, immF con) %{ 10711 match(Set dst (DivF dst con)); 10712 format %{ "divss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 10713 ins_cost(150); // XXX 10714 ins_encode %{ 10715 __ divss($dst$$XMMRegister, $constantaddress($con)); 10716 %} 10717 ins_pipe(pipe_slow); 10718 %} 10719 10720 instruct divD_reg(regD dst, regD src) 10721 %{ 10722 match(Set dst (DivD dst src)); 10723 10724 format %{ "divsd $dst, $src" %} 10725 ins_cost(150); // XXX 10726 opcode(0xF2, 0x0F, 0x5E); 10727 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10728 ins_pipe(pipe_slow); 10729 %} 10730 10731 instruct divD_mem(regD dst, memory src) 10732 %{ 10733 match(Set dst (DivD dst (LoadD src))); 10734 10735 format %{ "divsd $dst, $src" %} 10736 ins_cost(150); // XXX 10737 opcode(0xF2, 0x0F, 0x5E); 10738 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10739 ins_pipe(pipe_slow); 10740 %} 10741 10742 instruct divD_imm(regD dst, immD con) %{ 10743 match(Set dst (DivD dst con)); 10744 format %{ "divsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 10745 ins_cost(150); // XXX 10746 ins_encode %{ 10747 __ divsd($dst$$XMMRegister, $constantaddress($con)); 10748 %} 10749 ins_pipe(pipe_slow); 10750 %} 10751 10752 instruct sqrtF_reg(regF dst, regF src) 10753 %{ 10754 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 10755 10756 format %{ "sqrtss $dst, $src" %} 10757 ins_cost(150); // XXX 10758 opcode(0xF3, 0x0F, 0x51); 10759 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10760 ins_pipe(pipe_slow); 10761 %} 10762 10763 instruct sqrtF_mem(regF dst, memory src) 10764 %{ 10765 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src))))); 10766 10767 format %{ "sqrtss $dst, $src" %} 10768 ins_cost(150); // XXX 10769 opcode(0xF3, 0x0F, 0x51); 10770 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10771 ins_pipe(pipe_slow); 10772 %} 10773 10774 instruct sqrtF_imm(regF dst, immF con) %{ 10775 match(Set dst (ConvD2F (SqrtD (ConvF2D con)))); 10776 format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 10777 ins_cost(150); // XXX 10778 ins_encode %{ 10779 __ sqrtss($dst$$XMMRegister, $constantaddress($con)); 10780 %} 10781 ins_pipe(pipe_slow); 10782 %} 10783 10784 instruct sqrtD_reg(regD dst, regD src) 10785 %{ 10786 match(Set dst (SqrtD src)); 10787 10788 format %{ "sqrtsd $dst, $src" %} 10789 ins_cost(150); // XXX 10790 opcode(0xF2, 0x0F, 0x51); 10791 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10792 ins_pipe(pipe_slow); 10793 %} 10794 10795 instruct sqrtD_mem(regD dst, memory src) 10796 %{ 10797 match(Set dst (SqrtD (LoadD src))); 10798 10799 format %{ "sqrtsd $dst, $src" %} 10800 ins_cost(150); // XXX 10801 opcode(0xF2, 0x0F, 0x51); 10802 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10803 ins_pipe(pipe_slow); 10804 %} 10805 10806 instruct sqrtD_imm(regD dst, immD con) %{ 10807 match(Set dst (SqrtD con)); 10808 format %{ "sqrtsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 10809 ins_cost(150); // XXX 10810 ins_encode %{ 10811 __ sqrtsd($dst$$XMMRegister, $constantaddress($con)); 10812 %} 10813 ins_pipe(pipe_slow); 10814 %} 10815 10816 instruct absF_reg(regF dst) 10817 %{ 10818 match(Set dst (AbsF dst)); 10819 10820 format %{ "andps $dst, [0x7fffffff]\t# abs float by sign masking" %} 10821 ins_encode(absF_encoding(dst)); 10822 ins_pipe(pipe_slow); 10823 %} 10824 10825 instruct absD_reg(regD dst) 10826 %{ 10827 match(Set dst (AbsD dst)); 10828 10829 format %{ "andpd $dst, [0x7fffffffffffffff]\t" 10830 "# abs double by sign masking" %} 10831 ins_encode(absD_encoding(dst)); 10832 ins_pipe(pipe_slow); 10833 %} 10834 10835 instruct negF_reg(regF dst) 10836 %{ 10837 match(Set dst (NegF dst)); 10838 10839 format %{ "xorps $dst, [0x80000000]\t# neg float by sign flipping" %} 10840 ins_encode(negF_encoding(dst)); 10841 ins_pipe(pipe_slow); 10842 %} 10843 10844 instruct negD_reg(regD dst) 10845 %{ 10846 match(Set dst (NegD dst)); 10847 10848 format %{ "xorpd $dst, [0x8000000000000000]\t" 10849 "# neg double by sign flipping" %} 10850 ins_encode(negD_encoding(dst)); 10851 ins_pipe(pipe_slow); 10852 %} 10853 10854 // -----------Trig and Trancendental Instructions------------------------------ 10855 instruct cosD_reg(regD dst) %{ 10856 match(Set dst (CosD dst)); 10857 10858 format %{ "dcos $dst\n\t" %} 10859 opcode(0xD9, 0xFF); 10860 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 10861 ins_pipe( pipe_slow ); 10862 %} 10863 10864 instruct sinD_reg(regD dst) %{ 10865 match(Set dst (SinD dst)); 10866 10867 format %{ "dsin $dst\n\t" %} 10868 opcode(0xD9, 0xFE); 10869 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 10870 ins_pipe( pipe_slow ); 10871 %} 10872 10873 instruct tanD_reg(regD dst) %{ 10874 match(Set dst (TanD dst)); 10875 10876 format %{ "dtan $dst\n\t" %} 10877 ins_encode( Push_SrcXD(dst), 10878 Opcode(0xD9), Opcode(0xF2), //fptan 10879 Opcode(0xDD), Opcode(0xD8), //fstp st 10880 Push_ResultXD(dst) ); 10881 ins_pipe( pipe_slow ); 10882 %} 10883 10884 instruct log10D_reg(regD dst) %{ 10885 // The source and result Double operands in XMM registers 10886 match(Set dst (Log10D dst)); 10887 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 10888 // fyl2x ; compute log_10(2) * log_2(x) 10889 format %{ "fldlg2\t\t\t#Log10\n\t" 10890 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 10891 %} 10892 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 10893 Push_SrcXD(dst), 10894 Opcode(0xD9), Opcode(0xF1), // fyl2x 10895 Push_ResultXD(dst)); 10896 10897 ins_pipe( pipe_slow ); 10898 %} 10899 10900 instruct logD_reg(regD dst) %{ 10901 // The source and result Double operands in XMM registers 10902 match(Set dst (LogD dst)); 10903 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 10904 // fyl2x ; compute log_e(2) * log_2(x) 10905 format %{ "fldln2\t\t\t#Log_e\n\t" 10906 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 10907 %} 10908 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 10909 Push_SrcXD(dst), 10910 Opcode(0xD9), Opcode(0xF1), // fyl2x 10911 Push_ResultXD(dst)); 10912 ins_pipe( pipe_slow ); 10913 %} 10914 10915 10916 10917 //----------Arithmetic Conversion Instructions--------------------------------- 10918 10919 instruct roundFloat_nop(regF dst) 10920 %{ 10921 match(Set dst (RoundFloat dst)); 10922 10923 ins_cost(0); 10924 ins_encode(); 10925 ins_pipe(empty); 10926 %} 10927 10928 instruct roundDouble_nop(regD dst) 10929 %{ 10930 match(Set dst (RoundDouble dst)); 10931 10932 ins_cost(0); 10933 ins_encode(); 10934 ins_pipe(empty); 10935 %} 10936 10937 instruct convF2D_reg_reg(regD dst, regF src) 10938 %{ 10939 match(Set dst (ConvF2D src)); 10940 10941 format %{ "cvtss2sd $dst, $src" %} 10942 opcode(0xF3, 0x0F, 0x5A); 10943 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10944 ins_pipe(pipe_slow); // XXX 10945 %} 10946 10947 instruct convF2D_reg_mem(regD dst, memory src) 10948 %{ 10949 match(Set dst (ConvF2D (LoadF src))); 10950 10951 format %{ "cvtss2sd $dst, $src" %} 10952 opcode(0xF3, 0x0F, 0x5A); 10953 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10954 ins_pipe(pipe_slow); // XXX 10955 %} 10956 10957 instruct convD2F_reg_reg(regF dst, regD src) 10958 %{ 10959 match(Set dst (ConvD2F src)); 10960 10961 format %{ "cvtsd2ss $dst, $src" %} 10962 opcode(0xF2, 0x0F, 0x5A); 10963 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10964 ins_pipe(pipe_slow); // XXX 10965 %} 10966 10967 instruct convD2F_reg_mem(regF dst, memory src) 10968 %{ 10969 match(Set dst (ConvD2F (LoadD src))); 10970 10971 format %{ "cvtsd2ss $dst, $src" %} 10972 opcode(0xF2, 0x0F, 0x5A); 10973 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10974 ins_pipe(pipe_slow); // XXX 10975 %} 10976 10977 // XXX do mem variants 10978 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10979 %{ 10980 match(Set dst (ConvF2I src)); 10981 effect(KILL cr); 10982 10983 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10984 "cmpl $dst, #0x80000000\n\t" 10985 "jne,s done\n\t" 10986 "subq rsp, #8\n\t" 10987 "movss [rsp], $src\n\t" 10988 "call f2i_fixup\n\t" 10989 "popq $dst\n" 10990 "done: "%} 10991 opcode(0xF3, 0x0F, 0x2C); 10992 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src), 10993 f2i_fixup(dst, src)); 10994 ins_pipe(pipe_slow); 10995 %} 10996 10997 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10998 %{ 10999 match(Set dst (ConvF2L src)); 11000 effect(KILL cr); 11001 11002 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 11003 "cmpq $dst, [0x8000000000000000]\n\t" 11004 "jne,s done\n\t" 11005 "subq rsp, #8\n\t" 11006 "movss [rsp], $src\n\t" 11007 "call f2l_fixup\n\t" 11008 "popq $dst\n" 11009 "done: "%} 11010 opcode(0xF3, 0x0F, 0x2C); 11011 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src), 11012 f2l_fixup(dst, src)); 11013 ins_pipe(pipe_slow); 11014 %} 11015 11016 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 11017 %{ 11018 match(Set dst (ConvD2I src)); 11019 effect(KILL cr); 11020 11021 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 11022 "cmpl $dst, #0x80000000\n\t" 11023 "jne,s done\n\t" 11024 "subq rsp, #8\n\t" 11025 "movsd [rsp], $src\n\t" 11026 "call d2i_fixup\n\t" 11027 "popq $dst\n" 11028 "done: "%} 11029 opcode(0xF2, 0x0F, 0x2C); 11030 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src), 11031 d2i_fixup(dst, src)); 11032 ins_pipe(pipe_slow); 11033 %} 11034 11035 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 11036 %{ 11037 match(Set dst (ConvD2L src)); 11038 effect(KILL cr); 11039 11040 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 11041 "cmpq $dst, [0x8000000000000000]\n\t" 11042 "jne,s done\n\t" 11043 "subq rsp, #8\n\t" 11044 "movsd [rsp], $src\n\t" 11045 "call d2l_fixup\n\t" 11046 "popq $dst\n" 11047 "done: "%} 11048 opcode(0xF2, 0x0F, 0x2C); 11049 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src), 11050 d2l_fixup(dst, src)); 11051 ins_pipe(pipe_slow); 11052 %} 11053 11054 instruct convI2F_reg_reg(regF dst, rRegI src) 11055 %{ 11056 predicate(!UseXmmI2F); 11057 match(Set dst (ConvI2F src)); 11058 11059 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11060 opcode(0xF3, 0x0F, 0x2A); 11061 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 11062 ins_pipe(pipe_slow); // XXX 11063 %} 11064 11065 instruct convI2F_reg_mem(regF dst, memory src) 11066 %{ 11067 match(Set dst (ConvI2F (LoadI src))); 11068 11069 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11070 opcode(0xF3, 0x0F, 0x2A); 11071 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11072 ins_pipe(pipe_slow); // XXX 11073 %} 11074 11075 instruct convI2D_reg_reg(regD dst, rRegI src) 11076 %{ 11077 predicate(!UseXmmI2D); 11078 match(Set dst (ConvI2D src)); 11079 11080 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11081 opcode(0xF2, 0x0F, 0x2A); 11082 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 11083 ins_pipe(pipe_slow); // XXX 11084 %} 11085 11086 instruct convI2D_reg_mem(regD dst, memory src) 11087 %{ 11088 match(Set dst (ConvI2D (LoadI src))); 11089 11090 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11091 opcode(0xF2, 0x0F, 0x2A); 11092 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11093 ins_pipe(pipe_slow); // XXX 11094 %} 11095 11096 instruct convXI2F_reg(regF dst, rRegI src) 11097 %{ 11098 predicate(UseXmmI2F); 11099 match(Set dst (ConvI2F src)); 11100 11101 format %{ "movdl $dst, $src\n\t" 11102 "cvtdq2psl $dst, $dst\t# i2f" %} 11103 ins_encode %{ 11104 __ movdl($dst$$XMMRegister, $src$$Register); 11105 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 11106 %} 11107 ins_pipe(pipe_slow); // XXX 11108 %} 11109 11110 instruct convXI2D_reg(regD dst, rRegI src) 11111 %{ 11112 predicate(UseXmmI2D); 11113 match(Set dst (ConvI2D src)); 11114 11115 format %{ "movdl $dst, $src\n\t" 11116 "cvtdq2pdl $dst, $dst\t# i2d" %} 11117 ins_encode %{ 11118 __ movdl($dst$$XMMRegister, $src$$Register); 11119 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 11120 %} 11121 ins_pipe(pipe_slow); // XXX 11122 %} 11123 11124 instruct convL2F_reg_reg(regF dst, rRegL src) 11125 %{ 11126 match(Set dst (ConvL2F src)); 11127 11128 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11129 opcode(0xF3, 0x0F, 0x2A); 11130 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src)); 11131 ins_pipe(pipe_slow); // XXX 11132 %} 11133 11134 instruct convL2F_reg_mem(regF dst, memory src) 11135 %{ 11136 match(Set dst (ConvL2F (LoadL src))); 11137 11138 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11139 opcode(0xF3, 0x0F, 0x2A); 11140 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11141 ins_pipe(pipe_slow); // XXX 11142 %} 11143 11144 instruct convL2D_reg_reg(regD dst, rRegL src) 11145 %{ 11146 match(Set dst (ConvL2D src)); 11147 11148 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11149 opcode(0xF2, 0x0F, 0x2A); 11150 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src)); 11151 ins_pipe(pipe_slow); // XXX 11152 %} 11153 11154 instruct convL2D_reg_mem(regD dst, memory src) 11155 %{ 11156 match(Set dst (ConvL2D (LoadL src))); 11157 11158 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11159 opcode(0xF2, 0x0F, 0x2A); 11160 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11161 ins_pipe(pipe_slow); // XXX 11162 %} 11163 11164 instruct convI2L_reg_reg(rRegL dst, rRegI src) 11165 %{ 11166 match(Set dst (ConvI2L src)); 11167 11168 ins_cost(125); 11169 format %{ "movslq $dst, $src\t# i2l" %} 11170 ins_encode %{ 11171 __ movslq($dst$$Register, $src$$Register); 11172 %} 11173 ins_pipe(ialu_reg_reg); 11174 %} 11175 11176 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 11177 // %{ 11178 // match(Set dst (ConvI2L src)); 11179 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 11180 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 11181 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 11182 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 11183 // ((const TypeNode*) n)->type()->is_long()->_lo == 11184 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 11185 11186 // format %{ "movl $dst, $src\t# unsigned i2l" %} 11187 // ins_encode(enc_copy(dst, src)); 11188 // // opcode(0x63); // needs REX.W 11189 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 11190 // ins_pipe(ialu_reg_reg); 11191 // %} 11192 11193 // Zero-extend convert int to long 11194 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 11195 %{ 11196 match(Set dst (AndL (ConvI2L src) mask)); 11197 11198 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11199 ins_encode(enc_copy(dst, src)); 11200 ins_pipe(ialu_reg_reg); 11201 %} 11202 11203 // Zero-extend convert int to long 11204 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 11205 %{ 11206 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 11207 11208 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11209 opcode(0x8B); 11210 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 11211 ins_pipe(ialu_reg_mem); 11212 %} 11213 11214 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 11215 %{ 11216 match(Set dst (AndL src mask)); 11217 11218 format %{ "movl $dst, $src\t# zero-extend long" %} 11219 ins_encode(enc_copy_always(dst, src)); 11220 ins_pipe(ialu_reg_reg); 11221 %} 11222 11223 instruct convL2I_reg_reg(rRegI dst, rRegL src) 11224 %{ 11225 match(Set dst (ConvL2I src)); 11226 11227 format %{ "movl $dst, $src\t# l2i" %} 11228 ins_encode(enc_copy_always(dst, src)); 11229 ins_pipe(ialu_reg_reg); 11230 %} 11231 11232 11233 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 11234 match(Set dst (MoveF2I src)); 11235 effect(DEF dst, USE src); 11236 11237 ins_cost(125); 11238 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 11239 opcode(0x8B); 11240 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 11241 ins_pipe(ialu_reg_mem); 11242 %} 11243 11244 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 11245 match(Set dst (MoveI2F src)); 11246 effect(DEF dst, USE src); 11247 11248 ins_cost(125); 11249 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 11250 opcode(0xF3, 0x0F, 0x10); 11251 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11252 ins_pipe(pipe_slow); 11253 %} 11254 11255 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 11256 match(Set dst (MoveD2L src)); 11257 effect(DEF dst, USE src); 11258 11259 ins_cost(125); 11260 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 11261 opcode(0x8B); 11262 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 11263 ins_pipe(ialu_reg_mem); 11264 %} 11265 11266 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 11267 predicate(!UseXmmLoadAndClearUpper); 11268 match(Set dst (MoveL2D src)); 11269 effect(DEF dst, USE src); 11270 11271 ins_cost(125); 11272 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 11273 opcode(0x66, 0x0F, 0x12); 11274 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11275 ins_pipe(pipe_slow); 11276 %} 11277 11278 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 11279 predicate(UseXmmLoadAndClearUpper); 11280 match(Set dst (MoveL2D src)); 11281 effect(DEF dst, USE src); 11282 11283 ins_cost(125); 11284 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 11285 opcode(0xF2, 0x0F, 0x10); 11286 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11287 ins_pipe(pipe_slow); 11288 %} 11289 11290 11291 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 11292 match(Set dst (MoveF2I src)); 11293 effect(DEF dst, USE src); 11294 11295 ins_cost(95); // XXX 11296 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 11297 opcode(0xF3, 0x0F, 0x11); 11298 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 11299 ins_pipe(pipe_slow); 11300 %} 11301 11302 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 11303 match(Set dst (MoveI2F src)); 11304 effect(DEF dst, USE src); 11305 11306 ins_cost(100); 11307 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 11308 opcode(0x89); 11309 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 11310 ins_pipe( ialu_mem_reg ); 11311 %} 11312 11313 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 11314 match(Set dst (MoveD2L src)); 11315 effect(DEF dst, USE src); 11316 11317 ins_cost(95); // XXX 11318 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 11319 opcode(0xF2, 0x0F, 0x11); 11320 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 11321 ins_pipe(pipe_slow); 11322 %} 11323 11324 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 11325 match(Set dst (MoveL2D src)); 11326 effect(DEF dst, USE src); 11327 11328 ins_cost(100); 11329 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 11330 opcode(0x89); 11331 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 11332 ins_pipe(ialu_mem_reg); 11333 %} 11334 11335 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 11336 match(Set dst (MoveF2I src)); 11337 effect(DEF dst, USE src); 11338 ins_cost(85); 11339 format %{ "movd $dst,$src\t# MoveF2I" %} 11340 ins_encode %{ __ movdl($dst$$Register, $src$$XMMRegister); %} 11341 ins_pipe( pipe_slow ); 11342 %} 11343 11344 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 11345 match(Set dst (MoveD2L src)); 11346 effect(DEF dst, USE src); 11347 ins_cost(85); 11348 format %{ "movd $dst,$src\t# MoveD2L" %} 11349 ins_encode %{ __ movdq($dst$$Register, $src$$XMMRegister); %} 11350 ins_pipe( pipe_slow ); 11351 %} 11352 11353 // The next instructions have long latency and use Int unit. Set high cost. 11354 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 11355 match(Set dst (MoveI2F src)); 11356 effect(DEF dst, USE src); 11357 ins_cost(300); 11358 format %{ "movd $dst,$src\t# MoveI2F" %} 11359 ins_encode %{ __ movdl($dst$$XMMRegister, $src$$Register); %} 11360 ins_pipe( pipe_slow ); 11361 %} 11362 11363 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 11364 match(Set dst (MoveL2D src)); 11365 effect(DEF dst, USE src); 11366 ins_cost(300); 11367 format %{ "movd $dst,$src\t# MoveL2D" %} 11368 ins_encode %{ __ movdq($dst$$XMMRegister, $src$$Register); %} 11369 ins_pipe( pipe_slow ); 11370 %} 11371 11372 // Replicate scalar to packed byte (1 byte) values in xmm 11373 instruct Repl8B_reg(regD dst, regD src) %{ 11374 match(Set dst (Replicate8B src)); 11375 format %{ "MOVDQA $dst,$src\n\t" 11376 "PUNPCKLBW $dst,$dst\n\t" 11377 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 11378 ins_encode( pshufd_8x8(dst, src)); 11379 ins_pipe( pipe_slow ); 11380 %} 11381 11382 // Replicate scalar to packed byte (1 byte) values in xmm 11383 instruct Repl8B_rRegI(regD dst, rRegI src) %{ 11384 match(Set dst (Replicate8B src)); 11385 format %{ "MOVD $dst,$src\n\t" 11386 "PUNPCKLBW $dst,$dst\n\t" 11387 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 11388 ins_encode( mov_i2x(dst, src), pshufd_8x8(dst, dst)); 11389 ins_pipe( pipe_slow ); 11390 %} 11391 11392 // Replicate scalar zero to packed byte (1 byte) values in xmm 11393 instruct Repl8B_immI0(regD dst, immI0 zero) %{ 11394 match(Set dst (Replicate8B zero)); 11395 format %{ "PXOR $dst,$dst\t! replicate8B" %} 11396 ins_encode( pxor(dst, dst)); 11397 ins_pipe( fpu_reg_reg ); 11398 %} 11399 11400 // Replicate scalar to packed shore (2 byte) values in xmm 11401 instruct Repl4S_reg(regD dst, regD src) %{ 11402 match(Set dst (Replicate4S src)); 11403 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %} 11404 ins_encode( pshufd_4x16(dst, src)); 11405 ins_pipe( fpu_reg_reg ); 11406 %} 11407 11408 // Replicate scalar to packed shore (2 byte) values in xmm 11409 instruct Repl4S_rRegI(regD dst, rRegI src) %{ 11410 match(Set dst (Replicate4S src)); 11411 format %{ "MOVD $dst,$src\n\t" 11412 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %} 11413 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst)); 11414 ins_pipe( fpu_reg_reg ); 11415 %} 11416 11417 // Replicate scalar zero to packed short (2 byte) values in xmm 11418 instruct Repl4S_immI0(regD dst, immI0 zero) %{ 11419 match(Set dst (Replicate4S zero)); 11420 format %{ "PXOR $dst,$dst\t! replicate4S" %} 11421 ins_encode( pxor(dst, dst)); 11422 ins_pipe( fpu_reg_reg ); 11423 %} 11424 11425 // Replicate scalar to packed char (2 byte) values in xmm 11426 instruct Repl4C_reg(regD dst, regD src) %{ 11427 match(Set dst (Replicate4C src)); 11428 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %} 11429 ins_encode( pshufd_4x16(dst, src)); 11430 ins_pipe( fpu_reg_reg ); 11431 %} 11432 11433 // Replicate scalar to packed char (2 byte) values in xmm 11434 instruct Repl4C_rRegI(regD dst, rRegI src) %{ 11435 match(Set dst (Replicate4C src)); 11436 format %{ "MOVD $dst,$src\n\t" 11437 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %} 11438 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst)); 11439 ins_pipe( fpu_reg_reg ); 11440 %} 11441 11442 // Replicate scalar zero to packed char (2 byte) values in xmm 11443 instruct Repl4C_immI0(regD dst, immI0 zero) %{ 11444 match(Set dst (Replicate4C zero)); 11445 format %{ "PXOR $dst,$dst\t! replicate4C" %} 11446 ins_encode( pxor(dst, dst)); 11447 ins_pipe( fpu_reg_reg ); 11448 %} 11449 11450 // Replicate scalar to packed integer (4 byte) values in xmm 11451 instruct Repl2I_reg(regD dst, regD src) %{ 11452 match(Set dst (Replicate2I src)); 11453 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %} 11454 ins_encode( pshufd(dst, src, 0x00)); 11455 ins_pipe( fpu_reg_reg ); 11456 %} 11457 11458 // Replicate scalar to packed integer (4 byte) values in xmm 11459 instruct Repl2I_rRegI(regD dst, rRegI src) %{ 11460 match(Set dst (Replicate2I src)); 11461 format %{ "MOVD $dst,$src\n\t" 11462 "PSHUFD $dst,$dst,0x00\t! replicate2I" %} 11463 ins_encode( mov_i2x(dst, src), pshufd(dst, dst, 0x00)); 11464 ins_pipe( fpu_reg_reg ); 11465 %} 11466 11467 // Replicate scalar zero to packed integer (2 byte) values in xmm 11468 instruct Repl2I_immI0(regD dst, immI0 zero) %{ 11469 match(Set dst (Replicate2I zero)); 11470 format %{ "PXOR $dst,$dst\t! replicate2I" %} 11471 ins_encode( pxor(dst, dst)); 11472 ins_pipe( fpu_reg_reg ); 11473 %} 11474 11475 // Replicate scalar to packed single precision floating point values in xmm 11476 instruct Repl2F_reg(regD dst, regD src) %{ 11477 match(Set dst (Replicate2F src)); 11478 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 11479 ins_encode( pshufd(dst, src, 0xe0)); 11480 ins_pipe( fpu_reg_reg ); 11481 %} 11482 11483 // Replicate scalar to packed single precision floating point values in xmm 11484 instruct Repl2F_regF(regD dst, regF src) %{ 11485 match(Set dst (Replicate2F src)); 11486 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 11487 ins_encode( pshufd(dst, src, 0xe0)); 11488 ins_pipe( fpu_reg_reg ); 11489 %} 11490 11491 // Replicate scalar to packed single precision floating point values in xmm 11492 instruct Repl2F_immF0(regD dst, immF0 zero) %{ 11493 match(Set dst (Replicate2F zero)); 11494 format %{ "PXOR $dst,$dst\t! replicate2F" %} 11495 ins_encode( pxor(dst, dst)); 11496 ins_pipe( fpu_reg_reg ); 11497 %} 11498 11499 11500 // ======================================================================= 11501 // fast clearing of an array 11502 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 11503 rFlagsReg cr) 11504 %{ 11505 match(Set dummy (ClearArray cnt base)); 11506 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 11507 11508 format %{ "xorl rax, rax\t# ClearArray:\n\t" 11509 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 11510 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax 11511 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos 11512 ins_pipe(pipe_slow); 11513 %} 11514 11515 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11516 rax_RegI result, regD tmp1, rFlagsReg cr) 11517 %{ 11518 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11519 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11520 11521 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11522 ins_encode %{ 11523 __ string_compare($str1$$Register, $str2$$Register, 11524 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11525 $tmp1$$XMMRegister); 11526 %} 11527 ins_pipe( pipe_slow ); 11528 %} 11529 11530 // fast search of substring with known size. 11531 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11532 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11533 %{ 11534 predicate(UseSSE42Intrinsics); 11535 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11536 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11537 11538 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11539 ins_encode %{ 11540 int icnt2 = (int)$int_cnt2$$constant; 11541 if (icnt2 >= 8) { 11542 // IndexOf for constant substrings with size >= 8 elements 11543 // which don't need to be loaded through stack. 11544 __ string_indexofC8($str1$$Register, $str2$$Register, 11545 $cnt1$$Register, $cnt2$$Register, 11546 icnt2, $result$$Register, 11547 $vec$$XMMRegister, $tmp$$Register); 11548 } else { 11549 // Small strings are loaded through stack if they cross page boundary. 11550 __ string_indexof($str1$$Register, $str2$$Register, 11551 $cnt1$$Register, $cnt2$$Register, 11552 icnt2, $result$$Register, 11553 $vec$$XMMRegister, $tmp$$Register); 11554 } 11555 %} 11556 ins_pipe( pipe_slow ); 11557 %} 11558 11559 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11560 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11561 %{ 11562 predicate(UseSSE42Intrinsics); 11563 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11564 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11565 11566 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11567 ins_encode %{ 11568 __ string_indexof($str1$$Register, $str2$$Register, 11569 $cnt1$$Register, $cnt2$$Register, 11570 (-1), $result$$Register, 11571 $vec$$XMMRegister, $tmp$$Register); 11572 %} 11573 ins_pipe( pipe_slow ); 11574 %} 11575 11576 // fast string equals 11577 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11578 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11579 %{ 11580 match(Set result (StrEquals (Binary str1 str2) cnt)); 11581 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11582 11583 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11584 ins_encode %{ 11585 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 11586 $cnt$$Register, $result$$Register, $tmp3$$Register, 11587 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11588 %} 11589 ins_pipe( pipe_slow ); 11590 %} 11591 11592 // fast array equals 11593 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11594 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11595 %{ 11596 match(Set result (AryEq ary1 ary2)); 11597 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11598 //ins_cost(300); 11599 11600 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11601 ins_encode %{ 11602 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 11603 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11604 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11605 %} 11606 ins_pipe( pipe_slow ); 11607 %} 11608 11609 //----------Control Flow Instructions------------------------------------------ 11610 // Signed compare Instructions 11611 11612 // XXX more variants!! 11613 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11614 %{ 11615 match(Set cr (CmpI op1 op2)); 11616 effect(DEF cr, USE op1, USE op2); 11617 11618 format %{ "cmpl $op1, $op2" %} 11619 opcode(0x3B); /* Opcode 3B /r */ 11620 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11621 ins_pipe(ialu_cr_reg_reg); 11622 %} 11623 11624 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11625 %{ 11626 match(Set cr (CmpI op1 op2)); 11627 11628 format %{ "cmpl $op1, $op2" %} 11629 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11630 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11631 ins_pipe(ialu_cr_reg_imm); 11632 %} 11633 11634 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11635 %{ 11636 match(Set cr (CmpI op1 (LoadI op2))); 11637 11638 ins_cost(500); // XXX 11639 format %{ "cmpl $op1, $op2" %} 11640 opcode(0x3B); /* Opcode 3B /r */ 11641 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11642 ins_pipe(ialu_cr_reg_mem); 11643 %} 11644 11645 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11646 %{ 11647 match(Set cr (CmpI src zero)); 11648 11649 format %{ "testl $src, $src" %} 11650 opcode(0x85); 11651 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11652 ins_pipe(ialu_cr_reg_imm); 11653 %} 11654 11655 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11656 %{ 11657 match(Set cr (CmpI (AndI src con) zero)); 11658 11659 format %{ "testl $src, $con" %} 11660 opcode(0xF7, 0x00); 11661 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11662 ins_pipe(ialu_cr_reg_imm); 11663 %} 11664 11665 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11666 %{ 11667 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11668 11669 format %{ "testl $src, $mem" %} 11670 opcode(0x85); 11671 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11672 ins_pipe(ialu_cr_reg_mem); 11673 %} 11674 11675 // Unsigned compare Instructions; really, same as signed except they 11676 // produce an rFlagsRegU instead of rFlagsReg. 11677 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11678 %{ 11679 match(Set cr (CmpU op1 op2)); 11680 11681 format %{ "cmpl $op1, $op2\t# unsigned" %} 11682 opcode(0x3B); /* Opcode 3B /r */ 11683 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11684 ins_pipe(ialu_cr_reg_reg); 11685 %} 11686 11687 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11688 %{ 11689 match(Set cr (CmpU op1 op2)); 11690 11691 format %{ "cmpl $op1, $op2\t# unsigned" %} 11692 opcode(0x81,0x07); /* Opcode 81 /7 */ 11693 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11694 ins_pipe(ialu_cr_reg_imm); 11695 %} 11696 11697 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11698 %{ 11699 match(Set cr (CmpU op1 (LoadI op2))); 11700 11701 ins_cost(500); // XXX 11702 format %{ "cmpl $op1, $op2\t# unsigned" %} 11703 opcode(0x3B); /* Opcode 3B /r */ 11704 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11705 ins_pipe(ialu_cr_reg_mem); 11706 %} 11707 11708 // // // Cisc-spilled version of cmpU_rReg 11709 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11710 // //%{ 11711 // // match(Set cr (CmpU (LoadI op1) op2)); 11712 // // 11713 // // format %{ "CMPu $op1,$op2" %} 11714 // // ins_cost(500); 11715 // // opcode(0x39); /* Opcode 39 /r */ 11716 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11717 // //%} 11718 11719 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11720 %{ 11721 match(Set cr (CmpU src zero)); 11722 11723 format %{ "testl $src, $src\t# unsigned" %} 11724 opcode(0x85); 11725 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11726 ins_pipe(ialu_cr_reg_imm); 11727 %} 11728 11729 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11730 %{ 11731 match(Set cr (CmpP op1 op2)); 11732 11733 format %{ "cmpq $op1, $op2\t# ptr" %} 11734 opcode(0x3B); /* Opcode 3B /r */ 11735 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11736 ins_pipe(ialu_cr_reg_reg); 11737 %} 11738 11739 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11740 %{ 11741 match(Set cr (CmpP op1 (LoadP op2))); 11742 11743 ins_cost(500); // XXX 11744 format %{ "cmpq $op1, $op2\t# ptr" %} 11745 opcode(0x3B); /* Opcode 3B /r */ 11746 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11747 ins_pipe(ialu_cr_reg_mem); 11748 %} 11749 11750 // // // Cisc-spilled version of cmpP_rReg 11751 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11752 // //%{ 11753 // // match(Set cr (CmpP (LoadP op1) op2)); 11754 // // 11755 // // format %{ "CMPu $op1,$op2" %} 11756 // // ins_cost(500); 11757 // // opcode(0x39); /* Opcode 39 /r */ 11758 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11759 // //%} 11760 11761 // XXX this is generalized by compP_rReg_mem??? 11762 // Compare raw pointer (used in out-of-heap check). 11763 // Only works because non-oop pointers must be raw pointers 11764 // and raw pointers have no anti-dependencies. 11765 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11766 %{ 11767 predicate(!n->in(2)->in(2)->bottom_type()->isa_oop_ptr()); 11768 match(Set cr (CmpP op1 (LoadP op2))); 11769 11770 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11771 opcode(0x3B); /* Opcode 3B /r */ 11772 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11773 ins_pipe(ialu_cr_reg_mem); 11774 %} 11775 11776 // This will generate a signed flags result. This should be OK since 11777 // any compare to a zero should be eq/neq. 11778 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11779 %{ 11780 match(Set cr (CmpP src zero)); 11781 11782 format %{ "testq $src, $src\t# ptr" %} 11783 opcode(0x85); 11784 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11785 ins_pipe(ialu_cr_reg_imm); 11786 %} 11787 11788 // This will generate a signed flags result. This should be OK since 11789 // any compare to a zero should be eq/neq. 11790 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11791 %{ 11792 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11793 match(Set cr (CmpP (LoadP op) zero)); 11794 11795 ins_cost(500); // XXX 11796 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11797 opcode(0xF7); /* Opcode F7 /0 */ 11798 ins_encode(REX_mem_wide(op), 11799 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11800 ins_pipe(ialu_cr_reg_imm); 11801 %} 11802 11803 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11804 %{ 11805 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 11806 match(Set cr (CmpP (LoadP mem) zero)); 11807 11808 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11809 ins_encode %{ 11810 __ cmpq(r12, $mem$$Address); 11811 %} 11812 ins_pipe(ialu_cr_reg_mem); 11813 %} 11814 11815 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11816 %{ 11817 match(Set cr (CmpN op1 op2)); 11818 11819 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11820 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11821 ins_pipe(ialu_cr_reg_reg); 11822 %} 11823 11824 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11825 %{ 11826 match(Set cr (CmpN src (LoadN mem))); 11827 11828 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11829 ins_encode %{ 11830 __ cmpl($src$$Register, $mem$$Address); 11831 %} 11832 ins_pipe(ialu_cr_reg_mem); 11833 %} 11834 11835 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11836 match(Set cr (CmpN op1 op2)); 11837 11838 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11839 ins_encode %{ 11840 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11841 %} 11842 ins_pipe(ialu_cr_reg_imm); 11843 %} 11844 11845 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11846 %{ 11847 match(Set cr (CmpN src (LoadN mem))); 11848 11849 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11850 ins_encode %{ 11851 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11852 %} 11853 ins_pipe(ialu_cr_reg_mem); 11854 %} 11855 11856 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11857 match(Set cr (CmpN src zero)); 11858 11859 format %{ "testl $src, $src\t# compressed ptr" %} 11860 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11861 ins_pipe(ialu_cr_reg_imm); 11862 %} 11863 11864 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11865 %{ 11866 predicate(Universe::narrow_oop_base() != NULL); 11867 match(Set cr (CmpN (LoadN mem) zero)); 11868 11869 ins_cost(500); // XXX 11870 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11871 ins_encode %{ 11872 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11873 %} 11874 ins_pipe(ialu_cr_reg_mem); 11875 %} 11876 11877 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11878 %{ 11879 predicate(Universe::narrow_oop_base() == NULL); 11880 match(Set cr (CmpN (LoadN mem) zero)); 11881 11882 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11883 ins_encode %{ 11884 __ cmpl(r12, $mem$$Address); 11885 %} 11886 ins_pipe(ialu_cr_reg_mem); 11887 %} 11888 11889 // Yanked all unsigned pointer compare operations. 11890 // Pointer compares are done with CmpP which is already unsigned. 11891 11892 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11893 %{ 11894 match(Set cr (CmpL op1 op2)); 11895 11896 format %{ "cmpq $op1, $op2" %} 11897 opcode(0x3B); /* Opcode 3B /r */ 11898 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11899 ins_pipe(ialu_cr_reg_reg); 11900 %} 11901 11902 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11903 %{ 11904 match(Set cr (CmpL op1 op2)); 11905 11906 format %{ "cmpq $op1, $op2" %} 11907 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11908 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11909 ins_pipe(ialu_cr_reg_imm); 11910 %} 11911 11912 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11913 %{ 11914 match(Set cr (CmpL op1 (LoadL op2))); 11915 11916 format %{ "cmpq $op1, $op2" %} 11917 opcode(0x3B); /* Opcode 3B /r */ 11918 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11919 ins_pipe(ialu_cr_reg_mem); 11920 %} 11921 11922 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11923 %{ 11924 match(Set cr (CmpL src zero)); 11925 11926 format %{ "testq $src, $src" %} 11927 opcode(0x85); 11928 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11929 ins_pipe(ialu_cr_reg_imm); 11930 %} 11931 11932 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11933 %{ 11934 match(Set cr (CmpL (AndL src con) zero)); 11935 11936 format %{ "testq $src, $con\t# long" %} 11937 opcode(0xF7, 0x00); 11938 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11939 ins_pipe(ialu_cr_reg_imm); 11940 %} 11941 11942 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11943 %{ 11944 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11945 11946 format %{ "testq $src, $mem" %} 11947 opcode(0x85); 11948 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11949 ins_pipe(ialu_cr_reg_mem); 11950 %} 11951 11952 // Manifest a CmpL result in an integer register. Very painful. 11953 // This is the test to avoid. 11954 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11955 %{ 11956 match(Set dst (CmpL3 src1 src2)); 11957 effect(KILL flags); 11958 11959 ins_cost(275); // XXX 11960 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11961 "movl $dst, -1\n\t" 11962 "jl,s done\n\t" 11963 "setne $dst\n\t" 11964 "movzbl $dst, $dst\n\t" 11965 "done:" %} 11966 ins_encode(cmpl3_flag(src1, src2, dst)); 11967 ins_pipe(pipe_slow); 11968 %} 11969 11970 //----------Max and Min-------------------------------------------------------- 11971 // Min Instructions 11972 11973 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11974 %{ 11975 effect(USE_DEF dst, USE src, USE cr); 11976 11977 format %{ "cmovlgt $dst, $src\t# min" %} 11978 opcode(0x0F, 0x4F); 11979 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11980 ins_pipe(pipe_cmov_reg); 11981 %} 11982 11983 11984 instruct minI_rReg(rRegI dst, rRegI src) 11985 %{ 11986 match(Set dst (MinI dst src)); 11987 11988 ins_cost(200); 11989 expand %{ 11990 rFlagsReg cr; 11991 compI_rReg(cr, dst, src); 11992 cmovI_reg_g(dst, src, cr); 11993 %} 11994 %} 11995 11996 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11997 %{ 11998 effect(USE_DEF dst, USE src, USE cr); 11999 12000 format %{ "cmovllt $dst, $src\t# max" %} 12001 opcode(0x0F, 0x4C); 12002 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12003 ins_pipe(pipe_cmov_reg); 12004 %} 12005 12006 12007 instruct maxI_rReg(rRegI dst, rRegI src) 12008 %{ 12009 match(Set dst (MaxI dst src)); 12010 12011 ins_cost(200); 12012 expand %{ 12013 rFlagsReg cr; 12014 compI_rReg(cr, dst, src); 12015 cmovI_reg_l(dst, src, cr); 12016 %} 12017 %} 12018 12019 // ============================================================================ 12020 // Branch Instructions 12021 12022 // Jump Direct - Label defines a relative address from JMP+1 12023 instruct jmpDir(label labl) 12024 %{ 12025 match(Goto); 12026 effect(USE labl); 12027 12028 ins_cost(300); 12029 format %{ "jmp $labl" %} 12030 size(5); 12031 ins_encode %{ 12032 Label* L = $labl$$label; 12033 __ jmp(*L, false); // Always long jump 12034 %} 12035 ins_pipe(pipe_jmp); 12036 %} 12037 12038 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12039 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12040 %{ 12041 match(If cop cr); 12042 effect(USE labl); 12043 12044 ins_cost(300); 12045 format %{ "j$cop $labl" %} 12046 size(6); 12047 ins_encode %{ 12048 Label* L = $labl$$label; 12049 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12050 %} 12051 ins_pipe(pipe_jcc); 12052 %} 12053 12054 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12055 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12056 %{ 12057 match(CountedLoopEnd cop cr); 12058 effect(USE labl); 12059 12060 ins_cost(300); 12061 format %{ "j$cop $labl\t# loop end" %} 12062 size(6); 12063 ins_encode %{ 12064 Label* L = $labl$$label; 12065 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12066 %} 12067 ins_pipe(pipe_jcc); 12068 %} 12069 12070 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12071 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12072 match(CountedLoopEnd cop cmp); 12073 effect(USE labl); 12074 12075 ins_cost(300); 12076 format %{ "j$cop,u $labl\t# loop end" %} 12077 size(6); 12078 ins_encode %{ 12079 Label* L = $labl$$label; 12080 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12081 %} 12082 ins_pipe(pipe_jcc); 12083 %} 12084 12085 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12086 match(CountedLoopEnd cop cmp); 12087 effect(USE labl); 12088 12089 ins_cost(200); 12090 format %{ "j$cop,u $labl\t# loop end" %} 12091 size(6); 12092 ins_encode %{ 12093 Label* L = $labl$$label; 12094 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12095 %} 12096 ins_pipe(pipe_jcc); 12097 %} 12098 12099 // Jump Direct Conditional - using unsigned comparison 12100 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12101 match(If cop cmp); 12102 effect(USE labl); 12103 12104 ins_cost(300); 12105 format %{ "j$cop,u $labl" %} 12106 size(6); 12107 ins_encode %{ 12108 Label* L = $labl$$label; 12109 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12110 %} 12111 ins_pipe(pipe_jcc); 12112 %} 12113 12114 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12115 match(If cop cmp); 12116 effect(USE labl); 12117 12118 ins_cost(200); 12119 format %{ "j$cop,u $labl" %} 12120 size(6); 12121 ins_encode %{ 12122 Label* L = $labl$$label; 12123 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12124 %} 12125 ins_pipe(pipe_jcc); 12126 %} 12127 12128 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12129 match(If cop cmp); 12130 effect(USE labl); 12131 12132 ins_cost(200); 12133 format %{ $$template 12134 if ($cop$$cmpcode == Assembler::notEqual) { 12135 $$emit$$"jp,u $labl\n\t" 12136 $$emit$$"j$cop,u $labl" 12137 } else { 12138 $$emit$$"jp,u done\n\t" 12139 $$emit$$"j$cop,u $labl\n\t" 12140 $$emit$$"done:" 12141 } 12142 %} 12143 ins_encode %{ 12144 Label* l = $labl$$label; 12145 if ($cop$$cmpcode == Assembler::notEqual) { 12146 __ jcc(Assembler::parity, *l, false); 12147 __ jcc(Assembler::notEqual, *l, false); 12148 } else if ($cop$$cmpcode == Assembler::equal) { 12149 Label done; 12150 __ jccb(Assembler::parity, done); 12151 __ jcc(Assembler::equal, *l, false); 12152 __ bind(done); 12153 } else { 12154 ShouldNotReachHere(); 12155 } 12156 %} 12157 ins_pipe(pipe_jcc); 12158 %} 12159 12160 // ============================================================================ 12161 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12162 // superklass array for an instance of the superklass. Set a hidden 12163 // internal cache on a hit (cache is checked with exposed code in 12164 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12165 // encoding ALSO sets flags. 12166 12167 instruct partialSubtypeCheck(rdi_RegP result, 12168 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12169 rFlagsReg cr) 12170 %{ 12171 match(Set result (PartialSubtypeCheck sub super)); 12172 effect(KILL rcx, KILL cr); 12173 12174 ins_cost(1100); // slightly larger than the next version 12175 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" 12176 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 12177 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 12178 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12179 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12180 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" 12181 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12182 "miss:\t" %} 12183 12184 opcode(0x1); // Force a XOR of RDI 12185 ins_encode(enc_PartialSubtypeCheck()); 12186 ins_pipe(pipe_slow); 12187 %} 12188 12189 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12190 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12191 immP0 zero, 12192 rdi_RegP result) 12193 %{ 12194 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12195 effect(KILL rcx, KILL result); 12196 12197 ins_cost(1000); 12198 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" 12199 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 12200 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 12201 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12202 "jne,s miss\t\t# Missed: flags nz\n\t" 12203 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" 12204 "miss:\t" %} 12205 12206 opcode(0x0); // No need to XOR RDI 12207 ins_encode(enc_PartialSubtypeCheck()); 12208 ins_pipe(pipe_slow); 12209 %} 12210 12211 // ============================================================================ 12212 // Branch Instructions -- short offset versions 12213 // 12214 // These instructions are used to replace jumps of a long offset (the default 12215 // match) with jumps of a shorter offset. These instructions are all tagged 12216 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12217 // match rules in general matching. Instead, the ADLC generates a conversion 12218 // method in the MachNode which can be used to do in-place replacement of the 12219 // long variant with the shorter variant. The compiler will determine if a 12220 // branch can be taken by the is_short_branch_offset() predicate in the machine 12221 // specific code section of the file. 12222 12223 // Jump Direct - Label defines a relative address from JMP+1 12224 instruct jmpDir_short(label labl) %{ 12225 match(Goto); 12226 effect(USE labl); 12227 12228 ins_cost(300); 12229 format %{ "jmp,s $labl" %} 12230 size(2); 12231 ins_encode %{ 12232 Label* L = $labl$$label; 12233 __ jmpb(*L); 12234 %} 12235 ins_pipe(pipe_jmp); 12236 ins_short_branch(1); 12237 %} 12238 12239 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12240 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12241 match(If cop cr); 12242 effect(USE labl); 12243 12244 ins_cost(300); 12245 format %{ "j$cop,s $labl" %} 12246 size(2); 12247 ins_encode %{ 12248 Label* L = $labl$$label; 12249 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12250 %} 12251 ins_pipe(pipe_jcc); 12252 ins_short_branch(1); 12253 %} 12254 12255 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12256 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12257 match(CountedLoopEnd cop cr); 12258 effect(USE labl); 12259 12260 ins_cost(300); 12261 format %{ "j$cop,s $labl\t# loop end" %} 12262 size(2); 12263 ins_encode %{ 12264 Label* L = $labl$$label; 12265 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12266 %} 12267 ins_pipe(pipe_jcc); 12268 ins_short_branch(1); 12269 %} 12270 12271 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12272 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12273 match(CountedLoopEnd cop cmp); 12274 effect(USE labl); 12275 12276 ins_cost(300); 12277 format %{ "j$cop,us $labl\t# loop end" %} 12278 size(2); 12279 ins_encode %{ 12280 Label* L = $labl$$label; 12281 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12282 %} 12283 ins_pipe(pipe_jcc); 12284 ins_short_branch(1); 12285 %} 12286 12287 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12288 match(CountedLoopEnd cop cmp); 12289 effect(USE labl); 12290 12291 ins_cost(300); 12292 format %{ "j$cop,us $labl\t# loop end" %} 12293 size(2); 12294 ins_encode %{ 12295 Label* L = $labl$$label; 12296 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12297 %} 12298 ins_pipe(pipe_jcc); 12299 ins_short_branch(1); 12300 %} 12301 12302 // Jump Direct Conditional - using unsigned comparison 12303 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12304 match(If cop cmp); 12305 effect(USE labl); 12306 12307 ins_cost(300); 12308 format %{ "j$cop,us $labl" %} 12309 size(2); 12310 ins_encode %{ 12311 Label* L = $labl$$label; 12312 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12313 %} 12314 ins_pipe(pipe_jcc); 12315 ins_short_branch(1); 12316 %} 12317 12318 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12319 match(If cop cmp); 12320 effect(USE labl); 12321 12322 ins_cost(300); 12323 format %{ "j$cop,us $labl" %} 12324 size(2); 12325 ins_encode %{ 12326 Label* L = $labl$$label; 12327 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12328 %} 12329 ins_pipe(pipe_jcc); 12330 ins_short_branch(1); 12331 %} 12332 12333 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12334 match(If cop cmp); 12335 effect(USE labl); 12336 12337 ins_cost(300); 12338 format %{ $$template 12339 if ($cop$$cmpcode == Assembler::notEqual) { 12340 $$emit$$"jp,u,s $labl\n\t" 12341 $$emit$$"j$cop,u,s $labl" 12342 } else { 12343 $$emit$$"jp,u,s done\n\t" 12344 $$emit$$"j$cop,u,s $labl\n\t" 12345 $$emit$$"done:" 12346 } 12347 %} 12348 size(4); 12349 ins_encode %{ 12350 Label* l = $labl$$label; 12351 if ($cop$$cmpcode == Assembler::notEqual) { 12352 __ jccb(Assembler::parity, *l); 12353 __ jccb(Assembler::notEqual, *l); 12354 } else if ($cop$$cmpcode == Assembler::equal) { 12355 Label done; 12356 __ jccb(Assembler::parity, done); 12357 __ jccb(Assembler::equal, *l); 12358 __ bind(done); 12359 } else { 12360 ShouldNotReachHere(); 12361 } 12362 %} 12363 ins_pipe(pipe_jcc); 12364 ins_short_branch(1); 12365 %} 12366 12367 // ============================================================================ 12368 // inlined locking and unlocking 12369 12370 instruct cmpFastLock(rFlagsReg cr, 12371 rRegP object, rRegP box, rax_RegI tmp, rRegP scr) 12372 %{ 12373 match(Set cr (FastLock object box)); 12374 effect(TEMP tmp, TEMP scr); 12375 12376 ins_cost(300); 12377 format %{ "fastlock $object,$box,$tmp,$scr" %} 12378 ins_encode(Fast_Lock(object, box, tmp, scr)); 12379 ins_pipe(pipe_slow); 12380 %} 12381 12382 instruct cmpFastUnlock(rFlagsReg cr, 12383 rRegP object, rax_RegP box, rRegP tmp) 12384 %{ 12385 match(Set cr (FastUnlock object box)); 12386 effect(TEMP tmp); 12387 12388 ins_cost(300); 12389 format %{ "fastunlock $object, $box, $tmp" %} 12390 ins_encode(Fast_Unlock(object, box, tmp)); 12391 ins_pipe(pipe_slow); 12392 %} 12393 12394 12395 // ============================================================================ 12396 // Safepoint Instructions 12397 instruct safePoint_poll(rFlagsReg cr) 12398 %{ 12399 predicate(!Assembler::is_polling_page_far()); 12400 match(SafePoint); 12401 effect(KILL cr); 12402 12403 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12404 "# Safepoint: poll for GC" %} 12405 ins_cost(125); 12406 ins_encode %{ 12407 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12408 __ testl(rax, addr); 12409 %} 12410 ins_pipe(ialu_reg_mem); 12411 %} 12412 12413 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12414 %{ 12415 predicate(Assembler::is_polling_page_far()); 12416 match(SafePoint poll); 12417 effect(KILL cr, USE poll); 12418 12419 format %{ "testl rax, [$poll]\t" 12420 "# Safepoint: poll for GC" %} 12421 ins_cost(125); 12422 ins_encode %{ 12423 __ relocate(relocInfo::poll_type); 12424 __ testl(rax, Address($poll$$Register, 0)); 12425 %} 12426 ins_pipe(ialu_reg_mem); 12427 %} 12428 12429 // ============================================================================ 12430 // Procedure Call/Return Instructions 12431 // Call Java Static Instruction 12432 // Note: If this code changes, the corresponding ret_addr_offset() and 12433 // compute_padding() functions will have to be adjusted. 12434 instruct CallStaticJavaDirect(method meth) %{ 12435 match(CallStaticJava); 12436 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); 12437 effect(USE meth); 12438 12439 ins_cost(300); 12440 format %{ "call,static " %} 12441 opcode(0xE8); /* E8 cd */ 12442 ins_encode(Java_Static_Call(meth), call_epilog); 12443 ins_pipe(pipe_slow); 12444 ins_alignment(4); 12445 %} 12446 12447 // Call Java Static Instruction (method handle version) 12448 // Note: If this code changes, the corresponding ret_addr_offset() and 12449 // compute_padding() functions will have to be adjusted. 12450 instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{ 12451 match(CallStaticJava); 12452 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); 12453 effect(USE meth); 12454 // RBP is saved by all callees (for interpreter stack correction). 12455 // We use it here for a similar purpose, in {preserve,restore}_SP. 12456 12457 ins_cost(300); 12458 format %{ "call,static/MethodHandle " %} 12459 opcode(0xE8); /* E8 cd */ 12460 ins_encode(preserve_SP, 12461 Java_Static_Call(meth), 12462 restore_SP, 12463 call_epilog); 12464 ins_pipe(pipe_slow); 12465 ins_alignment(4); 12466 %} 12467 12468 // Call Java Dynamic Instruction 12469 // Note: If this code changes, the corresponding ret_addr_offset() and 12470 // compute_padding() functions will have to be adjusted. 12471 instruct CallDynamicJavaDirect(method meth) 12472 %{ 12473 match(CallDynamicJava); 12474 effect(USE meth); 12475 12476 ins_cost(300); 12477 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12478 "call,dynamic " %} 12479 opcode(0xE8); /* E8 cd */ 12480 ins_encode(Java_Dynamic_Call(meth), call_epilog); 12481 ins_pipe(pipe_slow); 12482 ins_alignment(4); 12483 %} 12484 12485 // Call Runtime Instruction 12486 instruct CallRuntimeDirect(method meth) 12487 %{ 12488 match(CallRuntime); 12489 effect(USE meth); 12490 12491 ins_cost(300); 12492 format %{ "call,runtime " %} 12493 opcode(0xE8); /* E8 cd */ 12494 ins_encode(Java_To_Runtime(meth)); 12495 ins_pipe(pipe_slow); 12496 %} 12497 12498 // Call runtime without safepoint 12499 instruct CallLeafDirect(method meth) 12500 %{ 12501 match(CallLeaf); 12502 effect(USE meth); 12503 12504 ins_cost(300); 12505 format %{ "call_leaf,runtime " %} 12506 opcode(0xE8); /* E8 cd */ 12507 ins_encode(Java_To_Runtime(meth)); 12508 ins_pipe(pipe_slow); 12509 %} 12510 12511 // Call runtime without safepoint 12512 instruct CallLeafNoFPDirect(method meth) 12513 %{ 12514 match(CallLeafNoFP); 12515 effect(USE meth); 12516 12517 ins_cost(300); 12518 format %{ "call_leaf_nofp,runtime " %} 12519 opcode(0xE8); /* E8 cd */ 12520 ins_encode(Java_To_Runtime(meth)); 12521 ins_pipe(pipe_slow); 12522 %} 12523 12524 // Return Instruction 12525 // Remove the return address & jump to it. 12526 // Notice: We always emit a nop after a ret to make sure there is room 12527 // for safepoint patching 12528 instruct Ret() 12529 %{ 12530 match(Return); 12531 12532 format %{ "ret" %} 12533 opcode(0xC3); 12534 ins_encode(OpcP); 12535 ins_pipe(pipe_jmp); 12536 %} 12537 12538 // Tail Call; Jump from runtime stub to Java code. 12539 // Also known as an 'interprocedural jump'. 12540 // Target of jump will eventually return to caller. 12541 // TailJump below removes the return address. 12542 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12543 %{ 12544 match(TailCall jump_target method_oop); 12545 12546 ins_cost(300); 12547 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12548 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12549 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12550 ins_pipe(pipe_jmp); 12551 %} 12552 12553 // Tail Jump; remove the return address; jump to target. 12554 // TailCall above leaves the return address around. 12555 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12556 %{ 12557 match(TailJump jump_target ex_oop); 12558 12559 ins_cost(300); 12560 format %{ "popq rdx\t# pop return address\n\t" 12561 "jmp $jump_target" %} 12562 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12563 ins_encode(Opcode(0x5a), // popq rdx 12564 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12565 ins_pipe(pipe_jmp); 12566 %} 12567 12568 // Create exception oop: created by stack-crawling runtime code. 12569 // Created exception is now available to this handler, and is setup 12570 // just prior to jumping to this handler. No code emitted. 12571 instruct CreateException(rax_RegP ex_oop) 12572 %{ 12573 match(Set ex_oop (CreateEx)); 12574 12575 size(0); 12576 // use the following format syntax 12577 format %{ "# exception oop is in rax; no code emitted" %} 12578 ins_encode(); 12579 ins_pipe(empty); 12580 %} 12581 12582 // Rethrow exception: 12583 // The exception oop will come in the first argument position. 12584 // Then JUMP (not call) to the rethrow stub code. 12585 instruct RethrowException() 12586 %{ 12587 match(Rethrow); 12588 12589 // use the following format syntax 12590 format %{ "jmp rethrow_stub" %} 12591 ins_encode(enc_rethrow); 12592 ins_pipe(pipe_jmp); 12593 %} 12594 12595 12596 //----------PEEPHOLE RULES----------------------------------------------------- 12597 // These must follow all instruction definitions as they use the names 12598 // defined in the instructions definitions. 12599 // 12600 // peepmatch ( root_instr_name [preceding_instruction]* ); 12601 // 12602 // peepconstraint %{ 12603 // (instruction_number.operand_name relational_op instruction_number.operand_name 12604 // [, ...] ); 12605 // // instruction numbers are zero-based using left to right order in peepmatch 12606 // 12607 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12608 // // provide an instruction_number.operand_name for each operand that appears 12609 // // in the replacement instruction's match rule 12610 // 12611 // ---------VM FLAGS--------------------------------------------------------- 12612 // 12613 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12614 // 12615 // Each peephole rule is given an identifying number starting with zero and 12616 // increasing by one in the order seen by the parser. An individual peephole 12617 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12618 // on the command-line. 12619 // 12620 // ---------CURRENT LIMITATIONS---------------------------------------------- 12621 // 12622 // Only match adjacent instructions in same basic block 12623 // Only equality constraints 12624 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12625 // Only one replacement instruction 12626 // 12627 // ---------EXAMPLE---------------------------------------------------------- 12628 // 12629 // // pertinent parts of existing instructions in architecture description 12630 // instruct movI(rRegI dst, rRegI src) 12631 // %{ 12632 // match(Set dst (CopyI src)); 12633 // %} 12634 // 12635 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12636 // %{ 12637 // match(Set dst (AddI dst src)); 12638 // effect(KILL cr); 12639 // %} 12640 // 12641 // // Change (inc mov) to lea 12642 // peephole %{ 12643 // // increment preceeded by register-register move 12644 // peepmatch ( incI_rReg movI ); 12645 // // require that the destination register of the increment 12646 // // match the destination register of the move 12647 // peepconstraint ( 0.dst == 1.dst ); 12648 // // construct a replacement instruction that sets 12649 // // the destination to ( move's source register + one ) 12650 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12651 // %} 12652 // 12653 12654 // Implementation no longer uses movX instructions since 12655 // machine-independent system no longer uses CopyX nodes. 12656 // 12657 // peephole 12658 // %{ 12659 // peepmatch (incI_rReg movI); 12660 // peepconstraint (0.dst == 1.dst); 12661 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12662 // %} 12663 12664 // peephole 12665 // %{ 12666 // peepmatch (decI_rReg movI); 12667 // peepconstraint (0.dst == 1.dst); 12668 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12669 // %} 12670 12671 // peephole 12672 // %{ 12673 // peepmatch (addI_rReg_imm movI); 12674 // peepconstraint (0.dst == 1.dst); 12675 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12676 // %} 12677 12678 // peephole 12679 // %{ 12680 // peepmatch (incL_rReg movL); 12681 // peepconstraint (0.dst == 1.dst); 12682 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12683 // %} 12684 12685 // peephole 12686 // %{ 12687 // peepmatch (decL_rReg movL); 12688 // peepconstraint (0.dst == 1.dst); 12689 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12690 // %} 12691 12692 // peephole 12693 // %{ 12694 // peepmatch (addL_rReg_imm movL); 12695 // peepconstraint (0.dst == 1.dst); 12696 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12697 // %} 12698 12699 // peephole 12700 // %{ 12701 // peepmatch (addP_rReg_imm movP); 12702 // peepconstraint (0.dst == 1.dst); 12703 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12704 // %} 12705 12706 // // Change load of spilled value to only a spill 12707 // instruct storeI(memory mem, rRegI src) 12708 // %{ 12709 // match(Set mem (StoreI mem src)); 12710 // %} 12711 // 12712 // instruct loadI(rRegI dst, memory mem) 12713 // %{ 12714 // match(Set dst (LoadI mem)); 12715 // %} 12716 // 12717 12718 peephole 12719 %{ 12720 peepmatch (loadI storeI); 12721 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12722 peepreplace (storeI(1.mem 1.mem 1.src)); 12723 %} 12724 12725 peephole 12726 %{ 12727 peepmatch (loadL storeL); 12728 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12729 peepreplace (storeL(1.mem 1.mem 1.src)); 12730 %} 12731 12732 //----------SMARTSPILL RULES--------------------------------------------------- 12733 // These must follow all instruction definitions as they use the names 12734 // defined in the instructions definitions.