1 // 2 // Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, Red Hat Inc. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // AArch64 Architecture Description File 27 28 //----------REGISTER DEFINITION BLOCK------------------------------------------ 29 // This information is used by the matcher and the register allocator to 30 // describe individual registers and classes of registers within the target 31 // archtecture. 32 33 register %{ 34 //----------Architecture Description Register Definitions---------------------- 35 // General Registers 36 // "reg_def" name ( register save type, C convention save type, 37 // ideal register type, encoding ); 38 // Register Save Types: 39 // 40 // NS = No-Save: The register allocator assumes that these registers 41 // can be used without saving upon entry to the method, & 42 // that they do not need to be saved at call sites. 43 // 44 // SOC = Save-On-Call: The register allocator assumes that these registers 45 // can be used without saving upon entry to the method, 46 // but that they must be saved at call sites. 47 // 48 // SOE = Save-On-Entry: The register allocator assumes that these registers 49 // must be saved before using them upon entry to the 50 // method, but they do not need to be saved at call 51 // sites. 52 // 53 // AS = Always-Save: The register allocator assumes that these registers 54 // must be saved before using them upon entry to the 55 // method, & that they must be saved at call sites. 56 // 57 // Ideal Register Type is used to determine how to save & restore a 58 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 59 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 60 // 61 // The encoding number is the actual bit-pattern placed into the opcodes. 62 63 // We must define the 64 bit int registers in two 32 bit halves, the 64 // real lower register and a virtual upper half register. upper halves 65 // are used by the register allocator but are not actually supplied as 66 // operands to memory ops. 67 // 68 // follow the C1 compiler in making registers 69 // 70 // r0-r7,r10-r26 volatile (caller save) 71 // r27-r32 system (no save, no allocate) 72 // r8-r9 invisible to the allocator (so we can use them as scratch regs) 73 // 74 // as regards Java usage. we don't use any callee save registers 75 // because this makes it difficult to de-optimise a frame (see comment 76 // in x86 implementation of Deoptimization::unwind_callee_save_values) 77 // 78 79 // General Registers 80 81 reg_def R0 ( SOC, SOC, Op_RegI, 0, r0->as_VMReg() ); 82 reg_def R0_H ( SOC, SOC, Op_RegI, 0, r0->as_VMReg()->next() ); 83 reg_def R1 ( SOC, SOC, Op_RegI, 1, r1->as_VMReg() ); 84 reg_def R1_H ( SOC, SOC, Op_RegI, 1, r1->as_VMReg()->next() ); 85 reg_def R2 ( SOC, SOC, Op_RegI, 2, r2->as_VMReg() ); 86 reg_def R2_H ( SOC, SOC, Op_RegI, 2, r2->as_VMReg()->next() ); 87 reg_def R3 ( SOC, SOC, Op_RegI, 3, r3->as_VMReg() ); 88 reg_def R3_H ( SOC, SOC, Op_RegI, 3, r3->as_VMReg()->next() ); 89 reg_def R4 ( SOC, SOC, Op_RegI, 4, r4->as_VMReg() ); 90 reg_def R4_H ( SOC, SOC, Op_RegI, 4, r4->as_VMReg()->next() ); 91 reg_def R5 ( SOC, SOC, Op_RegI, 5, r5->as_VMReg() ); 92 reg_def R5_H ( SOC, SOC, Op_RegI, 5, r5->as_VMReg()->next() ); 93 reg_def R6 ( SOC, SOC, Op_RegI, 6, r6->as_VMReg() ); 94 reg_def R6_H ( SOC, SOC, Op_RegI, 6, r6->as_VMReg()->next() ); 95 reg_def R7 ( SOC, SOC, Op_RegI, 7, r7->as_VMReg() ); 96 reg_def R7_H ( SOC, SOC, Op_RegI, 7, r7->as_VMReg()->next() ); 97 reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() ); 98 reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 99 reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() ); 100 reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 101 reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() ); 102 reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next()); 103 reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() ); 104 reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next()); 105 reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() ); 106 reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next()); 107 reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() ); 108 reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next()); 109 reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); 110 reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 111 reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); 112 reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 113 reg_def R18 ( SOC, SOC, Op_RegI, 18, r18->as_VMReg() ); 114 reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); 115 reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); 116 reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); 117 reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp 118 reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next()); 119 reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() ); 120 reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next()); 121 reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() ); 122 reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next()); 123 reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() ); 124 reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next()); 125 reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() ); 126 reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next()); 127 reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); 128 reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); 129 reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); 130 reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); 131 reg_def R27 ( NS, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 132 reg_def R27_H ( NS, SOE, Op_RegI, 27, r27->as_VMReg()->next()); 133 reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread 134 reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); 135 reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp 136 reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next()); 137 reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr 138 reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next()); 139 reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp 140 reg_def R31_H ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg()->next()); 141 142 // ---------------------------- 143 // Float/Double Registers 144 // ---------------------------- 145 146 // Double Registers 147 148 // The rules of ADL require that double registers be defined in pairs. 149 // Each pair must be two 32-bit values, but not necessarily a pair of 150 // single float registers. In each pair, ADLC-assigned register numbers 151 // must be adjacent, with the lower number even. Finally, when the 152 // CPU stores such a register pair to memory, the word associated with 153 // the lower ADLC-assigned number must be stored to the lower address. 154 155 // AArch64 has 32 floating-point registers. Each can store a vector of 156 // single or double precision floating-point values up to 8 * 32 157 // floats, 4 * 64 bit floats or 2 * 128 bit floats. We currently only 158 // use the first float or double element of the vector. 159 160 // for Java use float registers v0-v15 are always save on call whereas 161 // the platform ABI treats v8-v15 as callee save). float registers 162 // v16-v31 are SOC as per the platform spec 163 164 reg_def V0 ( SOC, SOC, Op_RegF, 0, v0->as_VMReg() ); 165 reg_def V0_H ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next() ); 166 reg_def V1 ( SOC, SOC, Op_RegF, 1, v1->as_VMReg() ); 167 reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next() ); 168 reg_def V2 ( SOC, SOC, Op_RegF, 2, v2->as_VMReg() ); 169 reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next() ); 170 reg_def V3 ( SOC, SOC, Op_RegF, 3, v3->as_VMReg() ); 171 reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next() ); 172 reg_def V4 ( SOC, SOC, Op_RegF, 4, v4->as_VMReg() ); 173 reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next() ); 174 reg_def V5 ( SOC, SOC, Op_RegF, 5, v5->as_VMReg() ); 175 reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next() ); 176 reg_def V6 ( SOC, SOC, Op_RegF, 6, v6->as_VMReg() ); 177 reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next() ); 178 reg_def V7 ( SOC, SOC, Op_RegF, 7, v7->as_VMReg() ); 179 reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next() ); 180 reg_def V8 ( SOC, SOE, Op_RegF, 8, v8->as_VMReg() ); 181 reg_def V8_H ( SOC, SOE, Op_RegF, 8, v8->as_VMReg()->next() ); 182 reg_def V9 ( SOC, SOE, Op_RegF, 9, v9->as_VMReg() ); 183 reg_def V9_H ( SOC, SOE, Op_RegF, 9, v9->as_VMReg()->next() ); 184 reg_def V10 ( SOC, SOE, Op_RegF, 10, v10->as_VMReg() ); 185 reg_def V10_H( SOC, SOE, Op_RegF, 10, v10->as_VMReg()->next()); 186 reg_def V11 ( SOC, SOE, Op_RegF, 11, v11->as_VMReg() ); 187 reg_def V11_H( SOC, SOE, Op_RegF, 11, v11->as_VMReg()->next()); 188 reg_def V12 ( SOC, SOE, Op_RegF, 12, v12->as_VMReg() ); 189 reg_def V12_H( SOC, SOE, Op_RegF, 12, v12->as_VMReg()->next()); 190 reg_def V13 ( SOC, SOE, Op_RegF, 13, v13->as_VMReg() ); 191 reg_def V13_H( SOC, SOE, Op_RegF, 13, v13->as_VMReg()->next()); 192 reg_def V14 ( SOC, SOE, Op_RegF, 14, v14->as_VMReg() ); 193 reg_def V14_H( SOC, SOE, Op_RegF, 14, v14->as_VMReg()->next()); 194 reg_def V15 ( SOC, SOE, Op_RegF, 15, v15->as_VMReg() ); 195 reg_def V15_H( SOC, SOE, Op_RegF, 15, v15->as_VMReg()->next()); 196 reg_def V16 ( SOC, SOC, Op_RegF, 16, v16->as_VMReg() ); 197 reg_def V16_H( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next()); 198 reg_def V17 ( SOC, SOC, Op_RegF, 17, v17->as_VMReg() ); 199 reg_def V17_H( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next()); 200 reg_def V18 ( SOC, SOC, Op_RegF, 18, v18->as_VMReg() ); 201 reg_def V18_H( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next()); 202 reg_def V19 ( SOC, SOC, Op_RegF, 19, v19->as_VMReg() ); 203 reg_def V19_H( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next()); 204 reg_def V20 ( SOC, SOC, Op_RegF, 20, v20->as_VMReg() ); 205 reg_def V20_H( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next()); 206 reg_def V21 ( SOC, SOC, Op_RegF, 21, v21->as_VMReg() ); 207 reg_def V21_H( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next()); 208 reg_def V22 ( SOC, SOC, Op_RegF, 22, v22->as_VMReg() ); 209 reg_def V22_H( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next()); 210 reg_def V23 ( SOC, SOC, Op_RegF, 23, v23->as_VMReg() ); 211 reg_def V23_H( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next()); 212 reg_def V24 ( SOC, SOC, Op_RegF, 24, v24->as_VMReg() ); 213 reg_def V24_H( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next()); 214 reg_def V25 ( SOC, SOC, Op_RegF, 25, v25->as_VMReg() ); 215 reg_def V25_H( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next()); 216 reg_def V26 ( SOC, SOC, Op_RegF, 26, v26->as_VMReg() ); 217 reg_def V26_H( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next()); 218 reg_def V27 ( SOC, SOC, Op_RegF, 27, v27->as_VMReg() ); 219 reg_def V27_H( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next()); 220 reg_def V28 ( SOC, SOC, Op_RegF, 28, v28->as_VMReg() ); 221 reg_def V28_H( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next()); 222 reg_def V29 ( SOC, SOC, Op_RegF, 29, v29->as_VMReg() ); 223 reg_def V29_H( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next()); 224 reg_def V30 ( SOC, SOC, Op_RegF, 30, v30->as_VMReg() ); 225 reg_def V30_H( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next()); 226 reg_def V31 ( SOC, SOC, Op_RegF, 31, v31->as_VMReg() ); 227 reg_def V31_H( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // the AArch64 CSPR status flag register is not directly acessible as 234 // instruction operand. the FPSR status flag register is a system 235 // register which can be written/read using MSR/MRS but again does not 236 // appear as an operand (a code identifying the FSPR occurs as an 237 // immediate value in the instruction). 238 239 reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad()); 240 241 242 // Specify priority of register selection within phases of register 243 // allocation. Highest priority is first. A useful heuristic is to 244 // give registers a low priority when they are required by machine 245 // instructions, like EAX and EDX on I486, and choose no-save registers 246 // before save-on-call, & save-on-call before save-on-entry. Registers 247 // which participate in fixed calling sequences should come last. 248 // Registers which are used as pairs must fall on an even boundary. 249 250 alloc_class chunk0( 251 // volatiles 252 R10, R10_H, 253 R11, R11_H, 254 R12, R12_H, 255 R13, R13_H, 256 R14, R14_H, 257 R15, R15_H, 258 R16, R16_H, 259 R17, R17_H, 260 R18, R18_H, 261 262 // arg registers 263 R0, R0_H, 264 R1, R1_H, 265 R2, R2_H, 266 R3, R3_H, 267 R4, R4_H, 268 R5, R5_H, 269 R6, R6_H, 270 R7, R7_H, 271 272 // non-volatiles 273 R19, R19_H, 274 R20, R20_H, 275 R21, R21_H, 276 R22, R22_H, 277 R23, R23_H, 278 R24, R24_H, 279 R25, R25_H, 280 R26, R26_H, 281 282 // non-allocatable registers 283 284 R27, R27_H, // heapbase 285 R28, R28_H, // thread 286 R29, R29_H, // fp 287 R30, R30_H, // lr 288 R31, R31_H, // sp 289 ); 290 291 alloc_class chunk1( 292 293 // no save 294 V16, V16_H, 295 V17, V17_H, 296 V18, V18_H, 297 V19, V19_H, 298 V20, V20_H, 299 V21, V21_H, 300 V22, V22_H, 301 V23, V23_H, 302 V24, V24_H, 303 V25, V25_H, 304 V26, V26_H, 305 V27, V27_H, 306 V28, V28_H, 307 V29, V29_H, 308 V30, V30_H, 309 V31, V31_H, 310 311 // arg registers 312 V0, V0_H, 313 V1, V1_H, 314 V2, V2_H, 315 V3, V3_H, 316 V4, V4_H, 317 V5, V5_H, 318 V6, V6_H, 319 V7, V7_H, 320 321 // non-volatiles 322 V8, V8_H, 323 V9, V9_H, 324 V10, V10_H, 325 V11, V11_H, 326 V12, V12_H, 327 V13, V13_H, 328 V14, V14_H, 329 V15, V15_H, 330 ); 331 332 alloc_class chunk2(RFLAGS); 333 334 //----------Architecture Description Register Classes-------------------------- 335 // Several register classes are automatically defined based upon information in 336 // this architecture description. 337 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 338 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 339 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 340 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 341 // 342 343 // Class for all 32 bit integer registers -- excludes SP which will 344 // never be used as an integer register 345 reg_class any_reg32( 346 R0, 347 R1, 348 R2, 349 R3, 350 R4, 351 R5, 352 R6, 353 R7, 354 R10, 355 R11, 356 R12, 357 R13, 358 R14, 359 R15, 360 R16, 361 R17, 362 R18, 363 R19, 364 R20, 365 R21, 366 R22, 367 R23, 368 R24, 369 R25, 370 R26, 371 R27, 372 R28, 373 R29, 374 R30 375 ); 376 377 // Singleton class for R0 int register 378 reg_class int_r0_reg(R0); 379 380 // Singleton class for R2 int register 381 reg_class int_r2_reg(R2); 382 383 // Singleton class for R3 int register 384 reg_class int_r3_reg(R3); 385 386 // Singleton class for R4 int register 387 reg_class int_r4_reg(R4); 388 389 // Class for all long integer registers (including RSP) 390 reg_class any_reg( 391 R0, R0_H, 392 R1, R1_H, 393 R2, R2_H, 394 R3, R3_H, 395 R4, R4_H, 396 R5, R5_H, 397 R6, R6_H, 398 R7, R7_H, 399 R10, R10_H, 400 R11, R11_H, 401 R12, R12_H, 402 R13, R13_H, 403 R14, R14_H, 404 R15, R15_H, 405 R16, R16_H, 406 R17, R17_H, 407 R18, R18_H, 408 R19, R19_H, 409 R20, R20_H, 410 R21, R21_H, 411 R22, R22_H, 412 R23, R23_H, 413 R24, R24_H, 414 R25, R25_H, 415 R26, R26_H, 416 R27, R27_H, 417 R28, R28_H, 418 R29, R29_H, 419 R30, R30_H, 420 R31, R31_H 421 ); 422 423 // Class for all non-special integer registers 424 reg_class no_special_reg32_no_fp( 425 R0, 426 R1, 427 R2, 428 R3, 429 R4, 430 R5, 431 R6, 432 R7, 433 R10, 434 R11, 435 R12, // rmethod 436 R13, 437 R14, 438 R15, 439 R16, 440 R17, 441 R18, 442 R19, 443 R20, 444 R21, 445 R22, 446 R23, 447 R24, 448 R25, 449 R26 450 /* R27, */ // heapbase 451 /* R28, */ // thread 452 /* R29, */ // fp 453 /* R30, */ // lr 454 /* R31 */ // sp 455 ); 456 457 reg_class no_special_reg32_with_fp( 458 R0, 459 R1, 460 R2, 461 R3, 462 R4, 463 R5, 464 R6, 465 R7, 466 R10, 467 R11, 468 R12, // rmethod 469 R13, 470 R14, 471 R15, 472 R16, 473 R17, 474 R18, 475 R19, 476 R20, 477 R21, 478 R22, 479 R23, 480 R24, 481 R25, 482 R26 483 /* R27, */ // heapbase 484 /* R28, */ // thread 485 R29, // fp 486 /* R30, */ // lr 487 /* R31 */ // sp 488 ); 489 490 reg_class_dynamic no_special_reg32(no_special_reg32_no_fp, no_special_reg32_with_fp, %{ PreserveFramePointer %}); 491 492 // Class for all non-special long integer registers 493 reg_class no_special_reg_no_fp( 494 R0, R0_H, 495 R1, R1_H, 496 R2, R2_H, 497 R3, R3_H, 498 R4, R4_H, 499 R5, R5_H, 500 R6, R6_H, 501 R7, R7_H, 502 R10, R10_H, 503 R11, R11_H, 504 R12, R12_H, // rmethod 505 R13, R13_H, 506 R14, R14_H, 507 R15, R15_H, 508 R16, R16_H, 509 R17, R17_H, 510 R18, R18_H, 511 R19, R19_H, 512 R20, R20_H, 513 R21, R21_H, 514 R22, R22_H, 515 R23, R23_H, 516 R24, R24_H, 517 R25, R25_H, 518 R26, R26_H, 519 /* R27, R27_H, */ // heapbase 520 /* R28, R28_H, */ // thread 521 /* R29, R29_H, */ // fp 522 /* R30, R30_H, */ // lr 523 /* R31, R31_H */ // sp 524 ); 525 526 reg_class no_special_reg_with_fp( 527 R0, R0_H, 528 R1, R1_H, 529 R2, R2_H, 530 R3, R3_H, 531 R4, R4_H, 532 R5, R5_H, 533 R6, R6_H, 534 R7, R7_H, 535 R10, R10_H, 536 R11, R11_H, 537 R12, R12_H, // rmethod 538 R13, R13_H, 539 R14, R14_H, 540 R15, R15_H, 541 R16, R16_H, 542 R17, R17_H, 543 R18, R18_H, 544 R19, R19_H, 545 R20, R20_H, 546 R21, R21_H, 547 R22, R22_H, 548 R23, R23_H, 549 R24, R24_H, 550 R25, R25_H, 551 R26, R26_H, 552 /* R27, R27_H, */ // heapbase 553 /* R28, R28_H, */ // thread 554 R29, R29_H, // fp 555 /* R30, R30_H, */ // lr 556 /* R31, R31_H */ // sp 557 ); 558 559 reg_class_dynamic no_special_reg(no_special_reg_no_fp, no_special_reg_with_fp, %{ PreserveFramePointer %}); 560 561 // Class for 64 bit register r0 562 reg_class r0_reg( 563 R0, R0_H 564 ); 565 566 // Class for 64 bit register r1 567 reg_class r1_reg( 568 R1, R1_H 569 ); 570 571 // Class for 64 bit register r2 572 reg_class r2_reg( 573 R2, R2_H 574 ); 575 576 // Class for 64 bit register r3 577 reg_class r3_reg( 578 R3, R3_H 579 ); 580 581 // Class for 64 bit register r4 582 reg_class r4_reg( 583 R4, R4_H 584 ); 585 586 // Class for 64 bit register r5 587 reg_class r5_reg( 588 R5, R5_H 589 ); 590 591 // Class for 64 bit register r10 592 reg_class r10_reg( 593 R10, R10_H 594 ); 595 596 // Class for 64 bit register r11 597 reg_class r11_reg( 598 R11, R11_H 599 ); 600 601 // Class for method register 602 reg_class method_reg( 603 R12, R12_H 604 ); 605 606 // Class for heapbase register 607 reg_class heapbase_reg( 608 R27, R27_H 609 ); 610 611 // Class for thread register 612 reg_class thread_reg( 613 R28, R28_H 614 ); 615 616 // Class for frame pointer register 617 reg_class fp_reg( 618 R29, R29_H 619 ); 620 621 // Class for link register 622 reg_class lr_reg( 623 R30, R30_H 624 ); 625 626 // Class for long sp register 627 reg_class sp_reg( 628 R31, R31_H 629 ); 630 631 // Class for all pointer registers 632 reg_class ptr_reg( 633 R0, R0_H, 634 R1, R1_H, 635 R2, R2_H, 636 R3, R3_H, 637 R4, R4_H, 638 R5, R5_H, 639 R6, R6_H, 640 R7, R7_H, 641 R10, R10_H, 642 R11, R11_H, 643 R12, R12_H, 644 R13, R13_H, 645 R14, R14_H, 646 R15, R15_H, 647 R16, R16_H, 648 R17, R17_H, 649 R18, R18_H, 650 R19, R19_H, 651 R20, R20_H, 652 R21, R21_H, 653 R22, R22_H, 654 R23, R23_H, 655 R24, R24_H, 656 R25, R25_H, 657 R26, R26_H, 658 R27, R27_H, 659 R28, R28_H, 660 R29, R29_H, 661 R30, R30_H, 662 R31, R31_H 663 ); 664 665 // Class for all non_special pointer registers 666 reg_class no_special_ptr_reg( 667 R0, R0_H, 668 R1, R1_H, 669 R2, R2_H, 670 R3, R3_H, 671 R4, R4_H, 672 R5, R5_H, 673 R6, R6_H, 674 R7, R7_H, 675 R10, R10_H, 676 R11, R11_H, 677 R12, R12_H, 678 R13, R13_H, 679 R14, R14_H, 680 R15, R15_H, 681 R16, R16_H, 682 R17, R17_H, 683 R18, R18_H, 684 R19, R19_H, 685 R20, R20_H, 686 R21, R21_H, 687 R22, R22_H, 688 R23, R23_H, 689 R24, R24_H, 690 R25, R25_H, 691 R26, R26_H, 692 /* R27, R27_H, */ // heapbase 693 /* R28, R28_H, */ // thread 694 /* R29, R29_H, */ // fp 695 /* R30, R30_H, */ // lr 696 /* R31, R31_H */ // sp 697 ); 698 699 // Class for all float registers 700 reg_class float_reg( 701 V0, 702 V1, 703 V2, 704 V3, 705 V4, 706 V5, 707 V6, 708 V7, 709 V8, 710 V9, 711 V10, 712 V11, 713 V12, 714 V13, 715 V14, 716 V15, 717 V16, 718 V17, 719 V18, 720 V19, 721 V20, 722 V21, 723 V22, 724 V23, 725 V24, 726 V25, 727 V26, 728 V27, 729 V28, 730 V29, 731 V30, 732 V31 733 ); 734 735 // Double precision float registers have virtual `high halves' that 736 // are needed by the allocator. 737 // Class for all double registers 738 reg_class double_reg( 739 V0, V0_H, 740 V1, V1_H, 741 V2, V2_H, 742 V3, V3_H, 743 V4, V4_H, 744 V5, V5_H, 745 V6, V6_H, 746 V7, V7_H, 747 V8, V8_H, 748 V9, V9_H, 749 V10, V10_H, 750 V11, V11_H, 751 V12, V12_H, 752 V13, V13_H, 753 V14, V14_H, 754 V15, V15_H, 755 V16, V16_H, 756 V17, V17_H, 757 V18, V18_H, 758 V19, V19_H, 759 V20, V20_H, 760 V21, V21_H, 761 V22, V22_H, 762 V23, V23_H, 763 V24, V24_H, 764 V25, V25_H, 765 V26, V26_H, 766 V27, V27_H, 767 V28, V28_H, 768 V29, V29_H, 769 V30, V30_H, 770 V31, V31_H 771 ); 772 773 // Class for 128 bit register v0 774 reg_class v0_reg( 775 V0, V0_H 776 ); 777 778 // Class for 128 bit register v1 779 reg_class v1_reg( 780 V1, V1_H 781 ); 782 783 // Class for 128 bit register v2 784 reg_class v2_reg( 785 V2, V2_H 786 ); 787 788 // Class for 128 bit register v3 789 reg_class v3_reg( 790 V3, V3_H 791 ); 792 793 // Singleton class for condition codes 794 reg_class int_flags(RFLAGS); 795 796 %} 797 798 //----------DEFINITION BLOCK--------------------------------------------------- 799 // Define name --> value mappings to inform the ADLC of an integer valued name 800 // Current support includes integer values in the range [0, 0x7FFFFFFF] 801 // Format: 802 // int_def <name> ( <int_value>, <expression>); 803 // Generated Code in ad_<arch>.hpp 804 // #define <name> (<expression>) 805 // // value == <int_value> 806 // Generated code in ad_<arch>.cpp adlc_verification() 807 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 808 // 809 810 // we follow the ppc-aix port in using a simple cost model which ranks 811 // register operations as cheap, memory ops as more expensive and 812 // branches as most expensive. the first two have a low as well as a 813 // normal cost. huge cost appears to be a way of saying don't do 814 // something 815 816 definitions %{ 817 // The default cost (of a register move instruction). 818 int_def INSN_COST ( 100, 100); 819 int_def BRANCH_COST ( 200, 2 * INSN_COST); 820 int_def CALL_COST ( 200, 2 * INSN_COST); 821 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 822 %} 823 824 825 //----------SOURCE BLOCK------------------------------------------------------- 826 // This is a block of C++ code which provides values, functions, and 827 // definitions necessary in the rest of the architecture description 828 829 source_hpp %{ 830 831 #include "memory/cardTableModRefBS.hpp" 832 833 class CallStubImpl { 834 835 //-------------------------------------------------------------- 836 //---< Used for optimization in Compile::shorten_branches >--- 837 //-------------------------------------------------------------- 838 839 public: 840 // Size of call trampoline stub. 841 static uint size_call_trampoline() { 842 return 0; // no call trampolines on this platform 843 } 844 845 // number of relocations needed by a call trampoline stub 846 static uint reloc_call_trampoline() { 847 return 0; // no call trampolines on this platform 848 } 849 }; 850 851 class HandlerImpl { 852 853 public: 854 855 static int emit_exception_handler(CodeBuffer &cbuf); 856 static int emit_deopt_handler(CodeBuffer& cbuf); 857 858 static uint size_exception_handler() { 859 return MacroAssembler::far_branch_size(); 860 } 861 862 static uint size_deopt_handler() { 863 // count one adr and one far branch instruction 864 return 4 * NativeInstruction::instruction_size; 865 } 866 }; 867 868 // graph traversal helpers 869 MemBarNode *has_parent_membar(const Node *n, 870 ProjNode *&ctl, ProjNode *&mem); 871 MemBarNode *has_child_membar(const MemBarNode *n, 872 ProjNode *&ctl, ProjNode *&mem); 873 874 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 875 bool unnecessary_acquire(const Node *barrier); 876 bool needs_acquiring_load(const Node *load); 877 878 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 879 bool unnecessary_release(const Node *barrier); 880 bool unnecessary_volatile(const Node *barrier); 881 bool needs_releasing_store(const Node *store); 882 883 // Use barrier instructions for unsafe volatile gets rather than 884 // trying to identify an exact signature for them 885 const bool UseBarriersForUnsafeVolatileGet = false; 886 %} 887 888 source %{ 889 890 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 891 // use to implement volatile reads and writes. For a volatile read 892 // we simply need 893 // 894 // ldar<x> 895 // 896 // and for a volatile write we need 897 // 898 // stlr<x> 899 // 900 // Alternatively, we can implement them by pairing a normal 901 // load/store with a memory barrier. For a volatile read we need 902 // 903 // ldr<x> 904 // dmb ishld 905 // 906 // for a volatile write 907 // 908 // dmb ish 909 // str<x> 910 // dmb ish 911 // 912 // In order to generate the desired instruction sequence we need to 913 // be able to identify specific 'signature' ideal graph node 914 // sequences which i) occur as a translation of a volatile reads or 915 // writes and ii) do not occur through any other translation or 916 // graph transformation. We can then provide alternative aldc 917 // matching rules which translate these node sequences to the 918 // desired machine code sequences. Selection of the alternative 919 // rules can be implemented by predicates which identify the 920 // relevant node sequences. 921 // 922 // The ideal graph generator translates a volatile read to the node 923 // sequence 924 // 925 // LoadX[mo_acquire] 926 // MemBarAcquire 927 // 928 // As a special case when using the compressed oops optimization we 929 // may also see this variant 930 // 931 // LoadN[mo_acquire] 932 // DecodeN 933 // MemBarAcquire 934 // 935 // A volatile write is translated to the node sequence 936 // 937 // MemBarRelease 938 // StoreX[mo_release] 939 // MemBarVolatile 940 // 941 // n.b. the above node patterns are generated with a strict 942 // 'signature' configuration of input and output dependencies (see 943 // the predicates below for exact details). The two signatures are 944 // unique to translated volatile reads/stores -- they will not 945 // appear as a result of any other bytecode translation or inlining 946 // nor as a consequence of optimizing transforms. 947 // 948 // We also want to catch inlined unsafe volatile gets and puts and 949 // be able to implement them using either ldar<x>/stlr<x> or some 950 // combination of ldr<x>/stlr<x> and dmb instructions. 951 // 952 // Inlined unsafe volatiles puts manifest as a minor variant of the 953 // normal volatile put node sequence containing an extra cpuorder 954 // membar 955 // 956 // MemBarRelease 957 // MemBarCPUOrder 958 // StoreX[mo_release] 959 // MemBarVolatile 960 // 961 // n.b. as an aside, the cpuorder membar is not itself subject to 962 // matching and translation by adlc rules. However, the rule 963 // predicates need to detect its presence in order to correctly 964 // select the desired adlc rules. 965 // 966 // Inlined unsafe volatiles gets manifest as a somewhat different 967 // node sequence to a normal volatile get 968 // 969 // MemBarCPUOrder 970 // || \\ 971 // MemBarAcquire LoadX[mo_acquire] 972 // || 973 // MemBarCPUOrder 974 // 975 // In this case the acquire membar does not directly depend on the 976 // load. However, we can be sure that the load is generated from an 977 // inlined unsafe volatile get if we see it dependent on this unique 978 // sequence of membar nodes. Similarly, given an acquire membar we 979 // can know that it was added because of an inlined unsafe volatile 980 // get if it is fed and feeds a cpuorder membar and if its feed 981 // membar also feeds an acquiring load. 982 // 983 // So, where we can identify these volatile read and write 984 // signatures we can choose to plant either of the above two code 985 // sequences. For a volatile read we can simply plant a normal 986 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 987 // also choose to inhibit translation of the MemBarAcquire and 988 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 989 // 990 // When we recognise a volatile store signature we can choose to 991 // plant at a dmb ish as a translation for the MemBarRelease, a 992 // normal str<x> and then a dmb ish for the MemBarVolatile. 993 // Alternatively, we can inhibit translation of the MemBarRelease 994 // and MemBarVolatile and instead plant a simple stlr<x> 995 // instruction. 996 // 997 // Of course, the above only applies when we see these signature 998 // configurations. We still want to plant dmb instructions in any 999 // other cases where we may see a MemBarAcquire, MemBarRelease or 1000 // MemBarVolatile. For example, at the end of a constructor which 1001 // writes final/volatile fields we will see a MemBarRelease 1002 // instruction and this needs a 'dmb ish' lest we risk the 1003 // constructed object being visible without making the 1004 // final/volatile field writes visible. 1005 // 1006 // n.b. the translation rules below which rely on detection of the 1007 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1008 // If we see anything other than the signature configurations we 1009 // always just translate the loads and stors to ldr<x> and str<x> 1010 // and translate acquire, release and volatile membars to the 1011 // relevant dmb instructions. 1012 // 1013 // n.b.b as a case in point for the above comment, the current 1014 // predicates don't detect the precise signature for certain types 1015 // of volatile object stores (where the heap_base input type is not 1016 // known at compile-time to be non-NULL). In those cases the 1017 // MemBarRelease and MemBarVolatile bracket an if-then-else sequence 1018 // with a store in each branch (we need a different store depending 1019 // on whether heap_base is actually NULL). In such a case we will 1020 // just plant a dmb both before and after the branch/merge. The 1021 // predicate could (and probably should) be fixed later to also 1022 // detect this case. 1023 1024 // graph traversal helpers 1025 1026 // if node n is linked to a parent MemBarNode by an intervening 1027 // Control or Memory ProjNode return the MemBarNode otherwise return 1028 // NULL. 1029 // 1030 // n may only be a Load or a MemBar. 1031 // 1032 // The ProjNode* references c and m are used to return the relevant 1033 // nodes. 1034 1035 MemBarNode *has_parent_membar(const Node *n, ProjNode *&c, ProjNode *&m) 1036 { 1037 Node *ctl = NULL; 1038 Node *mem = NULL; 1039 Node *membar = NULL; 1040 1041 if (n->is_Load()) { 1042 ctl = n->lookup(LoadNode::Control); 1043 mem = n->lookup(LoadNode::Memory); 1044 } else if (n->is_MemBar()) { 1045 ctl = n->lookup(TypeFunc::Control); 1046 mem = n->lookup(TypeFunc::Memory); 1047 } else { 1048 return NULL; 1049 } 1050 1051 if (!ctl || !mem || !ctl->is_Proj() || !mem->is_Proj()) 1052 return NULL; 1053 1054 c = ctl->as_Proj(); 1055 1056 membar = ctl->lookup(0); 1057 1058 if (!membar || !membar->is_MemBar()) 1059 return NULL; 1060 1061 m = mem->as_Proj(); 1062 1063 if (mem->lookup(0) != membar) 1064 return NULL; 1065 1066 return membar->as_MemBar(); 1067 } 1068 1069 // if n is linked to a child MemBarNode by intervening Control and 1070 // Memory ProjNodes return the MemBarNode otherwise return NULL. 1071 // 1072 // The ProjNode** arguments c and m are used to return pointers to 1073 // the relevant nodes. A null argument means don't don't return a 1074 // value. 1075 1076 MemBarNode *has_child_membar(const MemBarNode *n, ProjNode *&c, ProjNode *&m) 1077 { 1078 ProjNode *ctl = n->proj_out(TypeFunc::Control); 1079 ProjNode *mem = n->proj_out(TypeFunc::Memory); 1080 1081 // MemBar needs to have both a Ctl and Mem projection 1082 if (! ctl || ! mem) 1083 return NULL; 1084 1085 c = ctl; 1086 m = mem; 1087 1088 MemBarNode *child = NULL; 1089 Node *x; 1090 1091 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1092 x = ctl->fast_out(i); 1093 // if we see a membar we keep hold of it. we may also see a new 1094 // arena copy of the original but it will appear later 1095 if (x->is_MemBar()) { 1096 child = x->as_MemBar(); 1097 break; 1098 } 1099 } 1100 1101 if (child == NULL) 1102 return NULL; 1103 1104 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1105 x = mem->fast_out(i); 1106 // if we see a membar we keep hold of it. we may also see a new 1107 // arena copy of the original but it will appear later 1108 if (x == child) { 1109 return child; 1110 } 1111 } 1112 return NULL; 1113 } 1114 1115 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1116 1117 bool unnecessary_acquire(const Node *barrier) { 1118 // assert barrier->is_MemBar(); 1119 if (UseBarriersForVolatile) 1120 // we need to plant a dmb 1121 return false; 1122 1123 // a volatile read derived from bytecode (or also from an inlined 1124 // SHA field read via LibraryCallKit::load_field_from_object) 1125 // manifests as a LoadX[mo_acquire] followed by an acquire membar 1126 // with a bogus read dependency on it's preceding load. so in those 1127 // cases we will find the load node at the PARMS offset of the 1128 // acquire membar. n.b. there may be an intervening DecodeN node. 1129 // 1130 // a volatile load derived from an inlined unsafe field access 1131 // manifests as a cpuorder membar with Ctl and Mem projections 1132 // feeding both an acquire membar and a LoadX[mo_acquire]. The 1133 // acquire then feeds another cpuorder membar via Ctl and Mem 1134 // projections. The load has no output dependency on these trailing 1135 // membars because subsequent nodes inserted into the graph take 1136 // their control feed from the final membar cpuorder meaning they 1137 // are all ordered after the load. 1138 1139 Node *x = barrier->lookup(TypeFunc::Parms); 1140 if (x) { 1141 // we are starting from an acquire and it has a fake dependency 1142 // 1143 // need to check for 1144 // 1145 // LoadX[mo_acquire] 1146 // { |1 } 1147 // {DecodeN} 1148 // |Parms 1149 // MemBarAcquire* 1150 // 1151 // where * tags node we were passed 1152 // and |k means input k 1153 if (x->is_DecodeNarrowPtr()) 1154 x = x->in(1); 1155 1156 return (x->is_Load() && x->as_Load()->is_acquire()); 1157 } 1158 1159 // only continue if we want to try to match unsafe volatile gets 1160 if (UseBarriersForUnsafeVolatileGet) 1161 return false; 1162 1163 // need to check for 1164 // 1165 // MemBarCPUOrder 1166 // || \\ 1167 // MemBarAcquire* LoadX[mo_acquire] 1168 // || 1169 // MemBarCPUOrder 1170 // 1171 // where * tags node we were passed 1172 // and || or \\ are Ctl+Mem feeds via intermediate Proj Nodes 1173 1174 // check for a parent MemBarCPUOrder 1175 ProjNode *ctl; 1176 ProjNode *mem; 1177 MemBarNode *parent = has_parent_membar(barrier, ctl, mem); 1178 if (!parent || parent->Opcode() != Op_MemBarCPUOrder) 1179 return false; 1180 // ensure the proj nodes both feed a LoadX[mo_acquire] 1181 LoadNode *ld = NULL; 1182 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1183 x = ctl->fast_out(i); 1184 // if we see a load we keep hold of it and stop searching 1185 if (x->is_Load()) { 1186 ld = x->as_Load(); 1187 break; 1188 } 1189 } 1190 // it must be an acquiring load 1191 if (! ld || ! ld->is_acquire()) 1192 return false; 1193 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1194 x = mem->fast_out(i); 1195 // if we see the same load we drop it and stop searching 1196 if (x == ld) { 1197 ld = NULL; 1198 break; 1199 } 1200 } 1201 // we must have dropped the load 1202 if (ld) 1203 return false; 1204 // check for a child cpuorder membar 1205 MemBarNode *child = has_child_membar(barrier->as_MemBar(), ctl, mem); 1206 if (!child || child->Opcode() != Op_MemBarCPUOrder) 1207 return false; 1208 1209 return true; 1210 } 1211 1212 bool needs_acquiring_load(const Node *n) 1213 { 1214 // assert n->is_Load(); 1215 if (UseBarriersForVolatile) 1216 // we use a normal load and a dmb 1217 return false; 1218 1219 LoadNode *ld = n->as_Load(); 1220 1221 if (!ld->is_acquire()) 1222 return false; 1223 1224 // check if this load is feeding an acquire membar 1225 // 1226 // LoadX[mo_acquire] 1227 // { |1 } 1228 // {DecodeN} 1229 // |Parms 1230 // MemBarAcquire* 1231 // 1232 // where * tags node we were passed 1233 // and |k means input k 1234 1235 Node *start = ld; 1236 Node *mbacq = NULL; 1237 1238 // if we hit a DecodeNarrowPtr we reset the start node and restart 1239 // the search through the outputs 1240 restart: 1241 1242 for (DUIterator_Fast imax, i = start->fast_outs(imax); i < imax; i++) { 1243 Node *x = start->fast_out(i); 1244 if (x->is_MemBar() && x->Opcode() == Op_MemBarAcquire) { 1245 mbacq = x; 1246 } else if (!mbacq && 1247 (x->is_DecodeNarrowPtr() || 1248 (x->is_Mach() && x->Opcode() == Op_DecodeN))) { 1249 start = x; 1250 goto restart; 1251 } 1252 } 1253 1254 if (mbacq) { 1255 return true; 1256 } 1257 1258 // only continue if we want to try to match unsafe volatile gets 1259 if (UseBarriersForUnsafeVolatileGet) 1260 return false; 1261 1262 // check if Ctl and Proj feed comes from a MemBarCPUOrder 1263 // 1264 // MemBarCPUOrder 1265 // || \\ 1266 // MemBarAcquire* LoadX[mo_acquire] 1267 // || 1268 // MemBarCPUOrder 1269 1270 MemBarNode *membar; 1271 ProjNode *ctl; 1272 ProjNode *mem; 1273 1274 membar = has_parent_membar(ld, ctl, mem); 1275 1276 if (!membar || !membar->Opcode() == Op_MemBarCPUOrder) 1277 return false; 1278 1279 // ensure that there is a CPUOrder->Acquire->CPUOrder membar chain 1280 1281 membar = has_child_membar(membar, ctl, mem); 1282 1283 if (!membar || !membar->Opcode() == Op_MemBarAcquire) 1284 return false; 1285 1286 membar = has_child_membar(membar, ctl, mem); 1287 1288 if (!membar || !membar->Opcode() == Op_MemBarCPUOrder) 1289 return false; 1290 1291 return true; 1292 } 1293 1294 bool unnecessary_release(const Node *n) { 1295 // assert n->is_MemBar(); 1296 if (UseBarriersForVolatile) 1297 // we need to plant a dmb 1298 return false; 1299 1300 // ok, so we can omit this release barrier if it has been inserted 1301 // as part of a volatile store sequence 1302 // 1303 // MemBarRelease 1304 // { || } 1305 // {MemBarCPUOrder} -- optional 1306 // || \\ 1307 // || StoreX[mo_release] 1308 // | \ / 1309 // | MergeMem 1310 // | / 1311 // MemBarVolatile 1312 // 1313 // where 1314 // || and \\ represent Ctl and Mem feeds via Proj nodes 1315 // | \ and / indicate further routing of the Ctl and Mem feeds 1316 // 1317 // so we need to check that 1318 // 1319 // ia) the release membar (or its dependent cpuorder membar) feeds 1320 // control to a store node (via a Control project node) 1321 // 1322 // ii) the store is ordered release 1323 // 1324 // iii) the release membar (or its dependent cpuorder membar) feeds 1325 // control to a volatile membar (via the same Control project node) 1326 // 1327 // iv) the release membar feeds memory to a merge mem and to the 1328 // same store (both via a single Memory proj node) 1329 // 1330 // v) the store outputs to the merge mem 1331 // 1332 // vi) the merge mem outputs to the same volatile membar 1333 // 1334 // n.b. if this is an inlined unsafe node then the release membar 1335 // may feed its control and memory links via an intervening cpuorder 1336 // membar. this case can be dealt with when we check the release 1337 // membar projections. if they both feed a single cpuorder membar 1338 // node continue to make the same checks as above but with the 1339 // cpuorder membar substituted for the release membar. if they don't 1340 // both feed a cpuorder membar then the check fails. 1341 // 1342 // n.b.b. for an inlined unsafe store of an object in the case where 1343 // !TypePtr::NULL_PTR->higher_equal(type(heap_base_oop)) we may see 1344 // an embedded if then else where we expect the store. this is 1345 // needed to do the right type of store depending on whether 1346 // heap_base is NULL. We could check for that but for now we can 1347 // just take the hit of on inserting a redundant dmb for this 1348 // redundant volatile membar 1349 1350 MemBarNode *barrier = n->as_MemBar(); 1351 ProjNode *ctl; 1352 ProjNode *mem; 1353 // check for an intervening cpuorder membar 1354 MemBarNode *b = has_child_membar(barrier, ctl, mem); 1355 if (b && b->Opcode() == Op_MemBarCPUOrder) { 1356 // ok, so start form the dependent cpuorder barrier 1357 barrier = b; 1358 } 1359 // check the ctl and mem flow 1360 ctl = barrier->proj_out(TypeFunc::Control); 1361 mem = barrier->proj_out(TypeFunc::Memory); 1362 1363 // the barrier needs to have both a Ctl and Mem projection 1364 if (! ctl || ! mem) 1365 return false; 1366 1367 Node *x = NULL; 1368 Node *mbvol = NULL; 1369 StoreNode * st = NULL; 1370 1371 // For a normal volatile write the Ctl ProjNode should have output 1372 // to a MemBarVolatile and a Store marked as releasing 1373 // 1374 // n.b. for an inlined unsafe store of an object in the case where 1375 // !TypePtr::NULL_PTR->higher_equal(type(heap_base_oop)) we may see 1376 // an embedded if then else where we expect the store. this is 1377 // needed to do the right type of store depending on whether 1378 // heap_base is NULL. We could check for that case too but for now 1379 // we can just take the hit of inserting a dmb and a non-volatile 1380 // store to implement the volatile store 1381 1382 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1383 x = ctl->fast_out(i); 1384 if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) { 1385 if (mbvol) { 1386 return false; 1387 } 1388 mbvol = x; 1389 } else if (x->is_Store()) { 1390 st = x->as_Store(); 1391 if (! st->is_release()) { 1392 return false; 1393 } 1394 } else if (!x->is_Mach()) { 1395 // we may see mach nodes added during matching but nothing else 1396 return false; 1397 } 1398 } 1399 1400 if (!mbvol || !st) 1401 return false; 1402 1403 // the Mem ProjNode should output to a MergeMem and the same Store 1404 Node *mm = NULL; 1405 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1406 x = mem->fast_out(i); 1407 if (!mm && x->is_MergeMem()) { 1408 mm = x; 1409 } else if (x != st && !x->is_Mach()) { 1410 // we may see mach nodes added during matching but nothing else 1411 return false; 1412 } 1413 } 1414 1415 if (!mm) 1416 return false; 1417 1418 // the MergeMem should output to the MemBarVolatile 1419 for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) { 1420 x = mm->fast_out(i); 1421 if (x != mbvol && !x->is_Mach()) { 1422 // we may see mach nodes added during matching but nothing else 1423 return false; 1424 } 1425 } 1426 1427 return true; 1428 } 1429 1430 bool unnecessary_volatile(const Node *n) { 1431 // assert n->is_MemBar(); 1432 if (UseBarriersForVolatile) 1433 // we need to plant a dmb 1434 return false; 1435 1436 // ok, so we can omit this volatile barrier if it has been inserted 1437 // as part of a volatile store sequence 1438 // 1439 // MemBarRelease 1440 // { || } 1441 // {MemBarCPUOrder} -- optional 1442 // || \\ 1443 // || StoreX[mo_release] 1444 // | \ / 1445 // | MergeMem 1446 // | / 1447 // MemBarVolatile 1448 // 1449 // where 1450 // || and \\ represent Ctl and Mem feeds via Proj nodes 1451 // | \ and / indicate further routing of the Ctl and Mem feeds 1452 // 1453 // we need to check that 1454 // 1455 // i) the volatile membar gets its control feed from a release 1456 // membar (or its dependent cpuorder membar) via a Control project 1457 // node 1458 // 1459 // ii) the release membar (or its dependent cpuorder membar) also 1460 // feeds control to a store node via the same proj node 1461 // 1462 // iii) the store is ordered release 1463 // 1464 // iv) the release membar (or its dependent cpuorder membar) feeds 1465 // memory to a merge mem and to the same store (both via a single 1466 // Memory proj node) 1467 // 1468 // v) the store outputs to the merge mem 1469 // 1470 // vi) the merge mem outputs to the volatile membar 1471 // 1472 // n.b. for an inlined unsafe store of an object in the case where 1473 // !TypePtr::NULL_PTR->higher_equal(type(heap_base_oop)) we may see 1474 // an embedded if then else where we expect the store. this is 1475 // needed to do the right type of store depending on whether 1476 // heap_base is NULL. We could check for that but for now we can 1477 // just take the hit of on inserting a redundant dmb for this 1478 // redundant volatile membar 1479 1480 MemBarNode *mbvol = n->as_MemBar(); 1481 Node *x = n->lookup(TypeFunc::Control); 1482 1483 if (! x || !x->is_Proj()) 1484 return false; 1485 1486 ProjNode *proj = x->as_Proj(); 1487 1488 x = proj->lookup(0); 1489 1490 if (!x || !x->is_MemBar()) 1491 return false; 1492 1493 MemBarNode *barrier = x->as_MemBar(); 1494 1495 // if the barrier is a release membar we have what we want. if it is 1496 // a cpuorder membar then we need to ensure that it is fed by a 1497 // release membar in which case we proceed to check the graph below 1498 // this cpuorder membar as the feed 1499 1500 if (x->Opcode() != Op_MemBarRelease) { 1501 if (x->Opcode() != Op_MemBarCPUOrder) 1502 return false; 1503 ProjNode *ctl; 1504 ProjNode *mem; 1505 MemBarNode *b = has_parent_membar(x, ctl, mem); 1506 if (!b || !b->Opcode() == Op_MemBarRelease) 1507 return false; 1508 } 1509 1510 ProjNode *ctl = barrier->proj_out(TypeFunc::Control); 1511 ProjNode *mem = barrier->proj_out(TypeFunc::Memory); 1512 1513 // barrier needs to have both a Ctl and Mem projection 1514 // and we need to have reached it via the Ctl projection 1515 if (! ctl || ! mem || ctl != proj) 1516 return false; 1517 1518 StoreNode * st = NULL; 1519 1520 // The Ctl ProjNode should have output to a MemBarVolatile and 1521 // a Store marked as releasing 1522 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1523 x = ctl->fast_out(i); 1524 if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) { 1525 if (x != mbvol) { 1526 return false; 1527 } 1528 } else if (x->is_Store()) { 1529 st = x->as_Store(); 1530 if (! st->is_release()) { 1531 return false; 1532 } 1533 } else if (!x->is_Mach()){ 1534 // we may see mach nodes added during matching but nothing else 1535 return false; 1536 } 1537 } 1538 1539 if (!st) 1540 return false; 1541 1542 // the Mem ProjNode should output to a MergeMem and the same Store 1543 Node *mm = NULL; 1544 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1545 x = mem->fast_out(i); 1546 if (!mm && x->is_MergeMem()) { 1547 mm = x; 1548 } else if (x != st && !x->is_Mach()) { 1549 // we may see mach nodes added during matching but nothing else 1550 return false; 1551 } 1552 } 1553 1554 if (!mm) 1555 return false; 1556 1557 // the MergeMem should output to the MemBarVolatile 1558 for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) { 1559 x = mm->fast_out(i); 1560 if (x != mbvol && !x->is_Mach()) { 1561 // we may see mach nodes added during matching but nothing else 1562 return false; 1563 } 1564 } 1565 1566 return true; 1567 } 1568 1569 1570 1571 bool needs_releasing_store(const Node *n) 1572 { 1573 // assert n->is_Store(); 1574 if (UseBarriersForVolatile) 1575 // we use a normal store and dmb combination 1576 return false; 1577 1578 StoreNode *st = n->as_Store(); 1579 1580 if (!st->is_release()) 1581 return false; 1582 1583 // check if this store is bracketed by a release (or its dependent 1584 // cpuorder membar) and a volatile membar 1585 // 1586 // MemBarRelease 1587 // { || } 1588 // {MemBarCPUOrder} -- optional 1589 // || \\ 1590 // || StoreX[mo_release] 1591 // | \ / 1592 // | MergeMem 1593 // | / 1594 // MemBarVolatile 1595 // 1596 // where 1597 // || and \\ represent Ctl and Mem feeds via Proj nodes 1598 // | \ and / indicate further routing of the Ctl and Mem feeds 1599 // 1600 1601 1602 Node *x = st->lookup(TypeFunc::Control); 1603 1604 if (! x || !x->is_Proj()) 1605 return false; 1606 1607 ProjNode *proj = x->as_Proj(); 1608 1609 x = proj->lookup(0); 1610 1611 if (!x || !x->is_MemBar()) 1612 return false; 1613 1614 MemBarNode *barrier = x->as_MemBar(); 1615 1616 // if the barrier is a release membar we have what we want. if it is 1617 // a cpuorder membar then we need to ensure that it is fed by a 1618 // release membar in which case we proceed to check the graph below 1619 // this cpuorder membar as the feed 1620 1621 if (x->Opcode() != Op_MemBarRelease) { 1622 if (x->Opcode() != Op_MemBarCPUOrder) 1623 return false; 1624 Node *ctl = x->lookup(TypeFunc::Control); 1625 Node *mem = x->lookup(TypeFunc::Memory); 1626 if (!ctl || !ctl->is_Proj() || !mem || !mem->is_Proj()) 1627 return false; 1628 x = ctl->lookup(0); 1629 if (!x || !x->is_MemBar() || !x->Opcode() == Op_MemBarRelease) 1630 return false; 1631 Node *y = mem->lookup(0); 1632 if (!y || y != x) 1633 return false; 1634 } 1635 1636 ProjNode *ctl = barrier->proj_out(TypeFunc::Control); 1637 ProjNode *mem = barrier->proj_out(TypeFunc::Memory); 1638 1639 // MemBarRelease needs to have both a Ctl and Mem projection 1640 // and we need to have reached it via the Ctl projection 1641 if (! ctl || ! mem || ctl != proj) 1642 return false; 1643 1644 MemBarNode *mbvol = NULL; 1645 1646 // The Ctl ProjNode should have output to a MemBarVolatile and 1647 // a Store marked as releasing 1648 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1649 x = ctl->fast_out(i); 1650 if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) { 1651 mbvol = x->as_MemBar(); 1652 } else if (x->is_Store()) { 1653 if (x != st) { 1654 return false; 1655 } 1656 } else if (!x->is_Mach()){ 1657 return false; 1658 } 1659 } 1660 1661 if (!mbvol) 1662 return false; 1663 1664 // the Mem ProjNode should output to a MergeMem and the same Store 1665 Node *mm = NULL; 1666 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1667 x = mem->fast_out(i); 1668 if (!mm && x->is_MergeMem()) { 1669 mm = x; 1670 } else if (x != st && !x->is_Mach()) { 1671 return false; 1672 } 1673 } 1674 1675 if (!mm) 1676 return false; 1677 1678 // the MergeMem should output to the MemBarVolatile 1679 for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) { 1680 x = mm->fast_out(i); 1681 if (x != mbvol && !x->is_Mach()) { 1682 return false; 1683 } 1684 } 1685 1686 return true; 1687 } 1688 1689 1690 1691 #define __ _masm. 1692 1693 // advance declarations for helper functions to convert register 1694 // indices to register objects 1695 1696 // the ad file has to provide implementations of certain methods 1697 // expected by the generic code 1698 // 1699 // REQUIRED FUNCTIONALITY 1700 1701 //============================================================================= 1702 1703 // !!!!! Special hack to get all types of calls to specify the byte offset 1704 // from the start of the call to the point where the return address 1705 // will point. 1706 1707 int MachCallStaticJavaNode::ret_addr_offset() 1708 { 1709 // call should be a simple bl 1710 int off = 4; 1711 return off; 1712 } 1713 1714 int MachCallDynamicJavaNode::ret_addr_offset() 1715 { 1716 return 16; // movz, movk, movk, bl 1717 } 1718 1719 int MachCallRuntimeNode::ret_addr_offset() { 1720 // for generated stubs the call will be 1721 // far_call(addr) 1722 // for real runtime callouts it will be six instructions 1723 // see aarch64_enc_java_to_runtime 1724 // adr(rscratch2, retaddr) 1725 // lea(rscratch1, RuntimeAddress(addr) 1726 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1727 // blrt rscratch1 1728 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1729 if (cb) { 1730 return MacroAssembler::far_branch_size(); 1731 } else { 1732 return 6 * NativeInstruction::instruction_size; 1733 } 1734 } 1735 1736 // Indicate if the safepoint node needs the polling page as an input 1737 1738 // the shared code plants the oop data at the start of the generated 1739 // code for the safepoint node and that needs ot be at the load 1740 // instruction itself. so we cannot plant a mov of the safepoint poll 1741 // address followed by a load. setting this to true means the mov is 1742 // scheduled as a prior instruction. that's better for scheduling 1743 // anyway. 1744 1745 bool SafePointNode::needs_polling_address_input() 1746 { 1747 return true; 1748 } 1749 1750 //============================================================================= 1751 1752 #ifndef PRODUCT 1753 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1754 st->print("BREAKPOINT"); 1755 } 1756 #endif 1757 1758 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1759 MacroAssembler _masm(&cbuf); 1760 __ brk(0); 1761 } 1762 1763 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1764 return MachNode::size(ra_); 1765 } 1766 1767 //============================================================================= 1768 1769 #ifndef PRODUCT 1770 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1771 st->print("nop \t# %d bytes pad for loops and calls", _count); 1772 } 1773 #endif 1774 1775 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1776 MacroAssembler _masm(&cbuf); 1777 for (int i = 0; i < _count; i++) { 1778 __ nop(); 1779 } 1780 } 1781 1782 uint MachNopNode::size(PhaseRegAlloc*) const { 1783 return _count * NativeInstruction::instruction_size; 1784 } 1785 1786 //============================================================================= 1787 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1788 1789 int Compile::ConstantTable::calculate_table_base_offset() const { 1790 return 0; // absolute addressing, no offset 1791 } 1792 1793 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1794 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1795 ShouldNotReachHere(); 1796 } 1797 1798 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1799 // Empty encoding 1800 } 1801 1802 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1803 return 0; 1804 } 1805 1806 #ifndef PRODUCT 1807 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1808 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1809 } 1810 #endif 1811 1812 #ifndef PRODUCT 1813 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1814 Compile* C = ra_->C; 1815 1816 int framesize = C->frame_slots() << LogBytesPerInt; 1817 1818 if (C->need_stack_bang(framesize)) 1819 st->print("# stack bang size=%d\n\t", framesize); 1820 1821 if (framesize < ((1 << 9) + 2 * wordSize)) { 1822 st->print("sub sp, sp, #%d\n\t", framesize); 1823 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1824 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1825 } else { 1826 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1827 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1828 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1829 st->print("sub sp, sp, rscratch1"); 1830 } 1831 } 1832 #endif 1833 1834 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1835 Compile* C = ra_->C; 1836 MacroAssembler _masm(&cbuf); 1837 1838 // n.b. frame size includes space for return pc and rfp 1839 const long framesize = C->frame_size_in_bytes(); 1840 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1841 1842 // insert a nop at the start of the prolog so we can patch in a 1843 // branch if we need to invalidate the method later 1844 __ nop(); 1845 1846 int bangsize = C->bang_size_in_bytes(); 1847 if (C->need_stack_bang(bangsize) && UseStackBanging) 1848 __ generate_stack_overflow_check(bangsize); 1849 1850 __ build_frame(framesize); 1851 1852 if (NotifySimulator) { 1853 __ notify(Assembler::method_entry); 1854 } 1855 1856 if (VerifyStackAtCalls) { 1857 Unimplemented(); 1858 } 1859 1860 C->set_frame_complete(cbuf.insts_size()); 1861 1862 if (C->has_mach_constant_base_node()) { 1863 // NOTE: We set the table base offset here because users might be 1864 // emitted before MachConstantBaseNode. 1865 Compile::ConstantTable& constant_table = C->constant_table(); 1866 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1867 } 1868 } 1869 1870 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1871 { 1872 return MachNode::size(ra_); // too many variables; just compute it 1873 // the hard way 1874 } 1875 1876 int MachPrologNode::reloc() const 1877 { 1878 return 0; 1879 } 1880 1881 //============================================================================= 1882 1883 #ifndef PRODUCT 1884 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1885 Compile* C = ra_->C; 1886 int framesize = C->frame_slots() << LogBytesPerInt; 1887 1888 st->print("# pop frame %d\n\t",framesize); 1889 1890 if (framesize == 0) { 1891 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1892 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1893 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1894 st->print("add sp, sp, #%d\n\t", framesize); 1895 } else { 1896 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1897 st->print("add sp, sp, rscratch1\n\t"); 1898 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1899 } 1900 1901 if (do_polling() && C->is_method_compilation()) { 1902 st->print("# touch polling page\n\t"); 1903 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1904 st->print("ldr zr, [rscratch1]"); 1905 } 1906 } 1907 #endif 1908 1909 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1910 Compile* C = ra_->C; 1911 MacroAssembler _masm(&cbuf); 1912 int framesize = C->frame_slots() << LogBytesPerInt; 1913 1914 __ remove_frame(framesize); 1915 1916 if (NotifySimulator) { 1917 __ notify(Assembler::method_reentry); 1918 } 1919 1920 if (do_polling() && C->is_method_compilation()) { 1921 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1922 } 1923 } 1924 1925 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1926 // Variable size. Determine dynamically. 1927 return MachNode::size(ra_); 1928 } 1929 1930 int MachEpilogNode::reloc() const { 1931 // Return number of relocatable values contained in this instruction. 1932 return 1; // 1 for polling page. 1933 } 1934 1935 const Pipeline * MachEpilogNode::pipeline() const { 1936 return MachNode::pipeline_class(); 1937 } 1938 1939 // This method seems to be obsolete. It is declared in machnode.hpp 1940 // and defined in all *.ad files, but it is never called. Should we 1941 // get rid of it? 1942 int MachEpilogNode::safepoint_offset() const { 1943 assert(do_polling(), "no return for this epilog node"); 1944 return 4; 1945 } 1946 1947 //============================================================================= 1948 1949 // Figure out which register class each belongs in: rc_int, rc_float or 1950 // rc_stack. 1951 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1952 1953 static enum RC rc_class(OptoReg::Name reg) { 1954 1955 if (reg == OptoReg::Bad) { 1956 return rc_bad; 1957 } 1958 1959 // we have 30 int registers * 2 halves 1960 // (rscratch1 and rscratch2 are omitted) 1961 1962 if (reg < 60) { 1963 return rc_int; 1964 } 1965 1966 // we have 32 float register * 2 halves 1967 if (reg < 60 + 64) { 1968 return rc_float; 1969 } 1970 1971 // Between float regs & stack is the flags regs. 1972 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1973 1974 return rc_stack; 1975 } 1976 1977 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1978 Compile* C = ra_->C; 1979 1980 // Get registers to move. 1981 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1982 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1983 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1984 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1985 1986 enum RC src_hi_rc = rc_class(src_hi); 1987 enum RC src_lo_rc = rc_class(src_lo); 1988 enum RC dst_hi_rc = rc_class(dst_hi); 1989 enum RC dst_lo_rc = rc_class(dst_lo); 1990 1991 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1992 1993 if (src_hi != OptoReg::Bad) { 1994 assert((src_lo&1)==0 && src_lo+1==src_hi && 1995 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1996 "expected aligned-adjacent pairs"); 1997 } 1998 1999 if (src_lo == dst_lo && src_hi == dst_hi) { 2000 return 0; // Self copy, no move. 2001 } 2002 2003 switch (src_lo_rc) { 2004 case rc_int: 2005 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 2006 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2007 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2008 // 64 bit 2009 if (cbuf) { 2010 MacroAssembler _masm(cbuf); 2011 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 2012 as_Register(Matcher::_regEncode[src_lo])); 2013 } else if (st) { 2014 st->print("mov %s, %s\t# shuffle", 2015 Matcher::regName[dst_lo], 2016 Matcher::regName[src_lo]); 2017 } 2018 } else { 2019 // 32 bit 2020 if (cbuf) { 2021 MacroAssembler _masm(cbuf); 2022 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 2023 as_Register(Matcher::_regEncode[src_lo])); 2024 } else if (st) { 2025 st->print("movw %s, %s\t# shuffle", 2026 Matcher::regName[dst_lo], 2027 Matcher::regName[src_lo]); 2028 } 2029 } 2030 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 2031 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2032 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2033 // 64 bit 2034 if (cbuf) { 2035 MacroAssembler _masm(cbuf); 2036 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2037 as_Register(Matcher::_regEncode[src_lo])); 2038 } else if (st) { 2039 st->print("fmovd %s, %s\t# shuffle", 2040 Matcher::regName[dst_lo], 2041 Matcher::regName[src_lo]); 2042 } 2043 } else { 2044 // 32 bit 2045 if (cbuf) { 2046 MacroAssembler _masm(cbuf); 2047 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2048 as_Register(Matcher::_regEncode[src_lo])); 2049 } else if (st) { 2050 st->print("fmovs %s, %s\t# shuffle", 2051 Matcher::regName[dst_lo], 2052 Matcher::regName[src_lo]); 2053 } 2054 } 2055 } else { // gpr --> stack spill 2056 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2057 int dst_offset = ra_->reg2offset(dst_lo); 2058 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2059 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2060 // 64 bit 2061 if (cbuf) { 2062 MacroAssembler _masm(cbuf); 2063 __ str(as_Register(Matcher::_regEncode[src_lo]), 2064 Address(sp, dst_offset)); 2065 } else if (st) { 2066 st->print("str %s, [sp, #%d]\t# spill", 2067 Matcher::regName[src_lo], 2068 dst_offset); 2069 } 2070 } else { 2071 // 32 bit 2072 if (cbuf) { 2073 MacroAssembler _masm(cbuf); 2074 __ strw(as_Register(Matcher::_regEncode[src_lo]), 2075 Address(sp, dst_offset)); 2076 } else if (st) { 2077 st->print("strw %s, [sp, #%d]\t# spill", 2078 Matcher::regName[src_lo], 2079 dst_offset); 2080 } 2081 } 2082 } 2083 return 4; 2084 case rc_float: 2085 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 2086 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2087 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2088 // 64 bit 2089 if (cbuf) { 2090 MacroAssembler _masm(cbuf); 2091 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 2092 as_FloatRegister(Matcher::_regEncode[src_lo])); 2093 } else if (st) { 2094 st->print("fmovd %s, %s\t# shuffle", 2095 Matcher::regName[dst_lo], 2096 Matcher::regName[src_lo]); 2097 } 2098 } else { 2099 // 32 bit 2100 if (cbuf) { 2101 MacroAssembler _masm(cbuf); 2102 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 2103 as_FloatRegister(Matcher::_regEncode[src_lo])); 2104 } else if (st) { 2105 st->print("fmovs %s, %s\t# shuffle", 2106 Matcher::regName[dst_lo], 2107 Matcher::regName[src_lo]); 2108 } 2109 } 2110 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 2111 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2112 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2113 // 64 bit 2114 if (cbuf) { 2115 MacroAssembler _masm(cbuf); 2116 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2117 as_FloatRegister(Matcher::_regEncode[src_lo])); 2118 } else if (st) { 2119 st->print("fmovd %s, %s\t# shuffle", 2120 Matcher::regName[dst_lo], 2121 Matcher::regName[src_lo]); 2122 } 2123 } else { 2124 // 32 bit 2125 if (cbuf) { 2126 MacroAssembler _masm(cbuf); 2127 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2128 as_FloatRegister(Matcher::_regEncode[src_lo])); 2129 } else if (st) { 2130 st->print("fmovs %s, %s\t# shuffle", 2131 Matcher::regName[dst_lo], 2132 Matcher::regName[src_lo]); 2133 } 2134 } 2135 } else { // fpr --> stack spill 2136 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2137 int dst_offset = ra_->reg2offset(dst_lo); 2138 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2139 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2140 // 64 bit 2141 if (cbuf) { 2142 MacroAssembler _masm(cbuf); 2143 __ strd(as_FloatRegister(Matcher::_regEncode[src_lo]), 2144 Address(sp, dst_offset)); 2145 } else if (st) { 2146 st->print("strd %s, [sp, #%d]\t# spill", 2147 Matcher::regName[src_lo], 2148 dst_offset); 2149 } 2150 } else { 2151 // 32 bit 2152 if (cbuf) { 2153 MacroAssembler _masm(cbuf); 2154 __ strs(as_FloatRegister(Matcher::_regEncode[src_lo]), 2155 Address(sp, dst_offset)); 2156 } else if (st) { 2157 st->print("strs %s, [sp, #%d]\t# spill", 2158 Matcher::regName[src_lo], 2159 dst_offset); 2160 } 2161 } 2162 } 2163 return 4; 2164 case rc_stack: 2165 int src_offset = ra_->reg2offset(src_lo); 2166 if (dst_lo_rc == rc_int) { // stack --> gpr load 2167 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2168 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2169 // 64 bit 2170 if (cbuf) { 2171 MacroAssembler _masm(cbuf); 2172 __ ldr(as_Register(Matcher::_regEncode[dst_lo]), 2173 Address(sp, src_offset)); 2174 } else if (st) { 2175 st->print("ldr %s, [sp, %d]\t# restore", 2176 Matcher::regName[dst_lo], 2177 src_offset); 2178 } 2179 } else { 2180 // 32 bit 2181 if (cbuf) { 2182 MacroAssembler _masm(cbuf); 2183 __ ldrw(as_Register(Matcher::_regEncode[dst_lo]), 2184 Address(sp, src_offset)); 2185 } else if (st) { 2186 st->print("ldr %s, [sp, %d]\t# restore", 2187 Matcher::regName[dst_lo], 2188 src_offset); 2189 } 2190 } 2191 return 4; 2192 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 2193 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2194 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2195 // 64 bit 2196 if (cbuf) { 2197 MacroAssembler _masm(cbuf); 2198 __ ldrd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2199 Address(sp, src_offset)); 2200 } else if (st) { 2201 st->print("ldrd %s, [sp, %d]\t# restore", 2202 Matcher::regName[dst_lo], 2203 src_offset); 2204 } 2205 } else { 2206 // 32 bit 2207 if (cbuf) { 2208 MacroAssembler _masm(cbuf); 2209 __ ldrs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2210 Address(sp, src_offset)); 2211 } else if (st) { 2212 st->print("ldrs %s, [sp, %d]\t# restore", 2213 Matcher::regName[dst_lo], 2214 src_offset); 2215 } 2216 } 2217 return 4; 2218 } else { // stack --> stack copy 2219 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2220 int dst_offset = ra_->reg2offset(dst_lo); 2221 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2222 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2223 // 64 bit 2224 if (cbuf) { 2225 MacroAssembler _masm(cbuf); 2226 __ ldr(rscratch1, Address(sp, src_offset)); 2227 __ str(rscratch1, Address(sp, dst_offset)); 2228 } else if (st) { 2229 st->print("ldr rscratch1, [sp, %d]\t# mem-mem spill", 2230 src_offset); 2231 st->print("\n\t"); 2232 st->print("str rscratch1, [sp, %d]", 2233 dst_offset); 2234 } 2235 } else { 2236 // 32 bit 2237 if (cbuf) { 2238 MacroAssembler _masm(cbuf); 2239 __ ldrw(rscratch1, Address(sp, src_offset)); 2240 __ strw(rscratch1, Address(sp, dst_offset)); 2241 } else if (st) { 2242 st->print("ldrw rscratch1, [sp, %d]\t# mem-mem spill", 2243 src_offset); 2244 st->print("\n\t"); 2245 st->print("strw rscratch1, [sp, %d]", 2246 dst_offset); 2247 } 2248 } 2249 return 8; 2250 } 2251 } 2252 2253 assert(false," bad rc_class for spill "); 2254 Unimplemented(); 2255 return 0; 2256 2257 } 2258 2259 #ifndef PRODUCT 2260 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2261 if (!ra_) 2262 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 2263 else 2264 implementation(NULL, ra_, false, st); 2265 } 2266 #endif 2267 2268 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2269 implementation(&cbuf, ra_, false, NULL); 2270 } 2271 2272 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 2273 return implementation(NULL, ra_, true, NULL); 2274 } 2275 2276 //============================================================================= 2277 2278 #ifndef PRODUCT 2279 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2280 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2281 int reg = ra_->get_reg_first(this); 2282 st->print("add %s, rsp, #%d]\t# box lock", 2283 Matcher::regName[reg], offset); 2284 } 2285 #endif 2286 2287 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2288 MacroAssembler _masm(&cbuf); 2289 2290 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2291 int reg = ra_->get_encode(this); 2292 2293 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 2294 __ add(as_Register(reg), sp, offset); 2295 } else { 2296 ShouldNotReachHere(); 2297 } 2298 } 2299 2300 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2301 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2302 return 4; 2303 } 2304 2305 //============================================================================= 2306 2307 #ifndef PRODUCT 2308 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 2309 { 2310 st->print_cr("# MachUEPNode"); 2311 if (UseCompressedClassPointers) { 2312 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2313 if (Universe::narrow_klass_shift() != 0) { 2314 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 2315 } 2316 } else { 2317 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2318 } 2319 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 2320 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 2321 } 2322 #endif 2323 2324 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2325 { 2326 // This is the unverified entry point. 2327 MacroAssembler _masm(&cbuf); 2328 2329 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2330 Label skip; 2331 // TODO 2332 // can we avoid this skip and still use a reloc? 2333 __ br(Assembler::EQ, skip); 2334 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2335 __ bind(skip); 2336 } 2337 2338 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2339 { 2340 return MachNode::size(ra_); 2341 } 2342 2343 // REQUIRED EMIT CODE 2344 2345 //============================================================================= 2346 2347 // Emit exception handler code. 2348 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2349 { 2350 // mov rscratch1 #exception_blob_entry_point 2351 // br rscratch1 2352 // Note that the code buffer's insts_mark is always relative to insts. 2353 // That's why we must use the macroassembler to generate a handler. 2354 MacroAssembler _masm(&cbuf); 2355 address base = 2356 __ start_a_stub(size_exception_handler()); 2357 if (base == NULL) return 0; // CodeBuffer::expand failed 2358 int offset = __ offset(); 2359 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2360 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2361 __ end_a_stub(); 2362 return offset; 2363 } 2364 2365 // Emit deopt handler code. 2366 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2367 { 2368 // Note that the code buffer's insts_mark is always relative to insts. 2369 // That's why we must use the macroassembler to generate a handler. 2370 MacroAssembler _masm(&cbuf); 2371 address base = 2372 __ start_a_stub(size_deopt_handler()); 2373 if (base == NULL) return 0; // CodeBuffer::expand failed 2374 int offset = __ offset(); 2375 2376 __ adr(lr, __ pc()); 2377 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2378 2379 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2380 __ end_a_stub(); 2381 return offset; 2382 } 2383 2384 // REQUIRED MATCHER CODE 2385 2386 //============================================================================= 2387 2388 const bool Matcher::match_rule_supported(int opcode) { 2389 2390 // TODO 2391 // identify extra cases that we might want to provide match rules for 2392 // e.g. Op_StrEquals and other intrinsics 2393 if (!has_match_rule(opcode)) { 2394 return false; 2395 } 2396 2397 return true; // Per default match rules are supported. 2398 } 2399 2400 int Matcher::regnum_to_fpu_offset(int regnum) 2401 { 2402 Unimplemented(); 2403 return 0; 2404 } 2405 2406 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) 2407 { 2408 Unimplemented(); 2409 return false; 2410 } 2411 2412 const bool Matcher::isSimpleConstant64(jlong value) { 2413 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2414 // Probably always true, even if a temp register is required. 2415 return true; 2416 } 2417 2418 // true just means we have fast l2f conversion 2419 const bool Matcher::convL2FSupported(void) { 2420 return true; 2421 } 2422 2423 // Vector width in bytes. 2424 const int Matcher::vector_width_in_bytes(BasicType bt) { 2425 // TODO fixme 2426 return 0; 2427 } 2428 2429 // Limits on vector size (number of elements) loaded into vector. 2430 const int Matcher::max_vector_size(const BasicType bt) { 2431 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2432 } 2433 const int Matcher::min_vector_size(const BasicType bt) { 2434 int max_size = max_vector_size(bt); 2435 // Min size which can be loaded into vector is 4 bytes. 2436 int size = (type2aelembytes(bt) == 1) ? 4 : 2; 2437 return MIN2(size,max_size); 2438 } 2439 2440 // Vector ideal reg. 2441 const int Matcher::vector_ideal_reg(int len) { 2442 // TODO fixme 2443 return Op_RegD; 2444 } 2445 2446 // Only lowest bits of xmm reg are used for vector shift count. 2447 const int Matcher::vector_shift_count_ideal_reg(int size) { 2448 // TODO fixme 2449 return Op_RegL; 2450 } 2451 2452 // AES support not yet implemented 2453 const bool Matcher::pass_original_key_for_aes() { 2454 return false; 2455 } 2456 2457 // x86 supports misaligned vectors store/load. 2458 const bool Matcher::misaligned_vectors_ok() { 2459 // TODO fixme 2460 // return !AlignVector; // can be changed by flag 2461 return false; 2462 } 2463 2464 // false => size gets scaled to BytesPerLong, ok. 2465 const bool Matcher::init_array_count_is_in_bytes = false; 2466 2467 // Threshold size for cleararray. 2468 const int Matcher::init_array_short_size = 18 * BytesPerLong; 2469 2470 // Use conditional move (CMOVL) 2471 const int Matcher::long_cmove_cost() { 2472 // long cmoves are no more expensive than int cmoves 2473 return 0; 2474 } 2475 2476 const int Matcher::float_cmove_cost() { 2477 // float cmoves are no more expensive than int cmoves 2478 return 0; 2479 } 2480 2481 // Does the CPU require late expand (see block.cpp for description of late expand)? 2482 const bool Matcher::require_postalloc_expand = false; 2483 2484 // Should the Matcher clone shifts on addressing modes, expecting them 2485 // to be subsumed into complex addressing expressions or compute them 2486 // into registers? True for Intel but false for most RISCs 2487 const bool Matcher::clone_shift_expressions = false; 2488 2489 // Do we need to mask the count passed to shift instructions or does 2490 // the cpu only look at the lower 5/6 bits anyway? 2491 const bool Matcher::need_masked_shift_count = false; 2492 2493 // This affects two different things: 2494 // - how Decode nodes are matched 2495 // - how ImplicitNullCheck opportunities are recognized 2496 // If true, the matcher will try to remove all Decodes and match them 2497 // (as operands) into nodes. NullChecks are not prepared to deal with 2498 // Decodes by final_graph_reshaping(). 2499 // If false, final_graph_reshaping() forces the decode behind the Cmp 2500 // for a NullCheck. The matcher matches the Decode node into a register. 2501 // Implicit_null_check optimization moves the Decode along with the 2502 // memory operation back up before the NullCheck. 2503 bool Matcher::narrow_oop_use_complex_address() { 2504 return Universe::narrow_oop_shift() == 0; 2505 } 2506 2507 bool Matcher::narrow_klass_use_complex_address() { 2508 // TODO 2509 // decide whether we need to set this to true 2510 return false; 2511 } 2512 2513 // Is it better to copy float constants, or load them directly from 2514 // memory? Intel can load a float constant from a direct address, 2515 // requiring no extra registers. Most RISCs will have to materialize 2516 // an address into a register first, so they would do better to copy 2517 // the constant from stack. 2518 const bool Matcher::rematerialize_float_constants = false; 2519 2520 // If CPU can load and store mis-aligned doubles directly then no 2521 // fixup is needed. Else we split the double into 2 integer pieces 2522 // and move it piece-by-piece. Only happens when passing doubles into 2523 // C code as the Java calling convention forces doubles to be aligned. 2524 const bool Matcher::misaligned_doubles_ok = true; 2525 2526 // No-op on amd64 2527 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2528 Unimplemented(); 2529 } 2530 2531 // Advertise here if the CPU requires explicit rounding operations to 2532 // implement the UseStrictFP mode. 2533 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2534 2535 // Are floats converted to double when stored to stack during 2536 // deoptimization? 2537 bool Matcher::float_in_double() { return true; } 2538 2539 // Do ints take an entire long register or just half? 2540 // The relevant question is how the int is callee-saved: 2541 // the whole long is written but de-opt'ing will have to extract 2542 // the relevant 32 bits. 2543 const bool Matcher::int_in_long = true; 2544 2545 // Return whether or not this register is ever used as an argument. 2546 // This function is used on startup to build the trampoline stubs in 2547 // generateOptoStub. Registers not mentioned will be killed by the VM 2548 // call in the trampoline, and arguments in those registers not be 2549 // available to the callee. 2550 bool Matcher::can_be_java_arg(int reg) 2551 { 2552 return 2553 reg == R0_num || reg == R0_H_num || 2554 reg == R1_num || reg == R1_H_num || 2555 reg == R2_num || reg == R2_H_num || 2556 reg == R3_num || reg == R3_H_num || 2557 reg == R4_num || reg == R4_H_num || 2558 reg == R5_num || reg == R5_H_num || 2559 reg == R6_num || reg == R6_H_num || 2560 reg == R7_num || reg == R7_H_num || 2561 reg == V0_num || reg == V0_H_num || 2562 reg == V1_num || reg == V1_H_num || 2563 reg == V2_num || reg == V2_H_num || 2564 reg == V3_num || reg == V3_H_num || 2565 reg == V4_num || reg == V4_H_num || 2566 reg == V5_num || reg == V5_H_num || 2567 reg == V6_num || reg == V6_H_num || 2568 reg == V7_num || reg == V7_H_num; 2569 } 2570 2571 bool Matcher::is_spillable_arg(int reg) 2572 { 2573 return can_be_java_arg(reg); 2574 } 2575 2576 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2577 return false; 2578 } 2579 2580 RegMask Matcher::divI_proj_mask() { 2581 ShouldNotReachHere(); 2582 return RegMask(); 2583 } 2584 2585 // Register for MODI projection of divmodI. 2586 RegMask Matcher::modI_proj_mask() { 2587 ShouldNotReachHere(); 2588 return RegMask(); 2589 } 2590 2591 // Register for DIVL projection of divmodL. 2592 RegMask Matcher::divL_proj_mask() { 2593 ShouldNotReachHere(); 2594 return RegMask(); 2595 } 2596 2597 // Register for MODL projection of divmodL. 2598 RegMask Matcher::modL_proj_mask() { 2599 ShouldNotReachHere(); 2600 return RegMask(); 2601 } 2602 2603 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2604 return FP_REG_mask(); 2605 } 2606 2607 // helper for encoding java_to_runtime calls on sim 2608 // 2609 // this is needed to compute the extra arguments required when 2610 // planting a call to the simulator blrt instruction. the TypeFunc 2611 // can be queried to identify the counts for integral, and floating 2612 // arguments and the return type 2613 2614 static void getCallInfo(const TypeFunc *tf, int &gpcnt, int &fpcnt, int &rtype) 2615 { 2616 int gps = 0; 2617 int fps = 0; 2618 const TypeTuple *domain = tf->domain(); 2619 int max = domain->cnt(); 2620 for (int i = TypeFunc::Parms; i < max; i++) { 2621 const Type *t = domain->field_at(i); 2622 switch(t->basic_type()) { 2623 case T_FLOAT: 2624 case T_DOUBLE: 2625 fps++; 2626 default: 2627 gps++; 2628 } 2629 } 2630 gpcnt = gps; 2631 fpcnt = fps; 2632 BasicType rt = tf->return_type(); 2633 switch (rt) { 2634 case T_VOID: 2635 rtype = MacroAssembler::ret_type_void; 2636 break; 2637 default: 2638 rtype = MacroAssembler::ret_type_integral; 2639 break; 2640 case T_FLOAT: 2641 rtype = MacroAssembler::ret_type_float; 2642 break; 2643 case T_DOUBLE: 2644 rtype = MacroAssembler::ret_type_double; 2645 break; 2646 } 2647 } 2648 2649 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2650 MacroAssembler _masm(&cbuf); \ 2651 { \ 2652 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2653 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2654 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2655 __ INSN(REG, as_Register(BASE)); \ 2656 } 2657 2658 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2659 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2660 2661 // Used for all non-volatile memory accesses. The use of 2662 // $mem->opcode() to discover whether this pattern uses sign-extended 2663 // offsets is something of a kludge. 2664 static void loadStore(MacroAssembler masm, mem_insn insn, 2665 Register reg, int opcode, 2666 Register base, int index, int size, int disp) 2667 { 2668 Address::extend scale; 2669 2670 // Hooboy, this is fugly. We need a way to communicate to the 2671 // encoder that the index needs to be sign extended, so we have to 2672 // enumerate all the cases. 2673 switch (opcode) { 2674 case INDINDEXSCALEDOFFSETI2L: 2675 case INDINDEXSCALEDI2L: 2676 case INDINDEXSCALEDOFFSETI2LN: 2677 case INDINDEXSCALEDI2LN: 2678 case INDINDEXOFFSETI2L: 2679 case INDINDEXOFFSETI2LN: 2680 scale = Address::sxtw(size); 2681 break; 2682 default: 2683 scale = Address::lsl(size); 2684 } 2685 2686 if (index == -1) { 2687 (masm.*insn)(reg, Address(base, disp)); 2688 } else { 2689 if (disp == 0) { 2690 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2691 } else { 2692 masm.lea(rscratch1, Address(base, disp)); 2693 (masm.*insn)(reg, Address(rscratch1, as_Register(index), scale)); 2694 } 2695 } 2696 } 2697 2698 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2699 FloatRegister reg, int opcode, 2700 Register base, int index, int size, int disp) 2701 { 2702 Address::extend scale; 2703 2704 switch (opcode) { 2705 case INDINDEXSCALEDOFFSETI2L: 2706 case INDINDEXSCALEDI2L: 2707 case INDINDEXSCALEDOFFSETI2LN: 2708 case INDINDEXSCALEDI2LN: 2709 scale = Address::sxtw(size); 2710 break; 2711 default: 2712 scale = Address::lsl(size); 2713 } 2714 2715 if (index == -1) { 2716 (masm.*insn)(reg, Address(base, disp)); 2717 } else { 2718 if (disp == 0) { 2719 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2720 } else { 2721 masm.lea(rscratch1, Address(base, disp)); 2722 (masm.*insn)(reg, Address(rscratch1, as_Register(index), scale)); 2723 } 2724 } 2725 } 2726 2727 %} 2728 2729 2730 2731 //----------ENCODING BLOCK----------------------------------------------------- 2732 // This block specifies the encoding classes used by the compiler to 2733 // output byte streams. Encoding classes are parameterized macros 2734 // used by Machine Instruction Nodes in order to generate the bit 2735 // encoding of the instruction. Operands specify their base encoding 2736 // interface with the interface keyword. There are currently 2737 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2738 // COND_INTER. REG_INTER causes an operand to generate a function 2739 // which returns its register number when queried. CONST_INTER causes 2740 // an operand to generate a function which returns the value of the 2741 // constant when queried. MEMORY_INTER causes an operand to generate 2742 // four functions which return the Base Register, the Index Register, 2743 // the Scale Value, and the Offset Value of the operand when queried. 2744 // COND_INTER causes an operand to generate six functions which return 2745 // the encoding code (ie - encoding bits for the instruction) 2746 // associated with each basic boolean condition for a conditional 2747 // instruction. 2748 // 2749 // Instructions specify two basic values for encoding. Again, a 2750 // function is available to check if the constant displacement is an 2751 // oop. They use the ins_encode keyword to specify their encoding 2752 // classes (which must be a sequence of enc_class names, and their 2753 // parameters, specified in the encoding block), and they use the 2754 // opcode keyword to specify, in order, their primary, secondary, and 2755 // tertiary opcode. Only the opcode sections which a particular 2756 // instruction needs for encoding need to be specified. 2757 encode %{ 2758 // Build emit functions for each basic byte or larger field in the 2759 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2760 // from C++ code in the enc_class source block. Emit functions will 2761 // live in the main source block for now. In future, we can 2762 // generalize this by adding a syntax that specifies the sizes of 2763 // fields in an order, so that the adlc can build the emit functions 2764 // automagically 2765 2766 // catch all for unimplemented encodings 2767 enc_class enc_unimplemented %{ 2768 MacroAssembler _masm(&cbuf); 2769 __ unimplemented("C2 catch all"); 2770 %} 2771 2772 // BEGIN Non-volatile memory access 2773 2774 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 2775 Register dst_reg = as_Register($dst$$reg); 2776 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2777 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2778 %} 2779 2780 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 2781 Register dst_reg = as_Register($dst$$reg); 2782 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2783 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2784 %} 2785 2786 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 2787 Register dst_reg = as_Register($dst$$reg); 2788 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2789 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2790 %} 2791 2792 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 2793 Register dst_reg = as_Register($dst$$reg); 2794 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2795 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2796 %} 2797 2798 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 2799 Register dst_reg = as_Register($dst$$reg); 2800 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2801 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2802 %} 2803 2804 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 2805 Register dst_reg = as_Register($dst$$reg); 2806 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2807 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2808 %} 2809 2810 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 2811 Register dst_reg = as_Register($dst$$reg); 2812 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2813 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2814 %} 2815 2816 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 2817 Register dst_reg = as_Register($dst$$reg); 2818 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2819 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2820 %} 2821 2822 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 2823 Register dst_reg = as_Register($dst$$reg); 2824 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2825 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2826 %} 2827 2828 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 2829 Register dst_reg = as_Register($dst$$reg); 2830 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2831 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2832 %} 2833 2834 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 2835 Register dst_reg = as_Register($dst$$reg); 2836 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2837 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2838 %} 2839 2840 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 2841 Register dst_reg = as_Register($dst$$reg); 2842 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2843 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2844 %} 2845 2846 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 2847 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2848 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2849 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2850 %} 2851 2852 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 2853 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2854 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2855 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2856 %} 2857 2858 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 2859 Register src_reg = as_Register($src$$reg); 2860 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2861 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2862 %} 2863 2864 enc_class aarch64_enc_strb0(memory mem) %{ 2865 MacroAssembler _masm(&cbuf); 2866 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2867 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2868 %} 2869 2870 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 2871 Register src_reg = as_Register($src$$reg); 2872 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2873 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2874 %} 2875 2876 enc_class aarch64_enc_strh0(memory mem) %{ 2877 MacroAssembler _masm(&cbuf); 2878 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2879 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2880 %} 2881 2882 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 2883 Register src_reg = as_Register($src$$reg); 2884 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2885 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2886 %} 2887 2888 enc_class aarch64_enc_strw0(memory mem) %{ 2889 MacroAssembler _masm(&cbuf); 2890 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2891 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2892 %} 2893 2894 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 2895 Register src_reg = as_Register($src$$reg); 2896 // we sometimes get asked to store the stack pointer into the 2897 // current thread -- we cannot do that directly on AArch64 2898 if (src_reg == r31_sp) { 2899 MacroAssembler _masm(&cbuf); 2900 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2901 __ mov(rscratch2, sp); 2902 src_reg = rscratch2; 2903 } 2904 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2905 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2906 %} 2907 2908 enc_class aarch64_enc_str0(memory mem) %{ 2909 MacroAssembler _masm(&cbuf); 2910 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2911 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2912 %} 2913 2914 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 2915 FloatRegister src_reg = as_FloatRegister($src$$reg); 2916 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2917 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2918 %} 2919 2920 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 2921 FloatRegister src_reg = as_FloatRegister($src$$reg); 2922 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2923 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2924 %} 2925 2926 // END Non-volatile memory access 2927 2928 // volatile loads and stores 2929 2930 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2931 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2932 rscratch1, stlrb); 2933 %} 2934 2935 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2936 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2937 rscratch1, stlrh); 2938 %} 2939 2940 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2941 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2942 rscratch1, stlrw); 2943 %} 2944 2945 2946 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2947 Register dst_reg = as_Register($dst$$reg); 2948 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2949 rscratch1, ldarb); 2950 __ sxtbw(dst_reg, dst_reg); 2951 %} 2952 2953 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2954 Register dst_reg = as_Register($dst$$reg); 2955 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2956 rscratch1, ldarb); 2957 __ sxtb(dst_reg, dst_reg); 2958 %} 2959 2960 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2961 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2962 rscratch1, ldarb); 2963 %} 2964 2965 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2966 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2967 rscratch1, ldarb); 2968 %} 2969 2970 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2971 Register dst_reg = as_Register($dst$$reg); 2972 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2973 rscratch1, ldarh); 2974 __ sxthw(dst_reg, dst_reg); 2975 %} 2976 2977 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2978 Register dst_reg = as_Register($dst$$reg); 2979 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2980 rscratch1, ldarh); 2981 __ sxth(dst_reg, dst_reg); 2982 %} 2983 2984 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2985 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2986 rscratch1, ldarh); 2987 %} 2988 2989 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2990 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2991 rscratch1, ldarh); 2992 %} 2993 2994 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2995 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2996 rscratch1, ldarw); 2997 %} 2998 2999 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 3000 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3001 rscratch1, ldarw); 3002 %} 3003 3004 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 3005 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3006 rscratch1, ldar); 3007 %} 3008 3009 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 3010 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3011 rscratch1, ldarw); 3012 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 3013 %} 3014 3015 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 3016 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3017 rscratch1, ldar); 3018 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 3019 %} 3020 3021 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 3022 Register src_reg = as_Register($src$$reg); 3023 // we sometimes get asked to store the stack pointer into the 3024 // current thread -- we cannot do that directly on AArch64 3025 if (src_reg == r31_sp) { 3026 MacroAssembler _masm(&cbuf); 3027 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3028 __ mov(rscratch2, sp); 3029 src_reg = rscratch2; 3030 } 3031 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3032 rscratch1, stlr); 3033 %} 3034 3035 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 3036 { 3037 MacroAssembler _masm(&cbuf); 3038 FloatRegister src_reg = as_FloatRegister($src$$reg); 3039 __ fmovs(rscratch2, src_reg); 3040 } 3041 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3042 rscratch1, stlrw); 3043 %} 3044 3045 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 3046 { 3047 MacroAssembler _masm(&cbuf); 3048 FloatRegister src_reg = as_FloatRegister($src$$reg); 3049 __ fmovd(rscratch2, src_reg); 3050 } 3051 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3052 rscratch1, stlr); 3053 %} 3054 3055 // synchronized read/update encodings 3056 3057 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 3058 MacroAssembler _masm(&cbuf); 3059 Register dst_reg = as_Register($dst$$reg); 3060 Register base = as_Register($mem$$base); 3061 int index = $mem$$index; 3062 int scale = $mem$$scale; 3063 int disp = $mem$$disp; 3064 if (index == -1) { 3065 if (disp != 0) { 3066 __ lea(rscratch1, Address(base, disp)); 3067 __ ldaxr(dst_reg, rscratch1); 3068 } else { 3069 // TODO 3070 // should we ever get anything other than this case? 3071 __ ldaxr(dst_reg, base); 3072 } 3073 } else { 3074 Register index_reg = as_Register(index); 3075 if (disp == 0) { 3076 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3077 __ ldaxr(dst_reg, rscratch1); 3078 } else { 3079 __ lea(rscratch1, Address(base, disp)); 3080 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3081 __ ldaxr(dst_reg, rscratch1); 3082 } 3083 } 3084 %} 3085 3086 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 3087 MacroAssembler _masm(&cbuf); 3088 Register src_reg = as_Register($src$$reg); 3089 Register base = as_Register($mem$$base); 3090 int index = $mem$$index; 3091 int scale = $mem$$scale; 3092 int disp = $mem$$disp; 3093 if (index == -1) { 3094 if (disp != 0) { 3095 __ lea(rscratch2, Address(base, disp)); 3096 __ stlxr(rscratch1, src_reg, rscratch2); 3097 } else { 3098 // TODO 3099 // should we ever get anything other than this case? 3100 __ stlxr(rscratch1, src_reg, base); 3101 } 3102 } else { 3103 Register index_reg = as_Register(index); 3104 if (disp == 0) { 3105 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3106 __ stlxr(rscratch1, src_reg, rscratch2); 3107 } else { 3108 __ lea(rscratch2, Address(base, disp)); 3109 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3110 __ stlxr(rscratch1, src_reg, rscratch2); 3111 } 3112 } 3113 __ cmpw(rscratch1, zr); 3114 %} 3115 3116 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3117 MacroAssembler _masm(&cbuf); 3118 Register old_reg = as_Register($oldval$$reg); 3119 Register new_reg = as_Register($newval$$reg); 3120 Register base = as_Register($mem$$base); 3121 Register addr_reg; 3122 int index = $mem$$index; 3123 int scale = $mem$$scale; 3124 int disp = $mem$$disp; 3125 if (index == -1) { 3126 if (disp != 0) { 3127 __ lea(rscratch2, Address(base, disp)); 3128 addr_reg = rscratch2; 3129 } else { 3130 // TODO 3131 // should we ever get anything other than this case? 3132 addr_reg = base; 3133 } 3134 } else { 3135 Register index_reg = as_Register(index); 3136 if (disp == 0) { 3137 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3138 addr_reg = rscratch2; 3139 } else { 3140 __ lea(rscratch2, Address(base, disp)); 3141 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3142 addr_reg = rscratch2; 3143 } 3144 } 3145 Label retry_load, done; 3146 __ bind(retry_load); 3147 __ ldxr(rscratch1, addr_reg); 3148 __ cmp(rscratch1, old_reg); 3149 __ br(Assembler::NE, done); 3150 __ stlxr(rscratch1, new_reg, addr_reg); 3151 __ cbnzw(rscratch1, retry_load); 3152 __ bind(done); 3153 %} 3154 3155 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3156 MacroAssembler _masm(&cbuf); 3157 Register old_reg = as_Register($oldval$$reg); 3158 Register new_reg = as_Register($newval$$reg); 3159 Register base = as_Register($mem$$base); 3160 Register addr_reg; 3161 int index = $mem$$index; 3162 int scale = $mem$$scale; 3163 int disp = $mem$$disp; 3164 if (index == -1) { 3165 if (disp != 0) { 3166 __ lea(rscratch2, Address(base, disp)); 3167 addr_reg = rscratch2; 3168 } else { 3169 // TODO 3170 // should we ever get anything other than this case? 3171 addr_reg = base; 3172 } 3173 } else { 3174 Register index_reg = as_Register(index); 3175 if (disp == 0) { 3176 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3177 addr_reg = rscratch2; 3178 } else { 3179 __ lea(rscratch2, Address(base, disp)); 3180 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3181 addr_reg = rscratch2; 3182 } 3183 } 3184 Label retry_load, done; 3185 __ bind(retry_load); 3186 __ ldxrw(rscratch1, addr_reg); 3187 __ cmpw(rscratch1, old_reg); 3188 __ br(Assembler::NE, done); 3189 __ stlxrw(rscratch1, new_reg, addr_reg); 3190 __ cbnzw(rscratch1, retry_load); 3191 __ bind(done); 3192 %} 3193 3194 // auxiliary used for CompareAndSwapX to set result register 3195 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3196 MacroAssembler _masm(&cbuf); 3197 Register res_reg = as_Register($res$$reg); 3198 __ cset(res_reg, Assembler::EQ); 3199 %} 3200 3201 // prefetch encodings 3202 3203 enc_class aarch64_enc_prefetchw(memory mem) %{ 3204 MacroAssembler _masm(&cbuf); 3205 Register base = as_Register($mem$$base); 3206 int index = $mem$$index; 3207 int scale = $mem$$scale; 3208 int disp = $mem$$disp; 3209 if (index == -1) { 3210 __ prfm(Address(base, disp), PSTL1KEEP); 3211 __ nop(); 3212 } else { 3213 Register index_reg = as_Register(index); 3214 if (disp == 0) { 3215 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3216 } else { 3217 __ lea(rscratch1, Address(base, disp)); 3218 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3219 } 3220 } 3221 %} 3222 3223 enc_class aarch64_enc_clear_array_reg_reg(iRegL_R11 cnt, iRegP_R10 base) %{ 3224 MacroAssembler _masm(&cbuf); 3225 Register cnt_reg = as_Register($cnt$$reg); 3226 Register base_reg = as_Register($base$$reg); 3227 // base is word aligned 3228 // cnt is count of words 3229 3230 Label loop; 3231 Label entry; 3232 3233 // Algorithm: 3234 // 3235 // scratch1 = cnt & 7; 3236 // cnt -= scratch1; 3237 // p += scratch1; 3238 // switch (scratch1) { 3239 // do { 3240 // cnt -= 8; 3241 // p[-8] = 0; 3242 // case 7: 3243 // p[-7] = 0; 3244 // case 6: 3245 // p[-6] = 0; 3246 // // ... 3247 // case 1: 3248 // p[-1] = 0; 3249 // case 0: 3250 // p += 8; 3251 // } while (cnt); 3252 // } 3253 3254 const int unroll = 8; // Number of str(zr) instructions we'll unroll 3255 3256 __ andr(rscratch1, cnt_reg, unroll - 1); // tmp1 = cnt % unroll 3257 __ sub(cnt_reg, cnt_reg, rscratch1); // cnt -= unroll 3258 // base_reg always points to the end of the region we're about to zero 3259 __ add(base_reg, base_reg, rscratch1, Assembler::LSL, exact_log2(wordSize)); 3260 __ adr(rscratch2, entry); 3261 __ sub(rscratch2, rscratch2, rscratch1, Assembler::LSL, 2); 3262 __ br(rscratch2); 3263 __ bind(loop); 3264 __ sub(cnt_reg, cnt_reg, unroll); 3265 for (int i = -unroll; i < 0; i++) 3266 __ str(zr, Address(base_reg, i * wordSize)); 3267 __ bind(entry); 3268 __ add(base_reg, base_reg, unroll * wordSize); 3269 __ cbnz(cnt_reg, loop); 3270 %} 3271 3272 /// mov envcodings 3273 3274 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3275 MacroAssembler _masm(&cbuf); 3276 u_int32_t con = (u_int32_t)$src$$constant; 3277 Register dst_reg = as_Register($dst$$reg); 3278 if (con == 0) { 3279 __ movw(dst_reg, zr); 3280 } else { 3281 __ movw(dst_reg, con); 3282 } 3283 %} 3284 3285 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3286 MacroAssembler _masm(&cbuf); 3287 Register dst_reg = as_Register($dst$$reg); 3288 u_int64_t con = (u_int64_t)$src$$constant; 3289 if (con == 0) { 3290 __ mov(dst_reg, zr); 3291 } else { 3292 __ mov(dst_reg, con); 3293 } 3294 %} 3295 3296 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3297 MacroAssembler _masm(&cbuf); 3298 Register dst_reg = as_Register($dst$$reg); 3299 address con = (address)$src$$constant; 3300 if (con == NULL || con == (address)1) { 3301 ShouldNotReachHere(); 3302 } else { 3303 relocInfo::relocType rtype = $src->constant_reloc(); 3304 if (rtype == relocInfo::oop_type) { 3305 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3306 } else if (rtype == relocInfo::metadata_type) { 3307 __ mov_metadata(dst_reg, (Metadata*)con); 3308 } else { 3309 assert(rtype == relocInfo::none, "unexpected reloc type"); 3310 if (con < (address)(uintptr_t)os::vm_page_size()) { 3311 __ mov(dst_reg, con); 3312 } else { 3313 unsigned long offset; 3314 __ adrp(dst_reg, con, offset); 3315 __ add(dst_reg, dst_reg, offset); 3316 } 3317 } 3318 } 3319 %} 3320 3321 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3322 MacroAssembler _masm(&cbuf); 3323 Register dst_reg = as_Register($dst$$reg); 3324 __ mov(dst_reg, zr); 3325 %} 3326 3327 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3328 MacroAssembler _masm(&cbuf); 3329 Register dst_reg = as_Register($dst$$reg); 3330 __ mov(dst_reg, (u_int64_t)1); 3331 %} 3332 3333 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3334 MacroAssembler _masm(&cbuf); 3335 address page = (address)$src$$constant; 3336 Register dst_reg = as_Register($dst$$reg); 3337 unsigned long off; 3338 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3339 assert(off == 0, "assumed offset == 0"); 3340 %} 3341 3342 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3343 MacroAssembler _masm(&cbuf); 3344 address page = (address)$src$$constant; 3345 Register dst_reg = as_Register($dst$$reg); 3346 unsigned long off; 3347 __ adrp(dst_reg, ExternalAddress(page), off); 3348 assert(off == 0, "assumed offset == 0"); 3349 %} 3350 3351 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3352 MacroAssembler _masm(&cbuf); 3353 Register dst_reg = as_Register($dst$$reg); 3354 address con = (address)$src$$constant; 3355 if (con == NULL) { 3356 ShouldNotReachHere(); 3357 } else { 3358 relocInfo::relocType rtype = $src->constant_reloc(); 3359 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3360 __ set_narrow_oop(dst_reg, (jobject)con); 3361 } 3362 %} 3363 3364 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3365 MacroAssembler _masm(&cbuf); 3366 Register dst_reg = as_Register($dst$$reg); 3367 __ mov(dst_reg, zr); 3368 %} 3369 3370 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3371 MacroAssembler _masm(&cbuf); 3372 Register dst_reg = as_Register($dst$$reg); 3373 address con = (address)$src$$constant; 3374 if (con == NULL) { 3375 ShouldNotReachHere(); 3376 } else { 3377 relocInfo::relocType rtype = $src->constant_reloc(); 3378 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3379 __ set_narrow_klass(dst_reg, (Klass *)con); 3380 } 3381 %} 3382 3383 // arithmetic encodings 3384 3385 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3386 MacroAssembler _masm(&cbuf); 3387 Register dst_reg = as_Register($dst$$reg); 3388 Register src_reg = as_Register($src1$$reg); 3389 int32_t con = (int32_t)$src2$$constant; 3390 // add has primary == 0, subtract has primary == 1 3391 if ($primary) { con = -con; } 3392 if (con < 0) { 3393 __ subw(dst_reg, src_reg, -con); 3394 } else { 3395 __ addw(dst_reg, src_reg, con); 3396 } 3397 %} 3398 3399 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3400 MacroAssembler _masm(&cbuf); 3401 Register dst_reg = as_Register($dst$$reg); 3402 Register src_reg = as_Register($src1$$reg); 3403 int32_t con = (int32_t)$src2$$constant; 3404 // add has primary == 0, subtract has primary == 1 3405 if ($primary) { con = -con; } 3406 if (con < 0) { 3407 __ sub(dst_reg, src_reg, -con); 3408 } else { 3409 __ add(dst_reg, src_reg, con); 3410 } 3411 %} 3412 3413 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3414 MacroAssembler _masm(&cbuf); 3415 Register dst_reg = as_Register($dst$$reg); 3416 Register src1_reg = as_Register($src1$$reg); 3417 Register src2_reg = as_Register($src2$$reg); 3418 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3419 %} 3420 3421 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3422 MacroAssembler _masm(&cbuf); 3423 Register dst_reg = as_Register($dst$$reg); 3424 Register src1_reg = as_Register($src1$$reg); 3425 Register src2_reg = as_Register($src2$$reg); 3426 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3427 %} 3428 3429 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3430 MacroAssembler _masm(&cbuf); 3431 Register dst_reg = as_Register($dst$$reg); 3432 Register src1_reg = as_Register($src1$$reg); 3433 Register src2_reg = as_Register($src2$$reg); 3434 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3435 %} 3436 3437 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3438 MacroAssembler _masm(&cbuf); 3439 Register dst_reg = as_Register($dst$$reg); 3440 Register src1_reg = as_Register($src1$$reg); 3441 Register src2_reg = as_Register($src2$$reg); 3442 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3443 %} 3444 3445 // compare instruction encodings 3446 3447 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3448 MacroAssembler _masm(&cbuf); 3449 Register reg1 = as_Register($src1$$reg); 3450 Register reg2 = as_Register($src2$$reg); 3451 __ cmpw(reg1, reg2); 3452 %} 3453 3454 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3455 MacroAssembler _masm(&cbuf); 3456 Register reg = as_Register($src1$$reg); 3457 int32_t val = $src2$$constant; 3458 if (val >= 0) { 3459 __ subsw(zr, reg, val); 3460 } else { 3461 __ addsw(zr, reg, -val); 3462 } 3463 %} 3464 3465 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3466 MacroAssembler _masm(&cbuf); 3467 Register reg1 = as_Register($src1$$reg); 3468 u_int32_t val = (u_int32_t)$src2$$constant; 3469 __ movw(rscratch1, val); 3470 __ cmpw(reg1, rscratch1); 3471 %} 3472 3473 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3474 MacroAssembler _masm(&cbuf); 3475 Register reg1 = as_Register($src1$$reg); 3476 Register reg2 = as_Register($src2$$reg); 3477 __ cmp(reg1, reg2); 3478 %} 3479 3480 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3481 MacroAssembler _masm(&cbuf); 3482 Register reg = as_Register($src1$$reg); 3483 int64_t val = $src2$$constant; 3484 if (val >= 0) { 3485 __ subs(zr, reg, val); 3486 } else if (val != -val) { 3487 __ adds(zr, reg, -val); 3488 } else { 3489 // aargh, Long.MIN_VALUE is a special case 3490 __ orr(rscratch1, zr, (u_int64_t)val); 3491 __ subs(zr, reg, rscratch1); 3492 } 3493 %} 3494 3495 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3496 MacroAssembler _masm(&cbuf); 3497 Register reg1 = as_Register($src1$$reg); 3498 u_int64_t val = (u_int64_t)$src2$$constant; 3499 __ mov(rscratch1, val); 3500 __ cmp(reg1, rscratch1); 3501 %} 3502 3503 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3504 MacroAssembler _masm(&cbuf); 3505 Register reg1 = as_Register($src1$$reg); 3506 Register reg2 = as_Register($src2$$reg); 3507 __ cmp(reg1, reg2); 3508 %} 3509 3510 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3511 MacroAssembler _masm(&cbuf); 3512 Register reg1 = as_Register($src1$$reg); 3513 Register reg2 = as_Register($src2$$reg); 3514 __ cmpw(reg1, reg2); 3515 %} 3516 3517 enc_class aarch64_enc_testp(iRegP src) %{ 3518 MacroAssembler _masm(&cbuf); 3519 Register reg = as_Register($src$$reg); 3520 __ cmp(reg, zr); 3521 %} 3522 3523 enc_class aarch64_enc_testn(iRegN src) %{ 3524 MacroAssembler _masm(&cbuf); 3525 Register reg = as_Register($src$$reg); 3526 __ cmpw(reg, zr); 3527 %} 3528 3529 enc_class aarch64_enc_b(label lbl) %{ 3530 MacroAssembler _masm(&cbuf); 3531 Label *L = $lbl$$label; 3532 __ b(*L); 3533 %} 3534 3535 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3536 MacroAssembler _masm(&cbuf); 3537 Label *L = $lbl$$label; 3538 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3539 %} 3540 3541 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3542 MacroAssembler _masm(&cbuf); 3543 Label *L = $lbl$$label; 3544 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3545 %} 3546 3547 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3548 %{ 3549 Register sub_reg = as_Register($sub$$reg); 3550 Register super_reg = as_Register($super$$reg); 3551 Register temp_reg = as_Register($temp$$reg); 3552 Register result_reg = as_Register($result$$reg); 3553 3554 Label miss; 3555 MacroAssembler _masm(&cbuf); 3556 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3557 NULL, &miss, 3558 /*set_cond_codes:*/ true); 3559 if ($primary) { 3560 __ mov(result_reg, zr); 3561 } 3562 __ bind(miss); 3563 %} 3564 3565 enc_class aarch64_enc_java_static_call(method meth) %{ 3566 MacroAssembler _masm(&cbuf); 3567 3568 address addr = (address)$meth$$method; 3569 if (!_method) { 3570 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3571 __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3572 } else if (_optimized_virtual) { 3573 __ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf); 3574 } else { 3575 __ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf); 3576 } 3577 3578 if (_method) { 3579 // Emit stub for static call 3580 CompiledStaticCall::emit_to_interp_stub(cbuf); 3581 } 3582 %} 3583 3584 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3585 MacroAssembler _masm(&cbuf); 3586 __ ic_call((address)$meth$$method); 3587 %} 3588 3589 enc_class aarch64_enc_call_epilog() %{ 3590 MacroAssembler _masm(&cbuf); 3591 if (VerifyStackAtCalls) { 3592 // Check that stack depth is unchanged: find majik cookie on stack 3593 __ call_Unimplemented(); 3594 } 3595 %} 3596 3597 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3598 MacroAssembler _masm(&cbuf); 3599 3600 // some calls to generated routines (arraycopy code) are scheduled 3601 // by C2 as runtime calls. if so we can call them using a br (they 3602 // will be in a reachable segment) otherwise we have to use a blrt 3603 // which loads the absolute address into a register. 3604 address entry = (address)$meth$$method; 3605 CodeBlob *cb = CodeCache::find_blob(entry); 3606 if (cb) { 3607 __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3608 } else { 3609 int gpcnt; 3610 int fpcnt; 3611 int rtype; 3612 getCallInfo(tf(), gpcnt, fpcnt, rtype); 3613 Label retaddr; 3614 __ adr(rscratch2, retaddr); 3615 __ lea(rscratch1, RuntimeAddress(entry)); 3616 // Leave a breadcrumb for JavaThread::pd_last_frame(). 3617 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3618 __ blrt(rscratch1, gpcnt, fpcnt, rtype); 3619 __ bind(retaddr); 3620 __ add(sp, sp, 2 * wordSize); 3621 } 3622 %} 3623 3624 enc_class aarch64_enc_rethrow() %{ 3625 MacroAssembler _masm(&cbuf); 3626 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3627 %} 3628 3629 enc_class aarch64_enc_ret() %{ 3630 MacroAssembler _masm(&cbuf); 3631 __ ret(lr); 3632 %} 3633 3634 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3635 MacroAssembler _masm(&cbuf); 3636 Register target_reg = as_Register($jump_target$$reg); 3637 __ br(target_reg); 3638 %} 3639 3640 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3641 MacroAssembler _masm(&cbuf); 3642 Register target_reg = as_Register($jump_target$$reg); 3643 // exception oop should be in r0 3644 // ret addr has been popped into lr 3645 // callee expects it in r3 3646 __ mov(r3, lr); 3647 __ br(target_reg); 3648 %} 3649 3650 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3651 MacroAssembler _masm(&cbuf); 3652 Register oop = as_Register($object$$reg); 3653 Register box = as_Register($box$$reg); 3654 Register disp_hdr = as_Register($tmp$$reg); 3655 Register tmp = as_Register($tmp2$$reg); 3656 Label cont; 3657 Label object_has_monitor; 3658 Label cas_failed; 3659 3660 assert_different_registers(oop, box, tmp, disp_hdr); 3661 3662 // Load markOop from object into displaced_header. 3663 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3664 3665 // Always do locking in runtime. 3666 if (EmitSync & 0x01) { 3667 __ cmp(oop, zr); 3668 return; 3669 } 3670 3671 if (UseBiasedLocking) { 3672 __ biased_locking_enter(disp_hdr, oop, box, tmp, true, cont); 3673 } 3674 3675 // Handle existing monitor 3676 if (EmitSync & 0x02) { 3677 // we can use AArch64's bit test and branch here but 3678 // markoopDesc does not define a bit index just the bit value 3679 // so assert in case the bit pos changes 3680 # define __monitor_value_log2 1 3681 assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position"); 3682 __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor); 3683 # undef __monitor_value_log2 3684 } 3685 3686 // Set displaced_header to be (markOop of object | UNLOCK_VALUE). 3687 __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value); 3688 3689 // Load Compare Value application register. 3690 3691 // Initialize the box. (Must happen before we update the object mark!) 3692 __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3693 3694 // Compare object markOop with mark and if equal exchange scratch1 3695 // with object markOop. 3696 // Note that this is simply a CAS: it does not generate any 3697 // barriers. These are separately generated by 3698 // membar_acquire_lock(). 3699 { 3700 Label retry_load; 3701 __ bind(retry_load); 3702 __ ldxr(tmp, oop); 3703 __ cmp(tmp, disp_hdr); 3704 __ br(Assembler::NE, cas_failed); 3705 // use stlxr to ensure update is immediately visible 3706 __ stlxr(tmp, box, oop); 3707 __ cbzw(tmp, cont); 3708 __ b(retry_load); 3709 } 3710 3711 // Formerly: 3712 // __ cmpxchgptr(/*oldv=*/disp_hdr, 3713 // /*newv=*/box, 3714 // /*addr=*/oop, 3715 // /*tmp=*/tmp, 3716 // cont, 3717 // /*fail*/NULL); 3718 3719 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3720 3721 // If the compare-and-exchange succeeded, then we found an unlocked 3722 // object, will have now locked it will continue at label cont 3723 3724 __ bind(cas_failed); 3725 // We did not see an unlocked object so try the fast recursive case. 3726 3727 // Check if the owner is self by comparing the value in the 3728 // markOop of object (disp_hdr) with the stack pointer. 3729 __ mov(rscratch1, sp); 3730 __ sub(disp_hdr, disp_hdr, rscratch1); 3731 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place)); 3732 // If condition is true we are cont and hence we can store 0 as the 3733 // displaced header in the box, which indicates that it is a recursive lock. 3734 __ ands(tmp/*==0?*/, disp_hdr, tmp); 3735 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3736 3737 // Handle existing monitor. 3738 if ((EmitSync & 0x02) == 0) { 3739 __ b(cont); 3740 3741 __ bind(object_has_monitor); 3742 // The object's monitor m is unlocked iff m->owner == NULL, 3743 // otherwise m->owner may contain a thread or a stack address. 3744 // 3745 // Try to CAS m->owner from NULL to current thread. 3746 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value)); 3747 __ mov(disp_hdr, zr); 3748 3749 { 3750 Label retry_load, fail; 3751 __ bind(retry_load); 3752 __ ldxr(rscratch1, tmp); 3753 __ cmp(disp_hdr, rscratch1); 3754 __ br(Assembler::NE, fail); 3755 // use stlxr to ensure update is immediately visible 3756 __ stlxr(rscratch1, rthread, tmp); 3757 __ cbnzw(rscratch1, retry_load); 3758 __ bind(fail); 3759 } 3760 3761 // Label next; 3762 // __ cmpxchgptr(/*oldv=*/disp_hdr, 3763 // /*newv=*/rthread, 3764 // /*addr=*/tmp, 3765 // /*tmp=*/rscratch1, 3766 // /*succeed*/next, 3767 // /*fail*/NULL); 3768 // __ bind(next); 3769 3770 // store a non-null value into the box. 3771 __ str(box, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3772 3773 // PPC port checks the following invariants 3774 // #ifdef ASSERT 3775 // bne(flag, cont); 3776 // We have acquired the monitor, check some invariants. 3777 // addw(/*monitor=*/tmp, tmp, -ObjectMonitor::owner_offset_in_bytes()); 3778 // Invariant 1: _recursions should be 0. 3779 // assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size"); 3780 // assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), tmp, 3781 // "monitor->_recursions should be 0", -1); 3782 // Invariant 2: OwnerIsThread shouldn't be 0. 3783 // assert(ObjectMonitor::OwnerIsThread_size_in_bytes() == 4, "unexpected size"); 3784 //assert_mem4_isnot_zero(ObjectMonitor::OwnerIsThread_offset_in_bytes(), tmp, 3785 // "monitor->OwnerIsThread shouldn't be 0", -1); 3786 // #endif 3787 } 3788 3789 __ bind(cont); 3790 // flag == EQ indicates success 3791 // flag == NE indicates failure 3792 3793 %} 3794 3795 // TODO 3796 // reimplement this with custom cmpxchgptr code 3797 // which avoids some of the unnecessary branching 3798 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3799 MacroAssembler _masm(&cbuf); 3800 Register oop = as_Register($object$$reg); 3801 Register box = as_Register($box$$reg); 3802 Register disp_hdr = as_Register($tmp$$reg); 3803 Register tmp = as_Register($tmp2$$reg); 3804 Label cont; 3805 Label object_has_monitor; 3806 Label cas_failed; 3807 3808 assert_different_registers(oop, box, tmp, disp_hdr); 3809 3810 // Always do locking in runtime. 3811 if (EmitSync & 0x01) { 3812 __ cmp(oop, zr); // Oop can't be 0 here => always false. 3813 return; 3814 } 3815 3816 if (UseBiasedLocking) { 3817 __ biased_locking_exit(oop, tmp, cont); 3818 } 3819 3820 // Find the lock address and load the displaced header from the stack. 3821 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3822 3823 // If the displaced header is 0, we have a recursive unlock. 3824 __ cmp(disp_hdr, zr); 3825 __ br(Assembler::EQ, cont); 3826 3827 3828 // Handle existing monitor. 3829 if ((EmitSync & 0x02) == 0) { 3830 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3831 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3832 } 3833 3834 // Check if it is still a light weight lock, this is is true if we 3835 // see the stack address of the basicLock in the markOop of the 3836 // object. 3837 3838 { 3839 Label retry_load; 3840 __ bind(retry_load); 3841 __ ldxr(tmp, oop); 3842 __ cmp(box, tmp); 3843 __ br(Assembler::NE, cas_failed); 3844 // use stlxr to ensure update is immediately visible 3845 __ stlxr(tmp, disp_hdr, oop); 3846 __ cbzw(tmp, cont); 3847 __ b(retry_load); 3848 } 3849 3850 // __ cmpxchgptr(/*compare_value=*/box, 3851 // /*exchange_value=*/disp_hdr, 3852 // /*where=*/oop, 3853 // /*result=*/tmp, 3854 // cont, 3855 // /*cas_failed*/NULL); 3856 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3857 3858 __ bind(cas_failed); 3859 3860 // Handle existing monitor. 3861 if ((EmitSync & 0x02) == 0) { 3862 __ b(cont); 3863 3864 __ bind(object_has_monitor); 3865 __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor 3866 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3867 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3868 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3869 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3870 __ cmp(rscratch1, zr); 3871 __ br(Assembler::NE, cont); 3872 3873 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3874 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3875 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3876 __ cmp(rscratch1, zr); 3877 __ cbnz(rscratch1, cont); 3878 // need a release store here 3879 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3880 __ stlr(rscratch1, tmp); // rscratch1 is zero 3881 } 3882 3883 __ bind(cont); 3884 // flag == EQ indicates success 3885 // flag == NE indicates failure 3886 %} 3887 3888 %} 3889 3890 //----------FRAME-------------------------------------------------------------- 3891 // Definition of frame structure and management information. 3892 // 3893 // S T A C K L A Y O U T Allocators stack-slot number 3894 // | (to get allocators register number 3895 // G Owned by | | v add OptoReg::stack0()) 3896 // r CALLER | | 3897 // o | +--------+ pad to even-align allocators stack-slot 3898 // w V | pad0 | numbers; owned by CALLER 3899 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3900 // h ^ | in | 5 3901 // | | args | 4 Holes in incoming args owned by SELF 3902 // | | | | 3 3903 // | | +--------+ 3904 // V | | old out| Empty on Intel, window on Sparc 3905 // | old |preserve| Must be even aligned. 3906 // | SP-+--------+----> Matcher::_old_SP, even aligned 3907 // | | in | 3 area for Intel ret address 3908 // Owned by |preserve| Empty on Sparc. 3909 // SELF +--------+ 3910 // | | pad2 | 2 pad to align old SP 3911 // | +--------+ 1 3912 // | | locks | 0 3913 // | +--------+----> OptoReg::stack0(), even aligned 3914 // | | pad1 | 11 pad to align new SP 3915 // | +--------+ 3916 // | | | 10 3917 // | | spills | 9 spills 3918 // V | | 8 (pad0 slot for callee) 3919 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3920 // ^ | out | 7 3921 // | | args | 6 Holes in outgoing args owned by CALLEE 3922 // Owned by +--------+ 3923 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3924 // | new |preserve| Must be even-aligned. 3925 // | SP-+--------+----> Matcher::_new_SP, even aligned 3926 // | | | 3927 // 3928 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3929 // known from SELF's arguments and the Java calling convention. 3930 // Region 6-7 is determined per call site. 3931 // Note 2: If the calling convention leaves holes in the incoming argument 3932 // area, those holes are owned by SELF. Holes in the outgoing area 3933 // are owned by the CALLEE. Holes should not be nessecary in the 3934 // incoming area, as the Java calling convention is completely under 3935 // the control of the AD file. Doubles can be sorted and packed to 3936 // avoid holes. Holes in the outgoing arguments may be nessecary for 3937 // varargs C calling conventions. 3938 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3939 // even aligned with pad0 as needed. 3940 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3941 // (the latter is true on Intel but is it false on AArch64?) 3942 // region 6-11 is even aligned; it may be padded out more so that 3943 // the region from SP to FP meets the minimum stack alignment. 3944 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3945 // alignment. Region 11, pad1, may be dynamically extended so that 3946 // SP meets the minimum alignment. 3947 3948 frame %{ 3949 // What direction does stack grow in (assumed to be same for C & Java) 3950 stack_direction(TOWARDS_LOW); 3951 3952 // These three registers define part of the calling convention 3953 // between compiled code and the interpreter. 3954 3955 // Inline Cache Register or methodOop for I2C. 3956 inline_cache_reg(R12); 3957 3958 // Method Oop Register when calling interpreter. 3959 interpreter_method_oop_reg(R12); 3960 3961 // Number of stack slots consumed by locking an object 3962 sync_stack_slots(2); 3963 3964 // Compiled code's Frame Pointer 3965 frame_pointer(R31); 3966 3967 // Interpreter stores its frame pointer in a register which is 3968 // stored to the stack by I2CAdaptors. 3969 // I2CAdaptors convert from interpreted java to compiled java. 3970 interpreter_frame_pointer(R29); 3971 3972 // Stack alignment requirement 3973 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3974 3975 // Number of stack slots between incoming argument block and the start of 3976 // a new frame. The PROLOG must add this many slots to the stack. The 3977 // EPILOG must remove this many slots. aarch64 needs two slots for 3978 // return address and fp. 3979 // TODO think this is correct but check 3980 in_preserve_stack_slots(4); 3981 3982 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3983 // for calls to C. Supports the var-args backing area for register parms. 3984 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3985 3986 // The after-PROLOG location of the return address. Location of 3987 // return address specifies a type (REG or STACK) and a number 3988 // representing the register number (i.e. - use a register name) or 3989 // stack slot. 3990 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3991 // Otherwise, it is above the locks and verification slot and alignment word 3992 // TODO this may well be correct but need to check why that - 2 is there 3993 // ppc port uses 0 but we definitely need to allow for fixed_slots 3994 // which folds in the space used for monitors 3995 return_addr(STACK - 2 + 3996 round_to((Compile::current()->in_preserve_stack_slots() + 3997 Compile::current()->fixed_slots()), 3998 stack_alignment_in_slots())); 3999 4000 // Body of function which returns an integer array locating 4001 // arguments either in registers or in stack slots. Passed an array 4002 // of ideal registers called "sig" and a "length" count. Stack-slot 4003 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4004 // arguments for a CALLEE. Incoming stack arguments are 4005 // automatically biased by the preserve_stack_slots field above. 4006 4007 calling_convention 4008 %{ 4009 // No difference between ingoing/outgoing just pass false 4010 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4011 %} 4012 4013 c_calling_convention 4014 %{ 4015 // This is obviously always outgoing 4016 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 4017 %} 4018 4019 // Location of compiled Java return values. Same as C for now. 4020 return_value 4021 %{ 4022 // TODO do we allow ideal_reg == Op_RegN??? 4023 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 4024 "only return normal values"); 4025 4026 static const int lo[Op_RegL + 1] = { // enum name 4027 0, // Op_Node 4028 0, // Op_Set 4029 R0_num, // Op_RegN 4030 R0_num, // Op_RegI 4031 R0_num, // Op_RegP 4032 V0_num, // Op_RegF 4033 V0_num, // Op_RegD 4034 R0_num // Op_RegL 4035 }; 4036 4037 static const int hi[Op_RegL + 1] = { // enum name 4038 0, // Op_Node 4039 0, // Op_Set 4040 OptoReg::Bad, // Op_RegN 4041 OptoReg::Bad, // Op_RegI 4042 R0_H_num, // Op_RegP 4043 OptoReg::Bad, // Op_RegF 4044 V0_H_num, // Op_RegD 4045 R0_H_num // Op_RegL 4046 }; 4047 4048 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 4049 %} 4050 %} 4051 4052 //----------ATTRIBUTES--------------------------------------------------------- 4053 //----------Operand Attributes------------------------------------------------- 4054 op_attrib op_cost(1); // Required cost attribute 4055 4056 //----------Instruction Attributes--------------------------------------------- 4057 ins_attrib ins_cost(INSN_COST); // Required cost attribute 4058 ins_attrib ins_size(32); // Required size attribute (in bits) 4059 ins_attrib ins_short_branch(0); // Required flag: is this instruction 4060 // a non-matching short branch variant 4061 // of some long branch? 4062 ins_attrib ins_alignment(4); // Required alignment attribute (must 4063 // be a power of 2) specifies the 4064 // alignment that some part of the 4065 // instruction (not necessarily the 4066 // start) requires. If > 1, a 4067 // compute_padding() function must be 4068 // provided for the instruction 4069 4070 //----------OPERANDS----------------------------------------------------------- 4071 // Operand definitions must precede instruction definitions for correct parsing 4072 // in the ADLC because operands constitute user defined types which are used in 4073 // instruction definitions. 4074 4075 //----------Simple Operands---------------------------------------------------- 4076 4077 // Integer operands 32 bit 4078 // 32 bit immediate 4079 operand immI() 4080 %{ 4081 match(ConI); 4082 4083 op_cost(0); 4084 format %{ %} 4085 interface(CONST_INTER); 4086 %} 4087 4088 // 32 bit zero 4089 operand immI0() 4090 %{ 4091 predicate(n->get_int() == 0); 4092 match(ConI); 4093 4094 op_cost(0); 4095 format %{ %} 4096 interface(CONST_INTER); 4097 %} 4098 4099 // 32 bit unit increment 4100 operand immI_1() 4101 %{ 4102 predicate(n->get_int() == 1); 4103 match(ConI); 4104 4105 op_cost(0); 4106 format %{ %} 4107 interface(CONST_INTER); 4108 %} 4109 4110 // 32 bit unit decrement 4111 operand immI_M1() 4112 %{ 4113 predicate(n->get_int() == -1); 4114 match(ConI); 4115 4116 op_cost(0); 4117 format %{ %} 4118 interface(CONST_INTER); 4119 %} 4120 4121 operand immI_le_4() 4122 %{ 4123 predicate(n->get_int() <= 4); 4124 match(ConI); 4125 4126 op_cost(0); 4127 format %{ %} 4128 interface(CONST_INTER); 4129 %} 4130 4131 operand immI_31() 4132 %{ 4133 predicate(n->get_int() == 31); 4134 match(ConI); 4135 4136 op_cost(0); 4137 format %{ %} 4138 interface(CONST_INTER); 4139 %} 4140 4141 operand immI_8() 4142 %{ 4143 predicate(n->get_int() == 8); 4144 match(ConI); 4145 4146 op_cost(0); 4147 format %{ %} 4148 interface(CONST_INTER); 4149 %} 4150 4151 operand immI_16() 4152 %{ 4153 predicate(n->get_int() == 16); 4154 match(ConI); 4155 4156 op_cost(0); 4157 format %{ %} 4158 interface(CONST_INTER); 4159 %} 4160 4161 operand immI_24() 4162 %{ 4163 predicate(n->get_int() == 24); 4164 match(ConI); 4165 4166 op_cost(0); 4167 format %{ %} 4168 interface(CONST_INTER); 4169 %} 4170 4171 operand immI_32() 4172 %{ 4173 predicate(n->get_int() == 32); 4174 match(ConI); 4175 4176 op_cost(0); 4177 format %{ %} 4178 interface(CONST_INTER); 4179 %} 4180 4181 operand immI_48() 4182 %{ 4183 predicate(n->get_int() == 48); 4184 match(ConI); 4185 4186 op_cost(0); 4187 format %{ %} 4188 interface(CONST_INTER); 4189 %} 4190 4191 operand immI_56() 4192 %{ 4193 predicate(n->get_int() == 56); 4194 match(ConI); 4195 4196 op_cost(0); 4197 format %{ %} 4198 interface(CONST_INTER); 4199 %} 4200 4201 operand immI_64() 4202 %{ 4203 predicate(n->get_int() == 64); 4204 match(ConI); 4205 4206 op_cost(0); 4207 format %{ %} 4208 interface(CONST_INTER); 4209 %} 4210 4211 operand immI_255() 4212 %{ 4213 predicate(n->get_int() == 255); 4214 match(ConI); 4215 4216 op_cost(0); 4217 format %{ %} 4218 interface(CONST_INTER); 4219 %} 4220 4221 operand immI_65535() 4222 %{ 4223 predicate(n->get_int() == 65535); 4224 match(ConI); 4225 4226 op_cost(0); 4227 format %{ %} 4228 interface(CONST_INTER); 4229 %} 4230 4231 operand immL_63() 4232 %{ 4233 predicate(n->get_int() == 63); 4234 match(ConI); 4235 4236 op_cost(0); 4237 format %{ %} 4238 interface(CONST_INTER); 4239 %} 4240 4241 operand immL_255() 4242 %{ 4243 predicate(n->get_int() == 255); 4244 match(ConI); 4245 4246 op_cost(0); 4247 format %{ %} 4248 interface(CONST_INTER); 4249 %} 4250 4251 operand immL_65535() 4252 %{ 4253 predicate(n->get_long() == 65535L); 4254 match(ConL); 4255 4256 op_cost(0); 4257 format %{ %} 4258 interface(CONST_INTER); 4259 %} 4260 4261 operand immL_4294967295() 4262 %{ 4263 predicate(n->get_long() == 4294967295L); 4264 match(ConL); 4265 4266 op_cost(0); 4267 format %{ %} 4268 interface(CONST_INTER); 4269 %} 4270 4271 operand immL_bitmask() 4272 %{ 4273 predicate(((n->get_long() & 0xc000000000000000l) == 0) 4274 && is_power_of_2(n->get_long() + 1)); 4275 match(ConL); 4276 4277 op_cost(0); 4278 format %{ %} 4279 interface(CONST_INTER); 4280 %} 4281 4282 operand immI_bitmask() 4283 %{ 4284 predicate(((n->get_int() & 0xc0000000) == 0) 4285 && is_power_of_2(n->get_int() + 1)); 4286 match(ConI); 4287 4288 op_cost(0); 4289 format %{ %} 4290 interface(CONST_INTER); 4291 %} 4292 4293 // Scale values for scaled offset addressing modes (up to long but not quad) 4294 operand immIScale() 4295 %{ 4296 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4297 match(ConI); 4298 4299 op_cost(0); 4300 format %{ %} 4301 interface(CONST_INTER); 4302 %} 4303 4304 // 26 bit signed offset -- for pc-relative branches 4305 operand immI26() 4306 %{ 4307 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4308 match(ConI); 4309 4310 op_cost(0); 4311 format %{ %} 4312 interface(CONST_INTER); 4313 %} 4314 4315 // 19 bit signed offset -- for pc-relative loads 4316 operand immI19() 4317 %{ 4318 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4319 match(ConI); 4320 4321 op_cost(0); 4322 format %{ %} 4323 interface(CONST_INTER); 4324 %} 4325 4326 // 12 bit unsigned offset -- for base plus immediate loads 4327 operand immIU12() 4328 %{ 4329 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4330 match(ConI); 4331 4332 op_cost(0); 4333 format %{ %} 4334 interface(CONST_INTER); 4335 %} 4336 4337 operand immLU12() 4338 %{ 4339 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4340 match(ConL); 4341 4342 op_cost(0); 4343 format %{ %} 4344 interface(CONST_INTER); 4345 %} 4346 4347 // Offset for scaled or unscaled immediate loads and stores 4348 operand immIOffset() 4349 %{ 4350 predicate(Address::offset_ok_for_immed(n->get_int())); 4351 match(ConI); 4352 4353 op_cost(0); 4354 format %{ %} 4355 interface(CONST_INTER); 4356 %} 4357 4358 operand immLoffset() 4359 %{ 4360 predicate(Address::offset_ok_for_immed(n->get_long())); 4361 match(ConL); 4362 4363 op_cost(0); 4364 format %{ %} 4365 interface(CONST_INTER); 4366 %} 4367 4368 // 32 bit integer valid for add sub immediate 4369 operand immIAddSub() 4370 %{ 4371 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4372 match(ConI); 4373 op_cost(0); 4374 format %{ %} 4375 interface(CONST_INTER); 4376 %} 4377 4378 // 32 bit unsigned integer valid for logical immediate 4379 // TODO -- check this is right when e.g the mask is 0x80000000 4380 operand immILog() 4381 %{ 4382 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4383 match(ConI); 4384 4385 op_cost(0); 4386 format %{ %} 4387 interface(CONST_INTER); 4388 %} 4389 4390 // Integer operands 64 bit 4391 // 64 bit immediate 4392 operand immL() 4393 %{ 4394 match(ConL); 4395 4396 op_cost(0); 4397 format %{ %} 4398 interface(CONST_INTER); 4399 %} 4400 4401 // 64 bit zero 4402 operand immL0() 4403 %{ 4404 predicate(n->get_long() == 0); 4405 match(ConL); 4406 4407 op_cost(0); 4408 format %{ %} 4409 interface(CONST_INTER); 4410 %} 4411 4412 // 64 bit unit increment 4413 operand immL_1() 4414 %{ 4415 predicate(n->get_long() == 1); 4416 match(ConL); 4417 4418 op_cost(0); 4419 format %{ %} 4420 interface(CONST_INTER); 4421 %} 4422 4423 // 64 bit unit decrement 4424 operand immL_M1() 4425 %{ 4426 predicate(n->get_long() == -1); 4427 match(ConL); 4428 4429 op_cost(0); 4430 format %{ %} 4431 interface(CONST_INTER); 4432 %} 4433 4434 // 32 bit offset of pc in thread anchor 4435 4436 operand immL_pc_off() 4437 %{ 4438 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4439 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4440 match(ConL); 4441 4442 op_cost(0); 4443 format %{ %} 4444 interface(CONST_INTER); 4445 %} 4446 4447 // 64 bit integer valid for add sub immediate 4448 operand immLAddSub() 4449 %{ 4450 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4451 match(ConL); 4452 op_cost(0); 4453 format %{ %} 4454 interface(CONST_INTER); 4455 %} 4456 4457 // 64 bit integer valid for logical immediate 4458 operand immLLog() 4459 %{ 4460 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4461 match(ConL); 4462 op_cost(0); 4463 format %{ %} 4464 interface(CONST_INTER); 4465 %} 4466 4467 // Long Immediate: low 32-bit mask 4468 operand immL_32bits() 4469 %{ 4470 predicate(n->get_long() == 0xFFFFFFFFL); 4471 match(ConL); 4472 op_cost(0); 4473 format %{ %} 4474 interface(CONST_INTER); 4475 %} 4476 4477 // Pointer operands 4478 // Pointer Immediate 4479 operand immP() 4480 %{ 4481 match(ConP); 4482 4483 op_cost(0); 4484 format %{ %} 4485 interface(CONST_INTER); 4486 %} 4487 4488 // NULL Pointer Immediate 4489 operand immP0() 4490 %{ 4491 predicate(n->get_ptr() == 0); 4492 match(ConP); 4493 4494 op_cost(0); 4495 format %{ %} 4496 interface(CONST_INTER); 4497 %} 4498 4499 // Pointer Immediate One 4500 // this is used in object initialization (initial object header) 4501 operand immP_1() 4502 %{ 4503 predicate(n->get_ptr() == 1); 4504 match(ConP); 4505 4506 op_cost(0); 4507 format %{ %} 4508 interface(CONST_INTER); 4509 %} 4510 4511 // Polling Page Pointer Immediate 4512 operand immPollPage() 4513 %{ 4514 predicate((address)n->get_ptr() == os::get_polling_page()); 4515 match(ConP); 4516 4517 op_cost(0); 4518 format %{ %} 4519 interface(CONST_INTER); 4520 %} 4521 4522 // Card Table Byte Map Base 4523 operand immByteMapBase() 4524 %{ 4525 // Get base of card map 4526 predicate((jbyte*)n->get_ptr() == 4527 ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base); 4528 match(ConP); 4529 4530 op_cost(0); 4531 format %{ %} 4532 interface(CONST_INTER); 4533 %} 4534 4535 // Pointer Immediate Minus One 4536 // this is used when we want to write the current PC to the thread anchor 4537 operand immP_M1() 4538 %{ 4539 predicate(n->get_ptr() == -1); 4540 match(ConP); 4541 4542 op_cost(0); 4543 format %{ %} 4544 interface(CONST_INTER); 4545 %} 4546 4547 // Pointer Immediate Minus Two 4548 // this is used when we want to write the current PC to the thread anchor 4549 operand immP_M2() 4550 %{ 4551 predicate(n->get_ptr() == -2); 4552 match(ConP); 4553 4554 op_cost(0); 4555 format %{ %} 4556 interface(CONST_INTER); 4557 %} 4558 4559 // Float and Double operands 4560 // Double Immediate 4561 operand immD() 4562 %{ 4563 match(ConD); 4564 op_cost(0); 4565 format %{ %} 4566 interface(CONST_INTER); 4567 %} 4568 4569 // Double Immediate: +0.0d 4570 operand immD0() 4571 %{ 4572 predicate(jlong_cast(n->getd()) == 0); 4573 match(ConD); 4574 4575 op_cost(0); 4576 format %{ %} 4577 interface(CONST_INTER); 4578 %} 4579 4580 // constant 'double +0.0'. 4581 operand immDPacked() 4582 %{ 4583 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4584 match(ConD); 4585 op_cost(0); 4586 format %{ %} 4587 interface(CONST_INTER); 4588 %} 4589 4590 // Float Immediate 4591 operand immF() 4592 %{ 4593 match(ConF); 4594 op_cost(0); 4595 format %{ %} 4596 interface(CONST_INTER); 4597 %} 4598 4599 // Float Immediate: +0.0f. 4600 operand immF0() 4601 %{ 4602 predicate(jint_cast(n->getf()) == 0); 4603 match(ConF); 4604 4605 op_cost(0); 4606 format %{ %} 4607 interface(CONST_INTER); 4608 %} 4609 4610 // 4611 operand immFPacked() 4612 %{ 4613 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4614 match(ConF); 4615 op_cost(0); 4616 format %{ %} 4617 interface(CONST_INTER); 4618 %} 4619 4620 // Narrow pointer operands 4621 // Narrow Pointer Immediate 4622 operand immN() 4623 %{ 4624 match(ConN); 4625 4626 op_cost(0); 4627 format %{ %} 4628 interface(CONST_INTER); 4629 %} 4630 4631 // Narrow NULL Pointer Immediate 4632 operand immN0() 4633 %{ 4634 predicate(n->get_narrowcon() == 0); 4635 match(ConN); 4636 4637 op_cost(0); 4638 format %{ %} 4639 interface(CONST_INTER); 4640 %} 4641 4642 operand immNKlass() 4643 %{ 4644 match(ConNKlass); 4645 4646 op_cost(0); 4647 format %{ %} 4648 interface(CONST_INTER); 4649 %} 4650 4651 // Integer 32 bit Register Operands 4652 // Integer 32 bitRegister (excludes SP) 4653 operand iRegI() 4654 %{ 4655 constraint(ALLOC_IN_RC(any_reg32)); 4656 match(RegI); 4657 match(iRegINoSp); 4658 op_cost(0); 4659 format %{ %} 4660 interface(REG_INTER); 4661 %} 4662 4663 // Integer 32 bit Register not Special 4664 operand iRegINoSp() 4665 %{ 4666 constraint(ALLOC_IN_RC(no_special_reg32)); 4667 match(RegI); 4668 op_cost(0); 4669 format %{ %} 4670 interface(REG_INTER); 4671 %} 4672 4673 // Integer 64 bit Register Operands 4674 // Integer 64 bit Register (includes SP) 4675 operand iRegL() 4676 %{ 4677 constraint(ALLOC_IN_RC(any_reg)); 4678 match(RegL); 4679 match(iRegLNoSp); 4680 op_cost(0); 4681 format %{ %} 4682 interface(REG_INTER); 4683 %} 4684 4685 // Integer 64 bit Register not Special 4686 operand iRegLNoSp() 4687 %{ 4688 constraint(ALLOC_IN_RC(no_special_reg)); 4689 match(RegL); 4690 format %{ %} 4691 interface(REG_INTER); 4692 %} 4693 4694 // Pointer Register Operands 4695 // Pointer Register 4696 operand iRegP() 4697 %{ 4698 constraint(ALLOC_IN_RC(ptr_reg)); 4699 match(RegP); 4700 match(iRegPNoSp); 4701 match(iRegP_R0); 4702 //match(iRegP_R2); 4703 //match(iRegP_R4); 4704 //match(iRegP_R5); 4705 match(thread_RegP); 4706 op_cost(0); 4707 format %{ %} 4708 interface(REG_INTER); 4709 %} 4710 4711 // Pointer 64 bit Register not Special 4712 operand iRegPNoSp() 4713 %{ 4714 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4715 match(RegP); 4716 // match(iRegP); 4717 // match(iRegP_R0); 4718 // match(iRegP_R2); 4719 // match(iRegP_R4); 4720 // match(iRegP_R5); 4721 // match(thread_RegP); 4722 op_cost(0); 4723 format %{ %} 4724 interface(REG_INTER); 4725 %} 4726 4727 // Pointer 64 bit Register R0 only 4728 operand iRegP_R0() 4729 %{ 4730 constraint(ALLOC_IN_RC(r0_reg)); 4731 match(RegP); 4732 // match(iRegP); 4733 match(iRegPNoSp); 4734 op_cost(0); 4735 format %{ %} 4736 interface(REG_INTER); 4737 %} 4738 4739 // Pointer 64 bit Register R1 only 4740 operand iRegP_R1() 4741 %{ 4742 constraint(ALLOC_IN_RC(r1_reg)); 4743 match(RegP); 4744 // match(iRegP); 4745 match(iRegPNoSp); 4746 op_cost(0); 4747 format %{ %} 4748 interface(REG_INTER); 4749 %} 4750 4751 // Pointer 64 bit Register R2 only 4752 operand iRegP_R2() 4753 %{ 4754 constraint(ALLOC_IN_RC(r2_reg)); 4755 match(RegP); 4756 // match(iRegP); 4757 match(iRegPNoSp); 4758 op_cost(0); 4759 format %{ %} 4760 interface(REG_INTER); 4761 %} 4762 4763 // Pointer 64 bit Register R3 only 4764 operand iRegP_R3() 4765 %{ 4766 constraint(ALLOC_IN_RC(r3_reg)); 4767 match(RegP); 4768 // match(iRegP); 4769 match(iRegPNoSp); 4770 op_cost(0); 4771 format %{ %} 4772 interface(REG_INTER); 4773 %} 4774 4775 // Pointer 64 bit Register R4 only 4776 operand iRegP_R4() 4777 %{ 4778 constraint(ALLOC_IN_RC(r4_reg)); 4779 match(RegP); 4780 // match(iRegP); 4781 match(iRegPNoSp); 4782 op_cost(0); 4783 format %{ %} 4784 interface(REG_INTER); 4785 %} 4786 4787 // Pointer 64 bit Register R5 only 4788 operand iRegP_R5() 4789 %{ 4790 constraint(ALLOC_IN_RC(r5_reg)); 4791 match(RegP); 4792 // match(iRegP); 4793 match(iRegPNoSp); 4794 op_cost(0); 4795 format %{ %} 4796 interface(REG_INTER); 4797 %} 4798 4799 // Pointer 64 bit Register R10 only 4800 operand iRegP_R10() 4801 %{ 4802 constraint(ALLOC_IN_RC(r10_reg)); 4803 match(RegP); 4804 // match(iRegP); 4805 match(iRegPNoSp); 4806 op_cost(0); 4807 format %{ %} 4808 interface(REG_INTER); 4809 %} 4810 4811 // Long 64 bit Register R11 only 4812 operand iRegL_R11() 4813 %{ 4814 constraint(ALLOC_IN_RC(r11_reg)); 4815 match(RegL); 4816 match(iRegLNoSp); 4817 op_cost(0); 4818 format %{ %} 4819 interface(REG_INTER); 4820 %} 4821 4822 // Pointer 64 bit Register FP only 4823 operand iRegP_FP() 4824 %{ 4825 constraint(ALLOC_IN_RC(fp_reg)); 4826 match(RegP); 4827 // match(iRegP); 4828 op_cost(0); 4829 format %{ %} 4830 interface(REG_INTER); 4831 %} 4832 4833 // Register R0 only 4834 operand iRegI_R0() 4835 %{ 4836 constraint(ALLOC_IN_RC(int_r0_reg)); 4837 match(RegI); 4838 match(iRegINoSp); 4839 op_cost(0); 4840 format %{ %} 4841 interface(REG_INTER); 4842 %} 4843 4844 // Register R2 only 4845 operand iRegI_R2() 4846 %{ 4847 constraint(ALLOC_IN_RC(int_r2_reg)); 4848 match(RegI); 4849 match(iRegINoSp); 4850 op_cost(0); 4851 format %{ %} 4852 interface(REG_INTER); 4853 %} 4854 4855 // Register R3 only 4856 operand iRegI_R3() 4857 %{ 4858 constraint(ALLOC_IN_RC(int_r3_reg)); 4859 match(RegI); 4860 match(iRegINoSp); 4861 op_cost(0); 4862 format %{ %} 4863 interface(REG_INTER); 4864 %} 4865 4866 4867 // Register R2 only 4868 operand iRegI_R4() 4869 %{ 4870 constraint(ALLOC_IN_RC(int_r4_reg)); 4871 match(RegI); 4872 match(iRegINoSp); 4873 op_cost(0); 4874 format %{ %} 4875 interface(REG_INTER); 4876 %} 4877 4878 4879 // Pointer Register Operands 4880 // Narrow Pointer Register 4881 operand iRegN() 4882 %{ 4883 constraint(ALLOC_IN_RC(any_reg32)); 4884 match(RegN); 4885 match(iRegNNoSp); 4886 op_cost(0); 4887 format %{ %} 4888 interface(REG_INTER); 4889 %} 4890 4891 // Integer 64 bit Register not Special 4892 operand iRegNNoSp() 4893 %{ 4894 constraint(ALLOC_IN_RC(no_special_reg32)); 4895 match(RegN); 4896 op_cost(0); 4897 format %{ %} 4898 interface(REG_INTER); 4899 %} 4900 4901 // heap base register -- used for encoding immN0 4902 4903 operand iRegIHeapbase() 4904 %{ 4905 constraint(ALLOC_IN_RC(heapbase_reg)); 4906 match(RegI); 4907 op_cost(0); 4908 format %{ %} 4909 interface(REG_INTER); 4910 %} 4911 4912 // Float Register 4913 // Float register operands 4914 operand vRegF() 4915 %{ 4916 constraint(ALLOC_IN_RC(float_reg)); 4917 match(RegF); 4918 4919 op_cost(0); 4920 format %{ %} 4921 interface(REG_INTER); 4922 %} 4923 4924 // Double Register 4925 // Double register operands 4926 operand vRegD() 4927 %{ 4928 constraint(ALLOC_IN_RC(double_reg)); 4929 match(RegD); 4930 4931 op_cost(0); 4932 format %{ %} 4933 interface(REG_INTER); 4934 %} 4935 4936 operand vRegD_V0() 4937 %{ 4938 constraint(ALLOC_IN_RC(v0_reg)); 4939 match(RegD); 4940 op_cost(0); 4941 format %{ %} 4942 interface(REG_INTER); 4943 %} 4944 4945 operand vRegD_V1() 4946 %{ 4947 constraint(ALLOC_IN_RC(v1_reg)); 4948 match(RegD); 4949 op_cost(0); 4950 format %{ %} 4951 interface(REG_INTER); 4952 %} 4953 4954 operand vRegD_V2() 4955 %{ 4956 constraint(ALLOC_IN_RC(v2_reg)); 4957 match(RegD); 4958 op_cost(0); 4959 format %{ %} 4960 interface(REG_INTER); 4961 %} 4962 4963 operand vRegD_V3() 4964 %{ 4965 constraint(ALLOC_IN_RC(v3_reg)); 4966 match(RegD); 4967 op_cost(0); 4968 format %{ %} 4969 interface(REG_INTER); 4970 %} 4971 4972 // Flags register, used as output of signed compare instructions 4973 4974 // note that on AArch64 we also use this register as the output for 4975 // for floating point compare instructions (CmpF CmpD). this ensures 4976 // that ordered inequality tests use GT, GE, LT or LE none of which 4977 // pass through cases where the result is unordered i.e. one or both 4978 // inputs to the compare is a NaN. this means that the ideal code can 4979 // replace e.g. a GT with an LE and not end up capturing the NaN case 4980 // (where the comparison should always fail). EQ and NE tests are 4981 // always generated in ideal code so that unordered folds into the NE 4982 // case, matching the behaviour of AArch64 NE. 4983 // 4984 // This differs from x86 where the outputs of FP compares use a 4985 // special FP flags registers and where compares based on this 4986 // register are distinguished into ordered inequalities (cmpOpUCF) and 4987 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 4988 // to explicitly handle the unordered case in branches. x86 also has 4989 // to include extra CMoveX rules to accept a cmpOpUCF input. 4990 4991 operand rFlagsReg() 4992 %{ 4993 constraint(ALLOC_IN_RC(int_flags)); 4994 match(RegFlags); 4995 4996 op_cost(0); 4997 format %{ "RFLAGS" %} 4998 interface(REG_INTER); 4999 %} 5000 5001 // Flags register, used as output of unsigned compare instructions 5002 operand rFlagsRegU() 5003 %{ 5004 constraint(ALLOC_IN_RC(int_flags)); 5005 match(RegFlags); 5006 5007 op_cost(0); 5008 format %{ "RFLAGSU" %} 5009 interface(REG_INTER); 5010 %} 5011 5012 // Special Registers 5013 5014 // Method Register 5015 operand inline_cache_RegP(iRegP reg) 5016 %{ 5017 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5018 match(reg); 5019 match(iRegPNoSp); 5020 op_cost(0); 5021 format %{ %} 5022 interface(REG_INTER); 5023 %} 5024 5025 operand interpreter_method_oop_RegP(iRegP reg) 5026 %{ 5027 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 5028 match(reg); 5029 match(iRegPNoSp); 5030 op_cost(0); 5031 format %{ %} 5032 interface(REG_INTER); 5033 %} 5034 5035 // Thread Register 5036 operand thread_RegP(iRegP reg) 5037 %{ 5038 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5039 match(reg); 5040 op_cost(0); 5041 format %{ %} 5042 interface(REG_INTER); 5043 %} 5044 5045 operand lr_RegP(iRegP reg) 5046 %{ 5047 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5048 match(reg); 5049 op_cost(0); 5050 format %{ %} 5051 interface(REG_INTER); 5052 %} 5053 5054 //----------Memory Operands---------------------------------------------------- 5055 5056 operand indirect(iRegP reg) 5057 %{ 5058 constraint(ALLOC_IN_RC(ptr_reg)); 5059 match(reg); 5060 op_cost(0); 5061 format %{ "[$reg]" %} 5062 interface(MEMORY_INTER) %{ 5063 base($reg); 5064 index(0xffffffff); 5065 scale(0x0); 5066 disp(0x0); 5067 %} 5068 %} 5069 5070 operand indIndexScaledOffsetI(iRegP reg, iRegL lreg, immIScale scale, immIU12 off) 5071 %{ 5072 constraint(ALLOC_IN_RC(ptr_reg)); 5073 match(AddP (AddP reg (LShiftL lreg scale)) off); 5074 op_cost(INSN_COST); 5075 format %{ "$reg, $lreg lsl($scale), $off" %} 5076 interface(MEMORY_INTER) %{ 5077 base($reg); 5078 index($lreg); 5079 scale($scale); 5080 disp($off); 5081 %} 5082 %} 5083 5084 operand indIndexScaledOffsetL(iRegP reg, iRegL lreg, immIScale scale, immLU12 off) 5085 %{ 5086 constraint(ALLOC_IN_RC(ptr_reg)); 5087 match(AddP (AddP reg (LShiftL lreg scale)) off); 5088 op_cost(INSN_COST); 5089 format %{ "$reg, $lreg lsl($scale), $off" %} 5090 interface(MEMORY_INTER) %{ 5091 base($reg); 5092 index($lreg); 5093 scale($scale); 5094 disp($off); 5095 %} 5096 %} 5097 5098 operand indIndexOffsetI2L(iRegP reg, iRegI ireg, immLU12 off) 5099 %{ 5100 constraint(ALLOC_IN_RC(ptr_reg)); 5101 match(AddP (AddP reg (ConvI2L ireg)) off); 5102 op_cost(INSN_COST); 5103 format %{ "$reg, $ireg, $off I2L" %} 5104 interface(MEMORY_INTER) %{ 5105 base($reg); 5106 index($ireg); 5107 scale(0x0); 5108 disp($off); 5109 %} 5110 %} 5111 5112 operand indIndexScaledOffsetI2L(iRegP reg, iRegI ireg, immIScale scale, immLU12 off) 5113 %{ 5114 constraint(ALLOC_IN_RC(ptr_reg)); 5115 match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off); 5116 op_cost(INSN_COST); 5117 format %{ "$reg, $ireg sxtw($scale), $off I2L" %} 5118 interface(MEMORY_INTER) %{ 5119 base($reg); 5120 index($ireg); 5121 scale($scale); 5122 disp($off); 5123 %} 5124 %} 5125 5126 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5127 %{ 5128 constraint(ALLOC_IN_RC(ptr_reg)); 5129 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5130 op_cost(0); 5131 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5132 interface(MEMORY_INTER) %{ 5133 base($reg); 5134 index($ireg); 5135 scale($scale); 5136 disp(0x0); 5137 %} 5138 %} 5139 5140 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5141 %{ 5142 constraint(ALLOC_IN_RC(ptr_reg)); 5143 match(AddP reg (LShiftL lreg scale)); 5144 op_cost(0); 5145 format %{ "$reg, $lreg lsl($scale)" %} 5146 interface(MEMORY_INTER) %{ 5147 base($reg); 5148 index($lreg); 5149 scale($scale); 5150 disp(0x0); 5151 %} 5152 %} 5153 5154 operand indIndex(iRegP reg, iRegL lreg) 5155 %{ 5156 constraint(ALLOC_IN_RC(ptr_reg)); 5157 match(AddP reg lreg); 5158 op_cost(0); 5159 format %{ "$reg, $lreg" %} 5160 interface(MEMORY_INTER) %{ 5161 base($reg); 5162 index($lreg); 5163 scale(0x0); 5164 disp(0x0); 5165 %} 5166 %} 5167 5168 operand indOffI(iRegP reg, immIOffset off) 5169 %{ 5170 constraint(ALLOC_IN_RC(ptr_reg)); 5171 match(AddP reg off); 5172 op_cost(0); 5173 format %{ "[$reg, $off]" %} 5174 interface(MEMORY_INTER) %{ 5175 base($reg); 5176 index(0xffffffff); 5177 scale(0x0); 5178 disp($off); 5179 %} 5180 %} 5181 5182 operand indOffL(iRegP reg, immLoffset off) 5183 %{ 5184 constraint(ALLOC_IN_RC(ptr_reg)); 5185 match(AddP reg off); 5186 op_cost(0); 5187 format %{ "[$reg, $off]" %} 5188 interface(MEMORY_INTER) %{ 5189 base($reg); 5190 index(0xffffffff); 5191 scale(0x0); 5192 disp($off); 5193 %} 5194 %} 5195 5196 5197 operand indirectN(iRegN reg) 5198 %{ 5199 predicate(Universe::narrow_oop_shift() == 0); 5200 constraint(ALLOC_IN_RC(ptr_reg)); 5201 match(DecodeN reg); 5202 op_cost(0); 5203 format %{ "[$reg]\t# narrow" %} 5204 interface(MEMORY_INTER) %{ 5205 base($reg); 5206 index(0xffffffff); 5207 scale(0x0); 5208 disp(0x0); 5209 %} 5210 %} 5211 5212 operand indIndexScaledOffsetIN(iRegN reg, iRegL lreg, immIScale scale, immIU12 off) 5213 %{ 5214 predicate(Universe::narrow_oop_shift() == 0); 5215 constraint(ALLOC_IN_RC(ptr_reg)); 5216 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 5217 op_cost(0); 5218 format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %} 5219 interface(MEMORY_INTER) %{ 5220 base($reg); 5221 index($lreg); 5222 scale($scale); 5223 disp($off); 5224 %} 5225 %} 5226 5227 operand indIndexScaledOffsetLN(iRegN reg, iRegL lreg, immIScale scale, immLU12 off) 5228 %{ 5229 predicate(Universe::narrow_oop_shift() == 0); 5230 constraint(ALLOC_IN_RC(ptr_reg)); 5231 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 5232 op_cost(INSN_COST); 5233 format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %} 5234 interface(MEMORY_INTER) %{ 5235 base($reg); 5236 index($lreg); 5237 scale($scale); 5238 disp($off); 5239 %} 5240 %} 5241 5242 operand indIndexOffsetI2LN(iRegN reg, iRegI ireg, immLU12 off) 5243 %{ 5244 predicate(Universe::narrow_oop_shift() == 0); 5245 constraint(ALLOC_IN_RC(ptr_reg)); 5246 match(AddP (AddP (DecodeN reg) (ConvI2L ireg)) off); 5247 op_cost(INSN_COST); 5248 format %{ "$reg, $ireg, $off I2L\t# narrow" %} 5249 interface(MEMORY_INTER) %{ 5250 base($reg); 5251 index($ireg); 5252 scale(0x0); 5253 disp($off); 5254 %} 5255 %} 5256 5257 operand indIndexScaledOffsetI2LN(iRegN reg, iRegI ireg, immIScale scale, immLU12 off) 5258 %{ 5259 predicate(Universe::narrow_oop_shift() == 0); 5260 constraint(ALLOC_IN_RC(ptr_reg)); 5261 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)) off); 5262 op_cost(INSN_COST); 5263 format %{ "$reg, $ireg sxtw($scale), $off I2L\t# narrow" %} 5264 interface(MEMORY_INTER) %{ 5265 base($reg); 5266 index($ireg); 5267 scale($scale); 5268 disp($off); 5269 %} 5270 %} 5271 5272 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5273 %{ 5274 predicate(Universe::narrow_oop_shift() == 0); 5275 constraint(ALLOC_IN_RC(ptr_reg)); 5276 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5277 op_cost(0); 5278 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5279 interface(MEMORY_INTER) %{ 5280 base($reg); 5281 index($ireg); 5282 scale($scale); 5283 disp(0x0); 5284 %} 5285 %} 5286 5287 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5288 %{ 5289 predicate(Universe::narrow_oop_shift() == 0); 5290 constraint(ALLOC_IN_RC(ptr_reg)); 5291 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5292 op_cost(0); 5293 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5294 interface(MEMORY_INTER) %{ 5295 base($reg); 5296 index($lreg); 5297 scale($scale); 5298 disp(0x0); 5299 %} 5300 %} 5301 5302 operand indIndexN(iRegN reg, iRegL lreg) 5303 %{ 5304 predicate(Universe::narrow_oop_shift() == 0); 5305 constraint(ALLOC_IN_RC(ptr_reg)); 5306 match(AddP (DecodeN reg) lreg); 5307 op_cost(0); 5308 format %{ "$reg, $lreg\t# narrow" %} 5309 interface(MEMORY_INTER) %{ 5310 base($reg); 5311 index($lreg); 5312 scale(0x0); 5313 disp(0x0); 5314 %} 5315 %} 5316 5317 operand indOffIN(iRegN reg, immIOffset off) 5318 %{ 5319 predicate(Universe::narrow_oop_shift() == 0); 5320 constraint(ALLOC_IN_RC(ptr_reg)); 5321 match(AddP (DecodeN reg) off); 5322 op_cost(0); 5323 format %{ "[$reg, $off]\t# narrow" %} 5324 interface(MEMORY_INTER) %{ 5325 base($reg); 5326 index(0xffffffff); 5327 scale(0x0); 5328 disp($off); 5329 %} 5330 %} 5331 5332 operand indOffLN(iRegN reg, immLoffset off) 5333 %{ 5334 predicate(Universe::narrow_oop_shift() == 0); 5335 constraint(ALLOC_IN_RC(ptr_reg)); 5336 match(AddP (DecodeN reg) off); 5337 op_cost(0); 5338 format %{ "[$reg, $off]\t# narrow" %} 5339 interface(MEMORY_INTER) %{ 5340 base($reg); 5341 index(0xffffffff); 5342 scale(0x0); 5343 disp($off); 5344 %} 5345 %} 5346 5347 5348 5349 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5350 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5351 %{ 5352 constraint(ALLOC_IN_RC(ptr_reg)); 5353 match(AddP reg off); 5354 op_cost(0); 5355 format %{ "[$reg, $off]" %} 5356 interface(MEMORY_INTER) %{ 5357 base($reg); 5358 index(0xffffffff); 5359 scale(0x0); 5360 disp($off); 5361 %} 5362 %} 5363 5364 //----------Special Memory Operands-------------------------------------------- 5365 // Stack Slot Operand - This operand is used for loading and storing temporary 5366 // values on the stack where a match requires a value to 5367 // flow through memory. 5368 operand stackSlotP(sRegP reg) 5369 %{ 5370 constraint(ALLOC_IN_RC(stack_slots)); 5371 op_cost(100); 5372 // No match rule because this operand is only generated in matching 5373 // match(RegP); 5374 format %{ "[$reg]" %} 5375 interface(MEMORY_INTER) %{ 5376 base(0x1e); // RSP 5377 index(0x0); // No Index 5378 scale(0x0); // No Scale 5379 disp($reg); // Stack Offset 5380 %} 5381 %} 5382 5383 operand stackSlotI(sRegI reg) 5384 %{ 5385 constraint(ALLOC_IN_RC(stack_slots)); 5386 // No match rule because this operand is only generated in matching 5387 // match(RegI); 5388 format %{ "[$reg]" %} 5389 interface(MEMORY_INTER) %{ 5390 base(0x1e); // RSP 5391 index(0x0); // No Index 5392 scale(0x0); // No Scale 5393 disp($reg); // Stack Offset 5394 %} 5395 %} 5396 5397 operand stackSlotF(sRegF reg) 5398 %{ 5399 constraint(ALLOC_IN_RC(stack_slots)); 5400 // No match rule because this operand is only generated in matching 5401 // match(RegF); 5402 format %{ "[$reg]" %} 5403 interface(MEMORY_INTER) %{ 5404 base(0x1e); // RSP 5405 index(0x0); // No Index 5406 scale(0x0); // No Scale 5407 disp($reg); // Stack Offset 5408 %} 5409 %} 5410 5411 operand stackSlotD(sRegD reg) 5412 %{ 5413 constraint(ALLOC_IN_RC(stack_slots)); 5414 // No match rule because this operand is only generated in matching 5415 // match(RegD); 5416 format %{ "[$reg]" %} 5417 interface(MEMORY_INTER) %{ 5418 base(0x1e); // RSP 5419 index(0x0); // No Index 5420 scale(0x0); // No Scale 5421 disp($reg); // Stack Offset 5422 %} 5423 %} 5424 5425 operand stackSlotL(sRegL reg) 5426 %{ 5427 constraint(ALLOC_IN_RC(stack_slots)); 5428 // No match rule because this operand is only generated in matching 5429 // match(RegL); 5430 format %{ "[$reg]" %} 5431 interface(MEMORY_INTER) %{ 5432 base(0x1e); // RSP 5433 index(0x0); // No Index 5434 scale(0x0); // No Scale 5435 disp($reg); // Stack Offset 5436 %} 5437 %} 5438 5439 // Operands for expressing Control Flow 5440 // NOTE: Label is a predefined operand which should not be redefined in 5441 // the AD file. It is generically handled within the ADLC. 5442 5443 //----------Conditional Branch Operands---------------------------------------- 5444 // Comparison Op - This is the operation of the comparison, and is limited to 5445 // the following set of codes: 5446 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5447 // 5448 // Other attributes of the comparison, such as unsignedness, are specified 5449 // by the comparison instruction that sets a condition code flags register. 5450 // That result is represented by a flags operand whose subtype is appropriate 5451 // to the unsignedness (etc.) of the comparison. 5452 // 5453 // Later, the instruction which matches both the Comparison Op (a Bool) and 5454 // the flags (produced by the Cmp) specifies the coding of the comparison op 5455 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5456 5457 // used for signed integral comparisons and fp comparisons 5458 5459 operand cmpOp() 5460 %{ 5461 match(Bool); 5462 5463 format %{ "" %} 5464 interface(COND_INTER) %{ 5465 equal(0x0, "eq"); 5466 not_equal(0x1, "ne"); 5467 less(0xb, "lt"); 5468 greater_equal(0xa, "ge"); 5469 less_equal(0xd, "le"); 5470 greater(0xc, "gt"); 5471 overflow(0x6, "vs"); 5472 no_overflow(0x7, "vc"); 5473 %} 5474 %} 5475 5476 // used for unsigned integral comparisons 5477 5478 operand cmpOpU() 5479 %{ 5480 match(Bool); 5481 5482 format %{ "" %} 5483 interface(COND_INTER) %{ 5484 equal(0x0, "eq"); 5485 not_equal(0x1, "ne"); 5486 less(0x3, "lo"); 5487 greater_equal(0x2, "hs"); 5488 less_equal(0x9, "ls"); 5489 greater(0x8, "hi"); 5490 overflow(0x6, "vs"); 5491 no_overflow(0x7, "vc"); 5492 %} 5493 %} 5494 5495 // Special operand allowing long args to int ops to be truncated for free 5496 5497 operand iRegL2I(iRegL reg) %{ 5498 5499 op_cost(0); 5500 5501 match(ConvL2I reg); 5502 5503 format %{ "l2i($reg)" %} 5504 5505 interface(REG_INTER) 5506 %} 5507 5508 5509 //----------OPERAND CLASSES---------------------------------------------------- 5510 // Operand Classes are groups of operands that are used as to simplify 5511 // instruction definitions by not requiring the AD writer to specify 5512 // separate instructions for every form of operand when the 5513 // instruction accepts multiple operand types with the same basic 5514 // encoding and format. The classic case of this is memory operands. 5515 5516 // memory is used to define read/write location for load/store 5517 // instruction defs. we can turn a memory op into an Address 5518 5519 opclass memory(indirect, indIndexScaledOffsetI, indIndexScaledOffsetL, indIndexOffsetI2L, indIndexScaledOffsetI2L, indIndexScaled, indIndexScaledI2L, indIndex, indOffI, indOffL, 5520 indirectN, indIndexScaledOffsetIN, indIndexScaledOffsetLN, indIndexOffsetI2LN, indIndexScaledOffsetI2LN, indIndexScaledN, indIndexScaledI2LN, indIndexN, indOffIN, indOffLN); 5521 5522 5523 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5524 // operations. it allows the src to be either an iRegI or a (ConvL2I 5525 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5526 // can be elided because the 32-bit instruction will just employ the 5527 // lower 32 bits anyway. 5528 // 5529 // n.b. this does not elide all L2I conversions. if the truncated 5530 // value is consumed by more than one operation then the ConvL2I 5531 // cannot be bundled into the consuming nodes so an l2i gets planted 5532 // (actually a movw $dst $src) and the downstream instructions consume 5533 // the result of the l2i as an iRegI input. That's a shame since the 5534 // movw is actually redundant but its not too costly. 5535 5536 opclass iRegIorL2I(iRegI, iRegL2I); 5537 5538 //----------PIPELINE----------------------------------------------------------- 5539 // Rules which define the behavior of the target architectures pipeline. 5540 // Integer ALU reg operation 5541 pipeline %{ 5542 5543 attributes %{ 5544 // ARM instructions are of fixed length 5545 fixed_size_instructions; // Fixed size instructions TODO does 5546 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5547 // ARM instructions come in 32-bit word units 5548 instruction_unit_size = 4; // An instruction is 4 bytes long 5549 instruction_fetch_unit_size = 64; // The processor fetches one line 5550 instruction_fetch_units = 1; // of 64 bytes 5551 5552 // List of nop instructions 5553 nops( MachNop ); 5554 %} 5555 5556 // We don't use an actual pipeline model so don't care about resources 5557 // or description. we do use pipeline classes to introduce fixed 5558 // latencies 5559 5560 //----------RESOURCES---------------------------------------------------------- 5561 // Resources are the functional units available to the machine 5562 5563 resources( INS0, INS1, INS01 = INS0 | INS1, 5564 ALU0, ALU1, ALU = ALU0 | ALU1, 5565 MAC, 5566 DIV, 5567 BRANCH, 5568 LDST, 5569 NEON_FP); 5570 5571 //----------PIPELINE DESCRIPTION----------------------------------------------- 5572 // Pipeline Description specifies the stages in the machine's pipeline 5573 5574 pipe_desc(ISS, EX1, EX2, WR); 5575 5576 //----------PIPELINE CLASSES--------------------------------------------------- 5577 // Pipeline Classes describe the stages in which input and output are 5578 // referenced by the hardware pipeline. 5579 5580 //------- Integer ALU operations -------------------------- 5581 5582 // Integer ALU reg-reg operation 5583 // Operands needed in EX1, result generated in EX2 5584 // Eg. ADD x0, x1, x2 5585 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5586 %{ 5587 single_instruction; 5588 dst : EX2(write); 5589 src1 : EX1(read); 5590 src2 : EX1(read); 5591 INS01 : ISS; // Dual issue as instruction 0 or 1 5592 ALU : EX2; 5593 %} 5594 5595 // Integer ALU reg-reg operation with constant shift 5596 // Shifted register must be available in LATE_ISS instead of EX1 5597 // Eg. ADD x0, x1, x2, LSL #2 5598 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 5599 %{ 5600 single_instruction; 5601 dst : EX2(write); 5602 src1 : EX1(read); 5603 src2 : ISS(read); 5604 INS01 : ISS; 5605 ALU : EX2; 5606 %} 5607 5608 // Integer ALU reg operation with constant shift 5609 // Eg. LSL x0, x1, #shift 5610 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 5611 %{ 5612 single_instruction; 5613 dst : EX2(write); 5614 src1 : ISS(read); 5615 INS01 : ISS; 5616 ALU : EX2; 5617 %} 5618 5619 // Integer ALU reg-reg operation with variable shift 5620 // Both operands must be available in LATE_ISS instead of EX1 5621 // Result is available in EX1 instead of EX2 5622 // Eg. LSLV x0, x1, x2 5623 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 5624 %{ 5625 single_instruction; 5626 dst : EX1(write); 5627 src1 : ISS(read); 5628 src2 : ISS(read); 5629 INS01 : ISS; 5630 ALU : EX1; 5631 %} 5632 5633 // Integer ALU reg-reg operation with extract 5634 // As for _vshift above, but result generated in EX2 5635 // Eg. EXTR x0, x1, x2, #N 5636 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 5637 %{ 5638 single_instruction; 5639 dst : EX2(write); 5640 src1 : ISS(read); 5641 src2 : ISS(read); 5642 INS1 : ISS; // Can only dual issue as Instruction 1 5643 ALU : EX1; 5644 %} 5645 5646 // Integer ALU reg operation 5647 // Eg. NEG x0, x1 5648 pipe_class ialu_reg(iRegI dst, iRegI src) 5649 %{ 5650 single_instruction; 5651 dst : EX2(write); 5652 src : EX1(read); 5653 INS01 : ISS; 5654 ALU : EX2; 5655 %} 5656 5657 // Integer ALU reg mmediate operation 5658 // Eg. ADD x0, x1, #N 5659 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 5660 %{ 5661 single_instruction; 5662 dst : EX2(write); 5663 src1 : EX1(read); 5664 INS01 : ISS; 5665 ALU : EX2; 5666 %} 5667 5668 // Integer ALU immediate operation (no source operands) 5669 // Eg. MOV x0, #N 5670 pipe_class ialu_imm(iRegI dst) 5671 %{ 5672 single_instruction; 5673 dst : EX1(write); 5674 INS01 : ISS; 5675 ALU : EX1; 5676 %} 5677 5678 //------- Compare operation ------------------------------- 5679 5680 // Compare reg-reg 5681 // Eg. CMP x0, x1 5682 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 5683 %{ 5684 single_instruction; 5685 // fixed_latency(16); 5686 cr : EX2(write); 5687 op1 : EX1(read); 5688 op2 : EX1(read); 5689 INS01 : ISS; 5690 ALU : EX2; 5691 %} 5692 5693 // Compare reg-reg 5694 // Eg. CMP x0, #N 5695 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 5696 %{ 5697 single_instruction; 5698 // fixed_latency(16); 5699 cr : EX2(write); 5700 op1 : EX1(read); 5701 INS01 : ISS; 5702 ALU : EX2; 5703 %} 5704 5705 //------- Conditional instructions ------------------------ 5706 5707 // Conditional no operands 5708 // Eg. CSINC x0, zr, zr, <cond> 5709 pipe_class icond_none(iRegI dst, rFlagsReg cr) 5710 %{ 5711 single_instruction; 5712 cr : EX1(read); 5713 dst : EX2(write); 5714 INS01 : ISS; 5715 ALU : EX2; 5716 %} 5717 5718 // Conditional 2 operand 5719 // EG. CSEL X0, X1, X2, <cond> 5720 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 5721 %{ 5722 single_instruction; 5723 cr : EX1(read); 5724 src1 : EX1(read); 5725 src2 : EX1(read); 5726 dst : EX2(write); 5727 INS01 : ISS; 5728 ALU : EX2; 5729 %} 5730 5731 // Conditional 2 operand 5732 // EG. CSEL X0, X1, X2, <cond> 5733 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 5734 %{ 5735 single_instruction; 5736 cr : EX1(read); 5737 src : EX1(read); 5738 dst : EX2(write); 5739 INS01 : ISS; 5740 ALU : EX2; 5741 %} 5742 5743 //------- Multiply pipeline operations -------------------- 5744 5745 // Multiply reg-reg 5746 // Eg. MUL w0, w1, w2 5747 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5748 %{ 5749 single_instruction; 5750 dst : WR(write); 5751 src1 : ISS(read); 5752 src2 : ISS(read); 5753 INS01 : ISS; 5754 MAC : WR; 5755 %} 5756 5757 // Multiply accumulate 5758 // Eg. MADD w0, w1, w2, w3 5759 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 5760 %{ 5761 single_instruction; 5762 dst : WR(write); 5763 src1 : ISS(read); 5764 src2 : ISS(read); 5765 src3 : ISS(read); 5766 INS01 : ISS; 5767 MAC : WR; 5768 %} 5769 5770 // Eg. MUL w0, w1, w2 5771 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5772 %{ 5773 single_instruction; 5774 fixed_latency(3); // Maximum latency for 64 bit mul 5775 dst : WR(write); 5776 src1 : ISS(read); 5777 src2 : ISS(read); 5778 INS01 : ISS; 5779 MAC : WR; 5780 %} 5781 5782 // Multiply accumulate 5783 // Eg. MADD w0, w1, w2, w3 5784 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 5785 %{ 5786 single_instruction; 5787 fixed_latency(3); // Maximum latency for 64 bit mul 5788 dst : WR(write); 5789 src1 : ISS(read); 5790 src2 : ISS(read); 5791 src3 : ISS(read); 5792 INS01 : ISS; 5793 MAC : WR; 5794 %} 5795 5796 //------- Divide pipeline operations -------------------- 5797 5798 // Eg. SDIV w0, w1, w2 5799 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5800 %{ 5801 single_instruction; 5802 fixed_latency(8); // Maximum latency for 32 bit divide 5803 dst : WR(write); 5804 src1 : ISS(read); 5805 src2 : ISS(read); 5806 INS0 : ISS; // Can only dual issue as instruction 0 5807 DIV : WR; 5808 %} 5809 5810 // Eg. SDIV x0, x1, x2 5811 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5812 %{ 5813 single_instruction; 5814 fixed_latency(16); // Maximum latency for 64 bit divide 5815 dst : WR(write); 5816 src1 : ISS(read); 5817 src2 : ISS(read); 5818 INS0 : ISS; // Can only dual issue as instruction 0 5819 DIV : WR; 5820 %} 5821 5822 //------- Load pipeline operations ------------------------ 5823 5824 // Load - prefetch 5825 // Eg. PFRM <mem> 5826 pipe_class iload_prefetch(memory mem) 5827 %{ 5828 single_instruction; 5829 mem : ISS(read); 5830 INS01 : ISS; 5831 LDST : WR; 5832 %} 5833 5834 // Load - reg, mem 5835 // Eg. LDR x0, <mem> 5836 pipe_class iload_reg_mem(iRegI dst, memory mem) 5837 %{ 5838 single_instruction; 5839 dst : WR(write); 5840 mem : ISS(read); 5841 INS01 : ISS; 5842 LDST : WR; 5843 %} 5844 5845 // Load - reg, reg 5846 // Eg. LDR x0, [sp, x1] 5847 pipe_class iload_reg_reg(iRegI dst, iRegI src) 5848 %{ 5849 single_instruction; 5850 dst : WR(write); 5851 src : ISS(read); 5852 INS01 : ISS; 5853 LDST : WR; 5854 %} 5855 5856 //------- Store pipeline operations ----------------------- 5857 5858 // Store - zr, mem 5859 // Eg. STR zr, <mem> 5860 pipe_class istore_mem(memory mem) 5861 %{ 5862 single_instruction; 5863 mem : ISS(read); 5864 INS01 : ISS; 5865 LDST : WR; 5866 %} 5867 5868 // Store - reg, mem 5869 // Eg. STR x0, <mem> 5870 pipe_class istore_reg_mem(iRegI src, memory mem) 5871 %{ 5872 single_instruction; 5873 mem : ISS(read); 5874 src : EX2(read); 5875 INS01 : ISS; 5876 LDST : WR; 5877 %} 5878 5879 // Store - reg, reg 5880 // Eg. STR x0, [sp, x1] 5881 pipe_class istore_reg_reg(iRegI dst, iRegI src) 5882 %{ 5883 single_instruction; 5884 dst : ISS(read); 5885 src : EX2(read); 5886 INS01 : ISS; 5887 LDST : WR; 5888 %} 5889 5890 //------- Store pipeline operations ----------------------- 5891 5892 // Branch 5893 pipe_class pipe_branch() 5894 %{ 5895 single_instruction; 5896 INS01 : ISS; 5897 BRANCH : EX1; 5898 %} 5899 5900 // Conditional branch 5901 pipe_class pipe_branch_cond(rFlagsReg cr) 5902 %{ 5903 single_instruction; 5904 cr : EX1(read); 5905 INS01 : ISS; 5906 BRANCH : EX1; 5907 %} 5908 5909 // Compare & Branch 5910 // EG. CBZ/CBNZ 5911 pipe_class pipe_cmp_branch(iRegI op1) 5912 %{ 5913 single_instruction; 5914 op1 : EX1(read); 5915 INS01 : ISS; 5916 BRANCH : EX1; 5917 %} 5918 5919 //------- Synchronisation operations ---------------------- 5920 5921 // Any operation requiring serialization. 5922 // EG. DMB/Atomic Ops/Load Acquire/Str Release 5923 pipe_class pipe_serial() 5924 %{ 5925 single_instruction; 5926 force_serialization; 5927 fixed_latency(16); 5928 INS01 : ISS(2); // Cannot dual issue with any other instruction 5929 LDST : WR; 5930 %} 5931 5932 // Generic big/slow expanded idiom - also serialized 5933 pipe_class pipe_slow() 5934 %{ 5935 instruction_count(10); 5936 multiple_bundles; 5937 force_serialization; 5938 fixed_latency(16); 5939 INS01 : ISS(2); // Cannot dual issue with any other instruction 5940 LDST : WR; 5941 %} 5942 5943 // Empty pipeline class 5944 pipe_class pipe_class_empty() 5945 %{ 5946 single_instruction; 5947 fixed_latency(0); 5948 %} 5949 5950 // Default pipeline class. 5951 pipe_class pipe_class_default() 5952 %{ 5953 single_instruction; 5954 fixed_latency(2); 5955 %} 5956 5957 // Pipeline class for compares. 5958 pipe_class pipe_class_compare() 5959 %{ 5960 single_instruction; 5961 fixed_latency(16); 5962 %} 5963 5964 // Pipeline class for memory operations. 5965 pipe_class pipe_class_memory() 5966 %{ 5967 single_instruction; 5968 fixed_latency(16); 5969 %} 5970 5971 // Pipeline class for call. 5972 pipe_class pipe_class_call() 5973 %{ 5974 single_instruction; 5975 fixed_latency(100); 5976 %} 5977 5978 // Define the class for the Nop node. 5979 define %{ 5980 MachNop = pipe_class_empty; 5981 %} 5982 5983 %} 5984 //----------INSTRUCTIONS------------------------------------------------------- 5985 // 5986 // match -- States which machine-independent subtree may be replaced 5987 // by this instruction. 5988 // ins_cost -- The estimated cost of this instruction is used by instruction 5989 // selection to identify a minimum cost tree of machine 5990 // instructions that matches a tree of machine-independent 5991 // instructions. 5992 // format -- A string providing the disassembly for this instruction. 5993 // The value of an instruction's operand may be inserted 5994 // by referring to it with a '$' prefix. 5995 // opcode -- Three instruction opcodes may be provided. These are referred 5996 // to within an encode class as $primary, $secondary, and $tertiary 5997 // rrspectively. The primary opcode is commonly used to 5998 // indicate the type of machine instruction, while secondary 5999 // and tertiary are often used for prefix options or addressing 6000 // modes. 6001 // ins_encode -- A list of encode classes with parameters. The encode class 6002 // name must have been defined in an 'enc_class' specification 6003 // in the encode section of the architecture description. 6004 6005 // ============================================================================ 6006 // Memory (Load/Store) Instructions 6007 6008 // Load Instructions 6009 6010 // Load Byte (8 bit signed) 6011 instruct loadB(iRegINoSp dst, memory mem) 6012 %{ 6013 match(Set dst (LoadB mem)); 6014 predicate(!needs_acquiring_load(n)); 6015 6016 ins_cost(4 * INSN_COST); 6017 format %{ "ldrsbw $dst, $mem\t# byte" %} 6018 6019 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6020 6021 ins_pipe(iload_reg_mem); 6022 %} 6023 6024 // Load Byte (8 bit signed) into long 6025 instruct loadB2L(iRegLNoSp dst, memory mem) 6026 %{ 6027 match(Set dst (ConvI2L (LoadB mem))); 6028 predicate(!needs_acquiring_load(n->in(1))); 6029 6030 ins_cost(4 * INSN_COST); 6031 format %{ "ldrsb $dst, $mem\t# byte" %} 6032 6033 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6034 6035 ins_pipe(iload_reg_mem); 6036 %} 6037 6038 // Load Byte (8 bit unsigned) 6039 instruct loadUB(iRegINoSp dst, memory mem) 6040 %{ 6041 match(Set dst (LoadUB mem)); 6042 predicate(!needs_acquiring_load(n)); 6043 6044 ins_cost(4 * INSN_COST); 6045 format %{ "ldrbw $dst, $mem\t# byte" %} 6046 6047 ins_encode(aarch64_enc_ldrb(dst, mem)); 6048 6049 ins_pipe(iload_reg_mem); 6050 %} 6051 6052 // Load Byte (8 bit unsigned) into long 6053 instruct loadUB2L(iRegLNoSp dst, memory mem) 6054 %{ 6055 match(Set dst (ConvI2L (LoadUB mem))); 6056 predicate(!needs_acquiring_load(n->in(1))); 6057 6058 ins_cost(4 * INSN_COST); 6059 format %{ "ldrb $dst, $mem\t# byte" %} 6060 6061 ins_encode(aarch64_enc_ldrb(dst, mem)); 6062 6063 ins_pipe(iload_reg_mem); 6064 %} 6065 6066 // Load Short (16 bit signed) 6067 instruct loadS(iRegINoSp dst, memory mem) 6068 %{ 6069 match(Set dst (LoadS mem)); 6070 predicate(!needs_acquiring_load(n)); 6071 6072 ins_cost(4 * INSN_COST); 6073 format %{ "ldrshw $dst, $mem\t# short" %} 6074 6075 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6076 6077 ins_pipe(iload_reg_mem); 6078 %} 6079 6080 // Load Short (16 bit signed) into long 6081 instruct loadS2L(iRegLNoSp dst, memory mem) 6082 %{ 6083 match(Set dst (ConvI2L (LoadS mem))); 6084 predicate(!needs_acquiring_load(n->in(1))); 6085 6086 ins_cost(4 * INSN_COST); 6087 format %{ "ldrsh $dst, $mem\t# short" %} 6088 6089 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6090 6091 ins_pipe(iload_reg_mem); 6092 %} 6093 6094 // Load Char (16 bit unsigned) 6095 instruct loadUS(iRegINoSp dst, memory mem) 6096 %{ 6097 match(Set dst (LoadUS mem)); 6098 predicate(!needs_acquiring_load(n)); 6099 6100 ins_cost(4 * INSN_COST); 6101 format %{ "ldrh $dst, $mem\t# short" %} 6102 6103 ins_encode(aarch64_enc_ldrh(dst, mem)); 6104 6105 ins_pipe(iload_reg_mem); 6106 %} 6107 6108 // Load Short/Char (16 bit unsigned) into long 6109 instruct loadUS2L(iRegLNoSp dst, memory mem) 6110 %{ 6111 match(Set dst (ConvI2L (LoadUS mem))); 6112 predicate(!needs_acquiring_load(n->in(1))); 6113 6114 ins_cost(4 * INSN_COST); 6115 format %{ "ldrh $dst, $mem\t# short" %} 6116 6117 ins_encode(aarch64_enc_ldrh(dst, mem)); 6118 6119 ins_pipe(iload_reg_mem); 6120 %} 6121 6122 // Load Integer (32 bit signed) 6123 instruct loadI(iRegINoSp dst, memory mem) 6124 %{ 6125 match(Set dst (LoadI mem)); 6126 predicate(!needs_acquiring_load(n)); 6127 6128 ins_cost(4 * INSN_COST); 6129 format %{ "ldrw $dst, $mem\t# int" %} 6130 6131 ins_encode(aarch64_enc_ldrw(dst, mem)); 6132 6133 ins_pipe(iload_reg_mem); 6134 %} 6135 6136 // Load Integer (32 bit signed) into long 6137 instruct loadI2L(iRegLNoSp dst, memory mem) 6138 %{ 6139 match(Set dst (ConvI2L (LoadI mem))); 6140 predicate(!needs_acquiring_load(n->in(1))); 6141 6142 ins_cost(4 * INSN_COST); 6143 format %{ "ldrsw $dst, $mem\t# int" %} 6144 6145 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6146 6147 ins_pipe(iload_reg_mem); 6148 %} 6149 6150 // Load Integer (32 bit unsigned) into long 6151 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 6152 %{ 6153 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6154 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6155 6156 ins_cost(4 * INSN_COST); 6157 format %{ "ldrw $dst, $mem\t# int" %} 6158 6159 ins_encode(aarch64_enc_ldrw(dst, mem)); 6160 6161 ins_pipe(iload_reg_mem); 6162 %} 6163 6164 // Load Long (64 bit signed) 6165 instruct loadL(iRegLNoSp dst, memory mem) 6166 %{ 6167 match(Set dst (LoadL mem)); 6168 predicate(!needs_acquiring_load(n)); 6169 6170 ins_cost(4 * INSN_COST); 6171 format %{ "ldr $dst, $mem\t# int" %} 6172 6173 ins_encode(aarch64_enc_ldr(dst, mem)); 6174 6175 ins_pipe(iload_reg_mem); 6176 %} 6177 6178 // Load Range 6179 instruct loadRange(iRegINoSp dst, memory mem) 6180 %{ 6181 match(Set dst (LoadRange mem)); 6182 6183 ins_cost(4 * INSN_COST); 6184 format %{ "ldrw $dst, $mem\t# range" %} 6185 6186 ins_encode(aarch64_enc_ldrw(dst, mem)); 6187 6188 ins_pipe(iload_reg_mem); 6189 %} 6190 6191 // Load Pointer 6192 instruct loadP(iRegPNoSp dst, memory mem) 6193 %{ 6194 match(Set dst (LoadP mem)); 6195 predicate(!needs_acquiring_load(n)); 6196 6197 ins_cost(4 * INSN_COST); 6198 format %{ "ldr $dst, $mem\t# ptr" %} 6199 6200 ins_encode(aarch64_enc_ldr(dst, mem)); 6201 6202 ins_pipe(iload_reg_mem); 6203 %} 6204 6205 // Load Compressed Pointer 6206 instruct loadN(iRegNNoSp dst, memory mem) 6207 %{ 6208 match(Set dst (LoadN mem)); 6209 predicate(!needs_acquiring_load(n)); 6210 6211 ins_cost(4 * INSN_COST); 6212 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 6213 6214 ins_encode(aarch64_enc_ldrw(dst, mem)); 6215 6216 ins_pipe(iload_reg_mem); 6217 %} 6218 6219 // Load Klass Pointer 6220 instruct loadKlass(iRegPNoSp dst, memory mem) 6221 %{ 6222 match(Set dst (LoadKlass mem)); 6223 predicate(!needs_acquiring_load(n)); 6224 6225 ins_cost(4 * INSN_COST); 6226 format %{ "ldr $dst, $mem\t# class" %} 6227 6228 ins_encode(aarch64_enc_ldr(dst, mem)); 6229 6230 ins_pipe(iload_reg_mem); 6231 %} 6232 6233 // Load Narrow Klass Pointer 6234 instruct loadNKlass(iRegNNoSp dst, memory mem) 6235 %{ 6236 match(Set dst (LoadNKlass mem)); 6237 predicate(!needs_acquiring_load(n)); 6238 6239 ins_cost(4 * INSN_COST); 6240 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 6241 6242 ins_encode(aarch64_enc_ldrw(dst, mem)); 6243 6244 ins_pipe(iload_reg_mem); 6245 %} 6246 6247 // Load Float 6248 instruct loadF(vRegF dst, memory mem) 6249 %{ 6250 match(Set dst (LoadF mem)); 6251 predicate(!needs_acquiring_load(n)); 6252 6253 ins_cost(4 * INSN_COST); 6254 format %{ "ldrs $dst, $mem\t# float" %} 6255 6256 ins_encode( aarch64_enc_ldrs(dst, mem) ); 6257 6258 ins_pipe(pipe_class_memory); 6259 %} 6260 6261 // Load Double 6262 instruct loadD(vRegD dst, memory mem) 6263 %{ 6264 match(Set dst (LoadD mem)); 6265 predicate(!needs_acquiring_load(n)); 6266 6267 ins_cost(4 * INSN_COST); 6268 format %{ "ldrd $dst, $mem\t# double" %} 6269 6270 ins_encode( aarch64_enc_ldrd(dst, mem) ); 6271 6272 ins_pipe(pipe_class_memory); 6273 %} 6274 6275 6276 // Load Int Constant 6277 instruct loadConI(iRegINoSp dst, immI src) 6278 %{ 6279 match(Set dst src); 6280 6281 ins_cost(INSN_COST); 6282 format %{ "mov $dst, $src\t# int" %} 6283 6284 ins_encode( aarch64_enc_movw_imm(dst, src) ); 6285 6286 ins_pipe(ialu_imm); 6287 %} 6288 6289 // Load Long Constant 6290 instruct loadConL(iRegLNoSp dst, immL src) 6291 %{ 6292 match(Set dst src); 6293 6294 ins_cost(INSN_COST); 6295 format %{ "mov $dst, $src\t# long" %} 6296 6297 ins_encode( aarch64_enc_mov_imm(dst, src) ); 6298 6299 ins_pipe(ialu_imm); 6300 %} 6301 6302 // Load Pointer Constant 6303 6304 instruct loadConP(iRegPNoSp dst, immP con) 6305 %{ 6306 match(Set dst con); 6307 6308 ins_cost(INSN_COST * 4); 6309 format %{ 6310 "mov $dst, $con\t# ptr\n\t" 6311 %} 6312 6313 ins_encode(aarch64_enc_mov_p(dst, con)); 6314 6315 ins_pipe(ialu_imm); 6316 %} 6317 6318 // Load Null Pointer Constant 6319 6320 instruct loadConP0(iRegPNoSp dst, immP0 con) 6321 %{ 6322 match(Set dst con); 6323 6324 ins_cost(INSN_COST); 6325 format %{ "mov $dst, $con\t# NULL ptr" %} 6326 6327 ins_encode(aarch64_enc_mov_p0(dst, con)); 6328 6329 ins_pipe(ialu_imm); 6330 %} 6331 6332 // Load Pointer Constant One 6333 6334 instruct loadConP1(iRegPNoSp dst, immP_1 con) 6335 %{ 6336 match(Set dst con); 6337 6338 ins_cost(INSN_COST); 6339 format %{ "mov $dst, $con\t# NULL ptr" %} 6340 6341 ins_encode(aarch64_enc_mov_p1(dst, con)); 6342 6343 ins_pipe(ialu_imm); 6344 %} 6345 6346 // Load Poll Page Constant 6347 6348 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 6349 %{ 6350 match(Set dst con); 6351 6352 ins_cost(INSN_COST); 6353 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 6354 6355 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 6356 6357 ins_pipe(ialu_imm); 6358 %} 6359 6360 // Load Byte Map Base Constant 6361 6362 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 6363 %{ 6364 match(Set dst con); 6365 6366 ins_cost(INSN_COST); 6367 format %{ "adr $dst, $con\t# Byte Map Base" %} 6368 6369 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 6370 6371 ins_pipe(ialu_imm); 6372 %} 6373 6374 // Load Narrow Pointer Constant 6375 6376 instruct loadConN(iRegNNoSp dst, immN con) 6377 %{ 6378 match(Set dst con); 6379 6380 ins_cost(INSN_COST * 4); 6381 format %{ "mov $dst, $con\t# compressed ptr" %} 6382 6383 ins_encode(aarch64_enc_mov_n(dst, con)); 6384 6385 ins_pipe(ialu_imm); 6386 %} 6387 6388 // Load Narrow Null Pointer Constant 6389 6390 instruct loadConN0(iRegNNoSp dst, immN0 con) 6391 %{ 6392 match(Set dst con); 6393 6394 ins_cost(INSN_COST); 6395 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 6396 6397 ins_encode(aarch64_enc_mov_n0(dst, con)); 6398 6399 ins_pipe(ialu_imm); 6400 %} 6401 6402 // Load Narrow Klass Constant 6403 6404 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 6405 %{ 6406 match(Set dst con); 6407 6408 ins_cost(INSN_COST); 6409 format %{ "mov $dst, $con\t# compressed klass ptr" %} 6410 6411 ins_encode(aarch64_enc_mov_nk(dst, con)); 6412 6413 ins_pipe(ialu_imm); 6414 %} 6415 6416 // Load Packed Float Constant 6417 6418 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 6419 match(Set dst con); 6420 ins_cost(INSN_COST * 4); 6421 format %{ "fmovs $dst, $con"%} 6422 ins_encode %{ 6423 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 6424 %} 6425 6426 ins_pipe(pipe_class_default); 6427 %} 6428 6429 // Load Float Constant 6430 6431 instruct loadConF(vRegF dst, immF con) %{ 6432 match(Set dst con); 6433 6434 ins_cost(INSN_COST * 4); 6435 6436 format %{ 6437 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6438 %} 6439 6440 ins_encode %{ 6441 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 6442 %} 6443 6444 ins_pipe(pipe_class_default); 6445 %} 6446 6447 // Load Packed Double Constant 6448 6449 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 6450 match(Set dst con); 6451 ins_cost(INSN_COST); 6452 format %{ "fmovd $dst, $con"%} 6453 ins_encode %{ 6454 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 6455 %} 6456 6457 ins_pipe(pipe_class_default); 6458 %} 6459 6460 // Load Double Constant 6461 6462 instruct loadConD(vRegD dst, immD con) %{ 6463 match(Set dst con); 6464 6465 ins_cost(INSN_COST * 5); 6466 format %{ 6467 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6468 %} 6469 6470 ins_encode %{ 6471 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 6472 %} 6473 6474 ins_pipe(pipe_class_default); 6475 %} 6476 6477 // Store Instructions 6478 6479 // Store CMS card-mark Immediate 6480 instruct storeimmCM0(immI0 zero, memory mem) 6481 %{ 6482 match(Set mem (StoreCM mem zero)); 6483 6484 ins_cost(INSN_COST); 6485 format %{ "strb zr, $mem\t# byte" %} 6486 6487 ins_encode(aarch64_enc_strb0(mem)); 6488 6489 ins_pipe(istore_mem); 6490 %} 6491 6492 // Store Byte 6493 instruct storeB(iRegIorL2I src, memory mem) 6494 %{ 6495 match(Set mem (StoreB mem src)); 6496 predicate(!needs_releasing_store(n)); 6497 6498 ins_cost(INSN_COST); 6499 format %{ "strb $src, $mem\t# byte" %} 6500 6501 ins_encode(aarch64_enc_strb(src, mem)); 6502 6503 ins_pipe(istore_reg_mem); 6504 %} 6505 6506 6507 instruct storeimmB0(immI0 zero, memory mem) 6508 %{ 6509 match(Set mem (StoreB mem zero)); 6510 predicate(!needs_releasing_store(n)); 6511 6512 ins_cost(INSN_COST); 6513 format %{ "strb zr, $mem\t# byte" %} 6514 6515 ins_encode(aarch64_enc_strb0(mem)); 6516 6517 ins_pipe(istore_mem); 6518 %} 6519 6520 // Store Char/Short 6521 instruct storeC(iRegIorL2I src, memory mem) 6522 %{ 6523 match(Set mem (StoreC mem src)); 6524 predicate(!needs_releasing_store(n)); 6525 6526 ins_cost(INSN_COST); 6527 format %{ "strh $src, $mem\t# short" %} 6528 6529 ins_encode(aarch64_enc_strh(src, mem)); 6530 6531 ins_pipe(istore_reg_mem); 6532 %} 6533 6534 instruct storeimmC0(immI0 zero, memory mem) 6535 %{ 6536 match(Set mem (StoreC mem zero)); 6537 predicate(!needs_releasing_store(n)); 6538 6539 ins_cost(INSN_COST); 6540 format %{ "strh zr, $mem\t# short" %} 6541 6542 ins_encode(aarch64_enc_strh0(mem)); 6543 6544 ins_pipe(istore_mem); 6545 %} 6546 6547 // Store Integer 6548 6549 instruct storeI(iRegIorL2I src, memory mem) 6550 %{ 6551 match(Set mem(StoreI mem src)); 6552 predicate(!needs_releasing_store(n)); 6553 6554 ins_cost(INSN_COST); 6555 format %{ "strw $src, $mem\t# int" %} 6556 6557 ins_encode(aarch64_enc_strw(src, mem)); 6558 6559 ins_pipe(istore_reg_mem); 6560 %} 6561 6562 instruct storeimmI0(immI0 zero, memory mem) 6563 %{ 6564 match(Set mem(StoreI mem zero)); 6565 predicate(!needs_releasing_store(n)); 6566 6567 ins_cost(INSN_COST); 6568 format %{ "strw zr, $mem\t# int" %} 6569 6570 ins_encode(aarch64_enc_strw0(mem)); 6571 6572 ins_pipe(istore_mem); 6573 %} 6574 6575 // Store Long (64 bit signed) 6576 instruct storeL(iRegL src, memory mem) 6577 %{ 6578 match(Set mem (StoreL mem src)); 6579 predicate(!needs_releasing_store(n)); 6580 6581 ins_cost(INSN_COST); 6582 format %{ "str $src, $mem\t# int" %} 6583 6584 ins_encode(aarch64_enc_str(src, mem)); 6585 6586 ins_pipe(istore_reg_mem); 6587 %} 6588 6589 // Store Long (64 bit signed) 6590 instruct storeimmL0(immL0 zero, memory mem) 6591 %{ 6592 match(Set mem (StoreL mem zero)); 6593 predicate(!needs_releasing_store(n)); 6594 6595 ins_cost(INSN_COST); 6596 format %{ "str zr, $mem\t# int" %} 6597 6598 ins_encode(aarch64_enc_str0(mem)); 6599 6600 ins_pipe(istore_mem); 6601 %} 6602 6603 // Store Pointer 6604 instruct storeP(iRegP src, memory mem) 6605 %{ 6606 match(Set mem (StoreP mem src)); 6607 predicate(!needs_releasing_store(n)); 6608 6609 ins_cost(INSN_COST); 6610 format %{ "str $src, $mem\t# ptr" %} 6611 6612 ins_encode(aarch64_enc_str(src, mem)); 6613 6614 ins_pipe(istore_reg_mem); 6615 %} 6616 6617 // Store Pointer 6618 instruct storeimmP0(immP0 zero, memory mem) 6619 %{ 6620 match(Set mem (StoreP mem zero)); 6621 predicate(!needs_releasing_store(n)); 6622 6623 ins_cost(INSN_COST); 6624 format %{ "str zr, $mem\t# ptr" %} 6625 6626 ins_encode(aarch64_enc_str0(mem)); 6627 6628 ins_pipe(istore_mem); 6629 %} 6630 6631 // Store Compressed Pointer 6632 instruct storeN(iRegN src, memory mem) 6633 %{ 6634 match(Set mem (StoreN mem src)); 6635 predicate(!needs_releasing_store(n)); 6636 6637 ins_cost(INSN_COST); 6638 format %{ "strw $src, $mem\t# compressed ptr" %} 6639 6640 ins_encode(aarch64_enc_strw(src, mem)); 6641 6642 ins_pipe(istore_reg_mem); 6643 %} 6644 6645 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 6646 %{ 6647 match(Set mem (StoreN mem zero)); 6648 predicate(Universe::narrow_oop_base() == NULL && 6649 Universe::narrow_klass_base() == NULL && 6650 (!needs_releasing_store(n))); 6651 6652 ins_cost(INSN_COST); 6653 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 6654 6655 ins_encode(aarch64_enc_strw(heapbase, mem)); 6656 6657 ins_pipe(istore_reg_mem); 6658 %} 6659 6660 // Store Float 6661 instruct storeF(vRegF src, memory mem) 6662 %{ 6663 match(Set mem (StoreF mem src)); 6664 predicate(!needs_releasing_store(n)); 6665 6666 ins_cost(INSN_COST); 6667 format %{ "strs $src, $mem\t# float" %} 6668 6669 ins_encode( aarch64_enc_strs(src, mem) ); 6670 6671 ins_pipe(pipe_class_memory); 6672 %} 6673 6674 // TODO 6675 // implement storeImmF0 and storeFImmPacked 6676 6677 // Store Double 6678 instruct storeD(vRegD src, memory mem) 6679 %{ 6680 match(Set mem (StoreD mem src)); 6681 predicate(!needs_releasing_store(n)); 6682 6683 ins_cost(INSN_COST); 6684 format %{ "strd $src, $mem\t# double" %} 6685 6686 ins_encode( aarch64_enc_strd(src, mem) ); 6687 6688 ins_pipe(pipe_class_memory); 6689 %} 6690 6691 // Store Compressed Klass Pointer 6692 instruct storeNKlass(iRegN src, memory mem) 6693 %{ 6694 predicate(!needs_releasing_store(n)); 6695 match(Set mem (StoreNKlass mem src)); 6696 6697 ins_cost(INSN_COST); 6698 format %{ "strw $src, $mem\t# compressed klass ptr" %} 6699 6700 ins_encode(aarch64_enc_strw(src, mem)); 6701 6702 ins_pipe(istore_reg_mem); 6703 %} 6704 6705 // TODO 6706 // implement storeImmD0 and storeDImmPacked 6707 6708 // prefetch instructions 6709 // Must be safe to execute with invalid address (cannot fault). 6710 6711 instruct prefetchalloc( memory mem ) %{ 6712 match(PrefetchAllocation mem); 6713 6714 ins_cost(INSN_COST); 6715 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 6716 6717 ins_encode( aarch64_enc_prefetchw(mem) ); 6718 6719 ins_pipe(iload_prefetch); 6720 %} 6721 6722 // ---------------- volatile loads and stores ---------------- 6723 6724 // Load Byte (8 bit signed) 6725 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6726 %{ 6727 match(Set dst (LoadB mem)); 6728 6729 ins_cost(VOLATILE_REF_COST); 6730 format %{ "ldarsb $dst, $mem\t# byte" %} 6731 6732 ins_encode(aarch64_enc_ldarsb(dst, mem)); 6733 6734 ins_pipe(pipe_serial); 6735 %} 6736 6737 // Load Byte (8 bit signed) into long 6738 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6739 %{ 6740 match(Set dst (ConvI2L (LoadB mem))); 6741 6742 ins_cost(VOLATILE_REF_COST); 6743 format %{ "ldarsb $dst, $mem\t# byte" %} 6744 6745 ins_encode(aarch64_enc_ldarsb(dst, mem)); 6746 6747 ins_pipe(pipe_serial); 6748 %} 6749 6750 // Load Byte (8 bit unsigned) 6751 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6752 %{ 6753 match(Set dst (LoadUB mem)); 6754 6755 ins_cost(VOLATILE_REF_COST); 6756 format %{ "ldarb $dst, $mem\t# byte" %} 6757 6758 ins_encode(aarch64_enc_ldarb(dst, mem)); 6759 6760 ins_pipe(pipe_serial); 6761 %} 6762 6763 // Load Byte (8 bit unsigned) into long 6764 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6765 %{ 6766 match(Set dst (ConvI2L (LoadUB mem))); 6767 6768 ins_cost(VOLATILE_REF_COST); 6769 format %{ "ldarb $dst, $mem\t# byte" %} 6770 6771 ins_encode(aarch64_enc_ldarb(dst, mem)); 6772 6773 ins_pipe(pipe_serial); 6774 %} 6775 6776 // Load Short (16 bit signed) 6777 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6778 %{ 6779 match(Set dst (LoadS mem)); 6780 6781 ins_cost(VOLATILE_REF_COST); 6782 format %{ "ldarshw $dst, $mem\t# short" %} 6783 6784 ins_encode(aarch64_enc_ldarshw(dst, mem)); 6785 6786 ins_pipe(pipe_serial); 6787 %} 6788 6789 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6790 %{ 6791 match(Set dst (LoadUS mem)); 6792 6793 ins_cost(VOLATILE_REF_COST); 6794 format %{ "ldarhw $dst, $mem\t# short" %} 6795 6796 ins_encode(aarch64_enc_ldarhw(dst, mem)); 6797 6798 ins_pipe(pipe_serial); 6799 %} 6800 6801 // Load Short/Char (16 bit unsigned) into long 6802 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6803 %{ 6804 match(Set dst (ConvI2L (LoadUS mem))); 6805 6806 ins_cost(VOLATILE_REF_COST); 6807 format %{ "ldarh $dst, $mem\t# short" %} 6808 6809 ins_encode(aarch64_enc_ldarh(dst, mem)); 6810 6811 ins_pipe(pipe_serial); 6812 %} 6813 6814 // Load Short/Char (16 bit signed) into long 6815 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6816 %{ 6817 match(Set dst (ConvI2L (LoadS mem))); 6818 6819 ins_cost(VOLATILE_REF_COST); 6820 format %{ "ldarh $dst, $mem\t# short" %} 6821 6822 ins_encode(aarch64_enc_ldarsh(dst, mem)); 6823 6824 ins_pipe(pipe_serial); 6825 %} 6826 6827 // Load Integer (32 bit signed) 6828 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6829 %{ 6830 match(Set dst (LoadI mem)); 6831 6832 ins_cost(VOLATILE_REF_COST); 6833 format %{ "ldarw $dst, $mem\t# int" %} 6834 6835 ins_encode(aarch64_enc_ldarw(dst, mem)); 6836 6837 ins_pipe(pipe_serial); 6838 %} 6839 6840 // Load Integer (32 bit unsigned) into long 6841 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 6842 %{ 6843 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6844 6845 ins_cost(VOLATILE_REF_COST); 6846 format %{ "ldarw $dst, $mem\t# int" %} 6847 6848 ins_encode(aarch64_enc_ldarw(dst, mem)); 6849 6850 ins_pipe(pipe_serial); 6851 %} 6852 6853 // Load Long (64 bit signed) 6854 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6855 %{ 6856 match(Set dst (LoadL mem)); 6857 6858 ins_cost(VOLATILE_REF_COST); 6859 format %{ "ldar $dst, $mem\t# int" %} 6860 6861 ins_encode(aarch64_enc_ldar(dst, mem)); 6862 6863 ins_pipe(pipe_serial); 6864 %} 6865 6866 // Load Pointer 6867 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 6868 %{ 6869 match(Set dst (LoadP mem)); 6870 6871 ins_cost(VOLATILE_REF_COST); 6872 format %{ "ldar $dst, $mem\t# ptr" %} 6873 6874 ins_encode(aarch64_enc_ldar(dst, mem)); 6875 6876 ins_pipe(pipe_serial); 6877 %} 6878 6879 // Load Compressed Pointer 6880 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 6881 %{ 6882 match(Set dst (LoadN mem)); 6883 6884 ins_cost(VOLATILE_REF_COST); 6885 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 6886 6887 ins_encode(aarch64_enc_ldarw(dst, mem)); 6888 6889 ins_pipe(pipe_serial); 6890 %} 6891 6892 // Load Float 6893 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 6894 %{ 6895 match(Set dst (LoadF mem)); 6896 6897 ins_cost(VOLATILE_REF_COST); 6898 format %{ "ldars $dst, $mem\t# float" %} 6899 6900 ins_encode( aarch64_enc_fldars(dst, mem) ); 6901 6902 ins_pipe(pipe_serial); 6903 %} 6904 6905 // Load Double 6906 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 6907 %{ 6908 match(Set dst (LoadD mem)); 6909 6910 ins_cost(VOLATILE_REF_COST); 6911 format %{ "ldard $dst, $mem\t# double" %} 6912 6913 ins_encode( aarch64_enc_fldard(dst, mem) ); 6914 6915 ins_pipe(pipe_serial); 6916 %} 6917 6918 // Store Byte 6919 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 6920 %{ 6921 match(Set mem (StoreB mem src)); 6922 6923 ins_cost(VOLATILE_REF_COST); 6924 format %{ "stlrb $src, $mem\t# byte" %} 6925 6926 ins_encode(aarch64_enc_stlrb(src, mem)); 6927 6928 ins_pipe(pipe_class_memory); 6929 %} 6930 6931 // Store Char/Short 6932 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 6933 %{ 6934 match(Set mem (StoreC mem src)); 6935 6936 ins_cost(VOLATILE_REF_COST); 6937 format %{ "stlrh $src, $mem\t# short" %} 6938 6939 ins_encode(aarch64_enc_stlrh(src, mem)); 6940 6941 ins_pipe(pipe_class_memory); 6942 %} 6943 6944 // Store Integer 6945 6946 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 6947 %{ 6948 match(Set mem(StoreI mem src)); 6949 6950 ins_cost(VOLATILE_REF_COST); 6951 format %{ "stlrw $src, $mem\t# int" %} 6952 6953 ins_encode(aarch64_enc_stlrw(src, mem)); 6954 6955 ins_pipe(pipe_class_memory); 6956 %} 6957 6958 // Store Long (64 bit signed) 6959 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 6960 %{ 6961 match(Set mem (StoreL mem src)); 6962 6963 ins_cost(VOLATILE_REF_COST); 6964 format %{ "stlr $src, $mem\t# int" %} 6965 6966 ins_encode(aarch64_enc_stlr(src, mem)); 6967 6968 ins_pipe(pipe_class_memory); 6969 %} 6970 6971 // Store Pointer 6972 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 6973 %{ 6974 match(Set mem (StoreP mem src)); 6975 6976 ins_cost(VOLATILE_REF_COST); 6977 format %{ "stlr $src, $mem\t# ptr" %} 6978 6979 ins_encode(aarch64_enc_stlr(src, mem)); 6980 6981 ins_pipe(pipe_class_memory); 6982 %} 6983 6984 // Store Compressed Pointer 6985 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 6986 %{ 6987 match(Set mem (StoreN mem src)); 6988 6989 ins_cost(VOLATILE_REF_COST); 6990 format %{ "stlrw $src, $mem\t# compressed ptr" %} 6991 6992 ins_encode(aarch64_enc_stlrw(src, mem)); 6993 6994 ins_pipe(pipe_class_memory); 6995 %} 6996 6997 // Store Float 6998 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 6999 %{ 7000 match(Set mem (StoreF mem src)); 7001 7002 ins_cost(VOLATILE_REF_COST); 7003 format %{ "stlrs $src, $mem\t# float" %} 7004 7005 ins_encode( aarch64_enc_fstlrs(src, mem) ); 7006 7007 ins_pipe(pipe_class_memory); 7008 %} 7009 7010 // TODO 7011 // implement storeImmF0 and storeFImmPacked 7012 7013 // Store Double 7014 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 7015 %{ 7016 match(Set mem (StoreD mem src)); 7017 7018 ins_cost(VOLATILE_REF_COST); 7019 format %{ "stlrd $src, $mem\t# double" %} 7020 7021 ins_encode( aarch64_enc_fstlrd(src, mem) ); 7022 7023 ins_pipe(pipe_class_memory); 7024 %} 7025 7026 // ---------------- end of volatile loads and stores ---------------- 7027 7028 // ============================================================================ 7029 // BSWAP Instructions 7030 7031 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 7032 match(Set dst (ReverseBytesI src)); 7033 7034 ins_cost(INSN_COST); 7035 format %{ "revw $dst, $src" %} 7036 7037 ins_encode %{ 7038 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 7039 %} 7040 7041 ins_pipe(ialu_reg); 7042 %} 7043 7044 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 7045 match(Set dst (ReverseBytesL src)); 7046 7047 ins_cost(INSN_COST); 7048 format %{ "rev $dst, $src" %} 7049 7050 ins_encode %{ 7051 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 7052 %} 7053 7054 ins_pipe(ialu_reg); 7055 %} 7056 7057 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 7058 match(Set dst (ReverseBytesUS src)); 7059 7060 ins_cost(INSN_COST); 7061 format %{ "rev16w $dst, $src" %} 7062 7063 ins_encode %{ 7064 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7065 %} 7066 7067 ins_pipe(ialu_reg); 7068 %} 7069 7070 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7071 match(Set dst (ReverseBytesS src)); 7072 7073 ins_cost(INSN_COST); 7074 format %{ "rev16w $dst, $src\n\t" 7075 "sbfmw $dst, $dst, #0, #15" %} 7076 7077 ins_encode %{ 7078 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7079 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7080 %} 7081 7082 ins_pipe(ialu_reg); 7083 %} 7084 7085 // ============================================================================ 7086 // Zero Count Instructions 7087 7088 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7089 match(Set dst (CountLeadingZerosI src)); 7090 7091 ins_cost(INSN_COST); 7092 format %{ "clzw $dst, $src" %} 7093 ins_encode %{ 7094 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7095 %} 7096 7097 ins_pipe(ialu_reg); 7098 %} 7099 7100 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7101 match(Set dst (CountLeadingZerosL src)); 7102 7103 ins_cost(INSN_COST); 7104 format %{ "clz $dst, $src" %} 7105 ins_encode %{ 7106 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7107 %} 7108 7109 ins_pipe(ialu_reg); 7110 %} 7111 7112 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7113 match(Set dst (CountTrailingZerosI src)); 7114 7115 ins_cost(INSN_COST * 2); 7116 format %{ "rbitw $dst, $src\n\t" 7117 "clzw $dst, $dst" %} 7118 ins_encode %{ 7119 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 7120 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 7121 %} 7122 7123 ins_pipe(ialu_reg); 7124 %} 7125 7126 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 7127 match(Set dst (CountTrailingZerosL src)); 7128 7129 ins_cost(INSN_COST * 2); 7130 format %{ "rbit $dst, $src\n\t" 7131 "clz $dst, $dst" %} 7132 ins_encode %{ 7133 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 7134 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 7135 %} 7136 7137 ins_pipe(ialu_reg); 7138 %} 7139 7140 // ============================================================================ 7141 // MemBar Instruction 7142 7143 instruct load_fence() %{ 7144 match(LoadFence); 7145 ins_cost(VOLATILE_REF_COST); 7146 7147 format %{ "load_fence" %} 7148 7149 ins_encode %{ 7150 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7151 %} 7152 ins_pipe(pipe_serial); 7153 %} 7154 7155 instruct unnecessary_membar_acquire() %{ 7156 predicate(unnecessary_acquire(n)); 7157 match(MemBarAcquire); 7158 ins_cost(0); 7159 7160 format %{ "membar_acquire (elided)" %} 7161 7162 ins_encode %{ 7163 __ block_comment("membar_acquire (elided)"); 7164 %} 7165 7166 ins_pipe(pipe_class_empty); 7167 %} 7168 7169 instruct membar_acquire() %{ 7170 match(MemBarAcquire); 7171 ins_cost(VOLATILE_REF_COST); 7172 7173 format %{ "membar_acquire" %} 7174 7175 ins_encode %{ 7176 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7177 %} 7178 7179 ins_pipe(pipe_serial); 7180 %} 7181 7182 7183 instruct membar_acquire_lock() %{ 7184 match(MemBarAcquireLock); 7185 ins_cost(VOLATILE_REF_COST); 7186 7187 format %{ "membar_acquire_lock" %} 7188 7189 ins_encode %{ 7190 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7191 %} 7192 7193 ins_pipe(pipe_serial); 7194 %} 7195 7196 instruct store_fence() %{ 7197 match(StoreFence); 7198 ins_cost(VOLATILE_REF_COST); 7199 7200 format %{ "store_fence" %} 7201 7202 ins_encode %{ 7203 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7204 %} 7205 ins_pipe(pipe_serial); 7206 %} 7207 7208 instruct unnecessary_membar_release() %{ 7209 predicate(unnecessary_release(n)); 7210 match(MemBarRelease); 7211 ins_cost(0); 7212 7213 format %{ "membar_release (elided)" %} 7214 7215 ins_encode %{ 7216 __ block_comment("membar_release (elided)"); 7217 %} 7218 ins_pipe(pipe_serial); 7219 %} 7220 7221 instruct membar_release() %{ 7222 match(MemBarRelease); 7223 ins_cost(VOLATILE_REF_COST); 7224 7225 format %{ "membar_release" %} 7226 7227 ins_encode %{ 7228 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7229 %} 7230 ins_pipe(pipe_serial); 7231 %} 7232 7233 instruct membar_storestore() %{ 7234 match(MemBarStoreStore); 7235 ins_cost(VOLATILE_REF_COST); 7236 7237 format %{ "MEMBAR-store-store" %} 7238 7239 ins_encode %{ 7240 __ membar(Assembler::StoreStore); 7241 %} 7242 ins_pipe(pipe_serial); 7243 %} 7244 7245 instruct membar_release_lock() %{ 7246 match(MemBarReleaseLock); 7247 ins_cost(VOLATILE_REF_COST); 7248 7249 format %{ "membar_release_lock" %} 7250 7251 ins_encode %{ 7252 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7253 %} 7254 7255 ins_pipe(pipe_serial); 7256 %} 7257 7258 instruct unnecessary_membar_volatile() %{ 7259 predicate(unnecessary_volatile(n)); 7260 match(MemBarVolatile); 7261 ins_cost(0); 7262 7263 format %{ "membar_volatile (elided)" %} 7264 7265 ins_encode %{ 7266 __ block_comment("membar_volatile (elided)"); 7267 %} 7268 7269 ins_pipe(pipe_serial); 7270 %} 7271 7272 instruct membar_volatile() %{ 7273 match(MemBarVolatile); 7274 ins_cost(VOLATILE_REF_COST*100); 7275 7276 format %{ "membar_volatile" %} 7277 7278 ins_encode %{ 7279 __ membar(Assembler::StoreLoad); 7280 %} 7281 7282 ins_pipe(pipe_serial); 7283 %} 7284 7285 // ============================================================================ 7286 // Cast/Convert Instructions 7287 7288 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 7289 match(Set dst (CastX2P src)); 7290 7291 ins_cost(INSN_COST); 7292 format %{ "mov $dst, $src\t# long -> ptr" %} 7293 7294 ins_encode %{ 7295 if ($dst$$reg != $src$$reg) { 7296 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7297 } 7298 %} 7299 7300 ins_pipe(ialu_reg); 7301 %} 7302 7303 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 7304 match(Set dst (CastP2X src)); 7305 7306 ins_cost(INSN_COST); 7307 format %{ "mov $dst, $src\t# ptr -> long" %} 7308 7309 ins_encode %{ 7310 if ($dst$$reg != $src$$reg) { 7311 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7312 } 7313 %} 7314 7315 ins_pipe(ialu_reg); 7316 %} 7317 7318 // Convert oop into int for vectors alignment masking 7319 instruct convP2I(iRegINoSp dst, iRegP src) %{ 7320 match(Set dst (ConvL2I (CastP2X src))); 7321 7322 ins_cost(INSN_COST); 7323 format %{ "movw $dst, $src\t# ptr -> int" %} 7324 ins_encode %{ 7325 __ movw($dst$$Register, $src$$Register); 7326 %} 7327 7328 ins_pipe(ialu_reg); 7329 %} 7330 7331 // Convert compressed oop into int for vectors alignment masking 7332 // in case of 32bit oops (heap < 4Gb). 7333 instruct convN2I(iRegINoSp dst, iRegN src) 7334 %{ 7335 predicate(Universe::narrow_oop_shift() == 0); 7336 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7337 7338 ins_cost(INSN_COST); 7339 format %{ "mov dst, $src\t# compressed ptr -> int" %} 7340 ins_encode %{ 7341 __ movw($dst$$Register, $src$$Register); 7342 %} 7343 7344 ins_pipe(ialu_reg); 7345 %} 7346 7347 7348 // Convert oop pointer into compressed form 7349 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7350 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7351 match(Set dst (EncodeP src)); 7352 effect(KILL cr); 7353 ins_cost(INSN_COST * 3); 7354 format %{ "encode_heap_oop $dst, $src" %} 7355 ins_encode %{ 7356 Register s = $src$$Register; 7357 Register d = $dst$$Register; 7358 __ encode_heap_oop(d, s); 7359 %} 7360 ins_pipe(ialu_reg); 7361 %} 7362 7363 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7364 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7365 match(Set dst (EncodeP src)); 7366 ins_cost(INSN_COST * 3); 7367 format %{ "encode_heap_oop_not_null $dst, $src" %} 7368 ins_encode %{ 7369 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7370 %} 7371 ins_pipe(ialu_reg); 7372 %} 7373 7374 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7375 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 7376 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 7377 match(Set dst (DecodeN src)); 7378 ins_cost(INSN_COST * 3); 7379 format %{ "decode_heap_oop $dst, $src" %} 7380 ins_encode %{ 7381 Register s = $src$$Register; 7382 Register d = $dst$$Register; 7383 __ decode_heap_oop(d, s); 7384 %} 7385 ins_pipe(ialu_reg); 7386 %} 7387 7388 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7389 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7390 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7391 match(Set dst (DecodeN src)); 7392 ins_cost(INSN_COST * 3); 7393 format %{ "decode_heap_oop_not_null $dst, $src" %} 7394 ins_encode %{ 7395 Register s = $src$$Register; 7396 Register d = $dst$$Register; 7397 __ decode_heap_oop_not_null(d, s); 7398 %} 7399 ins_pipe(ialu_reg); 7400 %} 7401 7402 // n.b. AArch64 implementations of encode_klass_not_null and 7403 // decode_klass_not_null do not modify the flags register so, unlike 7404 // Intel, we don't kill CR as a side effect here 7405 7406 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 7407 match(Set dst (EncodePKlass src)); 7408 7409 ins_cost(INSN_COST * 3); 7410 format %{ "encode_klass_not_null $dst,$src" %} 7411 7412 ins_encode %{ 7413 Register src_reg = as_Register($src$$reg); 7414 Register dst_reg = as_Register($dst$$reg); 7415 __ encode_klass_not_null(dst_reg, src_reg); 7416 %} 7417 7418 ins_pipe(ialu_reg); 7419 %} 7420 7421 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 7422 match(Set dst (DecodeNKlass src)); 7423 7424 ins_cost(INSN_COST * 3); 7425 format %{ "decode_klass_not_null $dst,$src" %} 7426 7427 ins_encode %{ 7428 Register src_reg = as_Register($src$$reg); 7429 Register dst_reg = as_Register($dst$$reg); 7430 if (dst_reg != src_reg) { 7431 __ decode_klass_not_null(dst_reg, src_reg); 7432 } else { 7433 __ decode_klass_not_null(dst_reg); 7434 } 7435 %} 7436 7437 ins_pipe(ialu_reg); 7438 %} 7439 7440 instruct checkCastPP(iRegPNoSp dst) 7441 %{ 7442 match(Set dst (CheckCastPP dst)); 7443 7444 size(0); 7445 format %{ "# checkcastPP of $dst" %} 7446 ins_encode(/* empty encoding */); 7447 ins_pipe(pipe_class_empty); 7448 %} 7449 7450 instruct castPP(iRegPNoSp dst) 7451 %{ 7452 match(Set dst (CastPP dst)); 7453 7454 size(0); 7455 format %{ "# castPP of $dst" %} 7456 ins_encode(/* empty encoding */); 7457 ins_pipe(pipe_class_empty); 7458 %} 7459 7460 instruct castII(iRegI dst) 7461 %{ 7462 match(Set dst (CastII dst)); 7463 7464 size(0); 7465 format %{ "# castII of $dst" %} 7466 ins_encode(/* empty encoding */); 7467 ins_cost(0); 7468 ins_pipe(pipe_class_empty); 7469 %} 7470 7471 // ============================================================================ 7472 // Atomic operation instructions 7473 // 7474 // Intel and SPARC both implement Ideal Node LoadPLocked and 7475 // Store{PIL}Conditional instructions using a normal load for the 7476 // LoadPLocked and a CAS for the Store{PIL}Conditional. 7477 // 7478 // The ideal code appears only to use LoadPLocked/StorePLocked as a 7479 // pair to lock object allocations from Eden space when not using 7480 // TLABs. 7481 // 7482 // There does not appear to be a Load{IL}Locked Ideal Node and the 7483 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 7484 // and to use StoreIConditional only for 32-bit and StoreLConditional 7485 // only for 64-bit. 7486 // 7487 // We implement LoadPLocked and StorePLocked instructions using, 7488 // respectively the AArch64 hw load-exclusive and store-conditional 7489 // instructions. Whereas we must implement each of 7490 // Store{IL}Conditional using a CAS which employs a pair of 7491 // instructions comprising a load-exclusive followed by a 7492 // store-conditional. 7493 7494 7495 // Locked-load (linked load) of the current heap-top 7496 // used when updating the eden heap top 7497 // implemented using ldaxr on AArch64 7498 7499 instruct loadPLocked(iRegPNoSp dst, indirect mem) 7500 %{ 7501 match(Set dst (LoadPLocked mem)); 7502 7503 ins_cost(VOLATILE_REF_COST); 7504 7505 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 7506 7507 ins_encode(aarch64_enc_ldaxr(dst, mem)); 7508 7509 ins_pipe(pipe_serial); 7510 %} 7511 7512 // Conditional-store of the updated heap-top. 7513 // Used during allocation of the shared heap. 7514 // Sets flag (EQ) on success. 7515 // implemented using stlxr on AArch64. 7516 7517 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 7518 %{ 7519 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7520 7521 ins_cost(VOLATILE_REF_COST); 7522 7523 // TODO 7524 // do we need to do a store-conditional release or can we just use a 7525 // plain store-conditional? 7526 7527 format %{ 7528 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 7529 "cmpw rscratch1, zr\t# EQ on successful write" 7530 %} 7531 7532 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 7533 7534 ins_pipe(pipe_serial); 7535 %} 7536 7537 // this has to be implemented as a CAS 7538 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 7539 %{ 7540 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7541 7542 ins_cost(VOLATILE_REF_COST); 7543 7544 format %{ 7545 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 7546 "cmpw rscratch1, zr\t# EQ on successful write" 7547 %} 7548 7549 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval)); 7550 7551 ins_pipe(pipe_slow); 7552 %} 7553 7554 // this has to be implemented as a CAS 7555 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 7556 %{ 7557 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7558 7559 ins_cost(VOLATILE_REF_COST); 7560 7561 format %{ 7562 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 7563 "cmpw rscratch1, zr\t# EQ on successful write" 7564 %} 7565 7566 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval)); 7567 7568 ins_pipe(pipe_slow); 7569 %} 7570 7571 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 7572 // can't match them 7573 7574 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 7575 7576 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 7577 7578 effect(KILL cr); 7579 7580 format %{ 7581 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 7582 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7583 %} 7584 7585 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 7586 aarch64_enc_cset_eq(res)); 7587 7588 ins_pipe(pipe_slow); 7589 %} 7590 7591 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 7592 7593 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 7594 7595 effect(KILL cr); 7596 7597 format %{ 7598 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 7599 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7600 %} 7601 7602 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 7603 aarch64_enc_cset_eq(res)); 7604 7605 ins_pipe(pipe_slow); 7606 %} 7607 7608 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 7609 7610 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 7611 7612 effect(KILL cr); 7613 7614 format %{ 7615 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 7616 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7617 %} 7618 7619 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 7620 aarch64_enc_cset_eq(res)); 7621 7622 ins_pipe(pipe_slow); 7623 %} 7624 7625 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 7626 7627 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 7628 7629 effect(KILL cr); 7630 7631 format %{ 7632 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 7633 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7634 %} 7635 7636 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 7637 aarch64_enc_cset_eq(res)); 7638 7639 ins_pipe(pipe_slow); 7640 %} 7641 7642 7643 instruct get_and_setI(indirect mem, iRegINoSp newv, iRegI prev) %{ 7644 match(Set prev (GetAndSetI mem newv)); 7645 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 7646 ins_encode %{ 7647 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7648 %} 7649 ins_pipe(pipe_serial); 7650 %} 7651 7652 instruct get_and_setL(indirect mem, iRegLNoSp newv, iRegL prev) %{ 7653 match(Set prev (GetAndSetL mem newv)); 7654 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 7655 ins_encode %{ 7656 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7657 %} 7658 ins_pipe(pipe_serial); 7659 %} 7660 7661 instruct get_and_setN(indirect mem, iRegNNoSp newv, iRegI prev) %{ 7662 match(Set prev (GetAndSetN mem newv)); 7663 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 7664 ins_encode %{ 7665 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7666 %} 7667 ins_pipe(pipe_serial); 7668 %} 7669 7670 instruct get_and_setP(indirect mem, iRegPNoSp newv, iRegP prev) %{ 7671 match(Set prev (GetAndSetP mem newv)); 7672 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 7673 ins_encode %{ 7674 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7675 %} 7676 ins_pipe(pipe_serial); 7677 %} 7678 7679 7680 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 7681 match(Set newval (GetAndAddL mem incr)); 7682 ins_cost(INSN_COST * 10); 7683 format %{ "get_and_addL $newval, [$mem], $incr" %} 7684 ins_encode %{ 7685 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 7686 %} 7687 ins_pipe(pipe_serial); 7688 %} 7689 7690 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 7691 predicate(n->as_LoadStore()->result_not_used()); 7692 match(Set dummy (GetAndAddL mem incr)); 7693 ins_cost(INSN_COST * 9); 7694 format %{ "get_and_addL [$mem], $incr" %} 7695 ins_encode %{ 7696 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 7697 %} 7698 ins_pipe(pipe_serial); 7699 %} 7700 7701 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 7702 match(Set newval (GetAndAddL mem incr)); 7703 ins_cost(INSN_COST * 10); 7704 format %{ "get_and_addL $newval, [$mem], $incr" %} 7705 ins_encode %{ 7706 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 7707 %} 7708 ins_pipe(pipe_serial); 7709 %} 7710 7711 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 7712 predicate(n->as_LoadStore()->result_not_used()); 7713 match(Set dummy (GetAndAddL mem incr)); 7714 ins_cost(INSN_COST * 9); 7715 format %{ "get_and_addL [$mem], $incr" %} 7716 ins_encode %{ 7717 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 7718 %} 7719 ins_pipe(pipe_serial); 7720 %} 7721 7722 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 7723 match(Set newval (GetAndAddI mem incr)); 7724 ins_cost(INSN_COST * 10); 7725 format %{ "get_and_addI $newval, [$mem], $incr" %} 7726 ins_encode %{ 7727 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 7728 %} 7729 ins_pipe(pipe_serial); 7730 %} 7731 7732 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 7733 predicate(n->as_LoadStore()->result_not_used()); 7734 match(Set dummy (GetAndAddI mem incr)); 7735 ins_cost(INSN_COST * 9); 7736 format %{ "get_and_addI [$mem], $incr" %} 7737 ins_encode %{ 7738 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 7739 %} 7740 ins_pipe(pipe_serial); 7741 %} 7742 7743 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 7744 match(Set newval (GetAndAddI mem incr)); 7745 ins_cost(INSN_COST * 10); 7746 format %{ "get_and_addI $newval, [$mem], $incr" %} 7747 ins_encode %{ 7748 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 7749 %} 7750 ins_pipe(pipe_serial); 7751 %} 7752 7753 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 7754 predicate(n->as_LoadStore()->result_not_used()); 7755 match(Set dummy (GetAndAddI mem incr)); 7756 ins_cost(INSN_COST * 9); 7757 format %{ "get_and_addI [$mem], $incr" %} 7758 ins_encode %{ 7759 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 7760 %} 7761 ins_pipe(pipe_serial); 7762 %} 7763 7764 // Manifest a CmpL result in an integer register. 7765 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 7766 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 7767 %{ 7768 match(Set dst (CmpL3 src1 src2)); 7769 effect(KILL flags); 7770 7771 ins_cost(INSN_COST * 6); 7772 format %{ 7773 "cmp $src1, $src2" 7774 "csetw $dst, ne" 7775 "cnegw $dst, lt" 7776 %} 7777 // format %{ "CmpL3 $dst, $src1, $src2" %} 7778 ins_encode %{ 7779 __ cmp($src1$$Register, $src2$$Register); 7780 __ csetw($dst$$Register, Assembler::NE); 7781 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 7782 %} 7783 7784 ins_pipe(pipe_class_default); 7785 %} 7786 7787 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 7788 %{ 7789 match(Set dst (CmpL3 src1 src2)); 7790 effect(KILL flags); 7791 7792 ins_cost(INSN_COST * 6); 7793 format %{ 7794 "cmp $src1, $src2" 7795 "csetw $dst, ne" 7796 "cnegw $dst, lt" 7797 %} 7798 ins_encode %{ 7799 int32_t con = (int32_t)$src2$$constant; 7800 if (con < 0) { 7801 __ adds(zr, $src1$$Register, -con); 7802 } else { 7803 __ subs(zr, $src1$$Register, con); 7804 } 7805 __ csetw($dst$$Register, Assembler::NE); 7806 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 7807 %} 7808 7809 ins_pipe(pipe_class_default); 7810 %} 7811 7812 // ============================================================================ 7813 // Conditional Move Instructions 7814 7815 // n.b. we have identical rules for both a signed compare op (cmpOp) 7816 // and an unsigned compare op (cmpOpU). it would be nice if we could 7817 // define an op class which merged both inputs and use it to type the 7818 // argument to a single rule. unfortunatelyt his fails because the 7819 // opclass does not live up to the COND_INTER interface of its 7820 // component operands. When the generic code tries to negate the 7821 // operand it ends up running the generci Machoper::negate method 7822 // which throws a ShouldNotHappen. So, we have to provide two flavours 7823 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 7824 7825 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7826 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 7827 7828 ins_cost(INSN_COST * 2); 7829 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 7830 7831 ins_encode %{ 7832 __ cselw(as_Register($dst$$reg), 7833 as_Register($src2$$reg), 7834 as_Register($src1$$reg), 7835 (Assembler::Condition)$cmp$$cmpcode); 7836 %} 7837 7838 ins_pipe(icond_reg_reg); 7839 %} 7840 7841 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7842 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 7843 7844 ins_cost(INSN_COST * 2); 7845 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 7846 7847 ins_encode %{ 7848 __ cselw(as_Register($dst$$reg), 7849 as_Register($src2$$reg), 7850 as_Register($src1$$reg), 7851 (Assembler::Condition)$cmp$$cmpcode); 7852 %} 7853 7854 ins_pipe(icond_reg_reg); 7855 %} 7856 7857 // special cases where one arg is zero 7858 7859 // n.b. this is selected in preference to the rule above because it 7860 // avoids loading constant 0 into a source register 7861 7862 // TODO 7863 // we ought only to be able to cull one of these variants as the ideal 7864 // transforms ought always to order the zero consistently (to left/right?) 7865 7866 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 7867 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 7868 7869 ins_cost(INSN_COST * 2); 7870 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 7871 7872 ins_encode %{ 7873 __ cselw(as_Register($dst$$reg), 7874 as_Register($src$$reg), 7875 zr, 7876 (Assembler::Condition)$cmp$$cmpcode); 7877 %} 7878 7879 ins_pipe(icond_reg); 7880 %} 7881 7882 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 7883 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 7884 7885 ins_cost(INSN_COST * 2); 7886 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 7887 7888 ins_encode %{ 7889 __ cselw(as_Register($dst$$reg), 7890 as_Register($src$$reg), 7891 zr, 7892 (Assembler::Condition)$cmp$$cmpcode); 7893 %} 7894 7895 ins_pipe(icond_reg); 7896 %} 7897 7898 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 7899 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 7900 7901 ins_cost(INSN_COST * 2); 7902 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 7903 7904 ins_encode %{ 7905 __ cselw(as_Register($dst$$reg), 7906 zr, 7907 as_Register($src$$reg), 7908 (Assembler::Condition)$cmp$$cmpcode); 7909 %} 7910 7911 ins_pipe(icond_reg); 7912 %} 7913 7914 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 7915 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 7916 7917 ins_cost(INSN_COST * 2); 7918 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 7919 7920 ins_encode %{ 7921 __ cselw(as_Register($dst$$reg), 7922 zr, 7923 as_Register($src$$reg), 7924 (Assembler::Condition)$cmp$$cmpcode); 7925 %} 7926 7927 ins_pipe(icond_reg); 7928 %} 7929 7930 // special case for creating a boolean 0 or 1 7931 7932 // n.b. this is selected in preference to the rule above because it 7933 // avoids loading constants 0 and 1 into a source register 7934 7935 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 7936 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 7937 7938 ins_cost(INSN_COST * 2); 7939 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 7940 7941 ins_encode %{ 7942 // equivalently 7943 // cset(as_Register($dst$$reg), 7944 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 7945 __ csincw(as_Register($dst$$reg), 7946 zr, 7947 zr, 7948 (Assembler::Condition)$cmp$$cmpcode); 7949 %} 7950 7951 ins_pipe(icond_none); 7952 %} 7953 7954 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 7955 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 7956 7957 ins_cost(INSN_COST * 2); 7958 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 7959 7960 ins_encode %{ 7961 // equivalently 7962 // cset(as_Register($dst$$reg), 7963 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 7964 __ csincw(as_Register($dst$$reg), 7965 zr, 7966 zr, 7967 (Assembler::Condition)$cmp$$cmpcode); 7968 %} 7969 7970 ins_pipe(icond_none); 7971 %} 7972 7973 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7974 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 7975 7976 ins_cost(INSN_COST * 2); 7977 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 7978 7979 ins_encode %{ 7980 __ csel(as_Register($dst$$reg), 7981 as_Register($src2$$reg), 7982 as_Register($src1$$reg), 7983 (Assembler::Condition)$cmp$$cmpcode); 7984 %} 7985 7986 ins_pipe(icond_reg_reg); 7987 %} 7988 7989 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7990 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 7991 7992 ins_cost(INSN_COST * 2); 7993 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 7994 7995 ins_encode %{ 7996 __ csel(as_Register($dst$$reg), 7997 as_Register($src2$$reg), 7998 as_Register($src1$$reg), 7999 (Assembler::Condition)$cmp$$cmpcode); 8000 %} 8001 8002 ins_pipe(icond_reg_reg); 8003 %} 8004 8005 // special cases where one arg is zero 8006 8007 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 8008 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 8009 8010 ins_cost(INSN_COST * 2); 8011 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 8012 8013 ins_encode %{ 8014 __ csel(as_Register($dst$$reg), 8015 zr, 8016 as_Register($src$$reg), 8017 (Assembler::Condition)$cmp$$cmpcode); 8018 %} 8019 8020 ins_pipe(icond_reg); 8021 %} 8022 8023 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 8024 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 8025 8026 ins_cost(INSN_COST * 2); 8027 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 8028 8029 ins_encode %{ 8030 __ csel(as_Register($dst$$reg), 8031 zr, 8032 as_Register($src$$reg), 8033 (Assembler::Condition)$cmp$$cmpcode); 8034 %} 8035 8036 ins_pipe(icond_reg); 8037 %} 8038 8039 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 8040 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 8041 8042 ins_cost(INSN_COST * 2); 8043 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 8044 8045 ins_encode %{ 8046 __ csel(as_Register($dst$$reg), 8047 as_Register($src$$reg), 8048 zr, 8049 (Assembler::Condition)$cmp$$cmpcode); 8050 %} 8051 8052 ins_pipe(icond_reg); 8053 %} 8054 8055 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 8056 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 8057 8058 ins_cost(INSN_COST * 2); 8059 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 8060 8061 ins_encode %{ 8062 __ csel(as_Register($dst$$reg), 8063 as_Register($src$$reg), 8064 zr, 8065 (Assembler::Condition)$cmp$$cmpcode); 8066 %} 8067 8068 ins_pipe(icond_reg); 8069 %} 8070 8071 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 8072 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 8073 8074 ins_cost(INSN_COST * 2); 8075 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 8076 8077 ins_encode %{ 8078 __ csel(as_Register($dst$$reg), 8079 as_Register($src2$$reg), 8080 as_Register($src1$$reg), 8081 (Assembler::Condition)$cmp$$cmpcode); 8082 %} 8083 8084 ins_pipe(icond_reg_reg); 8085 %} 8086 8087 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 8088 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 8089 8090 ins_cost(INSN_COST * 2); 8091 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 8092 8093 ins_encode %{ 8094 __ csel(as_Register($dst$$reg), 8095 as_Register($src2$$reg), 8096 as_Register($src1$$reg), 8097 (Assembler::Condition)$cmp$$cmpcode); 8098 %} 8099 8100 ins_pipe(icond_reg_reg); 8101 %} 8102 8103 // special cases where one arg is zero 8104 8105 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 8106 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 8107 8108 ins_cost(INSN_COST * 2); 8109 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 8110 8111 ins_encode %{ 8112 __ csel(as_Register($dst$$reg), 8113 zr, 8114 as_Register($src$$reg), 8115 (Assembler::Condition)$cmp$$cmpcode); 8116 %} 8117 8118 ins_pipe(icond_reg); 8119 %} 8120 8121 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 8122 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 8123 8124 ins_cost(INSN_COST * 2); 8125 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 8126 8127 ins_encode %{ 8128 __ csel(as_Register($dst$$reg), 8129 zr, 8130 as_Register($src$$reg), 8131 (Assembler::Condition)$cmp$$cmpcode); 8132 %} 8133 8134 ins_pipe(icond_reg); 8135 %} 8136 8137 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 8138 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 8139 8140 ins_cost(INSN_COST * 2); 8141 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 8142 8143 ins_encode %{ 8144 __ csel(as_Register($dst$$reg), 8145 as_Register($src$$reg), 8146 zr, 8147 (Assembler::Condition)$cmp$$cmpcode); 8148 %} 8149 8150 ins_pipe(icond_reg); 8151 %} 8152 8153 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 8154 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 8155 8156 ins_cost(INSN_COST * 2); 8157 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 8158 8159 ins_encode %{ 8160 __ csel(as_Register($dst$$reg), 8161 as_Register($src$$reg), 8162 zr, 8163 (Assembler::Condition)$cmp$$cmpcode); 8164 %} 8165 8166 ins_pipe(icond_reg); 8167 %} 8168 8169 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 8170 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 8171 8172 ins_cost(INSN_COST * 2); 8173 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 8174 8175 ins_encode %{ 8176 __ cselw(as_Register($dst$$reg), 8177 as_Register($src2$$reg), 8178 as_Register($src1$$reg), 8179 (Assembler::Condition)$cmp$$cmpcode); 8180 %} 8181 8182 ins_pipe(icond_reg_reg); 8183 %} 8184 8185 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 8186 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 8187 8188 ins_cost(INSN_COST * 2); 8189 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 8190 8191 ins_encode %{ 8192 __ cselw(as_Register($dst$$reg), 8193 as_Register($src2$$reg), 8194 as_Register($src1$$reg), 8195 (Assembler::Condition)$cmp$$cmpcode); 8196 %} 8197 8198 ins_pipe(icond_reg_reg); 8199 %} 8200 8201 // special cases where one arg is zero 8202 8203 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 8204 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 8205 8206 ins_cost(INSN_COST * 2); 8207 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 8208 8209 ins_encode %{ 8210 __ cselw(as_Register($dst$$reg), 8211 zr, 8212 as_Register($src$$reg), 8213 (Assembler::Condition)$cmp$$cmpcode); 8214 %} 8215 8216 ins_pipe(icond_reg); 8217 %} 8218 8219 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 8220 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 8221 8222 ins_cost(INSN_COST * 2); 8223 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 8224 8225 ins_encode %{ 8226 __ cselw(as_Register($dst$$reg), 8227 zr, 8228 as_Register($src$$reg), 8229 (Assembler::Condition)$cmp$$cmpcode); 8230 %} 8231 8232 ins_pipe(icond_reg); 8233 %} 8234 8235 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 8236 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 8237 8238 ins_cost(INSN_COST * 2); 8239 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 8240 8241 ins_encode %{ 8242 __ cselw(as_Register($dst$$reg), 8243 as_Register($src$$reg), 8244 zr, 8245 (Assembler::Condition)$cmp$$cmpcode); 8246 %} 8247 8248 ins_pipe(icond_reg); 8249 %} 8250 8251 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 8252 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 8253 8254 ins_cost(INSN_COST * 2); 8255 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 8256 8257 ins_encode %{ 8258 __ cselw(as_Register($dst$$reg), 8259 as_Register($src$$reg), 8260 zr, 8261 (Assembler::Condition)$cmp$$cmpcode); 8262 %} 8263 8264 ins_pipe(icond_reg); 8265 %} 8266 8267 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 8268 %{ 8269 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 8270 8271 ins_cost(INSN_COST * 3); 8272 8273 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 8274 ins_encode %{ 8275 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8276 __ fcsels(as_FloatRegister($dst$$reg), 8277 as_FloatRegister($src2$$reg), 8278 as_FloatRegister($src1$$reg), 8279 cond); 8280 %} 8281 8282 ins_pipe(pipe_class_default); 8283 %} 8284 8285 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 8286 %{ 8287 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 8288 8289 ins_cost(INSN_COST * 3); 8290 8291 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 8292 ins_encode %{ 8293 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8294 __ fcsels(as_FloatRegister($dst$$reg), 8295 as_FloatRegister($src2$$reg), 8296 as_FloatRegister($src1$$reg), 8297 cond); 8298 %} 8299 8300 ins_pipe(pipe_class_default); 8301 %} 8302 8303 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 8304 %{ 8305 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 8306 8307 ins_cost(INSN_COST * 3); 8308 8309 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 8310 ins_encode %{ 8311 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8312 __ fcseld(as_FloatRegister($dst$$reg), 8313 as_FloatRegister($src2$$reg), 8314 as_FloatRegister($src1$$reg), 8315 cond); 8316 %} 8317 8318 ins_pipe(pipe_class_default); 8319 %} 8320 8321 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 8322 %{ 8323 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 8324 8325 ins_cost(INSN_COST * 3); 8326 8327 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 8328 ins_encode %{ 8329 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8330 __ fcseld(as_FloatRegister($dst$$reg), 8331 as_FloatRegister($src2$$reg), 8332 as_FloatRegister($src1$$reg), 8333 cond); 8334 %} 8335 8336 ins_pipe(pipe_class_default); 8337 %} 8338 8339 // ============================================================================ 8340 // Arithmetic Instructions 8341 // 8342 8343 // Integer Addition 8344 8345 // TODO 8346 // these currently employ operations which do not set CR and hence are 8347 // not flagged as killing CR but we would like to isolate the cases 8348 // where we want to set flags from those where we don't. need to work 8349 // out how to do that. 8350 8351 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8352 match(Set dst (AddI src1 src2)); 8353 8354 ins_cost(INSN_COST); 8355 format %{ "addw $dst, $src1, $src2" %} 8356 8357 ins_encode %{ 8358 __ addw(as_Register($dst$$reg), 8359 as_Register($src1$$reg), 8360 as_Register($src2$$reg)); 8361 %} 8362 8363 ins_pipe(ialu_reg_reg); 8364 %} 8365 8366 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 8367 match(Set dst (AddI src1 src2)); 8368 8369 ins_cost(INSN_COST); 8370 format %{ "addw $dst, $src1, $src2" %} 8371 8372 // use opcode to indicate that this is an add not a sub 8373 opcode(0x0); 8374 8375 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 8376 8377 ins_pipe(ialu_reg_imm); 8378 %} 8379 8380 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 8381 match(Set dst (AddI (ConvL2I src1) src2)); 8382 8383 ins_cost(INSN_COST); 8384 format %{ "addw $dst, $src1, $src2" %} 8385 8386 // use opcode to indicate that this is an add not a sub 8387 opcode(0x0); 8388 8389 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 8390 8391 ins_pipe(ialu_reg_imm); 8392 %} 8393 8394 // Pointer Addition 8395 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 8396 match(Set dst (AddP src1 src2)); 8397 8398 ins_cost(INSN_COST); 8399 format %{ "add $dst, $src1, $src2\t# ptr" %} 8400 8401 ins_encode %{ 8402 __ add(as_Register($dst$$reg), 8403 as_Register($src1$$reg), 8404 as_Register($src2$$reg)); 8405 %} 8406 8407 ins_pipe(ialu_reg_reg); 8408 %} 8409 8410 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 8411 match(Set dst (AddP src1 (ConvI2L src2))); 8412 8413 ins_cost(1.9 * INSN_COST); 8414 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 8415 8416 ins_encode %{ 8417 __ add(as_Register($dst$$reg), 8418 as_Register($src1$$reg), 8419 as_Register($src2$$reg), ext::sxtw); 8420 %} 8421 8422 ins_pipe(ialu_reg_reg); 8423 %} 8424 8425 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 8426 match(Set dst (AddP src1 (LShiftL src2 scale))); 8427 8428 ins_cost(1.9 * INSN_COST); 8429 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 8430 8431 ins_encode %{ 8432 __ lea(as_Register($dst$$reg), 8433 Address(as_Register($src1$$reg), as_Register($src2$$reg), 8434 Address::lsl($scale$$constant))); 8435 %} 8436 8437 ins_pipe(ialu_reg_reg_shift); 8438 %} 8439 8440 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 8441 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 8442 8443 ins_cost(1.9 * INSN_COST); 8444 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 8445 8446 ins_encode %{ 8447 __ lea(as_Register($dst$$reg), 8448 Address(as_Register($src1$$reg), as_Register($src2$$reg), 8449 Address::sxtw($scale$$constant))); 8450 %} 8451 8452 ins_pipe(ialu_reg_reg_shift); 8453 %} 8454 8455 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 8456 match(Set dst (LShiftL (ConvI2L src) scale)); 8457 8458 ins_cost(INSN_COST); 8459 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 8460 8461 ins_encode %{ 8462 __ sbfiz(as_Register($dst$$reg), 8463 as_Register($src$$reg), 8464 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 8465 %} 8466 8467 ins_pipe(ialu_reg_shift); 8468 %} 8469 8470 // Pointer Immediate Addition 8471 // n.b. this needs to be more expensive than using an indirect memory 8472 // operand 8473 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 8474 match(Set dst (AddP src1 src2)); 8475 8476 ins_cost(INSN_COST); 8477 format %{ "add $dst, $src1, $src2\t# ptr" %} 8478 8479 // use opcode to indicate that this is an add not a sub 8480 opcode(0x0); 8481 8482 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 8483 8484 ins_pipe(ialu_reg_imm); 8485 %} 8486 8487 // Long Addition 8488 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8489 8490 match(Set dst (AddL src1 src2)); 8491 8492 ins_cost(INSN_COST); 8493 format %{ "add $dst, $src1, $src2" %} 8494 8495 ins_encode %{ 8496 __ add(as_Register($dst$$reg), 8497 as_Register($src1$$reg), 8498 as_Register($src2$$reg)); 8499 %} 8500 8501 ins_pipe(ialu_reg_reg); 8502 %} 8503 8504 // No constant pool entries requiredLong Immediate Addition. 8505 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 8506 match(Set dst (AddL src1 src2)); 8507 8508 ins_cost(INSN_COST); 8509 format %{ "add $dst, $src1, $src2" %} 8510 8511 // use opcode to indicate that this is an add not a sub 8512 opcode(0x0); 8513 8514 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 8515 8516 ins_pipe(ialu_reg_imm); 8517 %} 8518 8519 // Integer Subtraction 8520 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8521 match(Set dst (SubI src1 src2)); 8522 8523 ins_cost(INSN_COST); 8524 format %{ "subw $dst, $src1, $src2" %} 8525 8526 ins_encode %{ 8527 __ subw(as_Register($dst$$reg), 8528 as_Register($src1$$reg), 8529 as_Register($src2$$reg)); 8530 %} 8531 8532 ins_pipe(ialu_reg_reg); 8533 %} 8534 8535 // Immediate Subtraction 8536 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 8537 match(Set dst (SubI src1 src2)); 8538 8539 ins_cost(INSN_COST); 8540 format %{ "subw $dst, $src1, $src2" %} 8541 8542 // use opcode to indicate that this is a sub not an add 8543 opcode(0x1); 8544 8545 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 8546 8547 ins_pipe(ialu_reg_imm); 8548 %} 8549 8550 // Long Subtraction 8551 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8552 8553 match(Set dst (SubL src1 src2)); 8554 8555 ins_cost(INSN_COST); 8556 format %{ "sub $dst, $src1, $src2" %} 8557 8558 ins_encode %{ 8559 __ sub(as_Register($dst$$reg), 8560 as_Register($src1$$reg), 8561 as_Register($src2$$reg)); 8562 %} 8563 8564 ins_pipe(ialu_reg_reg); 8565 %} 8566 8567 // No constant pool entries requiredLong Immediate Subtraction. 8568 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 8569 match(Set dst (SubL src1 src2)); 8570 8571 ins_cost(INSN_COST); 8572 format %{ "sub$dst, $src1, $src2" %} 8573 8574 // use opcode to indicate that this is a sub not an add 8575 opcode(0x1); 8576 8577 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 8578 8579 ins_pipe(ialu_reg_imm); 8580 %} 8581 8582 // Integer Negation (special case for sub) 8583 8584 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 8585 match(Set dst (SubI zero src)); 8586 8587 ins_cost(INSN_COST); 8588 format %{ "negw $dst, $src\t# int" %} 8589 8590 ins_encode %{ 8591 __ negw(as_Register($dst$$reg), 8592 as_Register($src$$reg)); 8593 %} 8594 8595 ins_pipe(ialu_reg); 8596 %} 8597 8598 // Long Negation 8599 8600 instruct negL_reg(iRegLNoSp dst, iRegIorL2I src, immL0 zero, rFlagsReg cr) %{ 8601 match(Set dst (SubL zero src)); 8602 8603 ins_cost(INSN_COST); 8604 format %{ "neg $dst, $src\t# long" %} 8605 8606 ins_encode %{ 8607 __ neg(as_Register($dst$$reg), 8608 as_Register($src$$reg)); 8609 %} 8610 8611 ins_pipe(ialu_reg); 8612 %} 8613 8614 // Integer Multiply 8615 8616 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8617 match(Set dst (MulI src1 src2)); 8618 8619 ins_cost(INSN_COST * 3); 8620 format %{ "mulw $dst, $src1, $src2" %} 8621 8622 ins_encode %{ 8623 __ mulw(as_Register($dst$$reg), 8624 as_Register($src1$$reg), 8625 as_Register($src2$$reg)); 8626 %} 8627 8628 ins_pipe(imul_reg_reg); 8629 %} 8630 8631 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8632 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 8633 8634 ins_cost(INSN_COST * 3); 8635 format %{ "smull $dst, $src1, $src2" %} 8636 8637 ins_encode %{ 8638 __ smull(as_Register($dst$$reg), 8639 as_Register($src1$$reg), 8640 as_Register($src2$$reg)); 8641 %} 8642 8643 ins_pipe(imul_reg_reg); 8644 %} 8645 8646 // Long Multiply 8647 8648 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8649 match(Set dst (MulL src1 src2)); 8650 8651 ins_cost(INSN_COST * 5); 8652 format %{ "mul $dst, $src1, $src2" %} 8653 8654 ins_encode %{ 8655 __ mul(as_Register($dst$$reg), 8656 as_Register($src1$$reg), 8657 as_Register($src2$$reg)); 8658 %} 8659 8660 ins_pipe(lmul_reg_reg); 8661 %} 8662 8663 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 8664 %{ 8665 match(Set dst (MulHiL src1 src2)); 8666 8667 ins_cost(INSN_COST * 7); 8668 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 8669 8670 ins_encode %{ 8671 __ smulh(as_Register($dst$$reg), 8672 as_Register($src1$$reg), 8673 as_Register($src2$$reg)); 8674 %} 8675 8676 ins_pipe(lmul_reg_reg); 8677 %} 8678 8679 // Combined Integer Multiply & Add/Sub 8680 8681 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 8682 match(Set dst (AddI src3 (MulI src1 src2))); 8683 8684 ins_cost(INSN_COST * 3); 8685 format %{ "madd $dst, $src1, $src2, $src3" %} 8686 8687 ins_encode %{ 8688 __ maddw(as_Register($dst$$reg), 8689 as_Register($src1$$reg), 8690 as_Register($src2$$reg), 8691 as_Register($src3$$reg)); 8692 %} 8693 8694 ins_pipe(imac_reg_reg); 8695 %} 8696 8697 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 8698 match(Set dst (SubI src3 (MulI src1 src2))); 8699 8700 ins_cost(INSN_COST * 3); 8701 format %{ "msub $dst, $src1, $src2, $src3" %} 8702 8703 ins_encode %{ 8704 __ msubw(as_Register($dst$$reg), 8705 as_Register($src1$$reg), 8706 as_Register($src2$$reg), 8707 as_Register($src3$$reg)); 8708 %} 8709 8710 ins_pipe(imac_reg_reg); 8711 %} 8712 8713 // Combined Long Multiply & Add/Sub 8714 8715 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 8716 match(Set dst (AddL src3 (MulL src1 src2))); 8717 8718 ins_cost(INSN_COST * 5); 8719 format %{ "madd $dst, $src1, $src2, $src3" %} 8720 8721 ins_encode %{ 8722 __ madd(as_Register($dst$$reg), 8723 as_Register($src1$$reg), 8724 as_Register($src2$$reg), 8725 as_Register($src3$$reg)); 8726 %} 8727 8728 ins_pipe(lmac_reg_reg); 8729 %} 8730 8731 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 8732 match(Set dst (SubL src3 (MulL src1 src2))); 8733 8734 ins_cost(INSN_COST * 5); 8735 format %{ "msub $dst, $src1, $src2, $src3" %} 8736 8737 ins_encode %{ 8738 __ msub(as_Register($dst$$reg), 8739 as_Register($src1$$reg), 8740 as_Register($src2$$reg), 8741 as_Register($src3$$reg)); 8742 %} 8743 8744 ins_pipe(lmac_reg_reg); 8745 %} 8746 8747 // Integer Divide 8748 8749 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8750 match(Set dst (DivI src1 src2)); 8751 8752 ins_cost(INSN_COST * 19); 8753 format %{ "sdivw $dst, $src1, $src2" %} 8754 8755 ins_encode(aarch64_enc_divw(dst, src1, src2)); 8756 ins_pipe(idiv_reg_reg); 8757 %} 8758 8759 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 8760 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 8761 ins_cost(INSN_COST); 8762 format %{ "lsrw $dst, $src1, $div1" %} 8763 ins_encode %{ 8764 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 8765 %} 8766 ins_pipe(ialu_reg_shift); 8767 %} 8768 8769 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 8770 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 8771 ins_cost(INSN_COST); 8772 format %{ "addw $dst, $src, LSR $div1" %} 8773 8774 ins_encode %{ 8775 __ addw(as_Register($dst$$reg), 8776 as_Register($src$$reg), 8777 as_Register($src$$reg), 8778 Assembler::LSR, 31); 8779 %} 8780 ins_pipe(ialu_reg); 8781 %} 8782 8783 // Long Divide 8784 8785 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8786 match(Set dst (DivL src1 src2)); 8787 8788 ins_cost(INSN_COST * 35); 8789 format %{ "sdiv $dst, $src1, $src2" %} 8790 8791 ins_encode(aarch64_enc_div(dst, src1, src2)); 8792 ins_pipe(ldiv_reg_reg); 8793 %} 8794 8795 instruct signExtractL(iRegLNoSp dst, iRegL src1, immL_63 div1, immL_63 div2) %{ 8796 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 8797 ins_cost(INSN_COST); 8798 format %{ "lsr $dst, $src1, $div1" %} 8799 ins_encode %{ 8800 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 8801 %} 8802 ins_pipe(ialu_reg_shift); 8803 %} 8804 8805 instruct div2RoundL(iRegLNoSp dst, iRegL src, immL_63 div1, immL_63 div2) %{ 8806 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 8807 ins_cost(INSN_COST); 8808 format %{ "add $dst, $src, $div1" %} 8809 8810 ins_encode %{ 8811 __ add(as_Register($dst$$reg), 8812 as_Register($src$$reg), 8813 as_Register($src$$reg), 8814 Assembler::LSR, 63); 8815 %} 8816 ins_pipe(ialu_reg); 8817 %} 8818 8819 // Integer Remainder 8820 8821 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8822 match(Set dst (ModI src1 src2)); 8823 8824 ins_cost(INSN_COST * 22); 8825 format %{ "sdivw rscratch1, $src1, $src2\n\t" 8826 "msubw($dst, rscratch1, $src2, $src1" %} 8827 8828 ins_encode(aarch64_enc_modw(dst, src1, src2)); 8829 ins_pipe(idiv_reg_reg); 8830 %} 8831 8832 // Long Remainder 8833 8834 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8835 match(Set dst (ModL src1 src2)); 8836 8837 ins_cost(INSN_COST * 38); 8838 format %{ "sdiv rscratch1, $src1, $src2\n" 8839 "msub($dst, rscratch1, $src2, $src1" %} 8840 8841 ins_encode(aarch64_enc_mod(dst, src1, src2)); 8842 ins_pipe(ldiv_reg_reg); 8843 %} 8844 8845 // Integer Shifts 8846 8847 // Shift Left Register 8848 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8849 match(Set dst (LShiftI src1 src2)); 8850 8851 ins_cost(INSN_COST * 2); 8852 format %{ "lslvw $dst, $src1, $src2" %} 8853 8854 ins_encode %{ 8855 __ lslvw(as_Register($dst$$reg), 8856 as_Register($src1$$reg), 8857 as_Register($src2$$reg)); 8858 %} 8859 8860 ins_pipe(ialu_reg_reg_vshift); 8861 %} 8862 8863 // Shift Left Immediate 8864 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8865 match(Set dst (LShiftI src1 src2)); 8866 8867 ins_cost(INSN_COST); 8868 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 8869 8870 ins_encode %{ 8871 __ lslw(as_Register($dst$$reg), 8872 as_Register($src1$$reg), 8873 $src2$$constant & 0x1f); 8874 %} 8875 8876 ins_pipe(ialu_reg_shift); 8877 %} 8878 8879 // Shift Right Logical Register 8880 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8881 match(Set dst (URShiftI src1 src2)); 8882 8883 ins_cost(INSN_COST * 2); 8884 format %{ "lsrvw $dst, $src1, $src2" %} 8885 8886 ins_encode %{ 8887 __ lsrvw(as_Register($dst$$reg), 8888 as_Register($src1$$reg), 8889 as_Register($src2$$reg)); 8890 %} 8891 8892 ins_pipe(ialu_reg_reg_vshift); 8893 %} 8894 8895 // Shift Right Logical Immediate 8896 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8897 match(Set dst (URShiftI src1 src2)); 8898 8899 ins_cost(INSN_COST); 8900 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 8901 8902 ins_encode %{ 8903 __ lsrw(as_Register($dst$$reg), 8904 as_Register($src1$$reg), 8905 $src2$$constant & 0x1f); 8906 %} 8907 8908 ins_pipe(ialu_reg_shift); 8909 %} 8910 8911 // Shift Right Arithmetic Register 8912 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8913 match(Set dst (RShiftI src1 src2)); 8914 8915 ins_cost(INSN_COST * 2); 8916 format %{ "asrvw $dst, $src1, $src2" %} 8917 8918 ins_encode %{ 8919 __ asrvw(as_Register($dst$$reg), 8920 as_Register($src1$$reg), 8921 as_Register($src2$$reg)); 8922 %} 8923 8924 ins_pipe(ialu_reg_reg_vshift); 8925 %} 8926 8927 // Shift Right Arithmetic Immediate 8928 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8929 match(Set dst (RShiftI src1 src2)); 8930 8931 ins_cost(INSN_COST); 8932 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 8933 8934 ins_encode %{ 8935 __ asrw(as_Register($dst$$reg), 8936 as_Register($src1$$reg), 8937 $src2$$constant & 0x1f); 8938 %} 8939 8940 ins_pipe(ialu_reg_shift); 8941 %} 8942 8943 // Combined Int Mask and Right Shift (using UBFM) 8944 // TODO 8945 8946 // Long Shifts 8947 8948 // Shift Left Register 8949 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 8950 match(Set dst (LShiftL src1 src2)); 8951 8952 ins_cost(INSN_COST * 2); 8953 format %{ "lslv $dst, $src1, $src2" %} 8954 8955 ins_encode %{ 8956 __ lslv(as_Register($dst$$reg), 8957 as_Register($src1$$reg), 8958 as_Register($src2$$reg)); 8959 %} 8960 8961 ins_pipe(ialu_reg_reg_vshift); 8962 %} 8963 8964 // Shift Left Immediate 8965 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 8966 match(Set dst (LShiftL src1 src2)); 8967 8968 ins_cost(INSN_COST); 8969 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 8970 8971 ins_encode %{ 8972 __ lsl(as_Register($dst$$reg), 8973 as_Register($src1$$reg), 8974 $src2$$constant & 0x3f); 8975 %} 8976 8977 ins_pipe(ialu_reg_shift); 8978 %} 8979 8980 // Shift Right Logical Register 8981 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 8982 match(Set dst (URShiftL src1 src2)); 8983 8984 ins_cost(INSN_COST * 2); 8985 format %{ "lsrv $dst, $src1, $src2" %} 8986 8987 ins_encode %{ 8988 __ lsrv(as_Register($dst$$reg), 8989 as_Register($src1$$reg), 8990 as_Register($src2$$reg)); 8991 %} 8992 8993 ins_pipe(ialu_reg_reg_vshift); 8994 %} 8995 8996 // Shift Right Logical Immediate 8997 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 8998 match(Set dst (URShiftL src1 src2)); 8999 9000 ins_cost(INSN_COST); 9001 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 9002 9003 ins_encode %{ 9004 __ lsr(as_Register($dst$$reg), 9005 as_Register($src1$$reg), 9006 $src2$$constant & 0x3f); 9007 %} 9008 9009 ins_pipe(ialu_reg_shift); 9010 %} 9011 9012 // A special-case pattern for card table stores. 9013 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 9014 match(Set dst (URShiftL (CastP2X src1) src2)); 9015 9016 ins_cost(INSN_COST); 9017 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 9018 9019 ins_encode %{ 9020 __ lsr(as_Register($dst$$reg), 9021 as_Register($src1$$reg), 9022 $src2$$constant & 0x3f); 9023 %} 9024 9025 ins_pipe(ialu_reg_shift); 9026 %} 9027 9028 // Shift Right Arithmetic Register 9029 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 9030 match(Set dst (RShiftL src1 src2)); 9031 9032 ins_cost(INSN_COST * 2); 9033 format %{ "asrv $dst, $src1, $src2" %} 9034 9035 ins_encode %{ 9036 __ asrv(as_Register($dst$$reg), 9037 as_Register($src1$$reg), 9038 as_Register($src2$$reg)); 9039 %} 9040 9041 ins_pipe(ialu_reg_reg_vshift); 9042 %} 9043 9044 // Shift Right Arithmetic Immediate 9045 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 9046 match(Set dst (RShiftL src1 src2)); 9047 9048 ins_cost(INSN_COST); 9049 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 9050 9051 ins_encode %{ 9052 __ asr(as_Register($dst$$reg), 9053 as_Register($src1$$reg), 9054 $src2$$constant & 0x3f); 9055 %} 9056 9057 ins_pipe(ialu_reg_shift); 9058 %} 9059 9060 // BEGIN This section of the file is automatically generated. Do not edit -------------- 9061 9062 instruct regL_not_reg(iRegLNoSp dst, 9063 iRegL src1, immL_M1 m1, 9064 rFlagsReg cr) %{ 9065 match(Set dst (XorL src1 m1)); 9066 ins_cost(INSN_COST); 9067 format %{ "eon $dst, $src1, zr" %} 9068 9069 ins_encode %{ 9070 __ eon(as_Register($dst$$reg), 9071 as_Register($src1$$reg), 9072 zr, 9073 Assembler::LSL, 0); 9074 %} 9075 9076 ins_pipe(ialu_reg); 9077 %} 9078 instruct regI_not_reg(iRegINoSp dst, 9079 iRegIorL2I src1, immI_M1 m1, 9080 rFlagsReg cr) %{ 9081 match(Set dst (XorI src1 m1)); 9082 ins_cost(INSN_COST); 9083 format %{ "eonw $dst, $src1, zr" %} 9084 9085 ins_encode %{ 9086 __ eonw(as_Register($dst$$reg), 9087 as_Register($src1$$reg), 9088 zr, 9089 Assembler::LSL, 0); 9090 %} 9091 9092 ins_pipe(ialu_reg); 9093 %} 9094 9095 instruct AndI_reg_not_reg(iRegINoSp dst, 9096 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 9097 rFlagsReg cr) %{ 9098 match(Set dst (AndI src1 (XorI src2 m1))); 9099 ins_cost(INSN_COST); 9100 format %{ "bicw $dst, $src1, $src2" %} 9101 9102 ins_encode %{ 9103 __ bicw(as_Register($dst$$reg), 9104 as_Register($src1$$reg), 9105 as_Register($src2$$reg), 9106 Assembler::LSL, 0); 9107 %} 9108 9109 ins_pipe(ialu_reg_reg); 9110 %} 9111 9112 instruct AndL_reg_not_reg(iRegLNoSp dst, 9113 iRegL src1, iRegL src2, immL_M1 m1, 9114 rFlagsReg cr) %{ 9115 match(Set dst (AndL src1 (XorL src2 m1))); 9116 ins_cost(INSN_COST); 9117 format %{ "bic $dst, $src1, $src2" %} 9118 9119 ins_encode %{ 9120 __ bic(as_Register($dst$$reg), 9121 as_Register($src1$$reg), 9122 as_Register($src2$$reg), 9123 Assembler::LSL, 0); 9124 %} 9125 9126 ins_pipe(ialu_reg_reg); 9127 %} 9128 9129 instruct OrI_reg_not_reg(iRegINoSp dst, 9130 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 9131 rFlagsReg cr) %{ 9132 match(Set dst (OrI src1 (XorI src2 m1))); 9133 ins_cost(INSN_COST); 9134 format %{ "ornw $dst, $src1, $src2" %} 9135 9136 ins_encode %{ 9137 __ ornw(as_Register($dst$$reg), 9138 as_Register($src1$$reg), 9139 as_Register($src2$$reg), 9140 Assembler::LSL, 0); 9141 %} 9142 9143 ins_pipe(ialu_reg_reg); 9144 %} 9145 9146 instruct OrL_reg_not_reg(iRegLNoSp dst, 9147 iRegL src1, iRegL src2, immL_M1 m1, 9148 rFlagsReg cr) %{ 9149 match(Set dst (OrL src1 (XorL src2 m1))); 9150 ins_cost(INSN_COST); 9151 format %{ "orn $dst, $src1, $src2" %} 9152 9153 ins_encode %{ 9154 __ orn(as_Register($dst$$reg), 9155 as_Register($src1$$reg), 9156 as_Register($src2$$reg), 9157 Assembler::LSL, 0); 9158 %} 9159 9160 ins_pipe(ialu_reg_reg); 9161 %} 9162 9163 instruct XorI_reg_not_reg(iRegINoSp dst, 9164 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 9165 rFlagsReg cr) %{ 9166 match(Set dst (XorI m1 (XorI src2 src1))); 9167 ins_cost(INSN_COST); 9168 format %{ "eonw $dst, $src1, $src2" %} 9169 9170 ins_encode %{ 9171 __ eonw(as_Register($dst$$reg), 9172 as_Register($src1$$reg), 9173 as_Register($src2$$reg), 9174 Assembler::LSL, 0); 9175 %} 9176 9177 ins_pipe(ialu_reg_reg); 9178 %} 9179 9180 instruct XorL_reg_not_reg(iRegLNoSp dst, 9181 iRegL src1, iRegL src2, immL_M1 m1, 9182 rFlagsReg cr) %{ 9183 match(Set dst (XorL m1 (XorL src2 src1))); 9184 ins_cost(INSN_COST); 9185 format %{ "eon $dst, $src1, $src2" %} 9186 9187 ins_encode %{ 9188 __ eon(as_Register($dst$$reg), 9189 as_Register($src1$$reg), 9190 as_Register($src2$$reg), 9191 Assembler::LSL, 0); 9192 %} 9193 9194 ins_pipe(ialu_reg_reg); 9195 %} 9196 9197 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 9198 iRegIorL2I src1, iRegIorL2I src2, 9199 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9200 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 9201 ins_cost(1.9 * INSN_COST); 9202 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 9203 9204 ins_encode %{ 9205 __ bicw(as_Register($dst$$reg), 9206 as_Register($src1$$reg), 9207 as_Register($src2$$reg), 9208 Assembler::LSR, 9209 $src3$$constant & 0x3f); 9210 %} 9211 9212 ins_pipe(ialu_reg_reg_shift); 9213 %} 9214 9215 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 9216 iRegL src1, iRegL src2, 9217 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9218 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 9219 ins_cost(1.9 * INSN_COST); 9220 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 9221 9222 ins_encode %{ 9223 __ bic(as_Register($dst$$reg), 9224 as_Register($src1$$reg), 9225 as_Register($src2$$reg), 9226 Assembler::LSR, 9227 $src3$$constant & 0x3f); 9228 %} 9229 9230 ins_pipe(ialu_reg_reg_shift); 9231 %} 9232 9233 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 9234 iRegIorL2I src1, iRegIorL2I src2, 9235 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9236 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 9237 ins_cost(1.9 * INSN_COST); 9238 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 9239 9240 ins_encode %{ 9241 __ bicw(as_Register($dst$$reg), 9242 as_Register($src1$$reg), 9243 as_Register($src2$$reg), 9244 Assembler::ASR, 9245 $src3$$constant & 0x3f); 9246 %} 9247 9248 ins_pipe(ialu_reg_reg_shift); 9249 %} 9250 9251 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 9252 iRegL src1, iRegL src2, 9253 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9254 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 9255 ins_cost(1.9 * INSN_COST); 9256 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 9257 9258 ins_encode %{ 9259 __ bic(as_Register($dst$$reg), 9260 as_Register($src1$$reg), 9261 as_Register($src2$$reg), 9262 Assembler::ASR, 9263 $src3$$constant & 0x3f); 9264 %} 9265 9266 ins_pipe(ialu_reg_reg_shift); 9267 %} 9268 9269 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 9270 iRegIorL2I src1, iRegIorL2I src2, 9271 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9272 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 9273 ins_cost(1.9 * INSN_COST); 9274 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 9275 9276 ins_encode %{ 9277 __ bicw(as_Register($dst$$reg), 9278 as_Register($src1$$reg), 9279 as_Register($src2$$reg), 9280 Assembler::LSL, 9281 $src3$$constant & 0x3f); 9282 %} 9283 9284 ins_pipe(ialu_reg_reg_shift); 9285 %} 9286 9287 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 9288 iRegL src1, iRegL src2, 9289 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9290 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 9291 ins_cost(1.9 * INSN_COST); 9292 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 9293 9294 ins_encode %{ 9295 __ bic(as_Register($dst$$reg), 9296 as_Register($src1$$reg), 9297 as_Register($src2$$reg), 9298 Assembler::LSL, 9299 $src3$$constant & 0x3f); 9300 %} 9301 9302 ins_pipe(ialu_reg_reg_shift); 9303 %} 9304 9305 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 9306 iRegIorL2I src1, iRegIorL2I src2, 9307 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9308 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 9309 ins_cost(1.9 * INSN_COST); 9310 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 9311 9312 ins_encode %{ 9313 __ eonw(as_Register($dst$$reg), 9314 as_Register($src1$$reg), 9315 as_Register($src2$$reg), 9316 Assembler::LSR, 9317 $src3$$constant & 0x3f); 9318 %} 9319 9320 ins_pipe(ialu_reg_reg_shift); 9321 %} 9322 9323 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 9324 iRegL src1, iRegL src2, 9325 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9326 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 9327 ins_cost(1.9 * INSN_COST); 9328 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 9329 9330 ins_encode %{ 9331 __ eon(as_Register($dst$$reg), 9332 as_Register($src1$$reg), 9333 as_Register($src2$$reg), 9334 Assembler::LSR, 9335 $src3$$constant & 0x3f); 9336 %} 9337 9338 ins_pipe(ialu_reg_reg_shift); 9339 %} 9340 9341 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 9342 iRegIorL2I src1, iRegIorL2I src2, 9343 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9344 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 9345 ins_cost(1.9 * INSN_COST); 9346 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 9347 9348 ins_encode %{ 9349 __ eonw(as_Register($dst$$reg), 9350 as_Register($src1$$reg), 9351 as_Register($src2$$reg), 9352 Assembler::ASR, 9353 $src3$$constant & 0x3f); 9354 %} 9355 9356 ins_pipe(ialu_reg_reg_shift); 9357 %} 9358 9359 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 9360 iRegL src1, iRegL src2, 9361 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9362 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 9363 ins_cost(1.9 * INSN_COST); 9364 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 9365 9366 ins_encode %{ 9367 __ eon(as_Register($dst$$reg), 9368 as_Register($src1$$reg), 9369 as_Register($src2$$reg), 9370 Assembler::ASR, 9371 $src3$$constant & 0x3f); 9372 %} 9373 9374 ins_pipe(ialu_reg_reg_shift); 9375 %} 9376 9377 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 9378 iRegIorL2I src1, iRegIorL2I src2, 9379 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9380 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 9381 ins_cost(1.9 * INSN_COST); 9382 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 9383 9384 ins_encode %{ 9385 __ eonw(as_Register($dst$$reg), 9386 as_Register($src1$$reg), 9387 as_Register($src2$$reg), 9388 Assembler::LSL, 9389 $src3$$constant & 0x3f); 9390 %} 9391 9392 ins_pipe(ialu_reg_reg_shift); 9393 %} 9394 9395 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 9396 iRegL src1, iRegL src2, 9397 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9398 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 9399 ins_cost(1.9 * INSN_COST); 9400 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 9401 9402 ins_encode %{ 9403 __ eon(as_Register($dst$$reg), 9404 as_Register($src1$$reg), 9405 as_Register($src2$$reg), 9406 Assembler::LSL, 9407 $src3$$constant & 0x3f); 9408 %} 9409 9410 ins_pipe(ialu_reg_reg_shift); 9411 %} 9412 9413 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 9414 iRegIorL2I src1, iRegIorL2I src2, 9415 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9416 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 9417 ins_cost(1.9 * INSN_COST); 9418 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 9419 9420 ins_encode %{ 9421 __ ornw(as_Register($dst$$reg), 9422 as_Register($src1$$reg), 9423 as_Register($src2$$reg), 9424 Assembler::LSR, 9425 $src3$$constant & 0x3f); 9426 %} 9427 9428 ins_pipe(ialu_reg_reg_shift); 9429 %} 9430 9431 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 9432 iRegL src1, iRegL src2, 9433 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9434 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 9435 ins_cost(1.9 * INSN_COST); 9436 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 9437 9438 ins_encode %{ 9439 __ orn(as_Register($dst$$reg), 9440 as_Register($src1$$reg), 9441 as_Register($src2$$reg), 9442 Assembler::LSR, 9443 $src3$$constant & 0x3f); 9444 %} 9445 9446 ins_pipe(ialu_reg_reg_shift); 9447 %} 9448 9449 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 9450 iRegIorL2I src1, iRegIorL2I src2, 9451 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9452 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 9453 ins_cost(1.9 * INSN_COST); 9454 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 9455 9456 ins_encode %{ 9457 __ ornw(as_Register($dst$$reg), 9458 as_Register($src1$$reg), 9459 as_Register($src2$$reg), 9460 Assembler::ASR, 9461 $src3$$constant & 0x3f); 9462 %} 9463 9464 ins_pipe(ialu_reg_reg_shift); 9465 %} 9466 9467 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 9468 iRegL src1, iRegL src2, 9469 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9470 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 9471 ins_cost(1.9 * INSN_COST); 9472 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 9473 9474 ins_encode %{ 9475 __ orn(as_Register($dst$$reg), 9476 as_Register($src1$$reg), 9477 as_Register($src2$$reg), 9478 Assembler::ASR, 9479 $src3$$constant & 0x3f); 9480 %} 9481 9482 ins_pipe(ialu_reg_reg_shift); 9483 %} 9484 9485 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 9486 iRegIorL2I src1, iRegIorL2I src2, 9487 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9488 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 9489 ins_cost(1.9 * INSN_COST); 9490 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 9491 9492 ins_encode %{ 9493 __ ornw(as_Register($dst$$reg), 9494 as_Register($src1$$reg), 9495 as_Register($src2$$reg), 9496 Assembler::LSL, 9497 $src3$$constant & 0x3f); 9498 %} 9499 9500 ins_pipe(ialu_reg_reg_shift); 9501 %} 9502 9503 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 9504 iRegL src1, iRegL src2, 9505 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9506 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 9507 ins_cost(1.9 * INSN_COST); 9508 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 9509 9510 ins_encode %{ 9511 __ orn(as_Register($dst$$reg), 9512 as_Register($src1$$reg), 9513 as_Register($src2$$reg), 9514 Assembler::LSL, 9515 $src3$$constant & 0x3f); 9516 %} 9517 9518 ins_pipe(ialu_reg_reg_shift); 9519 %} 9520 9521 instruct AndI_reg_URShift_reg(iRegINoSp dst, 9522 iRegIorL2I src1, iRegIorL2I src2, 9523 immI src3, rFlagsReg cr) %{ 9524 match(Set dst (AndI src1 (URShiftI src2 src3))); 9525 9526 ins_cost(1.9 * INSN_COST); 9527 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 9528 9529 ins_encode %{ 9530 __ andw(as_Register($dst$$reg), 9531 as_Register($src1$$reg), 9532 as_Register($src2$$reg), 9533 Assembler::LSR, 9534 $src3$$constant & 0x3f); 9535 %} 9536 9537 ins_pipe(ialu_reg_reg_shift); 9538 %} 9539 9540 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 9541 iRegL src1, iRegL src2, 9542 immI src3, rFlagsReg cr) %{ 9543 match(Set dst (AndL src1 (URShiftL src2 src3))); 9544 9545 ins_cost(1.9 * INSN_COST); 9546 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 9547 9548 ins_encode %{ 9549 __ andr(as_Register($dst$$reg), 9550 as_Register($src1$$reg), 9551 as_Register($src2$$reg), 9552 Assembler::LSR, 9553 $src3$$constant & 0x3f); 9554 %} 9555 9556 ins_pipe(ialu_reg_reg_shift); 9557 %} 9558 9559 instruct AndI_reg_RShift_reg(iRegINoSp dst, 9560 iRegIorL2I src1, iRegIorL2I src2, 9561 immI src3, rFlagsReg cr) %{ 9562 match(Set dst (AndI src1 (RShiftI src2 src3))); 9563 9564 ins_cost(1.9 * INSN_COST); 9565 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 9566 9567 ins_encode %{ 9568 __ andw(as_Register($dst$$reg), 9569 as_Register($src1$$reg), 9570 as_Register($src2$$reg), 9571 Assembler::ASR, 9572 $src3$$constant & 0x3f); 9573 %} 9574 9575 ins_pipe(ialu_reg_reg_shift); 9576 %} 9577 9578 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 9579 iRegL src1, iRegL src2, 9580 immI src3, rFlagsReg cr) %{ 9581 match(Set dst (AndL src1 (RShiftL src2 src3))); 9582 9583 ins_cost(1.9 * INSN_COST); 9584 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 9585 9586 ins_encode %{ 9587 __ andr(as_Register($dst$$reg), 9588 as_Register($src1$$reg), 9589 as_Register($src2$$reg), 9590 Assembler::ASR, 9591 $src3$$constant & 0x3f); 9592 %} 9593 9594 ins_pipe(ialu_reg_reg_shift); 9595 %} 9596 9597 instruct AndI_reg_LShift_reg(iRegINoSp dst, 9598 iRegIorL2I src1, iRegIorL2I src2, 9599 immI src3, rFlagsReg cr) %{ 9600 match(Set dst (AndI src1 (LShiftI src2 src3))); 9601 9602 ins_cost(1.9 * INSN_COST); 9603 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 9604 9605 ins_encode %{ 9606 __ andw(as_Register($dst$$reg), 9607 as_Register($src1$$reg), 9608 as_Register($src2$$reg), 9609 Assembler::LSL, 9610 $src3$$constant & 0x3f); 9611 %} 9612 9613 ins_pipe(ialu_reg_reg_shift); 9614 %} 9615 9616 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 9617 iRegL src1, iRegL src2, 9618 immI src3, rFlagsReg cr) %{ 9619 match(Set dst (AndL src1 (LShiftL src2 src3))); 9620 9621 ins_cost(1.9 * INSN_COST); 9622 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 9623 9624 ins_encode %{ 9625 __ andr(as_Register($dst$$reg), 9626 as_Register($src1$$reg), 9627 as_Register($src2$$reg), 9628 Assembler::LSL, 9629 $src3$$constant & 0x3f); 9630 %} 9631 9632 ins_pipe(ialu_reg_reg_shift); 9633 %} 9634 9635 instruct XorI_reg_URShift_reg(iRegINoSp dst, 9636 iRegIorL2I src1, iRegIorL2I src2, 9637 immI src3, rFlagsReg cr) %{ 9638 match(Set dst (XorI src1 (URShiftI src2 src3))); 9639 9640 ins_cost(1.9 * INSN_COST); 9641 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 9642 9643 ins_encode %{ 9644 __ eorw(as_Register($dst$$reg), 9645 as_Register($src1$$reg), 9646 as_Register($src2$$reg), 9647 Assembler::LSR, 9648 $src3$$constant & 0x3f); 9649 %} 9650 9651 ins_pipe(ialu_reg_reg_shift); 9652 %} 9653 9654 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 9655 iRegL src1, iRegL src2, 9656 immI src3, rFlagsReg cr) %{ 9657 match(Set dst (XorL src1 (URShiftL src2 src3))); 9658 9659 ins_cost(1.9 * INSN_COST); 9660 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 9661 9662 ins_encode %{ 9663 __ eor(as_Register($dst$$reg), 9664 as_Register($src1$$reg), 9665 as_Register($src2$$reg), 9666 Assembler::LSR, 9667 $src3$$constant & 0x3f); 9668 %} 9669 9670 ins_pipe(ialu_reg_reg_shift); 9671 %} 9672 9673 instruct XorI_reg_RShift_reg(iRegINoSp dst, 9674 iRegIorL2I src1, iRegIorL2I src2, 9675 immI src3, rFlagsReg cr) %{ 9676 match(Set dst (XorI src1 (RShiftI src2 src3))); 9677 9678 ins_cost(1.9 * INSN_COST); 9679 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 9680 9681 ins_encode %{ 9682 __ eorw(as_Register($dst$$reg), 9683 as_Register($src1$$reg), 9684 as_Register($src2$$reg), 9685 Assembler::ASR, 9686 $src3$$constant & 0x3f); 9687 %} 9688 9689 ins_pipe(ialu_reg_reg_shift); 9690 %} 9691 9692 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 9693 iRegL src1, iRegL src2, 9694 immI src3, rFlagsReg cr) %{ 9695 match(Set dst (XorL src1 (RShiftL src2 src3))); 9696 9697 ins_cost(1.9 * INSN_COST); 9698 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 9699 9700 ins_encode %{ 9701 __ eor(as_Register($dst$$reg), 9702 as_Register($src1$$reg), 9703 as_Register($src2$$reg), 9704 Assembler::ASR, 9705 $src3$$constant & 0x3f); 9706 %} 9707 9708 ins_pipe(ialu_reg_reg_shift); 9709 %} 9710 9711 instruct XorI_reg_LShift_reg(iRegINoSp dst, 9712 iRegIorL2I src1, iRegIorL2I src2, 9713 immI src3, rFlagsReg cr) %{ 9714 match(Set dst (XorI src1 (LShiftI src2 src3))); 9715 9716 ins_cost(1.9 * INSN_COST); 9717 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 9718 9719 ins_encode %{ 9720 __ eorw(as_Register($dst$$reg), 9721 as_Register($src1$$reg), 9722 as_Register($src2$$reg), 9723 Assembler::LSL, 9724 $src3$$constant & 0x3f); 9725 %} 9726 9727 ins_pipe(ialu_reg_reg_shift); 9728 %} 9729 9730 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 9731 iRegL src1, iRegL src2, 9732 immI src3, rFlagsReg cr) %{ 9733 match(Set dst (XorL src1 (LShiftL src2 src3))); 9734 9735 ins_cost(1.9 * INSN_COST); 9736 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 9737 9738 ins_encode %{ 9739 __ eor(as_Register($dst$$reg), 9740 as_Register($src1$$reg), 9741 as_Register($src2$$reg), 9742 Assembler::LSL, 9743 $src3$$constant & 0x3f); 9744 %} 9745 9746 ins_pipe(ialu_reg_reg_shift); 9747 %} 9748 9749 instruct OrI_reg_URShift_reg(iRegINoSp dst, 9750 iRegIorL2I src1, iRegIorL2I src2, 9751 immI src3, rFlagsReg cr) %{ 9752 match(Set dst (OrI src1 (URShiftI src2 src3))); 9753 9754 ins_cost(1.9 * INSN_COST); 9755 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 9756 9757 ins_encode %{ 9758 __ orrw(as_Register($dst$$reg), 9759 as_Register($src1$$reg), 9760 as_Register($src2$$reg), 9761 Assembler::LSR, 9762 $src3$$constant & 0x3f); 9763 %} 9764 9765 ins_pipe(ialu_reg_reg_shift); 9766 %} 9767 9768 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 9769 iRegL src1, iRegL src2, 9770 immI src3, rFlagsReg cr) %{ 9771 match(Set dst (OrL src1 (URShiftL src2 src3))); 9772 9773 ins_cost(1.9 * INSN_COST); 9774 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 9775 9776 ins_encode %{ 9777 __ orr(as_Register($dst$$reg), 9778 as_Register($src1$$reg), 9779 as_Register($src2$$reg), 9780 Assembler::LSR, 9781 $src3$$constant & 0x3f); 9782 %} 9783 9784 ins_pipe(ialu_reg_reg_shift); 9785 %} 9786 9787 instruct OrI_reg_RShift_reg(iRegINoSp dst, 9788 iRegIorL2I src1, iRegIorL2I src2, 9789 immI src3, rFlagsReg cr) %{ 9790 match(Set dst (OrI src1 (RShiftI src2 src3))); 9791 9792 ins_cost(1.9 * INSN_COST); 9793 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 9794 9795 ins_encode %{ 9796 __ orrw(as_Register($dst$$reg), 9797 as_Register($src1$$reg), 9798 as_Register($src2$$reg), 9799 Assembler::ASR, 9800 $src3$$constant & 0x3f); 9801 %} 9802 9803 ins_pipe(ialu_reg_reg_shift); 9804 %} 9805 9806 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 9807 iRegL src1, iRegL src2, 9808 immI src3, rFlagsReg cr) %{ 9809 match(Set dst (OrL src1 (RShiftL src2 src3))); 9810 9811 ins_cost(1.9 * INSN_COST); 9812 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 9813 9814 ins_encode %{ 9815 __ orr(as_Register($dst$$reg), 9816 as_Register($src1$$reg), 9817 as_Register($src2$$reg), 9818 Assembler::ASR, 9819 $src3$$constant & 0x3f); 9820 %} 9821 9822 ins_pipe(ialu_reg_reg_shift); 9823 %} 9824 9825 instruct OrI_reg_LShift_reg(iRegINoSp dst, 9826 iRegIorL2I src1, iRegIorL2I src2, 9827 immI src3, rFlagsReg cr) %{ 9828 match(Set dst (OrI src1 (LShiftI src2 src3))); 9829 9830 ins_cost(1.9 * INSN_COST); 9831 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 9832 9833 ins_encode %{ 9834 __ orrw(as_Register($dst$$reg), 9835 as_Register($src1$$reg), 9836 as_Register($src2$$reg), 9837 Assembler::LSL, 9838 $src3$$constant & 0x3f); 9839 %} 9840 9841 ins_pipe(ialu_reg_reg_shift); 9842 %} 9843 9844 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 9845 iRegL src1, iRegL src2, 9846 immI src3, rFlagsReg cr) %{ 9847 match(Set dst (OrL src1 (LShiftL src2 src3))); 9848 9849 ins_cost(1.9 * INSN_COST); 9850 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 9851 9852 ins_encode %{ 9853 __ orr(as_Register($dst$$reg), 9854 as_Register($src1$$reg), 9855 as_Register($src2$$reg), 9856 Assembler::LSL, 9857 $src3$$constant & 0x3f); 9858 %} 9859 9860 ins_pipe(ialu_reg_reg_shift); 9861 %} 9862 9863 instruct AddI_reg_URShift_reg(iRegINoSp dst, 9864 iRegIorL2I src1, iRegIorL2I src2, 9865 immI src3, rFlagsReg cr) %{ 9866 match(Set dst (AddI src1 (URShiftI src2 src3))); 9867 9868 ins_cost(1.9 * INSN_COST); 9869 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 9870 9871 ins_encode %{ 9872 __ addw(as_Register($dst$$reg), 9873 as_Register($src1$$reg), 9874 as_Register($src2$$reg), 9875 Assembler::LSR, 9876 $src3$$constant & 0x3f); 9877 %} 9878 9879 ins_pipe(ialu_reg_reg_shift); 9880 %} 9881 9882 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 9883 iRegL src1, iRegL src2, 9884 immI src3, rFlagsReg cr) %{ 9885 match(Set dst (AddL src1 (URShiftL src2 src3))); 9886 9887 ins_cost(1.9 * INSN_COST); 9888 format %{ "add $dst, $src1, $src2, LSR $src3" %} 9889 9890 ins_encode %{ 9891 __ add(as_Register($dst$$reg), 9892 as_Register($src1$$reg), 9893 as_Register($src2$$reg), 9894 Assembler::LSR, 9895 $src3$$constant & 0x3f); 9896 %} 9897 9898 ins_pipe(ialu_reg_reg_shift); 9899 %} 9900 9901 instruct AddI_reg_RShift_reg(iRegINoSp dst, 9902 iRegIorL2I src1, iRegIorL2I src2, 9903 immI src3, rFlagsReg cr) %{ 9904 match(Set dst (AddI src1 (RShiftI src2 src3))); 9905 9906 ins_cost(1.9 * INSN_COST); 9907 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 9908 9909 ins_encode %{ 9910 __ addw(as_Register($dst$$reg), 9911 as_Register($src1$$reg), 9912 as_Register($src2$$reg), 9913 Assembler::ASR, 9914 $src3$$constant & 0x3f); 9915 %} 9916 9917 ins_pipe(ialu_reg_reg_shift); 9918 %} 9919 9920 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 9921 iRegL src1, iRegL src2, 9922 immI src3, rFlagsReg cr) %{ 9923 match(Set dst (AddL src1 (RShiftL src2 src3))); 9924 9925 ins_cost(1.9 * INSN_COST); 9926 format %{ "add $dst, $src1, $src2, ASR $src3" %} 9927 9928 ins_encode %{ 9929 __ add(as_Register($dst$$reg), 9930 as_Register($src1$$reg), 9931 as_Register($src2$$reg), 9932 Assembler::ASR, 9933 $src3$$constant & 0x3f); 9934 %} 9935 9936 ins_pipe(ialu_reg_reg_shift); 9937 %} 9938 9939 instruct AddI_reg_LShift_reg(iRegINoSp dst, 9940 iRegIorL2I src1, iRegIorL2I src2, 9941 immI src3, rFlagsReg cr) %{ 9942 match(Set dst (AddI src1 (LShiftI src2 src3))); 9943 9944 ins_cost(1.9 * INSN_COST); 9945 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 9946 9947 ins_encode %{ 9948 __ addw(as_Register($dst$$reg), 9949 as_Register($src1$$reg), 9950 as_Register($src2$$reg), 9951 Assembler::LSL, 9952 $src3$$constant & 0x3f); 9953 %} 9954 9955 ins_pipe(ialu_reg_reg_shift); 9956 %} 9957 9958 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 9959 iRegL src1, iRegL src2, 9960 immI src3, rFlagsReg cr) %{ 9961 match(Set dst (AddL src1 (LShiftL src2 src3))); 9962 9963 ins_cost(1.9 * INSN_COST); 9964 format %{ "add $dst, $src1, $src2, LSL $src3" %} 9965 9966 ins_encode %{ 9967 __ add(as_Register($dst$$reg), 9968 as_Register($src1$$reg), 9969 as_Register($src2$$reg), 9970 Assembler::LSL, 9971 $src3$$constant & 0x3f); 9972 %} 9973 9974 ins_pipe(ialu_reg_reg_shift); 9975 %} 9976 9977 instruct SubI_reg_URShift_reg(iRegINoSp dst, 9978 iRegIorL2I src1, iRegIorL2I src2, 9979 immI src3, rFlagsReg cr) %{ 9980 match(Set dst (SubI src1 (URShiftI src2 src3))); 9981 9982 ins_cost(1.9 * INSN_COST); 9983 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 9984 9985 ins_encode %{ 9986 __ subw(as_Register($dst$$reg), 9987 as_Register($src1$$reg), 9988 as_Register($src2$$reg), 9989 Assembler::LSR, 9990 $src3$$constant & 0x3f); 9991 %} 9992 9993 ins_pipe(ialu_reg_reg_shift); 9994 %} 9995 9996 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 9997 iRegL src1, iRegL src2, 9998 immI src3, rFlagsReg cr) %{ 9999 match(Set dst (SubL src1 (URShiftL src2 src3))); 10000 10001 ins_cost(1.9 * INSN_COST); 10002 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 10003 10004 ins_encode %{ 10005 __ sub(as_Register($dst$$reg), 10006 as_Register($src1$$reg), 10007 as_Register($src2$$reg), 10008 Assembler::LSR, 10009 $src3$$constant & 0x3f); 10010 %} 10011 10012 ins_pipe(ialu_reg_reg_shift); 10013 %} 10014 10015 instruct SubI_reg_RShift_reg(iRegINoSp dst, 10016 iRegIorL2I src1, iRegIorL2I src2, 10017 immI src3, rFlagsReg cr) %{ 10018 match(Set dst (SubI src1 (RShiftI src2 src3))); 10019 10020 ins_cost(1.9 * INSN_COST); 10021 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 10022 10023 ins_encode %{ 10024 __ subw(as_Register($dst$$reg), 10025 as_Register($src1$$reg), 10026 as_Register($src2$$reg), 10027 Assembler::ASR, 10028 $src3$$constant & 0x3f); 10029 %} 10030 10031 ins_pipe(ialu_reg_reg_shift); 10032 %} 10033 10034 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 10035 iRegL src1, iRegL src2, 10036 immI src3, rFlagsReg cr) %{ 10037 match(Set dst (SubL src1 (RShiftL src2 src3))); 10038 10039 ins_cost(1.9 * INSN_COST); 10040 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 10041 10042 ins_encode %{ 10043 __ sub(as_Register($dst$$reg), 10044 as_Register($src1$$reg), 10045 as_Register($src2$$reg), 10046 Assembler::ASR, 10047 $src3$$constant & 0x3f); 10048 %} 10049 10050 ins_pipe(ialu_reg_reg_shift); 10051 %} 10052 10053 instruct SubI_reg_LShift_reg(iRegINoSp dst, 10054 iRegIorL2I src1, iRegIorL2I src2, 10055 immI src3, rFlagsReg cr) %{ 10056 match(Set dst (SubI src1 (LShiftI src2 src3))); 10057 10058 ins_cost(1.9 * INSN_COST); 10059 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 10060 10061 ins_encode %{ 10062 __ subw(as_Register($dst$$reg), 10063 as_Register($src1$$reg), 10064 as_Register($src2$$reg), 10065 Assembler::LSL, 10066 $src3$$constant & 0x3f); 10067 %} 10068 10069 ins_pipe(ialu_reg_reg_shift); 10070 %} 10071 10072 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 10073 iRegL src1, iRegL src2, 10074 immI src3, rFlagsReg cr) %{ 10075 match(Set dst (SubL src1 (LShiftL src2 src3))); 10076 10077 ins_cost(1.9 * INSN_COST); 10078 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 10079 10080 ins_encode %{ 10081 __ sub(as_Register($dst$$reg), 10082 as_Register($src1$$reg), 10083 as_Register($src2$$reg), 10084 Assembler::LSL, 10085 $src3$$constant & 0x3f); 10086 %} 10087 10088 ins_pipe(ialu_reg_reg_shift); 10089 %} 10090 10091 10092 10093 // Shift Left followed by Shift Right. 10094 // This idiom is used by the compiler for the i2b bytecode etc. 10095 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 10096 %{ 10097 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 10098 // Make sure we are not going to exceed what sbfm can do. 10099 predicate((unsigned int)n->in(2)->get_int() <= 63 10100 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 10101 10102 ins_cost(INSN_COST * 2); 10103 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 10104 ins_encode %{ 10105 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10106 int s = 63 - lshift; 10107 int r = (rshift - lshift) & 63; 10108 __ sbfm(as_Register($dst$$reg), 10109 as_Register($src$$reg), 10110 r, s); 10111 %} 10112 10113 ins_pipe(ialu_reg_shift); 10114 %} 10115 10116 // Shift Left followed by Shift Right. 10117 // This idiom is used by the compiler for the i2b bytecode etc. 10118 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 10119 %{ 10120 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 10121 // Make sure we are not going to exceed what sbfmw can do. 10122 predicate((unsigned int)n->in(2)->get_int() <= 31 10123 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 10124 10125 ins_cost(INSN_COST * 2); 10126 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 10127 ins_encode %{ 10128 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10129 int s = 31 - lshift; 10130 int r = (rshift - lshift) & 31; 10131 __ sbfmw(as_Register($dst$$reg), 10132 as_Register($src$$reg), 10133 r, s); 10134 %} 10135 10136 ins_pipe(ialu_reg_shift); 10137 %} 10138 10139 // Shift Left followed by Shift Right. 10140 // This idiom is used by the compiler for the i2b bytecode etc. 10141 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 10142 %{ 10143 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 10144 // Make sure we are not going to exceed what ubfm can do. 10145 predicate((unsigned int)n->in(2)->get_int() <= 63 10146 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 10147 10148 ins_cost(INSN_COST * 2); 10149 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 10150 ins_encode %{ 10151 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10152 int s = 63 - lshift; 10153 int r = (rshift - lshift) & 63; 10154 __ ubfm(as_Register($dst$$reg), 10155 as_Register($src$$reg), 10156 r, s); 10157 %} 10158 10159 ins_pipe(ialu_reg_shift); 10160 %} 10161 10162 // Shift Left followed by Shift Right. 10163 // This idiom is used by the compiler for the i2b bytecode etc. 10164 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 10165 %{ 10166 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 10167 // Make sure we are not going to exceed what ubfmw can do. 10168 predicate((unsigned int)n->in(2)->get_int() <= 31 10169 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 10170 10171 ins_cost(INSN_COST * 2); 10172 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 10173 ins_encode %{ 10174 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10175 int s = 31 - lshift; 10176 int r = (rshift - lshift) & 31; 10177 __ ubfmw(as_Register($dst$$reg), 10178 as_Register($src$$reg), 10179 r, s); 10180 %} 10181 10182 ins_pipe(ialu_reg_shift); 10183 %} 10184 // Bitfield extract with shift & mask 10185 10186 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 10187 %{ 10188 match(Set dst (AndI (URShiftI src rshift) mask)); 10189 10190 ins_cost(INSN_COST); 10191 format %{ "ubfxw $dst, $src, $mask" %} 10192 ins_encode %{ 10193 int rshift = $rshift$$constant; 10194 long mask = $mask$$constant; 10195 int width = exact_log2(mask+1); 10196 __ ubfxw(as_Register($dst$$reg), 10197 as_Register($src$$reg), rshift, width); 10198 %} 10199 ins_pipe(ialu_reg_shift); 10200 %} 10201 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 10202 %{ 10203 match(Set dst (AndL (URShiftL src rshift) mask)); 10204 10205 ins_cost(INSN_COST); 10206 format %{ "ubfx $dst, $src, $mask" %} 10207 ins_encode %{ 10208 int rshift = $rshift$$constant; 10209 long mask = $mask$$constant; 10210 int width = exact_log2(mask+1); 10211 __ ubfx(as_Register($dst$$reg), 10212 as_Register($src$$reg), rshift, width); 10213 %} 10214 ins_pipe(ialu_reg_shift); 10215 %} 10216 10217 // We can use ubfx when extending an And with a mask when we know mask 10218 // is positive. We know that because immI_bitmask guarantees it. 10219 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 10220 %{ 10221 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 10222 10223 ins_cost(INSN_COST * 2); 10224 format %{ "ubfx $dst, $src, $mask" %} 10225 ins_encode %{ 10226 int rshift = $rshift$$constant; 10227 long mask = $mask$$constant; 10228 int width = exact_log2(mask+1); 10229 __ ubfx(as_Register($dst$$reg), 10230 as_Register($src$$reg), rshift, width); 10231 %} 10232 ins_pipe(ialu_reg_shift); 10233 %} 10234 10235 // Rotations 10236 10237 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 10238 %{ 10239 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 10240 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 10241 10242 ins_cost(INSN_COST); 10243 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10244 10245 ins_encode %{ 10246 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10247 $rshift$$constant & 63); 10248 %} 10249 ins_pipe(ialu_reg_reg_extr); 10250 %} 10251 10252 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 10253 %{ 10254 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 10255 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 10256 10257 ins_cost(INSN_COST); 10258 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10259 10260 ins_encode %{ 10261 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10262 $rshift$$constant & 31); 10263 %} 10264 ins_pipe(ialu_reg_reg_extr); 10265 %} 10266 10267 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 10268 %{ 10269 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 10270 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 10271 10272 ins_cost(INSN_COST); 10273 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10274 10275 ins_encode %{ 10276 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10277 $rshift$$constant & 63); 10278 %} 10279 ins_pipe(ialu_reg_reg_extr); 10280 %} 10281 10282 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 10283 %{ 10284 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 10285 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 10286 10287 ins_cost(INSN_COST); 10288 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10289 10290 ins_encode %{ 10291 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10292 $rshift$$constant & 31); 10293 %} 10294 ins_pipe(ialu_reg_reg_extr); 10295 %} 10296 10297 10298 // rol expander 10299 10300 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 10301 %{ 10302 effect(DEF dst, USE src, USE shift); 10303 10304 format %{ "rol $dst, $src, $shift" %} 10305 ins_cost(INSN_COST * 3); 10306 ins_encode %{ 10307 __ subw(rscratch1, zr, as_Register($shift$$reg)); 10308 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 10309 rscratch1); 10310 %} 10311 ins_pipe(ialu_reg_reg_vshift); 10312 %} 10313 10314 // rol expander 10315 10316 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 10317 %{ 10318 effect(DEF dst, USE src, USE shift); 10319 10320 format %{ "rol $dst, $src, $shift" %} 10321 ins_cost(INSN_COST * 3); 10322 ins_encode %{ 10323 __ subw(rscratch1, zr, as_Register($shift$$reg)); 10324 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 10325 rscratch1); 10326 %} 10327 ins_pipe(ialu_reg_reg_vshift); 10328 %} 10329 10330 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 10331 %{ 10332 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 10333 10334 expand %{ 10335 rolL_rReg(dst, src, shift, cr); 10336 %} 10337 %} 10338 10339 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10340 %{ 10341 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 10342 10343 expand %{ 10344 rolL_rReg(dst, src, shift, cr); 10345 %} 10346 %} 10347 10348 instruct rolI_rReg_Var_C_32(iRegLNoSp dst, iRegL src, iRegI shift, immI_32 c_32, rFlagsReg cr) 10349 %{ 10350 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 10351 10352 expand %{ 10353 rolL_rReg(dst, src, shift, cr); 10354 %} 10355 %} 10356 10357 instruct rolI_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10358 %{ 10359 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 10360 10361 expand %{ 10362 rolL_rReg(dst, src, shift, cr); 10363 %} 10364 %} 10365 10366 // ror expander 10367 10368 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 10369 %{ 10370 effect(DEF dst, USE src, USE shift); 10371 10372 format %{ "ror $dst, $src, $shift" %} 10373 ins_cost(INSN_COST); 10374 ins_encode %{ 10375 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 10376 as_Register($shift$$reg)); 10377 %} 10378 ins_pipe(ialu_reg_reg_vshift); 10379 %} 10380 10381 // ror expander 10382 10383 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 10384 %{ 10385 effect(DEF dst, USE src, USE shift); 10386 10387 format %{ "ror $dst, $src, $shift" %} 10388 ins_cost(INSN_COST); 10389 ins_encode %{ 10390 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 10391 as_Register($shift$$reg)); 10392 %} 10393 ins_pipe(ialu_reg_reg_vshift); 10394 %} 10395 10396 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 10397 %{ 10398 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 10399 10400 expand %{ 10401 rorL_rReg(dst, src, shift, cr); 10402 %} 10403 %} 10404 10405 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10406 %{ 10407 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 10408 10409 expand %{ 10410 rorL_rReg(dst, src, shift, cr); 10411 %} 10412 %} 10413 10414 instruct rorI_rReg_Var_C_32(iRegLNoSp dst, iRegL src, iRegI shift, immI_32 c_32, rFlagsReg cr) 10415 %{ 10416 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 10417 10418 expand %{ 10419 rorL_rReg(dst, src, shift, cr); 10420 %} 10421 %} 10422 10423 instruct rorI_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10424 %{ 10425 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 10426 10427 expand %{ 10428 rorL_rReg(dst, src, shift, cr); 10429 %} 10430 %} 10431 10432 // Add/subtract (extended) 10433 10434 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 10435 %{ 10436 match(Set dst (AddL src1 (ConvI2L src2))); 10437 ins_cost(INSN_COST); 10438 format %{ "add $dst, $src1, sxtw $src2" %} 10439 10440 ins_encode %{ 10441 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10442 as_Register($src2$$reg), ext::sxtw); 10443 %} 10444 ins_pipe(ialu_reg_reg); 10445 %}; 10446 10447 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 10448 %{ 10449 match(Set dst (SubL src1 (ConvI2L src2))); 10450 ins_cost(INSN_COST); 10451 format %{ "sub $dst, $src1, sxtw $src2" %} 10452 10453 ins_encode %{ 10454 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10455 as_Register($src2$$reg), ext::sxtw); 10456 %} 10457 ins_pipe(ialu_reg_reg); 10458 %}; 10459 10460 10461 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 10462 %{ 10463 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 10464 ins_cost(INSN_COST); 10465 format %{ "add $dst, $src1, sxth $src2" %} 10466 10467 ins_encode %{ 10468 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10469 as_Register($src2$$reg), ext::sxth); 10470 %} 10471 ins_pipe(ialu_reg_reg); 10472 %} 10473 10474 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 10475 %{ 10476 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 10477 ins_cost(INSN_COST); 10478 format %{ "add $dst, $src1, sxtb $src2" %} 10479 10480 ins_encode %{ 10481 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10482 as_Register($src2$$reg), ext::sxtb); 10483 %} 10484 ins_pipe(ialu_reg_reg); 10485 %} 10486 10487 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 10488 %{ 10489 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 10490 ins_cost(INSN_COST); 10491 format %{ "add $dst, $src1, uxtb $src2" %} 10492 10493 ins_encode %{ 10494 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10495 as_Register($src2$$reg), ext::uxtb); 10496 %} 10497 ins_pipe(ialu_reg_reg); 10498 %} 10499 10500 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 10501 %{ 10502 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 10503 ins_cost(INSN_COST); 10504 format %{ "add $dst, $src1, sxth $src2" %} 10505 10506 ins_encode %{ 10507 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10508 as_Register($src2$$reg), ext::sxth); 10509 %} 10510 ins_pipe(ialu_reg_reg); 10511 %} 10512 10513 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 10514 %{ 10515 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 10516 ins_cost(INSN_COST); 10517 format %{ "add $dst, $src1, sxtw $src2" %} 10518 10519 ins_encode %{ 10520 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10521 as_Register($src2$$reg), ext::sxtw); 10522 %} 10523 ins_pipe(ialu_reg_reg); 10524 %} 10525 10526 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 10527 %{ 10528 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 10529 ins_cost(INSN_COST); 10530 format %{ "add $dst, $src1, sxtb $src2" %} 10531 10532 ins_encode %{ 10533 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10534 as_Register($src2$$reg), ext::sxtb); 10535 %} 10536 ins_pipe(ialu_reg_reg); 10537 %} 10538 10539 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 10540 %{ 10541 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 10542 ins_cost(INSN_COST); 10543 format %{ "add $dst, $src1, uxtb $src2" %} 10544 10545 ins_encode %{ 10546 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10547 as_Register($src2$$reg), ext::uxtb); 10548 %} 10549 ins_pipe(ialu_reg_reg); 10550 %} 10551 10552 10553 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 10554 %{ 10555 match(Set dst (AddI src1 (AndI src2 mask))); 10556 ins_cost(INSN_COST); 10557 format %{ "addw $dst, $src1, $src2, uxtb" %} 10558 10559 ins_encode %{ 10560 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 10561 as_Register($src2$$reg), ext::uxtb); 10562 %} 10563 ins_pipe(ialu_reg_reg); 10564 %} 10565 10566 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 10567 %{ 10568 match(Set dst (AddI src1 (AndI src2 mask))); 10569 ins_cost(INSN_COST); 10570 format %{ "addw $dst, $src1, $src2, uxth" %} 10571 10572 ins_encode %{ 10573 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 10574 as_Register($src2$$reg), ext::uxth); 10575 %} 10576 ins_pipe(ialu_reg_reg); 10577 %} 10578 10579 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 10580 %{ 10581 match(Set dst (AddL src1 (AndL src2 mask))); 10582 ins_cost(INSN_COST); 10583 format %{ "add $dst, $src1, $src2, uxtb" %} 10584 10585 ins_encode %{ 10586 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10587 as_Register($src2$$reg), ext::uxtb); 10588 %} 10589 ins_pipe(ialu_reg_reg); 10590 %} 10591 10592 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 10593 %{ 10594 match(Set dst (AddL src1 (AndL src2 mask))); 10595 ins_cost(INSN_COST); 10596 format %{ "add $dst, $src1, $src2, uxth" %} 10597 10598 ins_encode %{ 10599 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10600 as_Register($src2$$reg), ext::uxth); 10601 %} 10602 ins_pipe(ialu_reg_reg); 10603 %} 10604 10605 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 10606 %{ 10607 match(Set dst (AddL src1 (AndL src2 mask))); 10608 ins_cost(INSN_COST); 10609 format %{ "add $dst, $src1, $src2, uxtw" %} 10610 10611 ins_encode %{ 10612 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10613 as_Register($src2$$reg), ext::uxtw); 10614 %} 10615 ins_pipe(ialu_reg_reg); 10616 %} 10617 10618 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 10619 %{ 10620 match(Set dst (SubI src1 (AndI src2 mask))); 10621 ins_cost(INSN_COST); 10622 format %{ "subw $dst, $src1, $src2, uxtb" %} 10623 10624 ins_encode %{ 10625 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 10626 as_Register($src2$$reg), ext::uxtb); 10627 %} 10628 ins_pipe(ialu_reg_reg); 10629 %} 10630 10631 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 10632 %{ 10633 match(Set dst (SubI src1 (AndI src2 mask))); 10634 ins_cost(INSN_COST); 10635 format %{ "subw $dst, $src1, $src2, uxth" %} 10636 10637 ins_encode %{ 10638 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 10639 as_Register($src2$$reg), ext::uxth); 10640 %} 10641 ins_pipe(ialu_reg_reg); 10642 %} 10643 10644 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 10645 %{ 10646 match(Set dst (SubL src1 (AndL src2 mask))); 10647 ins_cost(INSN_COST); 10648 format %{ "sub $dst, $src1, $src2, uxtb" %} 10649 10650 ins_encode %{ 10651 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10652 as_Register($src2$$reg), ext::uxtb); 10653 %} 10654 ins_pipe(ialu_reg_reg); 10655 %} 10656 10657 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 10658 %{ 10659 match(Set dst (SubL src1 (AndL src2 mask))); 10660 ins_cost(INSN_COST); 10661 format %{ "sub $dst, $src1, $src2, uxth" %} 10662 10663 ins_encode %{ 10664 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10665 as_Register($src2$$reg), ext::uxth); 10666 %} 10667 ins_pipe(ialu_reg_reg); 10668 %} 10669 10670 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 10671 %{ 10672 match(Set dst (SubL src1 (AndL src2 mask))); 10673 ins_cost(INSN_COST); 10674 format %{ "sub $dst, $src1, $src2, uxtw" %} 10675 10676 ins_encode %{ 10677 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10678 as_Register($src2$$reg), ext::uxtw); 10679 %} 10680 ins_pipe(ialu_reg_reg); 10681 %} 10682 10683 // END This section of the file is automatically generated. Do not edit -------------- 10684 10685 // ============================================================================ 10686 // Floating Point Arithmetic Instructions 10687 10688 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 10689 match(Set dst (AddF src1 src2)); 10690 10691 ins_cost(INSN_COST * 5); 10692 format %{ "fadds $dst, $src1, $src2" %} 10693 10694 ins_encode %{ 10695 __ fadds(as_FloatRegister($dst$$reg), 10696 as_FloatRegister($src1$$reg), 10697 as_FloatRegister($src2$$reg)); 10698 %} 10699 10700 ins_pipe(pipe_class_default); 10701 %} 10702 10703 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 10704 match(Set dst (AddD src1 src2)); 10705 10706 ins_cost(INSN_COST * 5); 10707 format %{ "faddd $dst, $src1, $src2" %} 10708 10709 ins_encode %{ 10710 __ faddd(as_FloatRegister($dst$$reg), 10711 as_FloatRegister($src1$$reg), 10712 as_FloatRegister($src2$$reg)); 10713 %} 10714 10715 ins_pipe(pipe_class_default); 10716 %} 10717 10718 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 10719 match(Set dst (SubF src1 src2)); 10720 10721 ins_cost(INSN_COST * 5); 10722 format %{ "fsubs $dst, $src1, $src2" %} 10723 10724 ins_encode %{ 10725 __ fsubs(as_FloatRegister($dst$$reg), 10726 as_FloatRegister($src1$$reg), 10727 as_FloatRegister($src2$$reg)); 10728 %} 10729 10730 ins_pipe(pipe_class_default); 10731 %} 10732 10733 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 10734 match(Set dst (SubD src1 src2)); 10735 10736 ins_cost(INSN_COST * 5); 10737 format %{ "fsubd $dst, $src1, $src2" %} 10738 10739 ins_encode %{ 10740 __ fsubd(as_FloatRegister($dst$$reg), 10741 as_FloatRegister($src1$$reg), 10742 as_FloatRegister($src2$$reg)); 10743 %} 10744 10745 ins_pipe(pipe_class_default); 10746 %} 10747 10748 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 10749 match(Set dst (MulF src1 src2)); 10750 10751 ins_cost(INSN_COST * 6); 10752 format %{ "fmuls $dst, $src1, $src2" %} 10753 10754 ins_encode %{ 10755 __ fmuls(as_FloatRegister($dst$$reg), 10756 as_FloatRegister($src1$$reg), 10757 as_FloatRegister($src2$$reg)); 10758 %} 10759 10760 ins_pipe(pipe_class_default); 10761 %} 10762 10763 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 10764 match(Set dst (MulD src1 src2)); 10765 10766 ins_cost(INSN_COST * 6); 10767 format %{ "fmuld $dst, $src1, $src2" %} 10768 10769 ins_encode %{ 10770 __ fmuld(as_FloatRegister($dst$$reg), 10771 as_FloatRegister($src1$$reg), 10772 as_FloatRegister($src2$$reg)); 10773 %} 10774 10775 ins_pipe(pipe_class_default); 10776 %} 10777 10778 // We cannot use these fused mul w add/sub ops because they don't 10779 // produce the same result as the equivalent separated ops 10780 // (essentially they don't round the intermediate result). that's a 10781 // shame. leaving them here in case we can idenitfy cases where it is 10782 // legitimate to use them 10783 10784 10785 // instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 10786 // match(Set dst (AddF (MulF src1 src2) src3)); 10787 10788 // format %{ "fmadds $dst, $src1, $src2, $src3" %} 10789 10790 // ins_encode %{ 10791 // __ fmadds(as_FloatRegister($dst$$reg), 10792 // as_FloatRegister($src1$$reg), 10793 // as_FloatRegister($src2$$reg), 10794 // as_FloatRegister($src3$$reg)); 10795 // %} 10796 10797 // ins_pipe(pipe_class_default); 10798 // %} 10799 10800 // instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 10801 // match(Set dst (AddD (MulD src1 src2) src3)); 10802 10803 // format %{ "fmaddd $dst, $src1, $src2, $src3" %} 10804 10805 // ins_encode %{ 10806 // __ fmaddd(as_FloatRegister($dst$$reg), 10807 // as_FloatRegister($src1$$reg), 10808 // as_FloatRegister($src2$$reg), 10809 // as_FloatRegister($src3$$reg)); 10810 // %} 10811 10812 // ins_pipe(pipe_class_default); 10813 // %} 10814 10815 // instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 10816 // match(Set dst (AddF (MulF (NegF src1) src2) src3)); 10817 // match(Set dst (AddF (NegF (MulF src1 src2)) src3)); 10818 10819 // format %{ "fmsubs $dst, $src1, $src2, $src3" %} 10820 10821 // ins_encode %{ 10822 // __ fmsubs(as_FloatRegister($dst$$reg), 10823 // as_FloatRegister($src1$$reg), 10824 // as_FloatRegister($src2$$reg), 10825 // as_FloatRegister($src3$$reg)); 10826 // %} 10827 10828 // ins_pipe(pipe_class_default); 10829 // %} 10830 10831 // instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 10832 // match(Set dst (AddD (MulD (NegD src1) src2) src3)); 10833 // match(Set dst (AddD (NegD (MulD src1 src2)) src3)); 10834 10835 // format %{ "fmsubd $dst, $src1, $src2, $src3" %} 10836 10837 // ins_encode %{ 10838 // __ fmsubd(as_FloatRegister($dst$$reg), 10839 // as_FloatRegister($src1$$reg), 10840 // as_FloatRegister($src2$$reg), 10841 // as_FloatRegister($src3$$reg)); 10842 // %} 10843 10844 // ins_pipe(pipe_class_default); 10845 // %} 10846 10847 // instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 10848 // match(Set dst (SubF (MulF (NegF src1) src2) src3)); 10849 // match(Set dst (SubF (NegF (MulF src1 src2)) src3)); 10850 10851 // format %{ "fnmadds $dst, $src1, $src2, $src3" %} 10852 10853 // ins_encode %{ 10854 // __ fnmadds(as_FloatRegister($dst$$reg), 10855 // as_FloatRegister($src1$$reg), 10856 // as_FloatRegister($src2$$reg), 10857 // as_FloatRegister($src3$$reg)); 10858 // %} 10859 10860 // ins_pipe(pipe_class_default); 10861 // %} 10862 10863 // instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 10864 // match(Set dst (SubD (MulD (NegD src1) src2) src3)); 10865 // match(Set dst (SubD (NegD (MulD src1 src2)) src3)); 10866 10867 // format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 10868 10869 // ins_encode %{ 10870 // __ fnmaddd(as_FloatRegister($dst$$reg), 10871 // as_FloatRegister($src1$$reg), 10872 // as_FloatRegister($src2$$reg), 10873 // as_FloatRegister($src3$$reg)); 10874 // %} 10875 10876 // ins_pipe(pipe_class_default); 10877 // %} 10878 10879 // instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 10880 // match(Set dst (SubF (MulF src1 src2) src3)); 10881 10882 // format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 10883 10884 // ins_encode %{ 10885 // __ fnmsubs(as_FloatRegister($dst$$reg), 10886 // as_FloatRegister($src1$$reg), 10887 // as_FloatRegister($src2$$reg), 10888 // as_FloatRegister($src3$$reg)); 10889 // %} 10890 10891 // ins_pipe(pipe_class_default); 10892 // %} 10893 10894 // instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 10895 // match(Set dst (SubD (MulD src1 src2) src3)); 10896 10897 // format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 10898 10899 // ins_encode %{ 10900 // // n.b. insn name should be fnmsubd 10901 // __ fnmsub(as_FloatRegister($dst$$reg), 10902 // as_FloatRegister($src1$$reg), 10903 // as_FloatRegister($src2$$reg), 10904 // as_FloatRegister($src3$$reg)); 10905 // %} 10906 10907 // ins_pipe(pipe_class_default); 10908 // %} 10909 10910 10911 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 10912 match(Set dst (DivF src1 src2)); 10913 10914 ins_cost(INSN_COST * 18); 10915 format %{ "fdivs $dst, $src1, $src2" %} 10916 10917 ins_encode %{ 10918 __ fdivs(as_FloatRegister($dst$$reg), 10919 as_FloatRegister($src1$$reg), 10920 as_FloatRegister($src2$$reg)); 10921 %} 10922 10923 ins_pipe(pipe_class_default); 10924 %} 10925 10926 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 10927 match(Set dst (DivD src1 src2)); 10928 10929 ins_cost(INSN_COST * 32); 10930 format %{ "fdivd $dst, $src1, $src2" %} 10931 10932 ins_encode %{ 10933 __ fdivd(as_FloatRegister($dst$$reg), 10934 as_FloatRegister($src1$$reg), 10935 as_FloatRegister($src2$$reg)); 10936 %} 10937 10938 ins_pipe(pipe_class_default); 10939 %} 10940 10941 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 10942 match(Set dst (NegF src)); 10943 10944 ins_cost(INSN_COST * 3); 10945 format %{ "fneg $dst, $src" %} 10946 10947 ins_encode %{ 10948 __ fnegs(as_FloatRegister($dst$$reg), 10949 as_FloatRegister($src$$reg)); 10950 %} 10951 10952 ins_pipe(pipe_class_default); 10953 %} 10954 10955 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 10956 match(Set dst (NegD src)); 10957 10958 ins_cost(INSN_COST * 3); 10959 format %{ "fnegd $dst, $src" %} 10960 10961 ins_encode %{ 10962 __ fnegd(as_FloatRegister($dst$$reg), 10963 as_FloatRegister($src$$reg)); 10964 %} 10965 10966 ins_pipe(pipe_class_default); 10967 %} 10968 10969 instruct absF_reg(vRegF dst, vRegF src) %{ 10970 match(Set dst (AbsF src)); 10971 10972 ins_cost(INSN_COST * 3); 10973 format %{ "fabss $dst, $src" %} 10974 ins_encode %{ 10975 __ fabss(as_FloatRegister($dst$$reg), 10976 as_FloatRegister($src$$reg)); 10977 %} 10978 10979 ins_pipe(pipe_class_default); 10980 %} 10981 10982 instruct absD_reg(vRegD dst, vRegD src) %{ 10983 match(Set dst (AbsD src)); 10984 10985 ins_cost(INSN_COST * 3); 10986 format %{ "fabsd $dst, $src" %} 10987 ins_encode %{ 10988 __ fabsd(as_FloatRegister($dst$$reg), 10989 as_FloatRegister($src$$reg)); 10990 %} 10991 10992 ins_pipe(pipe_class_default); 10993 %} 10994 10995 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 10996 match(Set dst (SqrtD src)); 10997 10998 ins_cost(INSN_COST * 50); 10999 format %{ "fsqrtd $dst, $src" %} 11000 ins_encode %{ 11001 __ fsqrtd(as_FloatRegister($dst$$reg), 11002 as_FloatRegister($src$$reg)); 11003 %} 11004 11005 ins_pipe(pipe_class_default); 11006 %} 11007 11008 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 11009 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 11010 11011 ins_cost(INSN_COST * 50); 11012 format %{ "fsqrts $dst, $src" %} 11013 ins_encode %{ 11014 __ fsqrts(as_FloatRegister($dst$$reg), 11015 as_FloatRegister($src$$reg)); 11016 %} 11017 11018 ins_pipe(pipe_class_default); 11019 %} 11020 11021 // ============================================================================ 11022 // Logical Instructions 11023 11024 // Integer Logical Instructions 11025 11026 // And Instructions 11027 11028 11029 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 11030 match(Set dst (AndI src1 src2)); 11031 11032 format %{ "andw $dst, $src1, $src2\t# int" %} 11033 11034 ins_cost(INSN_COST); 11035 ins_encode %{ 11036 __ andw(as_Register($dst$$reg), 11037 as_Register($src1$$reg), 11038 as_Register($src2$$reg)); 11039 %} 11040 11041 ins_pipe(ialu_reg_reg); 11042 %} 11043 11044 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 11045 match(Set dst (AndI src1 src2)); 11046 11047 format %{ "andsw $dst, $src1, $src2\t# int" %} 11048 11049 ins_cost(INSN_COST); 11050 ins_encode %{ 11051 __ andw(as_Register($dst$$reg), 11052 as_Register($src1$$reg), 11053 (unsigned long)($src2$$constant)); 11054 %} 11055 11056 ins_pipe(ialu_reg_imm); 11057 %} 11058 11059 // Or Instructions 11060 11061 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 11062 match(Set dst (OrI src1 src2)); 11063 11064 format %{ "orrw $dst, $src1, $src2\t# int" %} 11065 11066 ins_cost(INSN_COST); 11067 ins_encode %{ 11068 __ orrw(as_Register($dst$$reg), 11069 as_Register($src1$$reg), 11070 as_Register($src2$$reg)); 11071 %} 11072 11073 ins_pipe(ialu_reg_reg); 11074 %} 11075 11076 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 11077 match(Set dst (OrI src1 src2)); 11078 11079 format %{ "orrw $dst, $src1, $src2\t# int" %} 11080 11081 ins_cost(INSN_COST); 11082 ins_encode %{ 11083 __ orrw(as_Register($dst$$reg), 11084 as_Register($src1$$reg), 11085 (unsigned long)($src2$$constant)); 11086 %} 11087 11088 ins_pipe(ialu_reg_imm); 11089 %} 11090 11091 // Xor Instructions 11092 11093 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 11094 match(Set dst (XorI src1 src2)); 11095 11096 format %{ "eorw $dst, $src1, $src2\t# int" %} 11097 11098 ins_cost(INSN_COST); 11099 ins_encode %{ 11100 __ eorw(as_Register($dst$$reg), 11101 as_Register($src1$$reg), 11102 as_Register($src2$$reg)); 11103 %} 11104 11105 ins_pipe(ialu_reg_reg); 11106 %} 11107 11108 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 11109 match(Set dst (XorI src1 src2)); 11110 11111 format %{ "eorw $dst, $src1, $src2\t# int" %} 11112 11113 ins_cost(INSN_COST); 11114 ins_encode %{ 11115 __ eorw(as_Register($dst$$reg), 11116 as_Register($src1$$reg), 11117 (unsigned long)($src2$$constant)); 11118 %} 11119 11120 ins_pipe(ialu_reg_imm); 11121 %} 11122 11123 // Long Logical Instructions 11124 // TODO 11125 11126 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 11127 match(Set dst (AndL src1 src2)); 11128 11129 format %{ "and $dst, $src1, $src2\t# int" %} 11130 11131 ins_cost(INSN_COST); 11132 ins_encode %{ 11133 __ andr(as_Register($dst$$reg), 11134 as_Register($src1$$reg), 11135 as_Register($src2$$reg)); 11136 %} 11137 11138 ins_pipe(ialu_reg_reg); 11139 %} 11140 11141 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 11142 match(Set dst (AndL src1 src2)); 11143 11144 format %{ "and $dst, $src1, $src2\t# int" %} 11145 11146 ins_cost(INSN_COST); 11147 ins_encode %{ 11148 __ andr(as_Register($dst$$reg), 11149 as_Register($src1$$reg), 11150 (unsigned long)($src2$$constant)); 11151 %} 11152 11153 ins_pipe(ialu_reg_imm); 11154 %} 11155 11156 // Or Instructions 11157 11158 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 11159 match(Set dst (OrL src1 src2)); 11160 11161 format %{ "orr $dst, $src1, $src2\t# int" %} 11162 11163 ins_cost(INSN_COST); 11164 ins_encode %{ 11165 __ orr(as_Register($dst$$reg), 11166 as_Register($src1$$reg), 11167 as_Register($src2$$reg)); 11168 %} 11169 11170 ins_pipe(ialu_reg_reg); 11171 %} 11172 11173 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 11174 match(Set dst (OrL src1 src2)); 11175 11176 format %{ "orr $dst, $src1, $src2\t# int" %} 11177 11178 ins_cost(INSN_COST); 11179 ins_encode %{ 11180 __ orr(as_Register($dst$$reg), 11181 as_Register($src1$$reg), 11182 (unsigned long)($src2$$constant)); 11183 %} 11184 11185 ins_pipe(ialu_reg_imm); 11186 %} 11187 11188 // Xor Instructions 11189 11190 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 11191 match(Set dst (XorL src1 src2)); 11192 11193 format %{ "eor $dst, $src1, $src2\t# int" %} 11194 11195 ins_cost(INSN_COST); 11196 ins_encode %{ 11197 __ eor(as_Register($dst$$reg), 11198 as_Register($src1$$reg), 11199 as_Register($src2$$reg)); 11200 %} 11201 11202 ins_pipe(ialu_reg_reg); 11203 %} 11204 11205 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 11206 match(Set dst (XorL src1 src2)); 11207 11208 ins_cost(INSN_COST); 11209 format %{ "eor $dst, $src1, $src2\t# int" %} 11210 11211 ins_encode %{ 11212 __ eor(as_Register($dst$$reg), 11213 as_Register($src1$$reg), 11214 (unsigned long)($src2$$constant)); 11215 %} 11216 11217 ins_pipe(ialu_reg_imm); 11218 %} 11219 11220 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 11221 %{ 11222 match(Set dst (ConvI2L src)); 11223 11224 ins_cost(INSN_COST); 11225 format %{ "sxtw $dst, $src\t# i2l" %} 11226 ins_encode %{ 11227 __ sbfm($dst$$Register, $src$$Register, 0, 31); 11228 %} 11229 ins_pipe(ialu_reg_shift); 11230 %} 11231 11232 // this pattern occurs in bigmath arithmetic 11233 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 11234 %{ 11235 match(Set dst (AndL (ConvI2L src) mask)); 11236 11237 ins_cost(INSN_COST); 11238 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 11239 ins_encode %{ 11240 __ ubfm($dst$$Register, $src$$Register, 0, 31); 11241 %} 11242 11243 ins_pipe(ialu_reg_shift); 11244 %} 11245 11246 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 11247 match(Set dst (ConvL2I src)); 11248 11249 ins_cost(INSN_COST); 11250 format %{ "movw $dst, $src \t// l2i" %} 11251 11252 ins_encode %{ 11253 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 11254 %} 11255 11256 ins_pipe(ialu_reg); 11257 %} 11258 11259 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 11260 %{ 11261 match(Set dst (Conv2B src)); 11262 effect(KILL cr); 11263 11264 format %{ 11265 "cmpw $src, zr\n\t" 11266 "cset $dst, ne" 11267 %} 11268 11269 ins_encode %{ 11270 __ cmpw(as_Register($src$$reg), zr); 11271 __ cset(as_Register($dst$$reg), Assembler::NE); 11272 %} 11273 11274 ins_pipe(ialu_reg); 11275 %} 11276 11277 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 11278 %{ 11279 match(Set dst (Conv2B src)); 11280 effect(KILL cr); 11281 11282 format %{ 11283 "cmp $src, zr\n\t" 11284 "cset $dst, ne" 11285 %} 11286 11287 ins_encode %{ 11288 __ cmp(as_Register($src$$reg), zr); 11289 __ cset(as_Register($dst$$reg), Assembler::NE); 11290 %} 11291 11292 ins_pipe(ialu_reg); 11293 %} 11294 11295 instruct convD2F_reg(vRegF dst, vRegD src) %{ 11296 match(Set dst (ConvD2F src)); 11297 11298 ins_cost(INSN_COST * 5); 11299 format %{ "fcvtd $dst, $src \t// d2f" %} 11300 11301 ins_encode %{ 11302 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 11303 %} 11304 11305 ins_pipe(pipe_class_default); 11306 %} 11307 11308 instruct convF2D_reg(vRegD dst, vRegF src) %{ 11309 match(Set dst (ConvF2D src)); 11310 11311 ins_cost(INSN_COST * 5); 11312 format %{ "fcvts $dst, $src \t// f2d" %} 11313 11314 ins_encode %{ 11315 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 11316 %} 11317 11318 ins_pipe(pipe_class_default); 11319 %} 11320 11321 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 11322 match(Set dst (ConvF2I src)); 11323 11324 ins_cost(INSN_COST * 5); 11325 format %{ "fcvtzsw $dst, $src \t// f2i" %} 11326 11327 ins_encode %{ 11328 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11329 %} 11330 11331 ins_pipe(pipe_class_default); 11332 %} 11333 11334 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 11335 match(Set dst (ConvF2L src)); 11336 11337 ins_cost(INSN_COST * 5); 11338 format %{ "fcvtzs $dst, $src \t// f2l" %} 11339 11340 ins_encode %{ 11341 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11342 %} 11343 11344 ins_pipe(pipe_class_default); 11345 %} 11346 11347 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 11348 match(Set dst (ConvI2F src)); 11349 11350 ins_cost(INSN_COST * 5); 11351 format %{ "scvtfws $dst, $src \t// i2f" %} 11352 11353 ins_encode %{ 11354 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11355 %} 11356 11357 ins_pipe(pipe_class_default); 11358 %} 11359 11360 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 11361 match(Set dst (ConvL2F src)); 11362 11363 ins_cost(INSN_COST * 5); 11364 format %{ "scvtfs $dst, $src \t// l2f" %} 11365 11366 ins_encode %{ 11367 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11368 %} 11369 11370 ins_pipe(pipe_class_default); 11371 %} 11372 11373 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 11374 match(Set dst (ConvD2I src)); 11375 11376 ins_cost(INSN_COST * 5); 11377 format %{ "fcvtzdw $dst, $src \t// d2i" %} 11378 11379 ins_encode %{ 11380 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11381 %} 11382 11383 ins_pipe(pipe_class_default); 11384 %} 11385 11386 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 11387 match(Set dst (ConvD2L src)); 11388 11389 ins_cost(INSN_COST * 5); 11390 format %{ "fcvtzd $dst, $src \t// d2l" %} 11391 11392 ins_encode %{ 11393 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11394 %} 11395 11396 ins_pipe(pipe_class_default); 11397 %} 11398 11399 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 11400 match(Set dst (ConvI2D src)); 11401 11402 ins_cost(INSN_COST * 5); 11403 format %{ "scvtfwd $dst, $src \t// i2d" %} 11404 11405 ins_encode %{ 11406 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11407 %} 11408 11409 ins_pipe(pipe_class_default); 11410 %} 11411 11412 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 11413 match(Set dst (ConvL2D src)); 11414 11415 ins_cost(INSN_COST * 5); 11416 format %{ "scvtfd $dst, $src \t// l2d" %} 11417 11418 ins_encode %{ 11419 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11420 %} 11421 11422 ins_pipe(pipe_class_default); 11423 %} 11424 11425 // stack <-> reg and reg <-> reg shuffles with no conversion 11426 11427 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 11428 11429 match(Set dst (MoveF2I src)); 11430 11431 effect(DEF dst, USE src); 11432 11433 ins_cost(4 * INSN_COST); 11434 11435 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 11436 11437 ins_encode %{ 11438 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 11439 %} 11440 11441 ins_pipe(iload_reg_reg); 11442 11443 %} 11444 11445 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 11446 11447 match(Set dst (MoveI2F src)); 11448 11449 effect(DEF dst, USE src); 11450 11451 ins_cost(4 * INSN_COST); 11452 11453 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 11454 11455 ins_encode %{ 11456 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 11457 %} 11458 11459 ins_pipe(pipe_class_memory); 11460 11461 %} 11462 11463 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 11464 11465 match(Set dst (MoveD2L src)); 11466 11467 effect(DEF dst, USE src); 11468 11469 ins_cost(4 * INSN_COST); 11470 11471 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 11472 11473 ins_encode %{ 11474 __ ldr($dst$$Register, Address(sp, $src$$disp)); 11475 %} 11476 11477 ins_pipe(iload_reg_reg); 11478 11479 %} 11480 11481 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 11482 11483 match(Set dst (MoveL2D src)); 11484 11485 effect(DEF dst, USE src); 11486 11487 ins_cost(4 * INSN_COST); 11488 11489 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 11490 11491 ins_encode %{ 11492 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 11493 %} 11494 11495 ins_pipe(pipe_class_memory); 11496 11497 %} 11498 11499 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 11500 11501 match(Set dst (MoveF2I src)); 11502 11503 effect(DEF dst, USE src); 11504 11505 ins_cost(INSN_COST); 11506 11507 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 11508 11509 ins_encode %{ 11510 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 11511 %} 11512 11513 ins_pipe(pipe_class_memory); 11514 11515 %} 11516 11517 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 11518 11519 match(Set dst (MoveI2F src)); 11520 11521 effect(DEF dst, USE src); 11522 11523 ins_cost(INSN_COST); 11524 11525 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 11526 11527 ins_encode %{ 11528 __ strw($src$$Register, Address(sp, $dst$$disp)); 11529 %} 11530 11531 ins_pipe(istore_reg_reg); 11532 11533 %} 11534 11535 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 11536 11537 match(Set dst (MoveD2L src)); 11538 11539 effect(DEF dst, USE src); 11540 11541 ins_cost(INSN_COST); 11542 11543 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 11544 11545 ins_encode %{ 11546 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 11547 %} 11548 11549 ins_pipe(pipe_class_memory); 11550 11551 %} 11552 11553 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 11554 11555 match(Set dst (MoveL2D src)); 11556 11557 effect(DEF dst, USE src); 11558 11559 ins_cost(INSN_COST); 11560 11561 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 11562 11563 ins_encode %{ 11564 __ str($src$$Register, Address(sp, $dst$$disp)); 11565 %} 11566 11567 ins_pipe(istore_reg_reg); 11568 11569 %} 11570 11571 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 11572 11573 match(Set dst (MoveF2I src)); 11574 11575 effect(DEF dst, USE src); 11576 11577 ins_cost(INSN_COST); 11578 11579 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 11580 11581 ins_encode %{ 11582 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 11583 %} 11584 11585 ins_pipe(pipe_class_memory); 11586 11587 %} 11588 11589 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 11590 11591 match(Set dst (MoveI2F src)); 11592 11593 effect(DEF dst, USE src); 11594 11595 ins_cost(INSN_COST); 11596 11597 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 11598 11599 ins_encode %{ 11600 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 11601 %} 11602 11603 ins_pipe(pipe_class_memory); 11604 11605 %} 11606 11607 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 11608 11609 match(Set dst (MoveD2L src)); 11610 11611 effect(DEF dst, USE src); 11612 11613 ins_cost(INSN_COST); 11614 11615 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 11616 11617 ins_encode %{ 11618 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 11619 %} 11620 11621 ins_pipe(pipe_class_memory); 11622 11623 %} 11624 11625 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 11626 11627 match(Set dst (MoveL2D src)); 11628 11629 effect(DEF dst, USE src); 11630 11631 ins_cost(INSN_COST); 11632 11633 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 11634 11635 ins_encode %{ 11636 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 11637 %} 11638 11639 ins_pipe(pipe_class_memory); 11640 11641 %} 11642 11643 // ============================================================================ 11644 // clearing of an array 11645 11646 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 11647 %{ 11648 match(Set dummy (ClearArray cnt base)); 11649 effect(USE_KILL cnt, USE_KILL base); 11650 11651 ins_cost(4 * INSN_COST); 11652 format %{ "ClearArray $cnt, $base" %} 11653 11654 ins_encode(aarch64_enc_clear_array_reg_reg(cnt, base)); 11655 11656 ins_pipe(pipe_class_memory); 11657 %} 11658 11659 // ============================================================================ 11660 // Overflow Math Instructions 11661 11662 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 11663 %{ 11664 match(Set cr (OverflowAddI op1 op2)); 11665 11666 format %{ "cmnw $op1, $op2\t# overflow check int" %} 11667 ins_cost(INSN_COST); 11668 ins_encode %{ 11669 __ cmnw($op1$$Register, $op2$$Register); 11670 %} 11671 11672 ins_pipe(icmp_reg_reg); 11673 %} 11674 11675 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 11676 %{ 11677 match(Set cr (OverflowAddI op1 op2)); 11678 11679 format %{ "cmnw $op1, $op2\t# overflow check int" %} 11680 ins_cost(INSN_COST); 11681 ins_encode %{ 11682 __ cmnw($op1$$Register, $op2$$constant); 11683 %} 11684 11685 ins_pipe(icmp_reg_imm); 11686 %} 11687 11688 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 11689 %{ 11690 match(Set cr (OverflowAddL op1 op2)); 11691 11692 format %{ "cmn $op1, $op2\t# overflow check long" %} 11693 ins_cost(INSN_COST); 11694 ins_encode %{ 11695 __ cmn($op1$$Register, $op2$$Register); 11696 %} 11697 11698 ins_pipe(icmp_reg_reg); 11699 %} 11700 11701 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 11702 %{ 11703 match(Set cr (OverflowAddL op1 op2)); 11704 11705 format %{ "cmn $op1, $op2\t# overflow check long" %} 11706 ins_cost(INSN_COST); 11707 ins_encode %{ 11708 __ cmn($op1$$Register, $op2$$constant); 11709 %} 11710 11711 ins_pipe(icmp_reg_imm); 11712 %} 11713 11714 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 11715 %{ 11716 match(Set cr (OverflowSubI op1 op2)); 11717 11718 format %{ "cmpw $op1, $op2\t# overflow check int" %} 11719 ins_cost(INSN_COST); 11720 ins_encode %{ 11721 __ cmpw($op1$$Register, $op2$$Register); 11722 %} 11723 11724 ins_pipe(icmp_reg_reg); 11725 %} 11726 11727 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 11728 %{ 11729 match(Set cr (OverflowSubI op1 op2)); 11730 11731 format %{ "cmpw $op1, $op2\t# overflow check int" %} 11732 ins_cost(INSN_COST); 11733 ins_encode %{ 11734 __ cmpw($op1$$Register, $op2$$constant); 11735 %} 11736 11737 ins_pipe(icmp_reg_imm); 11738 %} 11739 11740 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 11741 %{ 11742 match(Set cr (OverflowSubL op1 op2)); 11743 11744 format %{ "cmp $op1, $op2\t# overflow check long" %} 11745 ins_cost(INSN_COST); 11746 ins_encode %{ 11747 __ cmp($op1$$Register, $op2$$Register); 11748 %} 11749 11750 ins_pipe(icmp_reg_reg); 11751 %} 11752 11753 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 11754 %{ 11755 match(Set cr (OverflowSubL op1 op2)); 11756 11757 format %{ "cmp $op1, $op2\t# overflow check long" %} 11758 ins_cost(INSN_COST); 11759 ins_encode %{ 11760 __ cmp($op1$$Register, $op2$$constant); 11761 %} 11762 11763 ins_pipe(icmp_reg_imm); 11764 %} 11765 11766 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 11767 %{ 11768 match(Set cr (OverflowSubI zero op1)); 11769 11770 format %{ "cmpw zr, $op1\t# overflow check int" %} 11771 ins_cost(INSN_COST); 11772 ins_encode %{ 11773 __ cmpw(zr, $op1$$Register); 11774 %} 11775 11776 ins_pipe(icmp_reg_imm); 11777 %} 11778 11779 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 11780 %{ 11781 match(Set cr (OverflowSubL zero op1)); 11782 11783 format %{ "cmp zr, $op1\t# overflow check long" %} 11784 ins_cost(INSN_COST); 11785 ins_encode %{ 11786 __ cmp(zr, $op1$$Register); 11787 %} 11788 11789 ins_pipe(icmp_reg_imm); 11790 %} 11791 11792 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 11793 %{ 11794 match(Set cr (OverflowMulI op1 op2)); 11795 11796 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 11797 "cmp rscratch1, rscratch1, sxtw\n\t" 11798 "movw rscratch1, #0x80000000\n\t" 11799 "cselw rscratch1, rscratch1, zr, NE\n\t" 11800 "cmpw rscratch1, #1" %} 11801 ins_cost(5 * INSN_COST); 11802 ins_encode %{ 11803 __ smull(rscratch1, $op1$$Register, $op2$$Register); 11804 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 11805 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 11806 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 11807 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 11808 %} 11809 11810 ins_pipe(pipe_slow); 11811 %} 11812 11813 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 11814 %{ 11815 match(If cmp (OverflowMulI op1 op2)); 11816 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 11817 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 11818 effect(USE labl, KILL cr); 11819 11820 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 11821 "cmp rscratch1, rscratch1, sxtw\n\t" 11822 "b$cmp $labl" %} 11823 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 11824 ins_encode %{ 11825 Label* L = $labl$$label; 11826 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11827 __ smull(rscratch1, $op1$$Register, $op2$$Register); 11828 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 11829 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 11830 %} 11831 11832 ins_pipe(pipe_serial); 11833 %} 11834 11835 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 11836 %{ 11837 match(Set cr (OverflowMulL op1 op2)); 11838 11839 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 11840 "smulh rscratch2, $op1, $op2\n\t" 11841 "cmp rscratch2, rscratch1, ASR #31\n\t" 11842 "movw rscratch1, #0x80000000\n\t" 11843 "cselw rscratch1, rscratch1, zr, NE\n\t" 11844 "cmpw rscratch1, #1" %} 11845 ins_cost(6 * INSN_COST); 11846 ins_encode %{ 11847 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 11848 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 11849 __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext 11850 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 11851 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 11852 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 11853 %} 11854 11855 ins_pipe(pipe_slow); 11856 %} 11857 11858 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 11859 %{ 11860 match(If cmp (OverflowMulL op1 op2)); 11861 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 11862 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 11863 effect(USE labl, KILL cr); 11864 11865 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 11866 "smulh rscratch2, $op1, $op2\n\t" 11867 "cmp rscratch2, rscratch1, ASR #31\n\t" 11868 "b$cmp $labl" %} 11869 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 11870 ins_encode %{ 11871 Label* L = $labl$$label; 11872 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11873 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 11874 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 11875 __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext 11876 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 11877 %} 11878 11879 ins_pipe(pipe_serial); 11880 %} 11881 11882 // ============================================================================ 11883 // Compare Instructions 11884 11885 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 11886 %{ 11887 match(Set cr (CmpI op1 op2)); 11888 11889 effect(DEF cr, USE op1, USE op2); 11890 11891 ins_cost(INSN_COST); 11892 format %{ "cmpw $op1, $op2" %} 11893 11894 ins_encode(aarch64_enc_cmpw(op1, op2)); 11895 11896 ins_pipe(icmp_reg_reg); 11897 %} 11898 11899 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 11900 %{ 11901 match(Set cr (CmpI op1 zero)); 11902 11903 effect(DEF cr, USE op1); 11904 11905 ins_cost(INSN_COST); 11906 format %{ "cmpw $op1, 0" %} 11907 11908 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 11909 11910 ins_pipe(icmp_reg_imm); 11911 %} 11912 11913 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 11914 %{ 11915 match(Set cr (CmpI op1 op2)); 11916 11917 effect(DEF cr, USE op1); 11918 11919 ins_cost(INSN_COST); 11920 format %{ "cmpw $op1, $op2" %} 11921 11922 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 11923 11924 ins_pipe(icmp_reg_imm); 11925 %} 11926 11927 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 11928 %{ 11929 match(Set cr (CmpI op1 op2)); 11930 11931 effect(DEF cr, USE op1); 11932 11933 ins_cost(INSN_COST * 2); 11934 format %{ "cmpw $op1, $op2" %} 11935 11936 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 11937 11938 ins_pipe(icmp_reg_imm); 11939 %} 11940 11941 // Unsigned compare Instructions; really, same as signed compare 11942 // except it should only be used to feed an If or a CMovI which takes a 11943 // cmpOpU. 11944 11945 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 11946 %{ 11947 match(Set cr (CmpU op1 op2)); 11948 11949 effect(DEF cr, USE op1, USE op2); 11950 11951 ins_cost(INSN_COST); 11952 format %{ "cmpw $op1, $op2\t# unsigned" %} 11953 11954 ins_encode(aarch64_enc_cmpw(op1, op2)); 11955 11956 ins_pipe(icmp_reg_reg); 11957 %} 11958 11959 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 11960 %{ 11961 match(Set cr (CmpU op1 zero)); 11962 11963 effect(DEF cr, USE op1); 11964 11965 ins_cost(INSN_COST); 11966 format %{ "cmpw $op1, #0\t# unsigned" %} 11967 11968 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 11969 11970 ins_pipe(icmp_reg_imm); 11971 %} 11972 11973 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 11974 %{ 11975 match(Set cr (CmpU op1 op2)); 11976 11977 effect(DEF cr, USE op1); 11978 11979 ins_cost(INSN_COST); 11980 format %{ "cmpw $op1, $op2\t# unsigned" %} 11981 11982 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 11983 11984 ins_pipe(icmp_reg_imm); 11985 %} 11986 11987 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 11988 %{ 11989 match(Set cr (CmpU op1 op2)); 11990 11991 effect(DEF cr, USE op1); 11992 11993 ins_cost(INSN_COST * 2); 11994 format %{ "cmpw $op1, $op2\t# unsigned" %} 11995 11996 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 11997 11998 ins_pipe(icmp_reg_imm); 11999 %} 12000 12001 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 12002 %{ 12003 match(Set cr (CmpL op1 op2)); 12004 12005 effect(DEF cr, USE op1, USE op2); 12006 12007 ins_cost(INSN_COST); 12008 format %{ "cmp $op1, $op2" %} 12009 12010 ins_encode(aarch64_enc_cmp(op1, op2)); 12011 12012 ins_pipe(icmp_reg_reg); 12013 %} 12014 12015 instruct compL_reg_immI0(rFlagsReg cr, iRegL op1, immI0 zero) 12016 %{ 12017 match(Set cr (CmpL op1 zero)); 12018 12019 effect(DEF cr, USE op1); 12020 12021 ins_cost(INSN_COST); 12022 format %{ "tst $op1" %} 12023 12024 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 12025 12026 ins_pipe(icmp_reg_imm); 12027 %} 12028 12029 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 12030 %{ 12031 match(Set cr (CmpL op1 op2)); 12032 12033 effect(DEF cr, USE op1); 12034 12035 ins_cost(INSN_COST); 12036 format %{ "cmp $op1, $op2" %} 12037 12038 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 12039 12040 ins_pipe(icmp_reg_imm); 12041 %} 12042 12043 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 12044 %{ 12045 match(Set cr (CmpL op1 op2)); 12046 12047 effect(DEF cr, USE op1); 12048 12049 ins_cost(INSN_COST * 2); 12050 format %{ "cmp $op1, $op2" %} 12051 12052 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 12053 12054 ins_pipe(icmp_reg_imm); 12055 %} 12056 12057 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 12058 %{ 12059 match(Set cr (CmpP op1 op2)); 12060 12061 effect(DEF cr, USE op1, USE op2); 12062 12063 ins_cost(INSN_COST); 12064 format %{ "cmp $op1, $op2\t // ptr" %} 12065 12066 ins_encode(aarch64_enc_cmpp(op1, op2)); 12067 12068 ins_pipe(icmp_reg_reg); 12069 %} 12070 12071 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 12072 %{ 12073 match(Set cr (CmpN op1 op2)); 12074 12075 effect(DEF cr, USE op1, USE op2); 12076 12077 ins_cost(INSN_COST); 12078 format %{ "cmp $op1, $op2\t // compressed ptr" %} 12079 12080 ins_encode(aarch64_enc_cmpn(op1, op2)); 12081 12082 ins_pipe(icmp_reg_reg); 12083 %} 12084 12085 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 12086 %{ 12087 match(Set cr (CmpP op1 zero)); 12088 12089 effect(DEF cr, USE op1, USE zero); 12090 12091 ins_cost(INSN_COST); 12092 format %{ "cmp $op1, 0\t // ptr" %} 12093 12094 ins_encode(aarch64_enc_testp(op1)); 12095 12096 ins_pipe(icmp_reg_imm); 12097 %} 12098 12099 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 12100 %{ 12101 match(Set cr (CmpN op1 zero)); 12102 12103 effect(DEF cr, USE op1, USE zero); 12104 12105 ins_cost(INSN_COST); 12106 format %{ "cmp $op1, 0\t // compressed ptr" %} 12107 12108 ins_encode(aarch64_enc_testn(op1)); 12109 12110 ins_pipe(icmp_reg_imm); 12111 %} 12112 12113 // FP comparisons 12114 // 12115 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 12116 // using normal cmpOp. See declaration of rFlagsReg for details. 12117 12118 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 12119 %{ 12120 match(Set cr (CmpF src1 src2)); 12121 12122 ins_cost(3 * INSN_COST); 12123 format %{ "fcmps $src1, $src2" %} 12124 12125 ins_encode %{ 12126 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 12127 %} 12128 12129 ins_pipe(pipe_class_compare); 12130 %} 12131 12132 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 12133 %{ 12134 match(Set cr (CmpF src1 src2)); 12135 12136 ins_cost(3 * INSN_COST); 12137 format %{ "fcmps $src1, 0.0" %} 12138 12139 ins_encode %{ 12140 __ fcmps(as_FloatRegister($src1$$reg), 0.0D); 12141 %} 12142 12143 ins_pipe(pipe_class_compare); 12144 %} 12145 // FROM HERE 12146 12147 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 12148 %{ 12149 match(Set cr (CmpD src1 src2)); 12150 12151 ins_cost(3 * INSN_COST); 12152 format %{ "fcmpd $src1, $src2" %} 12153 12154 ins_encode %{ 12155 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 12156 %} 12157 12158 ins_pipe(pipe_class_compare); 12159 %} 12160 12161 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 12162 %{ 12163 match(Set cr (CmpD src1 src2)); 12164 12165 ins_cost(3 * INSN_COST); 12166 format %{ "fcmpd $src1, 0.0" %} 12167 12168 ins_encode %{ 12169 __ fcmpd(as_FloatRegister($src1$$reg), 0.0D); 12170 %} 12171 12172 ins_pipe(pipe_class_compare); 12173 %} 12174 12175 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 12176 %{ 12177 match(Set dst (CmpF3 src1 src2)); 12178 effect(KILL cr); 12179 12180 ins_cost(5 * INSN_COST); 12181 format %{ "fcmps $src1, $src2\n\t" 12182 "csinvw($dst, zr, zr, eq\n\t" 12183 "csnegw($dst, $dst, $dst, lt)" 12184 %} 12185 12186 ins_encode %{ 12187 Label done; 12188 FloatRegister s1 = as_FloatRegister($src1$$reg); 12189 FloatRegister s2 = as_FloatRegister($src2$$reg); 12190 Register d = as_Register($dst$$reg); 12191 __ fcmps(s1, s2); 12192 // installs 0 if EQ else -1 12193 __ csinvw(d, zr, zr, Assembler::EQ); 12194 // keeps -1 if less or unordered else installs 1 12195 __ csnegw(d, d, d, Assembler::LT); 12196 __ bind(done); 12197 %} 12198 12199 ins_pipe(pipe_class_default); 12200 12201 %} 12202 12203 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 12204 %{ 12205 match(Set dst (CmpD3 src1 src2)); 12206 effect(KILL cr); 12207 12208 ins_cost(5 * INSN_COST); 12209 format %{ "fcmpd $src1, $src2\n\t" 12210 "csinvw($dst, zr, zr, eq\n\t" 12211 "csnegw($dst, $dst, $dst, lt)" 12212 %} 12213 12214 ins_encode %{ 12215 Label done; 12216 FloatRegister s1 = as_FloatRegister($src1$$reg); 12217 FloatRegister s2 = as_FloatRegister($src2$$reg); 12218 Register d = as_Register($dst$$reg); 12219 __ fcmpd(s1, s2); 12220 // installs 0 if EQ else -1 12221 __ csinvw(d, zr, zr, Assembler::EQ); 12222 // keeps -1 if less or unordered else installs 1 12223 __ csnegw(d, d, d, Assembler::LT); 12224 __ bind(done); 12225 %} 12226 ins_pipe(pipe_class_default); 12227 12228 %} 12229 12230 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 12231 %{ 12232 match(Set dst (CmpF3 src1 zero)); 12233 effect(KILL cr); 12234 12235 ins_cost(5 * INSN_COST); 12236 format %{ "fcmps $src1, 0.0\n\t" 12237 "csinvw($dst, zr, zr, eq\n\t" 12238 "csnegw($dst, $dst, $dst, lt)" 12239 %} 12240 12241 ins_encode %{ 12242 Label done; 12243 FloatRegister s1 = as_FloatRegister($src1$$reg); 12244 Register d = as_Register($dst$$reg); 12245 __ fcmps(s1, 0.0D); 12246 // installs 0 if EQ else -1 12247 __ csinvw(d, zr, zr, Assembler::EQ); 12248 // keeps -1 if less or unordered else installs 1 12249 __ csnegw(d, d, d, Assembler::LT); 12250 __ bind(done); 12251 %} 12252 12253 ins_pipe(pipe_class_default); 12254 12255 %} 12256 12257 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 12258 %{ 12259 match(Set dst (CmpD3 src1 zero)); 12260 effect(KILL cr); 12261 12262 ins_cost(5 * INSN_COST); 12263 format %{ "fcmpd $src1, 0.0\n\t" 12264 "csinvw($dst, zr, zr, eq\n\t" 12265 "csnegw($dst, $dst, $dst, lt)" 12266 %} 12267 12268 ins_encode %{ 12269 Label done; 12270 FloatRegister s1 = as_FloatRegister($src1$$reg); 12271 Register d = as_Register($dst$$reg); 12272 __ fcmpd(s1, 0.0D); 12273 // installs 0 if EQ else -1 12274 __ csinvw(d, zr, zr, Assembler::EQ); 12275 // keeps -1 if less or unordered else installs 1 12276 __ csnegw(d, d, d, Assembler::LT); 12277 __ bind(done); 12278 %} 12279 ins_pipe(pipe_class_default); 12280 12281 %} 12282 12283 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 12284 %{ 12285 match(Set dst (CmpLTMask p q)); 12286 effect(KILL cr); 12287 12288 ins_cost(3 * INSN_COST); 12289 12290 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 12291 "csetw $dst, lt\n\t" 12292 "subw $dst, zr, $dst" 12293 %} 12294 12295 ins_encode %{ 12296 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 12297 __ csetw(as_Register($dst$$reg), Assembler::LT); 12298 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 12299 %} 12300 12301 ins_pipe(ialu_reg_reg); 12302 %} 12303 12304 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 12305 %{ 12306 match(Set dst (CmpLTMask src zero)); 12307 effect(KILL cr); 12308 12309 ins_cost(INSN_COST); 12310 12311 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 12312 12313 ins_encode %{ 12314 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 12315 %} 12316 12317 ins_pipe(ialu_reg_shift); 12318 %} 12319 12320 // ============================================================================ 12321 // Max and Min 12322 12323 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 12324 %{ 12325 match(Set dst (MinI src1 src2)); 12326 12327 effect(DEF dst, USE src1, USE src2, KILL cr); 12328 size(8); 12329 12330 ins_cost(INSN_COST * 3); 12331 format %{ 12332 "cmpw $src1 $src2\t signed int\n\t" 12333 "cselw $dst, $src1, $src2 lt\t" 12334 %} 12335 12336 ins_encode %{ 12337 __ cmpw(as_Register($src1$$reg), 12338 as_Register($src2$$reg)); 12339 __ cselw(as_Register($dst$$reg), 12340 as_Register($src1$$reg), 12341 as_Register($src2$$reg), 12342 Assembler::LT); 12343 %} 12344 12345 ins_pipe(ialu_reg_reg); 12346 %} 12347 // FROM HERE 12348 12349 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 12350 %{ 12351 match(Set dst (MaxI src1 src2)); 12352 12353 effect(DEF dst, USE src1, USE src2, KILL cr); 12354 size(8); 12355 12356 ins_cost(INSN_COST * 3); 12357 format %{ 12358 "cmpw $src1 $src2\t signed int\n\t" 12359 "cselw $dst, $src1, $src2 gt\t" 12360 %} 12361 12362 ins_encode %{ 12363 __ cmpw(as_Register($src1$$reg), 12364 as_Register($src2$$reg)); 12365 __ cselw(as_Register($dst$$reg), 12366 as_Register($src1$$reg), 12367 as_Register($src2$$reg), 12368 Assembler::GT); 12369 %} 12370 12371 ins_pipe(ialu_reg_reg); 12372 %} 12373 12374 // ============================================================================ 12375 // Branch Instructions 12376 12377 // Direct Branch. 12378 instruct branch(label lbl) 12379 %{ 12380 match(Goto); 12381 12382 effect(USE lbl); 12383 12384 ins_cost(BRANCH_COST); 12385 format %{ "b $lbl" %} 12386 12387 ins_encode(aarch64_enc_b(lbl)); 12388 12389 ins_pipe(pipe_branch); 12390 %} 12391 12392 // Conditional Near Branch 12393 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 12394 %{ 12395 // Same match rule as `branchConFar'. 12396 match(If cmp cr); 12397 12398 effect(USE lbl); 12399 12400 ins_cost(BRANCH_COST); 12401 // If set to 1 this indicates that the current instruction is a 12402 // short variant of a long branch. This avoids using this 12403 // instruction in first-pass matching. It will then only be used in 12404 // the `Shorten_branches' pass. 12405 // ins_short_branch(1); 12406 format %{ "b$cmp $lbl" %} 12407 12408 ins_encode(aarch64_enc_br_con(cmp, lbl)); 12409 12410 ins_pipe(pipe_branch_cond); 12411 %} 12412 12413 // Conditional Near Branch Unsigned 12414 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 12415 %{ 12416 // Same match rule as `branchConFar'. 12417 match(If cmp cr); 12418 12419 effect(USE lbl); 12420 12421 ins_cost(BRANCH_COST); 12422 // If set to 1 this indicates that the current instruction is a 12423 // short variant of a long branch. This avoids using this 12424 // instruction in first-pass matching. It will then only be used in 12425 // the `Shorten_branches' pass. 12426 // ins_short_branch(1); 12427 format %{ "b$cmp $lbl\t# unsigned" %} 12428 12429 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 12430 12431 ins_pipe(pipe_branch_cond); 12432 %} 12433 12434 // Make use of CBZ and CBNZ. These instructions, as well as being 12435 // shorter than (cmp; branch), have the additional benefit of not 12436 // killing the flags. 12437 12438 instruct cmpI_imm0_branch(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 12439 match(If cmp (CmpI op1 op2)); 12440 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 12441 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 12442 effect(USE labl); 12443 12444 ins_cost(BRANCH_COST); 12445 format %{ "cbw$cmp $op1, $labl" %} 12446 ins_encode %{ 12447 Label* L = $labl$$label; 12448 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 12449 if (cond == Assembler::EQ) 12450 __ cbzw($op1$$Register, *L); 12451 else 12452 __ cbnzw($op1$$Register, *L); 12453 %} 12454 ins_pipe(pipe_cmp_branch); 12455 %} 12456 12457 instruct cmpL_imm0_branch(cmpOp cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 12458 match(If cmp (CmpL op1 op2)); 12459 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 12460 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 12461 effect(USE labl); 12462 12463 ins_cost(BRANCH_COST); 12464 format %{ "cb$cmp $op1, $labl" %} 12465 ins_encode %{ 12466 Label* L = $labl$$label; 12467 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 12468 if (cond == Assembler::EQ) 12469 __ cbz($op1$$Register, *L); 12470 else 12471 __ cbnz($op1$$Register, *L); 12472 %} 12473 ins_pipe(pipe_cmp_branch); 12474 %} 12475 12476 instruct cmpP_imm0_branch(cmpOp cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 12477 match(If cmp (CmpP op1 op2)); 12478 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 12479 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 12480 effect(USE labl); 12481 12482 ins_cost(BRANCH_COST); 12483 format %{ "cb$cmp $op1, $labl" %} 12484 ins_encode %{ 12485 Label* L = $labl$$label; 12486 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 12487 if (cond == Assembler::EQ) 12488 __ cbz($op1$$Register, *L); 12489 else 12490 __ cbnz($op1$$Register, *L); 12491 %} 12492 ins_pipe(pipe_cmp_branch); 12493 %} 12494 12495 // Conditional Far Branch 12496 // Conditional Far Branch Unsigned 12497 // TODO: fixme 12498 12499 // counted loop end branch near 12500 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 12501 %{ 12502 match(CountedLoopEnd cmp cr); 12503 12504 effect(USE lbl); 12505 12506 ins_cost(BRANCH_COST); 12507 // short variant. 12508 // ins_short_branch(1); 12509 format %{ "b$cmp $lbl \t// counted loop end" %} 12510 12511 ins_encode(aarch64_enc_br_con(cmp, lbl)); 12512 12513 ins_pipe(pipe_branch); 12514 %} 12515 12516 // counted loop end branch near Unsigned 12517 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 12518 %{ 12519 match(CountedLoopEnd cmp cr); 12520 12521 effect(USE lbl); 12522 12523 ins_cost(BRANCH_COST); 12524 // short variant. 12525 // ins_short_branch(1); 12526 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 12527 12528 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 12529 12530 ins_pipe(pipe_branch); 12531 %} 12532 12533 // counted loop end branch far 12534 // counted loop end branch far unsigned 12535 // TODO: fixme 12536 12537 // ============================================================================ 12538 // inlined locking and unlocking 12539 12540 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 12541 %{ 12542 match(Set cr (FastLock object box)); 12543 effect(TEMP tmp, TEMP tmp2); 12544 12545 // TODO 12546 // identify correct cost 12547 ins_cost(5 * INSN_COST); 12548 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 12549 12550 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 12551 12552 ins_pipe(pipe_serial); 12553 %} 12554 12555 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 12556 %{ 12557 match(Set cr (FastUnlock object box)); 12558 effect(TEMP tmp, TEMP tmp2); 12559 12560 ins_cost(5 * INSN_COST); 12561 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 12562 12563 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 12564 12565 ins_pipe(pipe_serial); 12566 %} 12567 12568 12569 // ============================================================================ 12570 // Safepoint Instructions 12571 12572 // TODO 12573 // provide a near and far version of this code 12574 12575 instruct safePoint(iRegP poll) 12576 %{ 12577 match(SafePoint poll); 12578 12579 format %{ 12580 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 12581 %} 12582 ins_encode %{ 12583 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 12584 %} 12585 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 12586 %} 12587 12588 12589 // ============================================================================ 12590 // Procedure Call/Return Instructions 12591 12592 // Call Java Static Instruction 12593 12594 instruct CallStaticJavaDirect(method meth) 12595 %{ 12596 match(CallStaticJava); 12597 12598 effect(USE meth); 12599 12600 ins_cost(CALL_COST); 12601 12602 format %{ "call,static $meth \t// ==> " %} 12603 12604 ins_encode( aarch64_enc_java_static_call(meth), 12605 aarch64_enc_call_epilog ); 12606 12607 ins_pipe(pipe_class_call); 12608 %} 12609 12610 // TO HERE 12611 12612 // Call Java Dynamic Instruction 12613 instruct CallDynamicJavaDirect(method meth) 12614 %{ 12615 match(CallDynamicJava); 12616 12617 effect(USE meth); 12618 12619 ins_cost(CALL_COST); 12620 12621 format %{ "CALL,dynamic $meth \t// ==> " %} 12622 12623 ins_encode( aarch64_enc_java_dynamic_call(meth), 12624 aarch64_enc_call_epilog ); 12625 12626 ins_pipe(pipe_class_call); 12627 %} 12628 12629 // Call Runtime Instruction 12630 12631 instruct CallRuntimeDirect(method meth) 12632 %{ 12633 match(CallRuntime); 12634 12635 effect(USE meth); 12636 12637 ins_cost(CALL_COST); 12638 12639 format %{ "CALL, runtime $meth" %} 12640 12641 ins_encode( aarch64_enc_java_to_runtime(meth) ); 12642 12643 ins_pipe(pipe_class_call); 12644 %} 12645 12646 // Call Runtime Instruction 12647 12648 instruct CallLeafDirect(method meth) 12649 %{ 12650 match(CallLeaf); 12651 12652 effect(USE meth); 12653 12654 ins_cost(CALL_COST); 12655 12656 format %{ "CALL, runtime leaf $meth" %} 12657 12658 ins_encode( aarch64_enc_java_to_runtime(meth) ); 12659 12660 ins_pipe(pipe_class_call); 12661 %} 12662 12663 // Call Runtime Instruction 12664 12665 instruct CallLeafNoFPDirect(method meth) 12666 %{ 12667 match(CallLeafNoFP); 12668 12669 effect(USE meth); 12670 12671 ins_cost(CALL_COST); 12672 12673 format %{ "CALL, runtime leaf nofp $meth" %} 12674 12675 ins_encode( aarch64_enc_java_to_runtime(meth) ); 12676 12677 ins_pipe(pipe_class_call); 12678 %} 12679 12680 // Tail Call; Jump from runtime stub to Java code. 12681 // Also known as an 'interprocedural jump'. 12682 // Target of jump will eventually return to caller. 12683 // TailJump below removes the return address. 12684 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 12685 %{ 12686 match(TailCall jump_target method_oop); 12687 12688 ins_cost(CALL_COST); 12689 12690 format %{ "br $jump_target\t# $method_oop holds method oop" %} 12691 12692 ins_encode(aarch64_enc_tail_call(jump_target)); 12693 12694 ins_pipe(pipe_class_call); 12695 %} 12696 12697 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 12698 %{ 12699 match(TailJump jump_target ex_oop); 12700 12701 ins_cost(CALL_COST); 12702 12703 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 12704 12705 ins_encode(aarch64_enc_tail_jmp(jump_target)); 12706 12707 ins_pipe(pipe_class_call); 12708 %} 12709 12710 // Create exception oop: created by stack-crawling runtime code. 12711 // Created exception is now available to this handler, and is setup 12712 // just prior to jumping to this handler. No code emitted. 12713 // TODO check 12714 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 12715 instruct CreateException(iRegP_R0 ex_oop) 12716 %{ 12717 match(Set ex_oop (CreateEx)); 12718 12719 format %{ " -- \t// exception oop; no code emitted" %} 12720 12721 size(0); 12722 12723 ins_encode( /*empty*/ ); 12724 12725 ins_pipe(pipe_class_empty); 12726 %} 12727 12728 // Rethrow exception: The exception oop will come in the first 12729 // argument position. Then JUMP (not call) to the rethrow stub code. 12730 instruct RethrowException() %{ 12731 match(Rethrow); 12732 ins_cost(CALL_COST); 12733 12734 format %{ "b rethrow_stub" %} 12735 12736 ins_encode( aarch64_enc_rethrow() ); 12737 12738 ins_pipe(pipe_class_call); 12739 %} 12740 12741 12742 // Return Instruction 12743 // epilog node loads ret address into lr as part of frame pop 12744 instruct Ret() 12745 %{ 12746 match(Return); 12747 12748 format %{ "ret\t// return register" %} 12749 12750 ins_encode( aarch64_enc_ret() ); 12751 12752 ins_pipe(pipe_branch); 12753 %} 12754 12755 // Die now. 12756 instruct ShouldNotReachHere() %{ 12757 match(Halt); 12758 12759 ins_cost(CALL_COST); 12760 format %{ "ShouldNotReachHere" %} 12761 12762 ins_encode %{ 12763 // TODO 12764 // implement proper trap call here 12765 __ brk(999); 12766 %} 12767 12768 ins_pipe(pipe_class_default); 12769 %} 12770 12771 // ============================================================================ 12772 // Partial Subtype Check 12773 // 12774 // superklass array for an instance of the superklass. Set a hidden 12775 // internal cache on a hit (cache is checked with exposed code in 12776 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12777 // encoding ALSO sets flags. 12778 12779 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 12780 %{ 12781 match(Set result (PartialSubtypeCheck sub super)); 12782 effect(KILL cr, KILL temp); 12783 12784 ins_cost(1100); // slightly larger than the next version 12785 format %{ "partialSubtypeCheck $result, $sub, $super" %} 12786 12787 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 12788 12789 opcode(0x1); // Force zero of result reg on hit 12790 12791 ins_pipe(pipe_class_memory); 12792 %} 12793 12794 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 12795 %{ 12796 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12797 effect(KILL temp, KILL result); 12798 12799 ins_cost(1100); // slightly larger than the next version 12800 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 12801 12802 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 12803 12804 opcode(0x0); // Don't zero result reg on hit 12805 12806 ins_pipe(pipe_class_memory); 12807 %} 12808 12809 instruct string_compare(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 12810 iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr) 12811 %{ 12812 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12813 effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12814 12815 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 12816 ins_encode %{ 12817 __ string_compare($str1$$Register, $str2$$Register, 12818 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12819 $tmp1$$Register); 12820 %} 12821 ins_pipe(pipe_class_memory); 12822 %} 12823 12824 instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 12825 iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr) 12826 %{ 12827 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12828 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 12829 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 12830 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result" %} 12831 12832 ins_encode %{ 12833 __ string_indexof($str1$$Register, $str2$$Register, 12834 $cnt1$$Register, $cnt2$$Register, 12835 $tmp1$$Register, $tmp2$$Register, 12836 $tmp3$$Register, $tmp4$$Register, 12837 -1, $result$$Register); 12838 %} 12839 ins_pipe(pipe_class_memory); 12840 %} 12841 12842 instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 12843 immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2, 12844 iRegI tmp3, iRegI tmp4, rFlagsReg cr) 12845 %{ 12846 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12847 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 12848 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 12849 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result" %} 12850 12851 ins_encode %{ 12852 int icnt2 = (int)$int_cnt2$$constant; 12853 __ string_indexof($str1$$Register, $str2$$Register, 12854 $cnt1$$Register, zr, 12855 $tmp1$$Register, $tmp2$$Register, 12856 $tmp3$$Register, $tmp4$$Register, 12857 icnt2, $result$$Register); 12858 %} 12859 ins_pipe(pipe_class_memory); 12860 %} 12861 12862 instruct string_equals(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 12863 iRegI_R0 result, iRegP_R10 tmp, rFlagsReg cr) 12864 %{ 12865 match(Set result (StrEquals (Binary str1 str2) cnt)); 12866 effect(KILL tmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 12867 12868 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %} 12869 ins_encode %{ 12870 __ string_equals($str1$$Register, $str2$$Register, 12871 $cnt$$Register, $result$$Register, 12872 $tmp$$Register); 12873 %} 12874 ins_pipe(pipe_class_memory); 12875 %} 12876 12877 instruct array_equals(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 12878 iRegP_R10 tmp, rFlagsReg cr) 12879 %{ 12880 match(Set result (AryEq ary1 ary2)); 12881 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, KILL cr); 12882 12883 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 12884 ins_encode %{ 12885 __ char_arrays_equals($ary1$$Register, $ary2$$Register, 12886 $result$$Register, $tmp$$Register); 12887 %} 12888 ins_pipe(pipe_class_memory); 12889 %} 12890 12891 // encode char[] to byte[] in ISO_8859_1 12892 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 12893 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 12894 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 12895 iRegI_R0 result, rFlagsReg cr) 12896 %{ 12897 match(Set result (EncodeISOArray src (Binary dst len))); 12898 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 12899 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 12900 12901 format %{ "Encode array $src,$dst,$len -> $result" %} 12902 ins_encode %{ 12903 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12904 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 12905 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 12906 %} 12907 ins_pipe( pipe_class_memory ); 12908 %} 12909 12910 // ============================================================================ 12911 // This name is KNOWN by the ADLC and cannot be changed. 12912 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12913 // for this guy. 12914 instruct tlsLoadP(thread_RegP dst) 12915 %{ 12916 match(Set dst (ThreadLocal)); 12917 12918 ins_cost(0); 12919 12920 format %{ " -- \t// $dst=Thread::current(), empty" %} 12921 12922 size(0); 12923 12924 ins_encode( /*empty*/ ); 12925 12926 ins_pipe(pipe_class_empty); 12927 %} 12928 12929 12930 12931 //----------PEEPHOLE RULES----------------------------------------------------- 12932 // These must follow all instruction definitions as they use the names 12933 // defined in the instructions definitions. 12934 // 12935 // peepmatch ( root_instr_name [preceding_instruction]* ); 12936 // 12937 // peepconstraint %{ 12938 // (instruction_number.operand_name relational_op instruction_number.operand_name 12939 // [, ...] ); 12940 // // instruction numbers are zero-based using left to right order in peepmatch 12941 // 12942 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12943 // // provide an instruction_number.operand_name for each operand that appears 12944 // // in the replacement instruction's match rule 12945 // 12946 // ---------VM FLAGS--------------------------------------------------------- 12947 // 12948 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12949 // 12950 // Each peephole rule is given an identifying number starting with zero and 12951 // increasing by one in the order seen by the parser. An individual peephole 12952 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12953 // on the command-line. 12954 // 12955 // ---------CURRENT LIMITATIONS---------------------------------------------- 12956 // 12957 // Only match adjacent instructions in same basic block 12958 // Only equality constraints 12959 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12960 // Only one replacement instruction 12961 // 12962 // ---------EXAMPLE---------------------------------------------------------- 12963 // 12964 // // pertinent parts of existing instructions in architecture description 12965 // instruct movI(iRegINoSp dst, iRegI src) 12966 // %{ 12967 // match(Set dst (CopyI src)); 12968 // %} 12969 // 12970 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 12971 // %{ 12972 // match(Set dst (AddI dst src)); 12973 // effect(KILL cr); 12974 // %} 12975 // 12976 // // Change (inc mov) to lea 12977 // peephole %{ 12978 // // increment preceeded by register-register move 12979 // peepmatch ( incI_iReg movI ); 12980 // // require that the destination register of the increment 12981 // // match the destination register of the move 12982 // peepconstraint ( 0.dst == 1.dst ); 12983 // // construct a replacement instruction that sets 12984 // // the destination to ( move's source register + one ) 12985 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 12986 // %} 12987 // 12988 12989 // Implementation no longer uses movX instructions since 12990 // machine-independent system no longer uses CopyX nodes. 12991 // 12992 // peephole 12993 // %{ 12994 // peepmatch (incI_iReg movI); 12995 // peepconstraint (0.dst == 1.dst); 12996 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 12997 // %} 12998 12999 // peephole 13000 // %{ 13001 // peepmatch (decI_iReg movI); 13002 // peepconstraint (0.dst == 1.dst); 13003 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 13004 // %} 13005 13006 // peephole 13007 // %{ 13008 // peepmatch (addI_iReg_imm movI); 13009 // peepconstraint (0.dst == 1.dst); 13010 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 13011 // %} 13012 13013 // peephole 13014 // %{ 13015 // peepmatch (incL_iReg movL); 13016 // peepconstraint (0.dst == 1.dst); 13017 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 13018 // %} 13019 13020 // peephole 13021 // %{ 13022 // peepmatch (decL_iReg movL); 13023 // peepconstraint (0.dst == 1.dst); 13024 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 13025 // %} 13026 13027 // peephole 13028 // %{ 13029 // peepmatch (addL_iReg_imm movL); 13030 // peepconstraint (0.dst == 1.dst); 13031 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 13032 // %} 13033 13034 // peephole 13035 // %{ 13036 // peepmatch (addP_iReg_imm movP); 13037 // peepconstraint (0.dst == 1.dst); 13038 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 13039 // %} 13040 13041 // // Change load of spilled value to only a spill 13042 // instruct storeI(memory mem, iRegI src) 13043 // %{ 13044 // match(Set mem (StoreI mem src)); 13045 // %} 13046 // 13047 // instruct loadI(iRegINoSp dst, memory mem) 13048 // %{ 13049 // match(Set dst (LoadI mem)); 13050 // %} 13051 // 13052 13053 //----------SMARTSPILL RULES--------------------------------------------------- 13054 // These must follow all instruction definitions as they use the names 13055 // defined in the instructions definitions. 13056 13057 // Local Variables: 13058 // mode: c++ 13059 // End: