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 834 //============================================================================= 835 const bool Matcher::constant_table_absolute_addressing = true; 836 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 837 838 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 839 // Empty encoding 840 } 841 842 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 843 return 0; 844 } 845 846 #ifndef PRODUCT 847 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 848 st->print("# MachConstantBaseNode (empty encoding)"); 849 } 850 #endif 851 852 853 //============================================================================= 854 #ifndef PRODUCT 855 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const 856 { 857 Compile* C = ra_->C; 858 859 int framesize = C->frame_slots() << LogBytesPerInt; 860 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 861 // Remove wordSize for return adr already pushed 862 // and another for the RBP we are going to save 863 framesize -= 2*wordSize; 864 bool need_nop = true; 865 866 // Calls to C2R adapters often do not accept exceptional returns. 867 // We require that their callers must bang for them. But be 868 // careful, because some VM calls (such as call site linkage) can 869 // use several kilobytes of stack. But the stack safety zone should 870 // account for that. See bugs 4446381, 4468289, 4497237. 871 if (C->need_stack_bang(framesize)) { 872 st->print_cr("# stack bang"); st->print("\t"); 873 need_nop = false; 874 } 875 st->print_cr("pushq rbp"); st->print("\t"); 876 877 if (VerifyStackAtCalls) { 878 // Majik cookie to verify stack depth 879 st->print_cr("pushq 0xffffffffbadb100d" 880 "\t# Majik cookie for stack depth check"); 881 st->print("\t"); 882 framesize -= wordSize; // Remove 2 for cookie 883 need_nop = false; 884 } 885 886 if (framesize) { 887 st->print("subq rsp, #%d\t# Create frame", framesize); 888 if (framesize < 0x80 && need_nop) { 889 st->print("\n\tnop\t# nop for patch_verified_entry"); 890 } 891 } 892 } 893 #endif 894 895 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const 896 { 897 Compile* C = ra_->C; 898 899 // WARNING: Initial instruction MUST be 5 bytes or longer so that 900 // NativeJump::patch_verified_entry will be able to patch out the entry 901 // code safely. The fldcw is ok at 6 bytes, the push to verify stack 902 // depth is ok at 5 bytes, the frame allocation can be either 3 or 903 // 6 bytes. So if we don't do the fldcw or the push then we must 904 // use the 6 byte frame allocation even if we have no frame. :-( 905 // If method sets FPU control word do it now 906 907 int framesize = C->frame_slots() << LogBytesPerInt; 908 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 909 // Remove wordSize for return adr already pushed 910 // and another for the RBP we are going to save 911 framesize -= 2*wordSize; 912 bool need_nop = true; 913 914 // Calls to C2R adapters often do not accept exceptional returns. 915 // We require that their callers must bang for them. But be 916 // careful, because some VM calls (such as call site linkage) can 917 // use several kilobytes of stack. But the stack safety zone should 918 // account for that. See bugs 4446381, 4468289, 4497237. 919 if (C->need_stack_bang(framesize)) { 920 MacroAssembler masm(&cbuf); 921 masm.generate_stack_overflow_check(framesize); 922 need_nop = false; 923 } 924 925 // We always push rbp so that on return to interpreter rbp will be 926 // restored correctly and we can correct the stack. 927 emit_opcode(cbuf, 0x50 | RBP_enc); 928 929 if (VerifyStackAtCalls) { 930 // Majik cookie to verify stack depth 931 emit_opcode(cbuf, 0x68); // pushq (sign-extended) 0xbadb100d 932 emit_d32(cbuf, 0xbadb100d); 933 framesize -= wordSize; // Remove 2 for cookie 934 need_nop = false; 935 } 936 937 if (framesize) { 938 emit_opcode(cbuf, Assembler::REX_W); 939 if (framesize < 0x80) { 940 emit_opcode(cbuf, 0x83); // sub SP,#framesize 941 emit_rm(cbuf, 0x3, 0x05, RSP_enc); 942 emit_d8(cbuf, framesize); 943 if (need_nop) { 944 emit_opcode(cbuf, 0x90); // nop 945 } 946 } else { 947 emit_opcode(cbuf, 0x81); // sub SP,#framesize 948 emit_rm(cbuf, 0x3, 0x05, RSP_enc); 949 emit_d32(cbuf, framesize); 950 } 951 } 952 953 C->set_frame_complete(cbuf.insts_size()); 954 955 #ifdef ASSERT 956 if (VerifyStackAtCalls) { 957 Label L; 958 MacroAssembler masm(&cbuf); 959 masm.push(rax); 960 masm.mov(rax, rsp); 961 masm.andptr(rax, StackAlignmentInBytes-1); 962 masm.cmpptr(rax, StackAlignmentInBytes-wordSize); 963 masm.pop(rax); 964 masm.jcc(Assembler::equal, L); 965 masm.stop("Stack is not properly aligned!"); 966 masm.bind(L); 967 } 968 #endif 969 } 970 971 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 972 { 973 return MachNode::size(ra_); // too many variables; just compute it 974 // the hard way 975 } 976 977 int MachPrologNode::reloc() const 978 { 979 return 0; // a large enough number 980 } 981 982 //============================================================================= 983 #ifndef PRODUCT 984 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 985 { 986 Compile* C = ra_->C; 987 int framesize = C->frame_slots() << LogBytesPerInt; 988 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 989 // Remove word for return adr already pushed 990 // and RBP 991 framesize -= 2*wordSize; 992 993 if (framesize) { 994 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 995 st->print("\t"); 996 } 997 998 st->print_cr("popq rbp"); 999 if (do_polling() && C->is_method_compilation()) { 1000 st->print("\t"); 1001 if (Assembler::is_polling_page_far()) { 1002 st->print_cr("movq rscratch1, #polling_page_address\n\t" 1003 "testl rax, [rscratch1]\t" 1004 "# Safepoint: poll for GC"); 1005 } else { 1006 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 1007 "# Safepoint: poll for GC"); 1008 } 1009 } 1010 } 1011 #endif 1012 1013 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1014 { 1015 Compile* C = ra_->C; 1016 int framesize = C->frame_slots() << LogBytesPerInt; 1017 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 1018 // Remove word for return adr already pushed 1019 // and RBP 1020 framesize -= 2*wordSize; 1021 1022 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 1023 1024 if (framesize) { 1025 emit_opcode(cbuf, Assembler::REX_W); 1026 if (framesize < 0x80) { 1027 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 1028 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1029 emit_d8(cbuf, framesize); 1030 } else { 1031 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 1032 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1033 emit_d32(cbuf, framesize); 1034 } 1035 } 1036 1037 // popq rbp 1038 emit_opcode(cbuf, 0x58 | RBP_enc); 1039 1040 if (do_polling() && C->is_method_compilation()) { 1041 MacroAssembler _masm(&cbuf); 1042 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1043 if (Assembler::is_polling_page_far()) { 1044 __ lea(rscratch1, polling_page); 1045 __ relocate(relocInfo::poll_return_type); 1046 __ testl(rax, Address(rscratch1, 0)); 1047 } else { 1048 __ testl(rax, polling_page); 1049 } 1050 } 1051 } 1052 1053 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1054 { 1055 return MachNode::size(ra_); // too many variables; just compute it 1056 // the hard way 1057 } 1058 1059 int MachEpilogNode::reloc() const 1060 { 1061 return 2; // a large enough number 1062 } 1063 1064 const Pipeline* MachEpilogNode::pipeline() const 1065 { 1066 return MachNode::pipeline_class(); 1067 } 1068 1069 int MachEpilogNode::safepoint_offset() const 1070 { 1071 return 0; 1072 } 1073 1074 //============================================================================= 1075 1076 enum RC { 1077 rc_bad, 1078 rc_int, 1079 rc_float, 1080 rc_stack 1081 }; 1082 1083 static enum RC rc_class(OptoReg::Name reg) 1084 { 1085 if( !OptoReg::is_valid(reg) ) return rc_bad; 1086 1087 if (OptoReg::is_stack(reg)) return rc_stack; 1088 1089 VMReg r = OptoReg::as_VMReg(reg); 1090 1091 if (r->is_Register()) return rc_int; 1092 1093 assert(r->is_XMMRegister(), "must be"); 1094 return rc_float; 1095 } 1096 1097 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1098 PhaseRegAlloc* ra_, 1099 bool do_size, 1100 outputStream* st) const 1101 { 1102 1103 // Get registers to move 1104 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1105 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1106 OptoReg::Name dst_second = ra_->get_reg_second(this); 1107 OptoReg::Name dst_first = ra_->get_reg_first(this); 1108 1109 enum RC src_second_rc = rc_class(src_second); 1110 enum RC src_first_rc = rc_class(src_first); 1111 enum RC dst_second_rc = rc_class(dst_second); 1112 enum RC dst_first_rc = rc_class(dst_first); 1113 1114 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1115 "must move at least 1 register" ); 1116 1117 if (src_first == dst_first && src_second == dst_second) { 1118 // Self copy, no move 1119 return 0; 1120 } else if (src_first_rc == rc_stack) { 1121 // mem -> 1122 if (dst_first_rc == rc_stack) { 1123 // mem -> mem 1124 assert(src_second != dst_first, "overlap"); 1125 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1126 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1127 // 64-bit 1128 int src_offset = ra_->reg2offset(src_first); 1129 int dst_offset = ra_->reg2offset(dst_first); 1130 if (cbuf) { 1131 emit_opcode(*cbuf, 0xFF); 1132 encode_RegMem(*cbuf, RSI_enc, RSP_enc, 0x4, 0, src_offset, false); 1133 1134 emit_opcode(*cbuf, 0x8F); 1135 encode_RegMem(*cbuf, RAX_enc, RSP_enc, 0x4, 0, dst_offset, false); 1136 1137 #ifndef PRODUCT 1138 } else if (!do_size) { 1139 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1140 "popq [rsp + #%d]", 1141 src_offset, 1142 dst_offset); 1143 #endif 1144 } 1145 return 1146 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + 1147 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)); 1148 } else { 1149 // 32-bit 1150 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1151 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1152 // No pushl/popl, so: 1153 int src_offset = ra_->reg2offset(src_first); 1154 int dst_offset = ra_->reg2offset(dst_first); 1155 if (cbuf) { 1156 emit_opcode(*cbuf, Assembler::REX_W); 1157 emit_opcode(*cbuf, 0x89); 1158 emit_opcode(*cbuf, 0x44); 1159 emit_opcode(*cbuf, 0x24); 1160 emit_opcode(*cbuf, 0xF8); 1161 1162 emit_opcode(*cbuf, 0x8B); 1163 encode_RegMem(*cbuf, 1164 RAX_enc, 1165 RSP_enc, 0x4, 0, src_offset, 1166 false); 1167 1168 emit_opcode(*cbuf, 0x89); 1169 encode_RegMem(*cbuf, 1170 RAX_enc, 1171 RSP_enc, 0x4, 0, dst_offset, 1172 false); 1173 1174 emit_opcode(*cbuf, Assembler::REX_W); 1175 emit_opcode(*cbuf, 0x8B); 1176 emit_opcode(*cbuf, 0x44); 1177 emit_opcode(*cbuf, 0x24); 1178 emit_opcode(*cbuf, 0xF8); 1179 1180 #ifndef PRODUCT 1181 } else if (!do_size) { 1182 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1183 "movl rax, [rsp + #%d]\n\t" 1184 "movl [rsp + #%d], rax\n\t" 1185 "movq rax, [rsp - #8]", 1186 src_offset, 1187 dst_offset); 1188 #endif 1189 } 1190 return 1191 5 + // movq 1192 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + // movl 1193 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)) + // movl 1194 5; // movq 1195 } 1196 } else if (dst_first_rc == rc_int) { 1197 // mem -> gpr 1198 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1199 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1200 // 64-bit 1201 int offset = ra_->reg2offset(src_first); 1202 if (cbuf) { 1203 if (Matcher::_regEncode[dst_first] < 8) { 1204 emit_opcode(*cbuf, Assembler::REX_W); 1205 } else { 1206 emit_opcode(*cbuf, Assembler::REX_WR); 1207 } 1208 emit_opcode(*cbuf, 0x8B); 1209 encode_RegMem(*cbuf, 1210 Matcher::_regEncode[dst_first], 1211 RSP_enc, 0x4, 0, offset, 1212 false); 1213 #ifndef PRODUCT 1214 } else if (!do_size) { 1215 st->print("movq %s, [rsp + #%d]\t# spill", 1216 Matcher::regName[dst_first], 1217 offset); 1218 #endif 1219 } 1220 return 1221 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX 1222 } else { 1223 // 32-bit 1224 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1225 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1226 int offset = ra_->reg2offset(src_first); 1227 if (cbuf) { 1228 if (Matcher::_regEncode[dst_first] >= 8) { 1229 emit_opcode(*cbuf, Assembler::REX_R); 1230 } 1231 emit_opcode(*cbuf, 0x8B); 1232 encode_RegMem(*cbuf, 1233 Matcher::_regEncode[dst_first], 1234 RSP_enc, 0x4, 0, offset, 1235 false); 1236 #ifndef PRODUCT 1237 } else if (!do_size) { 1238 st->print("movl %s, [rsp + #%d]\t# spill", 1239 Matcher::regName[dst_first], 1240 offset); 1241 #endif 1242 } 1243 return 1244 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1245 ((Matcher::_regEncode[dst_first] < 8) 1246 ? 3 1247 : 4); // REX 1248 } 1249 } else if (dst_first_rc == rc_float) { 1250 // mem-> xmm 1251 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1252 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1253 // 64-bit 1254 int offset = ra_->reg2offset(src_first); 1255 if (cbuf) { 1256 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 1257 if (Matcher::_regEncode[dst_first] >= 8) { 1258 emit_opcode(*cbuf, Assembler::REX_R); 1259 } 1260 emit_opcode(*cbuf, 0x0F); 1261 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12); 1262 encode_RegMem(*cbuf, 1263 Matcher::_regEncode[dst_first], 1264 RSP_enc, 0x4, 0, offset, 1265 false); 1266 #ifndef PRODUCT 1267 } else if (!do_size) { 1268 st->print("%s %s, [rsp + #%d]\t# spill", 1269 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1270 Matcher::regName[dst_first], 1271 offset); 1272 #endif 1273 } 1274 return 1275 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1276 ((Matcher::_regEncode[dst_first] < 8) 1277 ? 5 1278 : 6); // REX 1279 } else { 1280 // 32-bit 1281 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1282 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1283 int offset = ra_->reg2offset(src_first); 1284 if (cbuf) { 1285 emit_opcode(*cbuf, 0xF3); 1286 if (Matcher::_regEncode[dst_first] >= 8) { 1287 emit_opcode(*cbuf, Assembler::REX_R); 1288 } 1289 emit_opcode(*cbuf, 0x0F); 1290 emit_opcode(*cbuf, 0x10); 1291 encode_RegMem(*cbuf, 1292 Matcher::_regEncode[dst_first], 1293 RSP_enc, 0x4, 0, offset, 1294 false); 1295 #ifndef PRODUCT 1296 } else if (!do_size) { 1297 st->print("movss %s, [rsp + #%d]\t# spill", 1298 Matcher::regName[dst_first], 1299 offset); 1300 #endif 1301 } 1302 return 1303 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1304 ((Matcher::_regEncode[dst_first] < 8) 1305 ? 5 1306 : 6); // REX 1307 } 1308 } 1309 } else if (src_first_rc == rc_int) { 1310 // gpr -> 1311 if (dst_first_rc == rc_stack) { 1312 // gpr -> mem 1313 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1314 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1315 // 64-bit 1316 int offset = ra_->reg2offset(dst_first); 1317 if (cbuf) { 1318 if (Matcher::_regEncode[src_first] < 8) { 1319 emit_opcode(*cbuf, Assembler::REX_W); 1320 } else { 1321 emit_opcode(*cbuf, Assembler::REX_WR); 1322 } 1323 emit_opcode(*cbuf, 0x89); 1324 encode_RegMem(*cbuf, 1325 Matcher::_regEncode[src_first], 1326 RSP_enc, 0x4, 0, offset, 1327 false); 1328 #ifndef PRODUCT 1329 } else if (!do_size) { 1330 st->print("movq [rsp + #%d], %s\t# spill", 1331 offset, 1332 Matcher::regName[src_first]); 1333 #endif 1334 } 1335 return ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX 1336 } else { 1337 // 32-bit 1338 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1339 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1340 int offset = ra_->reg2offset(dst_first); 1341 if (cbuf) { 1342 if (Matcher::_regEncode[src_first] >= 8) { 1343 emit_opcode(*cbuf, Assembler::REX_R); 1344 } 1345 emit_opcode(*cbuf, 0x89); 1346 encode_RegMem(*cbuf, 1347 Matcher::_regEncode[src_first], 1348 RSP_enc, 0x4, 0, offset, 1349 false); 1350 #ifndef PRODUCT 1351 } else if (!do_size) { 1352 st->print("movl [rsp + #%d], %s\t# spill", 1353 offset, 1354 Matcher::regName[src_first]); 1355 #endif 1356 } 1357 return 1358 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1359 ((Matcher::_regEncode[src_first] < 8) 1360 ? 3 1361 : 4); // REX 1362 } 1363 } else if (dst_first_rc == rc_int) { 1364 // gpr -> gpr 1365 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1366 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1367 // 64-bit 1368 if (cbuf) { 1369 if (Matcher::_regEncode[dst_first] < 8) { 1370 if (Matcher::_regEncode[src_first] < 8) { 1371 emit_opcode(*cbuf, Assembler::REX_W); 1372 } else { 1373 emit_opcode(*cbuf, Assembler::REX_WB); 1374 } 1375 } else { 1376 if (Matcher::_regEncode[src_first] < 8) { 1377 emit_opcode(*cbuf, Assembler::REX_WR); 1378 } else { 1379 emit_opcode(*cbuf, Assembler::REX_WRB); 1380 } 1381 } 1382 emit_opcode(*cbuf, 0x8B); 1383 emit_rm(*cbuf, 0x3, 1384 Matcher::_regEncode[dst_first] & 7, 1385 Matcher::_regEncode[src_first] & 7); 1386 #ifndef PRODUCT 1387 } else if (!do_size) { 1388 st->print("movq %s, %s\t# spill", 1389 Matcher::regName[dst_first], 1390 Matcher::regName[src_first]); 1391 #endif 1392 } 1393 return 3; // REX 1394 } else { 1395 // 32-bit 1396 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1397 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1398 if (cbuf) { 1399 if (Matcher::_regEncode[dst_first] < 8) { 1400 if (Matcher::_regEncode[src_first] >= 8) { 1401 emit_opcode(*cbuf, Assembler::REX_B); 1402 } 1403 } else { 1404 if (Matcher::_regEncode[src_first] < 8) { 1405 emit_opcode(*cbuf, Assembler::REX_R); 1406 } else { 1407 emit_opcode(*cbuf, Assembler::REX_RB); 1408 } 1409 } 1410 emit_opcode(*cbuf, 0x8B); 1411 emit_rm(*cbuf, 0x3, 1412 Matcher::_regEncode[dst_first] & 7, 1413 Matcher::_regEncode[src_first] & 7); 1414 #ifndef PRODUCT 1415 } else if (!do_size) { 1416 st->print("movl %s, %s\t# spill", 1417 Matcher::regName[dst_first], 1418 Matcher::regName[src_first]); 1419 #endif 1420 } 1421 return 1422 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1423 ? 2 1424 : 3; // REX 1425 } 1426 } else if (dst_first_rc == rc_float) { 1427 // gpr -> xmm 1428 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1429 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1430 // 64-bit 1431 if (cbuf) { 1432 emit_opcode(*cbuf, 0x66); 1433 if (Matcher::_regEncode[dst_first] < 8) { 1434 if (Matcher::_regEncode[src_first] < 8) { 1435 emit_opcode(*cbuf, Assembler::REX_W); 1436 } else { 1437 emit_opcode(*cbuf, Assembler::REX_WB); 1438 } 1439 } else { 1440 if (Matcher::_regEncode[src_first] < 8) { 1441 emit_opcode(*cbuf, Assembler::REX_WR); 1442 } else { 1443 emit_opcode(*cbuf, Assembler::REX_WRB); 1444 } 1445 } 1446 emit_opcode(*cbuf, 0x0F); 1447 emit_opcode(*cbuf, 0x6E); 1448 emit_rm(*cbuf, 0x3, 1449 Matcher::_regEncode[dst_first] & 7, 1450 Matcher::_regEncode[src_first] & 7); 1451 #ifndef PRODUCT 1452 } else if (!do_size) { 1453 st->print("movdq %s, %s\t# spill", 1454 Matcher::regName[dst_first], 1455 Matcher::regName[src_first]); 1456 #endif 1457 } 1458 return 5; // REX 1459 } else { 1460 // 32-bit 1461 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1462 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1463 if (cbuf) { 1464 emit_opcode(*cbuf, 0x66); 1465 if (Matcher::_regEncode[dst_first] < 8) { 1466 if (Matcher::_regEncode[src_first] >= 8) { 1467 emit_opcode(*cbuf, Assembler::REX_B); 1468 } 1469 } else { 1470 if (Matcher::_regEncode[src_first] < 8) { 1471 emit_opcode(*cbuf, Assembler::REX_R); 1472 } else { 1473 emit_opcode(*cbuf, Assembler::REX_RB); 1474 } 1475 } 1476 emit_opcode(*cbuf, 0x0F); 1477 emit_opcode(*cbuf, 0x6E); 1478 emit_rm(*cbuf, 0x3, 1479 Matcher::_regEncode[dst_first] & 7, 1480 Matcher::_regEncode[src_first] & 7); 1481 #ifndef PRODUCT 1482 } else if (!do_size) { 1483 st->print("movdl %s, %s\t# spill", 1484 Matcher::regName[dst_first], 1485 Matcher::regName[src_first]); 1486 #endif 1487 } 1488 return 1489 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1490 ? 4 1491 : 5; // REX 1492 } 1493 } 1494 } else if (src_first_rc == rc_float) { 1495 // xmm -> 1496 if (dst_first_rc == rc_stack) { 1497 // xmm -> mem 1498 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1499 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1500 // 64-bit 1501 int offset = ra_->reg2offset(dst_first); 1502 if (cbuf) { 1503 emit_opcode(*cbuf, 0xF2); 1504 if (Matcher::_regEncode[src_first] >= 8) { 1505 emit_opcode(*cbuf, Assembler::REX_R); 1506 } 1507 emit_opcode(*cbuf, 0x0F); 1508 emit_opcode(*cbuf, 0x11); 1509 encode_RegMem(*cbuf, 1510 Matcher::_regEncode[src_first], 1511 RSP_enc, 0x4, 0, offset, 1512 false); 1513 #ifndef PRODUCT 1514 } else if (!do_size) { 1515 st->print("movsd [rsp + #%d], %s\t# spill", 1516 offset, 1517 Matcher::regName[src_first]); 1518 #endif 1519 } 1520 return 1521 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1522 ((Matcher::_regEncode[src_first] < 8) 1523 ? 5 1524 : 6); // REX 1525 } else { 1526 // 32-bit 1527 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1528 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1529 int offset = ra_->reg2offset(dst_first); 1530 if (cbuf) { 1531 emit_opcode(*cbuf, 0xF3); 1532 if (Matcher::_regEncode[src_first] >= 8) { 1533 emit_opcode(*cbuf, Assembler::REX_R); 1534 } 1535 emit_opcode(*cbuf, 0x0F); 1536 emit_opcode(*cbuf, 0x11); 1537 encode_RegMem(*cbuf, 1538 Matcher::_regEncode[src_first], 1539 RSP_enc, 0x4, 0, offset, 1540 false); 1541 #ifndef PRODUCT 1542 } else if (!do_size) { 1543 st->print("movss [rsp + #%d], %s\t# spill", 1544 offset, 1545 Matcher::regName[src_first]); 1546 #endif 1547 } 1548 return 1549 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1550 ((Matcher::_regEncode[src_first] < 8) 1551 ? 5 1552 : 6); // REX 1553 } 1554 } else if (dst_first_rc == rc_int) { 1555 // xmm -> gpr 1556 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1557 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1558 // 64-bit 1559 if (cbuf) { 1560 emit_opcode(*cbuf, 0x66); 1561 if (Matcher::_regEncode[dst_first] < 8) { 1562 if (Matcher::_regEncode[src_first] < 8) { 1563 emit_opcode(*cbuf, Assembler::REX_W); 1564 } else { 1565 emit_opcode(*cbuf, Assembler::REX_WR); // attention! 1566 } 1567 } else { 1568 if (Matcher::_regEncode[src_first] < 8) { 1569 emit_opcode(*cbuf, Assembler::REX_WB); // attention! 1570 } else { 1571 emit_opcode(*cbuf, Assembler::REX_WRB); 1572 } 1573 } 1574 emit_opcode(*cbuf, 0x0F); 1575 emit_opcode(*cbuf, 0x7E); 1576 emit_rm(*cbuf, 0x3, 1577 Matcher::_regEncode[src_first] & 7, 1578 Matcher::_regEncode[dst_first] & 7); 1579 #ifndef PRODUCT 1580 } else if (!do_size) { 1581 st->print("movdq %s, %s\t# spill", 1582 Matcher::regName[dst_first], 1583 Matcher::regName[src_first]); 1584 #endif 1585 } 1586 return 5; // REX 1587 } else { 1588 // 32-bit 1589 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1590 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1591 if (cbuf) { 1592 emit_opcode(*cbuf, 0x66); 1593 if (Matcher::_regEncode[dst_first] < 8) { 1594 if (Matcher::_regEncode[src_first] >= 8) { 1595 emit_opcode(*cbuf, Assembler::REX_R); // attention! 1596 } 1597 } else { 1598 if (Matcher::_regEncode[src_first] < 8) { 1599 emit_opcode(*cbuf, Assembler::REX_B); // attention! 1600 } else { 1601 emit_opcode(*cbuf, Assembler::REX_RB); 1602 } 1603 } 1604 emit_opcode(*cbuf, 0x0F); 1605 emit_opcode(*cbuf, 0x7E); 1606 emit_rm(*cbuf, 0x3, 1607 Matcher::_regEncode[src_first] & 7, 1608 Matcher::_regEncode[dst_first] & 7); 1609 #ifndef PRODUCT 1610 } else if (!do_size) { 1611 st->print("movdl %s, %s\t# spill", 1612 Matcher::regName[dst_first], 1613 Matcher::regName[src_first]); 1614 #endif 1615 } 1616 return 1617 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1618 ? 4 1619 : 5; // REX 1620 } 1621 } else if (dst_first_rc == rc_float) { 1622 // xmm -> xmm 1623 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1624 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1625 // 64-bit 1626 if (cbuf) { 1627 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2); 1628 if (Matcher::_regEncode[dst_first] < 8) { 1629 if (Matcher::_regEncode[src_first] >= 8) { 1630 emit_opcode(*cbuf, Assembler::REX_B); 1631 } 1632 } else { 1633 if (Matcher::_regEncode[src_first] < 8) { 1634 emit_opcode(*cbuf, Assembler::REX_R); 1635 } else { 1636 emit_opcode(*cbuf, Assembler::REX_RB); 1637 } 1638 } 1639 emit_opcode(*cbuf, 0x0F); 1640 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 1641 emit_rm(*cbuf, 0x3, 1642 Matcher::_regEncode[dst_first] & 7, 1643 Matcher::_regEncode[src_first] & 7); 1644 #ifndef PRODUCT 1645 } else if (!do_size) { 1646 st->print("%s %s, %s\t# spill", 1647 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1648 Matcher::regName[dst_first], 1649 Matcher::regName[src_first]); 1650 #endif 1651 } 1652 return 1653 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1654 ? 4 1655 : 5; // REX 1656 } else { 1657 // 32-bit 1658 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1659 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1660 if (cbuf) { 1661 if (!UseXmmRegToRegMoveAll) 1662 emit_opcode(*cbuf, 0xF3); 1663 if (Matcher::_regEncode[dst_first] < 8) { 1664 if (Matcher::_regEncode[src_first] >= 8) { 1665 emit_opcode(*cbuf, Assembler::REX_B); 1666 } 1667 } else { 1668 if (Matcher::_regEncode[src_first] < 8) { 1669 emit_opcode(*cbuf, Assembler::REX_R); 1670 } else { 1671 emit_opcode(*cbuf, Assembler::REX_RB); 1672 } 1673 } 1674 emit_opcode(*cbuf, 0x0F); 1675 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 1676 emit_rm(*cbuf, 0x3, 1677 Matcher::_regEncode[dst_first] & 7, 1678 Matcher::_regEncode[src_first] & 7); 1679 #ifndef PRODUCT 1680 } else if (!do_size) { 1681 st->print("%s %s, %s\t# spill", 1682 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1683 Matcher::regName[dst_first], 1684 Matcher::regName[src_first]); 1685 #endif 1686 } 1687 return 1688 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1689 ? (UseXmmRegToRegMoveAll ? 3 : 4) 1690 : (UseXmmRegToRegMoveAll ? 4 : 5); // REX 1691 } 1692 } 1693 } 1694 1695 assert(0," foo "); 1696 Unimplemented(); 1697 1698 return 0; 1699 } 1700 1701 #ifndef PRODUCT 1702 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const 1703 { 1704 implementation(NULL, ra_, false, st); 1705 } 1706 #endif 1707 1708 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const 1709 { 1710 implementation(&cbuf, ra_, false, NULL); 1711 } 1712 1713 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const 1714 { 1715 return implementation(NULL, ra_, true, NULL); 1716 } 1717 1718 //============================================================================= 1719 #ifndef PRODUCT 1720 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const 1721 { 1722 st->print("nop \t# %d bytes pad for loops and calls", _count); 1723 } 1724 #endif 1725 1726 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const 1727 { 1728 MacroAssembler _masm(&cbuf); 1729 __ nop(_count); 1730 } 1731 1732 uint MachNopNode::size(PhaseRegAlloc*) const 1733 { 1734 return _count; 1735 } 1736 1737 1738 //============================================================================= 1739 #ifndef PRODUCT 1740 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1741 { 1742 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1743 int reg = ra_->get_reg_first(this); 1744 st->print("leaq %s, [rsp + #%d]\t# box lock", 1745 Matcher::regName[reg], offset); 1746 } 1747 #endif 1748 1749 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1750 { 1751 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1752 int reg = ra_->get_encode(this); 1753 if (offset >= 0x80) { 1754 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1755 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1756 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1757 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1758 emit_d32(cbuf, offset); 1759 } else { 1760 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1761 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1762 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1763 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1764 emit_d8(cbuf, offset); 1765 } 1766 } 1767 1768 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1769 { 1770 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1771 return (offset < 0x80) ? 5 : 8; // REX 1772 } 1773 1774 //============================================================================= 1775 1776 // emit call stub, compiled java to interpreter 1777 void emit_java_to_interp(CodeBuffer& cbuf) 1778 { 1779 // Stub is fixed up when the corresponding call is converted from 1780 // calling compiled code to calling interpreted code. 1781 // movq rbx, 0 1782 // jmp -5 # to self 1783 1784 address mark = cbuf.insts_mark(); // get mark within main instrs section 1785 1786 // Note that the code buffer's insts_mark is always relative to insts. 1787 // That's why we must use the macroassembler to generate a stub. 1788 MacroAssembler _masm(&cbuf); 1789 1790 address base = 1791 __ start_a_stub(Compile::MAX_stubs_size); 1792 if (base == NULL) return; // CodeBuffer::expand failed 1793 // static stub relocation stores the instruction address of the call 1794 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); 1795 // static stub relocation also tags the methodOop in the code-stream. 1796 __ movoop(rbx, (jobject) NULL); // method is zapped till fixup time 1797 // This is recognized as unresolved by relocs/nativeinst/ic code 1798 __ jump(RuntimeAddress(__ pc())); 1799 1800 // Update current stubs pointer and restore insts_end. 1801 __ end_a_stub(); 1802 } 1803 1804 // size of call stub, compiled java to interpretor 1805 uint size_java_to_interp() 1806 { 1807 return 15; // movq (1+1+8); jmp (1+4) 1808 } 1809 1810 // relocation entries for call stub, compiled java to interpretor 1811 uint reloc_java_to_interp() 1812 { 1813 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call 1814 } 1815 1816 //============================================================================= 1817 #ifndef PRODUCT 1818 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1819 { 1820 if (UseCompressedOops) { 1821 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1822 if (Universe::narrow_oop_shift() != 0) { 1823 st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1"); 1824 } 1825 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1826 } else { 1827 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1828 "# Inline cache check"); 1829 } 1830 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1831 st->print_cr("\tnop\t# nops to align entry point"); 1832 } 1833 #endif 1834 1835 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1836 { 1837 MacroAssembler masm(&cbuf); 1838 uint insts_size = cbuf.insts_size(); 1839 if (UseCompressedOops) { 1840 masm.load_klass(rscratch1, j_rarg0); 1841 masm.cmpptr(rax, rscratch1); 1842 } else { 1843 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1844 } 1845 1846 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1847 1848 /* WARNING these NOPs are critical so that verified entry point is properly 1849 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1850 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1851 if (OptoBreakpoint) { 1852 // Leave space for int3 1853 nops_cnt -= 1; 1854 } 1855 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1856 if (nops_cnt > 0) 1857 masm.nop(nops_cnt); 1858 } 1859 1860 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1861 { 1862 return MachNode::size(ra_); // too many variables; just compute it 1863 // the hard way 1864 } 1865 1866 1867 //============================================================================= 1868 uint size_exception_handler() 1869 { 1870 // NativeCall instruction size is the same as NativeJump. 1871 // Note that this value is also credited (in output.cpp) to 1872 // the size of the code section. 1873 return NativeJump::instruction_size; 1874 } 1875 1876 // Emit exception handler code. 1877 int emit_exception_handler(CodeBuffer& cbuf) 1878 { 1879 1880 // Note that the code buffer's insts_mark is always relative to insts. 1881 // That's why we must use the macroassembler to generate a handler. 1882 MacroAssembler _masm(&cbuf); 1883 address base = 1884 __ start_a_stub(size_exception_handler()); 1885 if (base == NULL) return 0; // CodeBuffer::expand failed 1886 int offset = __ offset(); 1887 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1888 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1889 __ end_a_stub(); 1890 return offset; 1891 } 1892 1893 uint size_deopt_handler() 1894 { 1895 // three 5 byte instructions 1896 return 15; 1897 } 1898 1899 // Emit deopt handler code. 1900 int emit_deopt_handler(CodeBuffer& cbuf) 1901 { 1902 1903 // Note that the code buffer's insts_mark is always relative to insts. 1904 // That's why we must use the macroassembler to generate a handler. 1905 MacroAssembler _masm(&cbuf); 1906 address base = 1907 __ start_a_stub(size_deopt_handler()); 1908 if (base == NULL) return 0; // CodeBuffer::expand failed 1909 int offset = __ offset(); 1910 address the_pc = (address) __ pc(); 1911 Label next; 1912 // push a "the_pc" on the stack without destroying any registers 1913 // as they all may be live. 1914 1915 // push address of "next" 1916 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 1917 __ bind(next); 1918 // adjust it so it matches "the_pc" 1919 __ subptr(Address(rsp, 0), __ offset() - offset); 1920 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1921 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1922 __ end_a_stub(); 1923 return offset; 1924 } 1925 1926 1927 const bool Matcher::match_rule_supported(int opcode) { 1928 if (!has_match_rule(opcode)) 1929 return false; 1930 1931 return true; // Per default match rules are supported. 1932 } 1933 1934 int Matcher::regnum_to_fpu_offset(int regnum) 1935 { 1936 return regnum - 32; // The FP registers are in the second chunk 1937 } 1938 1939 // This is UltraSparc specific, true just means we have fast l2f conversion 1940 const bool Matcher::convL2FSupported(void) { 1941 return true; 1942 } 1943 1944 // Vector width in bytes 1945 const uint Matcher::vector_width_in_bytes(void) { 1946 return 8; 1947 } 1948 1949 // Vector ideal reg 1950 const uint Matcher::vector_ideal_reg(void) { 1951 return Op_RegD; 1952 } 1953 1954 // Is this branch offset short enough that a short branch can be used? 1955 // 1956 // NOTE: If the platform does not provide any short branch variants, then 1957 // this method should return false for offset 0. 1958 bool Matcher::is_short_branch_offset(int rule, int offset) { 1959 // the short version of jmpConUCF2 contains multiple branches, 1960 // making the reach slightly less 1961 if (rule == jmpConUCF2_rule) 1962 return (-126 <= offset && offset <= 125); 1963 return (-128 <= offset && offset <= 127); 1964 } 1965 1966 const bool Matcher::isSimpleConstant64(jlong value) { 1967 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1968 //return value == (int) value; // Cf. storeImmL and immL32. 1969 1970 // Probably always true, even if a temp register is required. 1971 return true; 1972 } 1973 1974 // The ecx parameter to rep stosq for the ClearArray node is in words. 1975 const bool Matcher::init_array_count_is_in_bytes = false; 1976 1977 // Threshold size for cleararray. 1978 const int Matcher::init_array_short_size = 8 * BytesPerLong; 1979 1980 // Should the Matcher clone shifts on addressing modes, expecting them 1981 // to be subsumed into complex addressing expressions or compute them 1982 // into registers? True for Intel but false for most RISCs 1983 const bool Matcher::clone_shift_expressions = true; 1984 1985 // Do we need to mask the count passed to shift instructions or does 1986 // the cpu only look at the lower 5/6 bits anyway? 1987 const bool Matcher::need_masked_shift_count = false; 1988 1989 bool Matcher::narrow_oop_use_complex_address() { 1990 assert(UseCompressedOops, "only for compressed oops code"); 1991 return (LogMinObjAlignmentInBytes <= 3); 1992 } 1993 1994 // Is it better to copy float constants, or load them directly from 1995 // memory? Intel can load a float constant from a direct address, 1996 // requiring no extra registers. Most RISCs will have to materialize 1997 // an address into a register first, so they would do better to copy 1998 // the constant from stack. 1999 const bool Matcher::rematerialize_float_constants = true; // XXX 2000 2001 // If CPU can load and store mis-aligned doubles directly then no 2002 // fixup is needed. Else we split the double into 2 integer pieces 2003 // and move it piece-by-piece. Only happens when passing doubles into 2004 // C code as the Java calling convention forces doubles to be aligned. 2005 const bool Matcher::misaligned_doubles_ok = true; 2006 2007 // No-op on amd64 2008 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 2009 2010 // Advertise here if the CPU requires explicit rounding operations to 2011 // implement the UseStrictFP mode. 2012 const bool Matcher::strict_fp_requires_explicit_rounding = true; 2013 2014 // Are floats conerted to double when stored to stack during deoptimization? 2015 // On x64 it is stored without convertion so we can use normal access. 2016 bool Matcher::float_in_double() { return false; } 2017 2018 // Do ints take an entire long register or just half? 2019 const bool Matcher::int_in_long = true; 2020 2021 // Return whether or not this register is ever used as an argument. 2022 // This function is used on startup to build the trampoline stubs in 2023 // generateOptoStub. Registers not mentioned will be killed by the VM 2024 // call in the trampoline, and arguments in those registers not be 2025 // available to the callee. 2026 bool Matcher::can_be_java_arg(int reg) 2027 { 2028 return 2029 reg == RDI_num || reg == RDI_H_num || 2030 reg == RSI_num || reg == RSI_H_num || 2031 reg == RDX_num || reg == RDX_H_num || 2032 reg == RCX_num || reg == RCX_H_num || 2033 reg == R8_num || reg == R8_H_num || 2034 reg == R9_num || reg == R9_H_num || 2035 reg == R12_num || reg == R12_H_num || 2036 reg == XMM0_num || reg == XMM0_H_num || 2037 reg == XMM1_num || reg == XMM1_H_num || 2038 reg == XMM2_num || reg == XMM2_H_num || 2039 reg == XMM3_num || reg == XMM3_H_num || 2040 reg == XMM4_num || reg == XMM4_H_num || 2041 reg == XMM5_num || reg == XMM5_H_num || 2042 reg == XMM6_num || reg == XMM6_H_num || 2043 reg == XMM7_num || reg == XMM7_H_num; 2044 } 2045 2046 bool Matcher::is_spillable_arg(int reg) 2047 { 2048 return can_be_java_arg(reg); 2049 } 2050 2051 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 2052 // In 64 bit mode a code which use multiply when 2053 // devisor is constant is faster than hardware 2054 // DIV instruction (it uses MulHiL). 2055 return false; 2056 } 2057 2058 // Register for DIVI projection of divmodI 2059 RegMask Matcher::divI_proj_mask() { 2060 return INT_RAX_REG_mask; 2061 } 2062 2063 // Register for MODI projection of divmodI 2064 RegMask Matcher::modI_proj_mask() { 2065 return INT_RDX_REG_mask; 2066 } 2067 2068 // Register for DIVL projection of divmodL 2069 RegMask Matcher::divL_proj_mask() { 2070 return LONG_RAX_REG_mask; 2071 } 2072 2073 // Register for MODL projection of divmodL 2074 RegMask Matcher::modL_proj_mask() { 2075 return LONG_RDX_REG_mask; 2076 } 2077 2078 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2079 return PTR_RBP_REG_mask; 2080 } 2081 2082 static Address build_address(int b, int i, int s, int d) { 2083 Register index = as_Register(i); 2084 Address::ScaleFactor scale = (Address::ScaleFactor)s; 2085 if (index == rsp) { 2086 index = noreg; 2087 scale = Address::no_scale; 2088 } 2089 Address addr(as_Register(b), index, scale, d); 2090 return addr; 2091 } 2092 2093 %} 2094 2095 //----------ENCODING BLOCK----------------------------------------------------- 2096 // This block specifies the encoding classes used by the compiler to 2097 // output byte streams. Encoding classes are parameterized macros 2098 // used by Machine Instruction Nodes in order to generate the bit 2099 // encoding of the instruction. Operands specify their base encoding 2100 // interface with the interface keyword. There are currently 2101 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2102 // COND_INTER. REG_INTER causes an operand to generate a function 2103 // which returns its register number when queried. CONST_INTER causes 2104 // an operand to generate a function which returns the value of the 2105 // constant when queried. MEMORY_INTER causes an operand to generate 2106 // four functions which return the Base Register, the Index Register, 2107 // the Scale Value, and the Offset Value of the operand when queried. 2108 // COND_INTER causes an operand to generate six functions which return 2109 // the encoding code (ie - encoding bits for the instruction) 2110 // associated with each basic boolean condition for a conditional 2111 // instruction. 2112 // 2113 // Instructions specify two basic values for encoding. Again, a 2114 // function is available to check if the constant displacement is an 2115 // oop. They use the ins_encode keyword to specify their encoding 2116 // classes (which must be a sequence of enc_class names, and their 2117 // parameters, specified in the encoding block), and they use the 2118 // opcode keyword to specify, in order, their primary, secondary, and 2119 // tertiary opcode. Only the opcode sections which a particular 2120 // instruction needs for encoding need to be specified. 2121 encode %{ 2122 // Build emit functions for each basic byte or larger field in the 2123 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2124 // from C++ code in the enc_class source block. Emit functions will 2125 // live in the main source block for now. In future, we can 2126 // generalize this by adding a syntax that specifies the sizes of 2127 // fields in an order, so that the adlc can build the emit functions 2128 // automagically 2129 2130 // Emit primary opcode 2131 enc_class OpcP 2132 %{ 2133 emit_opcode(cbuf, $primary); 2134 %} 2135 2136 // Emit secondary opcode 2137 enc_class OpcS 2138 %{ 2139 emit_opcode(cbuf, $secondary); 2140 %} 2141 2142 // Emit tertiary opcode 2143 enc_class OpcT 2144 %{ 2145 emit_opcode(cbuf, $tertiary); 2146 %} 2147 2148 // Emit opcode directly 2149 enc_class Opcode(immI d8) 2150 %{ 2151 emit_opcode(cbuf, $d8$$constant); 2152 %} 2153 2154 // Emit size prefix 2155 enc_class SizePrefix 2156 %{ 2157 emit_opcode(cbuf, 0x66); 2158 %} 2159 2160 enc_class reg(rRegI reg) 2161 %{ 2162 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 2163 %} 2164 2165 enc_class reg_reg(rRegI dst, rRegI src) 2166 %{ 2167 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2168 %} 2169 2170 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 2171 %{ 2172 emit_opcode(cbuf, $opcode$$constant); 2173 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2174 %} 2175 2176 enc_class cmpfp_fixup() 2177 %{ 2178 // jnp,s exit 2179 emit_opcode(cbuf, 0x7B); 2180 emit_d8(cbuf, 0x0A); 2181 2182 // pushfq 2183 emit_opcode(cbuf, 0x9C); 2184 2185 // andq $0xffffff2b, (%rsp) 2186 emit_opcode(cbuf, Assembler::REX_W); 2187 emit_opcode(cbuf, 0x81); 2188 emit_opcode(cbuf, 0x24); 2189 emit_opcode(cbuf, 0x24); 2190 emit_d32(cbuf, 0xffffff2b); 2191 2192 // popfq 2193 emit_opcode(cbuf, 0x9D); 2194 2195 // nop (target for branch to avoid branch to branch) 2196 emit_opcode(cbuf, 0x90); 2197 %} 2198 2199 enc_class cmpfp3(rRegI dst) 2200 %{ 2201 int dstenc = $dst$$reg; 2202 2203 // movl $dst, -1 2204 if (dstenc >= 8) { 2205 emit_opcode(cbuf, Assembler::REX_B); 2206 } 2207 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2208 emit_d32(cbuf, -1); 2209 2210 // jp,s done 2211 emit_opcode(cbuf, 0x7A); 2212 emit_d8(cbuf, dstenc < 4 ? 0x08 : 0x0A); 2213 2214 // jb,s done 2215 emit_opcode(cbuf, 0x72); 2216 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2217 2218 // setne $dst 2219 if (dstenc >= 4) { 2220 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2221 } 2222 emit_opcode(cbuf, 0x0F); 2223 emit_opcode(cbuf, 0x95); 2224 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2225 2226 // movzbl $dst, $dst 2227 if (dstenc >= 4) { 2228 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2229 } 2230 emit_opcode(cbuf, 0x0F); 2231 emit_opcode(cbuf, 0xB6); 2232 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2233 %} 2234 2235 enc_class cdql_enc(no_rax_rdx_RegI div) 2236 %{ 2237 // Full implementation of Java idiv and irem; checks for 2238 // special case as described in JVM spec., p.243 & p.271. 2239 // 2240 // normal case special case 2241 // 2242 // input : rax: dividend min_int 2243 // reg: divisor -1 2244 // 2245 // output: rax: quotient (= rax idiv reg) min_int 2246 // rdx: remainder (= rax irem reg) 0 2247 // 2248 // Code sequnce: 2249 // 2250 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 2251 // 5: 75 07/08 jne e <normal> 2252 // 7: 33 d2 xor %edx,%edx 2253 // [div >= 8 -> offset + 1] 2254 // [REX_B] 2255 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 2256 // c: 74 03/04 je 11 <done> 2257 // 000000000000000e <normal>: 2258 // e: 99 cltd 2259 // [div >= 8 -> offset + 1] 2260 // [REX_B] 2261 // f: f7 f9 idiv $div 2262 // 0000000000000011 <done>: 2263 2264 // cmp $0x80000000,%eax 2265 emit_opcode(cbuf, 0x3d); 2266 emit_d8(cbuf, 0x00); 2267 emit_d8(cbuf, 0x00); 2268 emit_d8(cbuf, 0x00); 2269 emit_d8(cbuf, 0x80); 2270 2271 // jne e <normal> 2272 emit_opcode(cbuf, 0x75); 2273 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 2274 2275 // xor %edx,%edx 2276 emit_opcode(cbuf, 0x33); 2277 emit_d8(cbuf, 0xD2); 2278 2279 // cmp $0xffffffffffffffff,%ecx 2280 if ($div$$reg >= 8) { 2281 emit_opcode(cbuf, Assembler::REX_B); 2282 } 2283 emit_opcode(cbuf, 0x83); 2284 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2285 emit_d8(cbuf, 0xFF); 2286 2287 // je 11 <done> 2288 emit_opcode(cbuf, 0x74); 2289 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 2290 2291 // <normal> 2292 // cltd 2293 emit_opcode(cbuf, 0x99); 2294 2295 // idivl (note: must be emitted by the user of this rule) 2296 // <done> 2297 %} 2298 2299 enc_class cdqq_enc(no_rax_rdx_RegL div) 2300 %{ 2301 // Full implementation of Java ldiv and lrem; checks for 2302 // special case as described in JVM spec., p.243 & p.271. 2303 // 2304 // normal case special case 2305 // 2306 // input : rax: dividend min_long 2307 // reg: divisor -1 2308 // 2309 // output: rax: quotient (= rax idiv reg) min_long 2310 // rdx: remainder (= rax irem reg) 0 2311 // 2312 // Code sequnce: 2313 // 2314 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 2315 // 7: 00 00 80 2316 // a: 48 39 d0 cmp %rdx,%rax 2317 // d: 75 08 jne 17 <normal> 2318 // f: 33 d2 xor %edx,%edx 2319 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 2320 // 15: 74 05 je 1c <done> 2321 // 0000000000000017 <normal>: 2322 // 17: 48 99 cqto 2323 // 19: 48 f7 f9 idiv $div 2324 // 000000000000001c <done>: 2325 2326 // mov $0x8000000000000000,%rdx 2327 emit_opcode(cbuf, Assembler::REX_W); 2328 emit_opcode(cbuf, 0xBA); 2329 emit_d8(cbuf, 0x00); 2330 emit_d8(cbuf, 0x00); 2331 emit_d8(cbuf, 0x00); 2332 emit_d8(cbuf, 0x00); 2333 emit_d8(cbuf, 0x00); 2334 emit_d8(cbuf, 0x00); 2335 emit_d8(cbuf, 0x00); 2336 emit_d8(cbuf, 0x80); 2337 2338 // cmp %rdx,%rax 2339 emit_opcode(cbuf, Assembler::REX_W); 2340 emit_opcode(cbuf, 0x39); 2341 emit_d8(cbuf, 0xD0); 2342 2343 // jne 17 <normal> 2344 emit_opcode(cbuf, 0x75); 2345 emit_d8(cbuf, 0x08); 2346 2347 // xor %edx,%edx 2348 emit_opcode(cbuf, 0x33); 2349 emit_d8(cbuf, 0xD2); 2350 2351 // cmp $0xffffffffffffffff,$div 2352 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 2353 emit_opcode(cbuf, 0x83); 2354 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2355 emit_d8(cbuf, 0xFF); 2356 2357 // je 1e <done> 2358 emit_opcode(cbuf, 0x74); 2359 emit_d8(cbuf, 0x05); 2360 2361 // <normal> 2362 // cqto 2363 emit_opcode(cbuf, Assembler::REX_W); 2364 emit_opcode(cbuf, 0x99); 2365 2366 // idivq (note: must be emitted by the user of this rule) 2367 // <done> 2368 %} 2369 2370 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2371 enc_class OpcSE(immI imm) 2372 %{ 2373 // Emit primary opcode and set sign-extend bit 2374 // Check for 8-bit immediate, and set sign extend bit in opcode 2375 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2376 emit_opcode(cbuf, $primary | 0x02); 2377 } else { 2378 // 32-bit immediate 2379 emit_opcode(cbuf, $primary); 2380 } 2381 %} 2382 2383 enc_class OpcSErm(rRegI dst, immI imm) 2384 %{ 2385 // OpcSEr/m 2386 int dstenc = $dst$$reg; 2387 if (dstenc >= 8) { 2388 emit_opcode(cbuf, Assembler::REX_B); 2389 dstenc -= 8; 2390 } 2391 // Emit primary opcode and set sign-extend bit 2392 // Check for 8-bit immediate, and set sign extend bit in opcode 2393 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2394 emit_opcode(cbuf, $primary | 0x02); 2395 } else { 2396 // 32-bit immediate 2397 emit_opcode(cbuf, $primary); 2398 } 2399 // Emit r/m byte with secondary opcode, after primary opcode. 2400 emit_rm(cbuf, 0x3, $secondary, dstenc); 2401 %} 2402 2403 enc_class OpcSErm_wide(rRegL dst, immI imm) 2404 %{ 2405 // OpcSEr/m 2406 int dstenc = $dst$$reg; 2407 if (dstenc < 8) { 2408 emit_opcode(cbuf, Assembler::REX_W); 2409 } else { 2410 emit_opcode(cbuf, Assembler::REX_WB); 2411 dstenc -= 8; 2412 } 2413 // Emit primary opcode and set sign-extend bit 2414 // Check for 8-bit immediate, and set sign extend bit in opcode 2415 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2416 emit_opcode(cbuf, $primary | 0x02); 2417 } else { 2418 // 32-bit immediate 2419 emit_opcode(cbuf, $primary); 2420 } 2421 // Emit r/m byte with secondary opcode, after primary opcode. 2422 emit_rm(cbuf, 0x3, $secondary, dstenc); 2423 %} 2424 2425 enc_class Con8or32(immI imm) 2426 %{ 2427 // Check for 8-bit immediate, and set sign extend bit in opcode 2428 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2429 $$$emit8$imm$$constant; 2430 } else { 2431 // 32-bit immediate 2432 $$$emit32$imm$$constant; 2433 } 2434 %} 2435 2436 enc_class Lbl(label labl) 2437 %{ 2438 // JMP, CALL 2439 Label* l = $labl$$label; 2440 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0); 2441 %} 2442 2443 enc_class LblShort(label labl) 2444 %{ 2445 // JMP, CALL 2446 Label* l = $labl$$label; 2447 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; 2448 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 2449 emit_d8(cbuf, disp); 2450 %} 2451 2452 enc_class opc2_reg(rRegI dst) 2453 %{ 2454 // BSWAP 2455 emit_cc(cbuf, $secondary, $dst$$reg); 2456 %} 2457 2458 enc_class opc3_reg(rRegI dst) 2459 %{ 2460 // BSWAP 2461 emit_cc(cbuf, $tertiary, $dst$$reg); 2462 %} 2463 2464 enc_class reg_opc(rRegI div) 2465 %{ 2466 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2467 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2468 %} 2469 2470 enc_class Jcc(cmpOp cop, label labl) 2471 %{ 2472 // JCC 2473 Label* l = $labl$$label; 2474 $$$emit8$primary; 2475 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2476 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0); 2477 %} 2478 2479 enc_class JccShort (cmpOp cop, label labl) 2480 %{ 2481 // JCC 2482 Label *l = $labl$$label; 2483 emit_cc(cbuf, $primary, $cop$$cmpcode); 2484 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; 2485 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 2486 emit_d8(cbuf, disp); 2487 %} 2488 2489 enc_class enc_cmov(cmpOp cop) 2490 %{ 2491 // CMOV 2492 $$$emit8$primary; 2493 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2494 %} 2495 2496 enc_class enc_cmovf_branch(cmpOp cop, regF dst, regF src) 2497 %{ 2498 // Invert sense of branch from sense of cmov 2499 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1); 2500 emit_d8(cbuf, ($dst$$reg < 8 && $src$$reg < 8) 2501 ? (UseXmmRegToRegMoveAll ? 3 : 4) 2502 : (UseXmmRegToRegMoveAll ? 4 : 5) ); // REX 2503 // UseXmmRegToRegMoveAll ? movaps(dst, src) : movss(dst, src) 2504 if (!UseXmmRegToRegMoveAll) emit_opcode(cbuf, 0xF3); 2505 if ($dst$$reg < 8) { 2506 if ($src$$reg >= 8) { 2507 emit_opcode(cbuf, Assembler::REX_B); 2508 } 2509 } else { 2510 if ($src$$reg < 8) { 2511 emit_opcode(cbuf, Assembler::REX_R); 2512 } else { 2513 emit_opcode(cbuf, Assembler::REX_RB); 2514 } 2515 } 2516 emit_opcode(cbuf, 0x0F); 2517 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 2518 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2519 %} 2520 2521 enc_class enc_cmovd_branch(cmpOp cop, regD dst, regD src) 2522 %{ 2523 // Invert sense of branch from sense of cmov 2524 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1); 2525 emit_d8(cbuf, $dst$$reg < 8 && $src$$reg < 8 ? 4 : 5); // REX 2526 2527 // UseXmmRegToRegMoveAll ? movapd(dst, src) : movsd(dst, src) 2528 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2); 2529 if ($dst$$reg < 8) { 2530 if ($src$$reg >= 8) { 2531 emit_opcode(cbuf, Assembler::REX_B); 2532 } 2533 } else { 2534 if ($src$$reg < 8) { 2535 emit_opcode(cbuf, Assembler::REX_R); 2536 } else { 2537 emit_opcode(cbuf, Assembler::REX_RB); 2538 } 2539 } 2540 emit_opcode(cbuf, 0x0F); 2541 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 2542 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2543 %} 2544 2545 enc_class enc_PartialSubtypeCheck() 2546 %{ 2547 Register Rrdi = as_Register(RDI_enc); // result register 2548 Register Rrax = as_Register(RAX_enc); // super class 2549 Register Rrcx = as_Register(RCX_enc); // killed 2550 Register Rrsi = as_Register(RSI_enc); // sub class 2551 Label miss; 2552 const bool set_cond_codes = true; 2553 2554 MacroAssembler _masm(&cbuf); 2555 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2556 NULL, &miss, 2557 /*set_cond_codes:*/ true); 2558 if ($primary) { 2559 __ xorptr(Rrdi, Rrdi); 2560 } 2561 __ bind(miss); 2562 %} 2563 2564 enc_class Java_To_Interpreter(method meth) 2565 %{ 2566 // CALL Java_To_Interpreter 2567 // This is the instruction starting address for relocation info. 2568 cbuf.set_insts_mark(); 2569 $$$emit8$primary; 2570 // CALL directly to the runtime 2571 emit_d32_reloc(cbuf, 2572 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2573 runtime_call_Relocation::spec(), 2574 RELOC_DISP32); 2575 %} 2576 2577 enc_class preserve_SP %{ 2578 debug_only(int off0 = cbuf.insts_size()); 2579 MacroAssembler _masm(&cbuf); 2580 // RBP is preserved across all calls, even compiled calls. 2581 // Use it to preserve RSP in places where the callee might change the SP. 2582 __ movptr(rbp_mh_SP_save, rsp); 2583 debug_only(int off1 = cbuf.insts_size()); 2584 assert(off1 - off0 == preserve_SP_size(), "correct size prediction"); 2585 %} 2586 2587 enc_class restore_SP %{ 2588 MacroAssembler _masm(&cbuf); 2589 __ movptr(rsp, rbp_mh_SP_save); 2590 %} 2591 2592 enc_class Java_Static_Call(method meth) 2593 %{ 2594 // JAVA STATIC CALL 2595 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2596 // determine who we intended to call. 2597 cbuf.set_insts_mark(); 2598 $$$emit8$primary; 2599 2600 if (!_method) { 2601 emit_d32_reloc(cbuf, 2602 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2603 runtime_call_Relocation::spec(), 2604 RELOC_DISP32); 2605 } else if (_optimized_virtual) { 2606 emit_d32_reloc(cbuf, 2607 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2608 opt_virtual_call_Relocation::spec(), 2609 RELOC_DISP32); 2610 } else { 2611 emit_d32_reloc(cbuf, 2612 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2613 static_call_Relocation::spec(), 2614 RELOC_DISP32); 2615 } 2616 if (_method) { 2617 // Emit stub for static call 2618 emit_java_to_interp(cbuf); 2619 } 2620 %} 2621 2622 enc_class Java_Dynamic_Call(method meth) 2623 %{ 2624 // JAVA DYNAMIC CALL 2625 // !!!!! 2626 // Generate "movq rax, -1", placeholder instruction to load oop-info 2627 // emit_call_dynamic_prologue( cbuf ); 2628 cbuf.set_insts_mark(); 2629 2630 // movq rax, -1 2631 emit_opcode(cbuf, Assembler::REX_W); 2632 emit_opcode(cbuf, 0xB8 | RAX_enc); 2633 emit_d64_reloc(cbuf, 2634 (int64_t) Universe::non_oop_word(), 2635 oop_Relocation::spec_for_immediate(), RELOC_IMM64); 2636 address virtual_call_oop_addr = cbuf.insts_mark(); 2637 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine 2638 // who we intended to call. 2639 cbuf.set_insts_mark(); 2640 $$$emit8$primary; 2641 emit_d32_reloc(cbuf, 2642 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2643 virtual_call_Relocation::spec(virtual_call_oop_addr), 2644 RELOC_DISP32); 2645 %} 2646 2647 enc_class Java_Compiled_Call(method meth) 2648 %{ 2649 // JAVA COMPILED CALL 2650 int disp = in_bytes(methodOopDesc:: from_compiled_offset()); 2651 2652 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2653 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2654 2655 // callq *disp(%rax) 2656 cbuf.set_insts_mark(); 2657 $$$emit8$primary; 2658 if (disp < 0x80) { 2659 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2660 emit_d8(cbuf, disp); // Displacement 2661 } else { 2662 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2663 emit_d32(cbuf, disp); // Displacement 2664 } 2665 %} 2666 2667 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2668 %{ 2669 // SAL, SAR, SHR 2670 int dstenc = $dst$$reg; 2671 if (dstenc >= 8) { 2672 emit_opcode(cbuf, Assembler::REX_B); 2673 dstenc -= 8; 2674 } 2675 $$$emit8$primary; 2676 emit_rm(cbuf, 0x3, $secondary, dstenc); 2677 $$$emit8$shift$$constant; 2678 %} 2679 2680 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2681 %{ 2682 // SAL, SAR, SHR 2683 int dstenc = $dst$$reg; 2684 if (dstenc < 8) { 2685 emit_opcode(cbuf, Assembler::REX_W); 2686 } else { 2687 emit_opcode(cbuf, Assembler::REX_WB); 2688 dstenc -= 8; 2689 } 2690 $$$emit8$primary; 2691 emit_rm(cbuf, 0x3, $secondary, dstenc); 2692 $$$emit8$shift$$constant; 2693 %} 2694 2695 enc_class load_immI(rRegI dst, immI src) 2696 %{ 2697 int dstenc = $dst$$reg; 2698 if (dstenc >= 8) { 2699 emit_opcode(cbuf, Assembler::REX_B); 2700 dstenc -= 8; 2701 } 2702 emit_opcode(cbuf, 0xB8 | dstenc); 2703 $$$emit32$src$$constant; 2704 %} 2705 2706 enc_class load_immL(rRegL dst, immL src) 2707 %{ 2708 int dstenc = $dst$$reg; 2709 if (dstenc < 8) { 2710 emit_opcode(cbuf, Assembler::REX_W); 2711 } else { 2712 emit_opcode(cbuf, Assembler::REX_WB); 2713 dstenc -= 8; 2714 } 2715 emit_opcode(cbuf, 0xB8 | dstenc); 2716 emit_d64(cbuf, $src$$constant); 2717 %} 2718 2719 enc_class load_immUL32(rRegL dst, immUL32 src) 2720 %{ 2721 // same as load_immI, but this time we care about zeroes in the high word 2722 int dstenc = $dst$$reg; 2723 if (dstenc >= 8) { 2724 emit_opcode(cbuf, Assembler::REX_B); 2725 dstenc -= 8; 2726 } 2727 emit_opcode(cbuf, 0xB8 | dstenc); 2728 $$$emit32$src$$constant; 2729 %} 2730 2731 enc_class load_immL32(rRegL dst, immL32 src) 2732 %{ 2733 int dstenc = $dst$$reg; 2734 if (dstenc < 8) { 2735 emit_opcode(cbuf, Assembler::REX_W); 2736 } else { 2737 emit_opcode(cbuf, Assembler::REX_WB); 2738 dstenc -= 8; 2739 } 2740 emit_opcode(cbuf, 0xC7); 2741 emit_rm(cbuf, 0x03, 0x00, dstenc); 2742 $$$emit32$src$$constant; 2743 %} 2744 2745 enc_class load_immP31(rRegP dst, immP32 src) 2746 %{ 2747 // same as load_immI, but this time we care about zeroes in the high word 2748 int dstenc = $dst$$reg; 2749 if (dstenc >= 8) { 2750 emit_opcode(cbuf, Assembler::REX_B); 2751 dstenc -= 8; 2752 } 2753 emit_opcode(cbuf, 0xB8 | dstenc); 2754 $$$emit32$src$$constant; 2755 %} 2756 2757 enc_class load_immP(rRegP dst, immP src) 2758 %{ 2759 int dstenc = $dst$$reg; 2760 if (dstenc < 8) { 2761 emit_opcode(cbuf, Assembler::REX_W); 2762 } else { 2763 emit_opcode(cbuf, Assembler::REX_WB); 2764 dstenc -= 8; 2765 } 2766 emit_opcode(cbuf, 0xB8 | dstenc); 2767 // This next line should be generated from ADLC 2768 if ($src->constant_is_oop()) { 2769 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64); 2770 } else { 2771 emit_d64(cbuf, $src$$constant); 2772 } 2773 %} 2774 2775 // Encode a reg-reg copy. If it is useless, then empty encoding. 2776 enc_class enc_copy(rRegI dst, rRegI src) 2777 %{ 2778 encode_copy(cbuf, $dst$$reg, $src$$reg); 2779 %} 2780 2781 // Encode xmm reg-reg copy. If it is useless, then empty encoding. 2782 enc_class enc_CopyXD( RegD dst, RegD src ) %{ 2783 encode_CopyXD( cbuf, $dst$$reg, $src$$reg ); 2784 %} 2785 2786 enc_class enc_copy_always(rRegI dst, rRegI src) 2787 %{ 2788 int srcenc = $src$$reg; 2789 int dstenc = $dst$$reg; 2790 2791 if (dstenc < 8) { 2792 if (srcenc >= 8) { 2793 emit_opcode(cbuf, Assembler::REX_B); 2794 srcenc -= 8; 2795 } 2796 } else { 2797 if (srcenc < 8) { 2798 emit_opcode(cbuf, Assembler::REX_R); 2799 } else { 2800 emit_opcode(cbuf, Assembler::REX_RB); 2801 srcenc -= 8; 2802 } 2803 dstenc -= 8; 2804 } 2805 2806 emit_opcode(cbuf, 0x8B); 2807 emit_rm(cbuf, 0x3, dstenc, srcenc); 2808 %} 2809 2810 enc_class enc_copy_wide(rRegL dst, rRegL src) 2811 %{ 2812 int srcenc = $src$$reg; 2813 int dstenc = $dst$$reg; 2814 2815 if (dstenc != srcenc) { 2816 if (dstenc < 8) { 2817 if (srcenc < 8) { 2818 emit_opcode(cbuf, Assembler::REX_W); 2819 } else { 2820 emit_opcode(cbuf, Assembler::REX_WB); 2821 srcenc -= 8; 2822 } 2823 } else { 2824 if (srcenc < 8) { 2825 emit_opcode(cbuf, Assembler::REX_WR); 2826 } else { 2827 emit_opcode(cbuf, Assembler::REX_WRB); 2828 srcenc -= 8; 2829 } 2830 dstenc -= 8; 2831 } 2832 emit_opcode(cbuf, 0x8B); 2833 emit_rm(cbuf, 0x3, dstenc, srcenc); 2834 } 2835 %} 2836 2837 enc_class Con32(immI src) 2838 %{ 2839 // Output immediate 2840 $$$emit32$src$$constant; 2841 %} 2842 2843 enc_class Con64(immL src) 2844 %{ 2845 // Output immediate 2846 emit_d64($src$$constant); 2847 %} 2848 2849 enc_class Con32F_as_bits(immF src) 2850 %{ 2851 // Output Float immediate bits 2852 jfloat jf = $src$$constant; 2853 jint jf_as_bits = jint_cast(jf); 2854 emit_d32(cbuf, jf_as_bits); 2855 %} 2856 2857 enc_class Con16(immI src) 2858 %{ 2859 // Output immediate 2860 $$$emit16$src$$constant; 2861 %} 2862 2863 // How is this different from Con32??? XXX 2864 enc_class Con_d32(immI src) 2865 %{ 2866 emit_d32(cbuf,$src$$constant); 2867 %} 2868 2869 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2870 // Output immediate memory reference 2871 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2872 emit_d32(cbuf, 0x00); 2873 %} 2874 2875 enc_class lock_prefix() 2876 %{ 2877 if (os::is_MP()) { 2878 emit_opcode(cbuf, 0xF0); // lock 2879 } 2880 %} 2881 2882 enc_class REX_mem(memory mem) 2883 %{ 2884 if ($mem$$base >= 8) { 2885 if ($mem$$index < 8) { 2886 emit_opcode(cbuf, Assembler::REX_B); 2887 } else { 2888 emit_opcode(cbuf, Assembler::REX_XB); 2889 } 2890 } else { 2891 if ($mem$$index >= 8) { 2892 emit_opcode(cbuf, Assembler::REX_X); 2893 } 2894 } 2895 %} 2896 2897 enc_class REX_mem_wide(memory mem) 2898 %{ 2899 if ($mem$$base >= 8) { 2900 if ($mem$$index < 8) { 2901 emit_opcode(cbuf, Assembler::REX_WB); 2902 } else { 2903 emit_opcode(cbuf, Assembler::REX_WXB); 2904 } 2905 } else { 2906 if ($mem$$index < 8) { 2907 emit_opcode(cbuf, Assembler::REX_W); 2908 } else { 2909 emit_opcode(cbuf, Assembler::REX_WX); 2910 } 2911 } 2912 %} 2913 2914 // for byte regs 2915 enc_class REX_breg(rRegI reg) 2916 %{ 2917 if ($reg$$reg >= 4) { 2918 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2919 } 2920 %} 2921 2922 // for byte regs 2923 enc_class REX_reg_breg(rRegI dst, rRegI src) 2924 %{ 2925 if ($dst$$reg < 8) { 2926 if ($src$$reg >= 4) { 2927 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2928 } 2929 } else { 2930 if ($src$$reg < 8) { 2931 emit_opcode(cbuf, Assembler::REX_R); 2932 } else { 2933 emit_opcode(cbuf, Assembler::REX_RB); 2934 } 2935 } 2936 %} 2937 2938 // for byte regs 2939 enc_class REX_breg_mem(rRegI reg, memory mem) 2940 %{ 2941 if ($reg$$reg < 8) { 2942 if ($mem$$base < 8) { 2943 if ($mem$$index >= 8) { 2944 emit_opcode(cbuf, Assembler::REX_X); 2945 } else if ($reg$$reg >= 4) { 2946 emit_opcode(cbuf, Assembler::REX); 2947 } 2948 } else { 2949 if ($mem$$index < 8) { 2950 emit_opcode(cbuf, Assembler::REX_B); 2951 } else { 2952 emit_opcode(cbuf, Assembler::REX_XB); 2953 } 2954 } 2955 } else { 2956 if ($mem$$base < 8) { 2957 if ($mem$$index < 8) { 2958 emit_opcode(cbuf, Assembler::REX_R); 2959 } else { 2960 emit_opcode(cbuf, Assembler::REX_RX); 2961 } 2962 } else { 2963 if ($mem$$index < 8) { 2964 emit_opcode(cbuf, Assembler::REX_RB); 2965 } else { 2966 emit_opcode(cbuf, Assembler::REX_RXB); 2967 } 2968 } 2969 } 2970 %} 2971 2972 enc_class REX_reg(rRegI reg) 2973 %{ 2974 if ($reg$$reg >= 8) { 2975 emit_opcode(cbuf, Assembler::REX_B); 2976 } 2977 %} 2978 2979 enc_class REX_reg_wide(rRegI reg) 2980 %{ 2981 if ($reg$$reg < 8) { 2982 emit_opcode(cbuf, Assembler::REX_W); 2983 } else { 2984 emit_opcode(cbuf, Assembler::REX_WB); 2985 } 2986 %} 2987 2988 enc_class REX_reg_reg(rRegI dst, rRegI src) 2989 %{ 2990 if ($dst$$reg < 8) { 2991 if ($src$$reg >= 8) { 2992 emit_opcode(cbuf, Assembler::REX_B); 2993 } 2994 } else { 2995 if ($src$$reg < 8) { 2996 emit_opcode(cbuf, Assembler::REX_R); 2997 } else { 2998 emit_opcode(cbuf, Assembler::REX_RB); 2999 } 3000 } 3001 %} 3002 3003 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 3004 %{ 3005 if ($dst$$reg < 8) { 3006 if ($src$$reg < 8) { 3007 emit_opcode(cbuf, Assembler::REX_W); 3008 } else { 3009 emit_opcode(cbuf, Assembler::REX_WB); 3010 } 3011 } else { 3012 if ($src$$reg < 8) { 3013 emit_opcode(cbuf, Assembler::REX_WR); 3014 } else { 3015 emit_opcode(cbuf, Assembler::REX_WRB); 3016 } 3017 } 3018 %} 3019 3020 enc_class REX_reg_mem(rRegI reg, memory mem) 3021 %{ 3022 if ($reg$$reg < 8) { 3023 if ($mem$$base < 8) { 3024 if ($mem$$index >= 8) { 3025 emit_opcode(cbuf, Assembler::REX_X); 3026 } 3027 } else { 3028 if ($mem$$index < 8) { 3029 emit_opcode(cbuf, Assembler::REX_B); 3030 } else { 3031 emit_opcode(cbuf, Assembler::REX_XB); 3032 } 3033 } 3034 } else { 3035 if ($mem$$base < 8) { 3036 if ($mem$$index < 8) { 3037 emit_opcode(cbuf, Assembler::REX_R); 3038 } else { 3039 emit_opcode(cbuf, Assembler::REX_RX); 3040 } 3041 } else { 3042 if ($mem$$index < 8) { 3043 emit_opcode(cbuf, Assembler::REX_RB); 3044 } else { 3045 emit_opcode(cbuf, Assembler::REX_RXB); 3046 } 3047 } 3048 } 3049 %} 3050 3051 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 3052 %{ 3053 if ($reg$$reg < 8) { 3054 if ($mem$$base < 8) { 3055 if ($mem$$index < 8) { 3056 emit_opcode(cbuf, Assembler::REX_W); 3057 } else { 3058 emit_opcode(cbuf, Assembler::REX_WX); 3059 } 3060 } else { 3061 if ($mem$$index < 8) { 3062 emit_opcode(cbuf, Assembler::REX_WB); 3063 } else { 3064 emit_opcode(cbuf, Assembler::REX_WXB); 3065 } 3066 } 3067 } else { 3068 if ($mem$$base < 8) { 3069 if ($mem$$index < 8) { 3070 emit_opcode(cbuf, Assembler::REX_WR); 3071 } else { 3072 emit_opcode(cbuf, Assembler::REX_WRX); 3073 } 3074 } else { 3075 if ($mem$$index < 8) { 3076 emit_opcode(cbuf, Assembler::REX_WRB); 3077 } else { 3078 emit_opcode(cbuf, Assembler::REX_WRXB); 3079 } 3080 } 3081 } 3082 %} 3083 3084 enc_class reg_mem(rRegI ereg, memory mem) 3085 %{ 3086 // High registers handle in encode_RegMem 3087 int reg = $ereg$$reg; 3088 int base = $mem$$base; 3089 int index = $mem$$index; 3090 int scale = $mem$$scale; 3091 int disp = $mem$$disp; 3092 bool disp_is_oop = $mem->disp_is_oop(); 3093 3094 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_is_oop); 3095 %} 3096 3097 enc_class RM_opc_mem(immI rm_opcode, memory mem) 3098 %{ 3099 int rm_byte_opcode = $rm_opcode$$constant; 3100 3101 // High registers handle in encode_RegMem 3102 int base = $mem$$base; 3103 int index = $mem$$index; 3104 int scale = $mem$$scale; 3105 int displace = $mem$$disp; 3106 3107 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when 3108 // working with static 3109 // globals 3110 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 3111 disp_is_oop); 3112 %} 3113 3114 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 3115 %{ 3116 int reg_encoding = $dst$$reg; 3117 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 3118 int index = 0x04; // 0x04 indicates no index 3119 int scale = 0x00; // 0x00 indicates no scale 3120 int displace = $src1$$constant; // 0x00 indicates no displacement 3121 bool disp_is_oop = false; 3122 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 3123 disp_is_oop); 3124 %} 3125 3126 enc_class neg_reg(rRegI dst) 3127 %{ 3128 int dstenc = $dst$$reg; 3129 if (dstenc >= 8) { 3130 emit_opcode(cbuf, Assembler::REX_B); 3131 dstenc -= 8; 3132 } 3133 // NEG $dst 3134 emit_opcode(cbuf, 0xF7); 3135 emit_rm(cbuf, 0x3, 0x03, dstenc); 3136 %} 3137 3138 enc_class neg_reg_wide(rRegI dst) 3139 %{ 3140 int dstenc = $dst$$reg; 3141 if (dstenc < 8) { 3142 emit_opcode(cbuf, Assembler::REX_W); 3143 } else { 3144 emit_opcode(cbuf, Assembler::REX_WB); 3145 dstenc -= 8; 3146 } 3147 // NEG $dst 3148 emit_opcode(cbuf, 0xF7); 3149 emit_rm(cbuf, 0x3, 0x03, dstenc); 3150 %} 3151 3152 enc_class setLT_reg(rRegI dst) 3153 %{ 3154 int dstenc = $dst$$reg; 3155 if (dstenc >= 8) { 3156 emit_opcode(cbuf, Assembler::REX_B); 3157 dstenc -= 8; 3158 } else if (dstenc >= 4) { 3159 emit_opcode(cbuf, Assembler::REX); 3160 } 3161 // SETLT $dst 3162 emit_opcode(cbuf, 0x0F); 3163 emit_opcode(cbuf, 0x9C); 3164 emit_rm(cbuf, 0x3, 0x0, dstenc); 3165 %} 3166 3167 enc_class setNZ_reg(rRegI dst) 3168 %{ 3169 int dstenc = $dst$$reg; 3170 if (dstenc >= 8) { 3171 emit_opcode(cbuf, Assembler::REX_B); 3172 dstenc -= 8; 3173 } else if (dstenc >= 4) { 3174 emit_opcode(cbuf, Assembler::REX); 3175 } 3176 // SETNZ $dst 3177 emit_opcode(cbuf, 0x0F); 3178 emit_opcode(cbuf, 0x95); 3179 emit_rm(cbuf, 0x3, 0x0, dstenc); 3180 %} 3181 3182 3183 // Compare the lonogs and set -1, 0, or 1 into dst 3184 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 3185 %{ 3186 int src1enc = $src1$$reg; 3187 int src2enc = $src2$$reg; 3188 int dstenc = $dst$$reg; 3189 3190 // cmpq $src1, $src2 3191 if (src1enc < 8) { 3192 if (src2enc < 8) { 3193 emit_opcode(cbuf, Assembler::REX_W); 3194 } else { 3195 emit_opcode(cbuf, Assembler::REX_WB); 3196 } 3197 } else { 3198 if (src2enc < 8) { 3199 emit_opcode(cbuf, Assembler::REX_WR); 3200 } else { 3201 emit_opcode(cbuf, Assembler::REX_WRB); 3202 } 3203 } 3204 emit_opcode(cbuf, 0x3B); 3205 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 3206 3207 // movl $dst, -1 3208 if (dstenc >= 8) { 3209 emit_opcode(cbuf, Assembler::REX_B); 3210 } 3211 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 3212 emit_d32(cbuf, -1); 3213 3214 // jl,s done 3215 emit_opcode(cbuf, 0x7C); 3216 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 3217 3218 // setne $dst 3219 if (dstenc >= 4) { 3220 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 3221 } 3222 emit_opcode(cbuf, 0x0F); 3223 emit_opcode(cbuf, 0x95); 3224 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 3225 3226 // movzbl $dst, $dst 3227 if (dstenc >= 4) { 3228 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 3229 } 3230 emit_opcode(cbuf, 0x0F); 3231 emit_opcode(cbuf, 0xB6); 3232 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 3233 %} 3234 3235 enc_class Push_ResultXD(regD dst) %{ 3236 int dstenc = $dst$$reg; 3237 3238 store_to_stackslot( cbuf, 0xDD, 0x03, 0 ); //FSTP [RSP] 3239 3240 // UseXmmLoadAndClearUpper ? movsd dst,[rsp] : movlpd dst,[rsp] 3241 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 3242 if (dstenc >= 8) { 3243 emit_opcode(cbuf, Assembler::REX_R); 3244 } 3245 emit_opcode (cbuf, 0x0F ); 3246 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12 ); 3247 encode_RegMem(cbuf, dstenc, RSP_enc, 0x4, 0, 0, false); 3248 3249 // add rsp,8 3250 emit_opcode(cbuf, Assembler::REX_W); 3251 emit_opcode(cbuf,0x83); 3252 emit_rm(cbuf,0x3, 0x0, RSP_enc); 3253 emit_d8(cbuf,0x08); 3254 %} 3255 3256 enc_class Push_SrcXD(regD src) %{ 3257 int srcenc = $src$$reg; 3258 3259 // subq rsp,#8 3260 emit_opcode(cbuf, Assembler::REX_W); 3261 emit_opcode(cbuf, 0x83); 3262 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3263 emit_d8(cbuf, 0x8); 3264 3265 // movsd [rsp],src 3266 emit_opcode(cbuf, 0xF2); 3267 if (srcenc >= 8) { 3268 emit_opcode(cbuf, Assembler::REX_R); 3269 } 3270 emit_opcode(cbuf, 0x0F); 3271 emit_opcode(cbuf, 0x11); 3272 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); 3273 3274 // fldd [rsp] 3275 emit_opcode(cbuf, 0x66); 3276 emit_opcode(cbuf, 0xDD); 3277 encode_RegMem(cbuf, 0x0, RSP_enc, 0x4, 0, 0, false); 3278 %} 3279 3280 3281 enc_class movq_ld(regD dst, memory mem) %{ 3282 MacroAssembler _masm(&cbuf); 3283 __ movq($dst$$XMMRegister, $mem$$Address); 3284 %} 3285 3286 enc_class movq_st(memory mem, regD src) %{ 3287 MacroAssembler _masm(&cbuf); 3288 __ movq($mem$$Address, $src$$XMMRegister); 3289 %} 3290 3291 enc_class pshufd_8x8(regF dst, regF src) %{ 3292 MacroAssembler _masm(&cbuf); 3293 3294 encode_CopyXD(cbuf, $dst$$reg, $src$$reg); 3295 __ punpcklbw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg)); 3296 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg), 0x00); 3297 %} 3298 3299 enc_class pshufd_4x16(regF dst, regF src) %{ 3300 MacroAssembler _masm(&cbuf); 3301 3302 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), 0x00); 3303 %} 3304 3305 enc_class pshufd(regD dst, regD src, int mode) %{ 3306 MacroAssembler _masm(&cbuf); 3307 3308 __ pshufd(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), $mode); 3309 %} 3310 3311 enc_class pxor(regD dst, regD src) %{ 3312 MacroAssembler _masm(&cbuf); 3313 3314 __ pxor(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg)); 3315 %} 3316 3317 enc_class mov_i2x(regD dst, rRegI src) %{ 3318 MacroAssembler _masm(&cbuf); 3319 3320 __ movdl(as_XMMRegister($dst$$reg), as_Register($src$$reg)); 3321 %} 3322 3323 // obj: object to lock 3324 // box: box address (header location) -- killed 3325 // tmp: rax -- killed 3326 // scr: rbx -- killed 3327 // 3328 // What follows is a direct transliteration of fast_lock() and fast_unlock() 3329 // from i486.ad. See that file for comments. 3330 // TODO: where possible switch from movq (r, 0) to movl(r,0) and 3331 // use the shorter encoding. (Movl clears the high-order 32-bits). 3332 3333 3334 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr) 3335 %{ 3336 Register objReg = as_Register((int)$obj$$reg); 3337 Register boxReg = as_Register((int)$box$$reg); 3338 Register tmpReg = as_Register($tmp$$reg); 3339 Register scrReg = as_Register($scr$$reg); 3340 MacroAssembler masm(&cbuf); 3341 3342 // Verify uniqueness of register assignments -- necessary but not sufficient 3343 assert (objReg != boxReg && objReg != tmpReg && 3344 objReg != scrReg && tmpReg != scrReg, "invariant") ; 3345 3346 if (_counters != NULL) { 3347 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 3348 } 3349 if (EmitSync & 1) { 3350 // Without cast to int32_t a movptr will destroy r10 which is typically obj 3351 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 3352 masm.cmpptr(rsp, (int32_t)NULL_WORD) ; 3353 } else 3354 if (EmitSync & 2) { 3355 Label DONE_LABEL; 3356 if (UseBiasedLocking) { 3357 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 3358 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 3359 } 3360 // QQQ was movl... 3361 masm.movptr(tmpReg, 0x1); 3362 masm.orptr(tmpReg, Address(objReg, 0)); 3363 masm.movptr(Address(boxReg, 0), tmpReg); 3364 if (os::is_MP()) { 3365 masm.lock(); 3366 } 3367 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3368 masm.jcc(Assembler::equal, DONE_LABEL); 3369 3370 // Recursive locking 3371 masm.subptr(tmpReg, rsp); 3372 masm.andptr(tmpReg, 7 - os::vm_page_size()); 3373 masm.movptr(Address(boxReg, 0), tmpReg); 3374 3375 masm.bind(DONE_LABEL); 3376 masm.nop(); // avoid branch to branch 3377 } else { 3378 Label DONE_LABEL, IsInflated, Egress; 3379 3380 masm.movptr(tmpReg, Address(objReg, 0)) ; 3381 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased 3382 masm.jcc (Assembler::notZero, IsInflated) ; 3383 3384 // it's stack-locked, biased or neutral 3385 // TODO: optimize markword triage order to reduce the number of 3386 // conditional branches in the most common cases. 3387 // Beware -- there's a subtle invariant that fetch of the markword 3388 // at [FETCH], below, will never observe a biased encoding (*101b). 3389 // If this invariant is not held we'll suffer exclusion (safety) failure. 3390 3391 if (UseBiasedLocking && !UseOptoBiasInlining) { 3392 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); 3393 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 3394 } 3395 3396 // was q will it destroy high? 3397 masm.orl (tmpReg, 1) ; 3398 masm.movptr(Address(boxReg, 0), tmpReg) ; 3399 if (os::is_MP()) { masm.lock(); } 3400 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3401 if (_counters != NULL) { 3402 masm.cond_inc32(Assembler::equal, 3403 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 3404 } 3405 masm.jcc (Assembler::equal, DONE_LABEL); 3406 3407 // Recursive locking 3408 masm.subptr(tmpReg, rsp); 3409 masm.andptr(tmpReg, 7 - os::vm_page_size()); 3410 masm.movptr(Address(boxReg, 0), tmpReg); 3411 if (_counters != NULL) { 3412 masm.cond_inc32(Assembler::equal, 3413 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 3414 } 3415 masm.jmp (DONE_LABEL) ; 3416 3417 masm.bind (IsInflated) ; 3418 // It's inflated 3419 3420 // TODO: someday avoid the ST-before-CAS penalty by 3421 // relocating (deferring) the following ST. 3422 // We should also think about trying a CAS without having 3423 // fetched _owner. If the CAS is successful we may 3424 // avoid an RTO->RTS upgrade on the $line. 3425 // Without cast to int32_t a movptr will destroy r10 which is typically obj 3426 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 3427 3428 masm.mov (boxReg, tmpReg) ; 3429 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3430 masm.testptr(tmpReg, tmpReg) ; 3431 masm.jcc (Assembler::notZero, DONE_LABEL) ; 3432 3433 // It's inflated and appears unlocked 3434 if (os::is_MP()) { masm.lock(); } 3435 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3436 // Intentional fall-through into DONE_LABEL ... 3437 3438 masm.bind (DONE_LABEL) ; 3439 masm.nop () ; // avoid jmp to jmp 3440 } 3441 %} 3442 3443 // obj: object to unlock 3444 // box: box address (displaced header location), killed 3445 // RBX: killed tmp; cannot be obj nor box 3446 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp) 3447 %{ 3448 3449 Register objReg = as_Register($obj$$reg); 3450 Register boxReg = as_Register($box$$reg); 3451 Register tmpReg = as_Register($tmp$$reg); 3452 MacroAssembler masm(&cbuf); 3453 3454 if (EmitSync & 4) { 3455 masm.cmpptr(rsp, 0) ; 3456 } else 3457 if (EmitSync & 8) { 3458 Label DONE_LABEL; 3459 if (UseBiasedLocking) { 3460 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3461 } 3462 3463 // Check whether the displaced header is 0 3464 //(=> recursive unlock) 3465 masm.movptr(tmpReg, Address(boxReg, 0)); 3466 masm.testptr(tmpReg, tmpReg); 3467 masm.jcc(Assembler::zero, DONE_LABEL); 3468 3469 // If not recursive lock, reset the header to displaced header 3470 if (os::is_MP()) { 3471 masm.lock(); 3472 } 3473 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3474 masm.bind(DONE_LABEL); 3475 masm.nop(); // avoid branch to branch 3476 } else { 3477 Label DONE_LABEL, Stacked, CheckSucc ; 3478 3479 if (UseBiasedLocking && !UseOptoBiasInlining) { 3480 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3481 } 3482 3483 masm.movptr(tmpReg, Address(objReg, 0)) ; 3484 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; 3485 masm.jcc (Assembler::zero, DONE_LABEL) ; 3486 masm.testl (tmpReg, 0x02) ; 3487 masm.jcc (Assembler::zero, Stacked) ; 3488 3489 // It's inflated 3490 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3491 masm.xorptr(boxReg, r15_thread) ; 3492 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 3493 masm.jcc (Assembler::notZero, DONE_LABEL) ; 3494 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 3495 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 3496 masm.jcc (Assembler::notZero, CheckSucc) ; 3497 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3498 masm.jmp (DONE_LABEL) ; 3499 3500 if ((EmitSync & 65536) == 0) { 3501 Label LSuccess, LGoSlowPath ; 3502 masm.bind (CheckSucc) ; 3503 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3504 masm.jcc (Assembler::zero, LGoSlowPath) ; 3505 3506 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the 3507 // the explicit ST;MEMBAR combination, but masm doesn't currently support 3508 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc 3509 // are all faster when the write buffer is populated. 3510 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3511 if (os::is_MP()) { 3512 masm.lock () ; masm.addl (Address(rsp, 0), 0) ; 3513 } 3514 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3515 masm.jcc (Assembler::notZero, LSuccess) ; 3516 3517 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX 3518 if (os::is_MP()) { masm.lock(); } 3519 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3520 masm.jcc (Assembler::notEqual, LSuccess) ; 3521 // Intentional fall-through into slow-path 3522 3523 masm.bind (LGoSlowPath) ; 3524 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure 3525 masm.jmp (DONE_LABEL) ; 3526 3527 masm.bind (LSuccess) ; 3528 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success 3529 masm.jmp (DONE_LABEL) ; 3530 } 3531 3532 masm.bind (Stacked) ; 3533 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch 3534 if (os::is_MP()) { masm.lock(); } 3535 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3536 3537 if (EmitSync & 65536) { 3538 masm.bind (CheckSucc) ; 3539 } 3540 masm.bind(DONE_LABEL); 3541 if (EmitSync & 32768) { 3542 masm.nop(); // avoid branch to branch 3543 } 3544 } 3545 %} 3546 3547 3548 enc_class enc_rethrow() 3549 %{ 3550 cbuf.set_insts_mark(); 3551 emit_opcode(cbuf, 0xE9); // jmp entry 3552 emit_d32_reloc(cbuf, 3553 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 3554 runtime_call_Relocation::spec(), 3555 RELOC_DISP32); 3556 %} 3557 3558 enc_class absF_encoding(regF dst) 3559 %{ 3560 int dstenc = $dst$$reg; 3561 address signmask_address = (address) StubRoutines::x86::float_sign_mask(); 3562 3563 cbuf.set_insts_mark(); 3564 if (dstenc >= 8) { 3565 emit_opcode(cbuf, Assembler::REX_R); 3566 dstenc -= 8; 3567 } 3568 // XXX reg_mem doesn't support RIP-relative addressing yet 3569 emit_opcode(cbuf, 0x0F); 3570 emit_opcode(cbuf, 0x54); 3571 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3572 emit_d32_reloc(cbuf, signmask_address); 3573 %} 3574 3575 enc_class absD_encoding(regD dst) 3576 %{ 3577 int dstenc = $dst$$reg; 3578 address signmask_address = (address) StubRoutines::x86::double_sign_mask(); 3579 3580 cbuf.set_insts_mark(); 3581 emit_opcode(cbuf, 0x66); 3582 if (dstenc >= 8) { 3583 emit_opcode(cbuf, Assembler::REX_R); 3584 dstenc -= 8; 3585 } 3586 // XXX reg_mem doesn't support RIP-relative addressing yet 3587 emit_opcode(cbuf, 0x0F); 3588 emit_opcode(cbuf, 0x54); 3589 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3590 emit_d32_reloc(cbuf, signmask_address); 3591 %} 3592 3593 enc_class negF_encoding(regF dst) 3594 %{ 3595 int dstenc = $dst$$reg; 3596 address signflip_address = (address) StubRoutines::x86::float_sign_flip(); 3597 3598 cbuf.set_insts_mark(); 3599 if (dstenc >= 8) { 3600 emit_opcode(cbuf, Assembler::REX_R); 3601 dstenc -= 8; 3602 } 3603 // XXX reg_mem doesn't support RIP-relative addressing yet 3604 emit_opcode(cbuf, 0x0F); 3605 emit_opcode(cbuf, 0x57); 3606 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3607 emit_d32_reloc(cbuf, signflip_address); 3608 %} 3609 3610 enc_class negD_encoding(regD dst) 3611 %{ 3612 int dstenc = $dst$$reg; 3613 address signflip_address = (address) StubRoutines::x86::double_sign_flip(); 3614 3615 cbuf.set_insts_mark(); 3616 emit_opcode(cbuf, 0x66); 3617 if (dstenc >= 8) { 3618 emit_opcode(cbuf, Assembler::REX_R); 3619 dstenc -= 8; 3620 } 3621 // XXX reg_mem doesn't support RIP-relative addressing yet 3622 emit_opcode(cbuf, 0x0F); 3623 emit_opcode(cbuf, 0x57); 3624 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3625 emit_d32_reloc(cbuf, signflip_address); 3626 %} 3627 3628 enc_class f2i_fixup(rRegI dst, regF src) 3629 %{ 3630 int dstenc = $dst$$reg; 3631 int srcenc = $src$$reg; 3632 3633 // cmpl $dst, #0x80000000 3634 if (dstenc >= 8) { 3635 emit_opcode(cbuf, Assembler::REX_B); 3636 } 3637 emit_opcode(cbuf, 0x81); 3638 emit_rm(cbuf, 0x3, 0x7, dstenc & 7); 3639 emit_d32(cbuf, 0x80000000); 3640 3641 // jne,s done 3642 emit_opcode(cbuf, 0x75); 3643 if (srcenc < 8 && dstenc < 8) { 3644 emit_d8(cbuf, 0xF); 3645 } else if (srcenc >= 8 && dstenc >= 8) { 3646 emit_d8(cbuf, 0x11); 3647 } else { 3648 emit_d8(cbuf, 0x10); 3649 } 3650 3651 // subq rsp, #8 3652 emit_opcode(cbuf, Assembler::REX_W); 3653 emit_opcode(cbuf, 0x83); 3654 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3655 emit_d8(cbuf, 8); 3656 3657 // movss [rsp], $src 3658 emit_opcode(cbuf, 0xF3); 3659 if (srcenc >= 8) { 3660 emit_opcode(cbuf, Assembler::REX_R); 3661 } 3662 emit_opcode(cbuf, 0x0F); 3663 emit_opcode(cbuf, 0x11); 3664 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 3665 3666 // call f2i_fixup 3667 cbuf.set_insts_mark(); 3668 emit_opcode(cbuf, 0xE8); 3669 emit_d32_reloc(cbuf, 3670 (int) 3671 (StubRoutines::x86::f2i_fixup() - cbuf.insts_end() - 4), 3672 runtime_call_Relocation::spec(), 3673 RELOC_DISP32); 3674 3675 // popq $dst 3676 if (dstenc >= 8) { 3677 emit_opcode(cbuf, Assembler::REX_B); 3678 } 3679 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 3680 3681 // done: 3682 %} 3683 3684 enc_class f2l_fixup(rRegL dst, regF src) 3685 %{ 3686 int dstenc = $dst$$reg; 3687 int srcenc = $src$$reg; 3688 address const_address = (address) StubRoutines::x86::double_sign_flip(); 3689 3690 // cmpq $dst, [0x8000000000000000] 3691 cbuf.set_insts_mark(); 3692 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR); 3693 emit_opcode(cbuf, 0x39); 3694 // XXX reg_mem doesn't support RIP-relative addressing yet 3695 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101 3696 emit_d32_reloc(cbuf, const_address); 3697 3698 3699 // jne,s done 3700 emit_opcode(cbuf, 0x75); 3701 if (srcenc < 8 && dstenc < 8) { 3702 emit_d8(cbuf, 0xF); 3703 } else if (srcenc >= 8 && dstenc >= 8) { 3704 emit_d8(cbuf, 0x11); 3705 } else { 3706 emit_d8(cbuf, 0x10); 3707 } 3708 3709 // subq rsp, #8 3710 emit_opcode(cbuf, Assembler::REX_W); 3711 emit_opcode(cbuf, 0x83); 3712 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3713 emit_d8(cbuf, 8); 3714 3715 // movss [rsp], $src 3716 emit_opcode(cbuf, 0xF3); 3717 if (srcenc >= 8) { 3718 emit_opcode(cbuf, Assembler::REX_R); 3719 } 3720 emit_opcode(cbuf, 0x0F); 3721 emit_opcode(cbuf, 0x11); 3722 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 3723 3724 // call f2l_fixup 3725 cbuf.set_insts_mark(); 3726 emit_opcode(cbuf, 0xE8); 3727 emit_d32_reloc(cbuf, 3728 (int) 3729 (StubRoutines::x86::f2l_fixup() - cbuf.insts_end() - 4), 3730 runtime_call_Relocation::spec(), 3731 RELOC_DISP32); 3732 3733 // popq $dst 3734 if (dstenc >= 8) { 3735 emit_opcode(cbuf, Assembler::REX_B); 3736 } 3737 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 3738 3739 // done: 3740 %} 3741 3742 enc_class d2i_fixup(rRegI dst, regD src) 3743 %{ 3744 int dstenc = $dst$$reg; 3745 int srcenc = $src$$reg; 3746 3747 // cmpl $dst, #0x80000000 3748 if (dstenc >= 8) { 3749 emit_opcode(cbuf, Assembler::REX_B); 3750 } 3751 emit_opcode(cbuf, 0x81); 3752 emit_rm(cbuf, 0x3, 0x7, dstenc & 7); 3753 emit_d32(cbuf, 0x80000000); 3754 3755 // jne,s done 3756 emit_opcode(cbuf, 0x75); 3757 if (srcenc < 8 && dstenc < 8) { 3758 emit_d8(cbuf, 0xF); 3759 } else if (srcenc >= 8 && dstenc >= 8) { 3760 emit_d8(cbuf, 0x11); 3761 } else { 3762 emit_d8(cbuf, 0x10); 3763 } 3764 3765 // subq rsp, #8 3766 emit_opcode(cbuf, Assembler::REX_W); 3767 emit_opcode(cbuf, 0x83); 3768 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3769 emit_d8(cbuf, 8); 3770 3771 // movsd [rsp], $src 3772 emit_opcode(cbuf, 0xF2); 3773 if (srcenc >= 8) { 3774 emit_opcode(cbuf, Assembler::REX_R); 3775 } 3776 emit_opcode(cbuf, 0x0F); 3777 emit_opcode(cbuf, 0x11); 3778 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 3779 3780 // call d2i_fixup 3781 cbuf.set_insts_mark(); 3782 emit_opcode(cbuf, 0xE8); 3783 emit_d32_reloc(cbuf, 3784 (int) 3785 (StubRoutines::x86::d2i_fixup() - cbuf.insts_end() - 4), 3786 runtime_call_Relocation::spec(), 3787 RELOC_DISP32); 3788 3789 // popq $dst 3790 if (dstenc >= 8) { 3791 emit_opcode(cbuf, Assembler::REX_B); 3792 } 3793 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 3794 3795 // done: 3796 %} 3797 3798 enc_class d2l_fixup(rRegL dst, regD src) 3799 %{ 3800 int dstenc = $dst$$reg; 3801 int srcenc = $src$$reg; 3802 address const_address = (address) StubRoutines::x86::double_sign_flip(); 3803 3804 // cmpq $dst, [0x8000000000000000] 3805 cbuf.set_insts_mark(); 3806 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR); 3807 emit_opcode(cbuf, 0x39); 3808 // XXX reg_mem doesn't support RIP-relative addressing yet 3809 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101 3810 emit_d32_reloc(cbuf, const_address); 3811 3812 3813 // jne,s done 3814 emit_opcode(cbuf, 0x75); 3815 if (srcenc < 8 && dstenc < 8) { 3816 emit_d8(cbuf, 0xF); 3817 } else if (srcenc >= 8 && dstenc >= 8) { 3818 emit_d8(cbuf, 0x11); 3819 } else { 3820 emit_d8(cbuf, 0x10); 3821 } 3822 3823 // subq rsp, #8 3824 emit_opcode(cbuf, Assembler::REX_W); 3825 emit_opcode(cbuf, 0x83); 3826 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3827 emit_d8(cbuf, 8); 3828 3829 // movsd [rsp], $src 3830 emit_opcode(cbuf, 0xF2); 3831 if (srcenc >= 8) { 3832 emit_opcode(cbuf, Assembler::REX_R); 3833 } 3834 emit_opcode(cbuf, 0x0F); 3835 emit_opcode(cbuf, 0x11); 3836 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 3837 3838 // call d2l_fixup 3839 cbuf.set_insts_mark(); 3840 emit_opcode(cbuf, 0xE8); 3841 emit_d32_reloc(cbuf, 3842 (int) 3843 (StubRoutines::x86::d2l_fixup() - cbuf.insts_end() - 4), 3844 runtime_call_Relocation::spec(), 3845 RELOC_DISP32); 3846 3847 // popq $dst 3848 if (dstenc >= 8) { 3849 emit_opcode(cbuf, Assembler::REX_B); 3850 } 3851 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 3852 3853 // done: 3854 %} 3855 %} 3856 3857 3858 3859 //----------FRAME-------------------------------------------------------------- 3860 // Definition of frame structure and management information. 3861 // 3862 // S T A C K L A Y O U T Allocators stack-slot number 3863 // | (to get allocators register number 3864 // G Owned by | | v add OptoReg::stack0()) 3865 // r CALLER | | 3866 // o | +--------+ pad to even-align allocators stack-slot 3867 // w V | pad0 | numbers; owned by CALLER 3868 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3869 // h ^ | in | 5 3870 // | | args | 4 Holes in incoming args owned by SELF 3871 // | | | | 3 3872 // | | +--------+ 3873 // V | | old out| Empty on Intel, window on Sparc 3874 // | old |preserve| Must be even aligned. 3875 // | SP-+--------+----> Matcher::_old_SP, even aligned 3876 // | | in | 3 area for Intel ret address 3877 // Owned by |preserve| Empty on Sparc. 3878 // SELF +--------+ 3879 // | | pad2 | 2 pad to align old SP 3880 // | +--------+ 1 3881 // | | locks | 0 3882 // | +--------+----> OptoReg::stack0(), even aligned 3883 // | | pad1 | 11 pad to align new SP 3884 // | +--------+ 3885 // | | | 10 3886 // | | spills | 9 spills 3887 // V | | 8 (pad0 slot for callee) 3888 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3889 // ^ | out | 7 3890 // | | args | 6 Holes in outgoing args owned by CALLEE 3891 // Owned by +--------+ 3892 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3893 // | new |preserve| Must be even-aligned. 3894 // | SP-+--------+----> Matcher::_new_SP, even aligned 3895 // | | | 3896 // 3897 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3898 // known from SELF's arguments and the Java calling convention. 3899 // Region 6-7 is determined per call site. 3900 // Note 2: If the calling convention leaves holes in the incoming argument 3901 // area, those holes are owned by SELF. Holes in the outgoing area 3902 // are owned by the CALLEE. Holes should not be nessecary in the 3903 // incoming area, as the Java calling convention is completely under 3904 // the control of the AD file. Doubles can be sorted and packed to 3905 // avoid holes. Holes in the outgoing arguments may be nessecary for 3906 // varargs C calling conventions. 3907 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3908 // even aligned with pad0 as needed. 3909 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3910 // region 6-11 is even aligned; it may be padded out more so that 3911 // the region from SP to FP meets the minimum stack alignment. 3912 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3913 // alignment. Region 11, pad1, may be dynamically extended so that 3914 // SP meets the minimum alignment. 3915 3916 frame 3917 %{ 3918 // What direction does stack grow in (assumed to be same for C & Java) 3919 stack_direction(TOWARDS_LOW); 3920 3921 // These three registers define part of the calling convention 3922 // between compiled code and the interpreter. 3923 inline_cache_reg(RAX); // Inline Cache Register 3924 interpreter_method_oop_reg(RBX); // Method Oop Register when 3925 // calling interpreter 3926 3927 // Optional: name the operand used by cisc-spilling to access 3928 // [stack_pointer + offset] 3929 cisc_spilling_operand_name(indOffset32); 3930 3931 // Number of stack slots consumed by locking an object 3932 sync_stack_slots(2); 3933 3934 // Compiled code's Frame Pointer 3935 frame_pointer(RSP); 3936 3937 // Interpreter stores its frame pointer in a register which is 3938 // stored to the stack by I2CAdaptors. 3939 // I2CAdaptors convert from interpreted java to compiled java. 3940 interpreter_frame_pointer(RBP); 3941 3942 // Stack alignment requirement 3943 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3944 3945 // Number of stack slots between incoming argument block and the start of 3946 // a new frame. The PROLOG must add this many slots to the stack. The 3947 // EPILOG must remove this many slots. amd64 needs two slots for 3948 // return address. 3949 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 3950 3951 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3952 // for calls to C. Supports the var-args backing area for register parms. 3953 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3954 3955 // The after-PROLOG location of the return address. Location of 3956 // return address specifies a type (REG or STACK) and a number 3957 // representing the register number (i.e. - use a register name) or 3958 // stack slot. 3959 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3960 // Otherwise, it is above the locks and verification slot and alignment word 3961 return_addr(STACK - 2 + 3962 round_to(2 + 2 * VerifyStackAtCalls + 3963 Compile::current()->fixed_slots(), 3964 WordsPerLong * 2)); 3965 3966 // Body of function which returns an integer array locating 3967 // arguments either in registers or in stack slots. Passed an array 3968 // of ideal registers called "sig" and a "length" count. Stack-slot 3969 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3970 // arguments for a CALLEE. Incoming stack arguments are 3971 // automatically biased by the preserve_stack_slots field above. 3972 3973 calling_convention 3974 %{ 3975 // No difference between ingoing/outgoing just pass false 3976 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3977 %} 3978 3979 c_calling_convention 3980 %{ 3981 // This is obviously always outgoing 3982 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); 3983 %} 3984 3985 // Location of compiled Java return values. Same as C for now. 3986 return_value 3987 %{ 3988 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3989 "only return normal values"); 3990 3991 static const int lo[Op_RegL + 1] = { 3992 0, 3993 0, 3994 RAX_num, // Op_RegN 3995 RAX_num, // Op_RegI 3996 RAX_num, // Op_RegP 3997 XMM0_num, // Op_RegF 3998 XMM0_num, // Op_RegD 3999 RAX_num // Op_RegL 4000 }; 4001 static const int hi[Op_RegL + 1] = { 4002 0, 4003 0, 4004 OptoReg::Bad, // Op_RegN 4005 OptoReg::Bad, // Op_RegI 4006 RAX_H_num, // Op_RegP 4007 OptoReg::Bad, // Op_RegF 4008 XMM0_H_num, // Op_RegD 4009 RAX_H_num // Op_RegL 4010 }; 4011 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 1, "missing type"); 4012 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 4013 %} 4014 %} 4015 4016 //----------ATTRIBUTES--------------------------------------------------------- 4017 //----------Operand Attributes------------------------------------------------- 4018 op_attrib op_cost(0); // Required cost attribute 4019 4020 //----------Instruction Attributes--------------------------------------------- 4021 ins_attrib ins_cost(100); // Required cost attribute 4022 ins_attrib ins_size(8); // Required size attribute (in bits) 4023 ins_attrib ins_pc_relative(0); // Required PC Relative flag 4024 ins_attrib ins_short_branch(0); // Required flag: is this instruction 4025 // a non-matching short branch variant 4026 // of some long branch? 4027 ins_attrib ins_alignment(1); // Required alignment attribute (must 4028 // be a power of 2) specifies the 4029 // alignment that some part of the 4030 // instruction (not necessarily the 4031 // start) requires. If > 1, a 4032 // compute_padding() function must be 4033 // provided for the instruction 4034 4035 //----------OPERANDS----------------------------------------------------------- 4036 // Operand definitions must precede instruction definitions for correct parsing 4037 // in the ADLC because operands constitute user defined types which are used in 4038 // instruction definitions. 4039 4040 //----------Simple Operands---------------------------------------------------- 4041 // Immediate Operands 4042 // Integer Immediate 4043 operand immI() 4044 %{ 4045 match(ConI); 4046 4047 op_cost(10); 4048 format %{ %} 4049 interface(CONST_INTER); 4050 %} 4051 4052 // Constant for test vs zero 4053 operand immI0() 4054 %{ 4055 predicate(n->get_int() == 0); 4056 match(ConI); 4057 4058 op_cost(0); 4059 format %{ %} 4060 interface(CONST_INTER); 4061 %} 4062 4063 // Constant for increment 4064 operand immI1() 4065 %{ 4066 predicate(n->get_int() == 1); 4067 match(ConI); 4068 4069 op_cost(0); 4070 format %{ %} 4071 interface(CONST_INTER); 4072 %} 4073 4074 // Constant for decrement 4075 operand immI_M1() 4076 %{ 4077 predicate(n->get_int() == -1); 4078 match(ConI); 4079 4080 op_cost(0); 4081 format %{ %} 4082 interface(CONST_INTER); 4083 %} 4084 4085 // Valid scale values for addressing modes 4086 operand immI2() 4087 %{ 4088 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4089 match(ConI); 4090 4091 format %{ %} 4092 interface(CONST_INTER); 4093 %} 4094 4095 operand immI8() 4096 %{ 4097 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 4098 match(ConI); 4099 4100 op_cost(5); 4101 format %{ %} 4102 interface(CONST_INTER); 4103 %} 4104 4105 operand immI16() 4106 %{ 4107 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 4108 match(ConI); 4109 4110 op_cost(10); 4111 format %{ %} 4112 interface(CONST_INTER); 4113 %} 4114 4115 // Constant for long shifts 4116 operand immI_32() 4117 %{ 4118 predicate( n->get_int() == 32 ); 4119 match(ConI); 4120 4121 op_cost(0); 4122 format %{ %} 4123 interface(CONST_INTER); 4124 %} 4125 4126 // Constant for long shifts 4127 operand immI_64() 4128 %{ 4129 predicate( n->get_int() == 64 ); 4130 match(ConI); 4131 4132 op_cost(0); 4133 format %{ %} 4134 interface(CONST_INTER); 4135 %} 4136 4137 // Pointer Immediate 4138 operand immP() 4139 %{ 4140 match(ConP); 4141 4142 op_cost(10); 4143 format %{ %} 4144 interface(CONST_INTER); 4145 %} 4146 4147 // NULL Pointer Immediate 4148 operand immP0() 4149 %{ 4150 predicate(n->get_ptr() == 0); 4151 match(ConP); 4152 4153 op_cost(5); 4154 format %{ %} 4155 interface(CONST_INTER); 4156 %} 4157 4158 operand immP_poll() %{ 4159 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page()); 4160 match(ConP); 4161 4162 // formats are generated automatically for constants and base registers 4163 format %{ %} 4164 interface(CONST_INTER); 4165 %} 4166 4167 // Pointer Immediate 4168 operand immN() %{ 4169 match(ConN); 4170 4171 op_cost(10); 4172 format %{ %} 4173 interface(CONST_INTER); 4174 %} 4175 4176 // NULL Pointer Immediate 4177 operand immN0() %{ 4178 predicate(n->get_narrowcon() == 0); 4179 match(ConN); 4180 4181 op_cost(5); 4182 format %{ %} 4183 interface(CONST_INTER); 4184 %} 4185 4186 operand immP31() 4187 %{ 4188 predicate(!n->as_Type()->type()->isa_oopptr() 4189 && (n->get_ptr() >> 31) == 0); 4190 match(ConP); 4191 4192 op_cost(5); 4193 format %{ %} 4194 interface(CONST_INTER); 4195 %} 4196 4197 4198 // Long Immediate 4199 operand immL() 4200 %{ 4201 match(ConL); 4202 4203 op_cost(20); 4204 format %{ %} 4205 interface(CONST_INTER); 4206 %} 4207 4208 // Long Immediate 8-bit 4209 operand immL8() 4210 %{ 4211 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 4212 match(ConL); 4213 4214 op_cost(5); 4215 format %{ %} 4216 interface(CONST_INTER); 4217 %} 4218 4219 // Long Immediate 32-bit unsigned 4220 operand immUL32() 4221 %{ 4222 predicate(n->get_long() == (unsigned int) (n->get_long())); 4223 match(ConL); 4224 4225 op_cost(10); 4226 format %{ %} 4227 interface(CONST_INTER); 4228 %} 4229 4230 // Long Immediate 32-bit signed 4231 operand immL32() 4232 %{ 4233 predicate(n->get_long() == (int) (n->get_long())); 4234 match(ConL); 4235 4236 op_cost(15); 4237 format %{ %} 4238 interface(CONST_INTER); 4239 %} 4240 4241 // Long Immediate zero 4242 operand immL0() 4243 %{ 4244 predicate(n->get_long() == 0L); 4245 match(ConL); 4246 4247 op_cost(10); 4248 format %{ %} 4249 interface(CONST_INTER); 4250 %} 4251 4252 // Constant for increment 4253 operand immL1() 4254 %{ 4255 predicate(n->get_long() == 1); 4256 match(ConL); 4257 4258 format %{ %} 4259 interface(CONST_INTER); 4260 %} 4261 4262 // Constant for decrement 4263 operand immL_M1() 4264 %{ 4265 predicate(n->get_long() == -1); 4266 match(ConL); 4267 4268 format %{ %} 4269 interface(CONST_INTER); 4270 %} 4271 4272 // Long Immediate: the value 10 4273 operand immL10() 4274 %{ 4275 predicate(n->get_long() == 10); 4276 match(ConL); 4277 4278 format %{ %} 4279 interface(CONST_INTER); 4280 %} 4281 4282 // Long immediate from 0 to 127. 4283 // Used for a shorter form of long mul by 10. 4284 operand immL_127() 4285 %{ 4286 predicate(0 <= n->get_long() && n->get_long() < 0x80); 4287 match(ConL); 4288 4289 op_cost(10); 4290 format %{ %} 4291 interface(CONST_INTER); 4292 %} 4293 4294 // Long Immediate: low 32-bit mask 4295 operand immL_32bits() 4296 %{ 4297 predicate(n->get_long() == 0xFFFFFFFFL); 4298 match(ConL); 4299 op_cost(20); 4300 4301 format %{ %} 4302 interface(CONST_INTER); 4303 %} 4304 4305 // Float Immediate zero 4306 operand immF0() 4307 %{ 4308 predicate(jint_cast(n->getf()) == 0); 4309 match(ConF); 4310 4311 op_cost(5); 4312 format %{ %} 4313 interface(CONST_INTER); 4314 %} 4315 4316 // Float Immediate 4317 operand immF() 4318 %{ 4319 match(ConF); 4320 4321 op_cost(15); 4322 format %{ %} 4323 interface(CONST_INTER); 4324 %} 4325 4326 // Double Immediate zero 4327 operand immD0() 4328 %{ 4329 predicate(jlong_cast(n->getd()) == 0); 4330 match(ConD); 4331 4332 op_cost(5); 4333 format %{ %} 4334 interface(CONST_INTER); 4335 %} 4336 4337 // Double Immediate 4338 operand immD() 4339 %{ 4340 match(ConD); 4341 4342 op_cost(15); 4343 format %{ %} 4344 interface(CONST_INTER); 4345 %} 4346 4347 // Immediates for special shifts (sign extend) 4348 4349 // Constants for increment 4350 operand immI_16() 4351 %{ 4352 predicate(n->get_int() == 16); 4353 match(ConI); 4354 4355 format %{ %} 4356 interface(CONST_INTER); 4357 %} 4358 4359 operand immI_24() 4360 %{ 4361 predicate(n->get_int() == 24); 4362 match(ConI); 4363 4364 format %{ %} 4365 interface(CONST_INTER); 4366 %} 4367 4368 // Constant for byte-wide masking 4369 operand immI_255() 4370 %{ 4371 predicate(n->get_int() == 255); 4372 match(ConI); 4373 4374 format %{ %} 4375 interface(CONST_INTER); 4376 %} 4377 4378 // Constant for short-wide masking 4379 operand immI_65535() 4380 %{ 4381 predicate(n->get_int() == 65535); 4382 match(ConI); 4383 4384 format %{ %} 4385 interface(CONST_INTER); 4386 %} 4387 4388 // Constant for byte-wide masking 4389 operand immL_255() 4390 %{ 4391 predicate(n->get_long() == 255); 4392 match(ConL); 4393 4394 format %{ %} 4395 interface(CONST_INTER); 4396 %} 4397 4398 // Constant for short-wide masking 4399 operand immL_65535() 4400 %{ 4401 predicate(n->get_long() == 65535); 4402 match(ConL); 4403 4404 format %{ %} 4405 interface(CONST_INTER); 4406 %} 4407 4408 // Register Operands 4409 // Integer Register 4410 operand rRegI() 4411 %{ 4412 constraint(ALLOC_IN_RC(int_reg)); 4413 match(RegI); 4414 4415 match(rax_RegI); 4416 match(rbx_RegI); 4417 match(rcx_RegI); 4418 match(rdx_RegI); 4419 match(rdi_RegI); 4420 4421 format %{ %} 4422 interface(REG_INTER); 4423 %} 4424 4425 // Special Registers 4426 operand rax_RegI() 4427 %{ 4428 constraint(ALLOC_IN_RC(int_rax_reg)); 4429 match(RegI); 4430 match(rRegI); 4431 4432 format %{ "RAX" %} 4433 interface(REG_INTER); 4434 %} 4435 4436 // Special Registers 4437 operand rbx_RegI() 4438 %{ 4439 constraint(ALLOC_IN_RC(int_rbx_reg)); 4440 match(RegI); 4441 match(rRegI); 4442 4443 format %{ "RBX" %} 4444 interface(REG_INTER); 4445 %} 4446 4447 operand rcx_RegI() 4448 %{ 4449 constraint(ALLOC_IN_RC(int_rcx_reg)); 4450 match(RegI); 4451 match(rRegI); 4452 4453 format %{ "RCX" %} 4454 interface(REG_INTER); 4455 %} 4456 4457 operand rdx_RegI() 4458 %{ 4459 constraint(ALLOC_IN_RC(int_rdx_reg)); 4460 match(RegI); 4461 match(rRegI); 4462 4463 format %{ "RDX" %} 4464 interface(REG_INTER); 4465 %} 4466 4467 operand rdi_RegI() 4468 %{ 4469 constraint(ALLOC_IN_RC(int_rdi_reg)); 4470 match(RegI); 4471 match(rRegI); 4472 4473 format %{ "RDI" %} 4474 interface(REG_INTER); 4475 %} 4476 4477 operand no_rcx_RegI() 4478 %{ 4479 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 4480 match(RegI); 4481 match(rax_RegI); 4482 match(rbx_RegI); 4483 match(rdx_RegI); 4484 match(rdi_RegI); 4485 4486 format %{ %} 4487 interface(REG_INTER); 4488 %} 4489 4490 operand no_rax_rdx_RegI() 4491 %{ 4492 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 4493 match(RegI); 4494 match(rbx_RegI); 4495 match(rcx_RegI); 4496 match(rdi_RegI); 4497 4498 format %{ %} 4499 interface(REG_INTER); 4500 %} 4501 4502 // Pointer Register 4503 operand any_RegP() 4504 %{ 4505 constraint(ALLOC_IN_RC(any_reg)); 4506 match(RegP); 4507 match(rax_RegP); 4508 match(rbx_RegP); 4509 match(rdi_RegP); 4510 match(rsi_RegP); 4511 match(rbp_RegP); 4512 match(r15_RegP); 4513 match(rRegP); 4514 4515 format %{ %} 4516 interface(REG_INTER); 4517 %} 4518 4519 operand rRegP() 4520 %{ 4521 constraint(ALLOC_IN_RC(ptr_reg)); 4522 match(RegP); 4523 match(rax_RegP); 4524 match(rbx_RegP); 4525 match(rdi_RegP); 4526 match(rsi_RegP); 4527 match(rbp_RegP); 4528 match(r15_RegP); // See Q&A below about r15_RegP. 4529 4530 format %{ %} 4531 interface(REG_INTER); 4532 %} 4533 4534 operand rRegN() %{ 4535 constraint(ALLOC_IN_RC(int_reg)); 4536 match(RegN); 4537 4538 format %{ %} 4539 interface(REG_INTER); 4540 %} 4541 4542 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 4543 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 4544 // It's fine for an instruction input which expects rRegP to match a r15_RegP. 4545 // The output of an instruction is controlled by the allocator, which respects 4546 // register class masks, not match rules. Unless an instruction mentions 4547 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 4548 // by the allocator as an input. 4549 4550 operand no_rax_RegP() 4551 %{ 4552 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 4553 match(RegP); 4554 match(rbx_RegP); 4555 match(rsi_RegP); 4556 match(rdi_RegP); 4557 4558 format %{ %} 4559 interface(REG_INTER); 4560 %} 4561 4562 operand no_rbp_RegP() 4563 %{ 4564 constraint(ALLOC_IN_RC(ptr_no_rbp_reg)); 4565 match(RegP); 4566 match(rbx_RegP); 4567 match(rsi_RegP); 4568 match(rdi_RegP); 4569 4570 format %{ %} 4571 interface(REG_INTER); 4572 %} 4573 4574 operand no_rax_rbx_RegP() 4575 %{ 4576 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 4577 match(RegP); 4578 match(rsi_RegP); 4579 match(rdi_RegP); 4580 4581 format %{ %} 4582 interface(REG_INTER); 4583 %} 4584 4585 // Special Registers 4586 // Return a pointer value 4587 operand rax_RegP() 4588 %{ 4589 constraint(ALLOC_IN_RC(ptr_rax_reg)); 4590 match(RegP); 4591 match(rRegP); 4592 4593 format %{ %} 4594 interface(REG_INTER); 4595 %} 4596 4597 // Special Registers 4598 // Return a compressed pointer value 4599 operand rax_RegN() 4600 %{ 4601 constraint(ALLOC_IN_RC(int_rax_reg)); 4602 match(RegN); 4603 match(rRegN); 4604 4605 format %{ %} 4606 interface(REG_INTER); 4607 %} 4608 4609 // Used in AtomicAdd 4610 operand rbx_RegP() 4611 %{ 4612 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 4613 match(RegP); 4614 match(rRegP); 4615 4616 format %{ %} 4617 interface(REG_INTER); 4618 %} 4619 4620 operand rsi_RegP() 4621 %{ 4622 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 4623 match(RegP); 4624 match(rRegP); 4625 4626 format %{ %} 4627 interface(REG_INTER); 4628 %} 4629 4630 // Used in rep stosq 4631 operand rdi_RegP() 4632 %{ 4633 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 4634 match(RegP); 4635 match(rRegP); 4636 4637 format %{ %} 4638 interface(REG_INTER); 4639 %} 4640 4641 operand rbp_RegP() 4642 %{ 4643 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 4644 match(RegP); 4645 match(rRegP); 4646 4647 format %{ %} 4648 interface(REG_INTER); 4649 %} 4650 4651 operand r15_RegP() 4652 %{ 4653 constraint(ALLOC_IN_RC(ptr_r15_reg)); 4654 match(RegP); 4655 match(rRegP); 4656 4657 format %{ %} 4658 interface(REG_INTER); 4659 %} 4660 4661 operand rRegL() 4662 %{ 4663 constraint(ALLOC_IN_RC(long_reg)); 4664 match(RegL); 4665 match(rax_RegL); 4666 match(rdx_RegL); 4667 4668 format %{ %} 4669 interface(REG_INTER); 4670 %} 4671 4672 // Special Registers 4673 operand no_rax_rdx_RegL() 4674 %{ 4675 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 4676 match(RegL); 4677 match(rRegL); 4678 4679 format %{ %} 4680 interface(REG_INTER); 4681 %} 4682 4683 operand no_rax_RegL() 4684 %{ 4685 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 4686 match(RegL); 4687 match(rRegL); 4688 match(rdx_RegL); 4689 4690 format %{ %} 4691 interface(REG_INTER); 4692 %} 4693 4694 operand no_rcx_RegL() 4695 %{ 4696 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 4697 match(RegL); 4698 match(rRegL); 4699 4700 format %{ %} 4701 interface(REG_INTER); 4702 %} 4703 4704 operand rax_RegL() 4705 %{ 4706 constraint(ALLOC_IN_RC(long_rax_reg)); 4707 match(RegL); 4708 match(rRegL); 4709 4710 format %{ "RAX" %} 4711 interface(REG_INTER); 4712 %} 4713 4714 operand rcx_RegL() 4715 %{ 4716 constraint(ALLOC_IN_RC(long_rcx_reg)); 4717 match(RegL); 4718 match(rRegL); 4719 4720 format %{ %} 4721 interface(REG_INTER); 4722 %} 4723 4724 operand rdx_RegL() 4725 %{ 4726 constraint(ALLOC_IN_RC(long_rdx_reg)); 4727 match(RegL); 4728 match(rRegL); 4729 4730 format %{ %} 4731 interface(REG_INTER); 4732 %} 4733 4734 // Flags register, used as output of compare instructions 4735 operand rFlagsReg() 4736 %{ 4737 constraint(ALLOC_IN_RC(int_flags)); 4738 match(RegFlags); 4739 4740 format %{ "RFLAGS" %} 4741 interface(REG_INTER); 4742 %} 4743 4744 // Flags register, used as output of FLOATING POINT compare instructions 4745 operand rFlagsRegU() 4746 %{ 4747 constraint(ALLOC_IN_RC(int_flags)); 4748 match(RegFlags); 4749 4750 format %{ "RFLAGS_U" %} 4751 interface(REG_INTER); 4752 %} 4753 4754 operand rFlagsRegUCF() %{ 4755 constraint(ALLOC_IN_RC(int_flags)); 4756 match(RegFlags); 4757 predicate(false); 4758 4759 format %{ "RFLAGS_U_CF" %} 4760 interface(REG_INTER); 4761 %} 4762 4763 // Float register operands 4764 operand regF() 4765 %{ 4766 constraint(ALLOC_IN_RC(float_reg)); 4767 match(RegF); 4768 4769 format %{ %} 4770 interface(REG_INTER); 4771 %} 4772 4773 // Double register operands 4774 operand regD() 4775 %{ 4776 constraint(ALLOC_IN_RC(double_reg)); 4777 match(RegD); 4778 4779 format %{ %} 4780 interface(REG_INTER); 4781 %} 4782 4783 4784 //----------Memory Operands---------------------------------------------------- 4785 // Direct Memory Operand 4786 // operand direct(immP addr) 4787 // %{ 4788 // match(addr); 4789 4790 // format %{ "[$addr]" %} 4791 // interface(MEMORY_INTER) %{ 4792 // base(0xFFFFFFFF); 4793 // index(0x4); 4794 // scale(0x0); 4795 // disp($addr); 4796 // %} 4797 // %} 4798 4799 // Indirect Memory Operand 4800 operand indirect(any_RegP reg) 4801 %{ 4802 constraint(ALLOC_IN_RC(ptr_reg)); 4803 match(reg); 4804 4805 format %{ "[$reg]" %} 4806 interface(MEMORY_INTER) %{ 4807 base($reg); 4808 index(0x4); 4809 scale(0x0); 4810 disp(0x0); 4811 %} 4812 %} 4813 4814 // Indirect Memory Plus Short Offset Operand 4815 operand indOffset8(any_RegP reg, immL8 off) 4816 %{ 4817 constraint(ALLOC_IN_RC(ptr_reg)); 4818 match(AddP reg off); 4819 4820 format %{ "[$reg + $off (8-bit)]" %} 4821 interface(MEMORY_INTER) %{ 4822 base($reg); 4823 index(0x4); 4824 scale(0x0); 4825 disp($off); 4826 %} 4827 %} 4828 4829 // Indirect Memory Plus Long Offset Operand 4830 operand indOffset32(any_RegP reg, immL32 off) 4831 %{ 4832 constraint(ALLOC_IN_RC(ptr_reg)); 4833 match(AddP reg off); 4834 4835 format %{ "[$reg + $off (32-bit)]" %} 4836 interface(MEMORY_INTER) %{ 4837 base($reg); 4838 index(0x4); 4839 scale(0x0); 4840 disp($off); 4841 %} 4842 %} 4843 4844 // Indirect Memory Plus Index Register Plus Offset Operand 4845 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 4846 %{ 4847 constraint(ALLOC_IN_RC(ptr_reg)); 4848 match(AddP (AddP reg lreg) off); 4849 4850 op_cost(10); 4851 format %{"[$reg + $off + $lreg]" %} 4852 interface(MEMORY_INTER) %{ 4853 base($reg); 4854 index($lreg); 4855 scale(0x0); 4856 disp($off); 4857 %} 4858 %} 4859 4860 // Indirect Memory Plus Index Register Plus Offset Operand 4861 operand indIndex(any_RegP reg, rRegL lreg) 4862 %{ 4863 constraint(ALLOC_IN_RC(ptr_reg)); 4864 match(AddP reg lreg); 4865 4866 op_cost(10); 4867 format %{"[$reg + $lreg]" %} 4868 interface(MEMORY_INTER) %{ 4869 base($reg); 4870 index($lreg); 4871 scale(0x0); 4872 disp(0x0); 4873 %} 4874 %} 4875 4876 // Indirect Memory Times Scale Plus Index Register 4877 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 4878 %{ 4879 constraint(ALLOC_IN_RC(ptr_reg)); 4880 match(AddP reg (LShiftL lreg scale)); 4881 4882 op_cost(10); 4883 format %{"[$reg + $lreg << $scale]" %} 4884 interface(MEMORY_INTER) %{ 4885 base($reg); 4886 index($lreg); 4887 scale($scale); 4888 disp(0x0); 4889 %} 4890 %} 4891 4892 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4893 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 4894 %{ 4895 constraint(ALLOC_IN_RC(ptr_reg)); 4896 match(AddP (AddP reg (LShiftL lreg scale)) off); 4897 4898 op_cost(10); 4899 format %{"[$reg + $off + $lreg << $scale]" %} 4900 interface(MEMORY_INTER) %{ 4901 base($reg); 4902 index($lreg); 4903 scale($scale); 4904 disp($off); 4905 %} 4906 %} 4907 4908 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4909 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 4910 %{ 4911 constraint(ALLOC_IN_RC(ptr_reg)); 4912 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4913 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 4914 4915 op_cost(10); 4916 format %{"[$reg + $off + $idx << $scale]" %} 4917 interface(MEMORY_INTER) %{ 4918 base($reg); 4919 index($idx); 4920 scale($scale); 4921 disp($off); 4922 %} 4923 %} 4924 4925 // Indirect Narrow Oop Plus Offset Operand 4926 // Note: x86 architecture doesn't support "scale * index + offset" without a base 4927 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 4928 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 4929 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 4930 constraint(ALLOC_IN_RC(ptr_reg)); 4931 match(AddP (DecodeN reg) off); 4932 4933 op_cost(10); 4934 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 4935 interface(MEMORY_INTER) %{ 4936 base(0xc); // R12 4937 index($reg); 4938 scale(0x3); 4939 disp($off); 4940 %} 4941 %} 4942 4943 // Indirect Memory Operand 4944 operand indirectNarrow(rRegN reg) 4945 %{ 4946 predicate(Universe::narrow_oop_shift() == 0); 4947 constraint(ALLOC_IN_RC(ptr_reg)); 4948 match(DecodeN reg); 4949 4950 format %{ "[$reg]" %} 4951 interface(MEMORY_INTER) %{ 4952 base($reg); 4953 index(0x4); 4954 scale(0x0); 4955 disp(0x0); 4956 %} 4957 %} 4958 4959 // Indirect Memory Plus Short Offset Operand 4960 operand indOffset8Narrow(rRegN reg, immL8 off) 4961 %{ 4962 predicate(Universe::narrow_oop_shift() == 0); 4963 constraint(ALLOC_IN_RC(ptr_reg)); 4964 match(AddP (DecodeN reg) off); 4965 4966 format %{ "[$reg + $off (8-bit)]" %} 4967 interface(MEMORY_INTER) %{ 4968 base($reg); 4969 index(0x4); 4970 scale(0x0); 4971 disp($off); 4972 %} 4973 %} 4974 4975 // Indirect Memory Plus Long Offset Operand 4976 operand indOffset32Narrow(rRegN reg, immL32 off) 4977 %{ 4978 predicate(Universe::narrow_oop_shift() == 0); 4979 constraint(ALLOC_IN_RC(ptr_reg)); 4980 match(AddP (DecodeN reg) off); 4981 4982 format %{ "[$reg + $off (32-bit)]" %} 4983 interface(MEMORY_INTER) %{ 4984 base($reg); 4985 index(0x4); 4986 scale(0x0); 4987 disp($off); 4988 %} 4989 %} 4990 4991 // Indirect Memory Plus Index Register Plus Offset Operand 4992 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 4993 %{ 4994 predicate(Universe::narrow_oop_shift() == 0); 4995 constraint(ALLOC_IN_RC(ptr_reg)); 4996 match(AddP (AddP (DecodeN reg) lreg) off); 4997 4998 op_cost(10); 4999 format %{"[$reg + $off + $lreg]" %} 5000 interface(MEMORY_INTER) %{ 5001 base($reg); 5002 index($lreg); 5003 scale(0x0); 5004 disp($off); 5005 %} 5006 %} 5007 5008 // Indirect Memory Plus Index Register Plus Offset Operand 5009 operand indIndexNarrow(rRegN reg, rRegL lreg) 5010 %{ 5011 predicate(Universe::narrow_oop_shift() == 0); 5012 constraint(ALLOC_IN_RC(ptr_reg)); 5013 match(AddP (DecodeN reg) lreg); 5014 5015 op_cost(10); 5016 format %{"[$reg + $lreg]" %} 5017 interface(MEMORY_INTER) %{ 5018 base($reg); 5019 index($lreg); 5020 scale(0x0); 5021 disp(0x0); 5022 %} 5023 %} 5024 5025 // Indirect Memory Times Scale Plus Index Register 5026 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 5027 %{ 5028 predicate(Universe::narrow_oop_shift() == 0); 5029 constraint(ALLOC_IN_RC(ptr_reg)); 5030 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5031 5032 op_cost(10); 5033 format %{"[$reg + $lreg << $scale]" %} 5034 interface(MEMORY_INTER) %{ 5035 base($reg); 5036 index($lreg); 5037 scale($scale); 5038 disp(0x0); 5039 %} 5040 %} 5041 5042 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 5043 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 5044 %{ 5045 predicate(Universe::narrow_oop_shift() == 0); 5046 constraint(ALLOC_IN_RC(ptr_reg)); 5047 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 5048 5049 op_cost(10); 5050 format %{"[$reg + $off + $lreg << $scale]" %} 5051 interface(MEMORY_INTER) %{ 5052 base($reg); 5053 index($lreg); 5054 scale($scale); 5055 disp($off); 5056 %} 5057 %} 5058 5059 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 5060 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 5061 %{ 5062 constraint(ALLOC_IN_RC(ptr_reg)); 5063 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 5064 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 5065 5066 op_cost(10); 5067 format %{"[$reg + $off + $idx << $scale]" %} 5068 interface(MEMORY_INTER) %{ 5069 base($reg); 5070 index($idx); 5071 scale($scale); 5072 disp($off); 5073 %} 5074 %} 5075 5076 5077 //----------Special Memory Operands-------------------------------------------- 5078 // Stack Slot Operand - This operand is used for loading and storing temporary 5079 // values on the stack where a match requires a value to 5080 // flow through memory. 5081 operand stackSlotP(sRegP reg) 5082 %{ 5083 constraint(ALLOC_IN_RC(stack_slots)); 5084 // No match rule because this operand is only generated in matching 5085 5086 format %{ "[$reg]" %} 5087 interface(MEMORY_INTER) %{ 5088 base(0x4); // RSP 5089 index(0x4); // No Index 5090 scale(0x0); // No Scale 5091 disp($reg); // Stack Offset 5092 %} 5093 %} 5094 5095 operand stackSlotI(sRegI reg) 5096 %{ 5097 constraint(ALLOC_IN_RC(stack_slots)); 5098 // No match rule because this operand is only generated in matching 5099 5100 format %{ "[$reg]" %} 5101 interface(MEMORY_INTER) %{ 5102 base(0x4); // RSP 5103 index(0x4); // No Index 5104 scale(0x0); // No Scale 5105 disp($reg); // Stack Offset 5106 %} 5107 %} 5108 5109 operand stackSlotF(sRegF reg) 5110 %{ 5111 constraint(ALLOC_IN_RC(stack_slots)); 5112 // No match rule because this operand is only generated in matching 5113 5114 format %{ "[$reg]" %} 5115 interface(MEMORY_INTER) %{ 5116 base(0x4); // RSP 5117 index(0x4); // No Index 5118 scale(0x0); // No Scale 5119 disp($reg); // Stack Offset 5120 %} 5121 %} 5122 5123 operand stackSlotD(sRegD reg) 5124 %{ 5125 constraint(ALLOC_IN_RC(stack_slots)); 5126 // No match rule because this operand is only generated in matching 5127 5128 format %{ "[$reg]" %} 5129 interface(MEMORY_INTER) %{ 5130 base(0x4); // RSP 5131 index(0x4); // No Index 5132 scale(0x0); // No Scale 5133 disp($reg); // Stack Offset 5134 %} 5135 %} 5136 operand stackSlotL(sRegL reg) 5137 %{ 5138 constraint(ALLOC_IN_RC(stack_slots)); 5139 // No match rule because this operand is only generated in matching 5140 5141 format %{ "[$reg]" %} 5142 interface(MEMORY_INTER) %{ 5143 base(0x4); // RSP 5144 index(0x4); // No Index 5145 scale(0x0); // No Scale 5146 disp($reg); // Stack Offset 5147 %} 5148 %} 5149 5150 //----------Conditional Branch Operands---------------------------------------- 5151 // Comparison Op - This is the operation of the comparison, and is limited to 5152 // the following set of codes: 5153 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5154 // 5155 // Other attributes of the comparison, such as unsignedness, are specified 5156 // by the comparison instruction that sets a condition code flags register. 5157 // That result is represented by a flags operand whose subtype is appropriate 5158 // to the unsignedness (etc.) of the comparison. 5159 // 5160 // Later, the instruction which matches both the Comparison Op (a Bool) and 5161 // the flags (produced by the Cmp) specifies the coding of the comparison op 5162 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5163 5164 // Comparision Code 5165 operand cmpOp() 5166 %{ 5167 match(Bool); 5168 5169 format %{ "" %} 5170 interface(COND_INTER) %{ 5171 equal(0x4, "e"); 5172 not_equal(0x5, "ne"); 5173 less(0xC, "l"); 5174 greater_equal(0xD, "ge"); 5175 less_equal(0xE, "le"); 5176 greater(0xF, "g"); 5177 %} 5178 %} 5179 5180 // Comparison Code, unsigned compare. Used by FP also, with 5181 // C2 (unordered) turned into GT or LT already. The other bits 5182 // C0 and C3 are turned into Carry & Zero flags. 5183 operand cmpOpU() 5184 %{ 5185 match(Bool); 5186 5187 format %{ "" %} 5188 interface(COND_INTER) %{ 5189 equal(0x4, "e"); 5190 not_equal(0x5, "ne"); 5191 less(0x2, "b"); 5192 greater_equal(0x3, "nb"); 5193 less_equal(0x6, "be"); 5194 greater(0x7, "nbe"); 5195 %} 5196 %} 5197 5198 5199 // Floating comparisons that don't require any fixup for the unordered case 5200 operand cmpOpUCF() %{ 5201 match(Bool); 5202 predicate(n->as_Bool()->_test._test == BoolTest::lt || 5203 n->as_Bool()->_test._test == BoolTest::ge || 5204 n->as_Bool()->_test._test == BoolTest::le || 5205 n->as_Bool()->_test._test == BoolTest::gt); 5206 format %{ "" %} 5207 interface(COND_INTER) %{ 5208 equal(0x4, "e"); 5209 not_equal(0x5, "ne"); 5210 less(0x2, "b"); 5211 greater_equal(0x3, "nb"); 5212 less_equal(0x6, "be"); 5213 greater(0x7, "nbe"); 5214 %} 5215 %} 5216 5217 5218 // Floating comparisons that can be fixed up with extra conditional jumps 5219 operand cmpOpUCF2() %{ 5220 match(Bool); 5221 predicate(n->as_Bool()->_test._test == BoolTest::ne || 5222 n->as_Bool()->_test._test == BoolTest::eq); 5223 format %{ "" %} 5224 interface(COND_INTER) %{ 5225 equal(0x4, "e"); 5226 not_equal(0x5, "ne"); 5227 less(0x2, "b"); 5228 greater_equal(0x3, "nb"); 5229 less_equal(0x6, "be"); 5230 greater(0x7, "nbe"); 5231 %} 5232 %} 5233 5234 5235 //----------OPERAND CLASSES---------------------------------------------------- 5236 // Operand Classes are groups of operands that are used as to simplify 5237 // instruction definitions by not requiring the AD writer to specify separate 5238 // instructions for every form of operand when the instruction accepts 5239 // multiple operand types with the same basic encoding and format. The classic 5240 // case of this is memory operands. 5241 5242 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 5243 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, 5244 indCompressedOopOffset, 5245 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 5246 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 5247 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow); 5248 5249 //----------PIPELINE----------------------------------------------------------- 5250 // Rules which define the behavior of the target architectures pipeline. 5251 pipeline %{ 5252 5253 //----------ATTRIBUTES--------------------------------------------------------- 5254 attributes %{ 5255 variable_size_instructions; // Fixed size instructions 5256 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 5257 instruction_unit_size = 1; // An instruction is 1 bytes long 5258 instruction_fetch_unit_size = 16; // The processor fetches one line 5259 instruction_fetch_units = 1; // of 16 bytes 5260 5261 // List of nop instructions 5262 nops( MachNop ); 5263 %} 5264 5265 //----------RESOURCES---------------------------------------------------------- 5266 // Resources are the functional units available to the machine 5267 5268 // Generic P2/P3 pipeline 5269 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 5270 // 3 instructions decoded per cycle. 5271 // 2 load/store ops per cycle, 1 branch, 1 FPU, 5272 // 3 ALU op, only ALU0 handles mul instructions. 5273 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 5274 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 5275 BR, FPU, 5276 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 5277 5278 //----------PIPELINE DESCRIPTION----------------------------------------------- 5279 // Pipeline Description specifies the stages in the machine's pipeline 5280 5281 // Generic P2/P3 pipeline 5282 pipe_desc(S0, S1, S2, S3, S4, S5); 5283 5284 //----------PIPELINE CLASSES--------------------------------------------------- 5285 // Pipeline Classes describe the stages in which input and output are 5286 // referenced by the hardware pipeline. 5287 5288 // Naming convention: ialu or fpu 5289 // Then: _reg 5290 // Then: _reg if there is a 2nd register 5291 // Then: _long if it's a pair of instructions implementing a long 5292 // Then: _fat if it requires the big decoder 5293 // Or: _mem if it requires the big decoder and a memory unit. 5294 5295 // Integer ALU reg operation 5296 pipe_class ialu_reg(rRegI dst) 5297 %{ 5298 single_instruction; 5299 dst : S4(write); 5300 dst : S3(read); 5301 DECODE : S0; // any decoder 5302 ALU : S3; // any alu 5303 %} 5304 5305 // Long ALU reg operation 5306 pipe_class ialu_reg_long(rRegL dst) 5307 %{ 5308 instruction_count(2); 5309 dst : S4(write); 5310 dst : S3(read); 5311 DECODE : S0(2); // any 2 decoders 5312 ALU : S3(2); // both alus 5313 %} 5314 5315 // Integer ALU reg operation using big decoder 5316 pipe_class ialu_reg_fat(rRegI dst) 5317 %{ 5318 single_instruction; 5319 dst : S4(write); 5320 dst : S3(read); 5321 D0 : S0; // big decoder only 5322 ALU : S3; // any alu 5323 %} 5324 5325 // Long ALU reg operation using big decoder 5326 pipe_class ialu_reg_long_fat(rRegL dst) 5327 %{ 5328 instruction_count(2); 5329 dst : S4(write); 5330 dst : S3(read); 5331 D0 : S0(2); // big decoder only; twice 5332 ALU : S3(2); // any 2 alus 5333 %} 5334 5335 // Integer ALU reg-reg operation 5336 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 5337 %{ 5338 single_instruction; 5339 dst : S4(write); 5340 src : S3(read); 5341 DECODE : S0; // any decoder 5342 ALU : S3; // any alu 5343 %} 5344 5345 // Long ALU reg-reg operation 5346 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 5347 %{ 5348 instruction_count(2); 5349 dst : S4(write); 5350 src : S3(read); 5351 DECODE : S0(2); // any 2 decoders 5352 ALU : S3(2); // both alus 5353 %} 5354 5355 // Integer ALU reg-reg operation 5356 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 5357 %{ 5358 single_instruction; 5359 dst : S4(write); 5360 src : S3(read); 5361 D0 : S0; // big decoder only 5362 ALU : S3; // any alu 5363 %} 5364 5365 // Long ALU reg-reg operation 5366 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 5367 %{ 5368 instruction_count(2); 5369 dst : S4(write); 5370 src : S3(read); 5371 D0 : S0(2); // big decoder only; twice 5372 ALU : S3(2); // both alus 5373 %} 5374 5375 // Integer ALU reg-mem operation 5376 pipe_class ialu_reg_mem(rRegI dst, memory mem) 5377 %{ 5378 single_instruction; 5379 dst : S5(write); 5380 mem : S3(read); 5381 D0 : S0; // big decoder only 5382 ALU : S4; // any alu 5383 MEM : S3; // any mem 5384 %} 5385 5386 // Integer mem operation (prefetch) 5387 pipe_class ialu_mem(memory mem) 5388 %{ 5389 single_instruction; 5390 mem : S3(read); 5391 D0 : S0; // big decoder only 5392 MEM : S3; // any mem 5393 %} 5394 5395 // Integer Store to Memory 5396 pipe_class ialu_mem_reg(memory mem, rRegI src) 5397 %{ 5398 single_instruction; 5399 mem : S3(read); 5400 src : S5(read); 5401 D0 : S0; // big decoder only 5402 ALU : S4; // any alu 5403 MEM : S3; 5404 %} 5405 5406 // // Long Store to Memory 5407 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 5408 // %{ 5409 // instruction_count(2); 5410 // mem : S3(read); 5411 // src : S5(read); 5412 // D0 : S0(2); // big decoder only; twice 5413 // ALU : S4(2); // any 2 alus 5414 // MEM : S3(2); // Both mems 5415 // %} 5416 5417 // Integer Store to Memory 5418 pipe_class ialu_mem_imm(memory mem) 5419 %{ 5420 single_instruction; 5421 mem : S3(read); 5422 D0 : S0; // big decoder only 5423 ALU : S4; // any alu 5424 MEM : S3; 5425 %} 5426 5427 // Integer ALU0 reg-reg operation 5428 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 5429 %{ 5430 single_instruction; 5431 dst : S4(write); 5432 src : S3(read); 5433 D0 : S0; // Big decoder only 5434 ALU0 : S3; // only alu0 5435 %} 5436 5437 // Integer ALU0 reg-mem operation 5438 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 5439 %{ 5440 single_instruction; 5441 dst : S5(write); 5442 mem : S3(read); 5443 D0 : S0; // big decoder only 5444 ALU0 : S4; // ALU0 only 5445 MEM : S3; // any mem 5446 %} 5447 5448 // Integer ALU reg-reg operation 5449 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 5450 %{ 5451 single_instruction; 5452 cr : S4(write); 5453 src1 : S3(read); 5454 src2 : S3(read); 5455 DECODE : S0; // any decoder 5456 ALU : S3; // any alu 5457 %} 5458 5459 // Integer ALU reg-imm operation 5460 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 5461 %{ 5462 single_instruction; 5463 cr : S4(write); 5464 src1 : S3(read); 5465 DECODE : S0; // any decoder 5466 ALU : S3; // any alu 5467 %} 5468 5469 // Integer ALU reg-mem operation 5470 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 5471 %{ 5472 single_instruction; 5473 cr : S4(write); 5474 src1 : S3(read); 5475 src2 : S3(read); 5476 D0 : S0; // big decoder only 5477 ALU : S4; // any alu 5478 MEM : S3; 5479 %} 5480 5481 // Conditional move reg-reg 5482 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 5483 %{ 5484 instruction_count(4); 5485 y : S4(read); 5486 q : S3(read); 5487 p : S3(read); 5488 DECODE : S0(4); // any decoder 5489 %} 5490 5491 // Conditional move reg-reg 5492 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 5493 %{ 5494 single_instruction; 5495 dst : S4(write); 5496 src : S3(read); 5497 cr : S3(read); 5498 DECODE : S0; // any decoder 5499 %} 5500 5501 // Conditional move reg-mem 5502 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 5503 %{ 5504 single_instruction; 5505 dst : S4(write); 5506 src : S3(read); 5507 cr : S3(read); 5508 DECODE : S0; // any decoder 5509 MEM : S3; 5510 %} 5511 5512 // Conditional move reg-reg long 5513 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 5514 %{ 5515 single_instruction; 5516 dst : S4(write); 5517 src : S3(read); 5518 cr : S3(read); 5519 DECODE : S0(2); // any 2 decoders 5520 %} 5521 5522 // XXX 5523 // // Conditional move double reg-reg 5524 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 5525 // %{ 5526 // single_instruction; 5527 // dst : S4(write); 5528 // src : S3(read); 5529 // cr : S3(read); 5530 // DECODE : S0; // any decoder 5531 // %} 5532 5533 // Float reg-reg operation 5534 pipe_class fpu_reg(regD dst) 5535 %{ 5536 instruction_count(2); 5537 dst : S3(read); 5538 DECODE : S0(2); // any 2 decoders 5539 FPU : S3; 5540 %} 5541 5542 // Float reg-reg operation 5543 pipe_class fpu_reg_reg(regD dst, regD src) 5544 %{ 5545 instruction_count(2); 5546 dst : S4(write); 5547 src : S3(read); 5548 DECODE : S0(2); // any 2 decoders 5549 FPU : S3; 5550 %} 5551 5552 // Float reg-reg operation 5553 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 5554 %{ 5555 instruction_count(3); 5556 dst : S4(write); 5557 src1 : S3(read); 5558 src2 : S3(read); 5559 DECODE : S0(3); // any 3 decoders 5560 FPU : S3(2); 5561 %} 5562 5563 // Float reg-reg operation 5564 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 5565 %{ 5566 instruction_count(4); 5567 dst : S4(write); 5568 src1 : S3(read); 5569 src2 : S3(read); 5570 src3 : S3(read); 5571 DECODE : S0(4); // any 3 decoders 5572 FPU : S3(2); 5573 %} 5574 5575 // Float reg-reg operation 5576 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 5577 %{ 5578 instruction_count(4); 5579 dst : S4(write); 5580 src1 : S3(read); 5581 src2 : S3(read); 5582 src3 : S3(read); 5583 DECODE : S1(3); // any 3 decoders 5584 D0 : S0; // Big decoder only 5585 FPU : S3(2); 5586 MEM : S3; 5587 %} 5588 5589 // Float reg-mem operation 5590 pipe_class fpu_reg_mem(regD dst, memory mem) 5591 %{ 5592 instruction_count(2); 5593 dst : S5(write); 5594 mem : S3(read); 5595 D0 : S0; // big decoder only 5596 DECODE : S1; // any decoder for FPU POP 5597 FPU : S4; 5598 MEM : S3; // any mem 5599 %} 5600 5601 // Float reg-mem operation 5602 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 5603 %{ 5604 instruction_count(3); 5605 dst : S5(write); 5606 src1 : S3(read); 5607 mem : S3(read); 5608 D0 : S0; // big decoder only 5609 DECODE : S1(2); // any decoder for FPU POP 5610 FPU : S4; 5611 MEM : S3; // any mem 5612 %} 5613 5614 // Float mem-reg operation 5615 pipe_class fpu_mem_reg(memory mem, regD src) 5616 %{ 5617 instruction_count(2); 5618 src : S5(read); 5619 mem : S3(read); 5620 DECODE : S0; // any decoder for FPU PUSH 5621 D0 : S1; // big decoder only 5622 FPU : S4; 5623 MEM : S3; // any mem 5624 %} 5625 5626 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 5627 %{ 5628 instruction_count(3); 5629 src1 : S3(read); 5630 src2 : S3(read); 5631 mem : S3(read); 5632 DECODE : S0(2); // any decoder for FPU PUSH 5633 D0 : S1; // big decoder only 5634 FPU : S4; 5635 MEM : S3; // any mem 5636 %} 5637 5638 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 5639 %{ 5640 instruction_count(3); 5641 src1 : S3(read); 5642 src2 : S3(read); 5643 mem : S4(read); 5644 DECODE : S0; // any decoder for FPU PUSH 5645 D0 : S0(2); // big decoder only 5646 FPU : S4; 5647 MEM : S3(2); // any mem 5648 %} 5649 5650 pipe_class fpu_mem_mem(memory dst, memory src1) 5651 %{ 5652 instruction_count(2); 5653 src1 : S3(read); 5654 dst : S4(read); 5655 D0 : S0(2); // big decoder only 5656 MEM : S3(2); // any mem 5657 %} 5658 5659 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 5660 %{ 5661 instruction_count(3); 5662 src1 : S3(read); 5663 src2 : S3(read); 5664 dst : S4(read); 5665 D0 : S0(3); // big decoder only 5666 FPU : S4; 5667 MEM : S3(3); // any mem 5668 %} 5669 5670 pipe_class fpu_mem_reg_con(memory mem, regD src1) 5671 %{ 5672 instruction_count(3); 5673 src1 : S4(read); 5674 mem : S4(read); 5675 DECODE : S0; // any decoder for FPU PUSH 5676 D0 : S0(2); // big decoder only 5677 FPU : S4; 5678 MEM : S3(2); // any mem 5679 %} 5680 5681 // Float load constant 5682 pipe_class fpu_reg_con(regD dst) 5683 %{ 5684 instruction_count(2); 5685 dst : S5(write); 5686 D0 : S0; // big decoder only for the load 5687 DECODE : S1; // any decoder for FPU POP 5688 FPU : S4; 5689 MEM : S3; // any mem 5690 %} 5691 5692 // Float load constant 5693 pipe_class fpu_reg_reg_con(regD dst, regD src) 5694 %{ 5695 instruction_count(3); 5696 dst : S5(write); 5697 src : S3(read); 5698 D0 : S0; // big decoder only for the load 5699 DECODE : S1(2); // any decoder for FPU POP 5700 FPU : S4; 5701 MEM : S3; // any mem 5702 %} 5703 5704 // UnConditional branch 5705 pipe_class pipe_jmp(label labl) 5706 %{ 5707 single_instruction; 5708 BR : S3; 5709 %} 5710 5711 // Conditional branch 5712 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 5713 %{ 5714 single_instruction; 5715 cr : S1(read); 5716 BR : S3; 5717 %} 5718 5719 // Allocation idiom 5720 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 5721 %{ 5722 instruction_count(1); force_serialization; 5723 fixed_latency(6); 5724 heap_ptr : S3(read); 5725 DECODE : S0(3); 5726 D0 : S2; 5727 MEM : S3; 5728 ALU : S3(2); 5729 dst : S5(write); 5730 BR : S5; 5731 %} 5732 5733 // Generic big/slow expanded idiom 5734 pipe_class pipe_slow() 5735 %{ 5736 instruction_count(10); multiple_bundles; force_serialization; 5737 fixed_latency(100); 5738 D0 : S0(2); 5739 MEM : S3(2); 5740 %} 5741 5742 // The real do-nothing guy 5743 pipe_class empty() 5744 %{ 5745 instruction_count(0); 5746 %} 5747 5748 // Define the class for the Nop node 5749 define 5750 %{ 5751 MachNop = empty; 5752 %} 5753 5754 %} 5755 5756 //----------INSTRUCTIONS------------------------------------------------------- 5757 // 5758 // match -- States which machine-independent subtree may be replaced 5759 // by this instruction. 5760 // ins_cost -- The estimated cost of this instruction is used by instruction 5761 // selection to identify a minimum cost tree of machine 5762 // instructions that matches a tree of machine-independent 5763 // instructions. 5764 // format -- A string providing the disassembly for this instruction. 5765 // The value of an instruction's operand may be inserted 5766 // by referring to it with a '$' prefix. 5767 // opcode -- Three instruction opcodes may be provided. These are referred 5768 // to within an encode class as $primary, $secondary, and $tertiary 5769 // rrspectively. The primary opcode is commonly used to 5770 // indicate the type of machine instruction, while secondary 5771 // and tertiary are often used for prefix options or addressing 5772 // modes. 5773 // ins_encode -- A list of encode classes with parameters. The encode class 5774 // name must have been defined in an 'enc_class' specification 5775 // in the encode section of the architecture description. 5776 5777 5778 //----------Load/Store/Move Instructions--------------------------------------- 5779 //----------Load Instructions-------------------------------------------------- 5780 5781 // Load Byte (8 bit signed) 5782 instruct loadB(rRegI dst, memory mem) 5783 %{ 5784 match(Set dst (LoadB mem)); 5785 5786 ins_cost(125); 5787 format %{ "movsbl $dst, $mem\t# byte" %} 5788 5789 ins_encode %{ 5790 __ movsbl($dst$$Register, $mem$$Address); 5791 %} 5792 5793 ins_pipe(ialu_reg_mem); 5794 %} 5795 5796 // Load Byte (8 bit signed) into Long Register 5797 instruct loadB2L(rRegL dst, memory mem) 5798 %{ 5799 match(Set dst (ConvI2L (LoadB mem))); 5800 5801 ins_cost(125); 5802 format %{ "movsbq $dst, $mem\t# byte -> long" %} 5803 5804 ins_encode %{ 5805 __ movsbq($dst$$Register, $mem$$Address); 5806 %} 5807 5808 ins_pipe(ialu_reg_mem); 5809 %} 5810 5811 // Load Unsigned Byte (8 bit UNsigned) 5812 instruct loadUB(rRegI dst, memory mem) 5813 %{ 5814 match(Set dst (LoadUB mem)); 5815 5816 ins_cost(125); 5817 format %{ "movzbl $dst, $mem\t# ubyte" %} 5818 5819 ins_encode %{ 5820 __ movzbl($dst$$Register, $mem$$Address); 5821 %} 5822 5823 ins_pipe(ialu_reg_mem); 5824 %} 5825 5826 // Load Unsigned Byte (8 bit UNsigned) into Long Register 5827 instruct loadUB2L(rRegL dst, memory mem) 5828 %{ 5829 match(Set dst (ConvI2L (LoadUB mem))); 5830 5831 ins_cost(125); 5832 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 5833 5834 ins_encode %{ 5835 __ movzbq($dst$$Register, $mem$$Address); 5836 %} 5837 5838 ins_pipe(ialu_reg_mem); 5839 %} 5840 5841 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register 5842 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ 5843 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5844 effect(KILL cr); 5845 5846 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" 5847 "andl $dst, $mask" %} 5848 ins_encode %{ 5849 Register Rdst = $dst$$Register; 5850 __ movzbq(Rdst, $mem$$Address); 5851 __ andl(Rdst, $mask$$constant); 5852 %} 5853 ins_pipe(ialu_reg_mem); 5854 %} 5855 5856 // Load Short (16 bit signed) 5857 instruct loadS(rRegI dst, memory mem) 5858 %{ 5859 match(Set dst (LoadS mem)); 5860 5861 ins_cost(125); 5862 format %{ "movswl $dst, $mem\t# short" %} 5863 5864 ins_encode %{ 5865 __ movswl($dst$$Register, $mem$$Address); 5866 %} 5867 5868 ins_pipe(ialu_reg_mem); 5869 %} 5870 5871 // Load Short (16 bit signed) to Byte (8 bit signed) 5872 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5873 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5874 5875 ins_cost(125); 5876 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5877 ins_encode %{ 5878 __ movsbl($dst$$Register, $mem$$Address); 5879 %} 5880 ins_pipe(ialu_reg_mem); 5881 %} 5882 5883 // Load Short (16 bit signed) into Long Register 5884 instruct loadS2L(rRegL dst, memory mem) 5885 %{ 5886 match(Set dst (ConvI2L (LoadS mem))); 5887 5888 ins_cost(125); 5889 format %{ "movswq $dst, $mem\t# short -> long" %} 5890 5891 ins_encode %{ 5892 __ movswq($dst$$Register, $mem$$Address); 5893 %} 5894 5895 ins_pipe(ialu_reg_mem); 5896 %} 5897 5898 // Load Unsigned Short/Char (16 bit UNsigned) 5899 instruct loadUS(rRegI dst, memory mem) 5900 %{ 5901 match(Set dst (LoadUS mem)); 5902 5903 ins_cost(125); 5904 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5905 5906 ins_encode %{ 5907 __ movzwl($dst$$Register, $mem$$Address); 5908 %} 5909 5910 ins_pipe(ialu_reg_mem); 5911 %} 5912 5913 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5914 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5915 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5916 5917 ins_cost(125); 5918 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5919 ins_encode %{ 5920 __ movsbl($dst$$Register, $mem$$Address); 5921 %} 5922 ins_pipe(ialu_reg_mem); 5923 %} 5924 5925 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5926 instruct loadUS2L(rRegL dst, memory mem) 5927 %{ 5928 match(Set dst (ConvI2L (LoadUS mem))); 5929 5930 ins_cost(125); 5931 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5932 5933 ins_encode %{ 5934 __ movzwq($dst$$Register, $mem$$Address); 5935 %} 5936 5937 ins_pipe(ialu_reg_mem); 5938 %} 5939 5940 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5941 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5942 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5943 5944 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5945 ins_encode %{ 5946 __ movzbq($dst$$Register, $mem$$Address); 5947 %} 5948 ins_pipe(ialu_reg_mem); 5949 %} 5950 5951 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register 5952 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ 5953 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5954 effect(KILL cr); 5955 5956 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" 5957 "andl $dst, $mask" %} 5958 ins_encode %{ 5959 Register Rdst = $dst$$Register; 5960 __ movzwq(Rdst, $mem$$Address); 5961 __ andl(Rdst, $mask$$constant); 5962 %} 5963 ins_pipe(ialu_reg_mem); 5964 %} 5965 5966 // Load Integer 5967 instruct loadI(rRegI dst, memory mem) 5968 %{ 5969 match(Set dst (LoadI mem)); 5970 5971 ins_cost(125); 5972 format %{ "movl $dst, $mem\t# int" %} 5973 5974 ins_encode %{ 5975 __ movl($dst$$Register, $mem$$Address); 5976 %} 5977 5978 ins_pipe(ialu_reg_mem); 5979 %} 5980 5981 // Load Integer (32 bit signed) to Byte (8 bit signed) 5982 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5983 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5984 5985 ins_cost(125); 5986 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5987 ins_encode %{ 5988 __ movsbl($dst$$Register, $mem$$Address); 5989 %} 5990 ins_pipe(ialu_reg_mem); 5991 %} 5992 5993 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5994 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5995 match(Set dst (AndI (LoadI mem) mask)); 5996 5997 ins_cost(125); 5998 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5999 ins_encode %{ 6000 __ movzbl($dst$$Register, $mem$$Address); 6001 %} 6002 ins_pipe(ialu_reg_mem); 6003 %} 6004 6005 // Load Integer (32 bit signed) to Short (16 bit signed) 6006 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 6007 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 6008 6009 ins_cost(125); 6010 format %{ "movswl $dst, $mem\t# int -> short" %} 6011 ins_encode %{ 6012 __ movswl($dst$$Register, $mem$$Address); 6013 %} 6014 ins_pipe(ialu_reg_mem); 6015 %} 6016 6017 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 6018 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 6019 match(Set dst (AndI (LoadI mem) mask)); 6020 6021 ins_cost(125); 6022 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 6023 ins_encode %{ 6024 __ movzwl($dst$$Register, $mem$$Address); 6025 %} 6026 ins_pipe(ialu_reg_mem); 6027 %} 6028 6029 // Load Integer into Long Register 6030 instruct loadI2L(rRegL dst, memory mem) 6031 %{ 6032 match(Set dst (ConvI2L (LoadI mem))); 6033 6034 ins_cost(125); 6035 format %{ "movslq $dst, $mem\t# int -> long" %} 6036 6037 ins_encode %{ 6038 __ movslq($dst$$Register, $mem$$Address); 6039 %} 6040 6041 ins_pipe(ialu_reg_mem); 6042 %} 6043 6044 // Load Integer with mask 0xFF into Long Register 6045 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 6046 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6047 6048 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 6049 ins_encode %{ 6050 __ movzbq($dst$$Register, $mem$$Address); 6051 %} 6052 ins_pipe(ialu_reg_mem); 6053 %} 6054 6055 // Load Integer with mask 0xFFFF into Long Register 6056 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 6057 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6058 6059 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 6060 ins_encode %{ 6061 __ movzwq($dst$$Register, $mem$$Address); 6062 %} 6063 ins_pipe(ialu_reg_mem); 6064 %} 6065 6066 // Load Integer with a 32-bit mask into Long Register 6067 instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 6068 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6069 effect(KILL cr); 6070 6071 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t" 6072 "andl $dst, $mask" %} 6073 ins_encode %{ 6074 Register Rdst = $dst$$Register; 6075 __ movl(Rdst, $mem$$Address); 6076 __ andl(Rdst, $mask$$constant); 6077 %} 6078 ins_pipe(ialu_reg_mem); 6079 %} 6080 6081 // Load Unsigned Integer into Long Register 6082 instruct loadUI2L(rRegL dst, memory mem) 6083 %{ 6084 match(Set dst (LoadUI2L mem)); 6085 6086 ins_cost(125); 6087 format %{ "movl $dst, $mem\t# uint -> long" %} 6088 6089 ins_encode %{ 6090 __ movl($dst$$Register, $mem$$Address); 6091 %} 6092 6093 ins_pipe(ialu_reg_mem); 6094 %} 6095 6096 // Load Long 6097 instruct loadL(rRegL dst, memory mem) 6098 %{ 6099 match(Set dst (LoadL mem)); 6100 6101 ins_cost(125); 6102 format %{ "movq $dst, $mem\t# long" %} 6103 6104 ins_encode %{ 6105 __ movq($dst$$Register, $mem$$Address); 6106 %} 6107 6108 ins_pipe(ialu_reg_mem); // XXX 6109 %} 6110 6111 // Load Range 6112 instruct loadRange(rRegI dst, memory mem) 6113 %{ 6114 match(Set dst (LoadRange mem)); 6115 6116 ins_cost(125); // XXX 6117 format %{ "movl $dst, $mem\t# range" %} 6118 opcode(0x8B); 6119 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 6120 ins_pipe(ialu_reg_mem); 6121 %} 6122 6123 // Load Pointer 6124 instruct loadP(rRegP dst, memory mem) 6125 %{ 6126 match(Set dst (LoadP mem)); 6127 6128 ins_cost(125); // XXX 6129 format %{ "movq $dst, $mem\t# ptr" %} 6130 opcode(0x8B); 6131 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6132 ins_pipe(ialu_reg_mem); // XXX 6133 %} 6134 6135 // Load Compressed Pointer 6136 instruct loadN(rRegN dst, memory mem) 6137 %{ 6138 match(Set dst (LoadN mem)); 6139 6140 ins_cost(125); // XXX 6141 format %{ "movl $dst, $mem\t# compressed ptr" %} 6142 ins_encode %{ 6143 __ movl($dst$$Register, $mem$$Address); 6144 %} 6145 ins_pipe(ialu_reg_mem); // XXX 6146 %} 6147 6148 6149 // Load Klass Pointer 6150 instruct loadKlass(rRegP dst, memory mem) 6151 %{ 6152 match(Set dst (LoadKlass mem)); 6153 6154 ins_cost(125); // XXX 6155 format %{ "movq $dst, $mem\t# class" %} 6156 opcode(0x8B); 6157 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6158 ins_pipe(ialu_reg_mem); // XXX 6159 %} 6160 6161 // Load narrow Klass Pointer 6162 instruct loadNKlass(rRegN dst, memory mem) 6163 %{ 6164 match(Set dst (LoadNKlass mem)); 6165 6166 ins_cost(125); // XXX 6167 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 6168 ins_encode %{ 6169 __ movl($dst$$Register, $mem$$Address); 6170 %} 6171 ins_pipe(ialu_reg_mem); // XXX 6172 %} 6173 6174 // Load Float 6175 instruct loadF(regF dst, memory mem) 6176 %{ 6177 match(Set dst (LoadF mem)); 6178 6179 ins_cost(145); // XXX 6180 format %{ "movss $dst, $mem\t# float" %} 6181 opcode(0xF3, 0x0F, 0x10); 6182 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 6183 ins_pipe(pipe_slow); // XXX 6184 %} 6185 6186 // Load Double 6187 instruct loadD_partial(regD dst, memory mem) 6188 %{ 6189 predicate(!UseXmmLoadAndClearUpper); 6190 match(Set dst (LoadD mem)); 6191 6192 ins_cost(145); // XXX 6193 format %{ "movlpd $dst, $mem\t# double" %} 6194 opcode(0x66, 0x0F, 0x12); 6195 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 6196 ins_pipe(pipe_slow); // XXX 6197 %} 6198 6199 instruct loadD(regD dst, memory mem) 6200 %{ 6201 predicate(UseXmmLoadAndClearUpper); 6202 match(Set dst (LoadD mem)); 6203 6204 ins_cost(145); // XXX 6205 format %{ "movsd $dst, $mem\t# double" %} 6206 opcode(0xF2, 0x0F, 0x10); 6207 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 6208 ins_pipe(pipe_slow); // XXX 6209 %} 6210 6211 // Load Aligned Packed Byte to XMM register 6212 instruct loadA8B(regD dst, memory mem) %{ 6213 match(Set dst (Load8B mem)); 6214 ins_cost(125); 6215 format %{ "MOVQ $dst,$mem\t! packed8B" %} 6216 ins_encode( movq_ld(dst, mem)); 6217 ins_pipe( pipe_slow ); 6218 %} 6219 6220 // Load Aligned Packed Short to XMM register 6221 instruct loadA4S(regD dst, memory mem) %{ 6222 match(Set dst (Load4S mem)); 6223 ins_cost(125); 6224 format %{ "MOVQ $dst,$mem\t! packed4S" %} 6225 ins_encode( movq_ld(dst, mem)); 6226 ins_pipe( pipe_slow ); 6227 %} 6228 6229 // Load Aligned Packed Char to XMM register 6230 instruct loadA4C(regD dst, memory mem) %{ 6231 match(Set dst (Load4C mem)); 6232 ins_cost(125); 6233 format %{ "MOVQ $dst,$mem\t! packed4C" %} 6234 ins_encode( movq_ld(dst, mem)); 6235 ins_pipe( pipe_slow ); 6236 %} 6237 6238 // Load Aligned Packed Integer to XMM register 6239 instruct load2IU(regD dst, memory mem) %{ 6240 match(Set dst (Load2I mem)); 6241 ins_cost(125); 6242 format %{ "MOVQ $dst,$mem\t! packed2I" %} 6243 ins_encode( movq_ld(dst, mem)); 6244 ins_pipe( pipe_slow ); 6245 %} 6246 6247 // Load Aligned Packed Single to XMM 6248 instruct loadA2F(regD dst, memory mem) %{ 6249 match(Set dst (Load2F mem)); 6250 ins_cost(145); 6251 format %{ "MOVQ $dst,$mem\t! packed2F" %} 6252 ins_encode( movq_ld(dst, mem)); 6253 ins_pipe( pipe_slow ); 6254 %} 6255 6256 // Load Effective Address 6257 instruct leaP8(rRegP dst, indOffset8 mem) 6258 %{ 6259 match(Set dst mem); 6260 6261 ins_cost(110); // XXX 6262 format %{ "leaq $dst, $mem\t# ptr 8" %} 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 leaP32(rRegP dst, indOffset32 mem) 6269 %{ 6270 match(Set dst mem); 6271 6272 ins_cost(110); 6273 format %{ "leaq $dst, $mem\t# ptr 32" %} 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 leaPIdx(rRegP dst, indIndex mem) 6280 // %{ 6281 // match(Set dst mem); 6282 6283 // ins_cost(110); 6284 // format %{ "leaq $dst, $mem\t# ptr idx" %} 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 leaPIdxOff(rRegP dst, indIndexOffset mem) 6291 %{ 6292 match(Set dst mem); 6293 6294 ins_cost(110); 6295 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 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 leaPIdxScale(rRegP dst, indIndexScale mem) 6302 %{ 6303 match(Set dst mem); 6304 6305 ins_cost(110); 6306 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 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 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 6313 %{ 6314 match(Set dst mem); 6315 6316 ins_cost(110); 6317 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 6318 opcode(0x8D); 6319 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6320 ins_pipe(ialu_reg_reg_fat); 6321 %} 6322 6323 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 6324 %{ 6325 match(Set dst mem); 6326 6327 ins_cost(110); 6328 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 6329 opcode(0x8D); 6330 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6331 ins_pipe(ialu_reg_reg_fat); 6332 %} 6333 6334 // Load Effective Address which uses Narrow (32-bits) oop 6335 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 6336 %{ 6337 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 6338 match(Set dst mem); 6339 6340 ins_cost(110); 6341 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 6342 opcode(0x8D); 6343 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6344 ins_pipe(ialu_reg_reg_fat); 6345 %} 6346 6347 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 6348 %{ 6349 predicate(Universe::narrow_oop_shift() == 0); 6350 match(Set dst mem); 6351 6352 ins_cost(110); // XXX 6353 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 6354 opcode(0x8D); 6355 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6356 ins_pipe(ialu_reg_reg_fat); 6357 %} 6358 6359 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 6360 %{ 6361 predicate(Universe::narrow_oop_shift() == 0); 6362 match(Set dst mem); 6363 6364 ins_cost(110); 6365 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 6366 opcode(0x8D); 6367 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6368 ins_pipe(ialu_reg_reg_fat); 6369 %} 6370 6371 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 6372 %{ 6373 predicate(Universe::narrow_oop_shift() == 0); 6374 match(Set dst mem); 6375 6376 ins_cost(110); 6377 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 6378 opcode(0x8D); 6379 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6380 ins_pipe(ialu_reg_reg_fat); 6381 %} 6382 6383 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 6384 %{ 6385 predicate(Universe::narrow_oop_shift() == 0); 6386 match(Set dst mem); 6387 6388 ins_cost(110); 6389 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 6390 opcode(0x8D); 6391 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6392 ins_pipe(ialu_reg_reg_fat); 6393 %} 6394 6395 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 6396 %{ 6397 predicate(Universe::narrow_oop_shift() == 0); 6398 match(Set dst mem); 6399 6400 ins_cost(110); 6401 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 6402 opcode(0x8D); 6403 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6404 ins_pipe(ialu_reg_reg_fat); 6405 %} 6406 6407 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 6408 %{ 6409 predicate(Universe::narrow_oop_shift() == 0); 6410 match(Set dst mem); 6411 6412 ins_cost(110); 6413 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 6414 opcode(0x8D); 6415 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6416 ins_pipe(ialu_reg_reg_fat); 6417 %} 6418 6419 instruct loadConI(rRegI dst, immI src) 6420 %{ 6421 match(Set dst src); 6422 6423 format %{ "movl $dst, $src\t# int" %} 6424 ins_encode(load_immI(dst, src)); 6425 ins_pipe(ialu_reg_fat); // XXX 6426 %} 6427 6428 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 6429 %{ 6430 match(Set dst src); 6431 effect(KILL cr); 6432 6433 ins_cost(50); 6434 format %{ "xorl $dst, $dst\t# int" %} 6435 opcode(0x33); /* + rd */ 6436 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 6437 ins_pipe(ialu_reg); 6438 %} 6439 6440 instruct loadConL(rRegL dst, immL src) 6441 %{ 6442 match(Set dst src); 6443 6444 ins_cost(150); 6445 format %{ "movq $dst, $src\t# long" %} 6446 ins_encode(load_immL(dst, src)); 6447 ins_pipe(ialu_reg); 6448 %} 6449 6450 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 6451 %{ 6452 match(Set dst src); 6453 effect(KILL cr); 6454 6455 ins_cost(50); 6456 format %{ "xorl $dst, $dst\t# long" %} 6457 opcode(0x33); /* + rd */ 6458 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 6459 ins_pipe(ialu_reg); // XXX 6460 %} 6461 6462 instruct loadConUL32(rRegL dst, immUL32 src) 6463 %{ 6464 match(Set dst src); 6465 6466 ins_cost(60); 6467 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 6468 ins_encode(load_immUL32(dst, src)); 6469 ins_pipe(ialu_reg); 6470 %} 6471 6472 instruct loadConL32(rRegL dst, immL32 src) 6473 %{ 6474 match(Set dst src); 6475 6476 ins_cost(70); 6477 format %{ "movq $dst, $src\t# long (32-bit)" %} 6478 ins_encode(load_immL32(dst, src)); 6479 ins_pipe(ialu_reg); 6480 %} 6481 6482 instruct loadConP(rRegP dst, immP con) %{ 6483 match(Set dst con); 6484 6485 format %{ "movq $dst, $con\t# ptr" %} 6486 ins_encode(load_immP(dst, con)); 6487 ins_pipe(ialu_reg_fat); // XXX 6488 %} 6489 6490 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 6491 %{ 6492 match(Set dst src); 6493 effect(KILL cr); 6494 6495 ins_cost(50); 6496 format %{ "xorl $dst, $dst\t# ptr" %} 6497 opcode(0x33); /* + rd */ 6498 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 6499 ins_pipe(ialu_reg); 6500 %} 6501 6502 instruct loadConP_poll(rRegP dst, immP_poll src) %{ 6503 match(Set dst src); 6504 format %{ "movq $dst, $src\t!ptr" %} 6505 ins_encode %{ 6506 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type); 6507 __ lea($dst$$Register, polling_page); 6508 %} 6509 ins_pipe(ialu_reg_fat); 6510 %} 6511 6512 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 6513 %{ 6514 match(Set dst src); 6515 effect(KILL cr); 6516 6517 ins_cost(60); 6518 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 6519 ins_encode(load_immP31(dst, src)); 6520 ins_pipe(ialu_reg); 6521 %} 6522 6523 instruct loadConF(regF dst, immF con) %{ 6524 match(Set dst con); 6525 ins_cost(125); 6526 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 6527 ins_encode %{ 6528 __ movflt($dst$$XMMRegister, $constantaddress($con)); 6529 %} 6530 ins_pipe(pipe_slow); 6531 %} 6532 6533 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 6534 match(Set dst src); 6535 effect(KILL cr); 6536 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 6537 ins_encode %{ 6538 __ xorq($dst$$Register, $dst$$Register); 6539 %} 6540 ins_pipe(ialu_reg); 6541 %} 6542 6543 instruct loadConN(rRegN dst, immN src) %{ 6544 match(Set dst src); 6545 6546 ins_cost(125); 6547 format %{ "movl $dst, $src\t# compressed ptr" %} 6548 ins_encode %{ 6549 address con = (address)$src$$constant; 6550 if (con == NULL) { 6551 ShouldNotReachHere(); 6552 } else { 6553 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 6554 } 6555 %} 6556 ins_pipe(ialu_reg_fat); // XXX 6557 %} 6558 6559 instruct loadConF0(regF dst, immF0 src) 6560 %{ 6561 match(Set dst src); 6562 ins_cost(100); 6563 6564 format %{ "xorps $dst, $dst\t# float 0.0" %} 6565 opcode(0x0F, 0x57); 6566 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 6567 ins_pipe(pipe_slow); 6568 %} 6569 6570 // Use the same format since predicate() can not be used here. 6571 instruct loadConD(regD dst, immD con) %{ 6572 match(Set dst con); 6573 ins_cost(125); 6574 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 6575 ins_encode %{ 6576 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 6577 %} 6578 ins_pipe(pipe_slow); 6579 %} 6580 6581 instruct loadConD0(regD dst, immD0 src) 6582 %{ 6583 match(Set dst src); 6584 ins_cost(100); 6585 6586 format %{ "xorpd $dst, $dst\t# double 0.0" %} 6587 opcode(0x66, 0x0F, 0x57); 6588 ins_encode(OpcP, REX_reg_reg(dst, dst), OpcS, OpcT, reg_reg(dst, dst)); 6589 ins_pipe(pipe_slow); 6590 %} 6591 6592 instruct loadSSI(rRegI dst, stackSlotI src) 6593 %{ 6594 match(Set dst src); 6595 6596 ins_cost(125); 6597 format %{ "movl $dst, $src\t# int stk" %} 6598 opcode(0x8B); 6599 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6600 ins_pipe(ialu_reg_mem); 6601 %} 6602 6603 instruct loadSSL(rRegL dst, stackSlotL src) 6604 %{ 6605 match(Set dst src); 6606 6607 ins_cost(125); 6608 format %{ "movq $dst, $src\t# long stk" %} 6609 opcode(0x8B); 6610 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6611 ins_pipe(ialu_reg_mem); 6612 %} 6613 6614 instruct loadSSP(rRegP dst, stackSlotP src) 6615 %{ 6616 match(Set dst src); 6617 6618 ins_cost(125); 6619 format %{ "movq $dst, $src\t# ptr stk" %} 6620 opcode(0x8B); 6621 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6622 ins_pipe(ialu_reg_mem); 6623 %} 6624 6625 instruct loadSSF(regF dst, stackSlotF src) 6626 %{ 6627 match(Set dst src); 6628 6629 ins_cost(125); 6630 format %{ "movss $dst, $src\t# float stk" %} 6631 opcode(0xF3, 0x0F, 0x10); 6632 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 6633 ins_pipe(pipe_slow); // XXX 6634 %} 6635 6636 // Use the same format since predicate() can not be used here. 6637 instruct loadSSD(regD dst, stackSlotD src) 6638 %{ 6639 match(Set dst src); 6640 6641 ins_cost(125); 6642 format %{ "movsd $dst, $src\t# double stk" %} 6643 ins_encode %{ 6644 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 6645 %} 6646 ins_pipe(pipe_slow); // XXX 6647 %} 6648 6649 // Prefetch instructions. 6650 // Must be safe to execute with invalid address (cannot fault). 6651 6652 instruct prefetchr( memory mem ) %{ 6653 predicate(ReadPrefetchInstr==3); 6654 match(PrefetchRead mem); 6655 ins_cost(125); 6656 6657 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} 6658 opcode(0x0F, 0x0D); /* Opcode 0F 0D /0 */ 6659 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem)); 6660 ins_pipe(ialu_mem); 6661 %} 6662 6663 instruct prefetchrNTA( memory mem ) %{ 6664 predicate(ReadPrefetchInstr==0); 6665 match(PrefetchRead mem); 6666 ins_cost(125); 6667 6668 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} 6669 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */ 6670 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem)); 6671 ins_pipe(ialu_mem); 6672 %} 6673 6674 instruct prefetchrT0( memory mem ) %{ 6675 predicate(ReadPrefetchInstr==1); 6676 match(PrefetchRead mem); 6677 ins_cost(125); 6678 6679 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} 6680 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */ 6681 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem)); 6682 ins_pipe(ialu_mem); 6683 %} 6684 6685 instruct prefetchrT2( memory mem ) %{ 6686 predicate(ReadPrefetchInstr==2); 6687 match(PrefetchRead mem); 6688 ins_cost(125); 6689 6690 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} 6691 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */ 6692 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x03, mem)); 6693 ins_pipe(ialu_mem); 6694 %} 6695 6696 instruct prefetchw( memory mem ) %{ 6697 predicate(AllocatePrefetchInstr==3); 6698 match(PrefetchWrite mem); 6699 ins_cost(125); 6700 6701 format %{ "PREFETCHW $mem\t# Prefetch into level 1 cache and mark modified" %} 6702 opcode(0x0F, 0x0D); /* Opcode 0F 0D /1 */ 6703 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem)); 6704 ins_pipe(ialu_mem); 6705 %} 6706 6707 instruct prefetchwNTA( memory mem ) %{ 6708 predicate(AllocatePrefetchInstr==0); 6709 match(PrefetchWrite mem); 6710 ins_cost(125); 6711 6712 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} 6713 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */ 6714 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem)); 6715 ins_pipe(ialu_mem); 6716 %} 6717 6718 instruct prefetchwT0( memory mem ) %{ 6719 predicate(AllocatePrefetchInstr==1); 6720 match(PrefetchWrite mem); 6721 ins_cost(125); 6722 6723 format %{ "PREFETCHT0 $mem\t# Prefetch to level 1 and 2 caches for write" %} 6724 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */ 6725 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem)); 6726 ins_pipe(ialu_mem); 6727 %} 6728 6729 instruct prefetchwT2( memory mem ) %{ 6730 predicate(AllocatePrefetchInstr==2); 6731 match(PrefetchWrite mem); 6732 ins_cost(125); 6733 6734 format %{ "PREFETCHT2 $mem\t# Prefetch to level 2 cache for write" %} 6735 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */ 6736 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x03, mem)); 6737 ins_pipe(ialu_mem); 6738 %} 6739 6740 //----------Store Instructions------------------------------------------------- 6741 6742 // Store Byte 6743 instruct storeB(memory mem, rRegI src) 6744 %{ 6745 match(Set mem (StoreB mem src)); 6746 6747 ins_cost(125); // XXX 6748 format %{ "movb $mem, $src\t# byte" %} 6749 opcode(0x88); 6750 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 6751 ins_pipe(ialu_mem_reg); 6752 %} 6753 6754 // Store Char/Short 6755 instruct storeC(memory mem, rRegI src) 6756 %{ 6757 match(Set mem (StoreC mem src)); 6758 6759 ins_cost(125); // XXX 6760 format %{ "movw $mem, $src\t# char/short" %} 6761 opcode(0x89); 6762 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6763 ins_pipe(ialu_mem_reg); 6764 %} 6765 6766 // Store Integer 6767 instruct storeI(memory mem, rRegI src) 6768 %{ 6769 match(Set mem (StoreI mem src)); 6770 6771 ins_cost(125); // XXX 6772 format %{ "movl $mem, $src\t# int" %} 6773 opcode(0x89); 6774 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6775 ins_pipe(ialu_mem_reg); 6776 %} 6777 6778 // Store Long 6779 instruct storeL(memory mem, rRegL src) 6780 %{ 6781 match(Set mem (StoreL mem src)); 6782 6783 ins_cost(125); // XXX 6784 format %{ "movq $mem, $src\t# long" %} 6785 opcode(0x89); 6786 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6787 ins_pipe(ialu_mem_reg); // XXX 6788 %} 6789 6790 // Store Pointer 6791 instruct storeP(memory mem, any_RegP src) 6792 %{ 6793 match(Set mem (StoreP mem src)); 6794 6795 ins_cost(125); // XXX 6796 format %{ "movq $mem, $src\t# ptr" %} 6797 opcode(0x89); 6798 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6799 ins_pipe(ialu_mem_reg); 6800 %} 6801 6802 instruct storeImmP0(memory mem, immP0 zero) 6803 %{ 6804 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6805 match(Set mem (StoreP mem zero)); 6806 6807 ins_cost(125); // XXX 6808 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 6809 ins_encode %{ 6810 __ movq($mem$$Address, r12); 6811 %} 6812 ins_pipe(ialu_mem_reg); 6813 %} 6814 6815 // Store NULL Pointer, mark word, or other simple pointer constant. 6816 instruct storeImmP(memory mem, immP31 src) 6817 %{ 6818 match(Set mem (StoreP mem src)); 6819 6820 ins_cost(150); // XXX 6821 format %{ "movq $mem, $src\t# ptr" %} 6822 opcode(0xC7); /* C7 /0 */ 6823 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6824 ins_pipe(ialu_mem_imm); 6825 %} 6826 6827 // Store Compressed Pointer 6828 instruct storeN(memory mem, rRegN src) 6829 %{ 6830 match(Set mem (StoreN mem src)); 6831 6832 ins_cost(125); // XXX 6833 format %{ "movl $mem, $src\t# compressed ptr" %} 6834 ins_encode %{ 6835 __ movl($mem$$Address, $src$$Register); 6836 %} 6837 ins_pipe(ialu_mem_reg); 6838 %} 6839 6840 instruct storeImmN0(memory mem, immN0 zero) 6841 %{ 6842 predicate(Universe::narrow_oop_base() == NULL); 6843 match(Set mem (StoreN mem zero)); 6844 6845 ins_cost(125); // XXX 6846 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6847 ins_encode %{ 6848 __ movl($mem$$Address, r12); 6849 %} 6850 ins_pipe(ialu_mem_reg); 6851 %} 6852 6853 instruct storeImmN(memory mem, immN src) 6854 %{ 6855 match(Set mem (StoreN mem src)); 6856 6857 ins_cost(150); // XXX 6858 format %{ "movl $mem, $src\t# compressed ptr" %} 6859 ins_encode %{ 6860 address con = (address)$src$$constant; 6861 if (con == NULL) { 6862 __ movl($mem$$Address, (int32_t)0); 6863 } else { 6864 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6865 } 6866 %} 6867 ins_pipe(ialu_mem_imm); 6868 %} 6869 6870 // Store Integer Immediate 6871 instruct storeImmI0(memory mem, immI0 zero) 6872 %{ 6873 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6874 match(Set mem (StoreI mem zero)); 6875 6876 ins_cost(125); // XXX 6877 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6878 ins_encode %{ 6879 __ movl($mem$$Address, r12); 6880 %} 6881 ins_pipe(ialu_mem_reg); 6882 %} 6883 6884 instruct storeImmI(memory mem, immI src) 6885 %{ 6886 match(Set mem (StoreI mem src)); 6887 6888 ins_cost(150); 6889 format %{ "movl $mem, $src\t# int" %} 6890 opcode(0xC7); /* C7 /0 */ 6891 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6892 ins_pipe(ialu_mem_imm); 6893 %} 6894 6895 // Store Long Immediate 6896 instruct storeImmL0(memory mem, immL0 zero) 6897 %{ 6898 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6899 match(Set mem (StoreL mem zero)); 6900 6901 ins_cost(125); // XXX 6902 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6903 ins_encode %{ 6904 __ movq($mem$$Address, r12); 6905 %} 6906 ins_pipe(ialu_mem_reg); 6907 %} 6908 6909 instruct storeImmL(memory mem, immL32 src) 6910 %{ 6911 match(Set mem (StoreL mem src)); 6912 6913 ins_cost(150); 6914 format %{ "movq $mem, $src\t# long" %} 6915 opcode(0xC7); /* C7 /0 */ 6916 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6917 ins_pipe(ialu_mem_imm); 6918 %} 6919 6920 // Store Short/Char Immediate 6921 instruct storeImmC0(memory mem, immI0 zero) 6922 %{ 6923 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6924 match(Set mem (StoreC mem zero)); 6925 6926 ins_cost(125); // XXX 6927 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6928 ins_encode %{ 6929 __ movw($mem$$Address, r12); 6930 %} 6931 ins_pipe(ialu_mem_reg); 6932 %} 6933 6934 instruct storeImmI16(memory mem, immI16 src) 6935 %{ 6936 predicate(UseStoreImmI16); 6937 match(Set mem (StoreC mem src)); 6938 6939 ins_cost(150); 6940 format %{ "movw $mem, $src\t# short/char" %} 6941 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6942 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6943 ins_pipe(ialu_mem_imm); 6944 %} 6945 6946 // Store Byte Immediate 6947 instruct storeImmB0(memory mem, immI0 zero) 6948 %{ 6949 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6950 match(Set mem (StoreB mem zero)); 6951 6952 ins_cost(125); // XXX 6953 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6954 ins_encode %{ 6955 __ movb($mem$$Address, r12); 6956 %} 6957 ins_pipe(ialu_mem_reg); 6958 %} 6959 6960 instruct storeImmB(memory mem, immI8 src) 6961 %{ 6962 match(Set mem (StoreB mem src)); 6963 6964 ins_cost(150); // XXX 6965 format %{ "movb $mem, $src\t# byte" %} 6966 opcode(0xC6); /* C6 /0 */ 6967 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6968 ins_pipe(ialu_mem_imm); 6969 %} 6970 6971 // Store Aligned Packed Byte XMM register to memory 6972 instruct storeA8B(memory mem, regD src) %{ 6973 match(Set mem (Store8B mem src)); 6974 ins_cost(145); 6975 format %{ "MOVQ $mem,$src\t! packed8B" %} 6976 ins_encode( movq_st(mem, src)); 6977 ins_pipe( pipe_slow ); 6978 %} 6979 6980 // Store Aligned Packed Char/Short XMM register to memory 6981 instruct storeA4C(memory mem, regD src) %{ 6982 match(Set mem (Store4C mem src)); 6983 ins_cost(145); 6984 format %{ "MOVQ $mem,$src\t! packed4C" %} 6985 ins_encode( movq_st(mem, src)); 6986 ins_pipe( pipe_slow ); 6987 %} 6988 6989 // Store Aligned Packed Integer XMM register to memory 6990 instruct storeA2I(memory mem, regD src) %{ 6991 match(Set mem (Store2I mem src)); 6992 ins_cost(145); 6993 format %{ "MOVQ $mem,$src\t! packed2I" %} 6994 ins_encode( movq_st(mem, src)); 6995 ins_pipe( pipe_slow ); 6996 %} 6997 6998 // Store CMS card-mark Immediate 6999 instruct storeImmCM0_reg(memory mem, immI0 zero) 7000 %{ 7001 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 7002 match(Set mem (StoreCM mem zero)); 7003 7004 ins_cost(125); // XXX 7005 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 7006 ins_encode %{ 7007 __ movb($mem$$Address, r12); 7008 %} 7009 ins_pipe(ialu_mem_reg); 7010 %} 7011 7012 instruct storeImmCM0(memory mem, immI0 src) 7013 %{ 7014 match(Set mem (StoreCM mem src)); 7015 7016 ins_cost(150); // XXX 7017 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 7018 opcode(0xC6); /* C6 /0 */ 7019 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 7020 ins_pipe(ialu_mem_imm); 7021 %} 7022 7023 // Store Aligned Packed Single Float XMM register to memory 7024 instruct storeA2F(memory mem, regD src) %{ 7025 match(Set mem (Store2F mem src)); 7026 ins_cost(145); 7027 format %{ "MOVQ $mem,$src\t! packed2F" %} 7028 ins_encode( movq_st(mem, src)); 7029 ins_pipe( pipe_slow ); 7030 %} 7031 7032 // Store Float 7033 instruct storeF(memory mem, regF src) 7034 %{ 7035 match(Set mem (StoreF mem src)); 7036 7037 ins_cost(95); // XXX 7038 format %{ "movss $mem, $src\t# float" %} 7039 opcode(0xF3, 0x0F, 0x11); 7040 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem)); 7041 ins_pipe(pipe_slow); // XXX 7042 %} 7043 7044 // Store immediate Float value (it is faster than store from XMM register) 7045 instruct storeF0(memory mem, immF0 zero) 7046 %{ 7047 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 7048 match(Set mem (StoreF mem zero)); 7049 7050 ins_cost(25); // XXX 7051 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 7052 ins_encode %{ 7053 __ movl($mem$$Address, r12); 7054 %} 7055 ins_pipe(ialu_mem_reg); 7056 %} 7057 7058 instruct storeF_imm(memory mem, immF src) 7059 %{ 7060 match(Set mem (StoreF mem src)); 7061 7062 ins_cost(50); 7063 format %{ "movl $mem, $src\t# float" %} 7064 opcode(0xC7); /* C7 /0 */ 7065 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 7066 ins_pipe(ialu_mem_imm); 7067 %} 7068 7069 // Store Double 7070 instruct storeD(memory mem, regD src) 7071 %{ 7072 match(Set mem (StoreD mem src)); 7073 7074 ins_cost(95); // XXX 7075 format %{ "movsd $mem, $src\t# double" %} 7076 opcode(0xF2, 0x0F, 0x11); 7077 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem)); 7078 ins_pipe(pipe_slow); // XXX 7079 %} 7080 7081 // Store immediate double 0.0 (it is faster than store from XMM register) 7082 instruct storeD0_imm(memory mem, immD0 src) 7083 %{ 7084 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 7085 match(Set mem (StoreD mem src)); 7086 7087 ins_cost(50); 7088 format %{ "movq $mem, $src\t# double 0." %} 7089 opcode(0xC7); /* C7 /0 */ 7090 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 7091 ins_pipe(ialu_mem_imm); 7092 %} 7093 7094 instruct storeD0(memory mem, immD0 zero) 7095 %{ 7096 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 7097 match(Set mem (StoreD mem zero)); 7098 7099 ins_cost(25); // XXX 7100 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 7101 ins_encode %{ 7102 __ movq($mem$$Address, r12); 7103 %} 7104 ins_pipe(ialu_mem_reg); 7105 %} 7106 7107 instruct storeSSI(stackSlotI dst, rRegI src) 7108 %{ 7109 match(Set dst src); 7110 7111 ins_cost(100); 7112 format %{ "movl $dst, $src\t# int stk" %} 7113 opcode(0x89); 7114 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7115 ins_pipe( ialu_mem_reg ); 7116 %} 7117 7118 instruct storeSSL(stackSlotL dst, rRegL src) 7119 %{ 7120 match(Set dst src); 7121 7122 ins_cost(100); 7123 format %{ "movq $dst, $src\t# long stk" %} 7124 opcode(0x89); 7125 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7126 ins_pipe(ialu_mem_reg); 7127 %} 7128 7129 instruct storeSSP(stackSlotP dst, rRegP src) 7130 %{ 7131 match(Set dst src); 7132 7133 ins_cost(100); 7134 format %{ "movq $dst, $src\t# ptr stk" %} 7135 opcode(0x89); 7136 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7137 ins_pipe(ialu_mem_reg); 7138 %} 7139 7140 instruct storeSSF(stackSlotF dst, regF src) 7141 %{ 7142 match(Set dst src); 7143 7144 ins_cost(95); // XXX 7145 format %{ "movss $dst, $src\t# float stk" %} 7146 opcode(0xF3, 0x0F, 0x11); 7147 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 7148 ins_pipe(pipe_slow); // XXX 7149 %} 7150 7151 instruct storeSSD(stackSlotD dst, regD src) 7152 %{ 7153 match(Set dst src); 7154 7155 ins_cost(95); // XXX 7156 format %{ "movsd $dst, $src\t# double stk" %} 7157 opcode(0xF2, 0x0F, 0x11); 7158 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 7159 ins_pipe(pipe_slow); // XXX 7160 %} 7161 7162 //----------BSWAP Instructions------------------------------------------------- 7163 instruct bytes_reverse_int(rRegI dst) %{ 7164 match(Set dst (ReverseBytesI dst)); 7165 7166 format %{ "bswapl $dst" %} 7167 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 7168 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 7169 ins_pipe( ialu_reg ); 7170 %} 7171 7172 instruct bytes_reverse_long(rRegL dst) %{ 7173 match(Set dst (ReverseBytesL dst)); 7174 7175 format %{ "bswapq $dst" %} 7176 7177 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 7178 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 7179 ins_pipe( ialu_reg); 7180 %} 7181 7182 instruct bytes_reverse_unsigned_short(rRegI dst) %{ 7183 match(Set dst (ReverseBytesUS dst)); 7184 7185 format %{ "bswapl $dst\n\t" 7186 "shrl $dst,16\n\t" %} 7187 ins_encode %{ 7188 __ bswapl($dst$$Register); 7189 __ shrl($dst$$Register, 16); 7190 %} 7191 ins_pipe( ialu_reg ); 7192 %} 7193 7194 instruct bytes_reverse_short(rRegI dst) %{ 7195 match(Set dst (ReverseBytesS dst)); 7196 7197 format %{ "bswapl $dst\n\t" 7198 "sar $dst,16\n\t" %} 7199 ins_encode %{ 7200 __ bswapl($dst$$Register); 7201 __ sarl($dst$$Register, 16); 7202 %} 7203 ins_pipe( ialu_reg ); 7204 %} 7205 7206 //---------- Zeros Count Instructions ------------------------------------------ 7207 7208 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 7209 predicate(UseCountLeadingZerosInstruction); 7210 match(Set dst (CountLeadingZerosI src)); 7211 effect(KILL cr); 7212 7213 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 7214 ins_encode %{ 7215 __ lzcntl($dst$$Register, $src$$Register); 7216 %} 7217 ins_pipe(ialu_reg); 7218 %} 7219 7220 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 7221 predicate(!UseCountLeadingZerosInstruction); 7222 match(Set dst (CountLeadingZerosI src)); 7223 effect(KILL cr); 7224 7225 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 7226 "jnz skip\n\t" 7227 "movl $dst, -1\n" 7228 "skip:\n\t" 7229 "negl $dst\n\t" 7230 "addl $dst, 31" %} 7231 ins_encode %{ 7232 Register Rdst = $dst$$Register; 7233 Register Rsrc = $src$$Register; 7234 Label skip; 7235 __ bsrl(Rdst, Rsrc); 7236 __ jccb(Assembler::notZero, skip); 7237 __ movl(Rdst, -1); 7238 __ bind(skip); 7239 __ negl(Rdst); 7240 __ addl(Rdst, BitsPerInt - 1); 7241 %} 7242 ins_pipe(ialu_reg); 7243 %} 7244 7245 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 7246 predicate(UseCountLeadingZerosInstruction); 7247 match(Set dst (CountLeadingZerosL src)); 7248 effect(KILL cr); 7249 7250 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 7251 ins_encode %{ 7252 __ lzcntq($dst$$Register, $src$$Register); 7253 %} 7254 ins_pipe(ialu_reg); 7255 %} 7256 7257 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 7258 predicate(!UseCountLeadingZerosInstruction); 7259 match(Set dst (CountLeadingZerosL src)); 7260 effect(KILL cr); 7261 7262 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 7263 "jnz skip\n\t" 7264 "movl $dst, -1\n" 7265 "skip:\n\t" 7266 "negl $dst\n\t" 7267 "addl $dst, 63" %} 7268 ins_encode %{ 7269 Register Rdst = $dst$$Register; 7270 Register Rsrc = $src$$Register; 7271 Label skip; 7272 __ bsrq(Rdst, Rsrc); 7273 __ jccb(Assembler::notZero, skip); 7274 __ movl(Rdst, -1); 7275 __ bind(skip); 7276 __ negl(Rdst); 7277 __ addl(Rdst, BitsPerLong - 1); 7278 %} 7279 ins_pipe(ialu_reg); 7280 %} 7281 7282 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 7283 match(Set dst (CountTrailingZerosI src)); 7284 effect(KILL cr); 7285 7286 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 7287 "jnz done\n\t" 7288 "movl $dst, 32\n" 7289 "done:" %} 7290 ins_encode %{ 7291 Register Rdst = $dst$$Register; 7292 Label done; 7293 __ bsfl(Rdst, $src$$Register); 7294 __ jccb(Assembler::notZero, done); 7295 __ movl(Rdst, BitsPerInt); 7296 __ bind(done); 7297 %} 7298 ins_pipe(ialu_reg); 7299 %} 7300 7301 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 7302 match(Set dst (CountTrailingZerosL src)); 7303 effect(KILL cr); 7304 7305 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 7306 "jnz done\n\t" 7307 "movl $dst, 64\n" 7308 "done:" %} 7309 ins_encode %{ 7310 Register Rdst = $dst$$Register; 7311 Label done; 7312 __ bsfq(Rdst, $src$$Register); 7313 __ jccb(Assembler::notZero, done); 7314 __ movl(Rdst, BitsPerLong); 7315 __ bind(done); 7316 %} 7317 ins_pipe(ialu_reg); 7318 %} 7319 7320 7321 //---------- Population Count Instructions ------------------------------------- 7322 7323 instruct popCountI(rRegI dst, rRegI src) %{ 7324 predicate(UsePopCountInstruction); 7325 match(Set dst (PopCountI src)); 7326 7327 format %{ "popcnt $dst, $src" %} 7328 ins_encode %{ 7329 __ popcntl($dst$$Register, $src$$Register); 7330 %} 7331 ins_pipe(ialu_reg); 7332 %} 7333 7334 instruct popCountI_mem(rRegI dst, memory mem) %{ 7335 predicate(UsePopCountInstruction); 7336 match(Set dst (PopCountI (LoadI mem))); 7337 7338 format %{ "popcnt $dst, $mem" %} 7339 ins_encode %{ 7340 __ popcntl($dst$$Register, $mem$$Address); 7341 %} 7342 ins_pipe(ialu_reg); 7343 %} 7344 7345 // Note: Long.bitCount(long) returns an int. 7346 instruct popCountL(rRegI dst, rRegL src) %{ 7347 predicate(UsePopCountInstruction); 7348 match(Set dst (PopCountL src)); 7349 7350 format %{ "popcnt $dst, $src" %} 7351 ins_encode %{ 7352 __ popcntq($dst$$Register, $src$$Register); 7353 %} 7354 ins_pipe(ialu_reg); 7355 %} 7356 7357 // Note: Long.bitCount(long) returns an int. 7358 instruct popCountL_mem(rRegI dst, memory mem) %{ 7359 predicate(UsePopCountInstruction); 7360 match(Set dst (PopCountL (LoadL mem))); 7361 7362 format %{ "popcnt $dst, $mem" %} 7363 ins_encode %{ 7364 __ popcntq($dst$$Register, $mem$$Address); 7365 %} 7366 ins_pipe(ialu_reg); 7367 %} 7368 7369 7370 //----------MemBar Instructions----------------------------------------------- 7371 // Memory barrier flavors 7372 7373 instruct membar_acquire() 7374 %{ 7375 match(MemBarAcquire); 7376 ins_cost(0); 7377 7378 size(0); 7379 format %{ "MEMBAR-acquire ! (empty encoding)" %} 7380 ins_encode(); 7381 ins_pipe(empty); 7382 %} 7383 7384 instruct membar_acquire_lock() 7385 %{ 7386 match(MemBarAcquire); 7387 predicate(Matcher::prior_fast_lock(n)); 7388 ins_cost(0); 7389 7390 size(0); 7391 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 7392 ins_encode(); 7393 ins_pipe(empty); 7394 %} 7395 7396 instruct membar_release() 7397 %{ 7398 match(MemBarRelease); 7399 ins_cost(0); 7400 7401 size(0); 7402 format %{ "MEMBAR-release ! (empty encoding)" %} 7403 ins_encode(); 7404 ins_pipe(empty); 7405 %} 7406 7407 instruct membar_release_lock() 7408 %{ 7409 match(MemBarRelease); 7410 predicate(Matcher::post_fast_unlock(n)); 7411 ins_cost(0); 7412 7413 size(0); 7414 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 7415 ins_encode(); 7416 ins_pipe(empty); 7417 %} 7418 7419 instruct membar_volatile(rFlagsReg cr) %{ 7420 match(MemBarVolatile); 7421 effect(KILL cr); 7422 ins_cost(400); 7423 7424 format %{ 7425 $$template 7426 if (os::is_MP()) { 7427 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 7428 } else { 7429 $$emit$$"MEMBAR-volatile ! (empty encoding)" 7430 } 7431 %} 7432 ins_encode %{ 7433 __ membar(Assembler::StoreLoad); 7434 %} 7435 ins_pipe(pipe_slow); 7436 %} 7437 7438 instruct unnecessary_membar_volatile() 7439 %{ 7440 match(MemBarVolatile); 7441 predicate(Matcher::post_store_load_barrier(n)); 7442 ins_cost(0); 7443 7444 size(0); 7445 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 7446 ins_encode(); 7447 ins_pipe(empty); 7448 %} 7449 7450 //----------Move Instructions-------------------------------------------------- 7451 7452 instruct castX2P(rRegP dst, rRegL src) 7453 %{ 7454 match(Set dst (CastX2P src)); 7455 7456 format %{ "movq $dst, $src\t# long->ptr" %} 7457 ins_encode(enc_copy_wide(dst, src)); 7458 ins_pipe(ialu_reg_reg); // XXX 7459 %} 7460 7461 instruct castP2X(rRegL dst, rRegP src) 7462 %{ 7463 match(Set dst (CastP2X src)); 7464 7465 format %{ "movq $dst, $src\t# ptr -> long" %} 7466 ins_encode(enc_copy_wide(dst, src)); 7467 ins_pipe(ialu_reg_reg); // XXX 7468 %} 7469 7470 7471 // Convert oop pointer into compressed form 7472 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 7473 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7474 match(Set dst (EncodeP src)); 7475 effect(KILL cr); 7476 format %{ "encode_heap_oop $dst,$src" %} 7477 ins_encode %{ 7478 Register s = $src$$Register; 7479 Register d = $dst$$Register; 7480 if (s != d) { 7481 __ movq(d, s); 7482 } 7483 __ encode_heap_oop(d); 7484 %} 7485 ins_pipe(ialu_reg_long); 7486 %} 7487 7488 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 7489 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7490 match(Set dst (EncodeP src)); 7491 effect(KILL cr); 7492 format %{ "encode_heap_oop_not_null $dst,$src" %} 7493 ins_encode %{ 7494 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7495 %} 7496 ins_pipe(ialu_reg_long); 7497 %} 7498 7499 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 7500 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7501 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant); 7502 match(Set dst (DecodeN src)); 7503 effect(KILL cr); 7504 format %{ "decode_heap_oop $dst,$src" %} 7505 ins_encode %{ 7506 Register s = $src$$Register; 7507 Register d = $dst$$Register; 7508 if (s != d) { 7509 __ movq(d, s); 7510 } 7511 __ decode_heap_oop(d); 7512 %} 7513 ins_pipe(ialu_reg_long); 7514 %} 7515 7516 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 7517 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7518 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); 7519 match(Set dst (DecodeN src)); 7520 effect(KILL cr); 7521 format %{ "decode_heap_oop_not_null $dst,$src" %} 7522 ins_encode %{ 7523 Register s = $src$$Register; 7524 Register d = $dst$$Register; 7525 if (s != d) { 7526 __ decode_heap_oop_not_null(d, s); 7527 } else { 7528 __ decode_heap_oop_not_null(d); 7529 } 7530 %} 7531 ins_pipe(ialu_reg_long); 7532 %} 7533 7534 7535 //----------Conditional Move--------------------------------------------------- 7536 // Jump 7537 // dummy instruction for generating temp registers 7538 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 7539 match(Jump (LShiftL switch_val shift)); 7540 ins_cost(350); 7541 predicate(false); 7542 effect(TEMP dest); 7543 7544 format %{ "leaq $dest, [$constantaddress]\n\t" 7545 "jmp [$dest + $switch_val << $shift]\n\t" %} 7546 ins_encode %{ 7547 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7548 // to do that and the compiler is using that register as one it can allocate. 7549 // So we build it all by hand. 7550 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 7551 // ArrayAddress dispatch(table, index); 7552 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 7553 __ lea($dest$$Register, $constantaddress); 7554 __ jmp(dispatch); 7555 %} 7556 ins_pipe(pipe_jmp); 7557 ins_pc_relative(1); 7558 %} 7559 7560 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 7561 match(Jump (AddL (LShiftL switch_val shift) offset)); 7562 ins_cost(350); 7563 effect(TEMP dest); 7564 7565 format %{ "leaq $dest, [$constantaddress]\n\t" 7566 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 7567 ins_encode %{ 7568 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7569 // to do that and the compiler is using that register as one it can allocate. 7570 // So we build it all by hand. 7571 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7572 // ArrayAddress dispatch(table, index); 7573 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7574 __ lea($dest$$Register, $constantaddress); 7575 __ jmp(dispatch); 7576 %} 7577 ins_pipe(pipe_jmp); 7578 ins_pc_relative(1); 7579 %} 7580 7581 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 7582 match(Jump switch_val); 7583 ins_cost(350); 7584 effect(TEMP dest); 7585 7586 format %{ "leaq $dest, [$constantaddress]\n\t" 7587 "jmp [$dest + $switch_val]\n\t" %} 7588 ins_encode %{ 7589 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7590 // to do that and the compiler is using that register as one it can allocate. 7591 // So we build it all by hand. 7592 // Address index(noreg, switch_reg, Address::times_1); 7593 // ArrayAddress dispatch(table, index); 7594 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 7595 __ lea($dest$$Register, $constantaddress); 7596 __ jmp(dispatch); 7597 %} 7598 ins_pipe(pipe_jmp); 7599 ins_pc_relative(1); 7600 %} 7601 7602 // Conditional move 7603 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 7604 %{ 7605 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7606 7607 ins_cost(200); // XXX 7608 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7609 opcode(0x0F, 0x40); 7610 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7611 ins_pipe(pipe_cmov_reg); 7612 %} 7613 7614 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 7615 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7616 7617 ins_cost(200); // XXX 7618 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7619 opcode(0x0F, 0x40); 7620 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7621 ins_pipe(pipe_cmov_reg); 7622 %} 7623 7624 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 7625 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7626 ins_cost(200); 7627 expand %{ 7628 cmovI_regU(cop, cr, dst, src); 7629 %} 7630 %} 7631 7632 // Conditional move 7633 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 7634 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7635 7636 ins_cost(250); // XXX 7637 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7638 opcode(0x0F, 0x40); 7639 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7640 ins_pipe(pipe_cmov_mem); 7641 %} 7642 7643 // Conditional move 7644 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 7645 %{ 7646 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7647 7648 ins_cost(250); // XXX 7649 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7650 opcode(0x0F, 0x40); 7651 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7652 ins_pipe(pipe_cmov_mem); 7653 %} 7654 7655 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 7656 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7657 ins_cost(250); 7658 expand %{ 7659 cmovI_memU(cop, cr, dst, src); 7660 %} 7661 %} 7662 7663 // Conditional move 7664 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 7665 %{ 7666 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7667 7668 ins_cost(200); // XXX 7669 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 7670 opcode(0x0F, 0x40); 7671 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7672 ins_pipe(pipe_cmov_reg); 7673 %} 7674 7675 // Conditional move 7676 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 7677 %{ 7678 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7679 7680 ins_cost(200); // XXX 7681 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 7682 opcode(0x0F, 0x40); 7683 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7684 ins_pipe(pipe_cmov_reg); 7685 %} 7686 7687 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 7688 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7689 ins_cost(200); 7690 expand %{ 7691 cmovN_regU(cop, cr, dst, src); 7692 %} 7693 %} 7694 7695 // Conditional move 7696 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7697 %{ 7698 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7699 7700 ins_cost(200); // XXX 7701 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 7702 opcode(0x0F, 0x40); 7703 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7704 ins_pipe(pipe_cmov_reg); // XXX 7705 %} 7706 7707 // Conditional move 7708 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 7709 %{ 7710 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7711 7712 ins_cost(200); // XXX 7713 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7714 opcode(0x0F, 0x40); 7715 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7716 ins_pipe(pipe_cmov_reg); // XXX 7717 %} 7718 7719 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 7720 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7721 ins_cost(200); 7722 expand %{ 7723 cmovP_regU(cop, cr, dst, src); 7724 %} 7725 %} 7726 7727 // DISABLED: Requires the ADLC to emit a bottom_type call that 7728 // correctly meets the two pointer arguments; one is an incoming 7729 // register but the other is a memory operand. ALSO appears to 7730 // be buggy with implicit null checks. 7731 // 7732 //// Conditional move 7733 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7734 //%{ 7735 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7736 // ins_cost(250); 7737 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7738 // opcode(0x0F,0x40); 7739 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7740 // ins_pipe( pipe_cmov_mem ); 7741 //%} 7742 // 7743 //// Conditional move 7744 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7745 //%{ 7746 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7747 // ins_cost(250); 7748 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 7749 // opcode(0x0F,0x40); 7750 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7751 // ins_pipe( pipe_cmov_mem ); 7752 //%} 7753 7754 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7755 %{ 7756 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7757 7758 ins_cost(200); // XXX 7759 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7760 opcode(0x0F, 0x40); 7761 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7762 ins_pipe(pipe_cmov_reg); // XXX 7763 %} 7764 7765 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7766 %{ 7767 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7768 7769 ins_cost(200); // XXX 7770 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7771 opcode(0x0F, 0x40); 7772 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7773 ins_pipe(pipe_cmov_mem); // XXX 7774 %} 7775 7776 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7777 %{ 7778 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7779 7780 ins_cost(200); // XXX 7781 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7782 opcode(0x0F, 0x40); 7783 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7784 ins_pipe(pipe_cmov_reg); // XXX 7785 %} 7786 7787 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7788 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7789 ins_cost(200); 7790 expand %{ 7791 cmovL_regU(cop, cr, dst, src); 7792 %} 7793 %} 7794 7795 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7796 %{ 7797 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7798 7799 ins_cost(200); // XXX 7800 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7801 opcode(0x0F, 0x40); 7802 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7803 ins_pipe(pipe_cmov_mem); // XXX 7804 %} 7805 7806 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7807 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7808 ins_cost(200); 7809 expand %{ 7810 cmovL_memU(cop, cr, dst, src); 7811 %} 7812 %} 7813 7814 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7815 %{ 7816 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7817 7818 ins_cost(200); // XXX 7819 format %{ "jn$cop skip\t# signed cmove float\n\t" 7820 "movss $dst, $src\n" 7821 "skip:" %} 7822 ins_encode(enc_cmovf_branch(cop, dst, src)); 7823 ins_pipe(pipe_slow); 7824 %} 7825 7826 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7827 // %{ 7828 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7829 7830 // ins_cost(200); // XXX 7831 // format %{ "jn$cop skip\t# signed cmove float\n\t" 7832 // "movss $dst, $src\n" 7833 // "skip:" %} 7834 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7835 // ins_pipe(pipe_slow); 7836 // %} 7837 7838 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7839 %{ 7840 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7841 7842 ins_cost(200); // XXX 7843 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7844 "movss $dst, $src\n" 7845 "skip:" %} 7846 ins_encode(enc_cmovf_branch(cop, dst, src)); 7847 ins_pipe(pipe_slow); 7848 %} 7849 7850 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7851 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7852 ins_cost(200); 7853 expand %{ 7854 cmovF_regU(cop, cr, dst, src); 7855 %} 7856 %} 7857 7858 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7859 %{ 7860 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7861 7862 ins_cost(200); // XXX 7863 format %{ "jn$cop skip\t# signed cmove double\n\t" 7864 "movsd $dst, $src\n" 7865 "skip:" %} 7866 ins_encode(enc_cmovd_branch(cop, dst, src)); 7867 ins_pipe(pipe_slow); 7868 %} 7869 7870 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7871 %{ 7872 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7873 7874 ins_cost(200); // XXX 7875 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7876 "movsd $dst, $src\n" 7877 "skip:" %} 7878 ins_encode(enc_cmovd_branch(cop, dst, src)); 7879 ins_pipe(pipe_slow); 7880 %} 7881 7882 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7883 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7884 ins_cost(200); 7885 expand %{ 7886 cmovD_regU(cop, cr, dst, src); 7887 %} 7888 %} 7889 7890 //----------Arithmetic Instructions-------------------------------------------- 7891 //----------Addition Instructions---------------------------------------------- 7892 7893 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7894 %{ 7895 match(Set dst (AddI dst src)); 7896 effect(KILL cr); 7897 7898 format %{ "addl $dst, $src\t# int" %} 7899 opcode(0x03); 7900 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7901 ins_pipe(ialu_reg_reg); 7902 %} 7903 7904 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7905 %{ 7906 match(Set dst (AddI dst src)); 7907 effect(KILL cr); 7908 7909 format %{ "addl $dst, $src\t# int" %} 7910 opcode(0x81, 0x00); /* /0 id */ 7911 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7912 ins_pipe( ialu_reg ); 7913 %} 7914 7915 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7916 %{ 7917 match(Set dst (AddI dst (LoadI src))); 7918 effect(KILL cr); 7919 7920 ins_cost(125); // XXX 7921 format %{ "addl $dst, $src\t# int" %} 7922 opcode(0x03); 7923 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7924 ins_pipe(ialu_reg_mem); 7925 %} 7926 7927 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7928 %{ 7929 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7930 effect(KILL cr); 7931 7932 ins_cost(150); // XXX 7933 format %{ "addl $dst, $src\t# int" %} 7934 opcode(0x01); /* Opcode 01 /r */ 7935 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7936 ins_pipe(ialu_mem_reg); 7937 %} 7938 7939 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7940 %{ 7941 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7942 effect(KILL cr); 7943 7944 ins_cost(125); // XXX 7945 format %{ "addl $dst, $src\t# int" %} 7946 opcode(0x81); /* Opcode 81 /0 id */ 7947 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7948 ins_pipe(ialu_mem_imm); 7949 %} 7950 7951 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7952 %{ 7953 predicate(UseIncDec); 7954 match(Set dst (AddI dst src)); 7955 effect(KILL cr); 7956 7957 format %{ "incl $dst\t# int" %} 7958 opcode(0xFF, 0x00); // FF /0 7959 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7960 ins_pipe(ialu_reg); 7961 %} 7962 7963 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7964 %{ 7965 predicate(UseIncDec); 7966 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7967 effect(KILL cr); 7968 7969 ins_cost(125); // XXX 7970 format %{ "incl $dst\t# int" %} 7971 opcode(0xFF); /* Opcode FF /0 */ 7972 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7973 ins_pipe(ialu_mem_imm); 7974 %} 7975 7976 // XXX why does that use AddI 7977 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7978 %{ 7979 predicate(UseIncDec); 7980 match(Set dst (AddI dst src)); 7981 effect(KILL cr); 7982 7983 format %{ "decl $dst\t# int" %} 7984 opcode(0xFF, 0x01); // FF /1 7985 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7986 ins_pipe(ialu_reg); 7987 %} 7988 7989 // XXX why does that use AddI 7990 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7991 %{ 7992 predicate(UseIncDec); 7993 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7994 effect(KILL cr); 7995 7996 ins_cost(125); // XXX 7997 format %{ "decl $dst\t# int" %} 7998 opcode(0xFF); /* Opcode FF /1 */ 7999 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 8000 ins_pipe(ialu_mem_imm); 8001 %} 8002 8003 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 8004 %{ 8005 match(Set dst (AddI src0 src1)); 8006 8007 ins_cost(110); 8008 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 8009 opcode(0x8D); /* 0x8D /r */ 8010 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 8011 ins_pipe(ialu_reg_reg); 8012 %} 8013 8014 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8015 %{ 8016 match(Set dst (AddL dst src)); 8017 effect(KILL cr); 8018 8019 format %{ "addq $dst, $src\t# long" %} 8020 opcode(0x03); 8021 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8022 ins_pipe(ialu_reg_reg); 8023 %} 8024 8025 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 8026 %{ 8027 match(Set dst (AddL dst src)); 8028 effect(KILL cr); 8029 8030 format %{ "addq $dst, $src\t# long" %} 8031 opcode(0x81, 0x00); /* /0 id */ 8032 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8033 ins_pipe( ialu_reg ); 8034 %} 8035 8036 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8037 %{ 8038 match(Set dst (AddL dst (LoadL src))); 8039 effect(KILL cr); 8040 8041 ins_cost(125); // XXX 8042 format %{ "addq $dst, $src\t# long" %} 8043 opcode(0x03); 8044 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8045 ins_pipe(ialu_reg_mem); 8046 %} 8047 8048 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8049 %{ 8050 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 8051 effect(KILL cr); 8052 8053 ins_cost(150); // XXX 8054 format %{ "addq $dst, $src\t# long" %} 8055 opcode(0x01); /* Opcode 01 /r */ 8056 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8057 ins_pipe(ialu_mem_reg); 8058 %} 8059 8060 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8061 %{ 8062 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 8063 effect(KILL cr); 8064 8065 ins_cost(125); // XXX 8066 format %{ "addq $dst, $src\t# long" %} 8067 opcode(0x81); /* Opcode 81 /0 id */ 8068 ins_encode(REX_mem_wide(dst), 8069 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 8070 ins_pipe(ialu_mem_imm); 8071 %} 8072 8073 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 8074 %{ 8075 predicate(UseIncDec); 8076 match(Set dst (AddL dst src)); 8077 effect(KILL cr); 8078 8079 format %{ "incq $dst\t# long" %} 8080 opcode(0xFF, 0x00); // FF /0 8081 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8082 ins_pipe(ialu_reg); 8083 %} 8084 8085 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 8086 %{ 8087 predicate(UseIncDec); 8088 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 8089 effect(KILL cr); 8090 8091 ins_cost(125); // XXX 8092 format %{ "incq $dst\t# long" %} 8093 opcode(0xFF); /* Opcode FF /0 */ 8094 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 8095 ins_pipe(ialu_mem_imm); 8096 %} 8097 8098 // XXX why does that use AddL 8099 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 8100 %{ 8101 predicate(UseIncDec); 8102 match(Set dst (AddL dst src)); 8103 effect(KILL cr); 8104 8105 format %{ "decq $dst\t# long" %} 8106 opcode(0xFF, 0x01); // FF /1 8107 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8108 ins_pipe(ialu_reg); 8109 %} 8110 8111 // XXX why does that use AddL 8112 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 8113 %{ 8114 predicate(UseIncDec); 8115 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 8116 effect(KILL cr); 8117 8118 ins_cost(125); // XXX 8119 format %{ "decq $dst\t# long" %} 8120 opcode(0xFF); /* Opcode FF /1 */ 8121 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 8122 ins_pipe(ialu_mem_imm); 8123 %} 8124 8125 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 8126 %{ 8127 match(Set dst (AddL src0 src1)); 8128 8129 ins_cost(110); 8130 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 8131 opcode(0x8D); /* 0x8D /r */ 8132 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 8133 ins_pipe(ialu_reg_reg); 8134 %} 8135 8136 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 8137 %{ 8138 match(Set dst (AddP dst src)); 8139 effect(KILL cr); 8140 8141 format %{ "addq $dst, $src\t# ptr" %} 8142 opcode(0x03); 8143 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8144 ins_pipe(ialu_reg_reg); 8145 %} 8146 8147 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 8148 %{ 8149 match(Set dst (AddP dst src)); 8150 effect(KILL cr); 8151 8152 format %{ "addq $dst, $src\t# ptr" %} 8153 opcode(0x81, 0x00); /* /0 id */ 8154 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8155 ins_pipe( ialu_reg ); 8156 %} 8157 8158 // XXX addP mem ops ???? 8159 8160 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 8161 %{ 8162 match(Set dst (AddP src0 src1)); 8163 8164 ins_cost(110); 8165 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 8166 opcode(0x8D); /* 0x8D /r */ 8167 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 8168 ins_pipe(ialu_reg_reg); 8169 %} 8170 8171 instruct checkCastPP(rRegP dst) 8172 %{ 8173 match(Set dst (CheckCastPP dst)); 8174 8175 size(0); 8176 format %{ "# checkcastPP of $dst" %} 8177 ins_encode(/* empty encoding */); 8178 ins_pipe(empty); 8179 %} 8180 8181 instruct castPP(rRegP dst) 8182 %{ 8183 match(Set dst (CastPP dst)); 8184 8185 size(0); 8186 format %{ "# castPP of $dst" %} 8187 ins_encode(/* empty encoding */); 8188 ins_pipe(empty); 8189 %} 8190 8191 instruct castII(rRegI dst) 8192 %{ 8193 match(Set dst (CastII dst)); 8194 8195 size(0); 8196 format %{ "# castII of $dst" %} 8197 ins_encode(/* empty encoding */); 8198 ins_cost(0); 8199 ins_pipe(empty); 8200 %} 8201 8202 // LoadP-locked same as a regular LoadP when used with compare-swap 8203 instruct loadPLocked(rRegP dst, memory mem) 8204 %{ 8205 match(Set dst (LoadPLocked mem)); 8206 8207 ins_cost(125); // XXX 8208 format %{ "movq $dst, $mem\t# ptr locked" %} 8209 opcode(0x8B); 8210 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 8211 ins_pipe(ialu_reg_mem); // XXX 8212 %} 8213 8214 // LoadL-locked - same as a regular LoadL when used with compare-swap 8215 instruct loadLLocked(rRegL dst, memory mem) 8216 %{ 8217 match(Set dst (LoadLLocked mem)); 8218 8219 ins_cost(125); // XXX 8220 format %{ "movq $dst, $mem\t# long locked" %} 8221 opcode(0x8B); 8222 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 8223 ins_pipe(ialu_reg_mem); // XXX 8224 %} 8225 8226 // Conditional-store of the updated heap-top. 8227 // Used during allocation of the shared heap. 8228 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 8229 8230 instruct storePConditional(memory heap_top_ptr, 8231 rax_RegP oldval, rRegP newval, 8232 rFlagsReg cr) 8233 %{ 8234 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8235 8236 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 8237 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 8238 opcode(0x0F, 0xB1); 8239 ins_encode(lock_prefix, 8240 REX_reg_mem_wide(newval, heap_top_ptr), 8241 OpcP, OpcS, 8242 reg_mem(newval, heap_top_ptr)); 8243 ins_pipe(pipe_cmpxchg); 8244 %} 8245 8246 // Conditional-store of an int value. 8247 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 8248 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 8249 %{ 8250 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8251 effect(KILL oldval); 8252 8253 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 8254 opcode(0x0F, 0xB1); 8255 ins_encode(lock_prefix, 8256 REX_reg_mem(newval, mem), 8257 OpcP, OpcS, 8258 reg_mem(newval, mem)); 8259 ins_pipe(pipe_cmpxchg); 8260 %} 8261 8262 // Conditional-store of a long value. 8263 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 8264 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 8265 %{ 8266 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8267 effect(KILL oldval); 8268 8269 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 8270 opcode(0x0F, 0xB1); 8271 ins_encode(lock_prefix, 8272 REX_reg_mem_wide(newval, mem), 8273 OpcP, OpcS, 8274 reg_mem(newval, mem)); 8275 ins_pipe(pipe_cmpxchg); 8276 %} 8277 8278 8279 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 8280 instruct compareAndSwapP(rRegI res, 8281 memory mem_ptr, 8282 rax_RegP oldval, rRegP newval, 8283 rFlagsReg cr) 8284 %{ 8285 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 8286 effect(KILL cr, KILL oldval); 8287 8288 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8289 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 8290 "sete $res\n\t" 8291 "movzbl $res, $res" %} 8292 opcode(0x0F, 0xB1); 8293 ins_encode(lock_prefix, 8294 REX_reg_mem_wide(newval, mem_ptr), 8295 OpcP, OpcS, 8296 reg_mem(newval, mem_ptr), 8297 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 8298 REX_reg_breg(res, res), // movzbl 8299 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 8300 ins_pipe( pipe_cmpxchg ); 8301 %} 8302 8303 instruct compareAndSwapL(rRegI res, 8304 memory mem_ptr, 8305 rax_RegL oldval, rRegL newval, 8306 rFlagsReg cr) 8307 %{ 8308 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 8309 effect(KILL cr, KILL oldval); 8310 8311 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8312 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 8313 "sete $res\n\t" 8314 "movzbl $res, $res" %} 8315 opcode(0x0F, 0xB1); 8316 ins_encode(lock_prefix, 8317 REX_reg_mem_wide(newval, mem_ptr), 8318 OpcP, OpcS, 8319 reg_mem(newval, mem_ptr), 8320 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 8321 REX_reg_breg(res, res), // movzbl 8322 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 8323 ins_pipe( pipe_cmpxchg ); 8324 %} 8325 8326 instruct compareAndSwapI(rRegI res, 8327 memory mem_ptr, 8328 rax_RegI oldval, rRegI newval, 8329 rFlagsReg cr) 8330 %{ 8331 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 8332 effect(KILL cr, KILL oldval); 8333 8334 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8335 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 8336 "sete $res\n\t" 8337 "movzbl $res, $res" %} 8338 opcode(0x0F, 0xB1); 8339 ins_encode(lock_prefix, 8340 REX_reg_mem(newval, mem_ptr), 8341 OpcP, OpcS, 8342 reg_mem(newval, mem_ptr), 8343 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 8344 REX_reg_breg(res, res), // movzbl 8345 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 8346 ins_pipe( pipe_cmpxchg ); 8347 %} 8348 8349 8350 instruct compareAndSwapN(rRegI res, 8351 memory mem_ptr, 8352 rax_RegN oldval, rRegN newval, 8353 rFlagsReg cr) %{ 8354 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 8355 effect(KILL cr, KILL oldval); 8356 8357 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8358 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 8359 "sete $res\n\t" 8360 "movzbl $res, $res" %} 8361 opcode(0x0F, 0xB1); 8362 ins_encode(lock_prefix, 8363 REX_reg_mem(newval, mem_ptr), 8364 OpcP, OpcS, 8365 reg_mem(newval, mem_ptr), 8366 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 8367 REX_reg_breg(res, res), // movzbl 8368 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 8369 ins_pipe( pipe_cmpxchg ); 8370 %} 8371 8372 //----------Subtraction Instructions------------------------------------------- 8373 8374 // Integer Subtraction Instructions 8375 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8376 %{ 8377 match(Set dst (SubI dst src)); 8378 effect(KILL cr); 8379 8380 format %{ "subl $dst, $src\t# int" %} 8381 opcode(0x2B); 8382 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8383 ins_pipe(ialu_reg_reg); 8384 %} 8385 8386 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8387 %{ 8388 match(Set dst (SubI dst src)); 8389 effect(KILL cr); 8390 8391 format %{ "subl $dst, $src\t# int" %} 8392 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8393 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8394 ins_pipe(ialu_reg); 8395 %} 8396 8397 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8398 %{ 8399 match(Set dst (SubI dst (LoadI src))); 8400 effect(KILL cr); 8401 8402 ins_cost(125); 8403 format %{ "subl $dst, $src\t# int" %} 8404 opcode(0x2B); 8405 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8406 ins_pipe(ialu_reg_mem); 8407 %} 8408 8409 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8410 %{ 8411 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8412 effect(KILL cr); 8413 8414 ins_cost(150); 8415 format %{ "subl $dst, $src\t# int" %} 8416 opcode(0x29); /* Opcode 29 /r */ 8417 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8418 ins_pipe(ialu_mem_reg); 8419 %} 8420 8421 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8422 %{ 8423 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8424 effect(KILL cr); 8425 8426 ins_cost(125); // XXX 8427 format %{ "subl $dst, $src\t# int" %} 8428 opcode(0x81); /* Opcode 81 /5 id */ 8429 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8430 ins_pipe(ialu_mem_imm); 8431 %} 8432 8433 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8434 %{ 8435 match(Set dst (SubL dst src)); 8436 effect(KILL cr); 8437 8438 format %{ "subq $dst, $src\t# long" %} 8439 opcode(0x2B); 8440 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8441 ins_pipe(ialu_reg_reg); 8442 %} 8443 8444 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8445 %{ 8446 match(Set dst (SubL dst src)); 8447 effect(KILL cr); 8448 8449 format %{ "subq $dst, $src\t# long" %} 8450 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8451 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8452 ins_pipe(ialu_reg); 8453 %} 8454 8455 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8456 %{ 8457 match(Set dst (SubL dst (LoadL src))); 8458 effect(KILL cr); 8459 8460 ins_cost(125); 8461 format %{ "subq $dst, $src\t# long" %} 8462 opcode(0x2B); 8463 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8464 ins_pipe(ialu_reg_mem); 8465 %} 8466 8467 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8468 %{ 8469 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8470 effect(KILL cr); 8471 8472 ins_cost(150); 8473 format %{ "subq $dst, $src\t# long" %} 8474 opcode(0x29); /* Opcode 29 /r */ 8475 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8476 ins_pipe(ialu_mem_reg); 8477 %} 8478 8479 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8480 %{ 8481 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8482 effect(KILL cr); 8483 8484 ins_cost(125); // XXX 8485 format %{ "subq $dst, $src\t# long" %} 8486 opcode(0x81); /* Opcode 81 /5 id */ 8487 ins_encode(REX_mem_wide(dst), 8488 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8489 ins_pipe(ialu_mem_imm); 8490 %} 8491 8492 // Subtract from a pointer 8493 // XXX hmpf??? 8494 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8495 %{ 8496 match(Set dst (AddP dst (SubI zero src))); 8497 effect(KILL cr); 8498 8499 format %{ "subq $dst, $src\t# ptr - int" %} 8500 opcode(0x2B); 8501 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8502 ins_pipe(ialu_reg_reg); 8503 %} 8504 8505 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8506 %{ 8507 match(Set dst (SubI zero dst)); 8508 effect(KILL cr); 8509 8510 format %{ "negl $dst\t# int" %} 8511 opcode(0xF7, 0x03); // Opcode F7 /3 8512 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8513 ins_pipe(ialu_reg); 8514 %} 8515 8516 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8517 %{ 8518 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8519 effect(KILL cr); 8520 8521 format %{ "negl $dst\t# int" %} 8522 opcode(0xF7, 0x03); // Opcode F7 /3 8523 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8524 ins_pipe(ialu_reg); 8525 %} 8526 8527 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8528 %{ 8529 match(Set dst (SubL zero dst)); 8530 effect(KILL cr); 8531 8532 format %{ "negq $dst\t# long" %} 8533 opcode(0xF7, 0x03); // Opcode F7 /3 8534 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8535 ins_pipe(ialu_reg); 8536 %} 8537 8538 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8539 %{ 8540 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8541 effect(KILL cr); 8542 8543 format %{ "negq $dst\t# long" %} 8544 opcode(0xF7, 0x03); // Opcode F7 /3 8545 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8546 ins_pipe(ialu_reg); 8547 %} 8548 8549 8550 //----------Multiplication/Division Instructions------------------------------- 8551 // Integer Multiplication Instructions 8552 // Multiply Register 8553 8554 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8555 %{ 8556 match(Set dst (MulI dst src)); 8557 effect(KILL cr); 8558 8559 ins_cost(300); 8560 format %{ "imull $dst, $src\t# int" %} 8561 opcode(0x0F, 0xAF); 8562 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8563 ins_pipe(ialu_reg_reg_alu0); 8564 %} 8565 8566 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8567 %{ 8568 match(Set dst (MulI src imm)); 8569 effect(KILL cr); 8570 8571 ins_cost(300); 8572 format %{ "imull $dst, $src, $imm\t# int" %} 8573 opcode(0x69); /* 69 /r id */ 8574 ins_encode(REX_reg_reg(dst, src), 8575 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8576 ins_pipe(ialu_reg_reg_alu0); 8577 %} 8578 8579 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8580 %{ 8581 match(Set dst (MulI dst (LoadI src))); 8582 effect(KILL cr); 8583 8584 ins_cost(350); 8585 format %{ "imull $dst, $src\t# int" %} 8586 opcode(0x0F, 0xAF); 8587 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8588 ins_pipe(ialu_reg_mem_alu0); 8589 %} 8590 8591 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8592 %{ 8593 match(Set dst (MulI (LoadI src) imm)); 8594 effect(KILL cr); 8595 8596 ins_cost(300); 8597 format %{ "imull $dst, $src, $imm\t# int" %} 8598 opcode(0x69); /* 69 /r id */ 8599 ins_encode(REX_reg_mem(dst, src), 8600 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8601 ins_pipe(ialu_reg_mem_alu0); 8602 %} 8603 8604 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8605 %{ 8606 match(Set dst (MulL dst src)); 8607 effect(KILL cr); 8608 8609 ins_cost(300); 8610 format %{ "imulq $dst, $src\t# long" %} 8611 opcode(0x0F, 0xAF); 8612 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8613 ins_pipe(ialu_reg_reg_alu0); 8614 %} 8615 8616 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8617 %{ 8618 match(Set dst (MulL src imm)); 8619 effect(KILL cr); 8620 8621 ins_cost(300); 8622 format %{ "imulq $dst, $src, $imm\t# long" %} 8623 opcode(0x69); /* 69 /r id */ 8624 ins_encode(REX_reg_reg_wide(dst, src), 8625 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8626 ins_pipe(ialu_reg_reg_alu0); 8627 %} 8628 8629 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8630 %{ 8631 match(Set dst (MulL dst (LoadL src))); 8632 effect(KILL cr); 8633 8634 ins_cost(350); 8635 format %{ "imulq $dst, $src\t# long" %} 8636 opcode(0x0F, 0xAF); 8637 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8638 ins_pipe(ialu_reg_mem_alu0); 8639 %} 8640 8641 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8642 %{ 8643 match(Set dst (MulL (LoadL src) imm)); 8644 effect(KILL cr); 8645 8646 ins_cost(300); 8647 format %{ "imulq $dst, $src, $imm\t# long" %} 8648 opcode(0x69); /* 69 /r id */ 8649 ins_encode(REX_reg_mem_wide(dst, src), 8650 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8651 ins_pipe(ialu_reg_mem_alu0); 8652 %} 8653 8654 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8655 %{ 8656 match(Set dst (MulHiL src rax)); 8657 effect(USE_KILL rax, KILL cr); 8658 8659 ins_cost(300); 8660 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8661 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8662 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8663 ins_pipe(ialu_reg_reg_alu0); 8664 %} 8665 8666 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8667 rFlagsReg cr) 8668 %{ 8669 match(Set rax (DivI rax div)); 8670 effect(KILL rdx, KILL cr); 8671 8672 ins_cost(30*100+10*100); // XXX 8673 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8674 "jne,s normal\n\t" 8675 "xorl rdx, rdx\n\t" 8676 "cmpl $div, -1\n\t" 8677 "je,s done\n" 8678 "normal: cdql\n\t" 8679 "idivl $div\n" 8680 "done:" %} 8681 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8682 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8683 ins_pipe(ialu_reg_reg_alu0); 8684 %} 8685 8686 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8687 rFlagsReg cr) 8688 %{ 8689 match(Set rax (DivL rax div)); 8690 effect(KILL rdx, KILL cr); 8691 8692 ins_cost(30*100+10*100); // XXX 8693 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8694 "cmpq rax, rdx\n\t" 8695 "jne,s normal\n\t" 8696 "xorl rdx, rdx\n\t" 8697 "cmpq $div, -1\n\t" 8698 "je,s done\n" 8699 "normal: cdqq\n\t" 8700 "idivq $div\n" 8701 "done:" %} 8702 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8703 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8704 ins_pipe(ialu_reg_reg_alu0); 8705 %} 8706 8707 // Integer DIVMOD with Register, both quotient and mod results 8708 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8709 rFlagsReg cr) 8710 %{ 8711 match(DivModI rax div); 8712 effect(KILL cr); 8713 8714 ins_cost(30*100+10*100); // XXX 8715 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8716 "jne,s normal\n\t" 8717 "xorl rdx, rdx\n\t" 8718 "cmpl $div, -1\n\t" 8719 "je,s done\n" 8720 "normal: cdql\n\t" 8721 "idivl $div\n" 8722 "done:" %} 8723 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8724 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8725 ins_pipe(pipe_slow); 8726 %} 8727 8728 // Long DIVMOD with Register, both quotient and mod results 8729 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8730 rFlagsReg cr) 8731 %{ 8732 match(DivModL rax div); 8733 effect(KILL cr); 8734 8735 ins_cost(30*100+10*100); // XXX 8736 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8737 "cmpq rax, rdx\n\t" 8738 "jne,s normal\n\t" 8739 "xorl rdx, rdx\n\t" 8740 "cmpq $div, -1\n\t" 8741 "je,s done\n" 8742 "normal: cdqq\n\t" 8743 "idivq $div\n" 8744 "done:" %} 8745 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8746 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8747 ins_pipe(pipe_slow); 8748 %} 8749 8750 //----------- DivL-By-Constant-Expansions-------------------------------------- 8751 // DivI cases are handled by the compiler 8752 8753 // Magic constant, reciprocal of 10 8754 instruct loadConL_0x6666666666666667(rRegL dst) 8755 %{ 8756 effect(DEF dst); 8757 8758 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8759 ins_encode(load_immL(dst, 0x6666666666666667)); 8760 ins_pipe(ialu_reg); 8761 %} 8762 8763 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8764 %{ 8765 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8766 8767 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8768 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8769 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8770 ins_pipe(ialu_reg_reg_alu0); 8771 %} 8772 8773 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8774 %{ 8775 effect(USE_DEF dst, KILL cr); 8776 8777 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8778 opcode(0xC1, 0x7); /* C1 /7 ib */ 8779 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8780 ins_pipe(ialu_reg); 8781 %} 8782 8783 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8784 %{ 8785 effect(USE_DEF dst, KILL cr); 8786 8787 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8788 opcode(0xC1, 0x7); /* C1 /7 ib */ 8789 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8790 ins_pipe(ialu_reg); 8791 %} 8792 8793 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8794 %{ 8795 match(Set dst (DivL src div)); 8796 8797 ins_cost((5+8)*100); 8798 expand %{ 8799 rax_RegL rax; // Killed temp 8800 rFlagsReg cr; // Killed 8801 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8802 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8803 sarL_rReg_63(src, cr); // sarq src, 63 8804 sarL_rReg_2(dst, cr); // sarq rdx, 2 8805 subL_rReg(dst, src, cr); // subl rdx, src 8806 %} 8807 %} 8808 8809 //----------------------------------------------------------------------------- 8810 8811 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8812 rFlagsReg cr) 8813 %{ 8814 match(Set rdx (ModI rax div)); 8815 effect(KILL rax, KILL cr); 8816 8817 ins_cost(300); // XXX 8818 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8819 "jne,s normal\n\t" 8820 "xorl rdx, rdx\n\t" 8821 "cmpl $div, -1\n\t" 8822 "je,s done\n" 8823 "normal: cdql\n\t" 8824 "idivl $div\n" 8825 "done:" %} 8826 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8827 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8828 ins_pipe(ialu_reg_reg_alu0); 8829 %} 8830 8831 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8832 rFlagsReg cr) 8833 %{ 8834 match(Set rdx (ModL rax div)); 8835 effect(KILL rax, KILL cr); 8836 8837 ins_cost(300); // XXX 8838 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8839 "cmpq rax, rdx\n\t" 8840 "jne,s normal\n\t" 8841 "xorl rdx, rdx\n\t" 8842 "cmpq $div, -1\n\t" 8843 "je,s done\n" 8844 "normal: cdqq\n\t" 8845 "idivq $div\n" 8846 "done:" %} 8847 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8848 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8849 ins_pipe(ialu_reg_reg_alu0); 8850 %} 8851 8852 // Integer Shift Instructions 8853 // Shift Left by one 8854 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8855 %{ 8856 match(Set dst (LShiftI dst shift)); 8857 effect(KILL cr); 8858 8859 format %{ "sall $dst, $shift" %} 8860 opcode(0xD1, 0x4); /* D1 /4 */ 8861 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8862 ins_pipe(ialu_reg); 8863 %} 8864 8865 // Shift Left by one 8866 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8867 %{ 8868 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8869 effect(KILL cr); 8870 8871 format %{ "sall $dst, $shift\t" %} 8872 opcode(0xD1, 0x4); /* D1 /4 */ 8873 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8874 ins_pipe(ialu_mem_imm); 8875 %} 8876 8877 // Shift Left by 8-bit immediate 8878 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8879 %{ 8880 match(Set dst (LShiftI dst shift)); 8881 effect(KILL cr); 8882 8883 format %{ "sall $dst, $shift" %} 8884 opcode(0xC1, 0x4); /* C1 /4 ib */ 8885 ins_encode(reg_opc_imm(dst, shift)); 8886 ins_pipe(ialu_reg); 8887 %} 8888 8889 // Shift Left by 8-bit immediate 8890 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8891 %{ 8892 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8893 effect(KILL cr); 8894 8895 format %{ "sall $dst, $shift" %} 8896 opcode(0xC1, 0x4); /* C1 /4 ib */ 8897 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8898 ins_pipe(ialu_mem_imm); 8899 %} 8900 8901 // Shift Left by variable 8902 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8903 %{ 8904 match(Set dst (LShiftI dst shift)); 8905 effect(KILL cr); 8906 8907 format %{ "sall $dst, $shift" %} 8908 opcode(0xD3, 0x4); /* D3 /4 */ 8909 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8910 ins_pipe(ialu_reg_reg); 8911 %} 8912 8913 // Shift Left by variable 8914 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8915 %{ 8916 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8917 effect(KILL cr); 8918 8919 format %{ "sall $dst, $shift" %} 8920 opcode(0xD3, 0x4); /* D3 /4 */ 8921 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8922 ins_pipe(ialu_mem_reg); 8923 %} 8924 8925 // Arithmetic shift right by one 8926 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8927 %{ 8928 match(Set dst (RShiftI dst shift)); 8929 effect(KILL cr); 8930 8931 format %{ "sarl $dst, $shift" %} 8932 opcode(0xD1, 0x7); /* D1 /7 */ 8933 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8934 ins_pipe(ialu_reg); 8935 %} 8936 8937 // Arithmetic shift right by one 8938 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8939 %{ 8940 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8941 effect(KILL cr); 8942 8943 format %{ "sarl $dst, $shift" %} 8944 opcode(0xD1, 0x7); /* D1 /7 */ 8945 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8946 ins_pipe(ialu_mem_imm); 8947 %} 8948 8949 // Arithmetic Shift Right by 8-bit immediate 8950 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8951 %{ 8952 match(Set dst (RShiftI dst shift)); 8953 effect(KILL cr); 8954 8955 format %{ "sarl $dst, $shift" %} 8956 opcode(0xC1, 0x7); /* C1 /7 ib */ 8957 ins_encode(reg_opc_imm(dst, shift)); 8958 ins_pipe(ialu_mem_imm); 8959 %} 8960 8961 // Arithmetic Shift Right by 8-bit immediate 8962 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8963 %{ 8964 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8965 effect(KILL cr); 8966 8967 format %{ "sarl $dst, $shift" %} 8968 opcode(0xC1, 0x7); /* C1 /7 ib */ 8969 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8970 ins_pipe(ialu_mem_imm); 8971 %} 8972 8973 // Arithmetic Shift Right by variable 8974 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8975 %{ 8976 match(Set dst (RShiftI dst shift)); 8977 effect(KILL cr); 8978 8979 format %{ "sarl $dst, $shift" %} 8980 opcode(0xD3, 0x7); /* D3 /7 */ 8981 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8982 ins_pipe(ialu_reg_reg); 8983 %} 8984 8985 // Arithmetic Shift Right by variable 8986 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8987 %{ 8988 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8989 effect(KILL cr); 8990 8991 format %{ "sarl $dst, $shift" %} 8992 opcode(0xD3, 0x7); /* D3 /7 */ 8993 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8994 ins_pipe(ialu_mem_reg); 8995 %} 8996 8997 // Logical shift right by one 8998 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8999 %{ 9000 match(Set dst (URShiftI dst shift)); 9001 effect(KILL cr); 9002 9003 format %{ "shrl $dst, $shift" %} 9004 opcode(0xD1, 0x5); /* D1 /5 */ 9005 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9006 ins_pipe(ialu_reg); 9007 %} 9008 9009 // Logical shift right by one 9010 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9011 %{ 9012 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9013 effect(KILL cr); 9014 9015 format %{ "shrl $dst, $shift" %} 9016 opcode(0xD1, 0x5); /* D1 /5 */ 9017 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 9018 ins_pipe(ialu_mem_imm); 9019 %} 9020 9021 // Logical Shift Right by 8-bit immediate 9022 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9023 %{ 9024 match(Set dst (URShiftI dst shift)); 9025 effect(KILL cr); 9026 9027 format %{ "shrl $dst, $shift" %} 9028 opcode(0xC1, 0x5); /* C1 /5 ib */ 9029 ins_encode(reg_opc_imm(dst, shift)); 9030 ins_pipe(ialu_reg); 9031 %} 9032 9033 // Logical Shift Right by 8-bit immediate 9034 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9035 %{ 9036 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9037 effect(KILL cr); 9038 9039 format %{ "shrl $dst, $shift" %} 9040 opcode(0xC1, 0x5); /* C1 /5 ib */ 9041 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 9042 ins_pipe(ialu_mem_imm); 9043 %} 9044 9045 // Logical Shift Right by variable 9046 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9047 %{ 9048 match(Set dst (URShiftI dst shift)); 9049 effect(KILL cr); 9050 9051 format %{ "shrl $dst, $shift" %} 9052 opcode(0xD3, 0x5); /* D3 /5 */ 9053 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9054 ins_pipe(ialu_reg_reg); 9055 %} 9056 9057 // Logical Shift Right by variable 9058 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9059 %{ 9060 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9061 effect(KILL cr); 9062 9063 format %{ "shrl $dst, $shift" %} 9064 opcode(0xD3, 0x5); /* D3 /5 */ 9065 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 9066 ins_pipe(ialu_mem_reg); 9067 %} 9068 9069 // Long Shift Instructions 9070 // Shift Left by one 9071 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9072 %{ 9073 match(Set dst (LShiftL dst shift)); 9074 effect(KILL cr); 9075 9076 format %{ "salq $dst, $shift" %} 9077 opcode(0xD1, 0x4); /* D1 /4 */ 9078 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9079 ins_pipe(ialu_reg); 9080 %} 9081 9082 // Shift Left by one 9083 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9084 %{ 9085 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9086 effect(KILL cr); 9087 9088 format %{ "salq $dst, $shift" %} 9089 opcode(0xD1, 0x4); /* D1 /4 */ 9090 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9091 ins_pipe(ialu_mem_imm); 9092 %} 9093 9094 // Shift Left by 8-bit immediate 9095 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9096 %{ 9097 match(Set dst (LShiftL dst shift)); 9098 effect(KILL cr); 9099 9100 format %{ "salq $dst, $shift" %} 9101 opcode(0xC1, 0x4); /* C1 /4 ib */ 9102 ins_encode(reg_opc_imm_wide(dst, shift)); 9103 ins_pipe(ialu_reg); 9104 %} 9105 9106 // Shift Left by 8-bit immediate 9107 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9108 %{ 9109 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9110 effect(KILL cr); 9111 9112 format %{ "salq $dst, $shift" %} 9113 opcode(0xC1, 0x4); /* C1 /4 ib */ 9114 ins_encode(REX_mem_wide(dst), OpcP, 9115 RM_opc_mem(secondary, dst), Con8or32(shift)); 9116 ins_pipe(ialu_mem_imm); 9117 %} 9118 9119 // Shift Left by variable 9120 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9121 %{ 9122 match(Set dst (LShiftL dst shift)); 9123 effect(KILL cr); 9124 9125 format %{ "salq $dst, $shift" %} 9126 opcode(0xD3, 0x4); /* D3 /4 */ 9127 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9128 ins_pipe(ialu_reg_reg); 9129 %} 9130 9131 // Shift Left by variable 9132 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9133 %{ 9134 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9135 effect(KILL cr); 9136 9137 format %{ "salq $dst, $shift" %} 9138 opcode(0xD3, 0x4); /* D3 /4 */ 9139 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9140 ins_pipe(ialu_mem_reg); 9141 %} 9142 9143 // Arithmetic shift right by one 9144 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9145 %{ 9146 match(Set dst (RShiftL dst shift)); 9147 effect(KILL cr); 9148 9149 format %{ "sarq $dst, $shift" %} 9150 opcode(0xD1, 0x7); /* D1 /7 */ 9151 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9152 ins_pipe(ialu_reg); 9153 %} 9154 9155 // Arithmetic shift right by one 9156 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9157 %{ 9158 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9159 effect(KILL cr); 9160 9161 format %{ "sarq $dst, $shift" %} 9162 opcode(0xD1, 0x7); /* D1 /7 */ 9163 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9164 ins_pipe(ialu_mem_imm); 9165 %} 9166 9167 // Arithmetic Shift Right by 8-bit immediate 9168 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9169 %{ 9170 match(Set dst (RShiftL dst shift)); 9171 effect(KILL cr); 9172 9173 format %{ "sarq $dst, $shift" %} 9174 opcode(0xC1, 0x7); /* C1 /7 ib */ 9175 ins_encode(reg_opc_imm_wide(dst, shift)); 9176 ins_pipe(ialu_mem_imm); 9177 %} 9178 9179 // Arithmetic Shift Right by 8-bit immediate 9180 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9181 %{ 9182 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9183 effect(KILL cr); 9184 9185 format %{ "sarq $dst, $shift" %} 9186 opcode(0xC1, 0x7); /* C1 /7 ib */ 9187 ins_encode(REX_mem_wide(dst), OpcP, 9188 RM_opc_mem(secondary, dst), Con8or32(shift)); 9189 ins_pipe(ialu_mem_imm); 9190 %} 9191 9192 // Arithmetic Shift Right by variable 9193 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9194 %{ 9195 match(Set dst (RShiftL dst shift)); 9196 effect(KILL cr); 9197 9198 format %{ "sarq $dst, $shift" %} 9199 opcode(0xD3, 0x7); /* D3 /7 */ 9200 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9201 ins_pipe(ialu_reg_reg); 9202 %} 9203 9204 // Arithmetic Shift Right by variable 9205 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9206 %{ 9207 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9208 effect(KILL cr); 9209 9210 format %{ "sarq $dst, $shift" %} 9211 opcode(0xD3, 0x7); /* D3 /7 */ 9212 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9213 ins_pipe(ialu_mem_reg); 9214 %} 9215 9216 // Logical shift right by one 9217 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9218 %{ 9219 match(Set dst (URShiftL dst shift)); 9220 effect(KILL cr); 9221 9222 format %{ "shrq $dst, $shift" %} 9223 opcode(0xD1, 0x5); /* D1 /5 */ 9224 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 9225 ins_pipe(ialu_reg); 9226 %} 9227 9228 // Logical shift right by one 9229 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9230 %{ 9231 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9232 effect(KILL cr); 9233 9234 format %{ "shrq $dst, $shift" %} 9235 opcode(0xD1, 0x5); /* D1 /5 */ 9236 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9237 ins_pipe(ialu_mem_imm); 9238 %} 9239 9240 // Logical Shift Right by 8-bit immediate 9241 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9242 %{ 9243 match(Set dst (URShiftL dst shift)); 9244 effect(KILL cr); 9245 9246 format %{ "shrq $dst, $shift" %} 9247 opcode(0xC1, 0x5); /* C1 /5 ib */ 9248 ins_encode(reg_opc_imm_wide(dst, shift)); 9249 ins_pipe(ialu_reg); 9250 %} 9251 9252 9253 // Logical Shift Right by 8-bit immediate 9254 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9255 %{ 9256 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9257 effect(KILL cr); 9258 9259 format %{ "shrq $dst, $shift" %} 9260 opcode(0xC1, 0x5); /* C1 /5 ib */ 9261 ins_encode(REX_mem_wide(dst), OpcP, 9262 RM_opc_mem(secondary, dst), Con8or32(shift)); 9263 ins_pipe(ialu_mem_imm); 9264 %} 9265 9266 // Logical Shift Right by variable 9267 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9268 %{ 9269 match(Set dst (URShiftL dst shift)); 9270 effect(KILL cr); 9271 9272 format %{ "shrq $dst, $shift" %} 9273 opcode(0xD3, 0x5); /* D3 /5 */ 9274 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9275 ins_pipe(ialu_reg_reg); 9276 %} 9277 9278 // Logical Shift Right by variable 9279 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9280 %{ 9281 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9282 effect(KILL cr); 9283 9284 format %{ "shrq $dst, $shift" %} 9285 opcode(0xD3, 0x5); /* D3 /5 */ 9286 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9287 ins_pipe(ialu_mem_reg); 9288 %} 9289 9290 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9291 // This idiom is used by the compiler for the i2b bytecode. 9292 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9293 %{ 9294 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9295 9296 format %{ "movsbl $dst, $src\t# i2b" %} 9297 opcode(0x0F, 0xBE); 9298 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9299 ins_pipe(ialu_reg_reg); 9300 %} 9301 9302 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9303 // This idiom is used by the compiler the i2s bytecode. 9304 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9305 %{ 9306 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9307 9308 format %{ "movswl $dst, $src\t# i2s" %} 9309 opcode(0x0F, 0xBF); 9310 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9311 ins_pipe(ialu_reg_reg); 9312 %} 9313 9314 // ROL/ROR instructions 9315 9316 // ROL expand 9317 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 9318 effect(KILL cr, USE_DEF dst); 9319 9320 format %{ "roll $dst" %} 9321 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9322 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9323 ins_pipe(ialu_reg); 9324 %} 9325 9326 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 9327 effect(USE_DEF dst, USE shift, KILL cr); 9328 9329 format %{ "roll $dst, $shift" %} 9330 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9331 ins_encode( reg_opc_imm(dst, shift) ); 9332 ins_pipe(ialu_reg); 9333 %} 9334 9335 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9336 %{ 9337 effect(USE_DEF dst, USE shift, KILL cr); 9338 9339 format %{ "roll $dst, $shift" %} 9340 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9341 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9342 ins_pipe(ialu_reg_reg); 9343 %} 9344 // end of ROL expand 9345 9346 // Rotate Left by one 9347 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9348 %{ 9349 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9350 9351 expand %{ 9352 rolI_rReg_imm1(dst, cr); 9353 %} 9354 %} 9355 9356 // Rotate Left by 8-bit immediate 9357 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9358 %{ 9359 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9360 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9361 9362 expand %{ 9363 rolI_rReg_imm8(dst, lshift, cr); 9364 %} 9365 %} 9366 9367 // Rotate Left by variable 9368 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9369 %{ 9370 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9371 9372 expand %{ 9373 rolI_rReg_CL(dst, shift, cr); 9374 %} 9375 %} 9376 9377 // Rotate Left by variable 9378 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9379 %{ 9380 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9381 9382 expand %{ 9383 rolI_rReg_CL(dst, shift, cr); 9384 %} 9385 %} 9386 9387 // ROR expand 9388 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9389 %{ 9390 effect(USE_DEF dst, KILL cr); 9391 9392 format %{ "rorl $dst" %} 9393 opcode(0xD1, 0x1); /* D1 /1 */ 9394 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9395 ins_pipe(ialu_reg); 9396 %} 9397 9398 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9399 %{ 9400 effect(USE_DEF dst, USE shift, KILL cr); 9401 9402 format %{ "rorl $dst, $shift" %} 9403 opcode(0xC1, 0x1); /* C1 /1 ib */ 9404 ins_encode(reg_opc_imm(dst, shift)); 9405 ins_pipe(ialu_reg); 9406 %} 9407 9408 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9409 %{ 9410 effect(USE_DEF dst, USE shift, KILL cr); 9411 9412 format %{ "rorl $dst, $shift" %} 9413 opcode(0xD3, 0x1); /* D3 /1 */ 9414 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9415 ins_pipe(ialu_reg_reg); 9416 %} 9417 // end of ROR expand 9418 9419 // Rotate Right by one 9420 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9421 %{ 9422 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9423 9424 expand %{ 9425 rorI_rReg_imm1(dst, cr); 9426 %} 9427 %} 9428 9429 // Rotate Right by 8-bit immediate 9430 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9431 %{ 9432 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9433 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9434 9435 expand %{ 9436 rorI_rReg_imm8(dst, rshift, cr); 9437 %} 9438 %} 9439 9440 // Rotate Right by variable 9441 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9442 %{ 9443 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9444 9445 expand %{ 9446 rorI_rReg_CL(dst, shift, cr); 9447 %} 9448 %} 9449 9450 // Rotate Right by variable 9451 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9452 %{ 9453 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9454 9455 expand %{ 9456 rorI_rReg_CL(dst, shift, cr); 9457 %} 9458 %} 9459 9460 // for long rotate 9461 // ROL expand 9462 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9463 effect(USE_DEF dst, KILL cr); 9464 9465 format %{ "rolq $dst" %} 9466 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9467 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9468 ins_pipe(ialu_reg); 9469 %} 9470 9471 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9472 effect(USE_DEF dst, USE shift, KILL cr); 9473 9474 format %{ "rolq $dst, $shift" %} 9475 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9476 ins_encode( reg_opc_imm_wide(dst, shift) ); 9477 ins_pipe(ialu_reg); 9478 %} 9479 9480 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9481 %{ 9482 effect(USE_DEF dst, USE shift, KILL cr); 9483 9484 format %{ "rolq $dst, $shift" %} 9485 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9486 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9487 ins_pipe(ialu_reg_reg); 9488 %} 9489 // end of ROL expand 9490 9491 // Rotate Left by one 9492 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9493 %{ 9494 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9495 9496 expand %{ 9497 rolL_rReg_imm1(dst, cr); 9498 %} 9499 %} 9500 9501 // Rotate Left by 8-bit immediate 9502 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9503 %{ 9504 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9505 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9506 9507 expand %{ 9508 rolL_rReg_imm8(dst, lshift, cr); 9509 %} 9510 %} 9511 9512 // Rotate Left by variable 9513 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9514 %{ 9515 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9516 9517 expand %{ 9518 rolL_rReg_CL(dst, shift, cr); 9519 %} 9520 %} 9521 9522 // Rotate Left by variable 9523 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9524 %{ 9525 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9526 9527 expand %{ 9528 rolL_rReg_CL(dst, shift, cr); 9529 %} 9530 %} 9531 9532 // ROR expand 9533 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9534 %{ 9535 effect(USE_DEF dst, KILL cr); 9536 9537 format %{ "rorq $dst" %} 9538 opcode(0xD1, 0x1); /* D1 /1 */ 9539 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9540 ins_pipe(ialu_reg); 9541 %} 9542 9543 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9544 %{ 9545 effect(USE_DEF dst, USE shift, KILL cr); 9546 9547 format %{ "rorq $dst, $shift" %} 9548 opcode(0xC1, 0x1); /* C1 /1 ib */ 9549 ins_encode(reg_opc_imm_wide(dst, shift)); 9550 ins_pipe(ialu_reg); 9551 %} 9552 9553 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9554 %{ 9555 effect(USE_DEF dst, USE shift, KILL cr); 9556 9557 format %{ "rorq $dst, $shift" %} 9558 opcode(0xD3, 0x1); /* D3 /1 */ 9559 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9560 ins_pipe(ialu_reg_reg); 9561 %} 9562 // end of ROR expand 9563 9564 // Rotate Right by one 9565 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9566 %{ 9567 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9568 9569 expand %{ 9570 rorL_rReg_imm1(dst, cr); 9571 %} 9572 %} 9573 9574 // Rotate Right by 8-bit immediate 9575 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9576 %{ 9577 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9578 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9579 9580 expand %{ 9581 rorL_rReg_imm8(dst, rshift, cr); 9582 %} 9583 %} 9584 9585 // Rotate Right by variable 9586 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9587 %{ 9588 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9589 9590 expand %{ 9591 rorL_rReg_CL(dst, shift, cr); 9592 %} 9593 %} 9594 9595 // Rotate Right by variable 9596 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9597 %{ 9598 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9599 9600 expand %{ 9601 rorL_rReg_CL(dst, shift, cr); 9602 %} 9603 %} 9604 9605 // Logical Instructions 9606 9607 // Integer Logical Instructions 9608 9609 // And Instructions 9610 // And Register with Register 9611 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9612 %{ 9613 match(Set dst (AndI dst src)); 9614 effect(KILL cr); 9615 9616 format %{ "andl $dst, $src\t# int" %} 9617 opcode(0x23); 9618 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9619 ins_pipe(ialu_reg_reg); 9620 %} 9621 9622 // And Register with Immediate 255 9623 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9624 %{ 9625 match(Set dst (AndI dst src)); 9626 9627 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9628 opcode(0x0F, 0xB6); 9629 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9630 ins_pipe(ialu_reg); 9631 %} 9632 9633 // And Register with Immediate 255 and promote to long 9634 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9635 %{ 9636 match(Set dst (ConvI2L (AndI src mask))); 9637 9638 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9639 opcode(0x0F, 0xB6); 9640 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9641 ins_pipe(ialu_reg); 9642 %} 9643 9644 // And Register with Immediate 65535 9645 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9646 %{ 9647 match(Set dst (AndI dst src)); 9648 9649 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9650 opcode(0x0F, 0xB7); 9651 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9652 ins_pipe(ialu_reg); 9653 %} 9654 9655 // And Register with Immediate 65535 and promote to long 9656 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9657 %{ 9658 match(Set dst (ConvI2L (AndI src mask))); 9659 9660 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9661 opcode(0x0F, 0xB7); 9662 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9663 ins_pipe(ialu_reg); 9664 %} 9665 9666 // And Register with Immediate 9667 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9668 %{ 9669 match(Set dst (AndI dst src)); 9670 effect(KILL cr); 9671 9672 format %{ "andl $dst, $src\t# int" %} 9673 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9674 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9675 ins_pipe(ialu_reg); 9676 %} 9677 9678 // And Register with Memory 9679 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9680 %{ 9681 match(Set dst (AndI dst (LoadI src))); 9682 effect(KILL cr); 9683 9684 ins_cost(125); 9685 format %{ "andl $dst, $src\t# int" %} 9686 opcode(0x23); 9687 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9688 ins_pipe(ialu_reg_mem); 9689 %} 9690 9691 // And Memory with Register 9692 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9693 %{ 9694 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9695 effect(KILL cr); 9696 9697 ins_cost(150); 9698 format %{ "andl $dst, $src\t# int" %} 9699 opcode(0x21); /* Opcode 21 /r */ 9700 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9701 ins_pipe(ialu_mem_reg); 9702 %} 9703 9704 // And Memory with Immediate 9705 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9706 %{ 9707 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9708 effect(KILL cr); 9709 9710 ins_cost(125); 9711 format %{ "andl $dst, $src\t# int" %} 9712 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9713 ins_encode(REX_mem(dst), OpcSE(src), 9714 RM_opc_mem(secondary, dst), Con8or32(src)); 9715 ins_pipe(ialu_mem_imm); 9716 %} 9717 9718 // Or Instructions 9719 // Or Register with Register 9720 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9721 %{ 9722 match(Set dst (OrI dst src)); 9723 effect(KILL cr); 9724 9725 format %{ "orl $dst, $src\t# int" %} 9726 opcode(0x0B); 9727 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9728 ins_pipe(ialu_reg_reg); 9729 %} 9730 9731 // Or Register with Immediate 9732 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9733 %{ 9734 match(Set dst (OrI dst src)); 9735 effect(KILL cr); 9736 9737 format %{ "orl $dst, $src\t# int" %} 9738 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9739 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9740 ins_pipe(ialu_reg); 9741 %} 9742 9743 // Or Register with Memory 9744 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9745 %{ 9746 match(Set dst (OrI dst (LoadI src))); 9747 effect(KILL cr); 9748 9749 ins_cost(125); 9750 format %{ "orl $dst, $src\t# int" %} 9751 opcode(0x0B); 9752 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9753 ins_pipe(ialu_reg_mem); 9754 %} 9755 9756 // Or Memory with Register 9757 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9758 %{ 9759 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9760 effect(KILL cr); 9761 9762 ins_cost(150); 9763 format %{ "orl $dst, $src\t# int" %} 9764 opcode(0x09); /* Opcode 09 /r */ 9765 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9766 ins_pipe(ialu_mem_reg); 9767 %} 9768 9769 // Or Memory with Immediate 9770 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9771 %{ 9772 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9773 effect(KILL cr); 9774 9775 ins_cost(125); 9776 format %{ "orl $dst, $src\t# int" %} 9777 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9778 ins_encode(REX_mem(dst), OpcSE(src), 9779 RM_opc_mem(secondary, dst), Con8or32(src)); 9780 ins_pipe(ialu_mem_imm); 9781 %} 9782 9783 // Xor Instructions 9784 // Xor Register with Register 9785 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9786 %{ 9787 match(Set dst (XorI dst src)); 9788 effect(KILL cr); 9789 9790 format %{ "xorl $dst, $src\t# int" %} 9791 opcode(0x33); 9792 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9793 ins_pipe(ialu_reg_reg); 9794 %} 9795 9796 // Xor Register with Immediate -1 9797 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9798 match(Set dst (XorI dst imm)); 9799 9800 format %{ "not $dst" %} 9801 ins_encode %{ 9802 __ notl($dst$$Register); 9803 %} 9804 ins_pipe(ialu_reg); 9805 %} 9806 9807 // Xor Register with Immediate 9808 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9809 %{ 9810 match(Set dst (XorI dst src)); 9811 effect(KILL cr); 9812 9813 format %{ "xorl $dst, $src\t# int" %} 9814 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9815 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9816 ins_pipe(ialu_reg); 9817 %} 9818 9819 // Xor Register with Memory 9820 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9821 %{ 9822 match(Set dst (XorI dst (LoadI src))); 9823 effect(KILL cr); 9824 9825 ins_cost(125); 9826 format %{ "xorl $dst, $src\t# int" %} 9827 opcode(0x33); 9828 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9829 ins_pipe(ialu_reg_mem); 9830 %} 9831 9832 // Xor Memory with Register 9833 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9834 %{ 9835 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9836 effect(KILL cr); 9837 9838 ins_cost(150); 9839 format %{ "xorl $dst, $src\t# int" %} 9840 opcode(0x31); /* Opcode 31 /r */ 9841 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9842 ins_pipe(ialu_mem_reg); 9843 %} 9844 9845 // Xor Memory with Immediate 9846 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9847 %{ 9848 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9849 effect(KILL cr); 9850 9851 ins_cost(125); 9852 format %{ "xorl $dst, $src\t# int" %} 9853 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9854 ins_encode(REX_mem(dst), OpcSE(src), 9855 RM_opc_mem(secondary, dst), Con8or32(src)); 9856 ins_pipe(ialu_mem_imm); 9857 %} 9858 9859 9860 // Long Logical Instructions 9861 9862 // And Instructions 9863 // And Register with Register 9864 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9865 %{ 9866 match(Set dst (AndL dst src)); 9867 effect(KILL cr); 9868 9869 format %{ "andq $dst, $src\t# long" %} 9870 opcode(0x23); 9871 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9872 ins_pipe(ialu_reg_reg); 9873 %} 9874 9875 // And Register with Immediate 255 9876 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9877 %{ 9878 match(Set dst (AndL dst src)); 9879 9880 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9881 opcode(0x0F, 0xB6); 9882 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9883 ins_pipe(ialu_reg); 9884 %} 9885 9886 // And Register with Immediate 65535 9887 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9888 %{ 9889 match(Set dst (AndL dst src)); 9890 9891 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9892 opcode(0x0F, 0xB7); 9893 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9894 ins_pipe(ialu_reg); 9895 %} 9896 9897 // And Register with Immediate 9898 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9899 %{ 9900 match(Set dst (AndL dst src)); 9901 effect(KILL cr); 9902 9903 format %{ "andq $dst, $src\t# long" %} 9904 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9905 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9906 ins_pipe(ialu_reg); 9907 %} 9908 9909 // And Register with Memory 9910 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9911 %{ 9912 match(Set dst (AndL dst (LoadL src))); 9913 effect(KILL cr); 9914 9915 ins_cost(125); 9916 format %{ "andq $dst, $src\t# long" %} 9917 opcode(0x23); 9918 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9919 ins_pipe(ialu_reg_mem); 9920 %} 9921 9922 // And Memory with Register 9923 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9924 %{ 9925 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9926 effect(KILL cr); 9927 9928 ins_cost(150); 9929 format %{ "andq $dst, $src\t# long" %} 9930 opcode(0x21); /* Opcode 21 /r */ 9931 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9932 ins_pipe(ialu_mem_reg); 9933 %} 9934 9935 // And Memory with Immediate 9936 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9937 %{ 9938 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9939 effect(KILL cr); 9940 9941 ins_cost(125); 9942 format %{ "andq $dst, $src\t# long" %} 9943 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9944 ins_encode(REX_mem_wide(dst), OpcSE(src), 9945 RM_opc_mem(secondary, dst), Con8or32(src)); 9946 ins_pipe(ialu_mem_imm); 9947 %} 9948 9949 // Or Instructions 9950 // Or Register with Register 9951 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9952 %{ 9953 match(Set dst (OrL dst src)); 9954 effect(KILL cr); 9955 9956 format %{ "orq $dst, $src\t# long" %} 9957 opcode(0x0B); 9958 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9959 ins_pipe(ialu_reg_reg); 9960 %} 9961 9962 // Use any_RegP to match R15 (TLS register) without spilling. 9963 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9964 match(Set dst (OrL dst (CastP2X src))); 9965 effect(KILL cr); 9966 9967 format %{ "orq $dst, $src\t# long" %} 9968 opcode(0x0B); 9969 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9970 ins_pipe(ialu_reg_reg); 9971 %} 9972 9973 9974 // Or Register with Immediate 9975 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9976 %{ 9977 match(Set dst (OrL dst src)); 9978 effect(KILL cr); 9979 9980 format %{ "orq $dst, $src\t# long" %} 9981 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9982 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9983 ins_pipe(ialu_reg); 9984 %} 9985 9986 // Or Register with Memory 9987 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9988 %{ 9989 match(Set dst (OrL dst (LoadL src))); 9990 effect(KILL cr); 9991 9992 ins_cost(125); 9993 format %{ "orq $dst, $src\t# long" %} 9994 opcode(0x0B); 9995 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9996 ins_pipe(ialu_reg_mem); 9997 %} 9998 9999 // Or Memory with Register 10000 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10001 %{ 10002 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10003 effect(KILL cr); 10004 10005 ins_cost(150); 10006 format %{ "orq $dst, $src\t# long" %} 10007 opcode(0x09); /* Opcode 09 /r */ 10008 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10009 ins_pipe(ialu_mem_reg); 10010 %} 10011 10012 // Or Memory with Immediate 10013 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10014 %{ 10015 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10016 effect(KILL cr); 10017 10018 ins_cost(125); 10019 format %{ "orq $dst, $src\t# long" %} 10020 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 10021 ins_encode(REX_mem_wide(dst), OpcSE(src), 10022 RM_opc_mem(secondary, dst), Con8or32(src)); 10023 ins_pipe(ialu_mem_imm); 10024 %} 10025 10026 // Xor Instructions 10027 // Xor Register with Register 10028 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10029 %{ 10030 match(Set dst (XorL dst src)); 10031 effect(KILL cr); 10032 10033 format %{ "xorq $dst, $src\t# long" %} 10034 opcode(0x33); 10035 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10036 ins_pipe(ialu_reg_reg); 10037 %} 10038 10039 // Xor Register with Immediate -1 10040 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 10041 match(Set dst (XorL dst imm)); 10042 10043 format %{ "notq $dst" %} 10044 ins_encode %{ 10045 __ notq($dst$$Register); 10046 %} 10047 ins_pipe(ialu_reg); 10048 %} 10049 10050 // Xor Register with Immediate 10051 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10052 %{ 10053 match(Set dst (XorL dst src)); 10054 effect(KILL cr); 10055 10056 format %{ "xorq $dst, $src\t# long" %} 10057 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 10058 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10059 ins_pipe(ialu_reg); 10060 %} 10061 10062 // Xor Register with Memory 10063 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10064 %{ 10065 match(Set dst (XorL dst (LoadL src))); 10066 effect(KILL cr); 10067 10068 ins_cost(125); 10069 format %{ "xorq $dst, $src\t# long" %} 10070 opcode(0x33); 10071 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10072 ins_pipe(ialu_reg_mem); 10073 %} 10074 10075 // Xor Memory with Register 10076 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10077 %{ 10078 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10079 effect(KILL cr); 10080 10081 ins_cost(150); 10082 format %{ "xorq $dst, $src\t# long" %} 10083 opcode(0x31); /* Opcode 31 /r */ 10084 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10085 ins_pipe(ialu_mem_reg); 10086 %} 10087 10088 // Xor Memory with Immediate 10089 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10090 %{ 10091 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10092 effect(KILL cr); 10093 10094 ins_cost(125); 10095 format %{ "xorq $dst, $src\t# long" %} 10096 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 10097 ins_encode(REX_mem_wide(dst), OpcSE(src), 10098 RM_opc_mem(secondary, dst), Con8or32(src)); 10099 ins_pipe(ialu_mem_imm); 10100 %} 10101 10102 // Convert Int to Boolean 10103 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 10104 %{ 10105 match(Set dst (Conv2B src)); 10106 effect(KILL cr); 10107 10108 format %{ "testl $src, $src\t# ci2b\n\t" 10109 "setnz $dst\n\t" 10110 "movzbl $dst, $dst" %} 10111 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10112 setNZ_reg(dst), 10113 REX_reg_breg(dst, dst), // movzbl 10114 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10115 ins_pipe(pipe_slow); // XXX 10116 %} 10117 10118 // Convert Pointer to Boolean 10119 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10120 %{ 10121 match(Set dst (Conv2B src)); 10122 effect(KILL cr); 10123 10124 format %{ "testq $src, $src\t# cp2b\n\t" 10125 "setnz $dst\n\t" 10126 "movzbl $dst, $dst" %} 10127 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10128 setNZ_reg(dst), 10129 REX_reg_breg(dst, dst), // movzbl 10130 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10131 ins_pipe(pipe_slow); // XXX 10132 %} 10133 10134 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10135 %{ 10136 match(Set dst (CmpLTMask p q)); 10137 effect(KILL cr); 10138 10139 ins_cost(400); // XXX 10140 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10141 "setlt $dst\n\t" 10142 "movzbl $dst, $dst\n\t" 10143 "negl $dst" %} 10144 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10145 setLT_reg(dst), 10146 REX_reg_breg(dst, dst), // movzbl 10147 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10148 neg_reg(dst)); 10149 ins_pipe(pipe_slow); 10150 %} 10151 10152 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10153 %{ 10154 match(Set dst (CmpLTMask dst zero)); 10155 effect(KILL cr); 10156 10157 ins_cost(100); // XXX 10158 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10159 opcode(0xC1, 0x7); /* C1 /7 ib */ 10160 ins_encode(reg_opc_imm(dst, 0x1F)); 10161 ins_pipe(ialu_reg); 10162 %} 10163 10164 10165 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr) 10166 %{ 10167 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10168 effect(TEMP tmp, KILL cr); 10169 10170 ins_cost(400); // XXX 10171 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t" 10172 "sbbl $tmp, $tmp\n\t" 10173 "andl $tmp, $y\n\t" 10174 "addl $p, $tmp" %} 10175 ins_encode %{ 10176 Register Rp = $p$$Register; 10177 Register Rq = $q$$Register; 10178 Register Ry = $y$$Register; 10179 Register Rt = $tmp$$Register; 10180 __ subl(Rp, Rq); 10181 __ sbbl(Rt, Rt); 10182 __ andl(Rt, Ry); 10183 __ addl(Rp, Rt); 10184 %} 10185 ins_pipe(pipe_cmplt); 10186 %} 10187 10188 //---------- FP Instructions------------------------------------------------ 10189 10190 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10191 %{ 10192 match(Set cr (CmpF src1 src2)); 10193 10194 ins_cost(145); 10195 format %{ "ucomiss $src1, $src2\n\t" 10196 "jnp,s exit\n\t" 10197 "pushfq\t# saw NaN, set CF\n\t" 10198 "andq [rsp], #0xffffff2b\n\t" 10199 "popfq\n" 10200 "exit: nop\t# avoid branch to branch" %} 10201 opcode(0x0F, 0x2E); 10202 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2), 10203 cmpfp_fixup); 10204 ins_pipe(pipe_slow); 10205 %} 10206 10207 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10208 match(Set cr (CmpF src1 src2)); 10209 10210 ins_cost(145); 10211 format %{ "ucomiss $src1, $src2" %} 10212 ins_encode %{ 10213 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10214 %} 10215 ins_pipe(pipe_slow); 10216 %} 10217 10218 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10219 %{ 10220 match(Set cr (CmpF src1 (LoadF src2))); 10221 10222 ins_cost(145); 10223 format %{ "ucomiss $src1, $src2\n\t" 10224 "jnp,s exit\n\t" 10225 "pushfq\t# saw NaN, set CF\n\t" 10226 "andq [rsp], #0xffffff2b\n\t" 10227 "popfq\n" 10228 "exit: nop\t# avoid branch to branch" %} 10229 opcode(0x0F, 0x2E); 10230 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2), 10231 cmpfp_fixup); 10232 ins_pipe(pipe_slow); 10233 %} 10234 10235 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10236 match(Set cr (CmpF src1 (LoadF src2))); 10237 10238 ins_cost(100); 10239 format %{ "ucomiss $src1, $src2" %} 10240 opcode(0x0F, 0x2E); 10241 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2)); 10242 ins_pipe(pipe_slow); 10243 %} 10244 10245 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10246 match(Set cr (CmpF src con)); 10247 10248 ins_cost(145); 10249 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10250 "jnp,s exit\n\t" 10251 "pushfq\t# saw NaN, set CF\n\t" 10252 "andq [rsp], #0xffffff2b\n\t" 10253 "popfq\n" 10254 "exit: nop\t# avoid branch to branch" %} 10255 ins_encode %{ 10256 Label L_exit; 10257 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10258 __ jcc(Assembler::noParity, L_exit); 10259 __ pushf(); 10260 __ andq(rsp, 0xffffff2b); 10261 __ popf(); 10262 __ bind(L_exit); 10263 __ nop(); 10264 %} 10265 ins_pipe(pipe_slow); 10266 %} 10267 10268 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10269 match(Set cr (CmpF src con)); 10270 ins_cost(100); 10271 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10272 ins_encode %{ 10273 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10274 %} 10275 ins_pipe(pipe_slow); 10276 %} 10277 10278 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10279 %{ 10280 match(Set cr (CmpD src1 src2)); 10281 10282 ins_cost(145); 10283 format %{ "ucomisd $src1, $src2\n\t" 10284 "jnp,s exit\n\t" 10285 "pushfq\t# saw NaN, set CF\n\t" 10286 "andq [rsp], #0xffffff2b\n\t" 10287 "popfq\n" 10288 "exit: nop\t# avoid branch to branch" %} 10289 opcode(0x66, 0x0F, 0x2E); 10290 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2), 10291 cmpfp_fixup); 10292 ins_pipe(pipe_slow); 10293 %} 10294 10295 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10296 match(Set cr (CmpD src1 src2)); 10297 10298 ins_cost(100); 10299 format %{ "ucomisd $src1, $src2 test" %} 10300 ins_encode %{ 10301 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10302 %} 10303 ins_pipe(pipe_slow); 10304 %} 10305 10306 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10307 %{ 10308 match(Set cr (CmpD src1 (LoadD src2))); 10309 10310 ins_cost(145); 10311 format %{ "ucomisd $src1, $src2\n\t" 10312 "jnp,s exit\n\t" 10313 "pushfq\t# saw NaN, set CF\n\t" 10314 "andq [rsp], #0xffffff2b\n\t" 10315 "popfq\n" 10316 "exit: nop\t# avoid branch to branch" %} 10317 opcode(0x66, 0x0F, 0x2E); 10318 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2), 10319 cmpfp_fixup); 10320 ins_pipe(pipe_slow); 10321 %} 10322 10323 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10324 match(Set cr (CmpD src1 (LoadD src2))); 10325 10326 ins_cost(100); 10327 format %{ "ucomisd $src1, $src2" %} 10328 opcode(0x66, 0x0F, 0x2E); 10329 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2)); 10330 ins_pipe(pipe_slow); 10331 %} 10332 10333 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10334 match(Set cr (CmpD src con)); 10335 10336 ins_cost(145); 10337 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10338 "jnp,s exit\n\t" 10339 "pushfq\t# saw NaN, set CF\n\t" 10340 "andq [rsp], #0xffffff2b\n\t" 10341 "popfq\n" 10342 "exit: nop\t# avoid branch to branch" %} 10343 ins_encode %{ 10344 Label L_exit; 10345 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10346 __ jcc(Assembler::noParity, L_exit); 10347 __ pushf(); 10348 __ andq(rsp, 0xffffff2b); 10349 __ popf(); 10350 __ bind(L_exit); 10351 __ nop(); 10352 %} 10353 ins_pipe(pipe_slow); 10354 %} 10355 10356 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10357 match(Set cr (CmpD src con)); 10358 ins_cost(100); 10359 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10360 ins_encode %{ 10361 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10362 %} 10363 ins_pipe(pipe_slow); 10364 %} 10365 10366 // Compare into -1,0,1 10367 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10368 %{ 10369 match(Set dst (CmpF3 src1 src2)); 10370 effect(KILL cr); 10371 10372 ins_cost(275); 10373 format %{ "ucomiss $src1, $src2\n\t" 10374 "movl $dst, #-1\n\t" 10375 "jp,s done\n\t" 10376 "jb,s done\n\t" 10377 "setne $dst\n\t" 10378 "movzbl $dst, $dst\n" 10379 "done:" %} 10380 10381 opcode(0x0F, 0x2E); 10382 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2), 10383 cmpfp3(dst)); 10384 ins_pipe(pipe_slow); 10385 %} 10386 10387 // Compare into -1,0,1 10388 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10389 %{ 10390 match(Set dst (CmpF3 src1 (LoadF src2))); 10391 effect(KILL cr); 10392 10393 ins_cost(275); 10394 format %{ "ucomiss $src1, $src2\n\t" 10395 "movl $dst, #-1\n\t" 10396 "jp,s done\n\t" 10397 "jb,s done\n\t" 10398 "setne $dst\n\t" 10399 "movzbl $dst, $dst\n" 10400 "done:" %} 10401 10402 opcode(0x0F, 0x2E); 10403 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2), 10404 cmpfp3(dst)); 10405 ins_pipe(pipe_slow); 10406 %} 10407 10408 // Compare into -1,0,1 10409 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10410 match(Set dst (CmpF3 src con)); 10411 effect(KILL cr); 10412 10413 ins_cost(275); 10414 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10415 "movl $dst, #-1\n\t" 10416 "jp,s done\n\t" 10417 "jb,s done\n\t" 10418 "setne $dst\n\t" 10419 "movzbl $dst, $dst\n" 10420 "done:" %} 10421 ins_encode %{ 10422 Label L_done; 10423 Register Rdst = $dst$$Register; 10424 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10425 __ movl(Rdst, -1); 10426 __ jcc(Assembler::parity, L_done); 10427 __ jcc(Assembler::below, L_done); 10428 __ setb(Assembler::notEqual, Rdst); 10429 __ movzbl(Rdst, Rdst); 10430 __ bind(L_done); 10431 %} 10432 ins_pipe(pipe_slow); 10433 %} 10434 10435 // Compare into -1,0,1 10436 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10437 %{ 10438 match(Set dst (CmpD3 src1 src2)); 10439 effect(KILL cr); 10440 10441 ins_cost(275); 10442 format %{ "ucomisd $src1, $src2\n\t" 10443 "movl $dst, #-1\n\t" 10444 "jp,s done\n\t" 10445 "jb,s done\n\t" 10446 "setne $dst\n\t" 10447 "movzbl $dst, $dst\n" 10448 "done:" %} 10449 10450 opcode(0x66, 0x0F, 0x2E); 10451 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2), 10452 cmpfp3(dst)); 10453 ins_pipe(pipe_slow); 10454 %} 10455 10456 // Compare into -1,0,1 10457 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10458 %{ 10459 match(Set dst (CmpD3 src1 (LoadD src2))); 10460 effect(KILL cr); 10461 10462 ins_cost(275); 10463 format %{ "ucomisd $src1, $src2\n\t" 10464 "movl $dst, #-1\n\t" 10465 "jp,s done\n\t" 10466 "jb,s done\n\t" 10467 "setne $dst\n\t" 10468 "movzbl $dst, $dst\n" 10469 "done:" %} 10470 10471 opcode(0x66, 0x0F, 0x2E); 10472 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2), 10473 cmpfp3(dst)); 10474 ins_pipe(pipe_slow); 10475 %} 10476 10477 // Compare into -1,0,1 10478 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10479 match(Set dst (CmpD3 src con)); 10480 effect(KILL cr); 10481 10482 ins_cost(275); 10483 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10484 "movl $dst, #-1\n\t" 10485 "jp,s done\n\t" 10486 "jb,s done\n\t" 10487 "setne $dst\n\t" 10488 "movzbl $dst, $dst\n" 10489 "done:" %} 10490 ins_encode %{ 10491 Register Rdst = $dst$$Register; 10492 Label L_done; 10493 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10494 __ movl(Rdst, -1); 10495 __ jcc(Assembler::parity, L_done); 10496 __ jcc(Assembler::below, L_done); 10497 __ setb(Assembler::notEqual, Rdst); 10498 __ movzbl(Rdst, Rdst); 10499 __ bind(L_done); 10500 %} 10501 ins_pipe(pipe_slow); 10502 %} 10503 10504 instruct addF_reg(regF dst, regF src) 10505 %{ 10506 match(Set dst (AddF dst src)); 10507 10508 format %{ "addss $dst, $src" %} 10509 ins_cost(150); // XXX 10510 opcode(0xF3, 0x0F, 0x58); 10511 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10512 ins_pipe(pipe_slow); 10513 %} 10514 10515 instruct addF_mem(regF dst, memory src) 10516 %{ 10517 match(Set dst (AddF dst (LoadF src))); 10518 10519 format %{ "addss $dst, $src" %} 10520 ins_cost(150); // XXX 10521 opcode(0xF3, 0x0F, 0x58); 10522 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10523 ins_pipe(pipe_slow); 10524 %} 10525 10526 instruct addF_imm(regF dst, immF con) %{ 10527 match(Set dst (AddF dst con)); 10528 format %{ "addss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 10529 ins_cost(150); // XXX 10530 ins_encode %{ 10531 __ addss($dst$$XMMRegister, $constantaddress($con)); 10532 %} 10533 ins_pipe(pipe_slow); 10534 %} 10535 10536 instruct addD_reg(regD dst, regD src) 10537 %{ 10538 match(Set dst (AddD dst src)); 10539 10540 format %{ "addsd $dst, $src" %} 10541 ins_cost(150); // XXX 10542 opcode(0xF2, 0x0F, 0x58); 10543 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10544 ins_pipe(pipe_slow); 10545 %} 10546 10547 instruct addD_mem(regD dst, memory src) 10548 %{ 10549 match(Set dst (AddD dst (LoadD src))); 10550 10551 format %{ "addsd $dst, $src" %} 10552 ins_cost(150); // XXX 10553 opcode(0xF2, 0x0F, 0x58); 10554 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10555 ins_pipe(pipe_slow); 10556 %} 10557 10558 instruct addD_imm(regD dst, immD con) %{ 10559 match(Set dst (AddD dst con)); 10560 format %{ "addsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 10561 ins_cost(150); // XXX 10562 ins_encode %{ 10563 __ addsd($dst$$XMMRegister, $constantaddress($con)); 10564 %} 10565 ins_pipe(pipe_slow); 10566 %} 10567 10568 instruct subF_reg(regF dst, regF src) 10569 %{ 10570 match(Set dst (SubF dst src)); 10571 10572 format %{ "subss $dst, $src" %} 10573 ins_cost(150); // XXX 10574 opcode(0xF3, 0x0F, 0x5C); 10575 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10576 ins_pipe(pipe_slow); 10577 %} 10578 10579 instruct subF_mem(regF dst, memory src) 10580 %{ 10581 match(Set dst (SubF dst (LoadF src))); 10582 10583 format %{ "subss $dst, $src" %} 10584 ins_cost(150); // XXX 10585 opcode(0xF3, 0x0F, 0x5C); 10586 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10587 ins_pipe(pipe_slow); 10588 %} 10589 10590 instruct subF_imm(regF dst, immF con) %{ 10591 match(Set dst (SubF dst con)); 10592 format %{ "subss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 10593 ins_cost(150); // XXX 10594 ins_encode %{ 10595 __ subss($dst$$XMMRegister, $constantaddress($con)); 10596 %} 10597 ins_pipe(pipe_slow); 10598 %} 10599 10600 instruct subD_reg(regD dst, regD src) 10601 %{ 10602 match(Set dst (SubD dst src)); 10603 10604 format %{ "subsd $dst, $src" %} 10605 ins_cost(150); // XXX 10606 opcode(0xF2, 0x0F, 0x5C); 10607 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10608 ins_pipe(pipe_slow); 10609 %} 10610 10611 instruct subD_mem(regD dst, memory src) 10612 %{ 10613 match(Set dst (SubD dst (LoadD src))); 10614 10615 format %{ "subsd $dst, $src" %} 10616 ins_cost(150); // XXX 10617 opcode(0xF2, 0x0F, 0x5C); 10618 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10619 ins_pipe(pipe_slow); 10620 %} 10621 10622 instruct subD_imm(regD dst, immD con) %{ 10623 match(Set dst (SubD dst con)); 10624 format %{ "subsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 10625 ins_cost(150); // XXX 10626 ins_encode %{ 10627 __ subsd($dst$$XMMRegister, $constantaddress($con)); 10628 %} 10629 ins_pipe(pipe_slow); 10630 %} 10631 10632 instruct mulF_reg(regF dst, regF src) 10633 %{ 10634 match(Set dst (MulF dst src)); 10635 10636 format %{ "mulss $dst, $src" %} 10637 ins_cost(150); // XXX 10638 opcode(0xF3, 0x0F, 0x59); 10639 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10640 ins_pipe(pipe_slow); 10641 %} 10642 10643 instruct mulF_mem(regF dst, memory src) 10644 %{ 10645 match(Set dst (MulF dst (LoadF src))); 10646 10647 format %{ "mulss $dst, $src" %} 10648 ins_cost(150); // XXX 10649 opcode(0xF3, 0x0F, 0x59); 10650 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10651 ins_pipe(pipe_slow); 10652 %} 10653 10654 instruct mulF_imm(regF dst, immF con) %{ 10655 match(Set dst (MulF dst con)); 10656 format %{ "mulss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 10657 ins_cost(150); // XXX 10658 ins_encode %{ 10659 __ mulss($dst$$XMMRegister, $constantaddress($con)); 10660 %} 10661 ins_pipe(pipe_slow); 10662 %} 10663 10664 instruct mulD_reg(regD dst, regD src) 10665 %{ 10666 match(Set dst (MulD dst src)); 10667 10668 format %{ "mulsd $dst, $src" %} 10669 ins_cost(150); // XXX 10670 opcode(0xF2, 0x0F, 0x59); 10671 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10672 ins_pipe(pipe_slow); 10673 %} 10674 10675 instruct mulD_mem(regD dst, memory src) 10676 %{ 10677 match(Set dst (MulD dst (LoadD src))); 10678 10679 format %{ "mulsd $dst, $src" %} 10680 ins_cost(150); // XXX 10681 opcode(0xF2, 0x0F, 0x59); 10682 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10683 ins_pipe(pipe_slow); 10684 %} 10685 10686 instruct mulD_imm(regD dst, immD con) %{ 10687 match(Set dst (MulD dst con)); 10688 format %{ "mulsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 10689 ins_cost(150); // XXX 10690 ins_encode %{ 10691 __ mulsd($dst$$XMMRegister, $constantaddress($con)); 10692 %} 10693 ins_pipe(pipe_slow); 10694 %} 10695 10696 instruct divF_reg(regF dst, regF src) 10697 %{ 10698 match(Set dst (DivF dst src)); 10699 10700 format %{ "divss $dst, $src" %} 10701 ins_cost(150); // XXX 10702 opcode(0xF3, 0x0F, 0x5E); 10703 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10704 ins_pipe(pipe_slow); 10705 %} 10706 10707 instruct divF_mem(regF dst, memory src) 10708 %{ 10709 match(Set dst (DivF dst (LoadF src))); 10710 10711 format %{ "divss $dst, $src" %} 10712 ins_cost(150); // XXX 10713 opcode(0xF3, 0x0F, 0x5E); 10714 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10715 ins_pipe(pipe_slow); 10716 %} 10717 10718 instruct divF_imm(regF dst, immF con) %{ 10719 match(Set dst (DivF dst con)); 10720 format %{ "divss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 10721 ins_cost(150); // XXX 10722 ins_encode %{ 10723 __ divss($dst$$XMMRegister, $constantaddress($con)); 10724 %} 10725 ins_pipe(pipe_slow); 10726 %} 10727 10728 instruct divD_reg(regD dst, regD src) 10729 %{ 10730 match(Set dst (DivD dst src)); 10731 10732 format %{ "divsd $dst, $src" %} 10733 ins_cost(150); // XXX 10734 opcode(0xF2, 0x0F, 0x5E); 10735 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10736 ins_pipe(pipe_slow); 10737 %} 10738 10739 instruct divD_mem(regD dst, memory src) 10740 %{ 10741 match(Set dst (DivD dst (LoadD src))); 10742 10743 format %{ "divsd $dst, $src" %} 10744 ins_cost(150); // XXX 10745 opcode(0xF2, 0x0F, 0x5E); 10746 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10747 ins_pipe(pipe_slow); 10748 %} 10749 10750 instruct divD_imm(regD dst, immD con) %{ 10751 match(Set dst (DivD dst con)); 10752 format %{ "divsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 10753 ins_cost(150); // XXX 10754 ins_encode %{ 10755 __ divsd($dst$$XMMRegister, $constantaddress($con)); 10756 %} 10757 ins_pipe(pipe_slow); 10758 %} 10759 10760 instruct sqrtF_reg(regF dst, regF src) 10761 %{ 10762 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 10763 10764 format %{ "sqrtss $dst, $src" %} 10765 ins_cost(150); // XXX 10766 opcode(0xF3, 0x0F, 0x51); 10767 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10768 ins_pipe(pipe_slow); 10769 %} 10770 10771 instruct sqrtF_mem(regF dst, memory src) 10772 %{ 10773 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src))))); 10774 10775 format %{ "sqrtss $dst, $src" %} 10776 ins_cost(150); // XXX 10777 opcode(0xF3, 0x0F, 0x51); 10778 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10779 ins_pipe(pipe_slow); 10780 %} 10781 10782 instruct sqrtF_imm(regF dst, immF con) %{ 10783 match(Set dst (ConvD2F (SqrtD (ConvF2D con)))); 10784 format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 10785 ins_cost(150); // XXX 10786 ins_encode %{ 10787 __ sqrtss($dst$$XMMRegister, $constantaddress($con)); 10788 %} 10789 ins_pipe(pipe_slow); 10790 %} 10791 10792 instruct sqrtD_reg(regD dst, regD src) 10793 %{ 10794 match(Set dst (SqrtD src)); 10795 10796 format %{ "sqrtsd $dst, $src" %} 10797 ins_cost(150); // XXX 10798 opcode(0xF2, 0x0F, 0x51); 10799 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10800 ins_pipe(pipe_slow); 10801 %} 10802 10803 instruct sqrtD_mem(regD dst, memory src) 10804 %{ 10805 match(Set dst (SqrtD (LoadD src))); 10806 10807 format %{ "sqrtsd $dst, $src" %} 10808 ins_cost(150); // XXX 10809 opcode(0xF2, 0x0F, 0x51); 10810 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10811 ins_pipe(pipe_slow); 10812 %} 10813 10814 instruct sqrtD_imm(regD dst, immD con) %{ 10815 match(Set dst (SqrtD con)); 10816 format %{ "sqrtsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 10817 ins_cost(150); // XXX 10818 ins_encode %{ 10819 __ sqrtsd($dst$$XMMRegister, $constantaddress($con)); 10820 %} 10821 ins_pipe(pipe_slow); 10822 %} 10823 10824 instruct absF_reg(regF dst) 10825 %{ 10826 match(Set dst (AbsF dst)); 10827 10828 format %{ "andps $dst, [0x7fffffff]\t# abs float by sign masking" %} 10829 ins_encode(absF_encoding(dst)); 10830 ins_pipe(pipe_slow); 10831 %} 10832 10833 instruct absD_reg(regD dst) 10834 %{ 10835 match(Set dst (AbsD dst)); 10836 10837 format %{ "andpd $dst, [0x7fffffffffffffff]\t" 10838 "# abs double by sign masking" %} 10839 ins_encode(absD_encoding(dst)); 10840 ins_pipe(pipe_slow); 10841 %} 10842 10843 instruct negF_reg(regF dst) 10844 %{ 10845 match(Set dst (NegF dst)); 10846 10847 format %{ "xorps $dst, [0x80000000]\t# neg float by sign flipping" %} 10848 ins_encode(negF_encoding(dst)); 10849 ins_pipe(pipe_slow); 10850 %} 10851 10852 instruct negD_reg(regD dst) 10853 %{ 10854 match(Set dst (NegD dst)); 10855 10856 format %{ "xorpd $dst, [0x8000000000000000]\t" 10857 "# neg double by sign flipping" %} 10858 ins_encode(negD_encoding(dst)); 10859 ins_pipe(pipe_slow); 10860 %} 10861 10862 // -----------Trig and Trancendental Instructions------------------------------ 10863 instruct cosD_reg(regD dst) %{ 10864 match(Set dst (CosD dst)); 10865 10866 format %{ "dcos $dst\n\t" %} 10867 opcode(0xD9, 0xFF); 10868 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 10869 ins_pipe( pipe_slow ); 10870 %} 10871 10872 instruct sinD_reg(regD dst) %{ 10873 match(Set dst (SinD dst)); 10874 10875 format %{ "dsin $dst\n\t" %} 10876 opcode(0xD9, 0xFE); 10877 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 10878 ins_pipe( pipe_slow ); 10879 %} 10880 10881 instruct tanD_reg(regD dst) %{ 10882 match(Set dst (TanD dst)); 10883 10884 format %{ "dtan $dst\n\t" %} 10885 ins_encode( Push_SrcXD(dst), 10886 Opcode(0xD9), Opcode(0xF2), //fptan 10887 Opcode(0xDD), Opcode(0xD8), //fstp st 10888 Push_ResultXD(dst) ); 10889 ins_pipe( pipe_slow ); 10890 %} 10891 10892 instruct log10D_reg(regD dst) %{ 10893 // The source and result Double operands in XMM registers 10894 match(Set dst (Log10D dst)); 10895 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 10896 // fyl2x ; compute log_10(2) * log_2(x) 10897 format %{ "fldlg2\t\t\t#Log10\n\t" 10898 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 10899 %} 10900 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 10901 Push_SrcXD(dst), 10902 Opcode(0xD9), Opcode(0xF1), // fyl2x 10903 Push_ResultXD(dst)); 10904 10905 ins_pipe( pipe_slow ); 10906 %} 10907 10908 instruct logD_reg(regD dst) %{ 10909 // The source and result Double operands in XMM registers 10910 match(Set dst (LogD dst)); 10911 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 10912 // fyl2x ; compute log_e(2) * log_2(x) 10913 format %{ "fldln2\t\t\t#Log_e\n\t" 10914 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 10915 %} 10916 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 10917 Push_SrcXD(dst), 10918 Opcode(0xD9), Opcode(0xF1), // fyl2x 10919 Push_ResultXD(dst)); 10920 ins_pipe( pipe_slow ); 10921 %} 10922 10923 10924 10925 //----------Arithmetic Conversion Instructions--------------------------------- 10926 10927 instruct roundFloat_nop(regF dst) 10928 %{ 10929 match(Set dst (RoundFloat dst)); 10930 10931 ins_cost(0); 10932 ins_encode(); 10933 ins_pipe(empty); 10934 %} 10935 10936 instruct roundDouble_nop(regD dst) 10937 %{ 10938 match(Set dst (RoundDouble dst)); 10939 10940 ins_cost(0); 10941 ins_encode(); 10942 ins_pipe(empty); 10943 %} 10944 10945 instruct convF2D_reg_reg(regD dst, regF src) 10946 %{ 10947 match(Set dst (ConvF2D src)); 10948 10949 format %{ "cvtss2sd $dst, $src" %} 10950 opcode(0xF3, 0x0F, 0x5A); 10951 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10952 ins_pipe(pipe_slow); // XXX 10953 %} 10954 10955 instruct convF2D_reg_mem(regD dst, memory src) 10956 %{ 10957 match(Set dst (ConvF2D (LoadF src))); 10958 10959 format %{ "cvtss2sd $dst, $src" %} 10960 opcode(0xF3, 0x0F, 0x5A); 10961 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10962 ins_pipe(pipe_slow); // XXX 10963 %} 10964 10965 instruct convD2F_reg_reg(regF dst, regD src) 10966 %{ 10967 match(Set dst (ConvD2F src)); 10968 10969 format %{ "cvtsd2ss $dst, $src" %} 10970 opcode(0xF2, 0x0F, 0x5A); 10971 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10972 ins_pipe(pipe_slow); // XXX 10973 %} 10974 10975 instruct convD2F_reg_mem(regF dst, memory src) 10976 %{ 10977 match(Set dst (ConvD2F (LoadD src))); 10978 10979 format %{ "cvtsd2ss $dst, $src" %} 10980 opcode(0xF2, 0x0F, 0x5A); 10981 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10982 ins_pipe(pipe_slow); // XXX 10983 %} 10984 10985 // XXX do mem variants 10986 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10987 %{ 10988 match(Set dst (ConvF2I src)); 10989 effect(KILL cr); 10990 10991 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10992 "cmpl $dst, #0x80000000\n\t" 10993 "jne,s done\n\t" 10994 "subq rsp, #8\n\t" 10995 "movss [rsp], $src\n\t" 10996 "call f2i_fixup\n\t" 10997 "popq $dst\n" 10998 "done: "%} 10999 opcode(0xF3, 0x0F, 0x2C); 11000 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src), 11001 f2i_fixup(dst, src)); 11002 ins_pipe(pipe_slow); 11003 %} 11004 11005 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 11006 %{ 11007 match(Set dst (ConvF2L src)); 11008 effect(KILL cr); 11009 11010 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 11011 "cmpq $dst, [0x8000000000000000]\n\t" 11012 "jne,s done\n\t" 11013 "subq rsp, #8\n\t" 11014 "movss [rsp], $src\n\t" 11015 "call f2l_fixup\n\t" 11016 "popq $dst\n" 11017 "done: "%} 11018 opcode(0xF3, 0x0F, 0x2C); 11019 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src), 11020 f2l_fixup(dst, src)); 11021 ins_pipe(pipe_slow); 11022 %} 11023 11024 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 11025 %{ 11026 match(Set dst (ConvD2I src)); 11027 effect(KILL cr); 11028 11029 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 11030 "cmpl $dst, #0x80000000\n\t" 11031 "jne,s done\n\t" 11032 "subq rsp, #8\n\t" 11033 "movsd [rsp], $src\n\t" 11034 "call d2i_fixup\n\t" 11035 "popq $dst\n" 11036 "done: "%} 11037 opcode(0xF2, 0x0F, 0x2C); 11038 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src), 11039 d2i_fixup(dst, src)); 11040 ins_pipe(pipe_slow); 11041 %} 11042 11043 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 11044 %{ 11045 match(Set dst (ConvD2L src)); 11046 effect(KILL cr); 11047 11048 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 11049 "cmpq $dst, [0x8000000000000000]\n\t" 11050 "jne,s done\n\t" 11051 "subq rsp, #8\n\t" 11052 "movsd [rsp], $src\n\t" 11053 "call d2l_fixup\n\t" 11054 "popq $dst\n" 11055 "done: "%} 11056 opcode(0xF2, 0x0F, 0x2C); 11057 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src), 11058 d2l_fixup(dst, src)); 11059 ins_pipe(pipe_slow); 11060 %} 11061 11062 instruct convI2F_reg_reg(regF dst, rRegI src) 11063 %{ 11064 predicate(!UseXmmI2F); 11065 match(Set dst (ConvI2F src)); 11066 11067 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11068 opcode(0xF3, 0x0F, 0x2A); 11069 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 11070 ins_pipe(pipe_slow); // XXX 11071 %} 11072 11073 instruct convI2F_reg_mem(regF dst, memory src) 11074 %{ 11075 match(Set dst (ConvI2F (LoadI src))); 11076 11077 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11078 opcode(0xF3, 0x0F, 0x2A); 11079 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11080 ins_pipe(pipe_slow); // XXX 11081 %} 11082 11083 instruct convI2D_reg_reg(regD dst, rRegI src) 11084 %{ 11085 predicate(!UseXmmI2D); 11086 match(Set dst (ConvI2D src)); 11087 11088 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11089 opcode(0xF2, 0x0F, 0x2A); 11090 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 11091 ins_pipe(pipe_slow); // XXX 11092 %} 11093 11094 instruct convI2D_reg_mem(regD dst, memory src) 11095 %{ 11096 match(Set dst (ConvI2D (LoadI src))); 11097 11098 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11099 opcode(0xF2, 0x0F, 0x2A); 11100 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11101 ins_pipe(pipe_slow); // XXX 11102 %} 11103 11104 instruct convXI2F_reg(regF dst, rRegI src) 11105 %{ 11106 predicate(UseXmmI2F); 11107 match(Set dst (ConvI2F src)); 11108 11109 format %{ "movdl $dst, $src\n\t" 11110 "cvtdq2psl $dst, $dst\t# i2f" %} 11111 ins_encode %{ 11112 __ movdl($dst$$XMMRegister, $src$$Register); 11113 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 11114 %} 11115 ins_pipe(pipe_slow); // XXX 11116 %} 11117 11118 instruct convXI2D_reg(regD dst, rRegI src) 11119 %{ 11120 predicate(UseXmmI2D); 11121 match(Set dst (ConvI2D src)); 11122 11123 format %{ "movdl $dst, $src\n\t" 11124 "cvtdq2pdl $dst, $dst\t# i2d" %} 11125 ins_encode %{ 11126 __ movdl($dst$$XMMRegister, $src$$Register); 11127 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 11128 %} 11129 ins_pipe(pipe_slow); // XXX 11130 %} 11131 11132 instruct convL2F_reg_reg(regF dst, rRegL src) 11133 %{ 11134 match(Set dst (ConvL2F src)); 11135 11136 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11137 opcode(0xF3, 0x0F, 0x2A); 11138 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src)); 11139 ins_pipe(pipe_slow); // XXX 11140 %} 11141 11142 instruct convL2F_reg_mem(regF dst, memory src) 11143 %{ 11144 match(Set dst (ConvL2F (LoadL src))); 11145 11146 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11147 opcode(0xF3, 0x0F, 0x2A); 11148 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11149 ins_pipe(pipe_slow); // XXX 11150 %} 11151 11152 instruct convL2D_reg_reg(regD dst, rRegL src) 11153 %{ 11154 match(Set dst (ConvL2D src)); 11155 11156 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11157 opcode(0xF2, 0x0F, 0x2A); 11158 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src)); 11159 ins_pipe(pipe_slow); // XXX 11160 %} 11161 11162 instruct convL2D_reg_mem(regD dst, memory src) 11163 %{ 11164 match(Set dst (ConvL2D (LoadL src))); 11165 11166 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11167 opcode(0xF2, 0x0F, 0x2A); 11168 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11169 ins_pipe(pipe_slow); // XXX 11170 %} 11171 11172 instruct convI2L_reg_reg(rRegL dst, rRegI src) 11173 %{ 11174 match(Set dst (ConvI2L src)); 11175 11176 ins_cost(125); 11177 format %{ "movslq $dst, $src\t# i2l" %} 11178 ins_encode %{ 11179 __ movslq($dst$$Register, $src$$Register); 11180 %} 11181 ins_pipe(ialu_reg_reg); 11182 %} 11183 11184 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 11185 // %{ 11186 // match(Set dst (ConvI2L src)); 11187 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 11188 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 11189 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 11190 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 11191 // ((const TypeNode*) n)->type()->is_long()->_lo == 11192 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 11193 11194 // format %{ "movl $dst, $src\t# unsigned i2l" %} 11195 // ins_encode(enc_copy(dst, src)); 11196 // // opcode(0x63); // needs REX.W 11197 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 11198 // ins_pipe(ialu_reg_reg); 11199 // %} 11200 11201 // Zero-extend convert int to long 11202 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 11203 %{ 11204 match(Set dst (AndL (ConvI2L src) mask)); 11205 11206 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11207 ins_encode(enc_copy(dst, src)); 11208 ins_pipe(ialu_reg_reg); 11209 %} 11210 11211 // Zero-extend convert int to long 11212 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 11213 %{ 11214 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 11215 11216 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11217 opcode(0x8B); 11218 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 11219 ins_pipe(ialu_reg_mem); 11220 %} 11221 11222 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 11223 %{ 11224 match(Set dst (AndL src mask)); 11225 11226 format %{ "movl $dst, $src\t# zero-extend long" %} 11227 ins_encode(enc_copy_always(dst, src)); 11228 ins_pipe(ialu_reg_reg); 11229 %} 11230 11231 instruct convL2I_reg_reg(rRegI dst, rRegL src) 11232 %{ 11233 match(Set dst (ConvL2I src)); 11234 11235 format %{ "movl $dst, $src\t# l2i" %} 11236 ins_encode(enc_copy_always(dst, src)); 11237 ins_pipe(ialu_reg_reg); 11238 %} 11239 11240 11241 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 11242 match(Set dst (MoveF2I src)); 11243 effect(DEF dst, USE src); 11244 11245 ins_cost(125); 11246 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 11247 opcode(0x8B); 11248 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 11249 ins_pipe(ialu_reg_mem); 11250 %} 11251 11252 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 11253 match(Set dst (MoveI2F src)); 11254 effect(DEF dst, USE src); 11255 11256 ins_cost(125); 11257 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 11258 opcode(0xF3, 0x0F, 0x10); 11259 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11260 ins_pipe(pipe_slow); 11261 %} 11262 11263 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 11264 match(Set dst (MoveD2L src)); 11265 effect(DEF dst, USE src); 11266 11267 ins_cost(125); 11268 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 11269 opcode(0x8B); 11270 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 11271 ins_pipe(ialu_reg_mem); 11272 %} 11273 11274 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 11275 predicate(!UseXmmLoadAndClearUpper); 11276 match(Set dst (MoveL2D src)); 11277 effect(DEF dst, USE src); 11278 11279 ins_cost(125); 11280 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 11281 opcode(0x66, 0x0F, 0x12); 11282 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11283 ins_pipe(pipe_slow); 11284 %} 11285 11286 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 11287 predicate(UseXmmLoadAndClearUpper); 11288 match(Set dst (MoveL2D src)); 11289 effect(DEF dst, USE src); 11290 11291 ins_cost(125); 11292 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 11293 opcode(0xF2, 0x0F, 0x10); 11294 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 11295 ins_pipe(pipe_slow); 11296 %} 11297 11298 11299 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 11300 match(Set dst (MoveF2I src)); 11301 effect(DEF dst, USE src); 11302 11303 ins_cost(95); // XXX 11304 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 11305 opcode(0xF3, 0x0F, 0x11); 11306 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 11307 ins_pipe(pipe_slow); 11308 %} 11309 11310 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 11311 match(Set dst (MoveI2F src)); 11312 effect(DEF dst, USE src); 11313 11314 ins_cost(100); 11315 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 11316 opcode(0x89); 11317 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 11318 ins_pipe( ialu_mem_reg ); 11319 %} 11320 11321 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 11322 match(Set dst (MoveD2L src)); 11323 effect(DEF dst, USE src); 11324 11325 ins_cost(95); // XXX 11326 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 11327 opcode(0xF2, 0x0F, 0x11); 11328 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 11329 ins_pipe(pipe_slow); 11330 %} 11331 11332 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 11333 match(Set dst (MoveL2D src)); 11334 effect(DEF dst, USE src); 11335 11336 ins_cost(100); 11337 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 11338 opcode(0x89); 11339 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 11340 ins_pipe(ialu_mem_reg); 11341 %} 11342 11343 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 11344 match(Set dst (MoveF2I src)); 11345 effect(DEF dst, USE src); 11346 ins_cost(85); 11347 format %{ "movd $dst,$src\t# MoveF2I" %} 11348 ins_encode %{ __ movdl($dst$$Register, $src$$XMMRegister); %} 11349 ins_pipe( pipe_slow ); 11350 %} 11351 11352 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 11353 match(Set dst (MoveD2L src)); 11354 effect(DEF dst, USE src); 11355 ins_cost(85); 11356 format %{ "movd $dst,$src\t# MoveD2L" %} 11357 ins_encode %{ __ movdq($dst$$Register, $src$$XMMRegister); %} 11358 ins_pipe( pipe_slow ); 11359 %} 11360 11361 // The next instructions have long latency and use Int unit. Set high cost. 11362 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 11363 match(Set dst (MoveI2F src)); 11364 effect(DEF dst, USE src); 11365 ins_cost(300); 11366 format %{ "movd $dst,$src\t# MoveI2F" %} 11367 ins_encode %{ __ movdl($dst$$XMMRegister, $src$$Register); %} 11368 ins_pipe( pipe_slow ); 11369 %} 11370 11371 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 11372 match(Set dst (MoveL2D src)); 11373 effect(DEF dst, USE src); 11374 ins_cost(300); 11375 format %{ "movd $dst,$src\t# MoveL2D" %} 11376 ins_encode %{ __ movdq($dst$$XMMRegister, $src$$Register); %} 11377 ins_pipe( pipe_slow ); 11378 %} 11379 11380 // Replicate scalar to packed byte (1 byte) values in xmm 11381 instruct Repl8B_reg(regD dst, regD src) %{ 11382 match(Set dst (Replicate8B src)); 11383 format %{ "MOVDQA $dst,$src\n\t" 11384 "PUNPCKLBW $dst,$dst\n\t" 11385 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 11386 ins_encode( pshufd_8x8(dst, src)); 11387 ins_pipe( pipe_slow ); 11388 %} 11389 11390 // Replicate scalar to packed byte (1 byte) values in xmm 11391 instruct Repl8B_rRegI(regD dst, rRegI src) %{ 11392 match(Set dst (Replicate8B src)); 11393 format %{ "MOVD $dst,$src\n\t" 11394 "PUNPCKLBW $dst,$dst\n\t" 11395 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 11396 ins_encode( mov_i2x(dst, src), pshufd_8x8(dst, dst)); 11397 ins_pipe( pipe_slow ); 11398 %} 11399 11400 // Replicate scalar zero to packed byte (1 byte) values in xmm 11401 instruct Repl8B_immI0(regD dst, immI0 zero) %{ 11402 match(Set dst (Replicate8B zero)); 11403 format %{ "PXOR $dst,$dst\t! replicate8B" %} 11404 ins_encode( pxor(dst, dst)); 11405 ins_pipe( fpu_reg_reg ); 11406 %} 11407 11408 // Replicate scalar to packed shore (2 byte) values in xmm 11409 instruct Repl4S_reg(regD dst, regD src) %{ 11410 match(Set dst (Replicate4S src)); 11411 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %} 11412 ins_encode( pshufd_4x16(dst, src)); 11413 ins_pipe( fpu_reg_reg ); 11414 %} 11415 11416 // Replicate scalar to packed shore (2 byte) values in xmm 11417 instruct Repl4S_rRegI(regD dst, rRegI src) %{ 11418 match(Set dst (Replicate4S src)); 11419 format %{ "MOVD $dst,$src\n\t" 11420 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %} 11421 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst)); 11422 ins_pipe( fpu_reg_reg ); 11423 %} 11424 11425 // Replicate scalar zero to packed short (2 byte) values in xmm 11426 instruct Repl4S_immI0(regD dst, immI0 zero) %{ 11427 match(Set dst (Replicate4S zero)); 11428 format %{ "PXOR $dst,$dst\t! replicate4S" %} 11429 ins_encode( pxor(dst, dst)); 11430 ins_pipe( fpu_reg_reg ); 11431 %} 11432 11433 // Replicate scalar to packed char (2 byte) values in xmm 11434 instruct Repl4C_reg(regD dst, regD src) %{ 11435 match(Set dst (Replicate4C src)); 11436 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %} 11437 ins_encode( pshufd_4x16(dst, src)); 11438 ins_pipe( fpu_reg_reg ); 11439 %} 11440 11441 // Replicate scalar to packed char (2 byte) values in xmm 11442 instruct Repl4C_rRegI(regD dst, rRegI src) %{ 11443 match(Set dst (Replicate4C src)); 11444 format %{ "MOVD $dst,$src\n\t" 11445 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %} 11446 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst)); 11447 ins_pipe( fpu_reg_reg ); 11448 %} 11449 11450 // Replicate scalar zero to packed char (2 byte) values in xmm 11451 instruct Repl4C_immI0(regD dst, immI0 zero) %{ 11452 match(Set dst (Replicate4C zero)); 11453 format %{ "PXOR $dst,$dst\t! replicate4C" %} 11454 ins_encode( pxor(dst, dst)); 11455 ins_pipe( fpu_reg_reg ); 11456 %} 11457 11458 // Replicate scalar to packed integer (4 byte) values in xmm 11459 instruct Repl2I_reg(regD dst, regD src) %{ 11460 match(Set dst (Replicate2I src)); 11461 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %} 11462 ins_encode( pshufd(dst, src, 0x00)); 11463 ins_pipe( fpu_reg_reg ); 11464 %} 11465 11466 // Replicate scalar to packed integer (4 byte) values in xmm 11467 instruct Repl2I_rRegI(regD dst, rRegI src) %{ 11468 match(Set dst (Replicate2I src)); 11469 format %{ "MOVD $dst,$src\n\t" 11470 "PSHUFD $dst,$dst,0x00\t! replicate2I" %} 11471 ins_encode( mov_i2x(dst, src), pshufd(dst, dst, 0x00)); 11472 ins_pipe( fpu_reg_reg ); 11473 %} 11474 11475 // Replicate scalar zero to packed integer (2 byte) values in xmm 11476 instruct Repl2I_immI0(regD dst, immI0 zero) %{ 11477 match(Set dst (Replicate2I zero)); 11478 format %{ "PXOR $dst,$dst\t! replicate2I" %} 11479 ins_encode( pxor(dst, dst)); 11480 ins_pipe( fpu_reg_reg ); 11481 %} 11482 11483 // Replicate scalar to packed single precision floating point values in xmm 11484 instruct Repl2F_reg(regD dst, regD 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_regF(regD dst, regF src) %{ 11493 match(Set dst (Replicate2F src)); 11494 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 11495 ins_encode( pshufd(dst, src, 0xe0)); 11496 ins_pipe( fpu_reg_reg ); 11497 %} 11498 11499 // Replicate scalar to packed single precision floating point values in xmm 11500 instruct Repl2F_immF0(regD dst, immF0 zero) %{ 11501 match(Set dst (Replicate2F zero)); 11502 format %{ "PXOR $dst,$dst\t! replicate2F" %} 11503 ins_encode( pxor(dst, dst)); 11504 ins_pipe( fpu_reg_reg ); 11505 %} 11506 11507 11508 // ======================================================================= 11509 // fast clearing of an array 11510 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 11511 rFlagsReg cr) 11512 %{ 11513 match(Set dummy (ClearArray cnt base)); 11514 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 11515 11516 format %{ "xorl rax, rax\t# ClearArray:\n\t" 11517 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 11518 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax 11519 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos 11520 ins_pipe(pipe_slow); 11521 %} 11522 11523 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11524 rax_RegI result, regD tmp1, rFlagsReg cr) 11525 %{ 11526 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11527 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11528 11529 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11530 ins_encode %{ 11531 __ string_compare($str1$$Register, $str2$$Register, 11532 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11533 $tmp1$$XMMRegister); 11534 %} 11535 ins_pipe( pipe_slow ); 11536 %} 11537 11538 // fast search of substring with known size. 11539 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11540 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11541 %{ 11542 predicate(UseSSE42Intrinsics); 11543 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11544 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11545 11546 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11547 ins_encode %{ 11548 int icnt2 = (int)$int_cnt2$$constant; 11549 if (icnt2 >= 8) { 11550 // IndexOf for constant substrings with size >= 8 elements 11551 // which don't need to be loaded through stack. 11552 __ string_indexofC8($str1$$Register, $str2$$Register, 11553 $cnt1$$Register, $cnt2$$Register, 11554 icnt2, $result$$Register, 11555 $vec$$XMMRegister, $tmp$$Register); 11556 } else { 11557 // Small strings are loaded through stack if they cross page boundary. 11558 __ string_indexof($str1$$Register, $str2$$Register, 11559 $cnt1$$Register, $cnt2$$Register, 11560 icnt2, $result$$Register, 11561 $vec$$XMMRegister, $tmp$$Register); 11562 } 11563 %} 11564 ins_pipe( pipe_slow ); 11565 %} 11566 11567 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11568 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 11569 %{ 11570 predicate(UseSSE42Intrinsics); 11571 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11572 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11573 11574 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11575 ins_encode %{ 11576 __ string_indexof($str1$$Register, $str2$$Register, 11577 $cnt1$$Register, $cnt2$$Register, 11578 (-1), $result$$Register, 11579 $vec$$XMMRegister, $tmp$$Register); 11580 %} 11581 ins_pipe( pipe_slow ); 11582 %} 11583 11584 // fast string equals 11585 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11586 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11587 %{ 11588 match(Set result (StrEquals (Binary str1 str2) cnt)); 11589 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11590 11591 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11592 ins_encode %{ 11593 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 11594 $cnt$$Register, $result$$Register, $tmp3$$Register, 11595 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11596 %} 11597 ins_pipe( pipe_slow ); 11598 %} 11599 11600 // fast array equals 11601 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11602 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11603 %{ 11604 match(Set result (AryEq ary1 ary2)); 11605 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11606 //ins_cost(300); 11607 11608 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11609 ins_encode %{ 11610 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 11611 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11612 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11613 %} 11614 ins_pipe( pipe_slow ); 11615 %} 11616 11617 //----------Control Flow Instructions------------------------------------------ 11618 // Signed compare Instructions 11619 11620 // XXX more variants!! 11621 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11622 %{ 11623 match(Set cr (CmpI op1 op2)); 11624 effect(DEF cr, USE op1, USE op2); 11625 11626 format %{ "cmpl $op1, $op2" %} 11627 opcode(0x3B); /* Opcode 3B /r */ 11628 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11629 ins_pipe(ialu_cr_reg_reg); 11630 %} 11631 11632 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11633 %{ 11634 match(Set cr (CmpI op1 op2)); 11635 11636 format %{ "cmpl $op1, $op2" %} 11637 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11638 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11639 ins_pipe(ialu_cr_reg_imm); 11640 %} 11641 11642 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11643 %{ 11644 match(Set cr (CmpI op1 (LoadI op2))); 11645 11646 ins_cost(500); // XXX 11647 format %{ "cmpl $op1, $op2" %} 11648 opcode(0x3B); /* Opcode 3B /r */ 11649 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11650 ins_pipe(ialu_cr_reg_mem); 11651 %} 11652 11653 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11654 %{ 11655 match(Set cr (CmpI src zero)); 11656 11657 format %{ "testl $src, $src" %} 11658 opcode(0x85); 11659 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11660 ins_pipe(ialu_cr_reg_imm); 11661 %} 11662 11663 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11664 %{ 11665 match(Set cr (CmpI (AndI src con) zero)); 11666 11667 format %{ "testl $src, $con" %} 11668 opcode(0xF7, 0x00); 11669 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11670 ins_pipe(ialu_cr_reg_imm); 11671 %} 11672 11673 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11674 %{ 11675 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11676 11677 format %{ "testl $src, $mem" %} 11678 opcode(0x85); 11679 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11680 ins_pipe(ialu_cr_reg_mem); 11681 %} 11682 11683 // Unsigned compare Instructions; really, same as signed except they 11684 // produce an rFlagsRegU instead of rFlagsReg. 11685 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11686 %{ 11687 match(Set cr (CmpU op1 op2)); 11688 11689 format %{ "cmpl $op1, $op2\t# unsigned" %} 11690 opcode(0x3B); /* Opcode 3B /r */ 11691 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11692 ins_pipe(ialu_cr_reg_reg); 11693 %} 11694 11695 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11696 %{ 11697 match(Set cr (CmpU op1 op2)); 11698 11699 format %{ "cmpl $op1, $op2\t# unsigned" %} 11700 opcode(0x81,0x07); /* Opcode 81 /7 */ 11701 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11702 ins_pipe(ialu_cr_reg_imm); 11703 %} 11704 11705 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11706 %{ 11707 match(Set cr (CmpU op1 (LoadI op2))); 11708 11709 ins_cost(500); // XXX 11710 format %{ "cmpl $op1, $op2\t# unsigned" %} 11711 opcode(0x3B); /* Opcode 3B /r */ 11712 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11713 ins_pipe(ialu_cr_reg_mem); 11714 %} 11715 11716 // // // Cisc-spilled version of cmpU_rReg 11717 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11718 // //%{ 11719 // // match(Set cr (CmpU (LoadI op1) op2)); 11720 // // 11721 // // format %{ "CMPu $op1,$op2" %} 11722 // // ins_cost(500); 11723 // // opcode(0x39); /* Opcode 39 /r */ 11724 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11725 // //%} 11726 11727 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11728 %{ 11729 match(Set cr (CmpU src zero)); 11730 11731 format %{ "testl $src, $src\t# unsigned" %} 11732 opcode(0x85); 11733 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11734 ins_pipe(ialu_cr_reg_imm); 11735 %} 11736 11737 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11738 %{ 11739 match(Set cr (CmpP op1 op2)); 11740 11741 format %{ "cmpq $op1, $op2\t# ptr" %} 11742 opcode(0x3B); /* Opcode 3B /r */ 11743 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11744 ins_pipe(ialu_cr_reg_reg); 11745 %} 11746 11747 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11748 %{ 11749 match(Set cr (CmpP op1 (LoadP op2))); 11750 11751 ins_cost(500); // XXX 11752 format %{ "cmpq $op1, $op2\t# ptr" %} 11753 opcode(0x3B); /* Opcode 3B /r */ 11754 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11755 ins_pipe(ialu_cr_reg_mem); 11756 %} 11757 11758 // // // Cisc-spilled version of cmpP_rReg 11759 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11760 // //%{ 11761 // // match(Set cr (CmpP (LoadP op1) op2)); 11762 // // 11763 // // format %{ "CMPu $op1,$op2" %} 11764 // // ins_cost(500); 11765 // // opcode(0x39); /* Opcode 39 /r */ 11766 // // ins_encode( OpcP, reg_mem( op1, op2) ); 11767 // //%} 11768 11769 // XXX this is generalized by compP_rReg_mem??? 11770 // Compare raw pointer (used in out-of-heap check). 11771 // Only works because non-oop pointers must be raw pointers 11772 // and raw pointers have no anti-dependencies. 11773 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11774 %{ 11775 predicate(!n->in(2)->in(2)->bottom_type()->isa_oop_ptr()); 11776 match(Set cr (CmpP op1 (LoadP op2))); 11777 11778 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11779 opcode(0x3B); /* Opcode 3B /r */ 11780 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11781 ins_pipe(ialu_cr_reg_mem); 11782 %} 11783 11784 // This will generate a signed flags result. This should be OK since 11785 // any compare to a zero should be eq/neq. 11786 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11787 %{ 11788 match(Set cr (CmpP src zero)); 11789 11790 format %{ "testq $src, $src\t# ptr" %} 11791 opcode(0x85); 11792 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11793 ins_pipe(ialu_cr_reg_imm); 11794 %} 11795 11796 // This will generate a signed flags result. This should be OK since 11797 // any compare to a zero should be eq/neq. 11798 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11799 %{ 11800 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11801 match(Set cr (CmpP (LoadP op) zero)); 11802 11803 ins_cost(500); // XXX 11804 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11805 opcode(0xF7); /* Opcode F7 /0 */ 11806 ins_encode(REX_mem_wide(op), 11807 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11808 ins_pipe(ialu_cr_reg_imm); 11809 %} 11810 11811 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11812 %{ 11813 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 11814 match(Set cr (CmpP (LoadP mem) zero)); 11815 11816 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11817 ins_encode %{ 11818 __ cmpq(r12, $mem$$Address); 11819 %} 11820 ins_pipe(ialu_cr_reg_mem); 11821 %} 11822 11823 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11824 %{ 11825 match(Set cr (CmpN op1 op2)); 11826 11827 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11828 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11829 ins_pipe(ialu_cr_reg_reg); 11830 %} 11831 11832 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11833 %{ 11834 match(Set cr (CmpN src (LoadN mem))); 11835 11836 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11837 ins_encode %{ 11838 __ cmpl($src$$Register, $mem$$Address); 11839 %} 11840 ins_pipe(ialu_cr_reg_mem); 11841 %} 11842 11843 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11844 match(Set cr (CmpN op1 op2)); 11845 11846 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11847 ins_encode %{ 11848 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11849 %} 11850 ins_pipe(ialu_cr_reg_imm); 11851 %} 11852 11853 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11854 %{ 11855 match(Set cr (CmpN src (LoadN mem))); 11856 11857 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11858 ins_encode %{ 11859 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11860 %} 11861 ins_pipe(ialu_cr_reg_mem); 11862 %} 11863 11864 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11865 match(Set cr (CmpN src zero)); 11866 11867 format %{ "testl $src, $src\t# compressed ptr" %} 11868 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11869 ins_pipe(ialu_cr_reg_imm); 11870 %} 11871 11872 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11873 %{ 11874 predicate(Universe::narrow_oop_base() != NULL); 11875 match(Set cr (CmpN (LoadN mem) zero)); 11876 11877 ins_cost(500); // XXX 11878 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11879 ins_encode %{ 11880 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11881 %} 11882 ins_pipe(ialu_cr_reg_mem); 11883 %} 11884 11885 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11886 %{ 11887 predicate(Universe::narrow_oop_base() == NULL); 11888 match(Set cr (CmpN (LoadN mem) zero)); 11889 11890 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11891 ins_encode %{ 11892 __ cmpl(r12, $mem$$Address); 11893 %} 11894 ins_pipe(ialu_cr_reg_mem); 11895 %} 11896 11897 // Yanked all unsigned pointer compare operations. 11898 // Pointer compares are done with CmpP which is already unsigned. 11899 11900 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11901 %{ 11902 match(Set cr (CmpL op1 op2)); 11903 11904 format %{ "cmpq $op1, $op2" %} 11905 opcode(0x3B); /* Opcode 3B /r */ 11906 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11907 ins_pipe(ialu_cr_reg_reg); 11908 %} 11909 11910 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11911 %{ 11912 match(Set cr (CmpL op1 op2)); 11913 11914 format %{ "cmpq $op1, $op2" %} 11915 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11916 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11917 ins_pipe(ialu_cr_reg_imm); 11918 %} 11919 11920 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11921 %{ 11922 match(Set cr (CmpL op1 (LoadL op2))); 11923 11924 format %{ "cmpq $op1, $op2" %} 11925 opcode(0x3B); /* Opcode 3B /r */ 11926 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11927 ins_pipe(ialu_cr_reg_mem); 11928 %} 11929 11930 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11931 %{ 11932 match(Set cr (CmpL src zero)); 11933 11934 format %{ "testq $src, $src" %} 11935 opcode(0x85); 11936 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11937 ins_pipe(ialu_cr_reg_imm); 11938 %} 11939 11940 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11941 %{ 11942 match(Set cr (CmpL (AndL src con) zero)); 11943 11944 format %{ "testq $src, $con\t# long" %} 11945 opcode(0xF7, 0x00); 11946 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11947 ins_pipe(ialu_cr_reg_imm); 11948 %} 11949 11950 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11951 %{ 11952 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11953 11954 format %{ "testq $src, $mem" %} 11955 opcode(0x85); 11956 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11957 ins_pipe(ialu_cr_reg_mem); 11958 %} 11959 11960 // Manifest a CmpL result in an integer register. Very painful. 11961 // This is the test to avoid. 11962 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11963 %{ 11964 match(Set dst (CmpL3 src1 src2)); 11965 effect(KILL flags); 11966 11967 ins_cost(275); // XXX 11968 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11969 "movl $dst, -1\n\t" 11970 "jl,s done\n\t" 11971 "setne $dst\n\t" 11972 "movzbl $dst, $dst\n\t" 11973 "done:" %} 11974 ins_encode(cmpl3_flag(src1, src2, dst)); 11975 ins_pipe(pipe_slow); 11976 %} 11977 11978 //----------Max and Min-------------------------------------------------------- 11979 // Min Instructions 11980 11981 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11982 %{ 11983 effect(USE_DEF dst, USE src, USE cr); 11984 11985 format %{ "cmovlgt $dst, $src\t# min" %} 11986 opcode(0x0F, 0x4F); 11987 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11988 ins_pipe(pipe_cmov_reg); 11989 %} 11990 11991 11992 instruct minI_rReg(rRegI dst, rRegI src) 11993 %{ 11994 match(Set dst (MinI dst src)); 11995 11996 ins_cost(200); 11997 expand %{ 11998 rFlagsReg cr; 11999 compI_rReg(cr, dst, src); 12000 cmovI_reg_g(dst, src, cr); 12001 %} 12002 %} 12003 12004 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12005 %{ 12006 effect(USE_DEF dst, USE src, USE cr); 12007 12008 format %{ "cmovllt $dst, $src\t# max" %} 12009 opcode(0x0F, 0x4C); 12010 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12011 ins_pipe(pipe_cmov_reg); 12012 %} 12013 12014 12015 instruct maxI_rReg(rRegI dst, rRegI src) 12016 %{ 12017 match(Set dst (MaxI dst src)); 12018 12019 ins_cost(200); 12020 expand %{ 12021 rFlagsReg cr; 12022 compI_rReg(cr, dst, src); 12023 cmovI_reg_l(dst, src, cr); 12024 %} 12025 %} 12026 12027 // ============================================================================ 12028 // Branch Instructions 12029 12030 // Jump Direct - Label defines a relative address from JMP+1 12031 instruct jmpDir(label labl) 12032 %{ 12033 match(Goto); 12034 effect(USE labl); 12035 12036 ins_cost(300); 12037 format %{ "jmp $labl" %} 12038 size(5); 12039 opcode(0xE9); 12040 ins_encode(OpcP, Lbl(labl)); 12041 ins_pipe(pipe_jmp); 12042 ins_pc_relative(1); 12043 %} 12044 12045 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12046 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12047 %{ 12048 match(If cop cr); 12049 effect(USE labl); 12050 12051 ins_cost(300); 12052 format %{ "j$cop $labl" %} 12053 size(6); 12054 opcode(0x0F, 0x80); 12055 ins_encode(Jcc(cop, labl)); 12056 ins_pipe(pipe_jcc); 12057 ins_pc_relative(1); 12058 %} 12059 12060 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12061 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12062 %{ 12063 match(CountedLoopEnd cop cr); 12064 effect(USE labl); 12065 12066 ins_cost(300); 12067 format %{ "j$cop $labl\t# loop end" %} 12068 size(6); 12069 opcode(0x0F, 0x80); 12070 ins_encode(Jcc(cop, labl)); 12071 ins_pipe(pipe_jcc); 12072 ins_pc_relative(1); 12073 %} 12074 12075 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12076 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12077 match(CountedLoopEnd cop cmp); 12078 effect(USE labl); 12079 12080 ins_cost(300); 12081 format %{ "j$cop,u $labl\t# loop end" %} 12082 size(6); 12083 opcode(0x0F, 0x80); 12084 ins_encode(Jcc(cop, labl)); 12085 ins_pipe(pipe_jcc); 12086 ins_pc_relative(1); 12087 %} 12088 12089 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12090 match(CountedLoopEnd cop cmp); 12091 effect(USE labl); 12092 12093 ins_cost(200); 12094 format %{ "j$cop,u $labl\t# loop end" %} 12095 size(6); 12096 opcode(0x0F, 0x80); 12097 ins_encode(Jcc(cop, labl)); 12098 ins_pipe(pipe_jcc); 12099 ins_pc_relative(1); 12100 %} 12101 12102 // Jump Direct Conditional - using unsigned comparison 12103 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12104 match(If cop cmp); 12105 effect(USE labl); 12106 12107 ins_cost(300); 12108 format %{ "j$cop,u $labl" %} 12109 size(6); 12110 opcode(0x0F, 0x80); 12111 ins_encode(Jcc(cop, labl)); 12112 ins_pipe(pipe_jcc); 12113 ins_pc_relative(1); 12114 %} 12115 12116 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12117 match(If cop cmp); 12118 effect(USE labl); 12119 12120 ins_cost(200); 12121 format %{ "j$cop,u $labl" %} 12122 size(6); 12123 opcode(0x0F, 0x80); 12124 ins_encode(Jcc(cop, labl)); 12125 ins_pipe(pipe_jcc); 12126 ins_pc_relative(1); 12127 %} 12128 12129 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12130 match(If cop cmp); 12131 effect(USE labl); 12132 12133 ins_cost(200); 12134 format %{ $$template 12135 if ($cop$$cmpcode == Assembler::notEqual) { 12136 $$emit$$"jp,u $labl\n\t" 12137 $$emit$$"j$cop,u $labl" 12138 } else { 12139 $$emit$$"jp,u done\n\t" 12140 $$emit$$"j$cop,u $labl\n\t" 12141 $$emit$$"done:" 12142 } 12143 %} 12144 size(12); 12145 opcode(0x0F, 0x80); 12146 ins_encode %{ 12147 Label* l = $labl$$label; 12148 $$$emit8$primary; 12149 emit_cc(cbuf, $secondary, Assembler::parity); 12150 int parity_disp = -1; 12151 if ($cop$$cmpcode == Assembler::notEqual) { 12152 // the two jumps 6 bytes apart so the jump distances are too 12153 parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0; 12154 } else if ($cop$$cmpcode == Assembler::equal) { 12155 parity_disp = 6; 12156 } else { 12157 ShouldNotReachHere(); 12158 } 12159 emit_d32(cbuf, parity_disp); 12160 $$$emit8$primary; 12161 emit_cc(cbuf, $secondary, $cop$$cmpcode); 12162 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0; 12163 emit_d32(cbuf, disp); 12164 %} 12165 ins_pipe(pipe_jcc); 12166 ins_pc_relative(1); 12167 %} 12168 12169 // ============================================================================ 12170 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12171 // superklass array for an instance of the superklass. Set a hidden 12172 // internal cache on a hit (cache is checked with exposed code in 12173 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12174 // encoding ALSO sets flags. 12175 12176 instruct partialSubtypeCheck(rdi_RegP result, 12177 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12178 rFlagsReg cr) 12179 %{ 12180 match(Set result (PartialSubtypeCheck sub super)); 12181 effect(KILL rcx, KILL cr); 12182 12183 ins_cost(1100); // slightly larger than the next version 12184 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" 12185 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 12186 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 12187 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12188 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12189 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" 12190 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12191 "miss:\t" %} 12192 12193 opcode(0x1); // Force a XOR of RDI 12194 ins_encode(enc_PartialSubtypeCheck()); 12195 ins_pipe(pipe_slow); 12196 %} 12197 12198 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12199 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12200 immP0 zero, 12201 rdi_RegP result) 12202 %{ 12203 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12204 effect(KILL rcx, KILL result); 12205 12206 ins_cost(1000); 12207 format %{ "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" 12208 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 12209 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 12210 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12211 "jne,s miss\t\t# Missed: flags nz\n\t" 12212 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" 12213 "miss:\t" %} 12214 12215 opcode(0x0); // No need to XOR RDI 12216 ins_encode(enc_PartialSubtypeCheck()); 12217 ins_pipe(pipe_slow); 12218 %} 12219 12220 // ============================================================================ 12221 // Branch Instructions -- short offset versions 12222 // 12223 // These instructions are used to replace jumps of a long offset (the default 12224 // match) with jumps of a shorter offset. These instructions are all tagged 12225 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12226 // match rules in general matching. Instead, the ADLC generates a conversion 12227 // method in the MachNode which can be used to do in-place replacement of the 12228 // long variant with the shorter variant. The compiler will determine if a 12229 // branch can be taken by the is_short_branch_offset() predicate in the machine 12230 // specific code section of the file. 12231 12232 // Jump Direct - Label defines a relative address from JMP+1 12233 instruct jmpDir_short(label labl) %{ 12234 match(Goto); 12235 effect(USE labl); 12236 12237 ins_cost(300); 12238 format %{ "jmp,s $labl" %} 12239 size(2); 12240 opcode(0xEB); 12241 ins_encode(OpcP, LblShort(labl)); 12242 ins_pipe(pipe_jmp); 12243 ins_pc_relative(1); 12244 ins_short_branch(1); 12245 %} 12246 12247 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12248 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12249 match(If cop cr); 12250 effect(USE labl); 12251 12252 ins_cost(300); 12253 format %{ "j$cop,s $labl" %} 12254 size(2); 12255 opcode(0x70); 12256 ins_encode(JccShort(cop, labl)); 12257 ins_pipe(pipe_jcc); 12258 ins_pc_relative(1); 12259 ins_short_branch(1); 12260 %} 12261 12262 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12263 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12264 match(CountedLoopEnd cop cr); 12265 effect(USE labl); 12266 12267 ins_cost(300); 12268 format %{ "j$cop,s $labl\t# loop end" %} 12269 size(2); 12270 opcode(0x70); 12271 ins_encode(JccShort(cop, labl)); 12272 ins_pipe(pipe_jcc); 12273 ins_pc_relative(1); 12274 ins_short_branch(1); 12275 %} 12276 12277 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12278 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12279 match(CountedLoopEnd cop cmp); 12280 effect(USE labl); 12281 12282 ins_cost(300); 12283 format %{ "j$cop,us $labl\t# loop end" %} 12284 size(2); 12285 opcode(0x70); 12286 ins_encode(JccShort(cop, labl)); 12287 ins_pipe(pipe_jcc); 12288 ins_pc_relative(1); 12289 ins_short_branch(1); 12290 %} 12291 12292 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12293 match(CountedLoopEnd cop cmp); 12294 effect(USE labl); 12295 12296 ins_cost(300); 12297 format %{ "j$cop,us $labl\t# loop end" %} 12298 size(2); 12299 opcode(0x70); 12300 ins_encode(JccShort(cop, labl)); 12301 ins_pipe(pipe_jcc); 12302 ins_pc_relative(1); 12303 ins_short_branch(1); 12304 %} 12305 12306 // Jump Direct Conditional - using unsigned comparison 12307 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12308 match(If cop cmp); 12309 effect(USE labl); 12310 12311 ins_cost(300); 12312 format %{ "j$cop,us $labl" %} 12313 size(2); 12314 opcode(0x70); 12315 ins_encode(JccShort(cop, labl)); 12316 ins_pipe(pipe_jcc); 12317 ins_pc_relative(1); 12318 ins_short_branch(1); 12319 %} 12320 12321 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12322 match(If cop cmp); 12323 effect(USE labl); 12324 12325 ins_cost(300); 12326 format %{ "j$cop,us $labl" %} 12327 size(2); 12328 opcode(0x70); 12329 ins_encode(JccShort(cop, labl)); 12330 ins_pipe(pipe_jcc); 12331 ins_pc_relative(1); 12332 ins_short_branch(1); 12333 %} 12334 12335 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12336 match(If cop cmp); 12337 effect(USE labl); 12338 12339 ins_cost(300); 12340 format %{ $$template 12341 if ($cop$$cmpcode == Assembler::notEqual) { 12342 $$emit$$"jp,u,s $labl\n\t" 12343 $$emit$$"j$cop,u,s $labl" 12344 } else { 12345 $$emit$$"jp,u,s done\n\t" 12346 $$emit$$"j$cop,u,s $labl\n\t" 12347 $$emit$$"done:" 12348 } 12349 %} 12350 size(4); 12351 opcode(0x70); 12352 ins_encode %{ 12353 Label* l = $labl$$label; 12354 emit_cc(cbuf, $primary, Assembler::parity); 12355 int parity_disp = -1; 12356 if ($cop$$cmpcode == Assembler::notEqual) { 12357 parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; 12358 } else if ($cop$$cmpcode == Assembler::equal) { 12359 parity_disp = 2; 12360 } else { 12361 ShouldNotReachHere(); 12362 } 12363 emit_d8(cbuf, parity_disp); 12364 emit_cc(cbuf, $primary, $cop$$cmpcode); 12365 int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0; 12366 emit_d8(cbuf, disp); 12367 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 12368 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp"); 12369 %} 12370 ins_pipe(pipe_jcc); 12371 ins_pc_relative(1); 12372 ins_short_branch(1); 12373 %} 12374 12375 // ============================================================================ 12376 // inlined locking and unlocking 12377 12378 instruct cmpFastLock(rFlagsReg cr, 12379 rRegP object, rRegP box, rax_RegI tmp, rRegP scr) 12380 %{ 12381 match(Set cr (FastLock object box)); 12382 effect(TEMP tmp, TEMP scr); 12383 12384 ins_cost(300); 12385 format %{ "fastlock $object,$box,$tmp,$scr" %} 12386 ins_encode(Fast_Lock(object, box, tmp, scr)); 12387 ins_pipe(pipe_slow); 12388 ins_pc_relative(1); 12389 %} 12390 12391 instruct cmpFastUnlock(rFlagsReg cr, 12392 rRegP object, rax_RegP box, rRegP tmp) 12393 %{ 12394 match(Set cr (FastUnlock object box)); 12395 effect(TEMP tmp); 12396 12397 ins_cost(300); 12398 format %{ "fastunlock $object, $box, $tmp" %} 12399 ins_encode(Fast_Unlock(object, box, tmp)); 12400 ins_pipe(pipe_slow); 12401 ins_pc_relative(1); 12402 %} 12403 12404 12405 // ============================================================================ 12406 // Safepoint Instructions 12407 instruct safePoint_poll(rFlagsReg cr) 12408 %{ 12409 predicate(!Assembler::is_polling_page_far()); 12410 match(SafePoint); 12411 effect(KILL cr); 12412 12413 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12414 "# Safepoint: poll for GC" %} 12415 ins_cost(125); 12416 ins_encode %{ 12417 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12418 __ testl(rax, addr); 12419 %} 12420 ins_pipe(ialu_reg_mem); 12421 %} 12422 12423 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12424 %{ 12425 predicate(Assembler::is_polling_page_far()); 12426 match(SafePoint poll); 12427 effect(KILL cr, USE poll); 12428 12429 format %{ "testl rax, [$poll]\t" 12430 "# Safepoint: poll for GC" %} 12431 ins_cost(125); 12432 ins_encode %{ 12433 __ relocate(relocInfo::poll_type); 12434 __ testl(rax, Address($poll$$Register, 0)); 12435 %} 12436 ins_pipe(ialu_reg_mem); 12437 %} 12438 12439 // ============================================================================ 12440 // Procedure Call/Return Instructions 12441 // Call Java Static Instruction 12442 // Note: If this code changes, the corresponding ret_addr_offset() and 12443 // compute_padding() functions will have to be adjusted. 12444 instruct CallStaticJavaDirect(method meth) %{ 12445 match(CallStaticJava); 12446 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); 12447 effect(USE meth); 12448 12449 ins_cost(300); 12450 format %{ "call,static " %} 12451 opcode(0xE8); /* E8 cd */ 12452 ins_encode(Java_Static_Call(meth), call_epilog); 12453 ins_pipe(pipe_slow); 12454 ins_pc_relative(1); 12455 ins_alignment(4); 12456 %} 12457 12458 // Call Java Static Instruction (method handle version) 12459 // Note: If this code changes, the corresponding ret_addr_offset() and 12460 // compute_padding() functions will have to be adjusted. 12461 instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{ 12462 match(CallStaticJava); 12463 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); 12464 effect(USE meth); 12465 // RBP is saved by all callees (for interpreter stack correction). 12466 // We use it here for a similar purpose, in {preserve,restore}_SP. 12467 12468 ins_cost(300); 12469 format %{ "call,static/MethodHandle " %} 12470 opcode(0xE8); /* E8 cd */ 12471 ins_encode(preserve_SP, 12472 Java_Static_Call(meth), 12473 restore_SP, 12474 call_epilog); 12475 ins_pipe(pipe_slow); 12476 ins_pc_relative(1); 12477 ins_alignment(4); 12478 %} 12479 12480 // Call Java Dynamic Instruction 12481 // Note: If this code changes, the corresponding ret_addr_offset() and 12482 // compute_padding() functions will have to be adjusted. 12483 instruct CallDynamicJavaDirect(method meth) 12484 %{ 12485 match(CallDynamicJava); 12486 effect(USE meth); 12487 12488 ins_cost(300); 12489 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12490 "call,dynamic " %} 12491 opcode(0xE8); /* E8 cd */ 12492 ins_encode(Java_Dynamic_Call(meth), call_epilog); 12493 ins_pipe(pipe_slow); 12494 ins_pc_relative(1); 12495 ins_alignment(4); 12496 %} 12497 12498 // Call Runtime Instruction 12499 instruct CallRuntimeDirect(method meth) 12500 %{ 12501 match(CallRuntime); 12502 effect(USE meth); 12503 12504 ins_cost(300); 12505 format %{ "call,runtime " %} 12506 opcode(0xE8); /* E8 cd */ 12507 ins_encode(Java_To_Runtime(meth)); 12508 ins_pipe(pipe_slow); 12509 ins_pc_relative(1); 12510 %} 12511 12512 // Call runtime without safepoint 12513 instruct CallLeafDirect(method meth) 12514 %{ 12515 match(CallLeaf); 12516 effect(USE meth); 12517 12518 ins_cost(300); 12519 format %{ "call_leaf,runtime " %} 12520 opcode(0xE8); /* E8 cd */ 12521 ins_encode(Java_To_Runtime(meth)); 12522 ins_pipe(pipe_slow); 12523 ins_pc_relative(1); 12524 %} 12525 12526 // Call runtime without safepoint 12527 instruct CallLeafNoFPDirect(method meth) 12528 %{ 12529 match(CallLeafNoFP); 12530 effect(USE meth); 12531 12532 ins_cost(300); 12533 format %{ "call_leaf_nofp,runtime " %} 12534 opcode(0xE8); /* E8 cd */ 12535 ins_encode(Java_To_Runtime(meth)); 12536 ins_pipe(pipe_slow); 12537 ins_pc_relative(1); 12538 %} 12539 12540 // Return Instruction 12541 // Remove the return address & jump to it. 12542 // Notice: We always emit a nop after a ret to make sure there is room 12543 // for safepoint patching 12544 instruct Ret() 12545 %{ 12546 match(Return); 12547 12548 format %{ "ret" %} 12549 opcode(0xC3); 12550 ins_encode(OpcP); 12551 ins_pipe(pipe_jmp); 12552 %} 12553 12554 // Tail Call; Jump from runtime stub to Java code. 12555 // Also known as an 'interprocedural jump'. 12556 // Target of jump will eventually return to caller. 12557 // TailJump below removes the return address. 12558 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12559 %{ 12560 match(TailCall jump_target method_oop); 12561 12562 ins_cost(300); 12563 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12564 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12565 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12566 ins_pipe(pipe_jmp); 12567 %} 12568 12569 // Tail Jump; remove the return address; jump to target. 12570 // TailCall above leaves the return address around. 12571 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12572 %{ 12573 match(TailJump jump_target ex_oop); 12574 12575 ins_cost(300); 12576 format %{ "popq rdx\t# pop return address\n\t" 12577 "jmp $jump_target" %} 12578 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12579 ins_encode(Opcode(0x5a), // popq rdx 12580 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12581 ins_pipe(pipe_jmp); 12582 %} 12583 12584 // Create exception oop: created by stack-crawling runtime code. 12585 // Created exception is now available to this handler, and is setup 12586 // just prior to jumping to this handler. No code emitted. 12587 instruct CreateException(rax_RegP ex_oop) 12588 %{ 12589 match(Set ex_oop (CreateEx)); 12590 12591 size(0); 12592 // use the following format syntax 12593 format %{ "# exception oop is in rax; no code emitted" %} 12594 ins_encode(); 12595 ins_pipe(empty); 12596 %} 12597 12598 // Rethrow exception: 12599 // The exception oop will come in the first argument position. 12600 // Then JUMP (not call) to the rethrow stub code. 12601 instruct RethrowException() 12602 %{ 12603 match(Rethrow); 12604 12605 // use the following format syntax 12606 format %{ "jmp rethrow_stub" %} 12607 ins_encode(enc_rethrow); 12608 ins_pipe(pipe_jmp); 12609 %} 12610 12611 12612 //----------PEEPHOLE RULES----------------------------------------------------- 12613 // These must follow all instruction definitions as they use the names 12614 // defined in the instructions definitions. 12615 // 12616 // peepmatch ( root_instr_name [preceding_instruction]* ); 12617 // 12618 // peepconstraint %{ 12619 // (instruction_number.operand_name relational_op instruction_number.operand_name 12620 // [, ...] ); 12621 // // instruction numbers are zero-based using left to right order in peepmatch 12622 // 12623 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12624 // // provide an instruction_number.operand_name for each operand that appears 12625 // // in the replacement instruction's match rule 12626 // 12627 // ---------VM FLAGS--------------------------------------------------------- 12628 // 12629 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12630 // 12631 // Each peephole rule is given an identifying number starting with zero and 12632 // increasing by one in the order seen by the parser. An individual peephole 12633 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12634 // on the command-line. 12635 // 12636 // ---------CURRENT LIMITATIONS---------------------------------------------- 12637 // 12638 // Only match adjacent instructions in same basic block 12639 // Only equality constraints 12640 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12641 // Only one replacement instruction 12642 // 12643 // ---------EXAMPLE---------------------------------------------------------- 12644 // 12645 // // pertinent parts of existing instructions in architecture description 12646 // instruct movI(rRegI dst, rRegI src) 12647 // %{ 12648 // match(Set dst (CopyI src)); 12649 // %} 12650 // 12651 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12652 // %{ 12653 // match(Set dst (AddI dst src)); 12654 // effect(KILL cr); 12655 // %} 12656 // 12657 // // Change (inc mov) to lea 12658 // peephole %{ 12659 // // increment preceeded by register-register move 12660 // peepmatch ( incI_rReg movI ); 12661 // // require that the destination register of the increment 12662 // // match the destination register of the move 12663 // peepconstraint ( 0.dst == 1.dst ); 12664 // // construct a replacement instruction that sets 12665 // // the destination to ( move's source register + one ) 12666 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12667 // %} 12668 // 12669 12670 // Implementation no longer uses movX instructions since 12671 // machine-independent system no longer uses CopyX nodes. 12672 // 12673 // peephole 12674 // %{ 12675 // peepmatch (incI_rReg movI); 12676 // peepconstraint (0.dst == 1.dst); 12677 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12678 // %} 12679 12680 // peephole 12681 // %{ 12682 // peepmatch (decI_rReg movI); 12683 // peepconstraint (0.dst == 1.dst); 12684 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12685 // %} 12686 12687 // peephole 12688 // %{ 12689 // peepmatch (addI_rReg_imm movI); 12690 // peepconstraint (0.dst == 1.dst); 12691 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12692 // %} 12693 12694 // peephole 12695 // %{ 12696 // peepmatch (incL_rReg movL); 12697 // peepconstraint (0.dst == 1.dst); 12698 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12699 // %} 12700 12701 // peephole 12702 // %{ 12703 // peepmatch (decL_rReg movL); 12704 // peepconstraint (0.dst == 1.dst); 12705 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12706 // %} 12707 12708 // peephole 12709 // %{ 12710 // peepmatch (addL_rReg_imm movL); 12711 // peepconstraint (0.dst == 1.dst); 12712 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12713 // %} 12714 12715 // peephole 12716 // %{ 12717 // peepmatch (addP_rReg_imm movP); 12718 // peepconstraint (0.dst == 1.dst); 12719 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12720 // %} 12721 12722 // // Change load of spilled value to only a spill 12723 // instruct storeI(memory mem, rRegI src) 12724 // %{ 12725 // match(Set mem (StoreI mem src)); 12726 // %} 12727 // 12728 // instruct loadI(rRegI dst, memory mem) 12729 // %{ 12730 // match(Set dst (LoadI mem)); 12731 // %} 12732 // 12733 12734 peephole 12735 %{ 12736 peepmatch (loadI storeI); 12737 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12738 peepreplace (storeI(1.mem 1.mem 1.src)); 12739 %} 12740 12741 peephole 12742 %{ 12743 peepmatch (loadL storeL); 12744 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12745 peepreplace (storeL(1.mem 1.mem 1.src)); 12746 %} 12747 12748 //----------SMARTSPILL RULES--------------------------------------------------- 12749 // These must follow all instruction definitions as they use the names 12750 // defined in the instructions definitions.