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( 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 // Class for all non-special long integer registers 458 reg_class no_special_reg( 459 R0, R0_H, 460 R1, R1_H, 461 R2, R2_H, 462 R3, R3_H, 463 R4, R4_H, 464 R5, R5_H, 465 R6, R6_H, 466 R7, R7_H, 467 R10, R10_H, 468 R11, R11_H, 469 R12, R12_H, // rmethod 470 R13, R13_H, 471 R14, R14_H, 472 R15, R15_H, 473 R16, R16_H, 474 R17, R17_H, 475 R18, R18_H, 476 R19, R19_H, 477 R20, R20_H, 478 R21, R21_H, 479 R22, R22_H, 480 R23, R23_H, 481 R24, R24_H, 482 R25, R25_H, 483 R26, R26_H, 484 /* R27, R27_H, */ // heapbase 485 /* R28, R28_H, */ // thread 486 R29, R29_H, // fp 487 /* R30, R30_H, */ // lr 488 /* R31, R31_H */ // sp 489 ); 490 491 // Class for 64 bit register r0 492 reg_class r0_reg( 493 R0, R0_H 494 ); 495 496 // Class for 64 bit register r1 497 reg_class r1_reg( 498 R1, R1_H 499 ); 500 501 // Class for 64 bit register r2 502 reg_class r2_reg( 503 R2, R2_H 504 ); 505 506 // Class for 64 bit register r3 507 reg_class r3_reg( 508 R3, R3_H 509 ); 510 511 // Class for 64 bit register r4 512 reg_class r4_reg( 513 R4, R4_H 514 ); 515 516 // Class for 64 bit register r5 517 reg_class r5_reg( 518 R5, R5_H 519 ); 520 521 // Class for 64 bit register r10 522 reg_class r10_reg( 523 R10, R10_H 524 ); 525 526 // Class for 64 bit register r11 527 reg_class r11_reg( 528 R11, R11_H 529 ); 530 531 // Class for method register 532 reg_class method_reg( 533 R12, R12_H 534 ); 535 536 // Class for heapbase register 537 reg_class heapbase_reg( 538 R27, R27_H 539 ); 540 541 // Class for thread register 542 reg_class thread_reg( 543 R28, R28_H 544 ); 545 546 // Class for frame pointer register 547 reg_class fp_reg( 548 R29, R29_H 549 ); 550 551 // Class for link register 552 reg_class lr_reg( 553 R30, R30_H 554 ); 555 556 // Class for long sp register 557 reg_class sp_reg( 558 R31, R31_H 559 ); 560 561 // Class for all pointer registers 562 reg_class ptr_reg( 563 R0, R0_H, 564 R1, R1_H, 565 R2, R2_H, 566 R3, R3_H, 567 R4, R4_H, 568 R5, R5_H, 569 R6, R6_H, 570 R7, R7_H, 571 R10, R10_H, 572 R11, R11_H, 573 R12, R12_H, 574 R13, R13_H, 575 R14, R14_H, 576 R15, R15_H, 577 R16, R16_H, 578 R17, R17_H, 579 R18, R18_H, 580 R19, R19_H, 581 R20, R20_H, 582 R21, R21_H, 583 R22, R22_H, 584 R23, R23_H, 585 R24, R24_H, 586 R25, R25_H, 587 R26, R26_H, 588 R27, R27_H, 589 R28, R28_H, 590 R29, R29_H, 591 R30, R30_H, 592 R31, R31_H 593 ); 594 595 // Class for all non_special pointer registers 596 reg_class no_special_ptr_reg( 597 R0, R0_H, 598 R1, R1_H, 599 R2, R2_H, 600 R3, R3_H, 601 R4, R4_H, 602 R5, R5_H, 603 R6, R6_H, 604 R7, R7_H, 605 R10, R10_H, 606 R11, R11_H, 607 R12, R12_H, 608 R13, R13_H, 609 R14, R14_H, 610 R15, R15_H, 611 R16, R16_H, 612 R17, R17_H, 613 R18, R18_H, 614 R19, R19_H, 615 R20, R20_H, 616 R21, R21_H, 617 R22, R22_H, 618 R23, R23_H, 619 R24, R24_H, 620 R25, R25_H, 621 R26, R26_H, 622 /* R27, R27_H, */ // heapbase 623 /* R28, R28_H, */ // thread 624 /* R29, R29_H, */ // fp 625 /* R30, R30_H, */ // lr 626 /* R31, R31_H */ // sp 627 ); 628 629 // Class for all float registers 630 reg_class float_reg( 631 V0, 632 V1, 633 V2, 634 V3, 635 V4, 636 V5, 637 V6, 638 V7, 639 V8, 640 V9, 641 V10, 642 V11, 643 V12, 644 V13, 645 V14, 646 V15, 647 V16, 648 V17, 649 V18, 650 V19, 651 V20, 652 V21, 653 V22, 654 V23, 655 V24, 656 V25, 657 V26, 658 V27, 659 V28, 660 V29, 661 V30, 662 V31 663 ); 664 665 // Double precision float registers have virtual `high halves' that 666 // are needed by the allocator. 667 // Class for all double registers 668 reg_class double_reg( 669 V0, V0_H, 670 V1, V1_H, 671 V2, V2_H, 672 V3, V3_H, 673 V4, V4_H, 674 V5, V5_H, 675 V6, V6_H, 676 V7, V7_H, 677 V8, V8_H, 678 V9, V9_H, 679 V10, V10_H, 680 V11, V11_H, 681 V12, V12_H, 682 V13, V13_H, 683 V14, V14_H, 684 V15, V15_H, 685 V16, V16_H, 686 V17, V17_H, 687 V18, V18_H, 688 V19, V19_H, 689 V20, V20_H, 690 V21, V21_H, 691 V22, V22_H, 692 V23, V23_H, 693 V24, V24_H, 694 V25, V25_H, 695 V26, V26_H, 696 V27, V27_H, 697 V28, V28_H, 698 V29, V29_H, 699 V30, V30_H, 700 V31, V31_H 701 ); 702 703 // Class for 128 bit register v0 704 reg_class v0_reg( 705 V0, V0_H 706 ); 707 708 // Class for 128 bit register v1 709 reg_class v1_reg( 710 V1, V1_H 711 ); 712 713 // Class for 128 bit register v2 714 reg_class v2_reg( 715 V2, V2_H 716 ); 717 718 // Class for 128 bit register v3 719 reg_class v3_reg( 720 V3, V3_H 721 ); 722 723 // Singleton class for condition codes 724 reg_class int_flags(RFLAGS); 725 726 %} 727 728 //----------DEFINITION BLOCK--------------------------------------------------- 729 // Define name --> value mappings to inform the ADLC of an integer valued name 730 // Current support includes integer values in the range [0, 0x7FFFFFFF] 731 // Format: 732 // int_def <name> ( <int_value>, <expression>); 733 // Generated Code in ad_<arch>.hpp 734 // #define <name> (<expression>) 735 // // value == <int_value> 736 // Generated code in ad_<arch>.cpp adlc_verification() 737 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 738 // 739 740 // we follow the ppc-aix port in using a simple cost model which ranks 741 // register operations as cheap, memory ops as more expensive and 742 // branches as most expensive. the first two have a low as well as a 743 // normal cost. huge cost appears to be a way of saying don't do 744 // something 745 746 definitions %{ 747 // The default cost (of a register move instruction). 748 int_def INSN_COST ( 100, 100); 749 int_def BRANCH_COST ( 200, 2 * INSN_COST); 750 int_def CALL_COST ( 200, 2 * INSN_COST); 751 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 752 %} 753 754 755 //----------SOURCE BLOCK------------------------------------------------------- 756 // This is a block of C++ code which provides values, functions, and 757 // definitions necessary in the rest of the architecture description 758 759 source_hpp %{ 760 761 #include "memory/cardTableModRefBS.hpp" 762 763 class CallStubImpl { 764 765 //-------------------------------------------------------------- 766 //---< Used for optimization in Compile::shorten_branches >--- 767 //-------------------------------------------------------------- 768 769 public: 770 // Size of call trampoline stub. 771 static uint size_call_trampoline() { 772 return 0; // no call trampolines on this platform 773 } 774 775 // number of relocations needed by a call trampoline stub 776 static uint reloc_call_trampoline() { 777 return 0; // no call trampolines on this platform 778 } 779 }; 780 781 class HandlerImpl { 782 783 public: 784 785 static int emit_exception_handler(CodeBuffer &cbuf); 786 static int emit_deopt_handler(CodeBuffer& cbuf); 787 788 static uint size_exception_handler() { 789 return MacroAssembler::far_branch_size(); 790 } 791 792 static uint size_deopt_handler() { 793 // count one adr and one far branch instruction 794 return 4 * NativeInstruction::instruction_size; 795 } 796 }; 797 798 // graph traversal helpers 799 MemBarNode *has_parent_membar(const Node *n, 800 ProjNode *&ctl, ProjNode *&mem); 801 MemBarNode *has_child_membar(const MemBarNode *n, 802 ProjNode *&ctl, ProjNode *&mem); 803 804 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 805 bool unnecessary_acquire(const Node *barrier); 806 bool needs_acquiring_load(const Node *load); 807 808 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 809 bool unnecessary_release(const Node *barrier); 810 bool unnecessary_volatile(const Node *barrier); 811 bool needs_releasing_store(const Node *store); 812 813 // Use barrier instructions rather than load acquire / store 814 // release. 815 const bool UseBarriersForVolatile = false; 816 // Use barrier instructions for unsafe volatile gets rather than 817 // trying to identify an exact signature for them 818 const bool UseBarriersForUnsafeVolatileGet = false; 819 %} 820 821 source %{ 822 823 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 824 // use to implement volatile reads and writes. For a volatile read 825 // we simply need 826 // 827 // ldar<x> 828 // 829 // and for a volatile write we need 830 // 831 // stlr<x> 832 // 833 // Alternatively, we can implement them by pairing a normal 834 // load/store with a memory barrier. For a volatile read we need 835 // 836 // ldr<x> 837 // dmb ishld 838 // 839 // for a volatile write 840 // 841 // dmb ish 842 // str<x> 843 // dmb ish 844 // 845 // In order to generate the desired instruction sequence we need to 846 // be able to identify specific 'signature' ideal graph node 847 // sequences which i) occur as a translation of a volatile reads or 848 // writes and ii) do not occur through any other translation or 849 // graph transformation. We can then provide alternative aldc 850 // matching rules which translate these node sequences to the 851 // desired machine code sequences. Selection of the alternative 852 // rules can be implemented by predicates which identify the 853 // relevant node sequences. 854 // 855 // The ideal graph generator translates a volatile read to the node 856 // sequence 857 // 858 // LoadX[mo_acquire] 859 // MemBarAcquire 860 // 861 // As a special case when using the compressed oops optimization we 862 // may also see this variant 863 // 864 // LoadN[mo_acquire] 865 // DecodeN 866 // MemBarAcquire 867 // 868 // A volatile write is translated to the node sequence 869 // 870 // MemBarRelease 871 // StoreX[mo_release] 872 // MemBarVolatile 873 // 874 // n.b. the above node patterns are generated with a strict 875 // 'signature' configuration of input and output dependencies (see 876 // the predicates below for exact details). The two signatures are 877 // unique to translated volatile reads/stores -- they will not 878 // appear as a result of any other bytecode translation or inlining 879 // nor as a consequence of optimizing transforms. 880 // 881 // We also want to catch inlined unsafe volatile gets and puts and 882 // be able to implement them using either ldar<x>/stlr<x> or some 883 // combination of ldr<x>/stlr<x> and dmb instructions. 884 // 885 // Inlined unsafe volatiles puts manifest as a minor variant of the 886 // normal volatile put node sequence containing an extra cpuorder 887 // membar 888 // 889 // MemBarRelease 890 // MemBarCPUOrder 891 // StoreX[mo_release] 892 // MemBarVolatile 893 // 894 // n.b. as an aside, the cpuorder membar is not itself subject to 895 // matching and translation by adlc rules. However, the rule 896 // predicates need to detect its presence in order to correctly 897 // select the desired adlc rules. 898 // 899 // Inlined unsafe volatiles gets manifest as a somewhat different 900 // node sequence to a normal volatile get 901 // 902 // MemBarCPUOrder 903 // || \\ 904 // MemBarAcquire LoadX[mo_acquire] 905 // || 906 // MemBarCPUOrder 907 // 908 // In this case the acquire membar does not directly depend on the 909 // load. However, we can be sure that the load is generated from an 910 // inlined unsafe volatile get if we see it dependent on this unique 911 // sequence of membar nodes. Similarly, given an acquire membar we 912 // can know that it was added because of an inlined unsafe volatile 913 // get if it is fed and feeds a cpuorder membar and if its feed 914 // membar also feeds an acquiring load. 915 // 916 // So, where we can identify these volatile read and write 917 // signatures we can choose to plant either of the above two code 918 // sequences. For a volatile read we can simply plant a normal 919 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 920 // also choose to inhibit translation of the MemBarAcquire and 921 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 922 // 923 // When we recognise a volatile store signature we can choose to 924 // plant at a dmb ish as a translation for the MemBarRelease, a 925 // normal str<x> and then a dmb ish for the MemBarVolatile. 926 // Alternatively, we can inhibit translation of the MemBarRelease 927 // and MemBarVolatile and instead plant a simple stlr<x> 928 // instruction. 929 // 930 // Of course, the above only applies when we see these signature 931 // configurations. We still want to plant dmb instructions in any 932 // other cases where we may see a MemBarAcquire, MemBarRelease or 933 // MemBarVolatile. For example, at the end of a constructor which 934 // writes final/volatile fields we will see a MemBarRelease 935 // instruction and this needs a 'dmb ish' lest we risk the 936 // constructed object being visible without making the 937 // final/volatile field writes visible. 938 // 939 // n.b. the translation rules below which rely on detection of the 940 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 941 // If we see anything other than the signature configurations we 942 // always just translate the loads and stors to ldr<x> and str<x> 943 // and translate acquire, release and volatile membars to the 944 // relevant dmb instructions. 945 // 946 // n.b.b as a case in point for the above comment, the current 947 // predicates don't detect the precise signature for certain types 948 // of volatile object stores (where the heap_base input type is not 949 // known at compile-time to be non-NULL). In those cases the 950 // MemBarRelease and MemBarVolatile bracket an if-then-else sequence 951 // with a store in each branch (we need a different store depending 952 // on whether heap_base is actually NULL). In such a case we will 953 // just plant a dmb both before and after the branch/merge. The 954 // predicate could (and probably should) be fixed later to also 955 // detect this case. 956 957 // graph traversal helpers 958 959 // if node n is linked to a parent MemBarNode by an intervening 960 // Control or Memory ProjNode return the MemBarNode otherwise return 961 // NULL. 962 // 963 // n may only be a Load or a MemBar. 964 // 965 // The ProjNode* references c and m are used to return the relevant 966 // nodes. 967 968 MemBarNode *has_parent_membar(const Node *n, ProjNode *&c, ProjNode *&m) 969 { 970 Node *ctl = NULL; 971 Node *mem = NULL; 972 Node *membar = NULL; 973 974 if (n->is_Load()) { 975 ctl = n->lookup(LoadNode::Control); 976 mem = n->lookup(LoadNode::Memory); 977 } else if (n->is_MemBar()) { 978 ctl = n->lookup(TypeFunc::Control); 979 mem = n->lookup(TypeFunc::Memory); 980 } else { 981 return NULL; 982 } 983 984 if (!ctl || !mem || !ctl->is_Proj() || !mem->is_Proj()) 985 return NULL; 986 987 c = ctl->as_Proj(); 988 989 membar = ctl->lookup(0); 990 991 if (!membar || !membar->is_MemBar()) 992 return NULL; 993 994 m = mem->as_Proj(); 995 996 if (mem->lookup(0) != membar) 997 return NULL; 998 999 return membar->as_MemBar(); 1000 } 1001 1002 // if n is linked to a child MemBarNode by intervening Control and 1003 // Memory ProjNodes return the MemBarNode otherwise return NULL. 1004 // 1005 // The ProjNode** arguments c and m are used to return pointers to 1006 // the relevant nodes. A null argument means don't don't return a 1007 // value. 1008 1009 MemBarNode *has_child_membar(const MemBarNode *n, ProjNode *&c, ProjNode *&m) 1010 { 1011 ProjNode *ctl = n->proj_out(TypeFunc::Control); 1012 ProjNode *mem = n->proj_out(TypeFunc::Memory); 1013 1014 // MemBar needs to have both a Ctl and Mem projection 1015 if (! ctl || ! mem) 1016 return NULL; 1017 1018 c = ctl; 1019 m = mem; 1020 1021 MemBarNode *child = NULL; 1022 Node *x; 1023 1024 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1025 x = ctl->fast_out(i); 1026 // if we see a membar we keep hold of it. we may also see a new 1027 // arena copy of the original but it will appear later 1028 if (x->is_MemBar()) { 1029 child = x->as_MemBar(); 1030 break; 1031 } 1032 } 1033 1034 if (child == NULL) 1035 return NULL; 1036 1037 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1038 x = mem->fast_out(i); 1039 // if we see a membar we keep hold of it. we may also see a new 1040 // arena copy of the original but it will appear later 1041 if (x == child) { 1042 return child; 1043 } 1044 } 1045 return NULL; 1046 } 1047 1048 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1049 1050 bool unnecessary_acquire(const Node *barrier) { 1051 // assert barrier->is_MemBar(); 1052 if (UseBarriersForVolatile) 1053 // we need to plant a dmb 1054 return false; 1055 1056 // a volatile read derived from bytecode (or also from an inlined 1057 // SHA field read via LibraryCallKit::load_field_from_object) 1058 // manifests as a LoadX[mo_acquire] followed by an acquire membar 1059 // with a bogus read dependency on it's preceding load. so in those 1060 // cases we will find the load node at the PARMS offset of the 1061 // acquire membar. n.b. there may be an intervening DecodeN node. 1062 // 1063 // a volatile load derived from an inlined unsafe field access 1064 // manifests as a cpuorder membar with Ctl and Mem projections 1065 // feeding both an acquire membar and a LoadX[mo_acquire]. The 1066 // acquire then feeds another cpuorder membar via Ctl and Mem 1067 // projections. The load has no output dependency on these trailing 1068 // membars because subsequent nodes inserted into the graph take 1069 // their control feed from the final membar cpuorder meaning they 1070 // are all ordered after the load. 1071 1072 Node *x = barrier->lookup(TypeFunc::Parms); 1073 if (x) { 1074 // we are starting from an acquire and it has a fake dependency 1075 // 1076 // need to check for 1077 // 1078 // LoadX[mo_acquire] 1079 // { |1 } 1080 // {DecodeN} 1081 // |Parms 1082 // MemBarAcquire* 1083 // 1084 // where * tags node we were passed 1085 // and |k means input k 1086 if (x->is_DecodeNarrowPtr()) 1087 x = x->in(1); 1088 1089 return (x->is_Load() && x->as_Load()->is_acquire()); 1090 } 1091 1092 // only continue if we want to try to match unsafe volatile gets 1093 if (UseBarriersForUnsafeVolatileGet) 1094 return false; 1095 1096 // need to check for 1097 // 1098 // MemBarCPUOrder 1099 // || \\ 1100 // MemBarAcquire* LoadX[mo_acquire] 1101 // || 1102 // MemBarCPUOrder 1103 // 1104 // where * tags node we were passed 1105 // and || or \\ are Ctl+Mem feeds via intermediate Proj Nodes 1106 1107 // check for a parent MemBarCPUOrder 1108 ProjNode *ctl; 1109 ProjNode *mem; 1110 MemBarNode *parent = has_parent_membar(barrier, ctl, mem); 1111 if (!parent || parent->Opcode() != Op_MemBarCPUOrder) 1112 return false; 1113 // ensure the proj nodes both feed a LoadX[mo_acquire] 1114 LoadNode *ld = NULL; 1115 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1116 x = ctl->fast_out(i); 1117 // if we see a load we keep hold of it and stop searching 1118 if (x->is_Load()) { 1119 ld = x->as_Load(); 1120 break; 1121 } 1122 } 1123 // it must be an acquiring load 1124 if (! ld || ! ld->is_acquire()) 1125 return false; 1126 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1127 x = mem->fast_out(i); 1128 // if we see the same load we drop it and stop searching 1129 if (x == ld) { 1130 ld = NULL; 1131 break; 1132 } 1133 } 1134 // we must have dropped the load 1135 if (ld) 1136 return false; 1137 // check for a child cpuorder membar 1138 MemBarNode *child = has_child_membar(barrier->as_MemBar(), ctl, mem); 1139 if (!child || child->Opcode() != Op_MemBarCPUOrder) 1140 return false; 1141 1142 return true; 1143 } 1144 1145 bool needs_acquiring_load(const Node *n) 1146 { 1147 // assert n->is_Load(); 1148 if (UseBarriersForVolatile) 1149 // we use a normal load and a dmb 1150 return false; 1151 1152 LoadNode *ld = n->as_Load(); 1153 1154 if (!ld->is_acquire()) 1155 return false; 1156 1157 // check if this load is feeding an acquire membar 1158 // 1159 // LoadX[mo_acquire] 1160 // { |1 } 1161 // {DecodeN} 1162 // |Parms 1163 // MemBarAcquire* 1164 // 1165 // where * tags node we were passed 1166 // and |k means input k 1167 1168 Node *start = ld; 1169 Node *mbacq = NULL; 1170 1171 // if we hit a DecodeNarrowPtr we reset the start node and restart 1172 // the search through the outputs 1173 restart: 1174 1175 for (DUIterator_Fast imax, i = start->fast_outs(imax); i < imax; i++) { 1176 Node *x = start->fast_out(i); 1177 if (x->is_MemBar() && x->Opcode() == Op_MemBarAcquire) { 1178 mbacq = x; 1179 } else if (!mbacq && 1180 (x->is_DecodeNarrowPtr() || 1181 (x->is_Mach() && x->Opcode() == Op_DecodeN))) { 1182 start = x; 1183 goto restart; 1184 } 1185 } 1186 1187 if (mbacq) { 1188 return true; 1189 } 1190 1191 // only continue if we want to try to match unsafe volatile gets 1192 if (UseBarriersForUnsafeVolatileGet) 1193 return false; 1194 1195 // check if Ctl and Proj feed comes from a MemBarCPUOrder 1196 // 1197 // MemBarCPUOrder 1198 // || \\ 1199 // MemBarAcquire* LoadX[mo_acquire] 1200 // || 1201 // MemBarCPUOrder 1202 1203 MemBarNode *membar; 1204 ProjNode *ctl; 1205 ProjNode *mem; 1206 1207 membar = has_parent_membar(ld, ctl, mem); 1208 1209 if (!membar || !membar->Opcode() == Op_MemBarCPUOrder) 1210 return false; 1211 1212 // ensure that there is a CPUOrder->Acquire->CPUOrder membar chain 1213 1214 membar = has_child_membar(membar, ctl, mem); 1215 1216 if (!membar || !membar->Opcode() == Op_MemBarAcquire) 1217 return false; 1218 1219 membar = has_child_membar(membar, ctl, mem); 1220 1221 if (!membar || !membar->Opcode() == Op_MemBarCPUOrder) 1222 return false; 1223 1224 return true; 1225 } 1226 1227 bool unnecessary_release(const Node *n) { 1228 // assert n->is_MemBar(); 1229 if (UseBarriersForVolatile) 1230 // we need to plant a dmb 1231 return false; 1232 1233 // ok, so we can omit this release barrier if it has been inserted 1234 // as part of a volatile store sequence 1235 // 1236 // MemBarRelease 1237 // { || } 1238 // {MemBarCPUOrder} -- optional 1239 // || \\ 1240 // || StoreX[mo_release] 1241 // | \ / 1242 // | MergeMem 1243 // | / 1244 // MemBarVolatile 1245 // 1246 // where 1247 // || and \\ represent Ctl and Mem feeds via Proj nodes 1248 // | \ and / indicate further routing of the Ctl and Mem feeds 1249 // 1250 // so we need to check that 1251 // 1252 // ia) the release membar (or its dependent cpuorder membar) feeds 1253 // control to a store node (via a Control project node) 1254 // 1255 // ii) the store is ordered release 1256 // 1257 // iii) the release membar (or its dependent cpuorder membar) feeds 1258 // control to a volatile membar (via the same Control project node) 1259 // 1260 // iv) the release membar feeds memory to a merge mem and to the 1261 // same store (both via a single Memory proj node) 1262 // 1263 // v) the store outputs to the merge mem 1264 // 1265 // vi) the merge mem outputs to the same volatile membar 1266 // 1267 // n.b. if this is an inlined unsafe node then the release membar 1268 // may feed its control and memory links via an intervening cpuorder 1269 // membar. this case can be dealt with when we check the release 1270 // membar projections. if they both feed a single cpuorder membar 1271 // node continue to make the same checks as above but with the 1272 // cpuorder membar substituted for the release membar. if they don't 1273 // both feed a cpuorder membar then the check fails. 1274 // 1275 // n.b.b. for an inlined unsafe store of an object in the case where 1276 // !TypePtr::NULL_PTR->higher_equal(type(heap_base_oop)) we may see 1277 // an embedded if then else where we expect the store. this is 1278 // needed to do the right type of store depending on whether 1279 // heap_base is NULL. We could check for that but for now we can 1280 // just take the hit of on inserting a redundant dmb for this 1281 // redundant volatile membar 1282 1283 MemBarNode *barrier = n->as_MemBar(); 1284 ProjNode *ctl; 1285 ProjNode *mem; 1286 // check for an intervening cpuorder membar 1287 MemBarNode *b = has_child_membar(barrier, ctl, mem); 1288 if (b && b->Opcode() == Op_MemBarCPUOrder) { 1289 // ok, so start form the dependent cpuorder barrier 1290 barrier = b; 1291 } 1292 // check the ctl and mem flow 1293 ctl = barrier->proj_out(TypeFunc::Control); 1294 mem = barrier->proj_out(TypeFunc::Memory); 1295 1296 // the barrier needs to have both a Ctl and Mem projection 1297 if (! ctl || ! mem) 1298 return false; 1299 1300 Node *x = NULL; 1301 Node *mbvol = NULL; 1302 StoreNode * st = NULL; 1303 1304 // For a normal volatile write the Ctl ProjNode should have output 1305 // to a MemBarVolatile and a Store marked as releasing 1306 // 1307 // n.b. for an inlined unsafe store of an object in the case where 1308 // !TypePtr::NULL_PTR->higher_equal(type(heap_base_oop)) we may see 1309 // an embedded if then else where we expect the store. this is 1310 // needed to do the right type of store depending on whether 1311 // heap_base is NULL. We could check for that case too but for now 1312 // we can just take the hit of inserting a dmb and a non-volatile 1313 // store to implement the volatile store 1314 1315 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1316 x = ctl->fast_out(i); 1317 if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) { 1318 if (mbvol) { 1319 return false; 1320 } 1321 mbvol = x; 1322 } else if (x->is_Store()) { 1323 st = x->as_Store(); 1324 if (! st->is_release()) { 1325 return false; 1326 } 1327 } else if (!x->is_Mach()) { 1328 // we may see mach nodes added during matching but nothing else 1329 return false; 1330 } 1331 } 1332 1333 if (!mbvol || !st) 1334 return false; 1335 1336 // the Mem ProjNode should output to a MergeMem and the same Store 1337 Node *mm = NULL; 1338 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1339 x = mem->fast_out(i); 1340 if (!mm && x->is_MergeMem()) { 1341 mm = x; 1342 } else if (x != st && !x->is_Mach()) { 1343 // we may see mach nodes added during matching but nothing else 1344 return false; 1345 } 1346 } 1347 1348 if (!mm) 1349 return false; 1350 1351 // the MergeMem should output to the MemBarVolatile 1352 for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) { 1353 x = mm->fast_out(i); 1354 if (x != mbvol && !x->is_Mach()) { 1355 // we may see mach nodes added during matching but nothing else 1356 return false; 1357 } 1358 } 1359 1360 return true; 1361 } 1362 1363 bool unnecessary_volatile(const Node *n) { 1364 // assert n->is_MemBar(); 1365 if (UseBarriersForVolatile) 1366 // we need to plant a dmb 1367 return false; 1368 1369 // ok, so we can omit this volatile barrier if it has been inserted 1370 // as part of a volatile store sequence 1371 // 1372 // MemBarRelease 1373 // { || } 1374 // {MemBarCPUOrder} -- optional 1375 // || \\ 1376 // || StoreX[mo_release] 1377 // | \ / 1378 // | MergeMem 1379 // | / 1380 // MemBarVolatile 1381 // 1382 // where 1383 // || and \\ represent Ctl and Mem feeds via Proj nodes 1384 // | \ and / indicate further routing of the Ctl and Mem feeds 1385 // 1386 // we need to check that 1387 // 1388 // i) the volatile membar gets its control feed from a release 1389 // membar (or its dependent cpuorder membar) via a Control project 1390 // node 1391 // 1392 // ii) the release membar (or its dependent cpuorder membar) also 1393 // feeds control to a store node via the same proj node 1394 // 1395 // iii) the store is ordered release 1396 // 1397 // iv) the release membar (or its dependent cpuorder membar) feeds 1398 // memory to a merge mem and to the same store (both via a single 1399 // Memory proj node) 1400 // 1401 // v) the store outputs to the merge mem 1402 // 1403 // vi) the merge mem outputs to the volatile membar 1404 // 1405 // n.b. for an inlined unsafe store of an object in the case where 1406 // !TypePtr::NULL_PTR->higher_equal(type(heap_base_oop)) we may see 1407 // an embedded if then else where we expect the store. this is 1408 // needed to do the right type of store depending on whether 1409 // heap_base is NULL. We could check for that but for now we can 1410 // just take the hit of on inserting a redundant dmb for this 1411 // redundant volatile membar 1412 1413 MemBarNode *mbvol = n->as_MemBar(); 1414 Node *x = n->lookup(TypeFunc::Control); 1415 1416 if (! x || !x->is_Proj()) 1417 return false; 1418 1419 ProjNode *proj = x->as_Proj(); 1420 1421 x = proj->lookup(0); 1422 1423 if (!x || !x->is_MemBar()) 1424 return false; 1425 1426 MemBarNode *barrier = x->as_MemBar(); 1427 1428 // if the barrier is a release membar we have what we want. if it is 1429 // a cpuorder membar then we need to ensure that it is fed by a 1430 // release membar in which case we proceed to check the graph below 1431 // this cpuorder membar as the feed 1432 1433 if (x->Opcode() != Op_MemBarRelease) { 1434 if (x->Opcode() != Op_MemBarCPUOrder) 1435 return false; 1436 ProjNode *ctl; 1437 ProjNode *mem; 1438 MemBarNode *b = has_parent_membar(x, ctl, mem); 1439 if (!b || !b->Opcode() == Op_MemBarRelease) 1440 return false; 1441 } 1442 1443 ProjNode *ctl = barrier->proj_out(TypeFunc::Control); 1444 ProjNode *mem = barrier->proj_out(TypeFunc::Memory); 1445 1446 // barrier needs to have both a Ctl and Mem projection 1447 // and we need to have reached it via the Ctl projection 1448 if (! ctl || ! mem || ctl != proj) 1449 return false; 1450 1451 StoreNode * st = NULL; 1452 1453 // The Ctl ProjNode should have output to a MemBarVolatile and 1454 // a Store marked as releasing 1455 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1456 x = ctl->fast_out(i); 1457 if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) { 1458 if (x != mbvol) { 1459 return false; 1460 } 1461 } else if (x->is_Store()) { 1462 st = x->as_Store(); 1463 if (! st->is_release()) { 1464 return false; 1465 } 1466 } else if (!x->is_Mach()){ 1467 // we may see mach nodes added during matching but nothing else 1468 return false; 1469 } 1470 } 1471 1472 if (!st) 1473 return false; 1474 1475 // the Mem ProjNode should output to a MergeMem and the same Store 1476 Node *mm = NULL; 1477 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1478 x = mem->fast_out(i); 1479 if (!mm && x->is_MergeMem()) { 1480 mm = x; 1481 } else if (x != st && !x->is_Mach()) { 1482 // we may see mach nodes added during matching but nothing else 1483 return false; 1484 } 1485 } 1486 1487 if (!mm) 1488 return false; 1489 1490 // the MergeMem should output to the MemBarVolatile 1491 for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) { 1492 x = mm->fast_out(i); 1493 if (x != mbvol && !x->is_Mach()) { 1494 // we may see mach nodes added during matching but nothing else 1495 return false; 1496 } 1497 } 1498 1499 return true; 1500 } 1501 1502 1503 1504 bool needs_releasing_store(const Node *n) 1505 { 1506 // assert n->is_Store(); 1507 if (UseBarriersForVolatile) 1508 // we use a normal store and dmb combination 1509 return false; 1510 1511 StoreNode *st = n->as_Store(); 1512 1513 if (!st->is_release()) 1514 return false; 1515 1516 // check if this store is bracketed by a release (or its dependent 1517 // cpuorder membar) and a volatile membar 1518 // 1519 // MemBarRelease 1520 // { || } 1521 // {MemBarCPUOrder} -- optional 1522 // || \\ 1523 // || StoreX[mo_release] 1524 // | \ / 1525 // | MergeMem 1526 // | / 1527 // MemBarVolatile 1528 // 1529 // where 1530 // || and \\ represent Ctl and Mem feeds via Proj nodes 1531 // | \ and / indicate further routing of the Ctl and Mem feeds 1532 // 1533 1534 1535 Node *x = st->lookup(TypeFunc::Control); 1536 1537 if (! x || !x->is_Proj()) 1538 return false; 1539 1540 ProjNode *proj = x->as_Proj(); 1541 1542 x = proj->lookup(0); 1543 1544 if (!x || !x->is_MemBar()) 1545 return false; 1546 1547 MemBarNode *barrier = x->as_MemBar(); 1548 1549 // if the barrier is a release membar we have what we want. if it is 1550 // a cpuorder membar then we need to ensure that it is fed by a 1551 // release membar in which case we proceed to check the graph below 1552 // this cpuorder membar as the feed 1553 1554 if (x->Opcode() != Op_MemBarRelease) { 1555 if (x->Opcode() != Op_MemBarCPUOrder) 1556 return false; 1557 Node *ctl = x->lookup(TypeFunc::Control); 1558 Node *mem = x->lookup(TypeFunc::Memory); 1559 if (!ctl || !ctl->is_Proj() || !mem || !mem->is_Proj()) 1560 return false; 1561 x = ctl->lookup(0); 1562 if (!x || !x->is_MemBar() || !x->Opcode() == Op_MemBarRelease) 1563 return false; 1564 Node *y = mem->lookup(0); 1565 if (!y || y != x) 1566 return false; 1567 } 1568 1569 ProjNode *ctl = barrier->proj_out(TypeFunc::Control); 1570 ProjNode *mem = barrier->proj_out(TypeFunc::Memory); 1571 1572 // MemBarRelease needs to have both a Ctl and Mem projection 1573 // and we need to have reached it via the Ctl projection 1574 if (! ctl || ! mem || ctl != proj) 1575 return false; 1576 1577 MemBarNode *mbvol = NULL; 1578 1579 // The Ctl ProjNode should have output to a MemBarVolatile and 1580 // a Store marked as releasing 1581 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { 1582 x = ctl->fast_out(i); 1583 if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) { 1584 mbvol = x->as_MemBar(); 1585 } else if (x->is_Store()) { 1586 if (x != st) { 1587 return false; 1588 } 1589 } else if (!x->is_Mach()){ 1590 return false; 1591 } 1592 } 1593 1594 if (!mbvol) 1595 return false; 1596 1597 // the Mem ProjNode should output to a MergeMem and the same Store 1598 Node *mm = NULL; 1599 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 1600 x = mem->fast_out(i); 1601 if (!mm && x->is_MergeMem()) { 1602 mm = x; 1603 } else if (x != st && !x->is_Mach()) { 1604 return false; 1605 } 1606 } 1607 1608 if (!mm) 1609 return false; 1610 1611 // the MergeMem should output to the MemBarVolatile 1612 for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) { 1613 x = mm->fast_out(i); 1614 if (x != mbvol && !x->is_Mach()) { 1615 return false; 1616 } 1617 } 1618 1619 return true; 1620 } 1621 1622 1623 1624 #define __ _masm. 1625 1626 // advance declarations for helper functions to convert register 1627 // indices to register objects 1628 1629 // the ad file has to provide implementations of certain methods 1630 // expected by the generic code 1631 // 1632 // REQUIRED FUNCTIONALITY 1633 1634 //============================================================================= 1635 1636 // !!!!! Special hack to get all types of calls to specify the byte offset 1637 // from the start of the call to the point where the return address 1638 // will point. 1639 1640 int MachCallStaticJavaNode::ret_addr_offset() 1641 { 1642 // call should be a simple bl 1643 // unless this is a method handle invoke in which case it is 1644 // mov(rfp, sp), bl, mov(sp, rfp) 1645 int off = 4; 1646 if (_method_handle_invoke) { 1647 off += 4; 1648 } 1649 return off; 1650 } 1651 1652 int MachCallDynamicJavaNode::ret_addr_offset() 1653 { 1654 return 16; // movz, movk, movk, bl 1655 } 1656 1657 int MachCallRuntimeNode::ret_addr_offset() { 1658 // for generated stubs the call will be 1659 // far_call(addr) 1660 // for real runtime callouts it will be six instructions 1661 // see aarch64_enc_java_to_runtime 1662 // adr(rscratch2, retaddr) 1663 // lea(rscratch1, RuntimeAddress(addr) 1664 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1665 // blrt rscratch1 1666 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1667 if (cb) { 1668 return MacroAssembler::far_branch_size(); 1669 } else { 1670 return 6 * NativeInstruction::instruction_size; 1671 } 1672 } 1673 1674 // Indicate if the safepoint node needs the polling page as an input 1675 1676 // the shared code plants the oop data at the start of the generated 1677 // code for the safepoint node and that needs ot be at the load 1678 // instruction itself. so we cannot plant a mov of the safepoint poll 1679 // address followed by a load. setting this to true means the mov is 1680 // scheduled as a prior instruction. that's better for scheduling 1681 // anyway. 1682 1683 bool SafePointNode::needs_polling_address_input() 1684 { 1685 return true; 1686 } 1687 1688 //============================================================================= 1689 1690 #ifndef PRODUCT 1691 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1692 st->print("BREAKPOINT"); 1693 } 1694 #endif 1695 1696 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1697 MacroAssembler _masm(&cbuf); 1698 __ brk(0); 1699 } 1700 1701 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1702 return MachNode::size(ra_); 1703 } 1704 1705 //============================================================================= 1706 1707 #ifndef PRODUCT 1708 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1709 st->print("nop \t# %d bytes pad for loops and calls", _count); 1710 } 1711 #endif 1712 1713 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1714 MacroAssembler _masm(&cbuf); 1715 for (int i = 0; i < _count; i++) { 1716 __ nop(); 1717 } 1718 } 1719 1720 uint MachNopNode::size(PhaseRegAlloc*) const { 1721 return _count * NativeInstruction::instruction_size; 1722 } 1723 1724 //============================================================================= 1725 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1726 1727 int Compile::ConstantTable::calculate_table_base_offset() const { 1728 return 0; // absolute addressing, no offset 1729 } 1730 1731 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1732 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1733 ShouldNotReachHere(); 1734 } 1735 1736 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1737 // Empty encoding 1738 } 1739 1740 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1741 return 0; 1742 } 1743 1744 #ifndef PRODUCT 1745 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1746 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1747 } 1748 #endif 1749 1750 #ifndef PRODUCT 1751 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1752 Compile* C = ra_->C; 1753 1754 int framesize = C->frame_slots() << LogBytesPerInt; 1755 1756 if (C->need_stack_bang(framesize)) 1757 st->print("# stack bang size=%d\n\t", framesize); 1758 1759 if (framesize == 0) { 1760 // Is this even possible? 1761 st->print("stp lr, rfp, [sp, #%d]!", -(2 * wordSize)); 1762 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1763 st->print("sub sp, sp, #%d\n\t", framesize); 1764 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1765 } else { 1766 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1767 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1768 st->print("sub sp, sp, rscratch1"); 1769 } 1770 } 1771 #endif 1772 1773 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1774 Compile* C = ra_->C; 1775 MacroAssembler _masm(&cbuf); 1776 1777 // n.b. frame size includes space for return pc and rfp 1778 const long framesize = C->frame_size_in_bytes(); 1779 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 1780 1781 // insert a nop at the start of the prolog so we can patch in a 1782 // branch if we need to invalidate the method later 1783 __ nop(); 1784 1785 int bangsize = C->bang_size_in_bytes(); 1786 if (C->need_stack_bang(bangsize) && UseStackBanging) 1787 __ generate_stack_overflow_check(bangsize); 1788 1789 __ build_frame(framesize); 1790 1791 if (NotifySimulator) { 1792 __ notify(Assembler::method_entry); 1793 } 1794 1795 if (VerifyStackAtCalls) { 1796 Unimplemented(); 1797 } 1798 1799 C->set_frame_complete(cbuf.insts_size()); 1800 1801 if (C->has_mach_constant_base_node()) { 1802 // NOTE: We set the table base offset here because users might be 1803 // emitted before MachConstantBaseNode. 1804 Compile::ConstantTable& constant_table = C->constant_table(); 1805 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1806 } 1807 } 1808 1809 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1810 { 1811 return MachNode::size(ra_); // too many variables; just compute it 1812 // the hard way 1813 } 1814 1815 int MachPrologNode::reloc() const 1816 { 1817 return 0; 1818 } 1819 1820 //============================================================================= 1821 1822 #ifndef PRODUCT 1823 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1824 Compile* C = ra_->C; 1825 int framesize = C->frame_slots() << LogBytesPerInt; 1826 1827 st->print("# pop frame %d\n\t",framesize); 1828 1829 if (framesize == 0) { 1830 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1831 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1832 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1833 st->print("add sp, sp, #%d\n\t", framesize); 1834 } else { 1835 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1836 st->print("add sp, sp, rscratch1\n\t"); 1837 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1838 } 1839 1840 if (do_polling() && C->is_method_compilation()) { 1841 st->print("# touch polling page\n\t"); 1842 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1843 st->print("ldr zr, [rscratch1]"); 1844 } 1845 } 1846 #endif 1847 1848 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1849 Compile* C = ra_->C; 1850 MacroAssembler _masm(&cbuf); 1851 int framesize = C->frame_slots() << LogBytesPerInt; 1852 1853 __ remove_frame(framesize); 1854 1855 if (NotifySimulator) { 1856 __ notify(Assembler::method_reentry); 1857 } 1858 1859 if (do_polling() && C->is_method_compilation()) { 1860 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1861 } 1862 } 1863 1864 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1865 // Variable size. Determine dynamically. 1866 return MachNode::size(ra_); 1867 } 1868 1869 int MachEpilogNode::reloc() const { 1870 // Return number of relocatable values contained in this instruction. 1871 return 1; // 1 for polling page. 1872 } 1873 1874 const Pipeline * MachEpilogNode::pipeline() const { 1875 return MachNode::pipeline_class(); 1876 } 1877 1878 // This method seems to be obsolete. It is declared in machnode.hpp 1879 // and defined in all *.ad files, but it is never called. Should we 1880 // get rid of it? 1881 int MachEpilogNode::safepoint_offset() const { 1882 assert(do_polling(), "no return for this epilog node"); 1883 return 4; 1884 } 1885 1886 //============================================================================= 1887 1888 // Figure out which register class each belongs in: rc_int, rc_float or 1889 // rc_stack. 1890 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1891 1892 static enum RC rc_class(OptoReg::Name reg) { 1893 1894 if (reg == OptoReg::Bad) { 1895 return rc_bad; 1896 } 1897 1898 // we have 30 int registers * 2 halves 1899 // (rscratch1 and rscratch2 are omitted) 1900 1901 if (reg < 60) { 1902 return rc_int; 1903 } 1904 1905 // we have 32 float register * 2 halves 1906 if (reg < 60 + 64) { 1907 return rc_float; 1908 } 1909 1910 // Between float regs & stack is the flags regs. 1911 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1912 1913 return rc_stack; 1914 } 1915 1916 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1917 Compile* C = ra_->C; 1918 1919 // Get registers to move. 1920 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1921 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1922 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1923 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1924 1925 enum RC src_hi_rc = rc_class(src_hi); 1926 enum RC src_lo_rc = rc_class(src_lo); 1927 enum RC dst_hi_rc = rc_class(dst_hi); 1928 enum RC dst_lo_rc = rc_class(dst_lo); 1929 1930 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1931 1932 if (src_hi != OptoReg::Bad) { 1933 assert((src_lo&1)==0 && src_lo+1==src_hi && 1934 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1935 "expected aligned-adjacent pairs"); 1936 } 1937 1938 if (src_lo == dst_lo && src_hi == dst_hi) { 1939 return 0; // Self copy, no move. 1940 } 1941 1942 switch (src_lo_rc) { 1943 case rc_int: 1944 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1945 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1946 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1947 // 64 bit 1948 if (cbuf) { 1949 MacroAssembler _masm(cbuf); 1950 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1951 as_Register(Matcher::_regEncode[src_lo])); 1952 } else if (st) { 1953 st->print("mov %s, %s\t# shuffle", 1954 Matcher::regName[dst_lo], 1955 Matcher::regName[src_lo]); 1956 } 1957 } else { 1958 // 32 bit 1959 if (cbuf) { 1960 MacroAssembler _masm(cbuf); 1961 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1962 as_Register(Matcher::_regEncode[src_lo])); 1963 } else if (st) { 1964 st->print("movw %s, %s\t# shuffle", 1965 Matcher::regName[dst_lo], 1966 Matcher::regName[src_lo]); 1967 } 1968 } 1969 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1970 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1971 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1972 // 64 bit 1973 if (cbuf) { 1974 MacroAssembler _masm(cbuf); 1975 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1976 as_Register(Matcher::_regEncode[src_lo])); 1977 } else if (st) { 1978 st->print("fmovd %s, %s\t# shuffle", 1979 Matcher::regName[dst_lo], 1980 Matcher::regName[src_lo]); 1981 } 1982 } else { 1983 // 32 bit 1984 if (cbuf) { 1985 MacroAssembler _masm(cbuf); 1986 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1987 as_Register(Matcher::_regEncode[src_lo])); 1988 } else if (st) { 1989 st->print("fmovs %s, %s\t# shuffle", 1990 Matcher::regName[dst_lo], 1991 Matcher::regName[src_lo]); 1992 } 1993 } 1994 } else { // gpr --> stack spill 1995 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1996 int dst_offset = ra_->reg2offset(dst_lo); 1997 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1998 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1999 // 64 bit 2000 if (cbuf) { 2001 MacroAssembler _masm(cbuf); 2002 __ str(as_Register(Matcher::_regEncode[src_lo]), 2003 Address(sp, dst_offset)); 2004 } else if (st) { 2005 st->print("str %s, [sp, #%d]\t# spill", 2006 Matcher::regName[src_lo], 2007 dst_offset); 2008 } 2009 } else { 2010 // 32 bit 2011 if (cbuf) { 2012 MacroAssembler _masm(cbuf); 2013 __ strw(as_Register(Matcher::_regEncode[src_lo]), 2014 Address(sp, dst_offset)); 2015 } else if (st) { 2016 st->print("strw %s, [sp, #%d]\t# spill", 2017 Matcher::regName[src_lo], 2018 dst_offset); 2019 } 2020 } 2021 } 2022 return 4; 2023 case rc_float: 2024 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 2025 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2026 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2027 // 64 bit 2028 if (cbuf) { 2029 MacroAssembler _masm(cbuf); 2030 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 2031 as_FloatRegister(Matcher::_regEncode[src_lo])); 2032 } else if (st) { 2033 st->print("fmovd %s, %s\t# shuffle", 2034 Matcher::regName[dst_lo], 2035 Matcher::regName[src_lo]); 2036 } 2037 } else { 2038 // 32 bit 2039 if (cbuf) { 2040 MacroAssembler _masm(cbuf); 2041 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 2042 as_FloatRegister(Matcher::_regEncode[src_lo])); 2043 } else if (st) { 2044 st->print("fmovs %s, %s\t# shuffle", 2045 Matcher::regName[dst_lo], 2046 Matcher::regName[src_lo]); 2047 } 2048 } 2049 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 2050 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2051 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2052 // 64 bit 2053 if (cbuf) { 2054 MacroAssembler _masm(cbuf); 2055 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2056 as_FloatRegister(Matcher::_regEncode[src_lo])); 2057 } else if (st) { 2058 st->print("fmovd %s, %s\t# shuffle", 2059 Matcher::regName[dst_lo], 2060 Matcher::regName[src_lo]); 2061 } 2062 } else { 2063 // 32 bit 2064 if (cbuf) { 2065 MacroAssembler _masm(cbuf); 2066 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2067 as_FloatRegister(Matcher::_regEncode[src_lo])); 2068 } else if (st) { 2069 st->print("fmovs %s, %s\t# shuffle", 2070 Matcher::regName[dst_lo], 2071 Matcher::regName[src_lo]); 2072 } 2073 } 2074 } else { // fpr --> stack spill 2075 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2076 int dst_offset = ra_->reg2offset(dst_lo); 2077 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2078 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2079 // 64 bit 2080 if (cbuf) { 2081 MacroAssembler _masm(cbuf); 2082 __ strd(as_FloatRegister(Matcher::_regEncode[src_lo]), 2083 Address(sp, dst_offset)); 2084 } else if (st) { 2085 st->print("strd %s, [sp, #%d]\t# spill", 2086 Matcher::regName[src_lo], 2087 dst_offset); 2088 } 2089 } else { 2090 // 32 bit 2091 if (cbuf) { 2092 MacroAssembler _masm(cbuf); 2093 __ strs(as_FloatRegister(Matcher::_regEncode[src_lo]), 2094 Address(sp, dst_offset)); 2095 } else if (st) { 2096 st->print("strs %s, [sp, #%d]\t# spill", 2097 Matcher::regName[src_lo], 2098 dst_offset); 2099 } 2100 } 2101 } 2102 return 4; 2103 case rc_stack: 2104 int src_offset = ra_->reg2offset(src_lo); 2105 if (dst_lo_rc == rc_int) { // stack --> gpr load 2106 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2107 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2108 // 64 bit 2109 if (cbuf) { 2110 MacroAssembler _masm(cbuf); 2111 __ ldr(as_Register(Matcher::_regEncode[dst_lo]), 2112 Address(sp, src_offset)); 2113 } else if (st) { 2114 st->print("ldr %s, [sp, %d]\t# restore", 2115 Matcher::regName[dst_lo], 2116 src_offset); 2117 } 2118 } else { 2119 // 32 bit 2120 if (cbuf) { 2121 MacroAssembler _masm(cbuf); 2122 __ ldrw(as_Register(Matcher::_regEncode[dst_lo]), 2123 Address(sp, src_offset)); 2124 } else if (st) { 2125 st->print("ldr %s, [sp, %d]\t# restore", 2126 Matcher::regName[dst_lo], 2127 src_offset); 2128 } 2129 } 2130 return 4; 2131 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 2132 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2133 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2134 // 64 bit 2135 if (cbuf) { 2136 MacroAssembler _masm(cbuf); 2137 __ ldrd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2138 Address(sp, src_offset)); 2139 } else if (st) { 2140 st->print("ldrd %s, [sp, %d]\t# restore", 2141 Matcher::regName[dst_lo], 2142 src_offset); 2143 } 2144 } else { 2145 // 32 bit 2146 if (cbuf) { 2147 MacroAssembler _masm(cbuf); 2148 __ ldrs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2149 Address(sp, src_offset)); 2150 } else if (st) { 2151 st->print("ldrs %s, [sp, %d]\t# restore", 2152 Matcher::regName[dst_lo], 2153 src_offset); 2154 } 2155 } 2156 return 4; 2157 } else { // stack --> stack copy 2158 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2159 int dst_offset = ra_->reg2offset(dst_lo); 2160 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 2161 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 2162 // 64 bit 2163 if (cbuf) { 2164 MacroAssembler _masm(cbuf); 2165 __ ldr(rscratch1, Address(sp, src_offset)); 2166 __ str(rscratch1, Address(sp, dst_offset)); 2167 } else if (st) { 2168 st->print("ldr rscratch1, [sp, %d]\t# mem-mem spill", 2169 src_offset); 2170 st->print("\n\t"); 2171 st->print("str rscratch1, [sp, %d]", 2172 dst_offset); 2173 } 2174 } else { 2175 // 32 bit 2176 if (cbuf) { 2177 MacroAssembler _masm(cbuf); 2178 __ ldrw(rscratch1, Address(sp, src_offset)); 2179 __ strw(rscratch1, Address(sp, dst_offset)); 2180 } else if (st) { 2181 st->print("ldrw rscratch1, [sp, %d]\t# mem-mem spill", 2182 src_offset); 2183 st->print("\n\t"); 2184 st->print("strw rscratch1, [sp, %d]", 2185 dst_offset); 2186 } 2187 } 2188 return 8; 2189 } 2190 } 2191 2192 assert(false," bad rc_class for spill "); 2193 Unimplemented(); 2194 return 0; 2195 2196 } 2197 2198 #ifndef PRODUCT 2199 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2200 if (!ra_) 2201 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 2202 else 2203 implementation(NULL, ra_, false, st); 2204 } 2205 #endif 2206 2207 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2208 implementation(&cbuf, ra_, false, NULL); 2209 } 2210 2211 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 2212 return implementation(NULL, ra_, true, NULL); 2213 } 2214 2215 //============================================================================= 2216 2217 #ifndef PRODUCT 2218 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2219 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2220 int reg = ra_->get_reg_first(this); 2221 st->print("add %s, rsp, #%d]\t# box lock", 2222 Matcher::regName[reg], offset); 2223 } 2224 #endif 2225 2226 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2227 MacroAssembler _masm(&cbuf); 2228 2229 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2230 int reg = ra_->get_encode(this); 2231 2232 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 2233 __ add(as_Register(reg), sp, offset); 2234 } else { 2235 ShouldNotReachHere(); 2236 } 2237 } 2238 2239 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2240 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2241 return 4; 2242 } 2243 2244 //============================================================================= 2245 2246 #ifndef PRODUCT 2247 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 2248 { 2249 st->print_cr("# MachUEPNode"); 2250 if (UseCompressedClassPointers) { 2251 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2252 if (Universe::narrow_klass_shift() != 0) { 2253 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 2254 } 2255 } else { 2256 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2257 } 2258 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 2259 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 2260 } 2261 #endif 2262 2263 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2264 { 2265 // This is the unverified entry point. 2266 MacroAssembler _masm(&cbuf); 2267 2268 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2269 Label skip; 2270 // TODO 2271 // can we avoid this skip and still use a reloc? 2272 __ br(Assembler::EQ, skip); 2273 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2274 __ bind(skip); 2275 } 2276 2277 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 2278 { 2279 return MachNode::size(ra_); 2280 } 2281 2282 // REQUIRED EMIT CODE 2283 2284 //============================================================================= 2285 2286 // Emit exception handler code. 2287 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2288 { 2289 // mov rscratch1 #exception_blob_entry_point 2290 // br rscratch1 2291 // Note that the code buffer's insts_mark is always relative to insts. 2292 // That's why we must use the macroassembler to generate a handler. 2293 MacroAssembler _masm(&cbuf); 2294 address base = 2295 __ start_a_stub(size_exception_handler()); 2296 if (base == NULL) return 0; // CodeBuffer::expand failed 2297 int offset = __ offset(); 2298 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2299 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2300 __ end_a_stub(); 2301 return offset; 2302 } 2303 2304 // Emit deopt handler code. 2305 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2306 { 2307 // Note that the code buffer's insts_mark is always relative to insts. 2308 // That's why we must use the macroassembler to generate a handler. 2309 MacroAssembler _masm(&cbuf); 2310 address base = 2311 __ start_a_stub(size_deopt_handler()); 2312 if (base == NULL) return 0; // CodeBuffer::expand failed 2313 int offset = __ offset(); 2314 2315 __ adr(lr, __ pc()); 2316 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2317 2318 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 2319 __ end_a_stub(); 2320 return offset; 2321 } 2322 2323 // REQUIRED MATCHER CODE 2324 2325 //============================================================================= 2326 2327 const bool Matcher::match_rule_supported(int opcode) { 2328 2329 // TODO 2330 // identify extra cases that we might want to provide match rules for 2331 // e.g. Op_StrEquals and other intrinsics 2332 if (!has_match_rule(opcode)) { 2333 return false; 2334 } 2335 2336 return true; // Per default match rules are supported. 2337 } 2338 2339 int Matcher::regnum_to_fpu_offset(int regnum) 2340 { 2341 Unimplemented(); 2342 return 0; 2343 } 2344 2345 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) 2346 { 2347 Unimplemented(); 2348 return false; 2349 } 2350 2351 const bool Matcher::isSimpleConstant64(jlong value) { 2352 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2353 // Probably always true, even if a temp register is required. 2354 return true; 2355 } 2356 2357 // true just means we have fast l2f conversion 2358 const bool Matcher::convL2FSupported(void) { 2359 return true; 2360 } 2361 2362 // Vector width in bytes. 2363 const int Matcher::vector_width_in_bytes(BasicType bt) { 2364 // TODO fixme 2365 return 0; 2366 } 2367 2368 // Limits on vector size (number of elements) loaded into vector. 2369 const int Matcher::max_vector_size(const BasicType bt) { 2370 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2371 } 2372 const int Matcher::min_vector_size(const BasicType bt) { 2373 int max_size = max_vector_size(bt); 2374 // Min size which can be loaded into vector is 4 bytes. 2375 int size = (type2aelembytes(bt) == 1) ? 4 : 2; 2376 return MIN2(size,max_size); 2377 } 2378 2379 // Vector ideal reg. 2380 const int Matcher::vector_ideal_reg(int len) { 2381 // TODO fixme 2382 return Op_RegD; 2383 } 2384 2385 // Only lowest bits of xmm reg are used for vector shift count. 2386 const int Matcher::vector_shift_count_ideal_reg(int size) { 2387 // TODO fixme 2388 return Op_RegL; 2389 } 2390 2391 // AES support not yet implemented 2392 const bool Matcher::pass_original_key_for_aes() { 2393 return false; 2394 } 2395 2396 // x86 supports misaligned vectors store/load. 2397 const bool Matcher::misaligned_vectors_ok() { 2398 // TODO fixme 2399 // return !AlignVector; // can be changed by flag 2400 return false; 2401 } 2402 2403 // false => size gets scaled to BytesPerLong, ok. 2404 const bool Matcher::init_array_count_is_in_bytes = false; 2405 2406 // Threshold size for cleararray. 2407 const int Matcher::init_array_short_size = 18 * BytesPerLong; 2408 2409 // Use conditional move (CMOVL) 2410 const int Matcher::long_cmove_cost() { 2411 // long cmoves are no more expensive than int cmoves 2412 return 0; 2413 } 2414 2415 const int Matcher::float_cmove_cost() { 2416 // float cmoves are no more expensive than int cmoves 2417 return 0; 2418 } 2419 2420 // Does the CPU require late expand (see block.cpp for description of late expand)? 2421 const bool Matcher::require_postalloc_expand = false; 2422 2423 // Should the Matcher clone shifts on addressing modes, expecting them 2424 // to be subsumed into complex addressing expressions or compute them 2425 // into registers? True for Intel but false for most RISCs 2426 const bool Matcher::clone_shift_expressions = false; 2427 2428 // Do we need to mask the count passed to shift instructions or does 2429 // the cpu only look at the lower 5/6 bits anyway? 2430 const bool Matcher::need_masked_shift_count = false; 2431 2432 // This affects two different things: 2433 // - how Decode nodes are matched 2434 // - how ImplicitNullCheck opportunities are recognized 2435 // If true, the matcher will try to remove all Decodes and match them 2436 // (as operands) into nodes. NullChecks are not prepared to deal with 2437 // Decodes by final_graph_reshaping(). 2438 // If false, final_graph_reshaping() forces the decode behind the Cmp 2439 // for a NullCheck. The matcher matches the Decode node into a register. 2440 // Implicit_null_check optimization moves the Decode along with the 2441 // memory operation back up before the NullCheck. 2442 bool Matcher::narrow_oop_use_complex_address() { 2443 return Universe::narrow_oop_shift() == 0; 2444 } 2445 2446 bool Matcher::narrow_klass_use_complex_address() { 2447 // TODO 2448 // decide whether we need to set this to true 2449 return false; 2450 } 2451 2452 // Is it better to copy float constants, or load them directly from 2453 // memory? Intel can load a float constant from a direct address, 2454 // requiring no extra registers. Most RISCs will have to materialize 2455 // an address into a register first, so they would do better to copy 2456 // the constant from stack. 2457 const bool Matcher::rematerialize_float_constants = false; 2458 2459 // If CPU can load and store mis-aligned doubles directly then no 2460 // fixup is needed. Else we split the double into 2 integer pieces 2461 // and move it piece-by-piece. Only happens when passing doubles into 2462 // C code as the Java calling convention forces doubles to be aligned. 2463 const bool Matcher::misaligned_doubles_ok = true; 2464 2465 // No-op on amd64 2466 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2467 Unimplemented(); 2468 } 2469 2470 // Advertise here if the CPU requires explicit rounding operations to 2471 // implement the UseStrictFP mode. 2472 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2473 2474 // Are floats converted to double when stored to stack during 2475 // deoptimization? 2476 bool Matcher::float_in_double() { return true; } 2477 2478 // Do ints take an entire long register or just half? 2479 // The relevant question is how the int is callee-saved: 2480 // the whole long is written but de-opt'ing will have to extract 2481 // the relevant 32 bits. 2482 const bool Matcher::int_in_long = true; 2483 2484 // Return whether or not this register is ever used as an argument. 2485 // This function is used on startup to build the trampoline stubs in 2486 // generateOptoStub. Registers not mentioned will be killed by the VM 2487 // call in the trampoline, and arguments in those registers not be 2488 // available to the callee. 2489 bool Matcher::can_be_java_arg(int reg) 2490 { 2491 return 2492 reg == R0_num || reg == R0_H_num || 2493 reg == R1_num || reg == R1_H_num || 2494 reg == R2_num || reg == R2_H_num || 2495 reg == R3_num || reg == R3_H_num || 2496 reg == R4_num || reg == R4_H_num || 2497 reg == R5_num || reg == R5_H_num || 2498 reg == R6_num || reg == R6_H_num || 2499 reg == R7_num || reg == R7_H_num || 2500 reg == V0_num || reg == V0_H_num || 2501 reg == V1_num || reg == V1_H_num || 2502 reg == V2_num || reg == V2_H_num || 2503 reg == V3_num || reg == V3_H_num || 2504 reg == V4_num || reg == V4_H_num || 2505 reg == V5_num || reg == V5_H_num || 2506 reg == V6_num || reg == V6_H_num || 2507 reg == V7_num || reg == V7_H_num; 2508 } 2509 2510 bool Matcher::is_spillable_arg(int reg) 2511 { 2512 return can_be_java_arg(reg); 2513 } 2514 2515 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2516 return false; 2517 } 2518 2519 RegMask Matcher::divI_proj_mask() { 2520 ShouldNotReachHere(); 2521 return RegMask(); 2522 } 2523 2524 // Register for MODI projection of divmodI. 2525 RegMask Matcher::modI_proj_mask() { 2526 ShouldNotReachHere(); 2527 return RegMask(); 2528 } 2529 2530 // Register for DIVL projection of divmodL. 2531 RegMask Matcher::divL_proj_mask() { 2532 ShouldNotReachHere(); 2533 return RegMask(); 2534 } 2535 2536 // Register for MODL projection of divmodL. 2537 RegMask Matcher::modL_proj_mask() { 2538 ShouldNotReachHere(); 2539 return RegMask(); 2540 } 2541 2542 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2543 return FP_REG_mask(); 2544 } 2545 2546 // helper for encoding java_to_runtime calls on sim 2547 // 2548 // this is needed to compute the extra arguments required when 2549 // planting a call to the simulator blrt instruction. the TypeFunc 2550 // can be queried to identify the counts for integral, and floating 2551 // arguments and the return type 2552 2553 static void getCallInfo(const TypeFunc *tf, int &gpcnt, int &fpcnt, int &rtype) 2554 { 2555 int gps = 0; 2556 int fps = 0; 2557 const TypeTuple *domain = tf->domain(); 2558 int max = domain->cnt(); 2559 for (int i = TypeFunc::Parms; i < max; i++) { 2560 const Type *t = domain->field_at(i); 2561 switch(t->basic_type()) { 2562 case T_FLOAT: 2563 case T_DOUBLE: 2564 fps++; 2565 default: 2566 gps++; 2567 } 2568 } 2569 gpcnt = gps; 2570 fpcnt = fps; 2571 BasicType rt = tf->return_type(); 2572 switch (rt) { 2573 case T_VOID: 2574 rtype = MacroAssembler::ret_type_void; 2575 break; 2576 default: 2577 rtype = MacroAssembler::ret_type_integral; 2578 break; 2579 case T_FLOAT: 2580 rtype = MacroAssembler::ret_type_float; 2581 break; 2582 case T_DOUBLE: 2583 rtype = MacroAssembler::ret_type_double; 2584 break; 2585 } 2586 } 2587 2588 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2589 MacroAssembler _masm(&cbuf); \ 2590 { \ 2591 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2592 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2593 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2594 __ INSN(REG, as_Register(BASE)); \ 2595 } 2596 2597 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2598 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2599 2600 // Used for all non-volatile memory accesses. The use of 2601 // $mem->opcode() to discover whether this pattern uses sign-extended 2602 // offsets is something of a kludge. 2603 static void loadStore(MacroAssembler masm, mem_insn insn, 2604 Register reg, int opcode, 2605 Register base, int index, int size, int disp) 2606 { 2607 Address::extend scale; 2608 2609 // Hooboy, this is fugly. We need a way to communicate to the 2610 // encoder that the index needs to be sign extended, so we have to 2611 // enumerate all the cases. 2612 switch (opcode) { 2613 case INDINDEXSCALEDOFFSETI2L: 2614 case INDINDEXSCALEDI2L: 2615 case INDINDEXSCALEDOFFSETI2LN: 2616 case INDINDEXSCALEDI2LN: 2617 scale = Address::sxtw(size); 2618 break; 2619 default: 2620 scale = Address::lsl(size); 2621 } 2622 2623 if (index == -1) { 2624 (masm.*insn)(reg, Address(base, disp)); 2625 } else { 2626 if (disp == 0) { 2627 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2628 } else { 2629 masm.lea(rscratch1, Address(base, disp)); 2630 (masm.*insn)(reg, Address(rscratch1, as_Register(index), scale)); 2631 } 2632 } 2633 } 2634 2635 static void loadStore(MacroAssembler masm, mem_float_insn insn, 2636 FloatRegister reg, int opcode, 2637 Register base, int index, int size, int disp) 2638 { 2639 Address::extend scale; 2640 2641 switch (opcode) { 2642 case INDINDEXSCALEDOFFSETI2L: 2643 case INDINDEXSCALEDI2L: 2644 case INDINDEXSCALEDOFFSETI2LN: 2645 case INDINDEXSCALEDI2LN: 2646 scale = Address::sxtw(size); 2647 break; 2648 default: 2649 scale = Address::lsl(size); 2650 } 2651 2652 if (index == -1) { 2653 (masm.*insn)(reg, Address(base, disp)); 2654 } else { 2655 if (disp == 0) { 2656 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2657 } else { 2658 masm.lea(rscratch1, Address(base, disp)); 2659 (masm.*insn)(reg, Address(rscratch1, as_Register(index), scale)); 2660 } 2661 } 2662 } 2663 2664 %} 2665 2666 2667 2668 //----------ENCODING BLOCK----------------------------------------------------- 2669 // This block specifies the encoding classes used by the compiler to 2670 // output byte streams. Encoding classes are parameterized macros 2671 // used by Machine Instruction Nodes in order to generate the bit 2672 // encoding of the instruction. Operands specify their base encoding 2673 // interface with the interface keyword. There are currently 2674 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2675 // COND_INTER. REG_INTER causes an operand to generate a function 2676 // which returns its register number when queried. CONST_INTER causes 2677 // an operand to generate a function which returns the value of the 2678 // constant when queried. MEMORY_INTER causes an operand to generate 2679 // four functions which return the Base Register, the Index Register, 2680 // the Scale Value, and the Offset Value of the operand when queried. 2681 // COND_INTER causes an operand to generate six functions which return 2682 // the encoding code (ie - encoding bits for the instruction) 2683 // associated with each basic boolean condition for a conditional 2684 // instruction. 2685 // 2686 // Instructions specify two basic values for encoding. Again, a 2687 // function is available to check if the constant displacement is an 2688 // oop. They use the ins_encode keyword to specify their encoding 2689 // classes (which must be a sequence of enc_class names, and their 2690 // parameters, specified in the encoding block), and they use the 2691 // opcode keyword to specify, in order, their primary, secondary, and 2692 // tertiary opcode. Only the opcode sections which a particular 2693 // instruction needs for encoding need to be specified. 2694 encode %{ 2695 // Build emit functions for each basic byte or larger field in the 2696 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2697 // from C++ code in the enc_class source block. Emit functions will 2698 // live in the main source block for now. In future, we can 2699 // generalize this by adding a syntax that specifies the sizes of 2700 // fields in an order, so that the adlc can build the emit functions 2701 // automagically 2702 2703 // catch all for unimplemented encodings 2704 enc_class enc_unimplemented %{ 2705 MacroAssembler _masm(&cbuf); 2706 __ unimplemented("C2 catch all"); 2707 %} 2708 2709 // BEGIN Non-volatile memory access 2710 2711 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 2712 Register dst_reg = as_Register($dst$$reg); 2713 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2714 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2715 %} 2716 2717 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 2718 Register dst_reg = as_Register($dst$$reg); 2719 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2720 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2721 %} 2722 2723 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 2724 Register dst_reg = as_Register($dst$$reg); 2725 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2726 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2727 %} 2728 2729 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 2730 Register dst_reg = as_Register($dst$$reg); 2731 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2732 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2733 %} 2734 2735 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 2736 Register dst_reg = as_Register($dst$$reg); 2737 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2738 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2739 %} 2740 2741 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 2742 Register dst_reg = as_Register($dst$$reg); 2743 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2744 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2745 %} 2746 2747 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 2748 Register dst_reg = as_Register($dst$$reg); 2749 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2750 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2751 %} 2752 2753 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 2754 Register dst_reg = as_Register($dst$$reg); 2755 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2756 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2757 %} 2758 2759 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 2760 Register dst_reg = as_Register($dst$$reg); 2761 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2762 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2763 %} 2764 2765 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 2766 Register dst_reg = as_Register($dst$$reg); 2767 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2768 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2769 %} 2770 2771 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 2772 Register dst_reg = as_Register($dst$$reg); 2773 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2774 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2775 %} 2776 2777 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 2778 Register dst_reg = as_Register($dst$$reg); 2779 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2780 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2781 %} 2782 2783 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 2784 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2785 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2786 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2787 %} 2788 2789 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 2790 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2791 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2792 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2793 %} 2794 2795 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 2796 Register src_reg = as_Register($src$$reg); 2797 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2798 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2799 %} 2800 2801 enc_class aarch64_enc_strb0(memory mem) %{ 2802 MacroAssembler _masm(&cbuf); 2803 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2804 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2805 %} 2806 2807 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 2808 Register src_reg = as_Register($src$$reg); 2809 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2810 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2811 %} 2812 2813 enc_class aarch64_enc_strh0(memory mem) %{ 2814 MacroAssembler _masm(&cbuf); 2815 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2816 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2817 %} 2818 2819 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 2820 Register src_reg = as_Register($src$$reg); 2821 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2822 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2823 %} 2824 2825 enc_class aarch64_enc_strw0(memory mem) %{ 2826 MacroAssembler _masm(&cbuf); 2827 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2828 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2829 %} 2830 2831 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 2832 Register src_reg = as_Register($src$$reg); 2833 // we sometimes get asked to store the stack pointer into the 2834 // current thread -- we cannot do that directly on AArch64 2835 if (src_reg == r31_sp) { 2836 MacroAssembler _masm(&cbuf); 2837 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2838 __ mov(rscratch2, sp); 2839 src_reg = rscratch2; 2840 } 2841 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2842 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2843 %} 2844 2845 enc_class aarch64_enc_str0(memory mem) %{ 2846 MacroAssembler _masm(&cbuf); 2847 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2848 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2849 %} 2850 2851 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 2852 FloatRegister src_reg = as_FloatRegister($src$$reg); 2853 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2854 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2855 %} 2856 2857 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 2858 FloatRegister src_reg = as_FloatRegister($src$$reg); 2859 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2860 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2861 %} 2862 2863 // END Non-volatile memory access 2864 2865 // volatile loads and stores 2866 2867 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2868 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2869 rscratch1, stlrb); 2870 %} 2871 2872 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2873 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2874 rscratch1, stlrh); 2875 %} 2876 2877 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2878 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2879 rscratch1, stlrw); 2880 %} 2881 2882 2883 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2884 Register dst_reg = as_Register($dst$$reg); 2885 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2886 rscratch1, ldarb); 2887 __ sxtbw(dst_reg, dst_reg); 2888 %} 2889 2890 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2891 Register dst_reg = as_Register($dst$$reg); 2892 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2893 rscratch1, ldarb); 2894 __ sxtb(dst_reg, dst_reg); 2895 %} 2896 2897 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2898 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2899 rscratch1, ldarb); 2900 %} 2901 2902 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2903 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2904 rscratch1, ldarb); 2905 %} 2906 2907 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2908 Register dst_reg = as_Register($dst$$reg); 2909 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2910 rscratch1, ldarh); 2911 __ sxthw(dst_reg, dst_reg); 2912 %} 2913 2914 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2915 Register dst_reg = as_Register($dst$$reg); 2916 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2917 rscratch1, ldarh); 2918 __ sxth(dst_reg, dst_reg); 2919 %} 2920 2921 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2922 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2923 rscratch1, ldarh); 2924 %} 2925 2926 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2927 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2928 rscratch1, ldarh); 2929 %} 2930 2931 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2932 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2933 rscratch1, ldarw); 2934 %} 2935 2936 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2937 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2938 rscratch1, ldarw); 2939 %} 2940 2941 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2942 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2943 rscratch1, ldar); 2944 %} 2945 2946 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2947 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2948 rscratch1, ldarw); 2949 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2950 %} 2951 2952 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2953 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2954 rscratch1, ldar); 2955 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2956 %} 2957 2958 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2959 Register src_reg = as_Register($src$$reg); 2960 // we sometimes get asked to store the stack pointer into the 2961 // current thread -- we cannot do that directly on AArch64 2962 if (src_reg == r31_sp) { 2963 MacroAssembler _masm(&cbuf); 2964 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2965 __ mov(rscratch2, sp); 2966 src_reg = rscratch2; 2967 } 2968 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2969 rscratch1, stlr); 2970 %} 2971 2972 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2973 { 2974 MacroAssembler _masm(&cbuf); 2975 FloatRegister src_reg = as_FloatRegister($src$$reg); 2976 __ fmovs(rscratch2, src_reg); 2977 } 2978 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2979 rscratch1, stlrw); 2980 %} 2981 2982 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2983 { 2984 MacroAssembler _masm(&cbuf); 2985 FloatRegister src_reg = as_FloatRegister($src$$reg); 2986 __ fmovd(rscratch2, src_reg); 2987 } 2988 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2989 rscratch1, stlr); 2990 %} 2991 2992 // synchronized read/update encodings 2993 2994 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 2995 MacroAssembler _masm(&cbuf); 2996 Register dst_reg = as_Register($dst$$reg); 2997 Register base = as_Register($mem$$base); 2998 int index = $mem$$index; 2999 int scale = $mem$$scale; 3000 int disp = $mem$$disp; 3001 if (index == -1) { 3002 if (disp != 0) { 3003 __ lea(rscratch1, Address(base, disp)); 3004 __ ldaxr(dst_reg, rscratch1); 3005 } else { 3006 // TODO 3007 // should we ever get anything other than this case? 3008 __ ldaxr(dst_reg, base); 3009 } 3010 } else { 3011 Register index_reg = as_Register(index); 3012 if (disp == 0) { 3013 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3014 __ ldaxr(dst_reg, rscratch1); 3015 } else { 3016 __ lea(rscratch1, Address(base, disp)); 3017 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3018 __ ldaxr(dst_reg, rscratch1); 3019 } 3020 } 3021 %} 3022 3023 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 3024 MacroAssembler _masm(&cbuf); 3025 Register src_reg = as_Register($src$$reg); 3026 Register base = as_Register($mem$$base); 3027 int index = $mem$$index; 3028 int scale = $mem$$scale; 3029 int disp = $mem$$disp; 3030 if (index == -1) { 3031 if (disp != 0) { 3032 __ lea(rscratch2, Address(base, disp)); 3033 __ stlxr(rscratch1, src_reg, rscratch2); 3034 } else { 3035 // TODO 3036 // should we ever get anything other than this case? 3037 __ stlxr(rscratch1, src_reg, base); 3038 } 3039 } else { 3040 Register index_reg = as_Register(index); 3041 if (disp == 0) { 3042 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3043 __ stlxr(rscratch1, src_reg, rscratch2); 3044 } else { 3045 __ lea(rscratch2, Address(base, disp)); 3046 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3047 __ stlxr(rscratch1, src_reg, rscratch2); 3048 } 3049 } 3050 __ cmpw(rscratch1, zr); 3051 %} 3052 3053 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3054 MacroAssembler _masm(&cbuf); 3055 Register old_reg = as_Register($oldval$$reg); 3056 Register new_reg = as_Register($newval$$reg); 3057 Register base = as_Register($mem$$base); 3058 Register addr_reg; 3059 int index = $mem$$index; 3060 int scale = $mem$$scale; 3061 int disp = $mem$$disp; 3062 if (index == -1) { 3063 if (disp != 0) { 3064 __ lea(rscratch2, Address(base, disp)); 3065 addr_reg = rscratch2; 3066 } else { 3067 // TODO 3068 // should we ever get anything other than this case? 3069 addr_reg = base; 3070 } 3071 } else { 3072 Register index_reg = as_Register(index); 3073 if (disp == 0) { 3074 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3075 addr_reg = rscratch2; 3076 } else { 3077 __ lea(rscratch2, Address(base, disp)); 3078 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3079 addr_reg = rscratch2; 3080 } 3081 } 3082 Label retry_load, done; 3083 __ bind(retry_load); 3084 __ ldxr(rscratch1, addr_reg); 3085 __ cmp(rscratch1, old_reg); 3086 __ br(Assembler::NE, done); 3087 __ stlxr(rscratch1, new_reg, addr_reg); 3088 __ cbnzw(rscratch1, retry_load); 3089 __ bind(done); 3090 %} 3091 3092 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3093 MacroAssembler _masm(&cbuf); 3094 Register old_reg = as_Register($oldval$$reg); 3095 Register new_reg = as_Register($newval$$reg); 3096 Register base = as_Register($mem$$base); 3097 Register addr_reg; 3098 int index = $mem$$index; 3099 int scale = $mem$$scale; 3100 int disp = $mem$$disp; 3101 if (index == -1) { 3102 if (disp != 0) { 3103 __ lea(rscratch2, Address(base, disp)); 3104 addr_reg = rscratch2; 3105 } else { 3106 // TODO 3107 // should we ever get anything other than this case? 3108 addr_reg = base; 3109 } 3110 } else { 3111 Register index_reg = as_Register(index); 3112 if (disp == 0) { 3113 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3114 addr_reg = rscratch2; 3115 } else { 3116 __ lea(rscratch2, Address(base, disp)); 3117 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3118 addr_reg = rscratch2; 3119 } 3120 } 3121 Label retry_load, done; 3122 __ bind(retry_load); 3123 __ ldxrw(rscratch1, addr_reg); 3124 __ cmpw(rscratch1, old_reg); 3125 __ br(Assembler::NE, done); 3126 __ stlxrw(rscratch1, new_reg, addr_reg); 3127 __ cbnzw(rscratch1, retry_load); 3128 __ bind(done); 3129 %} 3130 3131 // auxiliary used for CompareAndSwapX to set result register 3132 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3133 MacroAssembler _masm(&cbuf); 3134 Register res_reg = as_Register($res$$reg); 3135 __ cset(res_reg, Assembler::EQ); 3136 %} 3137 3138 // prefetch encodings 3139 3140 enc_class aarch64_enc_prefetchw(memory mem) %{ 3141 MacroAssembler _masm(&cbuf); 3142 Register base = as_Register($mem$$base); 3143 int index = $mem$$index; 3144 int scale = $mem$$scale; 3145 int disp = $mem$$disp; 3146 if (index == -1) { 3147 __ prfm(Address(base, disp), PSTL1KEEP); 3148 __ nop(); 3149 } else { 3150 Register index_reg = as_Register(index); 3151 if (disp == 0) { 3152 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3153 } else { 3154 __ lea(rscratch1, Address(base, disp)); 3155 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3156 } 3157 } 3158 %} 3159 3160 enc_class aarch64_enc_clear_array_reg_reg(iRegL_R11 cnt, iRegP_R10 base) %{ 3161 MacroAssembler _masm(&cbuf); 3162 Register cnt_reg = as_Register($cnt$$reg); 3163 Register base_reg = as_Register($base$$reg); 3164 // base is word aligned 3165 // cnt is count of words 3166 3167 Label loop; 3168 Label entry; 3169 3170 // Algorithm: 3171 // 3172 // scratch1 = cnt & 7; 3173 // cnt -= scratch1; 3174 // p += scratch1; 3175 // switch (scratch1) { 3176 // do { 3177 // cnt -= 8; 3178 // p[-8] = 0; 3179 // case 7: 3180 // p[-7] = 0; 3181 // case 6: 3182 // p[-6] = 0; 3183 // // ... 3184 // case 1: 3185 // p[-1] = 0; 3186 // case 0: 3187 // p += 8; 3188 // } while (cnt); 3189 // } 3190 3191 const int unroll = 8; // Number of str(zr) instructions we'll unroll 3192 3193 __ andr(rscratch1, cnt_reg, unroll - 1); // tmp1 = cnt % unroll 3194 __ sub(cnt_reg, cnt_reg, rscratch1); // cnt -= unroll 3195 // base_reg always points to the end of the region we're about to zero 3196 __ add(base_reg, base_reg, rscratch1, Assembler::LSL, exact_log2(wordSize)); 3197 __ adr(rscratch2, entry); 3198 __ sub(rscratch2, rscratch2, rscratch1, Assembler::LSL, 2); 3199 __ br(rscratch2); 3200 __ bind(loop); 3201 __ sub(cnt_reg, cnt_reg, unroll); 3202 for (int i = -unroll; i < 0; i++) 3203 __ str(zr, Address(base_reg, i * wordSize)); 3204 __ bind(entry); 3205 __ add(base_reg, base_reg, unroll * wordSize); 3206 __ cbnz(cnt_reg, loop); 3207 %} 3208 3209 /// mov envcodings 3210 3211 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3212 MacroAssembler _masm(&cbuf); 3213 u_int32_t con = (u_int32_t)$src$$constant; 3214 Register dst_reg = as_Register($dst$$reg); 3215 if (con == 0) { 3216 __ movw(dst_reg, zr); 3217 } else { 3218 __ movw(dst_reg, con); 3219 } 3220 %} 3221 3222 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3223 MacroAssembler _masm(&cbuf); 3224 Register dst_reg = as_Register($dst$$reg); 3225 u_int64_t con = (u_int64_t)$src$$constant; 3226 if (con == 0) { 3227 __ mov(dst_reg, zr); 3228 } else { 3229 __ mov(dst_reg, con); 3230 } 3231 %} 3232 3233 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3234 MacroAssembler _masm(&cbuf); 3235 Register dst_reg = as_Register($dst$$reg); 3236 address con = (address)$src$$constant; 3237 if (con == NULL || con == (address)1) { 3238 ShouldNotReachHere(); 3239 } else { 3240 relocInfo::relocType rtype = $src->constant_reloc(); 3241 if (rtype == relocInfo::oop_type) { 3242 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 3243 } else if (rtype == relocInfo::metadata_type) { 3244 __ mov_metadata(dst_reg, (Metadata*)con); 3245 } else { 3246 assert(rtype == relocInfo::none, "unexpected reloc type"); 3247 if (con < (address)(uintptr_t)os::vm_page_size()) { 3248 __ mov(dst_reg, con); 3249 } else { 3250 unsigned long offset; 3251 __ adrp(dst_reg, con, offset); 3252 __ add(dst_reg, dst_reg, offset); 3253 } 3254 } 3255 } 3256 %} 3257 3258 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3259 MacroAssembler _masm(&cbuf); 3260 Register dst_reg = as_Register($dst$$reg); 3261 __ mov(dst_reg, zr); 3262 %} 3263 3264 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3265 MacroAssembler _masm(&cbuf); 3266 Register dst_reg = as_Register($dst$$reg); 3267 __ mov(dst_reg, (u_int64_t)1); 3268 %} 3269 3270 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 3271 MacroAssembler _masm(&cbuf); 3272 address page = (address)$src$$constant; 3273 Register dst_reg = as_Register($dst$$reg); 3274 unsigned long off; 3275 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 3276 assert(off == 0, "assumed offset == 0"); 3277 %} 3278 3279 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3280 MacroAssembler _masm(&cbuf); 3281 address page = (address)$src$$constant; 3282 Register dst_reg = as_Register($dst$$reg); 3283 unsigned long off; 3284 __ adrp(dst_reg, ExternalAddress(page), off); 3285 assert(off == 0, "assumed offset == 0"); 3286 %} 3287 3288 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3289 MacroAssembler _masm(&cbuf); 3290 Register dst_reg = as_Register($dst$$reg); 3291 address con = (address)$src$$constant; 3292 if (con == NULL) { 3293 ShouldNotReachHere(); 3294 } else { 3295 relocInfo::relocType rtype = $src->constant_reloc(); 3296 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3297 __ set_narrow_oop(dst_reg, (jobject)con); 3298 } 3299 %} 3300 3301 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3302 MacroAssembler _masm(&cbuf); 3303 Register dst_reg = as_Register($dst$$reg); 3304 __ mov(dst_reg, zr); 3305 %} 3306 3307 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3308 MacroAssembler _masm(&cbuf); 3309 Register dst_reg = as_Register($dst$$reg); 3310 address con = (address)$src$$constant; 3311 if (con == NULL) { 3312 ShouldNotReachHere(); 3313 } else { 3314 relocInfo::relocType rtype = $src->constant_reloc(); 3315 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3316 __ set_narrow_klass(dst_reg, (Klass *)con); 3317 } 3318 %} 3319 3320 // arithmetic encodings 3321 3322 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3323 MacroAssembler _masm(&cbuf); 3324 Register dst_reg = as_Register($dst$$reg); 3325 Register src_reg = as_Register($src1$$reg); 3326 int32_t con = (int32_t)$src2$$constant; 3327 // add has primary == 0, subtract has primary == 1 3328 if ($primary) { con = -con; } 3329 if (con < 0) { 3330 __ subw(dst_reg, src_reg, -con); 3331 } else { 3332 __ addw(dst_reg, src_reg, con); 3333 } 3334 %} 3335 3336 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3337 MacroAssembler _masm(&cbuf); 3338 Register dst_reg = as_Register($dst$$reg); 3339 Register src_reg = as_Register($src1$$reg); 3340 int32_t con = (int32_t)$src2$$constant; 3341 // add has primary == 0, subtract has primary == 1 3342 if ($primary) { con = -con; } 3343 if (con < 0) { 3344 __ sub(dst_reg, src_reg, -con); 3345 } else { 3346 __ add(dst_reg, src_reg, con); 3347 } 3348 %} 3349 3350 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3351 MacroAssembler _masm(&cbuf); 3352 Register dst_reg = as_Register($dst$$reg); 3353 Register src1_reg = as_Register($src1$$reg); 3354 Register src2_reg = as_Register($src2$$reg); 3355 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3356 %} 3357 3358 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3359 MacroAssembler _masm(&cbuf); 3360 Register dst_reg = as_Register($dst$$reg); 3361 Register src1_reg = as_Register($src1$$reg); 3362 Register src2_reg = as_Register($src2$$reg); 3363 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3364 %} 3365 3366 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3367 MacroAssembler _masm(&cbuf); 3368 Register dst_reg = as_Register($dst$$reg); 3369 Register src1_reg = as_Register($src1$$reg); 3370 Register src2_reg = as_Register($src2$$reg); 3371 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3372 %} 3373 3374 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3375 MacroAssembler _masm(&cbuf); 3376 Register dst_reg = as_Register($dst$$reg); 3377 Register src1_reg = as_Register($src1$$reg); 3378 Register src2_reg = as_Register($src2$$reg); 3379 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3380 %} 3381 3382 // compare instruction encodings 3383 3384 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3385 MacroAssembler _masm(&cbuf); 3386 Register reg1 = as_Register($src1$$reg); 3387 Register reg2 = as_Register($src2$$reg); 3388 __ cmpw(reg1, reg2); 3389 %} 3390 3391 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3392 MacroAssembler _masm(&cbuf); 3393 Register reg = as_Register($src1$$reg); 3394 int32_t val = $src2$$constant; 3395 if (val >= 0) { 3396 __ subsw(zr, reg, val); 3397 } else { 3398 __ addsw(zr, reg, -val); 3399 } 3400 %} 3401 3402 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3403 MacroAssembler _masm(&cbuf); 3404 Register reg1 = as_Register($src1$$reg); 3405 u_int32_t val = (u_int32_t)$src2$$constant; 3406 __ movw(rscratch1, val); 3407 __ cmpw(reg1, rscratch1); 3408 %} 3409 3410 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3411 MacroAssembler _masm(&cbuf); 3412 Register reg1 = as_Register($src1$$reg); 3413 Register reg2 = as_Register($src2$$reg); 3414 __ cmp(reg1, reg2); 3415 %} 3416 3417 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3418 MacroAssembler _masm(&cbuf); 3419 Register reg = as_Register($src1$$reg); 3420 int64_t val = $src2$$constant; 3421 if (val >= 0) { 3422 __ subs(zr, reg, val); 3423 } else if (val != -val) { 3424 __ adds(zr, reg, -val); 3425 } else { 3426 // aargh, Long.MIN_VALUE is a special case 3427 __ orr(rscratch1, zr, (u_int64_t)val); 3428 __ subs(zr, reg, rscratch1); 3429 } 3430 %} 3431 3432 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3433 MacroAssembler _masm(&cbuf); 3434 Register reg1 = as_Register($src1$$reg); 3435 u_int64_t val = (u_int64_t)$src2$$constant; 3436 __ mov(rscratch1, val); 3437 __ cmp(reg1, rscratch1); 3438 %} 3439 3440 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3441 MacroAssembler _masm(&cbuf); 3442 Register reg1 = as_Register($src1$$reg); 3443 Register reg2 = as_Register($src2$$reg); 3444 __ cmp(reg1, reg2); 3445 %} 3446 3447 enc_class aarch64_enc_cmpn(iRegN src1, iRegN 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_testp(iRegP src) %{ 3455 MacroAssembler _masm(&cbuf); 3456 Register reg = as_Register($src$$reg); 3457 __ cmp(reg, zr); 3458 %} 3459 3460 enc_class aarch64_enc_testn(iRegN src) %{ 3461 MacroAssembler _masm(&cbuf); 3462 Register reg = as_Register($src$$reg); 3463 __ cmpw(reg, zr); 3464 %} 3465 3466 enc_class aarch64_enc_b(label lbl) %{ 3467 MacroAssembler _masm(&cbuf); 3468 Label *L = $lbl$$label; 3469 __ b(*L); 3470 %} 3471 3472 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3473 MacroAssembler _masm(&cbuf); 3474 Label *L = $lbl$$label; 3475 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3476 %} 3477 3478 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3479 MacroAssembler _masm(&cbuf); 3480 Label *L = $lbl$$label; 3481 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3482 %} 3483 3484 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3485 %{ 3486 Register sub_reg = as_Register($sub$$reg); 3487 Register super_reg = as_Register($super$$reg); 3488 Register temp_reg = as_Register($temp$$reg); 3489 Register result_reg = as_Register($result$$reg); 3490 3491 Label miss; 3492 MacroAssembler _masm(&cbuf); 3493 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3494 NULL, &miss, 3495 /*set_cond_codes:*/ true); 3496 if ($primary) { 3497 __ mov(result_reg, zr); 3498 } 3499 __ bind(miss); 3500 %} 3501 3502 enc_class aarch64_enc_java_static_call(method meth) %{ 3503 MacroAssembler _masm(&cbuf); 3504 3505 address addr = (address)$meth$$method; 3506 if (!_method) { 3507 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3508 __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3509 } else if (_optimized_virtual) { 3510 __ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf); 3511 } else { 3512 __ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf); 3513 } 3514 3515 if (_method) { 3516 // Emit stub for static call 3517 CompiledStaticCall::emit_to_interp_stub(cbuf); 3518 } 3519 %} 3520 3521 enc_class aarch64_enc_java_handle_call(method meth) %{ 3522 MacroAssembler _masm(&cbuf); 3523 relocInfo::relocType reloc; 3524 3525 // RFP is preserved across all calls, even compiled calls. 3526 // Use it to preserve SP. 3527 __ mov(rfp, sp); 3528 3529 const int start_offset = __ offset(); 3530 address addr = (address)$meth$$method; 3531 if (!_method) { 3532 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3533 __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 3534 } else if (_optimized_virtual) { 3535 __ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf); 3536 } else { 3537 __ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf); 3538 } 3539 3540 if (_method) { 3541 // Emit stub for static call 3542 CompiledStaticCall::emit_to_interp_stub(cbuf); 3543 } 3544 3545 // now restore sp 3546 __ mov(sp, rfp); 3547 %} 3548 3549 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3550 MacroAssembler _masm(&cbuf); 3551 __ ic_call((address)$meth$$method); 3552 %} 3553 3554 enc_class aarch64_enc_call_epilog() %{ 3555 MacroAssembler _masm(&cbuf); 3556 if (VerifyStackAtCalls) { 3557 // Check that stack depth is unchanged: find majik cookie on stack 3558 __ call_Unimplemented(); 3559 } 3560 %} 3561 3562 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3563 MacroAssembler _masm(&cbuf); 3564 3565 // some calls to generated routines (arraycopy code) are scheduled 3566 // by C2 as runtime calls. if so we can call them using a br (they 3567 // will be in a reachable segment) otherwise we have to use a blrt 3568 // which loads the absolute address into a register. 3569 address entry = (address)$meth$$method; 3570 CodeBlob *cb = CodeCache::find_blob(entry); 3571 if (cb) { 3572 __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3573 } else { 3574 int gpcnt; 3575 int fpcnt; 3576 int rtype; 3577 getCallInfo(tf(), gpcnt, fpcnt, rtype); 3578 Label retaddr; 3579 __ adr(rscratch2, retaddr); 3580 __ lea(rscratch1, RuntimeAddress(entry)); 3581 // Leave a breadcrumb for JavaThread::pd_last_frame(). 3582 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3583 __ blrt(rscratch1, gpcnt, fpcnt, rtype); 3584 __ bind(retaddr); 3585 __ add(sp, sp, 2 * wordSize); 3586 } 3587 %} 3588 3589 enc_class aarch64_enc_rethrow() %{ 3590 MacroAssembler _masm(&cbuf); 3591 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3592 %} 3593 3594 enc_class aarch64_enc_ret() %{ 3595 MacroAssembler _masm(&cbuf); 3596 __ ret(lr); 3597 %} 3598 3599 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3600 MacroAssembler _masm(&cbuf); 3601 Register target_reg = as_Register($jump_target$$reg); 3602 __ br(target_reg); 3603 %} 3604 3605 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3606 MacroAssembler _masm(&cbuf); 3607 Register target_reg = as_Register($jump_target$$reg); 3608 // exception oop should be in r0 3609 // ret addr has been popped into lr 3610 // callee expects it in r3 3611 __ mov(r3, lr); 3612 __ br(target_reg); 3613 %} 3614 3615 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3616 MacroAssembler _masm(&cbuf); 3617 Register oop = as_Register($object$$reg); 3618 Register box = as_Register($box$$reg); 3619 Register disp_hdr = as_Register($tmp$$reg); 3620 Register tmp = as_Register($tmp2$$reg); 3621 Label cont; 3622 Label object_has_monitor; 3623 Label cas_failed; 3624 3625 assert_different_registers(oop, box, tmp, disp_hdr); 3626 3627 // Load markOop from object into displaced_header. 3628 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 3629 3630 // Always do locking in runtime. 3631 if (EmitSync & 0x01) { 3632 __ cmp(oop, zr); 3633 return; 3634 } 3635 3636 if (UseBiasedLocking) { 3637 __ biased_locking_enter(disp_hdr, oop, box, tmp, true, cont); 3638 } 3639 3640 // Handle existing monitor 3641 if (EmitSync & 0x02) { 3642 // we can use AArch64's bit test and branch here but 3643 // markoopDesc does not define a bit index just the bit value 3644 // so assert in case the bit pos changes 3645 # define __monitor_value_log2 1 3646 assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position"); 3647 __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor); 3648 # undef __monitor_value_log2 3649 } 3650 3651 // Set displaced_header to be (markOop of object | UNLOCK_VALUE). 3652 __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value); 3653 3654 // Load Compare Value application register. 3655 3656 // Initialize the box. (Must happen before we update the object mark!) 3657 __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3658 3659 // Compare object markOop with mark and if equal exchange scratch1 3660 // with object markOop. 3661 // Note that this is simply a CAS: it does not generate any 3662 // barriers. These are separately generated by 3663 // membar_acquire_lock(). 3664 { 3665 Label retry_load; 3666 __ bind(retry_load); 3667 __ ldxr(tmp, oop); 3668 __ cmp(tmp, disp_hdr); 3669 __ br(Assembler::NE, cas_failed); 3670 // use stlxr to ensure update is immediately visible 3671 __ stlxr(tmp, box, oop); 3672 __ cbzw(tmp, cont); 3673 __ b(retry_load); 3674 } 3675 3676 // Formerly: 3677 // __ cmpxchgptr(/*oldv=*/disp_hdr, 3678 // /*newv=*/box, 3679 // /*addr=*/oop, 3680 // /*tmp=*/tmp, 3681 // cont, 3682 // /*fail*/NULL); 3683 3684 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3685 3686 // If the compare-and-exchange succeeded, then we found an unlocked 3687 // object, will have now locked it will continue at label cont 3688 3689 __ bind(cas_failed); 3690 // We did not see an unlocked object so try the fast recursive case. 3691 3692 // Check if the owner is self by comparing the value in the 3693 // markOop of object (disp_hdr) with the stack pointer. 3694 __ mov(rscratch1, sp); 3695 __ sub(disp_hdr, disp_hdr, rscratch1); 3696 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place)); 3697 // If condition is true we are cont and hence we can store 0 as the 3698 // displaced header in the box, which indicates that it is a recursive lock. 3699 __ ands(tmp/*==0?*/, disp_hdr, tmp); 3700 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3701 3702 // Handle existing monitor. 3703 if ((EmitSync & 0x02) == 0) { 3704 __ b(cont); 3705 3706 __ bind(object_has_monitor); 3707 // The object's monitor m is unlocked iff m->owner == NULL, 3708 // otherwise m->owner may contain a thread or a stack address. 3709 // 3710 // Try to CAS m->owner from NULL to current thread. 3711 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value)); 3712 __ mov(disp_hdr, zr); 3713 3714 { 3715 Label retry_load, fail; 3716 __ bind(retry_load); 3717 __ ldxr(rscratch1, tmp); 3718 __ cmp(disp_hdr, rscratch1); 3719 __ br(Assembler::NE, fail); 3720 // use stlxr to ensure update is immediately visible 3721 __ stlxr(rscratch1, rthread, tmp); 3722 __ cbnzw(rscratch1, retry_load); 3723 __ bind(fail); 3724 } 3725 3726 // Label next; 3727 // __ cmpxchgptr(/*oldv=*/disp_hdr, 3728 // /*newv=*/rthread, 3729 // /*addr=*/tmp, 3730 // /*tmp=*/rscratch1, 3731 // /*succeed*/next, 3732 // /*fail*/NULL); 3733 // __ bind(next); 3734 3735 // store a non-null value into the box. 3736 __ str(box, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3737 3738 // PPC port checks the following invariants 3739 // #ifdef ASSERT 3740 // bne(flag, cont); 3741 // We have acquired the monitor, check some invariants. 3742 // addw(/*monitor=*/tmp, tmp, -ObjectMonitor::owner_offset_in_bytes()); 3743 // Invariant 1: _recursions should be 0. 3744 // assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size"); 3745 // assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), tmp, 3746 // "monitor->_recursions should be 0", -1); 3747 // Invariant 2: OwnerIsThread shouldn't be 0. 3748 // assert(ObjectMonitor::OwnerIsThread_size_in_bytes() == 4, "unexpected size"); 3749 //assert_mem4_isnot_zero(ObjectMonitor::OwnerIsThread_offset_in_bytes(), tmp, 3750 // "monitor->OwnerIsThread shouldn't be 0", -1); 3751 // #endif 3752 } 3753 3754 __ bind(cont); 3755 // flag == EQ indicates success 3756 // flag == NE indicates failure 3757 3758 %} 3759 3760 // TODO 3761 // reimplement this with custom cmpxchgptr code 3762 // which avoids some of the unnecessary branching 3763 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3764 MacroAssembler _masm(&cbuf); 3765 Register oop = as_Register($object$$reg); 3766 Register box = as_Register($box$$reg); 3767 Register disp_hdr = as_Register($tmp$$reg); 3768 Register tmp = as_Register($tmp2$$reg); 3769 Label cont; 3770 Label object_has_monitor; 3771 Label cas_failed; 3772 3773 assert_different_registers(oop, box, tmp, disp_hdr); 3774 3775 // Always do locking in runtime. 3776 if (EmitSync & 0x01) { 3777 __ cmp(oop, zr); // Oop can't be 0 here => always false. 3778 return; 3779 } 3780 3781 if (UseBiasedLocking) { 3782 __ biased_locking_exit(oop, tmp, cont); 3783 } 3784 3785 // Find the lock address and load the displaced header from the stack. 3786 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3787 3788 // If the displaced header is 0, we have a recursive unlock. 3789 __ cmp(disp_hdr, zr); 3790 __ br(Assembler::EQ, cont); 3791 3792 3793 // Handle existing monitor. 3794 if ((EmitSync & 0x02) == 0) { 3795 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3796 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3797 } 3798 3799 // Check if it is still a light weight lock, this is is true if we 3800 // see the stack address of the basicLock in the markOop of the 3801 // object. 3802 3803 { 3804 Label retry_load; 3805 __ bind(retry_load); 3806 __ ldxr(tmp, oop); 3807 __ cmp(box, tmp); 3808 __ br(Assembler::NE, cas_failed); 3809 // use stlxr to ensure update is immediately visible 3810 __ stlxr(tmp, disp_hdr, oop); 3811 __ cbzw(tmp, cont); 3812 __ b(retry_load); 3813 } 3814 3815 // __ cmpxchgptr(/*compare_value=*/box, 3816 // /*exchange_value=*/disp_hdr, 3817 // /*where=*/oop, 3818 // /*result=*/tmp, 3819 // cont, 3820 // /*cas_failed*/NULL); 3821 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3822 3823 __ bind(cas_failed); 3824 3825 // Handle existing monitor. 3826 if ((EmitSync & 0x02) == 0) { 3827 __ b(cont); 3828 3829 __ bind(object_has_monitor); 3830 __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor 3831 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3832 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3833 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3834 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3835 __ cmp(rscratch1, zr); 3836 __ br(Assembler::NE, cont); 3837 3838 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3839 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3840 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3841 __ cmp(rscratch1, zr); 3842 __ cbnz(rscratch1, cont); 3843 // need a release store here 3844 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3845 __ stlr(rscratch1, tmp); // rscratch1 is zero 3846 } 3847 3848 __ bind(cont); 3849 // flag == EQ indicates success 3850 // flag == NE indicates failure 3851 %} 3852 3853 %} 3854 3855 //----------FRAME-------------------------------------------------------------- 3856 // Definition of frame structure and management information. 3857 // 3858 // S T A C K L A Y O U T Allocators stack-slot number 3859 // | (to get allocators register number 3860 // G Owned by | | v add OptoReg::stack0()) 3861 // r CALLER | | 3862 // o | +--------+ pad to even-align allocators stack-slot 3863 // w V | pad0 | numbers; owned by CALLER 3864 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3865 // h ^ | in | 5 3866 // | | args | 4 Holes in incoming args owned by SELF 3867 // | | | | 3 3868 // | | +--------+ 3869 // V | | old out| Empty on Intel, window on Sparc 3870 // | old |preserve| Must be even aligned. 3871 // | SP-+--------+----> Matcher::_old_SP, even aligned 3872 // | | in | 3 area for Intel ret address 3873 // Owned by |preserve| Empty on Sparc. 3874 // SELF +--------+ 3875 // | | pad2 | 2 pad to align old SP 3876 // | +--------+ 1 3877 // | | locks | 0 3878 // | +--------+----> OptoReg::stack0(), even aligned 3879 // | | pad1 | 11 pad to align new SP 3880 // | +--------+ 3881 // | | | 10 3882 // | | spills | 9 spills 3883 // V | | 8 (pad0 slot for callee) 3884 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3885 // ^ | out | 7 3886 // | | args | 6 Holes in outgoing args owned by CALLEE 3887 // Owned by +--------+ 3888 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3889 // | new |preserve| Must be even-aligned. 3890 // | SP-+--------+----> Matcher::_new_SP, even aligned 3891 // | | | 3892 // 3893 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3894 // known from SELF's arguments and the Java calling convention. 3895 // Region 6-7 is determined per call site. 3896 // Note 2: If the calling convention leaves holes in the incoming argument 3897 // area, those holes are owned by SELF. Holes in the outgoing area 3898 // are owned by the CALLEE. Holes should not be nessecary in the 3899 // incoming area, as the Java calling convention is completely under 3900 // the control of the AD file. Doubles can be sorted and packed to 3901 // avoid holes. Holes in the outgoing arguments may be nessecary for 3902 // varargs C calling conventions. 3903 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3904 // even aligned with pad0 as needed. 3905 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3906 // (the latter is true on Intel but is it false on AArch64?) 3907 // region 6-11 is even aligned; it may be padded out more so that 3908 // the region from SP to FP meets the minimum stack alignment. 3909 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3910 // alignment. Region 11, pad1, may be dynamically extended so that 3911 // SP meets the minimum alignment. 3912 3913 frame %{ 3914 // What direction does stack grow in (assumed to be same for C & Java) 3915 stack_direction(TOWARDS_LOW); 3916 3917 // These three registers define part of the calling convention 3918 // between compiled code and the interpreter. 3919 3920 // Inline Cache Register or methodOop for I2C. 3921 inline_cache_reg(R12); 3922 3923 // Method Oop Register when calling interpreter. 3924 interpreter_method_oop_reg(R12); 3925 3926 // Number of stack slots consumed by locking an object 3927 sync_stack_slots(2); 3928 3929 // Compiled code's Frame Pointer 3930 frame_pointer(R31); 3931 3932 // Interpreter stores its frame pointer in a register which is 3933 // stored to the stack by I2CAdaptors. 3934 // I2CAdaptors convert from interpreted java to compiled java. 3935 interpreter_frame_pointer(R29); 3936 3937 // Stack alignment requirement 3938 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3939 3940 // Number of stack slots between incoming argument block and the start of 3941 // a new frame. The PROLOG must add this many slots to the stack. The 3942 // EPILOG must remove this many slots. aarch64 needs two slots for 3943 // return address and fp. 3944 // TODO think this is correct but check 3945 in_preserve_stack_slots(4); 3946 3947 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3948 // for calls to C. Supports the var-args backing area for register parms. 3949 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3950 3951 // The after-PROLOG location of the return address. Location of 3952 // return address specifies a type (REG or STACK) and a number 3953 // representing the register number (i.e. - use a register name) or 3954 // stack slot. 3955 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3956 // Otherwise, it is above the locks and verification slot and alignment word 3957 // TODO this may well be correct but need to check why that - 2 is there 3958 // ppc port uses 0 but we definitely need to allow for fixed_slots 3959 // which folds in the space used for monitors 3960 return_addr(STACK - 2 + 3961 round_to((Compile::current()->in_preserve_stack_slots() + 3962 Compile::current()->fixed_slots()), 3963 stack_alignment_in_slots())); 3964 3965 // Body of function which returns an integer array locating 3966 // arguments either in registers or in stack slots. Passed an array 3967 // of ideal registers called "sig" and a "length" count. Stack-slot 3968 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3969 // arguments for a CALLEE. Incoming stack arguments are 3970 // automatically biased by the preserve_stack_slots field above. 3971 3972 calling_convention 3973 %{ 3974 // No difference between ingoing/outgoing just pass false 3975 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3976 %} 3977 3978 c_calling_convention 3979 %{ 3980 // This is obviously always outgoing 3981 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3982 %} 3983 3984 // Location of compiled Java return values. Same as C for now. 3985 return_value 3986 %{ 3987 // TODO do we allow ideal_reg == Op_RegN??? 3988 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3989 "only return normal values"); 3990 3991 static const int lo[Op_RegL + 1] = { // enum name 3992 0, // Op_Node 3993 0, // Op_Set 3994 R0_num, // Op_RegN 3995 R0_num, // Op_RegI 3996 R0_num, // Op_RegP 3997 V0_num, // Op_RegF 3998 V0_num, // Op_RegD 3999 R0_num // Op_RegL 4000 }; 4001 4002 static const int hi[Op_RegL + 1] = { // enum name 4003 0, // Op_Node 4004 0, // Op_Set 4005 OptoReg::Bad, // Op_RegN 4006 OptoReg::Bad, // Op_RegI 4007 R0_H_num, // Op_RegP 4008 OptoReg::Bad, // Op_RegF 4009 V0_H_num, // Op_RegD 4010 R0_H_num // Op_RegL 4011 }; 4012 4013 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 4014 %} 4015 %} 4016 4017 //----------ATTRIBUTES--------------------------------------------------------- 4018 //----------Operand Attributes------------------------------------------------- 4019 op_attrib op_cost(1); // Required cost attribute 4020 4021 //----------Instruction Attributes--------------------------------------------- 4022 ins_attrib ins_cost(INSN_COST); // Required cost attribute 4023 ins_attrib ins_size(32); // Required size attribute (in bits) 4024 ins_attrib ins_short_branch(0); // Required flag: is this instruction 4025 // a non-matching short branch variant 4026 // of some long branch? 4027 ins_attrib ins_alignment(4); // Required alignment attribute (must 4028 // be a power of 2) specifies the 4029 // alignment that some part of the 4030 // instruction (not necessarily the 4031 // start) requires. If > 1, a 4032 // compute_padding() function must be 4033 // provided for the instruction 4034 4035 //----------OPERANDS----------------------------------------------------------- 4036 // Operand definitions must precede instruction definitions for correct parsing 4037 // in the ADLC because operands constitute user defined types which are used in 4038 // instruction definitions. 4039 4040 //----------Simple Operands---------------------------------------------------- 4041 4042 // Integer operands 32 bit 4043 // 32 bit immediate 4044 operand immI() 4045 %{ 4046 match(ConI); 4047 4048 op_cost(0); 4049 format %{ %} 4050 interface(CONST_INTER); 4051 %} 4052 4053 // 32 bit zero 4054 operand immI0() 4055 %{ 4056 predicate(n->get_int() == 0); 4057 match(ConI); 4058 4059 op_cost(0); 4060 format %{ %} 4061 interface(CONST_INTER); 4062 %} 4063 4064 // 32 bit unit increment 4065 operand immI_1() 4066 %{ 4067 predicate(n->get_int() == 1); 4068 match(ConI); 4069 4070 op_cost(0); 4071 format %{ %} 4072 interface(CONST_INTER); 4073 %} 4074 4075 // 32 bit unit decrement 4076 operand immI_M1() 4077 %{ 4078 predicate(n->get_int() == -1); 4079 match(ConI); 4080 4081 op_cost(0); 4082 format %{ %} 4083 interface(CONST_INTER); 4084 %} 4085 4086 operand immI_le_4() 4087 %{ 4088 predicate(n->get_int() <= 4); 4089 match(ConI); 4090 4091 op_cost(0); 4092 format %{ %} 4093 interface(CONST_INTER); 4094 %} 4095 4096 operand immI_31() 4097 %{ 4098 predicate(n->get_int() == 31); 4099 match(ConI); 4100 4101 op_cost(0); 4102 format %{ %} 4103 interface(CONST_INTER); 4104 %} 4105 4106 operand immI_8() 4107 %{ 4108 predicate(n->get_int() == 8); 4109 match(ConI); 4110 4111 op_cost(0); 4112 format %{ %} 4113 interface(CONST_INTER); 4114 %} 4115 4116 operand immI_16() 4117 %{ 4118 predicate(n->get_int() == 16); 4119 match(ConI); 4120 4121 op_cost(0); 4122 format %{ %} 4123 interface(CONST_INTER); 4124 %} 4125 4126 operand immI_24() 4127 %{ 4128 predicate(n->get_int() == 24); 4129 match(ConI); 4130 4131 op_cost(0); 4132 format %{ %} 4133 interface(CONST_INTER); 4134 %} 4135 4136 operand immI_32() 4137 %{ 4138 predicate(n->get_int() == 32); 4139 match(ConI); 4140 4141 op_cost(0); 4142 format %{ %} 4143 interface(CONST_INTER); 4144 %} 4145 4146 operand immI_48() 4147 %{ 4148 predicate(n->get_int() == 48); 4149 match(ConI); 4150 4151 op_cost(0); 4152 format %{ %} 4153 interface(CONST_INTER); 4154 %} 4155 4156 operand immI_56() 4157 %{ 4158 predicate(n->get_int() == 56); 4159 match(ConI); 4160 4161 op_cost(0); 4162 format %{ %} 4163 interface(CONST_INTER); 4164 %} 4165 4166 operand immI_64() 4167 %{ 4168 predicate(n->get_int() == 64); 4169 match(ConI); 4170 4171 op_cost(0); 4172 format %{ %} 4173 interface(CONST_INTER); 4174 %} 4175 4176 operand immI_255() 4177 %{ 4178 predicate(n->get_int() == 255); 4179 match(ConI); 4180 4181 op_cost(0); 4182 format %{ %} 4183 interface(CONST_INTER); 4184 %} 4185 4186 operand immI_65535() 4187 %{ 4188 predicate(n->get_int() == 65535); 4189 match(ConI); 4190 4191 op_cost(0); 4192 format %{ %} 4193 interface(CONST_INTER); 4194 %} 4195 4196 operand immL_63() 4197 %{ 4198 predicate(n->get_int() == 63); 4199 match(ConI); 4200 4201 op_cost(0); 4202 format %{ %} 4203 interface(CONST_INTER); 4204 %} 4205 4206 operand immL_255() 4207 %{ 4208 predicate(n->get_int() == 255); 4209 match(ConI); 4210 4211 op_cost(0); 4212 format %{ %} 4213 interface(CONST_INTER); 4214 %} 4215 4216 operand immL_65535() 4217 %{ 4218 predicate(n->get_long() == 65535L); 4219 match(ConL); 4220 4221 op_cost(0); 4222 format %{ %} 4223 interface(CONST_INTER); 4224 %} 4225 4226 operand immL_4294967295() 4227 %{ 4228 predicate(n->get_long() == 4294967295L); 4229 match(ConL); 4230 4231 op_cost(0); 4232 format %{ %} 4233 interface(CONST_INTER); 4234 %} 4235 4236 operand immL_bitmask() 4237 %{ 4238 predicate(((n->get_long() & 0xc000000000000000l) == 0) 4239 && is_power_of_2(n->get_long() + 1)); 4240 match(ConL); 4241 4242 op_cost(0); 4243 format %{ %} 4244 interface(CONST_INTER); 4245 %} 4246 4247 operand immI_bitmask() 4248 %{ 4249 predicate(((n->get_int() & 0xc0000000) == 0) 4250 && is_power_of_2(n->get_int() + 1)); 4251 match(ConI); 4252 4253 op_cost(0); 4254 format %{ %} 4255 interface(CONST_INTER); 4256 %} 4257 4258 // Scale values for scaled offset addressing modes (up to long but not quad) 4259 operand immIScale() 4260 %{ 4261 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4262 match(ConI); 4263 4264 op_cost(0); 4265 format %{ %} 4266 interface(CONST_INTER); 4267 %} 4268 4269 // 26 bit signed offset -- for pc-relative branches 4270 operand immI26() 4271 %{ 4272 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4273 match(ConI); 4274 4275 op_cost(0); 4276 format %{ %} 4277 interface(CONST_INTER); 4278 %} 4279 4280 // 19 bit signed offset -- for pc-relative loads 4281 operand immI19() 4282 %{ 4283 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4284 match(ConI); 4285 4286 op_cost(0); 4287 format %{ %} 4288 interface(CONST_INTER); 4289 %} 4290 4291 // 12 bit unsigned offset -- for base plus immediate loads 4292 operand immIU12() 4293 %{ 4294 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4295 match(ConI); 4296 4297 op_cost(0); 4298 format %{ %} 4299 interface(CONST_INTER); 4300 %} 4301 4302 operand immLU12() 4303 %{ 4304 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4305 match(ConL); 4306 4307 op_cost(0); 4308 format %{ %} 4309 interface(CONST_INTER); 4310 %} 4311 4312 // Offset for scaled or unscaled immediate loads and stores 4313 operand immIOffset() 4314 %{ 4315 predicate(Address::offset_ok_for_immed(n->get_int())); 4316 match(ConI); 4317 4318 op_cost(0); 4319 format %{ %} 4320 interface(CONST_INTER); 4321 %} 4322 4323 operand immLoffset() 4324 %{ 4325 predicate(Address::offset_ok_for_immed(n->get_long())); 4326 match(ConL); 4327 4328 op_cost(0); 4329 format %{ %} 4330 interface(CONST_INTER); 4331 %} 4332 4333 // 32 bit integer valid for add sub immediate 4334 operand immIAddSub() 4335 %{ 4336 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 4337 match(ConI); 4338 op_cost(0); 4339 format %{ %} 4340 interface(CONST_INTER); 4341 %} 4342 4343 // 32 bit unsigned integer valid for logical immediate 4344 // TODO -- check this is right when e.g the mask is 0x80000000 4345 operand immILog() 4346 %{ 4347 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 4348 match(ConI); 4349 4350 op_cost(0); 4351 format %{ %} 4352 interface(CONST_INTER); 4353 %} 4354 4355 // Integer operands 64 bit 4356 // 64 bit immediate 4357 operand immL() 4358 %{ 4359 match(ConL); 4360 4361 op_cost(0); 4362 format %{ %} 4363 interface(CONST_INTER); 4364 %} 4365 4366 // 64 bit zero 4367 operand immL0() 4368 %{ 4369 predicate(n->get_long() == 0); 4370 match(ConL); 4371 4372 op_cost(0); 4373 format %{ %} 4374 interface(CONST_INTER); 4375 %} 4376 4377 // 64 bit unit increment 4378 operand immL_1() 4379 %{ 4380 predicate(n->get_long() == 1); 4381 match(ConL); 4382 4383 op_cost(0); 4384 format %{ %} 4385 interface(CONST_INTER); 4386 %} 4387 4388 // 64 bit unit decrement 4389 operand immL_M1() 4390 %{ 4391 predicate(n->get_long() == -1); 4392 match(ConL); 4393 4394 op_cost(0); 4395 format %{ %} 4396 interface(CONST_INTER); 4397 %} 4398 4399 // 32 bit offset of pc in thread anchor 4400 4401 operand immL_pc_off() 4402 %{ 4403 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4404 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4405 match(ConL); 4406 4407 op_cost(0); 4408 format %{ %} 4409 interface(CONST_INTER); 4410 %} 4411 4412 // 64 bit integer valid for add sub immediate 4413 operand immLAddSub() 4414 %{ 4415 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4416 match(ConL); 4417 op_cost(0); 4418 format %{ %} 4419 interface(CONST_INTER); 4420 %} 4421 4422 // 64 bit integer valid for logical immediate 4423 operand immLLog() 4424 %{ 4425 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 4426 match(ConL); 4427 op_cost(0); 4428 format %{ %} 4429 interface(CONST_INTER); 4430 %} 4431 4432 // Long Immediate: low 32-bit mask 4433 operand immL_32bits() 4434 %{ 4435 predicate(n->get_long() == 0xFFFFFFFFL); 4436 match(ConL); 4437 op_cost(0); 4438 format %{ %} 4439 interface(CONST_INTER); 4440 %} 4441 4442 // Pointer operands 4443 // Pointer Immediate 4444 operand immP() 4445 %{ 4446 match(ConP); 4447 4448 op_cost(0); 4449 format %{ %} 4450 interface(CONST_INTER); 4451 %} 4452 4453 // NULL Pointer Immediate 4454 operand immP0() 4455 %{ 4456 predicate(n->get_ptr() == 0); 4457 match(ConP); 4458 4459 op_cost(0); 4460 format %{ %} 4461 interface(CONST_INTER); 4462 %} 4463 4464 // Pointer Immediate One 4465 // this is used in object initialization (initial object header) 4466 operand immP_1() 4467 %{ 4468 predicate(n->get_ptr() == 1); 4469 match(ConP); 4470 4471 op_cost(0); 4472 format %{ %} 4473 interface(CONST_INTER); 4474 %} 4475 4476 // Polling Page Pointer Immediate 4477 operand immPollPage() 4478 %{ 4479 predicate((address)n->get_ptr() == os::get_polling_page()); 4480 match(ConP); 4481 4482 op_cost(0); 4483 format %{ %} 4484 interface(CONST_INTER); 4485 %} 4486 4487 // Card Table Byte Map Base 4488 operand immByteMapBase() 4489 %{ 4490 // Get base of card map 4491 predicate((jbyte*)n->get_ptr() == 4492 ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base); 4493 match(ConP); 4494 4495 op_cost(0); 4496 format %{ %} 4497 interface(CONST_INTER); 4498 %} 4499 4500 // Pointer Immediate Minus One 4501 // this is used when we want to write the current PC to the thread anchor 4502 operand immP_M1() 4503 %{ 4504 predicate(n->get_ptr() == -1); 4505 match(ConP); 4506 4507 op_cost(0); 4508 format %{ %} 4509 interface(CONST_INTER); 4510 %} 4511 4512 // Pointer Immediate Minus Two 4513 // this is used when we want to write the current PC to the thread anchor 4514 operand immP_M2() 4515 %{ 4516 predicate(n->get_ptr() == -2); 4517 match(ConP); 4518 4519 op_cost(0); 4520 format %{ %} 4521 interface(CONST_INTER); 4522 %} 4523 4524 // Float and Double operands 4525 // Double Immediate 4526 operand immD() 4527 %{ 4528 match(ConD); 4529 op_cost(0); 4530 format %{ %} 4531 interface(CONST_INTER); 4532 %} 4533 4534 // Double Immediate: +0.0d 4535 operand immD0() 4536 %{ 4537 predicate(jlong_cast(n->getd()) == 0); 4538 match(ConD); 4539 4540 op_cost(0); 4541 format %{ %} 4542 interface(CONST_INTER); 4543 %} 4544 4545 // constant 'double +0.0'. 4546 operand immDPacked() 4547 %{ 4548 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4549 match(ConD); 4550 op_cost(0); 4551 format %{ %} 4552 interface(CONST_INTER); 4553 %} 4554 4555 // Float Immediate 4556 operand immF() 4557 %{ 4558 match(ConF); 4559 op_cost(0); 4560 format %{ %} 4561 interface(CONST_INTER); 4562 %} 4563 4564 // Float Immediate: +0.0f. 4565 operand immF0() 4566 %{ 4567 predicate(jint_cast(n->getf()) == 0); 4568 match(ConF); 4569 4570 op_cost(0); 4571 format %{ %} 4572 interface(CONST_INTER); 4573 %} 4574 4575 // 4576 operand immFPacked() 4577 %{ 4578 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4579 match(ConF); 4580 op_cost(0); 4581 format %{ %} 4582 interface(CONST_INTER); 4583 %} 4584 4585 // Narrow pointer operands 4586 // Narrow Pointer Immediate 4587 operand immN() 4588 %{ 4589 match(ConN); 4590 4591 op_cost(0); 4592 format %{ %} 4593 interface(CONST_INTER); 4594 %} 4595 4596 // Narrow NULL Pointer Immediate 4597 operand immN0() 4598 %{ 4599 predicate(n->get_narrowcon() == 0); 4600 match(ConN); 4601 4602 op_cost(0); 4603 format %{ %} 4604 interface(CONST_INTER); 4605 %} 4606 4607 operand immNKlass() 4608 %{ 4609 match(ConNKlass); 4610 4611 op_cost(0); 4612 format %{ %} 4613 interface(CONST_INTER); 4614 %} 4615 4616 // Integer 32 bit Register Operands 4617 // Integer 32 bitRegister (excludes SP) 4618 operand iRegI() 4619 %{ 4620 constraint(ALLOC_IN_RC(any_reg32)); 4621 match(RegI); 4622 match(iRegINoSp); 4623 op_cost(0); 4624 format %{ %} 4625 interface(REG_INTER); 4626 %} 4627 4628 // Integer 32 bit Register not Special 4629 operand iRegINoSp() 4630 %{ 4631 constraint(ALLOC_IN_RC(no_special_reg32)); 4632 match(RegI); 4633 op_cost(0); 4634 format %{ %} 4635 interface(REG_INTER); 4636 %} 4637 4638 // Integer 64 bit Register Operands 4639 // Integer 64 bit Register (includes SP) 4640 operand iRegL() 4641 %{ 4642 constraint(ALLOC_IN_RC(any_reg)); 4643 match(RegL); 4644 match(iRegLNoSp); 4645 op_cost(0); 4646 format %{ %} 4647 interface(REG_INTER); 4648 %} 4649 4650 // Integer 64 bit Register not Special 4651 operand iRegLNoSp() 4652 %{ 4653 constraint(ALLOC_IN_RC(no_special_reg)); 4654 match(RegL); 4655 format %{ %} 4656 interface(REG_INTER); 4657 %} 4658 4659 // Pointer Register Operands 4660 // Pointer Register 4661 operand iRegP() 4662 %{ 4663 constraint(ALLOC_IN_RC(ptr_reg)); 4664 match(RegP); 4665 match(iRegPNoSp); 4666 match(iRegP_R0); 4667 //match(iRegP_R2); 4668 //match(iRegP_R4); 4669 //match(iRegP_R5); 4670 match(thread_RegP); 4671 op_cost(0); 4672 format %{ %} 4673 interface(REG_INTER); 4674 %} 4675 4676 // Pointer 64 bit Register not Special 4677 operand iRegPNoSp() 4678 %{ 4679 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4680 match(RegP); 4681 // match(iRegP); 4682 // match(iRegP_R0); 4683 // match(iRegP_R2); 4684 // match(iRegP_R4); 4685 // match(iRegP_R5); 4686 // match(thread_RegP); 4687 op_cost(0); 4688 format %{ %} 4689 interface(REG_INTER); 4690 %} 4691 4692 // Pointer 64 bit Register R0 only 4693 operand iRegP_R0() 4694 %{ 4695 constraint(ALLOC_IN_RC(r0_reg)); 4696 match(RegP); 4697 // match(iRegP); 4698 match(iRegPNoSp); 4699 op_cost(0); 4700 format %{ %} 4701 interface(REG_INTER); 4702 %} 4703 4704 // Pointer 64 bit Register R1 only 4705 operand iRegP_R1() 4706 %{ 4707 constraint(ALLOC_IN_RC(r1_reg)); 4708 match(RegP); 4709 // match(iRegP); 4710 match(iRegPNoSp); 4711 op_cost(0); 4712 format %{ %} 4713 interface(REG_INTER); 4714 %} 4715 4716 // Pointer 64 bit Register R2 only 4717 operand iRegP_R2() 4718 %{ 4719 constraint(ALLOC_IN_RC(r2_reg)); 4720 match(RegP); 4721 // match(iRegP); 4722 match(iRegPNoSp); 4723 op_cost(0); 4724 format %{ %} 4725 interface(REG_INTER); 4726 %} 4727 4728 // Pointer 64 bit Register R3 only 4729 operand iRegP_R3() 4730 %{ 4731 constraint(ALLOC_IN_RC(r3_reg)); 4732 match(RegP); 4733 // match(iRegP); 4734 match(iRegPNoSp); 4735 op_cost(0); 4736 format %{ %} 4737 interface(REG_INTER); 4738 %} 4739 4740 // Pointer 64 bit Register R4 only 4741 operand iRegP_R4() 4742 %{ 4743 constraint(ALLOC_IN_RC(r4_reg)); 4744 match(RegP); 4745 // match(iRegP); 4746 match(iRegPNoSp); 4747 op_cost(0); 4748 format %{ %} 4749 interface(REG_INTER); 4750 %} 4751 4752 // Pointer 64 bit Register R5 only 4753 operand iRegP_R5() 4754 %{ 4755 constraint(ALLOC_IN_RC(r5_reg)); 4756 match(RegP); 4757 // match(iRegP); 4758 match(iRegPNoSp); 4759 op_cost(0); 4760 format %{ %} 4761 interface(REG_INTER); 4762 %} 4763 4764 // Pointer 64 bit Register R10 only 4765 operand iRegP_R10() 4766 %{ 4767 constraint(ALLOC_IN_RC(r10_reg)); 4768 match(RegP); 4769 // match(iRegP); 4770 match(iRegPNoSp); 4771 op_cost(0); 4772 format %{ %} 4773 interface(REG_INTER); 4774 %} 4775 4776 // Long 64 bit Register R11 only 4777 operand iRegL_R11() 4778 %{ 4779 constraint(ALLOC_IN_RC(r11_reg)); 4780 match(RegL); 4781 match(iRegLNoSp); 4782 op_cost(0); 4783 format %{ %} 4784 interface(REG_INTER); 4785 %} 4786 4787 // Pointer 64 bit Register FP only 4788 operand iRegP_FP() 4789 %{ 4790 constraint(ALLOC_IN_RC(fp_reg)); 4791 match(RegP); 4792 // match(iRegP); 4793 op_cost(0); 4794 format %{ %} 4795 interface(REG_INTER); 4796 %} 4797 4798 // Register R0 only 4799 operand iRegI_R0() 4800 %{ 4801 constraint(ALLOC_IN_RC(int_r0_reg)); 4802 match(RegI); 4803 match(iRegINoSp); 4804 op_cost(0); 4805 format %{ %} 4806 interface(REG_INTER); 4807 %} 4808 4809 // Register R2 only 4810 operand iRegI_R2() 4811 %{ 4812 constraint(ALLOC_IN_RC(int_r2_reg)); 4813 match(RegI); 4814 match(iRegINoSp); 4815 op_cost(0); 4816 format %{ %} 4817 interface(REG_INTER); 4818 %} 4819 4820 // Register R3 only 4821 operand iRegI_R3() 4822 %{ 4823 constraint(ALLOC_IN_RC(int_r3_reg)); 4824 match(RegI); 4825 match(iRegINoSp); 4826 op_cost(0); 4827 format %{ %} 4828 interface(REG_INTER); 4829 %} 4830 4831 4832 // Register R2 only 4833 operand iRegI_R4() 4834 %{ 4835 constraint(ALLOC_IN_RC(int_r4_reg)); 4836 match(RegI); 4837 match(iRegINoSp); 4838 op_cost(0); 4839 format %{ %} 4840 interface(REG_INTER); 4841 %} 4842 4843 4844 // Pointer Register Operands 4845 // Narrow Pointer Register 4846 operand iRegN() 4847 %{ 4848 constraint(ALLOC_IN_RC(any_reg32)); 4849 match(RegN); 4850 match(iRegNNoSp); 4851 op_cost(0); 4852 format %{ %} 4853 interface(REG_INTER); 4854 %} 4855 4856 // Integer 64 bit Register not Special 4857 operand iRegNNoSp() 4858 %{ 4859 constraint(ALLOC_IN_RC(no_special_reg32)); 4860 match(RegN); 4861 op_cost(0); 4862 format %{ %} 4863 interface(REG_INTER); 4864 %} 4865 4866 // heap base register -- used for encoding immN0 4867 4868 operand iRegIHeapbase() 4869 %{ 4870 constraint(ALLOC_IN_RC(heapbase_reg)); 4871 match(RegI); 4872 op_cost(0); 4873 format %{ %} 4874 interface(REG_INTER); 4875 %} 4876 4877 // Float Register 4878 // Float register operands 4879 operand vRegF() 4880 %{ 4881 constraint(ALLOC_IN_RC(float_reg)); 4882 match(RegF); 4883 4884 op_cost(0); 4885 format %{ %} 4886 interface(REG_INTER); 4887 %} 4888 4889 // Double Register 4890 // Double register operands 4891 operand vRegD() 4892 %{ 4893 constraint(ALLOC_IN_RC(double_reg)); 4894 match(RegD); 4895 4896 op_cost(0); 4897 format %{ %} 4898 interface(REG_INTER); 4899 %} 4900 4901 operand vRegD_V0() 4902 %{ 4903 constraint(ALLOC_IN_RC(v0_reg)); 4904 match(RegD); 4905 op_cost(0); 4906 format %{ %} 4907 interface(REG_INTER); 4908 %} 4909 4910 operand vRegD_V1() 4911 %{ 4912 constraint(ALLOC_IN_RC(v1_reg)); 4913 match(RegD); 4914 op_cost(0); 4915 format %{ %} 4916 interface(REG_INTER); 4917 %} 4918 4919 operand vRegD_V2() 4920 %{ 4921 constraint(ALLOC_IN_RC(v2_reg)); 4922 match(RegD); 4923 op_cost(0); 4924 format %{ %} 4925 interface(REG_INTER); 4926 %} 4927 4928 operand vRegD_V3() 4929 %{ 4930 constraint(ALLOC_IN_RC(v3_reg)); 4931 match(RegD); 4932 op_cost(0); 4933 format %{ %} 4934 interface(REG_INTER); 4935 %} 4936 4937 // Flags register, used as output of signed compare instructions 4938 4939 // note that on AArch64 we also use this register as the output for 4940 // for floating point compare instructions (CmpF CmpD). this ensures 4941 // that ordered inequality tests use GT, GE, LT or LE none of which 4942 // pass through cases where the result is unordered i.e. one or both 4943 // inputs to the compare is a NaN. this means that the ideal code can 4944 // replace e.g. a GT with an LE and not end up capturing the NaN case 4945 // (where the comparison should always fail). EQ and NE tests are 4946 // always generated in ideal code so that unordered folds into the NE 4947 // case, matching the behaviour of AArch64 NE. 4948 // 4949 // This differs from x86 where the outputs of FP compares use a 4950 // special FP flags registers and where compares based on this 4951 // register are distinguished into ordered inequalities (cmpOpUCF) and 4952 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 4953 // to explicitly handle the unordered case in branches. x86 also has 4954 // to include extra CMoveX rules to accept a cmpOpUCF input. 4955 4956 operand rFlagsReg() 4957 %{ 4958 constraint(ALLOC_IN_RC(int_flags)); 4959 match(RegFlags); 4960 4961 op_cost(0); 4962 format %{ "RFLAGS" %} 4963 interface(REG_INTER); 4964 %} 4965 4966 // Flags register, used as output of unsigned compare instructions 4967 operand rFlagsRegU() 4968 %{ 4969 constraint(ALLOC_IN_RC(int_flags)); 4970 match(RegFlags); 4971 4972 op_cost(0); 4973 format %{ "RFLAGSU" %} 4974 interface(REG_INTER); 4975 %} 4976 4977 // Special Registers 4978 4979 // Method Register 4980 operand inline_cache_RegP(iRegP reg) 4981 %{ 4982 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 4983 match(reg); 4984 match(iRegPNoSp); 4985 op_cost(0); 4986 format %{ %} 4987 interface(REG_INTER); 4988 %} 4989 4990 operand interpreter_method_oop_RegP(iRegP reg) 4991 %{ 4992 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 4993 match(reg); 4994 match(iRegPNoSp); 4995 op_cost(0); 4996 format %{ %} 4997 interface(REG_INTER); 4998 %} 4999 5000 // Thread Register 5001 operand thread_RegP(iRegP reg) 5002 %{ 5003 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5004 match(reg); 5005 op_cost(0); 5006 format %{ %} 5007 interface(REG_INTER); 5008 %} 5009 5010 operand lr_RegP(iRegP reg) 5011 %{ 5012 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5013 match(reg); 5014 op_cost(0); 5015 format %{ %} 5016 interface(REG_INTER); 5017 %} 5018 5019 //----------Memory Operands---------------------------------------------------- 5020 5021 operand indirect(iRegP reg) 5022 %{ 5023 constraint(ALLOC_IN_RC(ptr_reg)); 5024 match(reg); 5025 op_cost(0); 5026 format %{ "[$reg]" %} 5027 interface(MEMORY_INTER) %{ 5028 base($reg); 5029 index(0xffffffff); 5030 scale(0x0); 5031 disp(0x0); 5032 %} 5033 %} 5034 5035 operand indIndexScaledOffsetI(iRegP reg, iRegL lreg, immIScale scale, immIU12 off) 5036 %{ 5037 constraint(ALLOC_IN_RC(ptr_reg)); 5038 match(AddP (AddP reg (LShiftL lreg scale)) off); 5039 op_cost(INSN_COST); 5040 format %{ "$reg, $lreg lsl($scale), $off" %} 5041 interface(MEMORY_INTER) %{ 5042 base($reg); 5043 index($lreg); 5044 scale($scale); 5045 disp($off); 5046 %} 5047 %} 5048 5049 operand indIndexScaledOffsetL(iRegP reg, iRegL lreg, immIScale scale, immLU12 off) 5050 %{ 5051 constraint(ALLOC_IN_RC(ptr_reg)); 5052 match(AddP (AddP reg (LShiftL lreg scale)) off); 5053 op_cost(INSN_COST); 5054 format %{ "$reg, $lreg lsl($scale), $off" %} 5055 interface(MEMORY_INTER) %{ 5056 base($reg); 5057 index($lreg); 5058 scale($scale); 5059 disp($off); 5060 %} 5061 %} 5062 5063 operand indIndexScaledOffsetI2L(iRegP reg, iRegI ireg, immIScale scale, immLU12 off) 5064 %{ 5065 constraint(ALLOC_IN_RC(ptr_reg)); 5066 match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off); 5067 op_cost(INSN_COST); 5068 format %{ "$reg, $ireg sxtw($scale), $off I2L" %} 5069 interface(MEMORY_INTER) %{ 5070 base($reg); 5071 index($ireg); 5072 scale($scale); 5073 disp($off); 5074 %} 5075 %} 5076 5077 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5078 %{ 5079 constraint(ALLOC_IN_RC(ptr_reg)); 5080 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5081 op_cost(0); 5082 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5083 interface(MEMORY_INTER) %{ 5084 base($reg); 5085 index($ireg); 5086 scale($scale); 5087 disp(0x0); 5088 %} 5089 %} 5090 5091 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5092 %{ 5093 constraint(ALLOC_IN_RC(ptr_reg)); 5094 match(AddP reg (LShiftL lreg scale)); 5095 op_cost(0); 5096 format %{ "$reg, $lreg lsl($scale)" %} 5097 interface(MEMORY_INTER) %{ 5098 base($reg); 5099 index($lreg); 5100 scale($scale); 5101 disp(0x0); 5102 %} 5103 %} 5104 5105 operand indIndex(iRegP reg, iRegL lreg) 5106 %{ 5107 constraint(ALLOC_IN_RC(ptr_reg)); 5108 match(AddP reg lreg); 5109 op_cost(0); 5110 format %{ "$reg, $lreg" %} 5111 interface(MEMORY_INTER) %{ 5112 base($reg); 5113 index($lreg); 5114 scale(0x0); 5115 disp(0x0); 5116 %} 5117 %} 5118 5119 operand indOffI(iRegP reg, immIOffset off) 5120 %{ 5121 constraint(ALLOC_IN_RC(ptr_reg)); 5122 match(AddP reg off); 5123 op_cost(INSN_COST); 5124 format %{ "[$reg, $off]" %} 5125 interface(MEMORY_INTER) %{ 5126 base($reg); 5127 index(0xffffffff); 5128 scale(0x0); 5129 disp($off); 5130 %} 5131 %} 5132 5133 operand indOffL(iRegP reg, immLoffset off) 5134 %{ 5135 constraint(ALLOC_IN_RC(ptr_reg)); 5136 match(AddP reg off); 5137 op_cost(0); 5138 format %{ "[$reg, $off]" %} 5139 interface(MEMORY_INTER) %{ 5140 base($reg); 5141 index(0xffffffff); 5142 scale(0x0); 5143 disp($off); 5144 %} 5145 %} 5146 5147 5148 operand indirectN(iRegN reg) 5149 %{ 5150 predicate(Universe::narrow_oop_shift() == 0); 5151 constraint(ALLOC_IN_RC(ptr_reg)); 5152 match(DecodeN reg); 5153 op_cost(0); 5154 format %{ "[$reg]\t# narrow" %} 5155 interface(MEMORY_INTER) %{ 5156 base($reg); 5157 index(0xffffffff); 5158 scale(0x0); 5159 disp(0x0); 5160 %} 5161 %} 5162 5163 operand indIndexScaledOffsetIN(iRegN reg, iRegL lreg, immIScale scale, immIU12 off) 5164 %{ 5165 predicate(Universe::narrow_oop_shift() == 0); 5166 constraint(ALLOC_IN_RC(ptr_reg)); 5167 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 5168 op_cost(0); 5169 format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %} 5170 interface(MEMORY_INTER) %{ 5171 base($reg); 5172 index($lreg); 5173 scale($scale); 5174 disp($off); 5175 %} 5176 %} 5177 5178 operand indIndexScaledOffsetLN(iRegN reg, iRegL lreg, immIScale scale, immLU12 off) 5179 %{ 5180 predicate(Universe::narrow_oop_shift() == 0); 5181 constraint(ALLOC_IN_RC(ptr_reg)); 5182 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 5183 op_cost(INSN_COST); 5184 format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %} 5185 interface(MEMORY_INTER) %{ 5186 base($reg); 5187 index($lreg); 5188 scale($scale); 5189 disp($off); 5190 %} 5191 %} 5192 5193 operand indIndexScaledOffsetI2LN(iRegN reg, iRegI ireg, immIScale scale, immLU12 off) 5194 %{ 5195 predicate(Universe::narrow_oop_shift() == 0); 5196 constraint(ALLOC_IN_RC(ptr_reg)); 5197 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)) off); 5198 op_cost(INSN_COST); 5199 format %{ "$reg, $ireg sxtw($scale), $off I2L\t# narrow" %} 5200 interface(MEMORY_INTER) %{ 5201 base($reg); 5202 index($ireg); 5203 scale($scale); 5204 disp($off); 5205 %} 5206 %} 5207 5208 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5209 %{ 5210 predicate(Universe::narrow_oop_shift() == 0); 5211 constraint(ALLOC_IN_RC(ptr_reg)); 5212 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5213 op_cost(0); 5214 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5215 interface(MEMORY_INTER) %{ 5216 base($reg); 5217 index($ireg); 5218 scale($scale); 5219 disp(0x0); 5220 %} 5221 %} 5222 5223 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5224 %{ 5225 predicate(Universe::narrow_oop_shift() == 0); 5226 constraint(ALLOC_IN_RC(ptr_reg)); 5227 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5228 op_cost(0); 5229 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5230 interface(MEMORY_INTER) %{ 5231 base($reg); 5232 index($lreg); 5233 scale($scale); 5234 disp(0x0); 5235 %} 5236 %} 5237 5238 operand indIndexN(iRegN reg, iRegL lreg) 5239 %{ 5240 predicate(Universe::narrow_oop_shift() == 0); 5241 constraint(ALLOC_IN_RC(ptr_reg)); 5242 match(AddP (DecodeN reg) lreg); 5243 op_cost(0); 5244 format %{ "$reg, $lreg\t# narrow" %} 5245 interface(MEMORY_INTER) %{ 5246 base($reg); 5247 index($lreg); 5248 scale(0x0); 5249 disp(0x0); 5250 %} 5251 %} 5252 5253 operand indOffIN(iRegN reg, immIOffset off) 5254 %{ 5255 predicate(Universe::narrow_oop_shift() == 0); 5256 constraint(ALLOC_IN_RC(ptr_reg)); 5257 match(AddP (DecodeN reg) off); 5258 op_cost(0); 5259 format %{ "[$reg, $off]\t# narrow" %} 5260 interface(MEMORY_INTER) %{ 5261 base($reg); 5262 index(0xffffffff); 5263 scale(0x0); 5264 disp($off); 5265 %} 5266 %} 5267 5268 operand indOffLN(iRegN reg, immLoffset off) 5269 %{ 5270 predicate(Universe::narrow_oop_shift() == 0); 5271 constraint(ALLOC_IN_RC(ptr_reg)); 5272 match(AddP (DecodeN reg) off); 5273 op_cost(0); 5274 format %{ "[$reg, $off]\t# narrow" %} 5275 interface(MEMORY_INTER) %{ 5276 base($reg); 5277 index(0xffffffff); 5278 scale(0x0); 5279 disp($off); 5280 %} 5281 %} 5282 5283 5284 5285 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5286 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5287 %{ 5288 constraint(ALLOC_IN_RC(ptr_reg)); 5289 match(AddP reg off); 5290 op_cost(0); 5291 format %{ "[$reg, $off]" %} 5292 interface(MEMORY_INTER) %{ 5293 base($reg); 5294 index(0xffffffff); 5295 scale(0x0); 5296 disp($off); 5297 %} 5298 %} 5299 5300 //----------Special Memory Operands-------------------------------------------- 5301 // Stack Slot Operand - This operand is used for loading and storing temporary 5302 // values on the stack where a match requires a value to 5303 // flow through memory. 5304 operand stackSlotP(sRegP reg) 5305 %{ 5306 constraint(ALLOC_IN_RC(stack_slots)); 5307 op_cost(100); 5308 // No match rule because this operand is only generated in matching 5309 // match(RegP); 5310 format %{ "[$reg]" %} 5311 interface(MEMORY_INTER) %{ 5312 base(0x1e); // RSP 5313 index(0x0); // No Index 5314 scale(0x0); // No Scale 5315 disp($reg); // Stack Offset 5316 %} 5317 %} 5318 5319 operand stackSlotI(sRegI reg) 5320 %{ 5321 constraint(ALLOC_IN_RC(stack_slots)); 5322 // No match rule because this operand is only generated in matching 5323 // match(RegI); 5324 format %{ "[$reg]" %} 5325 interface(MEMORY_INTER) %{ 5326 base(0x1e); // RSP 5327 index(0x0); // No Index 5328 scale(0x0); // No Scale 5329 disp($reg); // Stack Offset 5330 %} 5331 %} 5332 5333 operand stackSlotF(sRegF reg) 5334 %{ 5335 constraint(ALLOC_IN_RC(stack_slots)); 5336 // No match rule because this operand is only generated in matching 5337 // match(RegF); 5338 format %{ "[$reg]" %} 5339 interface(MEMORY_INTER) %{ 5340 base(0x1e); // RSP 5341 index(0x0); // No Index 5342 scale(0x0); // No Scale 5343 disp($reg); // Stack Offset 5344 %} 5345 %} 5346 5347 operand stackSlotD(sRegD reg) 5348 %{ 5349 constraint(ALLOC_IN_RC(stack_slots)); 5350 // No match rule because this operand is only generated in matching 5351 // match(RegD); 5352 format %{ "[$reg]" %} 5353 interface(MEMORY_INTER) %{ 5354 base(0x1e); // RSP 5355 index(0x0); // No Index 5356 scale(0x0); // No Scale 5357 disp($reg); // Stack Offset 5358 %} 5359 %} 5360 5361 operand stackSlotL(sRegL reg) 5362 %{ 5363 constraint(ALLOC_IN_RC(stack_slots)); 5364 // No match rule because this operand is only generated in matching 5365 // match(RegL); 5366 format %{ "[$reg]" %} 5367 interface(MEMORY_INTER) %{ 5368 base(0x1e); // RSP 5369 index(0x0); // No Index 5370 scale(0x0); // No Scale 5371 disp($reg); // Stack Offset 5372 %} 5373 %} 5374 5375 // Operands for expressing Control Flow 5376 // NOTE: Label is a predefined operand which should not be redefined in 5377 // the AD file. It is generically handled within the ADLC. 5378 5379 //----------Conditional Branch Operands---------------------------------------- 5380 // Comparison Op - This is the operation of the comparison, and is limited to 5381 // the following set of codes: 5382 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5383 // 5384 // Other attributes of the comparison, such as unsignedness, are specified 5385 // by the comparison instruction that sets a condition code flags register. 5386 // That result is represented by a flags operand whose subtype is appropriate 5387 // to the unsignedness (etc.) of the comparison. 5388 // 5389 // Later, the instruction which matches both the Comparison Op (a Bool) and 5390 // the flags (produced by the Cmp) specifies the coding of the comparison op 5391 // by matching a specific subtype of Bool operand below, such as cmpOpU. 5392 5393 // used for signed integral comparisons and fp comparisons 5394 5395 operand cmpOp() 5396 %{ 5397 match(Bool); 5398 5399 format %{ "" %} 5400 interface(COND_INTER) %{ 5401 equal(0x0, "eq"); 5402 not_equal(0x1, "ne"); 5403 less(0xb, "lt"); 5404 greater_equal(0xa, "ge"); 5405 less_equal(0xd, "le"); 5406 greater(0xc, "gt"); 5407 overflow(0x6, "vs"); 5408 no_overflow(0x7, "vc"); 5409 %} 5410 %} 5411 5412 // used for unsigned integral comparisons 5413 5414 operand cmpOpU() 5415 %{ 5416 match(Bool); 5417 5418 format %{ "" %} 5419 interface(COND_INTER) %{ 5420 equal(0x0, "eq"); 5421 not_equal(0x1, "ne"); 5422 less(0x3, "lo"); 5423 greater_equal(0x2, "hs"); 5424 less_equal(0x9, "ls"); 5425 greater(0x8, "hi"); 5426 overflow(0x6, "vs"); 5427 no_overflow(0x7, "vc"); 5428 %} 5429 %} 5430 5431 // Special operand allowing long args to int ops to be truncated for free 5432 5433 operand iRegL2I(iRegL reg) %{ 5434 5435 op_cost(0); 5436 5437 match(ConvL2I reg); 5438 5439 format %{ "l2i($reg)" %} 5440 5441 interface(REG_INTER) 5442 %} 5443 5444 5445 //----------OPERAND CLASSES---------------------------------------------------- 5446 // Operand Classes are groups of operands that are used as to simplify 5447 // instruction definitions by not requiring the AD writer to specify 5448 // separate instructions for every form of operand when the 5449 // instruction accepts multiple operand types with the same basic 5450 // encoding and format. The classic case of this is memory operands. 5451 5452 // memory is used to define read/write location for load/store 5453 // instruction defs. we can turn a memory op into an Address 5454 5455 opclass memory(indirect, indIndexScaledOffsetI, indIndexScaledOffsetL, indIndexScaledOffsetI2L, indIndexScaled, indIndexScaledI2L, indIndex, indOffI, indOffL, 5456 indirectN, indIndexScaledOffsetIN, indIndexScaledOffsetLN, indIndexScaledOffsetI2LN, indIndexScaledN, indIndexScaledI2LN, indIndexN, indOffIN, indOffLN); 5457 5458 5459 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 5460 // operations. it allows the src to be either an iRegI or a (ConvL2I 5461 // iRegL). in the latter case the l2i normally planted for a ConvL2I 5462 // can be elided because the 32-bit instruction will just employ the 5463 // lower 32 bits anyway. 5464 // 5465 // n.b. this does not elide all L2I conversions. if the truncated 5466 // value is consumed by more than one operation then the ConvL2I 5467 // cannot be bundled into the consuming nodes so an l2i gets planted 5468 // (actually a movw $dst $src) and the downstream instructions consume 5469 // the result of the l2i as an iRegI input. That's a shame since the 5470 // movw is actually redundant but its not too costly. 5471 5472 opclass iRegIorL2I(iRegI, iRegL2I); 5473 5474 //----------PIPELINE----------------------------------------------------------- 5475 // Rules which define the behavior of the target architectures pipeline. 5476 // Integer ALU reg operation 5477 pipeline %{ 5478 5479 attributes %{ 5480 // ARM instructions are of fixed length 5481 fixed_size_instructions; // Fixed size instructions TODO does 5482 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 5483 // ARM instructions come in 32-bit word units 5484 instruction_unit_size = 4; // An instruction is 4 bytes long 5485 instruction_fetch_unit_size = 64; // The processor fetches one line 5486 instruction_fetch_units = 1; // of 64 bytes 5487 5488 // List of nop instructions 5489 nops( MachNop ); 5490 %} 5491 5492 // We don't use an actual pipeline model so don't care about resources 5493 // or description. we do use pipeline classes to introduce fixed 5494 // latencies 5495 5496 //----------RESOURCES---------------------------------------------------------- 5497 // Resources are the functional units available to the machine 5498 5499 resources( INS0, INS1, INS01 = INS0 | INS1, 5500 ALU0, ALU1, ALU = ALU0 | ALU1, 5501 MAC, 5502 DIV, 5503 BRANCH, 5504 LDST, 5505 NEON_FP); 5506 5507 //----------PIPELINE DESCRIPTION----------------------------------------------- 5508 // Pipeline Description specifies the stages in the machine's pipeline 5509 5510 pipe_desc(ISS, EX1, EX2, WR); 5511 5512 //----------PIPELINE CLASSES--------------------------------------------------- 5513 // Pipeline Classes describe the stages in which input and output are 5514 // referenced by the hardware pipeline. 5515 5516 //------- Integer ALU operations -------------------------- 5517 5518 // Integer ALU reg-reg operation 5519 // Operands needed in EX1, result generated in EX2 5520 // Eg. ADD x0, x1, x2 5521 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5522 %{ 5523 single_instruction; 5524 dst : EX2(write); 5525 src1 : EX1(read); 5526 src2 : EX1(read); 5527 INS01 : ISS; // Dual issue as instruction 0 or 1 5528 ALU : EX2; 5529 %} 5530 5531 // Integer ALU reg-reg operation with constant shift 5532 // Shifted register must be available in LATE_ISS instead of EX1 5533 // Eg. ADD x0, x1, x2, LSL #2 5534 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 5535 %{ 5536 single_instruction; 5537 dst : EX2(write); 5538 src1 : EX1(read); 5539 src2 : ISS(read); 5540 INS01 : ISS; 5541 ALU : EX2; 5542 %} 5543 5544 // Integer ALU reg operation with constant shift 5545 // Eg. LSL x0, x1, #shift 5546 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 5547 %{ 5548 single_instruction; 5549 dst : EX2(write); 5550 src1 : ISS(read); 5551 INS01 : ISS; 5552 ALU : EX2; 5553 %} 5554 5555 // Integer ALU reg-reg operation with variable shift 5556 // Both operands must be available in LATE_ISS instead of EX1 5557 // Result is available in EX1 instead of EX2 5558 // Eg. LSLV x0, x1, x2 5559 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 5560 %{ 5561 single_instruction; 5562 dst : EX1(write); 5563 src1 : ISS(read); 5564 src2 : ISS(read); 5565 INS01 : ISS; 5566 ALU : EX1; 5567 %} 5568 5569 // Integer ALU reg-reg operation with extract 5570 // As for _vshift above, but result generated in EX2 5571 // Eg. EXTR x0, x1, x2, #N 5572 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 5573 %{ 5574 single_instruction; 5575 dst : EX2(write); 5576 src1 : ISS(read); 5577 src2 : ISS(read); 5578 INS1 : ISS; // Can only dual issue as Instruction 1 5579 ALU : EX1; 5580 %} 5581 5582 // Integer ALU reg operation 5583 // Eg. NEG x0, x1 5584 pipe_class ialu_reg(iRegI dst, iRegI src) 5585 %{ 5586 single_instruction; 5587 dst : EX2(write); 5588 src : EX1(read); 5589 INS01 : ISS; 5590 ALU : EX2; 5591 %} 5592 5593 // Integer ALU reg mmediate operation 5594 // Eg. ADD x0, x1, #N 5595 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 5596 %{ 5597 single_instruction; 5598 dst : EX2(write); 5599 src1 : EX1(read); 5600 INS01 : ISS; 5601 ALU : EX2; 5602 %} 5603 5604 // Integer ALU immediate operation (no source operands) 5605 // Eg. MOV x0, #N 5606 pipe_class ialu_imm(iRegI dst) 5607 %{ 5608 single_instruction; 5609 dst : EX1(write); 5610 INS01 : ISS; 5611 ALU : EX1; 5612 %} 5613 5614 //------- Compare operation ------------------------------- 5615 5616 // Compare reg-reg 5617 // Eg. CMP x0, x1 5618 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 5619 %{ 5620 single_instruction; 5621 // fixed_latency(16); 5622 cr : EX2(write); 5623 op1 : EX1(read); 5624 op2 : EX1(read); 5625 INS01 : ISS; 5626 ALU : EX2; 5627 %} 5628 5629 // Compare reg-reg 5630 // Eg. CMP x0, #N 5631 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 5632 %{ 5633 single_instruction; 5634 // fixed_latency(16); 5635 cr : EX2(write); 5636 op1 : EX1(read); 5637 INS01 : ISS; 5638 ALU : EX2; 5639 %} 5640 5641 //------- Conditional instructions ------------------------ 5642 5643 // Conditional no operands 5644 // Eg. CSINC x0, zr, zr, <cond> 5645 pipe_class icond_none(iRegI dst, rFlagsReg cr) 5646 %{ 5647 single_instruction; 5648 cr : EX1(read); 5649 dst : EX2(write); 5650 INS01 : ISS; 5651 ALU : EX2; 5652 %} 5653 5654 // Conditional 2 operand 5655 // EG. CSEL X0, X1, X2, <cond> 5656 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 5657 %{ 5658 single_instruction; 5659 cr : EX1(read); 5660 src1 : EX1(read); 5661 src2 : EX1(read); 5662 dst : EX2(write); 5663 INS01 : ISS; 5664 ALU : EX2; 5665 %} 5666 5667 // Conditional 2 operand 5668 // EG. CSEL X0, X1, X2, <cond> 5669 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 5670 %{ 5671 single_instruction; 5672 cr : EX1(read); 5673 src : EX1(read); 5674 dst : EX2(write); 5675 INS01 : ISS; 5676 ALU : EX2; 5677 %} 5678 5679 //------- Multiply pipeline operations -------------------- 5680 5681 // Multiply reg-reg 5682 // Eg. MUL w0, w1, w2 5683 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5684 %{ 5685 single_instruction; 5686 dst : WR(write); 5687 src1 : ISS(read); 5688 src2 : ISS(read); 5689 INS01 : ISS; 5690 MAC : WR; 5691 %} 5692 5693 // Multiply accumulate 5694 // Eg. MADD w0, w1, w2, w3 5695 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 5696 %{ 5697 single_instruction; 5698 dst : WR(write); 5699 src1 : ISS(read); 5700 src2 : ISS(read); 5701 src3 : ISS(read); 5702 INS01 : ISS; 5703 MAC : WR; 5704 %} 5705 5706 // Eg. MUL w0, w1, w2 5707 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5708 %{ 5709 single_instruction; 5710 fixed_latency(3); // Maximum latency for 64 bit mul 5711 dst : WR(write); 5712 src1 : ISS(read); 5713 src2 : ISS(read); 5714 INS01 : ISS; 5715 MAC : WR; 5716 %} 5717 5718 // Multiply accumulate 5719 // Eg. MADD w0, w1, w2, w3 5720 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 5721 %{ 5722 single_instruction; 5723 fixed_latency(3); // Maximum latency for 64 bit mul 5724 dst : WR(write); 5725 src1 : ISS(read); 5726 src2 : ISS(read); 5727 src3 : ISS(read); 5728 INS01 : ISS; 5729 MAC : WR; 5730 %} 5731 5732 //------- Divide pipeline operations -------------------- 5733 5734 // Eg. SDIV w0, w1, w2 5735 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5736 %{ 5737 single_instruction; 5738 fixed_latency(8); // Maximum latency for 32 bit divide 5739 dst : WR(write); 5740 src1 : ISS(read); 5741 src2 : ISS(read); 5742 INS0 : ISS; // Can only dual issue as instruction 0 5743 DIV : WR; 5744 %} 5745 5746 // Eg. SDIV x0, x1, x2 5747 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 5748 %{ 5749 single_instruction; 5750 fixed_latency(16); // Maximum latency for 64 bit divide 5751 dst : WR(write); 5752 src1 : ISS(read); 5753 src2 : ISS(read); 5754 INS0 : ISS; // Can only dual issue as instruction 0 5755 DIV : WR; 5756 %} 5757 5758 //------- Load pipeline operations ------------------------ 5759 5760 // Load - prefetch 5761 // Eg. PFRM <mem> 5762 pipe_class iload_prefetch(memory mem) 5763 %{ 5764 single_instruction; 5765 mem : ISS(read); 5766 INS01 : ISS; 5767 LDST : WR; 5768 %} 5769 5770 // Load - reg, mem 5771 // Eg. LDR x0, <mem> 5772 pipe_class iload_reg_mem(iRegI dst, memory mem) 5773 %{ 5774 single_instruction; 5775 dst : WR(write); 5776 mem : ISS(read); 5777 INS01 : ISS; 5778 LDST : WR; 5779 %} 5780 5781 // Load - reg, reg 5782 // Eg. LDR x0, [sp, x1] 5783 pipe_class iload_reg_reg(iRegI dst, iRegI src) 5784 %{ 5785 single_instruction; 5786 dst : WR(write); 5787 src : ISS(read); 5788 INS01 : ISS; 5789 LDST : WR; 5790 %} 5791 5792 //------- Store pipeline operations ----------------------- 5793 5794 // Store - zr, mem 5795 // Eg. STR zr, <mem> 5796 pipe_class istore_mem(memory mem) 5797 %{ 5798 single_instruction; 5799 mem : ISS(read); 5800 INS01 : ISS; 5801 LDST : WR; 5802 %} 5803 5804 // Store - reg, mem 5805 // Eg. STR x0, <mem> 5806 pipe_class istore_reg_mem(iRegI src, memory mem) 5807 %{ 5808 single_instruction; 5809 mem : ISS(read); 5810 src : EX2(read); 5811 INS01 : ISS; 5812 LDST : WR; 5813 %} 5814 5815 // Store - reg, reg 5816 // Eg. STR x0, [sp, x1] 5817 pipe_class istore_reg_reg(iRegI dst, iRegI src) 5818 %{ 5819 single_instruction; 5820 dst : ISS(read); 5821 src : EX2(read); 5822 INS01 : ISS; 5823 LDST : WR; 5824 %} 5825 5826 //------- Store pipeline operations ----------------------- 5827 5828 // Branch 5829 pipe_class pipe_branch() 5830 %{ 5831 single_instruction; 5832 INS01 : ISS; 5833 BRANCH : EX1; 5834 %} 5835 5836 // Conditional branch 5837 pipe_class pipe_branch_cond(rFlagsReg cr) 5838 %{ 5839 single_instruction; 5840 cr : EX1(read); 5841 INS01 : ISS; 5842 BRANCH : EX1; 5843 %} 5844 5845 // Compare & Branch 5846 // EG. CBZ/CBNZ 5847 pipe_class pipe_cmp_branch(iRegI op1) 5848 %{ 5849 single_instruction; 5850 op1 : EX1(read); 5851 INS01 : ISS; 5852 BRANCH : EX1; 5853 %} 5854 5855 //------- Synchronisation operations ---------------------- 5856 5857 // Any operation requiring serialization. 5858 // EG. DMB/Atomic Ops/Load Acquire/Str Release 5859 pipe_class pipe_serial() 5860 %{ 5861 single_instruction; 5862 force_serialization; 5863 fixed_latency(16); 5864 INS01 : ISS(2); // Cannot dual issue with any other instruction 5865 LDST : WR; 5866 %} 5867 5868 // Generic big/slow expanded idiom - also serialized 5869 pipe_class pipe_slow() 5870 %{ 5871 instruction_count(10); 5872 multiple_bundles; 5873 force_serialization; 5874 fixed_latency(16); 5875 INS01 : ISS(2); // Cannot dual issue with any other instruction 5876 LDST : WR; 5877 %} 5878 5879 // Empty pipeline class 5880 pipe_class pipe_class_empty() 5881 %{ 5882 single_instruction; 5883 fixed_latency(0); 5884 %} 5885 5886 // Default pipeline class. 5887 pipe_class pipe_class_default() 5888 %{ 5889 single_instruction; 5890 fixed_latency(2); 5891 %} 5892 5893 // Pipeline class for compares. 5894 pipe_class pipe_class_compare() 5895 %{ 5896 single_instruction; 5897 fixed_latency(16); 5898 %} 5899 5900 // Pipeline class for memory operations. 5901 pipe_class pipe_class_memory() 5902 %{ 5903 single_instruction; 5904 fixed_latency(16); 5905 %} 5906 5907 // Pipeline class for call. 5908 pipe_class pipe_class_call() 5909 %{ 5910 single_instruction; 5911 fixed_latency(100); 5912 %} 5913 5914 // Define the class for the Nop node. 5915 define %{ 5916 MachNop = pipe_class_empty; 5917 %} 5918 5919 %} 5920 //----------INSTRUCTIONS------------------------------------------------------- 5921 // 5922 // match -- States which machine-independent subtree may be replaced 5923 // by this instruction. 5924 // ins_cost -- The estimated cost of this instruction is used by instruction 5925 // selection to identify a minimum cost tree of machine 5926 // instructions that matches a tree of machine-independent 5927 // instructions. 5928 // format -- A string providing the disassembly for this instruction. 5929 // The value of an instruction's operand may be inserted 5930 // by referring to it with a '$' prefix. 5931 // opcode -- Three instruction opcodes may be provided. These are referred 5932 // to within an encode class as $primary, $secondary, and $tertiary 5933 // rrspectively. The primary opcode is commonly used to 5934 // indicate the type of machine instruction, while secondary 5935 // and tertiary are often used for prefix options or addressing 5936 // modes. 5937 // ins_encode -- A list of encode classes with parameters. The encode class 5938 // name must have been defined in an 'enc_class' specification 5939 // in the encode section of the architecture description. 5940 5941 // ============================================================================ 5942 // Memory (Load/Store) Instructions 5943 5944 // Load Instructions 5945 5946 // Load Byte (8 bit signed) 5947 instruct loadB(iRegINoSp dst, memory mem) 5948 %{ 5949 match(Set dst (LoadB mem)); 5950 predicate(!needs_acquiring_load(n)); 5951 5952 ins_cost(4 * INSN_COST); 5953 format %{ "ldrsbw $dst, $mem\t# byte" %} 5954 5955 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 5956 5957 ins_pipe(iload_reg_mem); 5958 %} 5959 5960 // Load Byte (8 bit signed) into long 5961 instruct loadB2L(iRegLNoSp dst, memory mem) 5962 %{ 5963 match(Set dst (ConvI2L (LoadB mem))); 5964 predicate(!needs_acquiring_load(n->in(1))); 5965 5966 ins_cost(4 * INSN_COST); 5967 format %{ "ldrsb $dst, $mem\t# byte" %} 5968 5969 ins_encode(aarch64_enc_ldrsb(dst, mem)); 5970 5971 ins_pipe(iload_reg_mem); 5972 %} 5973 5974 // Load Byte (8 bit unsigned) 5975 instruct loadUB(iRegINoSp dst, memory mem) 5976 %{ 5977 match(Set dst (LoadUB mem)); 5978 predicate(!needs_acquiring_load(n)); 5979 5980 ins_cost(4 * INSN_COST); 5981 format %{ "ldrbw $dst, $mem\t# byte" %} 5982 5983 ins_encode(aarch64_enc_ldrb(dst, mem)); 5984 5985 ins_pipe(iload_reg_mem); 5986 %} 5987 5988 // Load Byte (8 bit unsigned) into long 5989 instruct loadUB2L(iRegLNoSp dst, memory mem) 5990 %{ 5991 match(Set dst (ConvI2L (LoadUB mem))); 5992 predicate(!needs_acquiring_load(n->in(1))); 5993 5994 ins_cost(4 * INSN_COST); 5995 format %{ "ldrb $dst, $mem\t# byte" %} 5996 5997 ins_encode(aarch64_enc_ldrb(dst, mem)); 5998 5999 ins_pipe(iload_reg_mem); 6000 %} 6001 6002 // Load Short (16 bit signed) 6003 instruct loadS(iRegINoSp dst, memory mem) 6004 %{ 6005 match(Set dst (LoadS mem)); 6006 predicate(!needs_acquiring_load(n)); 6007 6008 ins_cost(4 * INSN_COST); 6009 format %{ "ldrshw $dst, $mem\t# short" %} 6010 6011 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6012 6013 ins_pipe(iload_reg_mem); 6014 %} 6015 6016 // Load Short (16 bit signed) into long 6017 instruct loadS2L(iRegLNoSp dst, memory mem) 6018 %{ 6019 match(Set dst (ConvI2L (LoadS mem))); 6020 predicate(!needs_acquiring_load(n->in(1))); 6021 6022 ins_cost(4 * INSN_COST); 6023 format %{ "ldrsh $dst, $mem\t# short" %} 6024 6025 ins_encode(aarch64_enc_ldrsh(dst, mem)); 6026 6027 ins_pipe(iload_reg_mem); 6028 %} 6029 6030 // Load Char (16 bit unsigned) 6031 instruct loadUS(iRegINoSp dst, memory mem) 6032 %{ 6033 match(Set dst (LoadUS mem)); 6034 predicate(!needs_acquiring_load(n)); 6035 6036 ins_cost(4 * INSN_COST); 6037 format %{ "ldrh $dst, $mem\t# short" %} 6038 6039 ins_encode(aarch64_enc_ldrh(dst, mem)); 6040 6041 ins_pipe(iload_reg_mem); 6042 %} 6043 6044 // Load Short/Char (16 bit unsigned) into long 6045 instruct loadUS2L(iRegLNoSp dst, memory mem) 6046 %{ 6047 match(Set dst (ConvI2L (LoadUS mem))); 6048 predicate(!needs_acquiring_load(n->in(1))); 6049 6050 ins_cost(4 * INSN_COST); 6051 format %{ "ldrh $dst, $mem\t# short" %} 6052 6053 ins_encode(aarch64_enc_ldrh(dst, mem)); 6054 6055 ins_pipe(iload_reg_mem); 6056 %} 6057 6058 // Load Integer (32 bit signed) 6059 instruct loadI(iRegINoSp dst, memory mem) 6060 %{ 6061 match(Set dst (LoadI mem)); 6062 predicate(!needs_acquiring_load(n)); 6063 6064 ins_cost(4 * INSN_COST); 6065 format %{ "ldrw $dst, $mem\t# int" %} 6066 6067 ins_encode(aarch64_enc_ldrw(dst, mem)); 6068 6069 ins_pipe(iload_reg_mem); 6070 %} 6071 6072 // Load Integer (32 bit signed) into long 6073 instruct loadI2L(iRegLNoSp dst, memory mem) 6074 %{ 6075 match(Set dst (ConvI2L (LoadI mem))); 6076 predicate(!needs_acquiring_load(n->in(1))); 6077 6078 ins_cost(4 * INSN_COST); 6079 format %{ "ldrsw $dst, $mem\t# int" %} 6080 6081 ins_encode(aarch64_enc_ldrsw(dst, mem)); 6082 6083 ins_pipe(iload_reg_mem); 6084 %} 6085 6086 // Load Integer (32 bit unsigned) into long 6087 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 6088 %{ 6089 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6090 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 6091 6092 ins_cost(4 * INSN_COST); 6093 format %{ "ldrw $dst, $mem\t# int" %} 6094 6095 ins_encode(aarch64_enc_ldrw(dst, mem)); 6096 6097 ins_pipe(iload_reg_mem); 6098 %} 6099 6100 // Load Long (64 bit signed) 6101 instruct loadL(iRegLNoSp dst, memory mem) 6102 %{ 6103 match(Set dst (LoadL mem)); 6104 predicate(!needs_acquiring_load(n)); 6105 6106 ins_cost(4 * INSN_COST); 6107 format %{ "ldr $dst, $mem\t# int" %} 6108 6109 ins_encode(aarch64_enc_ldr(dst, mem)); 6110 6111 ins_pipe(iload_reg_mem); 6112 %} 6113 6114 // Load Range 6115 instruct loadRange(iRegINoSp dst, memory mem) 6116 %{ 6117 match(Set dst (LoadRange mem)); 6118 6119 ins_cost(4 * INSN_COST); 6120 format %{ "ldrw $dst, $mem\t# range" %} 6121 6122 ins_encode(aarch64_enc_ldrw(dst, mem)); 6123 6124 ins_pipe(iload_reg_mem); 6125 %} 6126 6127 // Load Pointer 6128 instruct loadP(iRegPNoSp dst, memory mem) 6129 %{ 6130 match(Set dst (LoadP mem)); 6131 predicate(!needs_acquiring_load(n)); 6132 6133 ins_cost(4 * INSN_COST); 6134 format %{ "ldr $dst, $mem\t# ptr" %} 6135 6136 ins_encode(aarch64_enc_ldr(dst, mem)); 6137 6138 ins_pipe(iload_reg_mem); 6139 %} 6140 6141 // Load Compressed Pointer 6142 instruct loadN(iRegNNoSp dst, memory mem) 6143 %{ 6144 match(Set dst (LoadN mem)); 6145 predicate(!needs_acquiring_load(n)); 6146 6147 ins_cost(4 * INSN_COST); 6148 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 6149 6150 ins_encode(aarch64_enc_ldrw(dst, mem)); 6151 6152 ins_pipe(iload_reg_mem); 6153 %} 6154 6155 // Load Klass Pointer 6156 instruct loadKlass(iRegPNoSp dst, memory mem) 6157 %{ 6158 match(Set dst (LoadKlass mem)); 6159 predicate(!needs_acquiring_load(n)); 6160 6161 ins_cost(4 * INSN_COST); 6162 format %{ "ldr $dst, $mem\t# class" %} 6163 6164 ins_encode(aarch64_enc_ldr(dst, mem)); 6165 6166 ins_pipe(iload_reg_mem); 6167 %} 6168 6169 // Load Narrow Klass Pointer 6170 instruct loadNKlass(iRegNNoSp dst, memory mem) 6171 %{ 6172 match(Set dst (LoadNKlass mem)); 6173 predicate(!needs_acquiring_load(n)); 6174 6175 ins_cost(4 * INSN_COST); 6176 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 6177 6178 ins_encode(aarch64_enc_ldrw(dst, mem)); 6179 6180 ins_pipe(iload_reg_mem); 6181 %} 6182 6183 // Load Float 6184 instruct loadF(vRegF dst, memory mem) 6185 %{ 6186 match(Set dst (LoadF mem)); 6187 predicate(!needs_acquiring_load(n)); 6188 6189 ins_cost(4 * INSN_COST); 6190 format %{ "ldrs $dst, $mem\t# float" %} 6191 6192 ins_encode( aarch64_enc_ldrs(dst, mem) ); 6193 6194 ins_pipe(pipe_class_memory); 6195 %} 6196 6197 // Load Double 6198 instruct loadD(vRegD dst, memory mem) 6199 %{ 6200 match(Set dst (LoadD mem)); 6201 predicate(!needs_acquiring_load(n)); 6202 6203 ins_cost(4 * INSN_COST); 6204 format %{ "ldrd $dst, $mem\t# double" %} 6205 6206 ins_encode( aarch64_enc_ldrd(dst, mem) ); 6207 6208 ins_pipe(pipe_class_memory); 6209 %} 6210 6211 6212 // Load Int Constant 6213 instruct loadConI(iRegINoSp dst, immI src) 6214 %{ 6215 match(Set dst src); 6216 6217 ins_cost(INSN_COST); 6218 format %{ "mov $dst, $src\t# int" %} 6219 6220 ins_encode( aarch64_enc_movw_imm(dst, src) ); 6221 6222 ins_pipe(ialu_imm); 6223 %} 6224 6225 // Load Long Constant 6226 instruct loadConL(iRegLNoSp dst, immL src) 6227 %{ 6228 match(Set dst src); 6229 6230 ins_cost(INSN_COST); 6231 format %{ "mov $dst, $src\t# long" %} 6232 6233 ins_encode( aarch64_enc_mov_imm(dst, src) ); 6234 6235 ins_pipe(ialu_imm); 6236 %} 6237 6238 // Load Pointer Constant 6239 6240 instruct loadConP(iRegPNoSp dst, immP con) 6241 %{ 6242 match(Set dst con); 6243 6244 ins_cost(INSN_COST * 4); 6245 format %{ 6246 "mov $dst, $con\t# ptr\n\t" 6247 %} 6248 6249 ins_encode(aarch64_enc_mov_p(dst, con)); 6250 6251 ins_pipe(ialu_imm); 6252 %} 6253 6254 // Load Null Pointer Constant 6255 6256 instruct loadConP0(iRegPNoSp dst, immP0 con) 6257 %{ 6258 match(Set dst con); 6259 6260 ins_cost(INSN_COST); 6261 format %{ "mov $dst, $con\t# NULL ptr" %} 6262 6263 ins_encode(aarch64_enc_mov_p0(dst, con)); 6264 6265 ins_pipe(ialu_imm); 6266 %} 6267 6268 // Load Pointer Constant One 6269 6270 instruct loadConP1(iRegPNoSp dst, immP_1 con) 6271 %{ 6272 match(Set dst con); 6273 6274 ins_cost(INSN_COST); 6275 format %{ "mov $dst, $con\t# NULL ptr" %} 6276 6277 ins_encode(aarch64_enc_mov_p1(dst, con)); 6278 6279 ins_pipe(ialu_imm); 6280 %} 6281 6282 // Load Poll Page Constant 6283 6284 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 6285 %{ 6286 match(Set dst con); 6287 6288 ins_cost(INSN_COST); 6289 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 6290 6291 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 6292 6293 ins_pipe(ialu_imm); 6294 %} 6295 6296 // Load Byte Map Base Constant 6297 6298 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 6299 %{ 6300 match(Set dst con); 6301 6302 ins_cost(INSN_COST); 6303 format %{ "adr $dst, $con\t# Byte Map Base" %} 6304 6305 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 6306 6307 ins_pipe(ialu_imm); 6308 %} 6309 6310 // Load Narrow Pointer Constant 6311 6312 instruct loadConN(iRegNNoSp dst, immN con) 6313 %{ 6314 match(Set dst con); 6315 6316 ins_cost(INSN_COST * 4); 6317 format %{ "mov $dst, $con\t# compressed ptr" %} 6318 6319 ins_encode(aarch64_enc_mov_n(dst, con)); 6320 6321 ins_pipe(ialu_imm); 6322 %} 6323 6324 // Load Narrow Null Pointer Constant 6325 6326 instruct loadConN0(iRegNNoSp dst, immN0 con) 6327 %{ 6328 match(Set dst con); 6329 6330 ins_cost(INSN_COST); 6331 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 6332 6333 ins_encode(aarch64_enc_mov_n0(dst, con)); 6334 6335 ins_pipe(ialu_imm); 6336 %} 6337 6338 // Load Narrow Klass Constant 6339 6340 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 6341 %{ 6342 match(Set dst con); 6343 6344 ins_cost(INSN_COST); 6345 format %{ "mov $dst, $con\t# compressed klass ptr" %} 6346 6347 ins_encode(aarch64_enc_mov_nk(dst, con)); 6348 6349 ins_pipe(ialu_imm); 6350 %} 6351 6352 // Load Packed Float Constant 6353 6354 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 6355 match(Set dst con); 6356 ins_cost(INSN_COST * 4); 6357 format %{ "fmovs $dst, $con"%} 6358 ins_encode %{ 6359 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 6360 %} 6361 6362 ins_pipe(pipe_class_default); 6363 %} 6364 6365 // Load Float Constant 6366 6367 instruct loadConF(vRegF dst, immF con) %{ 6368 match(Set dst con); 6369 6370 ins_cost(INSN_COST * 4); 6371 6372 format %{ 6373 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6374 %} 6375 6376 ins_encode %{ 6377 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 6378 %} 6379 6380 ins_pipe(pipe_class_default); 6381 %} 6382 6383 // Load Packed Double Constant 6384 6385 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 6386 match(Set dst con); 6387 ins_cost(INSN_COST); 6388 format %{ "fmovd $dst, $con"%} 6389 ins_encode %{ 6390 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 6391 %} 6392 6393 ins_pipe(pipe_class_default); 6394 %} 6395 6396 // Load Double Constant 6397 6398 instruct loadConD(vRegD dst, immD con) %{ 6399 match(Set dst con); 6400 6401 ins_cost(INSN_COST * 5); 6402 format %{ 6403 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 6404 %} 6405 6406 ins_encode %{ 6407 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 6408 %} 6409 6410 ins_pipe(pipe_class_default); 6411 %} 6412 6413 // Store Instructions 6414 6415 // Store CMS card-mark Immediate 6416 instruct storeimmCM0(immI0 zero, memory mem) 6417 %{ 6418 match(Set mem (StoreCM mem zero)); 6419 6420 ins_cost(INSN_COST); 6421 format %{ "strb zr, $mem\t# byte" %} 6422 6423 ins_encode(aarch64_enc_strb0(mem)); 6424 6425 ins_pipe(istore_mem); 6426 %} 6427 6428 // Store Byte 6429 instruct storeB(iRegIorL2I src, memory mem) 6430 %{ 6431 match(Set mem (StoreB mem src)); 6432 predicate(!needs_releasing_store(n)); 6433 6434 ins_cost(INSN_COST); 6435 format %{ "strb $src, $mem\t# byte" %} 6436 6437 ins_encode(aarch64_enc_strb(src, mem)); 6438 6439 ins_pipe(istore_reg_mem); 6440 %} 6441 6442 6443 instruct storeimmB0(immI0 zero, memory mem) 6444 %{ 6445 match(Set mem (StoreB mem zero)); 6446 predicate(!needs_releasing_store(n)); 6447 6448 ins_cost(INSN_COST); 6449 format %{ "strb zr, $mem\t# byte" %} 6450 6451 ins_encode(aarch64_enc_strb0(mem)); 6452 6453 ins_pipe(istore_mem); 6454 %} 6455 6456 // Store Char/Short 6457 instruct storeC(iRegIorL2I src, memory mem) 6458 %{ 6459 match(Set mem (StoreC mem src)); 6460 predicate(!needs_releasing_store(n)); 6461 6462 ins_cost(INSN_COST); 6463 format %{ "strh $src, $mem\t# short" %} 6464 6465 ins_encode(aarch64_enc_strh(src, mem)); 6466 6467 ins_pipe(istore_reg_mem); 6468 %} 6469 6470 instruct storeimmC0(immI0 zero, memory mem) 6471 %{ 6472 match(Set mem (StoreC mem zero)); 6473 predicate(!needs_releasing_store(n)); 6474 6475 ins_cost(INSN_COST); 6476 format %{ "strh zr, $mem\t# short" %} 6477 6478 ins_encode(aarch64_enc_strh0(mem)); 6479 6480 ins_pipe(istore_mem); 6481 %} 6482 6483 // Store Integer 6484 6485 instruct storeI(iRegIorL2I src, memory mem) 6486 %{ 6487 match(Set mem(StoreI mem src)); 6488 predicate(!needs_releasing_store(n)); 6489 6490 ins_cost(INSN_COST); 6491 format %{ "strw $src, $mem\t# int" %} 6492 6493 ins_encode(aarch64_enc_strw(src, mem)); 6494 6495 ins_pipe(istore_reg_mem); 6496 %} 6497 6498 instruct storeimmI0(immI0 zero, memory mem) 6499 %{ 6500 match(Set mem(StoreI mem zero)); 6501 predicate(!needs_releasing_store(n)); 6502 6503 ins_cost(INSN_COST); 6504 format %{ "strw zr, $mem\t# int" %} 6505 6506 ins_encode(aarch64_enc_strw0(mem)); 6507 6508 ins_pipe(istore_mem); 6509 %} 6510 6511 // Store Long (64 bit signed) 6512 instruct storeL(iRegL src, memory mem) 6513 %{ 6514 match(Set mem (StoreL mem src)); 6515 predicate(!needs_releasing_store(n)); 6516 6517 ins_cost(INSN_COST); 6518 format %{ "str $src, $mem\t# int" %} 6519 6520 ins_encode(aarch64_enc_str(src, mem)); 6521 6522 ins_pipe(istore_reg_mem); 6523 %} 6524 6525 // Store Long (64 bit signed) 6526 instruct storeimmL0(immL0 zero, memory mem) 6527 %{ 6528 match(Set mem (StoreL mem zero)); 6529 predicate(!needs_releasing_store(n)); 6530 6531 ins_cost(INSN_COST); 6532 format %{ "str zr, $mem\t# int" %} 6533 6534 ins_encode(aarch64_enc_str0(mem)); 6535 6536 ins_pipe(istore_mem); 6537 %} 6538 6539 // Store Pointer 6540 instruct storeP(iRegP src, memory mem) 6541 %{ 6542 match(Set mem (StoreP mem src)); 6543 predicate(!needs_releasing_store(n)); 6544 6545 ins_cost(INSN_COST); 6546 format %{ "str $src, $mem\t# ptr" %} 6547 6548 ins_encode(aarch64_enc_str(src, mem)); 6549 6550 ins_pipe(istore_reg_mem); 6551 %} 6552 6553 // Store Pointer 6554 instruct storeimmP0(immP0 zero, memory mem) 6555 %{ 6556 match(Set mem (StoreP mem zero)); 6557 predicate(!needs_releasing_store(n)); 6558 6559 ins_cost(INSN_COST); 6560 format %{ "str zr, $mem\t# ptr" %} 6561 6562 ins_encode(aarch64_enc_str0(mem)); 6563 6564 ins_pipe(istore_mem); 6565 %} 6566 6567 // Store Compressed Pointer 6568 instruct storeN(iRegN src, memory mem) 6569 %{ 6570 match(Set mem (StoreN mem src)); 6571 predicate(!needs_releasing_store(n)); 6572 6573 ins_cost(INSN_COST); 6574 format %{ "strw $src, $mem\t# compressed ptr" %} 6575 6576 ins_encode(aarch64_enc_strw(src, mem)); 6577 6578 ins_pipe(istore_reg_mem); 6579 %} 6580 6581 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 6582 %{ 6583 match(Set mem (StoreN mem zero)); 6584 predicate(Universe::narrow_oop_base() == NULL && 6585 Universe::narrow_klass_base() == NULL && 6586 (!needs_releasing_store(n))); 6587 6588 ins_cost(INSN_COST); 6589 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 6590 6591 ins_encode(aarch64_enc_strw(heapbase, mem)); 6592 6593 ins_pipe(istore_reg_mem); 6594 %} 6595 6596 // Store Float 6597 instruct storeF(vRegF src, memory mem) 6598 %{ 6599 match(Set mem (StoreF mem src)); 6600 predicate(!needs_releasing_store(n)); 6601 6602 ins_cost(INSN_COST); 6603 format %{ "strs $src, $mem\t# float" %} 6604 6605 ins_encode( aarch64_enc_strs(src, mem) ); 6606 6607 ins_pipe(pipe_class_memory); 6608 %} 6609 6610 // TODO 6611 // implement storeImmF0 and storeFImmPacked 6612 6613 // Store Double 6614 instruct storeD(vRegD src, memory mem) 6615 %{ 6616 match(Set mem (StoreD mem src)); 6617 predicate(!needs_releasing_store(n)); 6618 6619 ins_cost(INSN_COST); 6620 format %{ "strd $src, $mem\t# double" %} 6621 6622 ins_encode( aarch64_enc_strd(src, mem) ); 6623 6624 ins_pipe(pipe_class_memory); 6625 %} 6626 6627 // Store Compressed Klass Pointer 6628 instruct storeNKlass(iRegN src, memory mem) 6629 %{ 6630 predicate(!needs_releasing_store(n)); 6631 match(Set mem (StoreNKlass mem src)); 6632 6633 ins_cost(INSN_COST); 6634 format %{ "strw $src, $mem\t# compressed klass ptr" %} 6635 6636 ins_encode(aarch64_enc_strw(src, mem)); 6637 6638 ins_pipe(istore_reg_mem); 6639 %} 6640 6641 // TODO 6642 // implement storeImmD0 and storeDImmPacked 6643 6644 // prefetch instructions 6645 // Must be safe to execute with invalid address (cannot fault). 6646 6647 instruct prefetchalloc( memory mem ) %{ 6648 match(PrefetchAllocation mem); 6649 6650 ins_cost(INSN_COST); 6651 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 6652 6653 ins_encode( aarch64_enc_prefetchw(mem) ); 6654 6655 ins_pipe(iload_prefetch); 6656 %} 6657 6658 // ---------------- volatile loads and stores ---------------- 6659 6660 // Load Byte (8 bit signed) 6661 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6662 %{ 6663 match(Set dst (LoadB mem)); 6664 6665 ins_cost(VOLATILE_REF_COST); 6666 format %{ "ldarsb $dst, $mem\t# byte" %} 6667 6668 ins_encode(aarch64_enc_ldarsb(dst, mem)); 6669 6670 ins_pipe(pipe_serial); 6671 %} 6672 6673 // Load Byte (8 bit signed) into long 6674 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6675 %{ 6676 match(Set dst (ConvI2L (LoadB mem))); 6677 6678 ins_cost(VOLATILE_REF_COST); 6679 format %{ "ldarsb $dst, $mem\t# byte" %} 6680 6681 ins_encode(aarch64_enc_ldarsb(dst, mem)); 6682 6683 ins_pipe(pipe_serial); 6684 %} 6685 6686 // Load Byte (8 bit unsigned) 6687 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6688 %{ 6689 match(Set dst (LoadUB mem)); 6690 6691 ins_cost(VOLATILE_REF_COST); 6692 format %{ "ldarb $dst, $mem\t# byte" %} 6693 6694 ins_encode(aarch64_enc_ldarb(dst, mem)); 6695 6696 ins_pipe(pipe_serial); 6697 %} 6698 6699 // Load Byte (8 bit unsigned) into long 6700 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6701 %{ 6702 match(Set dst (ConvI2L (LoadUB mem))); 6703 6704 ins_cost(VOLATILE_REF_COST); 6705 format %{ "ldarb $dst, $mem\t# byte" %} 6706 6707 ins_encode(aarch64_enc_ldarb(dst, mem)); 6708 6709 ins_pipe(pipe_serial); 6710 %} 6711 6712 // Load Short (16 bit signed) 6713 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6714 %{ 6715 match(Set dst (LoadS mem)); 6716 6717 ins_cost(VOLATILE_REF_COST); 6718 format %{ "ldarshw $dst, $mem\t# short" %} 6719 6720 ins_encode(aarch64_enc_ldarshw(dst, mem)); 6721 6722 ins_pipe(pipe_serial); 6723 %} 6724 6725 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6726 %{ 6727 match(Set dst (LoadUS mem)); 6728 6729 ins_cost(VOLATILE_REF_COST); 6730 format %{ "ldarhw $dst, $mem\t# short" %} 6731 6732 ins_encode(aarch64_enc_ldarhw(dst, mem)); 6733 6734 ins_pipe(pipe_serial); 6735 %} 6736 6737 // Load Short/Char (16 bit unsigned) into long 6738 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6739 %{ 6740 match(Set dst (ConvI2L (LoadUS mem))); 6741 6742 ins_cost(VOLATILE_REF_COST); 6743 format %{ "ldarh $dst, $mem\t# short" %} 6744 6745 ins_encode(aarch64_enc_ldarh(dst, mem)); 6746 6747 ins_pipe(pipe_serial); 6748 %} 6749 6750 // Load Short/Char (16 bit signed) into long 6751 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6752 %{ 6753 match(Set dst (ConvI2L (LoadS mem))); 6754 6755 ins_cost(VOLATILE_REF_COST); 6756 format %{ "ldarh $dst, $mem\t# short" %} 6757 6758 ins_encode(aarch64_enc_ldarsh(dst, mem)); 6759 6760 ins_pipe(pipe_serial); 6761 %} 6762 6763 // Load Integer (32 bit signed) 6764 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6765 %{ 6766 match(Set dst (LoadI mem)); 6767 6768 ins_cost(VOLATILE_REF_COST); 6769 format %{ "ldarw $dst, $mem\t# int" %} 6770 6771 ins_encode(aarch64_enc_ldarw(dst, mem)); 6772 6773 ins_pipe(pipe_serial); 6774 %} 6775 6776 // Load Integer (32 bit unsigned) into long 6777 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 6778 %{ 6779 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6780 6781 ins_cost(VOLATILE_REF_COST); 6782 format %{ "ldarw $dst, $mem\t# int" %} 6783 6784 ins_encode(aarch64_enc_ldarw(dst, mem)); 6785 6786 ins_pipe(pipe_serial); 6787 %} 6788 6789 // Load Long (64 bit signed) 6790 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6791 %{ 6792 match(Set dst (LoadL mem)); 6793 6794 ins_cost(VOLATILE_REF_COST); 6795 format %{ "ldar $dst, $mem\t# int" %} 6796 6797 ins_encode(aarch64_enc_ldar(dst, mem)); 6798 6799 ins_pipe(pipe_serial); 6800 %} 6801 6802 // Load Pointer 6803 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 6804 %{ 6805 match(Set dst (LoadP mem)); 6806 6807 ins_cost(VOLATILE_REF_COST); 6808 format %{ "ldar $dst, $mem\t# ptr" %} 6809 6810 ins_encode(aarch64_enc_ldar(dst, mem)); 6811 6812 ins_pipe(pipe_serial); 6813 %} 6814 6815 // Load Compressed Pointer 6816 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 6817 %{ 6818 match(Set dst (LoadN mem)); 6819 6820 ins_cost(VOLATILE_REF_COST); 6821 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 6822 6823 ins_encode(aarch64_enc_ldarw(dst, mem)); 6824 6825 ins_pipe(pipe_serial); 6826 %} 6827 6828 // Load Float 6829 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 6830 %{ 6831 match(Set dst (LoadF mem)); 6832 6833 ins_cost(VOLATILE_REF_COST); 6834 format %{ "ldars $dst, $mem\t# float" %} 6835 6836 ins_encode( aarch64_enc_fldars(dst, mem) ); 6837 6838 ins_pipe(pipe_serial); 6839 %} 6840 6841 // Load Double 6842 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 6843 %{ 6844 match(Set dst (LoadD mem)); 6845 6846 ins_cost(VOLATILE_REF_COST); 6847 format %{ "ldard $dst, $mem\t# double" %} 6848 6849 ins_encode( aarch64_enc_fldard(dst, mem) ); 6850 6851 ins_pipe(pipe_serial); 6852 %} 6853 6854 // Store Byte 6855 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 6856 %{ 6857 match(Set mem (StoreB mem src)); 6858 6859 ins_cost(VOLATILE_REF_COST); 6860 format %{ "stlrb $src, $mem\t# byte" %} 6861 6862 ins_encode(aarch64_enc_stlrb(src, mem)); 6863 6864 ins_pipe(pipe_class_memory); 6865 %} 6866 6867 // Store Char/Short 6868 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 6869 %{ 6870 match(Set mem (StoreC mem src)); 6871 6872 ins_cost(VOLATILE_REF_COST); 6873 format %{ "stlrh $src, $mem\t# short" %} 6874 6875 ins_encode(aarch64_enc_stlrh(src, mem)); 6876 6877 ins_pipe(pipe_class_memory); 6878 %} 6879 6880 // Store Integer 6881 6882 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 6883 %{ 6884 match(Set mem(StoreI mem src)); 6885 6886 ins_cost(VOLATILE_REF_COST); 6887 format %{ "stlrw $src, $mem\t# int" %} 6888 6889 ins_encode(aarch64_enc_stlrw(src, mem)); 6890 6891 ins_pipe(pipe_class_memory); 6892 %} 6893 6894 // Store Long (64 bit signed) 6895 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 6896 %{ 6897 match(Set mem (StoreL mem src)); 6898 6899 ins_cost(VOLATILE_REF_COST); 6900 format %{ "stlr $src, $mem\t# int" %} 6901 6902 ins_encode(aarch64_enc_stlr(src, mem)); 6903 6904 ins_pipe(pipe_class_memory); 6905 %} 6906 6907 // Store Pointer 6908 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 6909 %{ 6910 match(Set mem (StoreP mem src)); 6911 6912 ins_cost(VOLATILE_REF_COST); 6913 format %{ "stlr $src, $mem\t# ptr" %} 6914 6915 ins_encode(aarch64_enc_stlr(src, mem)); 6916 6917 ins_pipe(pipe_class_memory); 6918 %} 6919 6920 // Store Compressed Pointer 6921 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 6922 %{ 6923 match(Set mem (StoreN mem src)); 6924 6925 ins_cost(VOLATILE_REF_COST); 6926 format %{ "stlrw $src, $mem\t# compressed ptr" %} 6927 6928 ins_encode(aarch64_enc_stlrw(src, mem)); 6929 6930 ins_pipe(pipe_class_memory); 6931 %} 6932 6933 // Store Float 6934 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 6935 %{ 6936 match(Set mem (StoreF mem src)); 6937 6938 ins_cost(VOLATILE_REF_COST); 6939 format %{ "stlrs $src, $mem\t# float" %} 6940 6941 ins_encode( aarch64_enc_fstlrs(src, mem) ); 6942 6943 ins_pipe(pipe_class_memory); 6944 %} 6945 6946 // TODO 6947 // implement storeImmF0 and storeFImmPacked 6948 6949 // Store Double 6950 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 6951 %{ 6952 match(Set mem (StoreD mem src)); 6953 6954 ins_cost(VOLATILE_REF_COST); 6955 format %{ "stlrd $src, $mem\t# double" %} 6956 6957 ins_encode( aarch64_enc_fstlrd(src, mem) ); 6958 6959 ins_pipe(pipe_class_memory); 6960 %} 6961 6962 // ---------------- end of volatile loads and stores ---------------- 6963 6964 // ============================================================================ 6965 // BSWAP Instructions 6966 6967 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 6968 match(Set dst (ReverseBytesI src)); 6969 6970 ins_cost(INSN_COST); 6971 format %{ "revw $dst, $src" %} 6972 6973 ins_encode %{ 6974 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 6975 %} 6976 6977 ins_pipe(ialu_reg); 6978 %} 6979 6980 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 6981 match(Set dst (ReverseBytesL src)); 6982 6983 ins_cost(INSN_COST); 6984 format %{ "rev $dst, $src" %} 6985 6986 ins_encode %{ 6987 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 6988 %} 6989 6990 ins_pipe(ialu_reg); 6991 %} 6992 6993 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 6994 match(Set dst (ReverseBytesUS src)); 6995 6996 ins_cost(INSN_COST); 6997 format %{ "rev16w $dst, $src" %} 6998 6999 ins_encode %{ 7000 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7001 %} 7002 7003 ins_pipe(ialu_reg); 7004 %} 7005 7006 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 7007 match(Set dst (ReverseBytesS src)); 7008 7009 ins_cost(INSN_COST); 7010 format %{ "rev16w $dst, $src\n\t" 7011 "sbfmw $dst, $dst, #0, #15" %} 7012 7013 ins_encode %{ 7014 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 7015 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 7016 %} 7017 7018 ins_pipe(ialu_reg); 7019 %} 7020 7021 // ============================================================================ 7022 // Zero Count Instructions 7023 7024 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7025 match(Set dst (CountLeadingZerosI src)); 7026 7027 ins_cost(INSN_COST); 7028 format %{ "clzw $dst, $src" %} 7029 ins_encode %{ 7030 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 7031 %} 7032 7033 ins_pipe(ialu_reg); 7034 %} 7035 7036 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 7037 match(Set dst (CountLeadingZerosL src)); 7038 7039 ins_cost(INSN_COST); 7040 format %{ "clz $dst, $src" %} 7041 ins_encode %{ 7042 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 7043 %} 7044 7045 ins_pipe(ialu_reg); 7046 %} 7047 7048 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 7049 match(Set dst (CountTrailingZerosI src)); 7050 7051 ins_cost(INSN_COST * 2); 7052 format %{ "rbitw $dst, $src\n\t" 7053 "clzw $dst, $dst" %} 7054 ins_encode %{ 7055 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 7056 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 7057 %} 7058 7059 ins_pipe(ialu_reg); 7060 %} 7061 7062 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 7063 match(Set dst (CountTrailingZerosL src)); 7064 7065 ins_cost(INSN_COST * 2); 7066 format %{ "rbit $dst, $src\n\t" 7067 "clz $dst, $dst" %} 7068 ins_encode %{ 7069 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 7070 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 7071 %} 7072 7073 ins_pipe(ialu_reg); 7074 %} 7075 7076 // ============================================================================ 7077 // MemBar Instruction 7078 7079 instruct load_fence() %{ 7080 match(LoadFence); 7081 ins_cost(VOLATILE_REF_COST); 7082 7083 format %{ "load_fence" %} 7084 7085 ins_encode %{ 7086 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7087 %} 7088 ins_pipe(pipe_serial); 7089 %} 7090 7091 instruct unnecessary_membar_acquire() %{ 7092 predicate(unnecessary_acquire(n)); 7093 match(MemBarAcquire); 7094 ins_cost(0); 7095 7096 format %{ "membar_acquire (elided)" %} 7097 7098 ins_encode %{ 7099 __ block_comment("membar_acquire (elided)"); 7100 %} 7101 7102 ins_pipe(pipe_class_empty); 7103 %} 7104 7105 instruct membar_acquire() %{ 7106 match(MemBarAcquire); 7107 ins_cost(VOLATILE_REF_COST); 7108 7109 format %{ "membar_acquire" %} 7110 7111 ins_encode %{ 7112 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7113 %} 7114 7115 ins_pipe(pipe_serial); 7116 %} 7117 7118 7119 instruct membar_acquire_lock() %{ 7120 match(MemBarAcquireLock); 7121 ins_cost(VOLATILE_REF_COST); 7122 7123 format %{ "membar_acquire_lock" %} 7124 7125 ins_encode %{ 7126 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 7127 %} 7128 7129 ins_pipe(pipe_serial); 7130 %} 7131 7132 instruct store_fence() %{ 7133 match(StoreFence); 7134 ins_cost(VOLATILE_REF_COST); 7135 7136 format %{ "store_fence" %} 7137 7138 ins_encode %{ 7139 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7140 %} 7141 ins_pipe(pipe_serial); 7142 %} 7143 7144 instruct unnecessary_membar_release() %{ 7145 predicate(unnecessary_release(n)); 7146 match(MemBarRelease); 7147 ins_cost(0); 7148 7149 format %{ "membar_release (elided)" %} 7150 7151 ins_encode %{ 7152 __ block_comment("membar_release (elided)"); 7153 %} 7154 ins_pipe(pipe_serial); 7155 %} 7156 7157 instruct membar_release() %{ 7158 match(MemBarRelease); 7159 ins_cost(VOLATILE_REF_COST); 7160 7161 format %{ "membar_release" %} 7162 7163 ins_encode %{ 7164 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7165 %} 7166 ins_pipe(pipe_serial); 7167 %} 7168 7169 instruct membar_storestore() %{ 7170 match(MemBarStoreStore); 7171 ins_cost(VOLATILE_REF_COST); 7172 7173 format %{ "MEMBAR-store-store" %} 7174 7175 ins_encode %{ 7176 __ membar(Assembler::StoreStore); 7177 %} 7178 ins_pipe(pipe_serial); 7179 %} 7180 7181 instruct membar_release_lock() %{ 7182 match(MemBarReleaseLock); 7183 ins_cost(VOLATILE_REF_COST); 7184 7185 format %{ "membar_release_lock" %} 7186 7187 ins_encode %{ 7188 __ membar(Assembler::LoadStore|Assembler::StoreStore); 7189 %} 7190 7191 ins_pipe(pipe_serial); 7192 %} 7193 7194 instruct unnecessary_membar_volatile() %{ 7195 predicate(unnecessary_volatile(n)); 7196 match(MemBarVolatile); 7197 ins_cost(0); 7198 7199 format %{ "membar_volatile (elided)" %} 7200 7201 ins_encode %{ 7202 __ block_comment("membar_volatile (elided)"); 7203 %} 7204 7205 ins_pipe(pipe_serial); 7206 %} 7207 7208 instruct membar_volatile() %{ 7209 match(MemBarVolatile); 7210 ins_cost(VOLATILE_REF_COST*100); 7211 7212 format %{ "membar_volatile" %} 7213 7214 ins_encode %{ 7215 __ membar(Assembler::StoreLoad); 7216 %} 7217 7218 ins_pipe(pipe_serial); 7219 %} 7220 7221 // ============================================================================ 7222 // Cast/Convert Instructions 7223 7224 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 7225 match(Set dst (CastX2P src)); 7226 7227 ins_cost(INSN_COST); 7228 format %{ "mov $dst, $src\t# long -> ptr" %} 7229 7230 ins_encode %{ 7231 if ($dst$$reg != $src$$reg) { 7232 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7233 } 7234 %} 7235 7236 ins_pipe(ialu_reg); 7237 %} 7238 7239 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 7240 match(Set dst (CastP2X src)); 7241 7242 ins_cost(INSN_COST); 7243 format %{ "mov $dst, $src\t# ptr -> long" %} 7244 7245 ins_encode %{ 7246 if ($dst$$reg != $src$$reg) { 7247 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 7248 } 7249 %} 7250 7251 ins_pipe(ialu_reg); 7252 %} 7253 7254 // Convert oop into int for vectors alignment masking 7255 instruct convP2I(iRegINoSp dst, iRegP src) %{ 7256 match(Set dst (ConvL2I (CastP2X src))); 7257 7258 ins_cost(INSN_COST); 7259 format %{ "movw $dst, $src\t# ptr -> int" %} 7260 ins_encode %{ 7261 __ movw($dst$$Register, $src$$Register); 7262 %} 7263 7264 ins_pipe(ialu_reg); 7265 %} 7266 7267 // Convert compressed oop into int for vectors alignment masking 7268 // in case of 32bit oops (heap < 4Gb). 7269 instruct convN2I(iRegINoSp dst, iRegN src) 7270 %{ 7271 predicate(Universe::narrow_oop_shift() == 0); 7272 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 7273 7274 ins_cost(INSN_COST); 7275 format %{ "mov dst, $src\t# compressed ptr -> int" %} 7276 ins_encode %{ 7277 __ movw($dst$$Register, $src$$Register); 7278 %} 7279 7280 ins_pipe(ialu_reg); 7281 %} 7282 7283 7284 // Convert oop pointer into compressed form 7285 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7286 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7287 match(Set dst (EncodeP src)); 7288 effect(KILL cr); 7289 ins_cost(INSN_COST * 3); 7290 format %{ "encode_heap_oop $dst, $src" %} 7291 ins_encode %{ 7292 Register s = $src$$Register; 7293 Register d = $dst$$Register; 7294 __ encode_heap_oop(d, s); 7295 %} 7296 ins_pipe(ialu_reg); 7297 %} 7298 7299 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 7300 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7301 match(Set dst (EncodeP src)); 7302 ins_cost(INSN_COST * 3); 7303 format %{ "encode_heap_oop_not_null $dst, $src" %} 7304 ins_encode %{ 7305 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7306 %} 7307 ins_pipe(ialu_reg); 7308 %} 7309 7310 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7311 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 7312 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 7313 match(Set dst (DecodeN src)); 7314 ins_cost(INSN_COST * 3); 7315 format %{ "decode_heap_oop $dst, $src" %} 7316 ins_encode %{ 7317 Register s = $src$$Register; 7318 Register d = $dst$$Register; 7319 __ decode_heap_oop(d, s); 7320 %} 7321 ins_pipe(ialu_reg); 7322 %} 7323 7324 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 7325 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7326 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7327 match(Set dst (DecodeN src)); 7328 ins_cost(INSN_COST * 3); 7329 format %{ "decode_heap_oop_not_null $dst, $src" %} 7330 ins_encode %{ 7331 Register s = $src$$Register; 7332 Register d = $dst$$Register; 7333 __ decode_heap_oop_not_null(d, s); 7334 %} 7335 ins_pipe(ialu_reg); 7336 %} 7337 7338 // n.b. AArch64 implementations of encode_klass_not_null and 7339 // decode_klass_not_null do not modify the flags register so, unlike 7340 // Intel, we don't kill CR as a side effect here 7341 7342 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 7343 match(Set dst (EncodePKlass src)); 7344 7345 ins_cost(INSN_COST * 3); 7346 format %{ "encode_klass_not_null $dst,$src" %} 7347 7348 ins_encode %{ 7349 Register src_reg = as_Register($src$$reg); 7350 Register dst_reg = as_Register($dst$$reg); 7351 __ encode_klass_not_null(dst_reg, src_reg); 7352 %} 7353 7354 ins_pipe(ialu_reg); 7355 %} 7356 7357 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 7358 match(Set dst (DecodeNKlass src)); 7359 7360 ins_cost(INSN_COST * 3); 7361 format %{ "decode_klass_not_null $dst,$src" %} 7362 7363 ins_encode %{ 7364 Register src_reg = as_Register($src$$reg); 7365 Register dst_reg = as_Register($dst$$reg); 7366 if (dst_reg != src_reg) { 7367 __ decode_klass_not_null(dst_reg, src_reg); 7368 } else { 7369 __ decode_klass_not_null(dst_reg); 7370 } 7371 %} 7372 7373 ins_pipe(ialu_reg); 7374 %} 7375 7376 instruct checkCastPP(iRegPNoSp dst) 7377 %{ 7378 match(Set dst (CheckCastPP dst)); 7379 7380 size(0); 7381 format %{ "# checkcastPP of $dst" %} 7382 ins_encode(/* empty encoding */); 7383 ins_pipe(pipe_class_empty); 7384 %} 7385 7386 instruct castPP(iRegPNoSp dst) 7387 %{ 7388 match(Set dst (CastPP dst)); 7389 7390 size(0); 7391 format %{ "# castPP of $dst" %} 7392 ins_encode(/* empty encoding */); 7393 ins_pipe(pipe_class_empty); 7394 %} 7395 7396 instruct castII(iRegI dst) 7397 %{ 7398 match(Set dst (CastII dst)); 7399 7400 size(0); 7401 format %{ "# castII of $dst" %} 7402 ins_encode(/* empty encoding */); 7403 ins_cost(0); 7404 ins_pipe(pipe_class_empty); 7405 %} 7406 7407 // ============================================================================ 7408 // Atomic operation instructions 7409 // 7410 // Intel and SPARC both implement Ideal Node LoadPLocked and 7411 // Store{PIL}Conditional instructions using a normal load for the 7412 // LoadPLocked and a CAS for the Store{PIL}Conditional. 7413 // 7414 // The ideal code appears only to use LoadPLocked/StorePLocked as a 7415 // pair to lock object allocations from Eden space when not using 7416 // TLABs. 7417 // 7418 // There does not appear to be a Load{IL}Locked Ideal Node and the 7419 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 7420 // and to use StoreIConditional only for 32-bit and StoreLConditional 7421 // only for 64-bit. 7422 // 7423 // We implement LoadPLocked and StorePLocked instructions using, 7424 // respectively the AArch64 hw load-exclusive and store-conditional 7425 // instructions. Whereas we must implement each of 7426 // Store{IL}Conditional using a CAS which employs a pair of 7427 // instructions comprising a load-exclusive followed by a 7428 // store-conditional. 7429 7430 7431 // Locked-load (linked load) of the current heap-top 7432 // used when updating the eden heap top 7433 // implemented using ldaxr on AArch64 7434 7435 instruct loadPLocked(iRegPNoSp dst, indirect mem) 7436 %{ 7437 match(Set dst (LoadPLocked mem)); 7438 7439 ins_cost(VOLATILE_REF_COST); 7440 7441 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 7442 7443 ins_encode(aarch64_enc_ldaxr(dst, mem)); 7444 7445 ins_pipe(pipe_serial); 7446 %} 7447 7448 // Conditional-store of the updated heap-top. 7449 // Used during allocation of the shared heap. 7450 // Sets flag (EQ) on success. 7451 // implemented using stlxr on AArch64. 7452 7453 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 7454 %{ 7455 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7456 7457 ins_cost(VOLATILE_REF_COST); 7458 7459 // TODO 7460 // do we need to do a store-conditional release or can we just use a 7461 // plain store-conditional? 7462 7463 format %{ 7464 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 7465 "cmpw rscratch1, zr\t# EQ on successful write" 7466 %} 7467 7468 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 7469 7470 ins_pipe(pipe_serial); 7471 %} 7472 7473 // this has to be implemented as a CAS 7474 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 7475 %{ 7476 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7477 7478 ins_cost(VOLATILE_REF_COST); 7479 7480 format %{ 7481 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 7482 "cmpw rscratch1, zr\t# EQ on successful write" 7483 %} 7484 7485 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval)); 7486 7487 ins_pipe(pipe_slow); 7488 %} 7489 7490 // this has to be implemented as a CAS 7491 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 7492 %{ 7493 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7494 7495 ins_cost(VOLATILE_REF_COST); 7496 7497 format %{ 7498 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 7499 "cmpw rscratch1, zr\t# EQ on successful write" 7500 %} 7501 7502 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval)); 7503 7504 ins_pipe(pipe_slow); 7505 %} 7506 7507 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 7508 // can't match them 7509 7510 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 7511 7512 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 7513 7514 effect(KILL cr); 7515 7516 format %{ 7517 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 7518 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7519 %} 7520 7521 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 7522 aarch64_enc_cset_eq(res)); 7523 7524 ins_pipe(pipe_slow); 7525 %} 7526 7527 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 7528 7529 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 7530 7531 effect(KILL cr); 7532 7533 format %{ 7534 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 7535 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7536 %} 7537 7538 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 7539 aarch64_enc_cset_eq(res)); 7540 7541 ins_pipe(pipe_slow); 7542 %} 7543 7544 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 7545 7546 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 7547 7548 effect(KILL cr); 7549 7550 format %{ 7551 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 7552 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7553 %} 7554 7555 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 7556 aarch64_enc_cset_eq(res)); 7557 7558 ins_pipe(pipe_slow); 7559 %} 7560 7561 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 7562 7563 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 7564 7565 effect(KILL cr); 7566 7567 format %{ 7568 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 7569 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 7570 %} 7571 7572 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 7573 aarch64_enc_cset_eq(res)); 7574 7575 ins_pipe(pipe_slow); 7576 %} 7577 7578 7579 instruct get_and_setI(indirect mem, iRegINoSp newv, iRegI prev) %{ 7580 match(Set prev (GetAndSetI mem newv)); 7581 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 7582 ins_encode %{ 7583 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7584 %} 7585 ins_pipe(pipe_serial); 7586 %} 7587 7588 instruct get_and_setL(indirect mem, iRegLNoSp newv, iRegL prev) %{ 7589 match(Set prev (GetAndSetL mem newv)); 7590 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 7591 ins_encode %{ 7592 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7593 %} 7594 ins_pipe(pipe_serial); 7595 %} 7596 7597 instruct get_and_setN(indirect mem, iRegNNoSp newv, iRegI prev) %{ 7598 match(Set prev (GetAndSetN mem newv)); 7599 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 7600 ins_encode %{ 7601 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7602 %} 7603 ins_pipe(pipe_serial); 7604 %} 7605 7606 instruct get_and_setP(indirect mem, iRegPNoSp newv, iRegP prev) %{ 7607 match(Set prev (GetAndSetP mem newv)); 7608 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 7609 ins_encode %{ 7610 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 7611 %} 7612 ins_pipe(pipe_serial); 7613 %} 7614 7615 7616 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 7617 match(Set newval (GetAndAddL mem incr)); 7618 ins_cost(INSN_COST * 10); 7619 format %{ "get_and_addL $newval, [$mem], $incr" %} 7620 ins_encode %{ 7621 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 7622 %} 7623 ins_pipe(pipe_serial); 7624 %} 7625 7626 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 7627 predicate(n->as_LoadStore()->result_not_used()); 7628 match(Set dummy (GetAndAddL mem incr)); 7629 ins_cost(INSN_COST * 9); 7630 format %{ "get_and_addL [$mem], $incr" %} 7631 ins_encode %{ 7632 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 7633 %} 7634 ins_pipe(pipe_serial); 7635 %} 7636 7637 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 7638 match(Set newval (GetAndAddL mem incr)); 7639 ins_cost(INSN_COST * 10); 7640 format %{ "get_and_addL $newval, [$mem], $incr" %} 7641 ins_encode %{ 7642 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 7643 %} 7644 ins_pipe(pipe_serial); 7645 %} 7646 7647 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 7648 predicate(n->as_LoadStore()->result_not_used()); 7649 match(Set dummy (GetAndAddL mem incr)); 7650 ins_cost(INSN_COST * 9); 7651 format %{ "get_and_addL [$mem], $incr" %} 7652 ins_encode %{ 7653 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 7654 %} 7655 ins_pipe(pipe_serial); 7656 %} 7657 7658 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 7659 match(Set newval (GetAndAddI mem incr)); 7660 ins_cost(INSN_COST * 10); 7661 format %{ "get_and_addI $newval, [$mem], $incr" %} 7662 ins_encode %{ 7663 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 7664 %} 7665 ins_pipe(pipe_serial); 7666 %} 7667 7668 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 7669 predicate(n->as_LoadStore()->result_not_used()); 7670 match(Set dummy (GetAndAddI mem incr)); 7671 ins_cost(INSN_COST * 9); 7672 format %{ "get_and_addI [$mem], $incr" %} 7673 ins_encode %{ 7674 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 7675 %} 7676 ins_pipe(pipe_serial); 7677 %} 7678 7679 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 7680 match(Set newval (GetAndAddI mem incr)); 7681 ins_cost(INSN_COST * 10); 7682 format %{ "get_and_addI $newval, [$mem], $incr" %} 7683 ins_encode %{ 7684 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 7685 %} 7686 ins_pipe(pipe_serial); 7687 %} 7688 7689 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 7690 predicate(n->as_LoadStore()->result_not_used()); 7691 match(Set dummy (GetAndAddI mem incr)); 7692 ins_cost(INSN_COST * 9); 7693 format %{ "get_and_addI [$mem], $incr" %} 7694 ins_encode %{ 7695 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 7696 %} 7697 ins_pipe(pipe_serial); 7698 %} 7699 7700 // Manifest a CmpL result in an integer register. 7701 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 7702 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 7703 %{ 7704 match(Set dst (CmpL3 src1 src2)); 7705 effect(KILL flags); 7706 7707 ins_cost(INSN_COST * 6); 7708 format %{ 7709 "cmp $src1, $src2" 7710 "csetw $dst, ne" 7711 "cnegw $dst, lt" 7712 %} 7713 // format %{ "CmpL3 $dst, $src1, $src2" %} 7714 ins_encode %{ 7715 __ cmp($src1$$Register, $src2$$Register); 7716 __ csetw($dst$$Register, Assembler::NE); 7717 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 7718 %} 7719 7720 ins_pipe(pipe_class_default); 7721 %} 7722 7723 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 7724 %{ 7725 match(Set dst (CmpL3 src1 src2)); 7726 effect(KILL flags); 7727 7728 ins_cost(INSN_COST * 6); 7729 format %{ 7730 "cmp $src1, $src2" 7731 "csetw $dst, ne" 7732 "cnegw $dst, lt" 7733 %} 7734 ins_encode %{ 7735 int32_t con = (int32_t)$src2$$constant; 7736 if (con < 0) { 7737 __ adds(zr, $src1$$Register, -con); 7738 } else { 7739 __ subs(zr, $src1$$Register, con); 7740 } 7741 __ csetw($dst$$Register, Assembler::NE); 7742 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 7743 %} 7744 7745 ins_pipe(pipe_class_default); 7746 %} 7747 7748 // ============================================================================ 7749 // Conditional Move Instructions 7750 7751 // n.b. we have identical rules for both a signed compare op (cmpOp) 7752 // and an unsigned compare op (cmpOpU). it would be nice if we could 7753 // define an op class which merged both inputs and use it to type the 7754 // argument to a single rule. unfortunatelyt his fails because the 7755 // opclass does not live up to the COND_INTER interface of its 7756 // component operands. When the generic code tries to negate the 7757 // operand it ends up running the generci Machoper::negate method 7758 // which throws a ShouldNotHappen. So, we have to provide two flavours 7759 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 7760 7761 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7762 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 7763 7764 ins_cost(INSN_COST * 2); 7765 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 7766 7767 ins_encode %{ 7768 __ cselw(as_Register($dst$$reg), 7769 as_Register($src2$$reg), 7770 as_Register($src1$$reg), 7771 (Assembler::Condition)$cmp$$cmpcode); 7772 %} 7773 7774 ins_pipe(icond_reg_reg); 7775 %} 7776 7777 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7778 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 7779 7780 ins_cost(INSN_COST * 2); 7781 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 7782 7783 ins_encode %{ 7784 __ cselw(as_Register($dst$$reg), 7785 as_Register($src2$$reg), 7786 as_Register($src1$$reg), 7787 (Assembler::Condition)$cmp$$cmpcode); 7788 %} 7789 7790 ins_pipe(icond_reg_reg); 7791 %} 7792 7793 // special cases where one arg is zero 7794 7795 // n.b. this is selected in preference to the rule above because it 7796 // avoids loading constant 0 into a source register 7797 7798 // TODO 7799 // we ought only to be able to cull one of these variants as the ideal 7800 // transforms ought always to order the zero consistently (to left/right?) 7801 7802 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 7803 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 7804 7805 ins_cost(INSN_COST * 2); 7806 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 7807 7808 ins_encode %{ 7809 __ cselw(as_Register($dst$$reg), 7810 as_Register($src$$reg), 7811 zr, 7812 (Assembler::Condition)$cmp$$cmpcode); 7813 %} 7814 7815 ins_pipe(icond_reg); 7816 %} 7817 7818 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 7819 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 7820 7821 ins_cost(INSN_COST * 2); 7822 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 7823 7824 ins_encode %{ 7825 __ cselw(as_Register($dst$$reg), 7826 as_Register($src$$reg), 7827 zr, 7828 (Assembler::Condition)$cmp$$cmpcode); 7829 %} 7830 7831 ins_pipe(icond_reg); 7832 %} 7833 7834 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 7835 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 7836 7837 ins_cost(INSN_COST * 2); 7838 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 7839 7840 ins_encode %{ 7841 __ cselw(as_Register($dst$$reg), 7842 zr, 7843 as_Register($src$$reg), 7844 (Assembler::Condition)$cmp$$cmpcode); 7845 %} 7846 7847 ins_pipe(icond_reg); 7848 %} 7849 7850 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 7851 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 7852 7853 ins_cost(INSN_COST * 2); 7854 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 7855 7856 ins_encode %{ 7857 __ cselw(as_Register($dst$$reg), 7858 zr, 7859 as_Register($src$$reg), 7860 (Assembler::Condition)$cmp$$cmpcode); 7861 %} 7862 7863 ins_pipe(icond_reg); 7864 %} 7865 7866 // special case for creating a boolean 0 or 1 7867 7868 // n.b. this is selected in preference to the rule above because it 7869 // avoids loading constants 0 and 1 into a source register 7870 7871 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 7872 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 7873 7874 ins_cost(INSN_COST * 2); 7875 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 7876 7877 ins_encode %{ 7878 // equivalently 7879 // cset(as_Register($dst$$reg), 7880 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 7881 __ csincw(as_Register($dst$$reg), 7882 zr, 7883 zr, 7884 (Assembler::Condition)$cmp$$cmpcode); 7885 %} 7886 7887 ins_pipe(icond_none); 7888 %} 7889 7890 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 7891 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 7892 7893 ins_cost(INSN_COST * 2); 7894 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 7895 7896 ins_encode %{ 7897 // equivalently 7898 // cset(as_Register($dst$$reg), 7899 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 7900 __ csincw(as_Register($dst$$reg), 7901 zr, 7902 zr, 7903 (Assembler::Condition)$cmp$$cmpcode); 7904 %} 7905 7906 ins_pipe(icond_none); 7907 %} 7908 7909 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7910 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 7911 7912 ins_cost(INSN_COST * 2); 7913 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 7914 7915 ins_encode %{ 7916 __ csel(as_Register($dst$$reg), 7917 as_Register($src2$$reg), 7918 as_Register($src1$$reg), 7919 (Assembler::Condition)$cmp$$cmpcode); 7920 %} 7921 7922 ins_pipe(icond_reg_reg); 7923 %} 7924 7925 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7926 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 7927 7928 ins_cost(INSN_COST * 2); 7929 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 7930 7931 ins_encode %{ 7932 __ csel(as_Register($dst$$reg), 7933 as_Register($src2$$reg), 7934 as_Register($src1$$reg), 7935 (Assembler::Condition)$cmp$$cmpcode); 7936 %} 7937 7938 ins_pipe(icond_reg_reg); 7939 %} 7940 7941 // special cases where one arg is zero 7942 7943 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 7944 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 7945 7946 ins_cost(INSN_COST * 2); 7947 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 7948 7949 ins_encode %{ 7950 __ csel(as_Register($dst$$reg), 7951 zr, 7952 as_Register($src$$reg), 7953 (Assembler::Condition)$cmp$$cmpcode); 7954 %} 7955 7956 ins_pipe(icond_reg); 7957 %} 7958 7959 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 7960 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 7961 7962 ins_cost(INSN_COST * 2); 7963 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 7964 7965 ins_encode %{ 7966 __ csel(as_Register($dst$$reg), 7967 zr, 7968 as_Register($src$$reg), 7969 (Assembler::Condition)$cmp$$cmpcode); 7970 %} 7971 7972 ins_pipe(icond_reg); 7973 %} 7974 7975 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 7976 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 7977 7978 ins_cost(INSN_COST * 2); 7979 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 7980 7981 ins_encode %{ 7982 __ csel(as_Register($dst$$reg), 7983 as_Register($src$$reg), 7984 zr, 7985 (Assembler::Condition)$cmp$$cmpcode); 7986 %} 7987 7988 ins_pipe(icond_reg); 7989 %} 7990 7991 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 7992 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 7993 7994 ins_cost(INSN_COST * 2); 7995 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 7996 7997 ins_encode %{ 7998 __ csel(as_Register($dst$$reg), 7999 as_Register($src$$reg), 8000 zr, 8001 (Assembler::Condition)$cmp$$cmpcode); 8002 %} 8003 8004 ins_pipe(icond_reg); 8005 %} 8006 8007 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 8008 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 8009 8010 ins_cost(INSN_COST * 2); 8011 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 8012 8013 ins_encode %{ 8014 __ csel(as_Register($dst$$reg), 8015 as_Register($src2$$reg), 8016 as_Register($src1$$reg), 8017 (Assembler::Condition)$cmp$$cmpcode); 8018 %} 8019 8020 ins_pipe(icond_reg_reg); 8021 %} 8022 8023 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 8024 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 8025 8026 ins_cost(INSN_COST * 2); 8027 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 8028 8029 ins_encode %{ 8030 __ csel(as_Register($dst$$reg), 8031 as_Register($src2$$reg), 8032 as_Register($src1$$reg), 8033 (Assembler::Condition)$cmp$$cmpcode); 8034 %} 8035 8036 ins_pipe(icond_reg_reg); 8037 %} 8038 8039 // special cases where one arg is zero 8040 8041 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 8042 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 8043 8044 ins_cost(INSN_COST * 2); 8045 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 8046 8047 ins_encode %{ 8048 __ csel(as_Register($dst$$reg), 8049 zr, 8050 as_Register($src$$reg), 8051 (Assembler::Condition)$cmp$$cmpcode); 8052 %} 8053 8054 ins_pipe(icond_reg); 8055 %} 8056 8057 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 8058 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 8059 8060 ins_cost(INSN_COST * 2); 8061 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 8062 8063 ins_encode %{ 8064 __ csel(as_Register($dst$$reg), 8065 zr, 8066 as_Register($src$$reg), 8067 (Assembler::Condition)$cmp$$cmpcode); 8068 %} 8069 8070 ins_pipe(icond_reg); 8071 %} 8072 8073 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 8074 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 8075 8076 ins_cost(INSN_COST * 2); 8077 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 8078 8079 ins_encode %{ 8080 __ csel(as_Register($dst$$reg), 8081 as_Register($src$$reg), 8082 zr, 8083 (Assembler::Condition)$cmp$$cmpcode); 8084 %} 8085 8086 ins_pipe(icond_reg); 8087 %} 8088 8089 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 8090 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 8091 8092 ins_cost(INSN_COST * 2); 8093 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 8094 8095 ins_encode %{ 8096 __ csel(as_Register($dst$$reg), 8097 as_Register($src$$reg), 8098 zr, 8099 (Assembler::Condition)$cmp$$cmpcode); 8100 %} 8101 8102 ins_pipe(icond_reg); 8103 %} 8104 8105 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 8106 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 8107 8108 ins_cost(INSN_COST * 2); 8109 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 8110 8111 ins_encode %{ 8112 __ cselw(as_Register($dst$$reg), 8113 as_Register($src2$$reg), 8114 as_Register($src1$$reg), 8115 (Assembler::Condition)$cmp$$cmpcode); 8116 %} 8117 8118 ins_pipe(icond_reg_reg); 8119 %} 8120 8121 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 8122 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 8123 8124 ins_cost(INSN_COST * 2); 8125 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 8126 8127 ins_encode %{ 8128 __ cselw(as_Register($dst$$reg), 8129 as_Register($src2$$reg), 8130 as_Register($src1$$reg), 8131 (Assembler::Condition)$cmp$$cmpcode); 8132 %} 8133 8134 ins_pipe(icond_reg_reg); 8135 %} 8136 8137 // special cases where one arg is zero 8138 8139 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 8140 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 8141 8142 ins_cost(INSN_COST * 2); 8143 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 8144 8145 ins_encode %{ 8146 __ cselw(as_Register($dst$$reg), 8147 zr, 8148 as_Register($src$$reg), 8149 (Assembler::Condition)$cmp$$cmpcode); 8150 %} 8151 8152 ins_pipe(icond_reg); 8153 %} 8154 8155 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 8156 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 8157 8158 ins_cost(INSN_COST * 2); 8159 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 8160 8161 ins_encode %{ 8162 __ cselw(as_Register($dst$$reg), 8163 zr, 8164 as_Register($src$$reg), 8165 (Assembler::Condition)$cmp$$cmpcode); 8166 %} 8167 8168 ins_pipe(icond_reg); 8169 %} 8170 8171 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 8172 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 8173 8174 ins_cost(INSN_COST * 2); 8175 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 8176 8177 ins_encode %{ 8178 __ cselw(as_Register($dst$$reg), 8179 as_Register($src$$reg), 8180 zr, 8181 (Assembler::Condition)$cmp$$cmpcode); 8182 %} 8183 8184 ins_pipe(icond_reg); 8185 %} 8186 8187 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 8188 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 8189 8190 ins_cost(INSN_COST * 2); 8191 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 8192 8193 ins_encode %{ 8194 __ cselw(as_Register($dst$$reg), 8195 as_Register($src$$reg), 8196 zr, 8197 (Assembler::Condition)$cmp$$cmpcode); 8198 %} 8199 8200 ins_pipe(icond_reg); 8201 %} 8202 8203 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 8204 %{ 8205 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 8206 8207 ins_cost(INSN_COST * 3); 8208 8209 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 8210 ins_encode %{ 8211 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8212 __ fcsels(as_FloatRegister($dst$$reg), 8213 as_FloatRegister($src2$$reg), 8214 as_FloatRegister($src1$$reg), 8215 cond); 8216 %} 8217 8218 ins_pipe(pipe_class_default); 8219 %} 8220 8221 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 8222 %{ 8223 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 8224 8225 ins_cost(INSN_COST * 3); 8226 8227 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 8228 ins_encode %{ 8229 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8230 __ fcsels(as_FloatRegister($dst$$reg), 8231 as_FloatRegister($src2$$reg), 8232 as_FloatRegister($src1$$reg), 8233 cond); 8234 %} 8235 8236 ins_pipe(pipe_class_default); 8237 %} 8238 8239 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 8240 %{ 8241 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 8242 8243 ins_cost(INSN_COST * 3); 8244 8245 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 8246 ins_encode %{ 8247 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8248 __ fcseld(as_FloatRegister($dst$$reg), 8249 as_FloatRegister($src2$$reg), 8250 as_FloatRegister($src1$$reg), 8251 cond); 8252 %} 8253 8254 ins_pipe(pipe_class_default); 8255 %} 8256 8257 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 8258 %{ 8259 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 8260 8261 ins_cost(INSN_COST * 3); 8262 8263 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 8264 ins_encode %{ 8265 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 8266 __ fcseld(as_FloatRegister($dst$$reg), 8267 as_FloatRegister($src2$$reg), 8268 as_FloatRegister($src1$$reg), 8269 cond); 8270 %} 8271 8272 ins_pipe(pipe_class_default); 8273 %} 8274 8275 // ============================================================================ 8276 // Arithmetic Instructions 8277 // 8278 8279 // Integer Addition 8280 8281 // TODO 8282 // these currently employ operations which do not set CR and hence are 8283 // not flagged as killing CR but we would like to isolate the cases 8284 // where we want to set flags from those where we don't. need to work 8285 // out how to do that. 8286 8287 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8288 match(Set dst (AddI src1 src2)); 8289 8290 ins_cost(INSN_COST); 8291 format %{ "addw $dst, $src1, $src2" %} 8292 8293 ins_encode %{ 8294 __ addw(as_Register($dst$$reg), 8295 as_Register($src1$$reg), 8296 as_Register($src2$$reg)); 8297 %} 8298 8299 ins_pipe(ialu_reg_reg); 8300 %} 8301 8302 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 8303 match(Set dst (AddI src1 src2)); 8304 8305 ins_cost(INSN_COST); 8306 format %{ "addw $dst, $src1, $src2" %} 8307 8308 // use opcode to indicate that this is an add not a sub 8309 opcode(0x0); 8310 8311 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 8312 8313 ins_pipe(ialu_reg_imm); 8314 %} 8315 8316 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 8317 match(Set dst (AddI (ConvL2I src1) src2)); 8318 8319 ins_cost(INSN_COST); 8320 format %{ "addw $dst, $src1, $src2" %} 8321 8322 // use opcode to indicate that this is an add not a sub 8323 opcode(0x0); 8324 8325 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 8326 8327 ins_pipe(ialu_reg_imm); 8328 %} 8329 8330 // Pointer Addition 8331 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 8332 match(Set dst (AddP src1 src2)); 8333 8334 ins_cost(INSN_COST); 8335 format %{ "add $dst, $src1, $src2\t# ptr" %} 8336 8337 ins_encode %{ 8338 __ add(as_Register($dst$$reg), 8339 as_Register($src1$$reg), 8340 as_Register($src2$$reg)); 8341 %} 8342 8343 ins_pipe(ialu_reg_reg); 8344 %} 8345 8346 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 8347 match(Set dst (AddP src1 (ConvI2L src2))); 8348 8349 ins_cost(INSN_COST); 8350 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 8351 8352 ins_encode %{ 8353 __ add(as_Register($dst$$reg), 8354 as_Register($src1$$reg), 8355 as_Register($src2$$reg), ext::sxtw); 8356 %} 8357 8358 ins_pipe(ialu_reg_reg); 8359 %} 8360 8361 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 8362 match(Set dst (AddP src1 (LShiftL src2 scale))); 8363 8364 ins_cost(1.9 * INSN_COST); 8365 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 8366 8367 ins_encode %{ 8368 __ lea(as_Register($dst$$reg), 8369 Address(as_Register($src1$$reg), as_Register($src2$$reg), 8370 Address::lsl($scale$$constant))); 8371 %} 8372 8373 ins_pipe(ialu_reg_reg_shift); 8374 %} 8375 8376 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 8377 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 8378 8379 ins_cost(1.9 * INSN_COST); 8380 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 8381 8382 ins_encode %{ 8383 __ lea(as_Register($dst$$reg), 8384 Address(as_Register($src1$$reg), as_Register($src2$$reg), 8385 Address::sxtw($scale$$constant))); 8386 %} 8387 8388 ins_pipe(ialu_reg_reg_shift); 8389 %} 8390 8391 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 8392 match(Set dst (LShiftL (ConvI2L src) scale)); 8393 8394 ins_cost(INSN_COST); 8395 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 8396 8397 ins_encode %{ 8398 __ sbfiz(as_Register($dst$$reg), 8399 as_Register($src$$reg), 8400 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 8401 %} 8402 8403 ins_pipe(ialu_reg_shift); 8404 %} 8405 8406 // Pointer Immediate Addition 8407 // n.b. this needs to be more expensive than using an indirect memory 8408 // operand 8409 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 8410 match(Set dst (AddP src1 src2)); 8411 8412 ins_cost(INSN_COST); 8413 format %{ "add $dst, $src1, $src2\t# ptr" %} 8414 8415 // use opcode to indicate that this is an add not a sub 8416 opcode(0x0); 8417 8418 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 8419 8420 ins_pipe(ialu_reg_imm); 8421 %} 8422 8423 // Long Addition 8424 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8425 8426 match(Set dst (AddL src1 src2)); 8427 8428 ins_cost(INSN_COST); 8429 format %{ "add $dst, $src1, $src2" %} 8430 8431 ins_encode %{ 8432 __ add(as_Register($dst$$reg), 8433 as_Register($src1$$reg), 8434 as_Register($src2$$reg)); 8435 %} 8436 8437 ins_pipe(ialu_reg_reg); 8438 %} 8439 8440 // No constant pool entries requiredLong Immediate Addition. 8441 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 8442 match(Set dst (AddL src1 src2)); 8443 8444 ins_cost(INSN_COST); 8445 format %{ "add $dst, $src1, $src2" %} 8446 8447 // use opcode to indicate that this is an add not a sub 8448 opcode(0x0); 8449 8450 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 8451 8452 ins_pipe(ialu_reg_imm); 8453 %} 8454 8455 // Integer Subtraction 8456 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8457 match(Set dst (SubI src1 src2)); 8458 8459 ins_cost(INSN_COST); 8460 format %{ "subw $dst, $src1, $src2" %} 8461 8462 ins_encode %{ 8463 __ subw(as_Register($dst$$reg), 8464 as_Register($src1$$reg), 8465 as_Register($src2$$reg)); 8466 %} 8467 8468 ins_pipe(ialu_reg_reg); 8469 %} 8470 8471 // Immediate Subtraction 8472 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 8473 match(Set dst (SubI src1 src2)); 8474 8475 ins_cost(INSN_COST); 8476 format %{ "subw $dst, $src1, $src2" %} 8477 8478 // use opcode to indicate that this is a sub not an add 8479 opcode(0x1); 8480 8481 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 8482 8483 ins_pipe(ialu_reg_imm); 8484 %} 8485 8486 // Long Subtraction 8487 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8488 8489 match(Set dst (SubL src1 src2)); 8490 8491 ins_cost(INSN_COST); 8492 format %{ "sub $dst, $src1, $src2" %} 8493 8494 ins_encode %{ 8495 __ sub(as_Register($dst$$reg), 8496 as_Register($src1$$reg), 8497 as_Register($src2$$reg)); 8498 %} 8499 8500 ins_pipe(ialu_reg_reg); 8501 %} 8502 8503 // No constant pool entries requiredLong Immediate Subtraction. 8504 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 8505 match(Set dst (SubL src1 src2)); 8506 8507 ins_cost(INSN_COST); 8508 format %{ "sub$dst, $src1, $src2" %} 8509 8510 // use opcode to indicate that this is a sub not an add 8511 opcode(0x1); 8512 8513 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 8514 8515 ins_pipe(ialu_reg_imm); 8516 %} 8517 8518 // Integer Negation (special case for sub) 8519 8520 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 8521 match(Set dst (SubI zero src)); 8522 8523 ins_cost(INSN_COST); 8524 format %{ "negw $dst, $src\t# int" %} 8525 8526 ins_encode %{ 8527 __ negw(as_Register($dst$$reg), 8528 as_Register($src$$reg)); 8529 %} 8530 8531 ins_pipe(ialu_reg); 8532 %} 8533 8534 // Long Negation 8535 8536 instruct negL_reg(iRegLNoSp dst, iRegIorL2I src, immL0 zero, rFlagsReg cr) %{ 8537 match(Set dst (SubL zero src)); 8538 8539 ins_cost(INSN_COST); 8540 format %{ "neg $dst, $src\t# long" %} 8541 8542 ins_encode %{ 8543 __ neg(as_Register($dst$$reg), 8544 as_Register($src$$reg)); 8545 %} 8546 8547 ins_pipe(ialu_reg); 8548 %} 8549 8550 // Integer Multiply 8551 8552 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8553 match(Set dst (MulI src1 src2)); 8554 8555 ins_cost(INSN_COST * 3); 8556 format %{ "mulw $dst, $src1, $src2" %} 8557 8558 ins_encode %{ 8559 __ mulw(as_Register($dst$$reg), 8560 as_Register($src1$$reg), 8561 as_Register($src2$$reg)); 8562 %} 8563 8564 ins_pipe(imul_reg_reg); 8565 %} 8566 8567 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8568 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 8569 8570 ins_cost(INSN_COST * 3); 8571 format %{ "smull $dst, $src1, $src2" %} 8572 8573 ins_encode %{ 8574 __ smull(as_Register($dst$$reg), 8575 as_Register($src1$$reg), 8576 as_Register($src2$$reg)); 8577 %} 8578 8579 ins_pipe(imul_reg_reg); 8580 %} 8581 8582 // Long Multiply 8583 8584 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8585 match(Set dst (MulL src1 src2)); 8586 8587 ins_cost(INSN_COST * 5); 8588 format %{ "mul $dst, $src1, $src2" %} 8589 8590 ins_encode %{ 8591 __ mul(as_Register($dst$$reg), 8592 as_Register($src1$$reg), 8593 as_Register($src2$$reg)); 8594 %} 8595 8596 ins_pipe(lmul_reg_reg); 8597 %} 8598 8599 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 8600 %{ 8601 match(Set dst (MulHiL src1 src2)); 8602 8603 ins_cost(INSN_COST * 7); 8604 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 8605 8606 ins_encode %{ 8607 __ smulh(as_Register($dst$$reg), 8608 as_Register($src1$$reg), 8609 as_Register($src2$$reg)); 8610 %} 8611 8612 ins_pipe(lmul_reg_reg); 8613 %} 8614 8615 // Combined Integer Multiply & Add/Sub 8616 8617 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 8618 match(Set dst (AddI src3 (MulI src1 src2))); 8619 8620 ins_cost(INSN_COST * 3); 8621 format %{ "madd $dst, $src1, $src2, $src3" %} 8622 8623 ins_encode %{ 8624 __ maddw(as_Register($dst$$reg), 8625 as_Register($src1$$reg), 8626 as_Register($src2$$reg), 8627 as_Register($src3$$reg)); 8628 %} 8629 8630 ins_pipe(imac_reg_reg); 8631 %} 8632 8633 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 8634 match(Set dst (SubI src3 (MulI src1 src2))); 8635 8636 ins_cost(INSN_COST * 3); 8637 format %{ "msub $dst, $src1, $src2, $src3" %} 8638 8639 ins_encode %{ 8640 __ msubw(as_Register($dst$$reg), 8641 as_Register($src1$$reg), 8642 as_Register($src2$$reg), 8643 as_Register($src3$$reg)); 8644 %} 8645 8646 ins_pipe(imac_reg_reg); 8647 %} 8648 8649 // Combined Long Multiply & Add/Sub 8650 8651 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 8652 match(Set dst (AddL src3 (MulL src1 src2))); 8653 8654 ins_cost(INSN_COST * 5); 8655 format %{ "madd $dst, $src1, $src2, $src3" %} 8656 8657 ins_encode %{ 8658 __ madd(as_Register($dst$$reg), 8659 as_Register($src1$$reg), 8660 as_Register($src2$$reg), 8661 as_Register($src3$$reg)); 8662 %} 8663 8664 ins_pipe(lmac_reg_reg); 8665 %} 8666 8667 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 8668 match(Set dst (SubL src3 (MulL src1 src2))); 8669 8670 ins_cost(INSN_COST * 5); 8671 format %{ "msub $dst, $src1, $src2, $src3" %} 8672 8673 ins_encode %{ 8674 __ msub(as_Register($dst$$reg), 8675 as_Register($src1$$reg), 8676 as_Register($src2$$reg), 8677 as_Register($src3$$reg)); 8678 %} 8679 8680 ins_pipe(lmac_reg_reg); 8681 %} 8682 8683 // Integer Divide 8684 8685 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8686 match(Set dst (DivI src1 src2)); 8687 8688 ins_cost(INSN_COST * 19); 8689 format %{ "sdivw $dst, $src1, $src2" %} 8690 8691 ins_encode(aarch64_enc_divw(dst, src1, src2)); 8692 ins_pipe(idiv_reg_reg); 8693 %} 8694 8695 instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{ 8696 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 8697 ins_cost(INSN_COST); 8698 format %{ "lsrw $dst, $src1, $div1" %} 8699 ins_encode %{ 8700 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 8701 %} 8702 ins_pipe(ialu_reg_shift); 8703 %} 8704 8705 instruct div2Round(iRegINoSp dst, iRegIorL2I src, immI_31 div1, immI_31 div2) %{ 8706 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 8707 ins_cost(INSN_COST); 8708 format %{ "addw $dst, $src, LSR $div1" %} 8709 8710 ins_encode %{ 8711 __ addw(as_Register($dst$$reg), 8712 as_Register($src$$reg), 8713 as_Register($src$$reg), 8714 Assembler::LSR, 31); 8715 %} 8716 ins_pipe(ialu_reg); 8717 %} 8718 8719 // Long Divide 8720 8721 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8722 match(Set dst (DivL src1 src2)); 8723 8724 ins_cost(INSN_COST * 35); 8725 format %{ "sdiv $dst, $src1, $src2" %} 8726 8727 ins_encode(aarch64_enc_div(dst, src1, src2)); 8728 ins_pipe(ldiv_reg_reg); 8729 %} 8730 8731 instruct signExtractL(iRegLNoSp dst, iRegL src1, immL_63 div1, immL_63 div2) %{ 8732 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 8733 ins_cost(INSN_COST); 8734 format %{ "lsr $dst, $src1, $div1" %} 8735 ins_encode %{ 8736 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 8737 %} 8738 ins_pipe(ialu_reg_shift); 8739 %} 8740 8741 instruct div2RoundL(iRegLNoSp dst, iRegL src, immL_63 div1, immL_63 div2) %{ 8742 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 8743 ins_cost(INSN_COST); 8744 format %{ "add $dst, $src, $div1" %} 8745 8746 ins_encode %{ 8747 __ add(as_Register($dst$$reg), 8748 as_Register($src$$reg), 8749 as_Register($src$$reg), 8750 Assembler::LSR, 63); 8751 %} 8752 ins_pipe(ialu_reg); 8753 %} 8754 8755 // Integer Remainder 8756 8757 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8758 match(Set dst (ModI src1 src2)); 8759 8760 ins_cost(INSN_COST * 22); 8761 format %{ "sdivw rscratch1, $src1, $src2\n\t" 8762 "msubw($dst, rscratch1, $src2, $src1" %} 8763 8764 ins_encode(aarch64_enc_modw(dst, src1, src2)); 8765 ins_pipe(idiv_reg_reg); 8766 %} 8767 8768 // Long Remainder 8769 8770 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8771 match(Set dst (ModL src1 src2)); 8772 8773 ins_cost(INSN_COST * 38); 8774 format %{ "sdiv rscratch1, $src1, $src2\n" 8775 "msub($dst, rscratch1, $src2, $src1" %} 8776 8777 ins_encode(aarch64_enc_mod(dst, src1, src2)); 8778 ins_pipe(ldiv_reg_reg); 8779 %} 8780 8781 // Integer Shifts 8782 8783 // Shift Left Register 8784 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8785 match(Set dst (LShiftI src1 src2)); 8786 8787 ins_cost(INSN_COST * 2); 8788 format %{ "lslvw $dst, $src1, $src2" %} 8789 8790 ins_encode %{ 8791 __ lslvw(as_Register($dst$$reg), 8792 as_Register($src1$$reg), 8793 as_Register($src2$$reg)); 8794 %} 8795 8796 ins_pipe(ialu_reg_reg_vshift); 8797 %} 8798 8799 // Shift Left Immediate 8800 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8801 match(Set dst (LShiftI src1 src2)); 8802 8803 ins_cost(INSN_COST); 8804 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 8805 8806 ins_encode %{ 8807 __ lslw(as_Register($dst$$reg), 8808 as_Register($src1$$reg), 8809 $src2$$constant & 0x1f); 8810 %} 8811 8812 ins_pipe(ialu_reg_shift); 8813 %} 8814 8815 // Shift Right Logical Register 8816 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8817 match(Set dst (URShiftI src1 src2)); 8818 8819 ins_cost(INSN_COST * 2); 8820 format %{ "lsrvw $dst, $src1, $src2" %} 8821 8822 ins_encode %{ 8823 __ lsrvw(as_Register($dst$$reg), 8824 as_Register($src1$$reg), 8825 as_Register($src2$$reg)); 8826 %} 8827 8828 ins_pipe(ialu_reg_reg_vshift); 8829 %} 8830 8831 // Shift Right Logical Immediate 8832 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8833 match(Set dst (URShiftI src1 src2)); 8834 8835 ins_cost(INSN_COST); 8836 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 8837 8838 ins_encode %{ 8839 __ lsrw(as_Register($dst$$reg), 8840 as_Register($src1$$reg), 8841 $src2$$constant & 0x1f); 8842 %} 8843 8844 ins_pipe(ialu_reg_shift); 8845 %} 8846 8847 // Shift Right Arithmetic Register 8848 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8849 match(Set dst (RShiftI src1 src2)); 8850 8851 ins_cost(INSN_COST * 2); 8852 format %{ "asrvw $dst, $src1, $src2" %} 8853 8854 ins_encode %{ 8855 __ asrvw(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 Right Arithmetic Immediate 8864 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8865 match(Set dst (RShiftI src1 src2)); 8866 8867 ins_cost(INSN_COST); 8868 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 8869 8870 ins_encode %{ 8871 __ asrw(as_Register($dst$$reg), 8872 as_Register($src1$$reg), 8873 $src2$$constant & 0x1f); 8874 %} 8875 8876 ins_pipe(ialu_reg_shift); 8877 %} 8878 8879 // Combined Int Mask and Right Shift (using UBFM) 8880 // TODO 8881 8882 // Long Shifts 8883 8884 // Shift Left Register 8885 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 8886 match(Set dst (LShiftL src1 src2)); 8887 8888 ins_cost(INSN_COST * 2); 8889 format %{ "lslv $dst, $src1, $src2" %} 8890 8891 ins_encode %{ 8892 __ lslv(as_Register($dst$$reg), 8893 as_Register($src1$$reg), 8894 as_Register($src2$$reg)); 8895 %} 8896 8897 ins_pipe(ialu_reg_reg_vshift); 8898 %} 8899 8900 // Shift Left Immediate 8901 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 8902 match(Set dst (LShiftL src1 src2)); 8903 8904 ins_cost(INSN_COST); 8905 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 8906 8907 ins_encode %{ 8908 __ lsl(as_Register($dst$$reg), 8909 as_Register($src1$$reg), 8910 $src2$$constant & 0x3f); 8911 %} 8912 8913 ins_pipe(ialu_reg_shift); 8914 %} 8915 8916 // Shift Right Logical Register 8917 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 8918 match(Set dst (URShiftL src1 src2)); 8919 8920 ins_cost(INSN_COST * 2); 8921 format %{ "lsrv $dst, $src1, $src2" %} 8922 8923 ins_encode %{ 8924 __ lsrv(as_Register($dst$$reg), 8925 as_Register($src1$$reg), 8926 as_Register($src2$$reg)); 8927 %} 8928 8929 ins_pipe(ialu_reg_reg_vshift); 8930 %} 8931 8932 // Shift Right Logical Immediate 8933 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 8934 match(Set dst (URShiftL src1 src2)); 8935 8936 ins_cost(INSN_COST); 8937 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 8938 8939 ins_encode %{ 8940 __ lsr(as_Register($dst$$reg), 8941 as_Register($src1$$reg), 8942 $src2$$constant & 0x3f); 8943 %} 8944 8945 ins_pipe(ialu_reg_shift); 8946 %} 8947 8948 // A special-case pattern for card table stores. 8949 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 8950 match(Set dst (URShiftL (CastP2X src1) src2)); 8951 8952 ins_cost(INSN_COST); 8953 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 8954 8955 ins_encode %{ 8956 __ lsr(as_Register($dst$$reg), 8957 as_Register($src1$$reg), 8958 $src2$$constant & 0x3f); 8959 %} 8960 8961 ins_pipe(ialu_reg_shift); 8962 %} 8963 8964 // Shift Right Arithmetic Register 8965 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 8966 match(Set dst (RShiftL src1 src2)); 8967 8968 ins_cost(INSN_COST * 2); 8969 format %{ "asrv $dst, $src1, $src2" %} 8970 8971 ins_encode %{ 8972 __ asrv(as_Register($dst$$reg), 8973 as_Register($src1$$reg), 8974 as_Register($src2$$reg)); 8975 %} 8976 8977 ins_pipe(ialu_reg_reg_vshift); 8978 %} 8979 8980 // Shift Right Arithmetic Immediate 8981 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 8982 match(Set dst (RShiftL src1 src2)); 8983 8984 ins_cost(INSN_COST); 8985 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 8986 8987 ins_encode %{ 8988 __ asr(as_Register($dst$$reg), 8989 as_Register($src1$$reg), 8990 $src2$$constant & 0x3f); 8991 %} 8992 8993 ins_pipe(ialu_reg_shift); 8994 %} 8995 8996 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8997 8998 instruct regL_not_reg(iRegLNoSp dst, 8999 iRegL src1, immL_M1 m1, 9000 rFlagsReg cr) %{ 9001 match(Set dst (XorL src1 m1)); 9002 ins_cost(INSN_COST); 9003 format %{ "eon $dst, $src1, zr" %} 9004 9005 ins_encode %{ 9006 __ eon(as_Register($dst$$reg), 9007 as_Register($src1$$reg), 9008 zr, 9009 Assembler::LSL, 0); 9010 %} 9011 9012 ins_pipe(ialu_reg); 9013 %} 9014 instruct regI_not_reg(iRegINoSp dst, 9015 iRegIorL2I src1, immI_M1 m1, 9016 rFlagsReg cr) %{ 9017 match(Set dst (XorI src1 m1)); 9018 ins_cost(INSN_COST); 9019 format %{ "eonw $dst, $src1, zr" %} 9020 9021 ins_encode %{ 9022 __ eonw(as_Register($dst$$reg), 9023 as_Register($src1$$reg), 9024 zr, 9025 Assembler::LSL, 0); 9026 %} 9027 9028 ins_pipe(ialu_reg); 9029 %} 9030 9031 instruct AndI_reg_not_reg(iRegINoSp dst, 9032 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 9033 rFlagsReg cr) %{ 9034 match(Set dst (AndI src1 (XorI src2 m1))); 9035 ins_cost(INSN_COST); 9036 format %{ "bicw $dst, $src1, $src2" %} 9037 9038 ins_encode %{ 9039 __ bicw(as_Register($dst$$reg), 9040 as_Register($src1$$reg), 9041 as_Register($src2$$reg), 9042 Assembler::LSL, 0); 9043 %} 9044 9045 ins_pipe(ialu_reg_reg); 9046 %} 9047 9048 instruct AndL_reg_not_reg(iRegLNoSp dst, 9049 iRegL src1, iRegL src2, immL_M1 m1, 9050 rFlagsReg cr) %{ 9051 match(Set dst (AndL src1 (XorL src2 m1))); 9052 ins_cost(INSN_COST); 9053 format %{ "bic $dst, $src1, $src2" %} 9054 9055 ins_encode %{ 9056 __ bic(as_Register($dst$$reg), 9057 as_Register($src1$$reg), 9058 as_Register($src2$$reg), 9059 Assembler::LSL, 0); 9060 %} 9061 9062 ins_pipe(ialu_reg_reg); 9063 %} 9064 9065 instruct OrI_reg_not_reg(iRegINoSp dst, 9066 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 9067 rFlagsReg cr) %{ 9068 match(Set dst (OrI src1 (XorI src2 m1))); 9069 ins_cost(INSN_COST); 9070 format %{ "ornw $dst, $src1, $src2" %} 9071 9072 ins_encode %{ 9073 __ ornw(as_Register($dst$$reg), 9074 as_Register($src1$$reg), 9075 as_Register($src2$$reg), 9076 Assembler::LSL, 0); 9077 %} 9078 9079 ins_pipe(ialu_reg_reg); 9080 %} 9081 9082 instruct OrL_reg_not_reg(iRegLNoSp dst, 9083 iRegL src1, iRegL src2, immL_M1 m1, 9084 rFlagsReg cr) %{ 9085 match(Set dst (OrL src1 (XorL src2 m1))); 9086 ins_cost(INSN_COST); 9087 format %{ "orn $dst, $src1, $src2" %} 9088 9089 ins_encode %{ 9090 __ orn(as_Register($dst$$reg), 9091 as_Register($src1$$reg), 9092 as_Register($src2$$reg), 9093 Assembler::LSL, 0); 9094 %} 9095 9096 ins_pipe(ialu_reg_reg); 9097 %} 9098 9099 instruct XorI_reg_not_reg(iRegINoSp dst, 9100 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1, 9101 rFlagsReg cr) %{ 9102 match(Set dst (XorI m1 (XorI src2 src1))); 9103 ins_cost(INSN_COST); 9104 format %{ "eonw $dst, $src1, $src2" %} 9105 9106 ins_encode %{ 9107 __ eonw(as_Register($dst$$reg), 9108 as_Register($src1$$reg), 9109 as_Register($src2$$reg), 9110 Assembler::LSL, 0); 9111 %} 9112 9113 ins_pipe(ialu_reg_reg); 9114 %} 9115 9116 instruct XorL_reg_not_reg(iRegLNoSp dst, 9117 iRegL src1, iRegL src2, immL_M1 m1, 9118 rFlagsReg cr) %{ 9119 match(Set dst (XorL m1 (XorL src2 src1))); 9120 ins_cost(INSN_COST); 9121 format %{ "eon $dst, $src1, $src2" %} 9122 9123 ins_encode %{ 9124 __ eon(as_Register($dst$$reg), 9125 as_Register($src1$$reg), 9126 as_Register($src2$$reg), 9127 Assembler::LSL, 0); 9128 %} 9129 9130 ins_pipe(ialu_reg_reg); 9131 %} 9132 9133 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 9134 iRegIorL2I src1, iRegIorL2I src2, 9135 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9136 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 9137 ins_cost(1.9 * INSN_COST); 9138 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 9139 9140 ins_encode %{ 9141 __ bicw(as_Register($dst$$reg), 9142 as_Register($src1$$reg), 9143 as_Register($src2$$reg), 9144 Assembler::LSR, 9145 $src3$$constant & 0x3f); 9146 %} 9147 9148 ins_pipe(ialu_reg_reg_shift); 9149 %} 9150 9151 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 9152 iRegL src1, iRegL src2, 9153 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9154 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 9155 ins_cost(1.9 * INSN_COST); 9156 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 9157 9158 ins_encode %{ 9159 __ bic(as_Register($dst$$reg), 9160 as_Register($src1$$reg), 9161 as_Register($src2$$reg), 9162 Assembler::LSR, 9163 $src3$$constant & 0x3f); 9164 %} 9165 9166 ins_pipe(ialu_reg_reg_shift); 9167 %} 9168 9169 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 9170 iRegIorL2I src1, iRegIorL2I src2, 9171 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9172 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 9173 ins_cost(1.9 * INSN_COST); 9174 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 9175 9176 ins_encode %{ 9177 __ bicw(as_Register($dst$$reg), 9178 as_Register($src1$$reg), 9179 as_Register($src2$$reg), 9180 Assembler::ASR, 9181 $src3$$constant & 0x3f); 9182 %} 9183 9184 ins_pipe(ialu_reg_reg_shift); 9185 %} 9186 9187 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 9188 iRegL src1, iRegL src2, 9189 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9190 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 9191 ins_cost(1.9 * INSN_COST); 9192 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 9193 9194 ins_encode %{ 9195 __ bic(as_Register($dst$$reg), 9196 as_Register($src1$$reg), 9197 as_Register($src2$$reg), 9198 Assembler::ASR, 9199 $src3$$constant & 0x3f); 9200 %} 9201 9202 ins_pipe(ialu_reg_reg_shift); 9203 %} 9204 9205 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 9206 iRegIorL2I src1, iRegIorL2I src2, 9207 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9208 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 9209 ins_cost(1.9 * INSN_COST); 9210 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 9211 9212 ins_encode %{ 9213 __ bicw(as_Register($dst$$reg), 9214 as_Register($src1$$reg), 9215 as_Register($src2$$reg), 9216 Assembler::LSL, 9217 $src3$$constant & 0x3f); 9218 %} 9219 9220 ins_pipe(ialu_reg_reg_shift); 9221 %} 9222 9223 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 9224 iRegL src1, iRegL src2, 9225 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9226 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 9227 ins_cost(1.9 * INSN_COST); 9228 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 9229 9230 ins_encode %{ 9231 __ bic(as_Register($dst$$reg), 9232 as_Register($src1$$reg), 9233 as_Register($src2$$reg), 9234 Assembler::LSL, 9235 $src3$$constant & 0x3f); 9236 %} 9237 9238 ins_pipe(ialu_reg_reg_shift); 9239 %} 9240 9241 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 9242 iRegIorL2I src1, iRegIorL2I src2, 9243 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9244 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 9245 ins_cost(1.9 * INSN_COST); 9246 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 9247 9248 ins_encode %{ 9249 __ eonw(as_Register($dst$$reg), 9250 as_Register($src1$$reg), 9251 as_Register($src2$$reg), 9252 Assembler::LSR, 9253 $src3$$constant & 0x3f); 9254 %} 9255 9256 ins_pipe(ialu_reg_reg_shift); 9257 %} 9258 9259 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 9260 iRegL src1, iRegL src2, 9261 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9262 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 9263 ins_cost(1.9 * INSN_COST); 9264 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 9265 9266 ins_encode %{ 9267 __ eon(as_Register($dst$$reg), 9268 as_Register($src1$$reg), 9269 as_Register($src2$$reg), 9270 Assembler::LSR, 9271 $src3$$constant & 0x3f); 9272 %} 9273 9274 ins_pipe(ialu_reg_reg_shift); 9275 %} 9276 9277 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 9278 iRegIorL2I src1, iRegIorL2I src2, 9279 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9280 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 9281 ins_cost(1.9 * INSN_COST); 9282 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 9283 9284 ins_encode %{ 9285 __ eonw(as_Register($dst$$reg), 9286 as_Register($src1$$reg), 9287 as_Register($src2$$reg), 9288 Assembler::ASR, 9289 $src3$$constant & 0x3f); 9290 %} 9291 9292 ins_pipe(ialu_reg_reg_shift); 9293 %} 9294 9295 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 9296 iRegL src1, iRegL src2, 9297 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9298 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 9299 ins_cost(1.9 * INSN_COST); 9300 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 9301 9302 ins_encode %{ 9303 __ eon(as_Register($dst$$reg), 9304 as_Register($src1$$reg), 9305 as_Register($src2$$reg), 9306 Assembler::ASR, 9307 $src3$$constant & 0x3f); 9308 %} 9309 9310 ins_pipe(ialu_reg_reg_shift); 9311 %} 9312 9313 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 9314 iRegIorL2I src1, iRegIorL2I src2, 9315 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9316 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 9317 ins_cost(1.9 * INSN_COST); 9318 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 9319 9320 ins_encode %{ 9321 __ eonw(as_Register($dst$$reg), 9322 as_Register($src1$$reg), 9323 as_Register($src2$$reg), 9324 Assembler::LSL, 9325 $src3$$constant & 0x3f); 9326 %} 9327 9328 ins_pipe(ialu_reg_reg_shift); 9329 %} 9330 9331 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 9332 iRegL src1, iRegL src2, 9333 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9334 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 9335 ins_cost(1.9 * INSN_COST); 9336 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 9337 9338 ins_encode %{ 9339 __ eon(as_Register($dst$$reg), 9340 as_Register($src1$$reg), 9341 as_Register($src2$$reg), 9342 Assembler::LSL, 9343 $src3$$constant & 0x3f); 9344 %} 9345 9346 ins_pipe(ialu_reg_reg_shift); 9347 %} 9348 9349 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 9350 iRegIorL2I src1, iRegIorL2I src2, 9351 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9352 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 9353 ins_cost(1.9 * INSN_COST); 9354 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 9355 9356 ins_encode %{ 9357 __ ornw(as_Register($dst$$reg), 9358 as_Register($src1$$reg), 9359 as_Register($src2$$reg), 9360 Assembler::LSR, 9361 $src3$$constant & 0x3f); 9362 %} 9363 9364 ins_pipe(ialu_reg_reg_shift); 9365 %} 9366 9367 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 9368 iRegL src1, iRegL src2, 9369 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9370 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 9371 ins_cost(1.9 * INSN_COST); 9372 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 9373 9374 ins_encode %{ 9375 __ orn(as_Register($dst$$reg), 9376 as_Register($src1$$reg), 9377 as_Register($src2$$reg), 9378 Assembler::LSR, 9379 $src3$$constant & 0x3f); 9380 %} 9381 9382 ins_pipe(ialu_reg_reg_shift); 9383 %} 9384 9385 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 9386 iRegIorL2I src1, iRegIorL2I src2, 9387 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9388 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 9389 ins_cost(1.9 * INSN_COST); 9390 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 9391 9392 ins_encode %{ 9393 __ ornw(as_Register($dst$$reg), 9394 as_Register($src1$$reg), 9395 as_Register($src2$$reg), 9396 Assembler::ASR, 9397 $src3$$constant & 0x3f); 9398 %} 9399 9400 ins_pipe(ialu_reg_reg_shift); 9401 %} 9402 9403 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 9404 iRegL src1, iRegL src2, 9405 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9406 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 9407 ins_cost(1.9 * INSN_COST); 9408 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 9409 9410 ins_encode %{ 9411 __ orn(as_Register($dst$$reg), 9412 as_Register($src1$$reg), 9413 as_Register($src2$$reg), 9414 Assembler::ASR, 9415 $src3$$constant & 0x3f); 9416 %} 9417 9418 ins_pipe(ialu_reg_reg_shift); 9419 %} 9420 9421 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 9422 iRegIorL2I src1, iRegIorL2I src2, 9423 immI src3, immI_M1 src4, rFlagsReg cr) %{ 9424 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 9425 ins_cost(1.9 * INSN_COST); 9426 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 9427 9428 ins_encode %{ 9429 __ ornw(as_Register($dst$$reg), 9430 as_Register($src1$$reg), 9431 as_Register($src2$$reg), 9432 Assembler::LSL, 9433 $src3$$constant & 0x3f); 9434 %} 9435 9436 ins_pipe(ialu_reg_reg_shift); 9437 %} 9438 9439 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 9440 iRegL src1, iRegL src2, 9441 immI src3, immL_M1 src4, rFlagsReg cr) %{ 9442 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 9443 ins_cost(1.9 * INSN_COST); 9444 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 9445 9446 ins_encode %{ 9447 __ orn(as_Register($dst$$reg), 9448 as_Register($src1$$reg), 9449 as_Register($src2$$reg), 9450 Assembler::LSL, 9451 $src3$$constant & 0x3f); 9452 %} 9453 9454 ins_pipe(ialu_reg_reg_shift); 9455 %} 9456 9457 instruct AndI_reg_URShift_reg(iRegINoSp dst, 9458 iRegIorL2I src1, iRegIorL2I src2, 9459 immI src3, rFlagsReg cr) %{ 9460 match(Set dst (AndI src1 (URShiftI src2 src3))); 9461 9462 ins_cost(1.9 * INSN_COST); 9463 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 9464 9465 ins_encode %{ 9466 __ andw(as_Register($dst$$reg), 9467 as_Register($src1$$reg), 9468 as_Register($src2$$reg), 9469 Assembler::LSR, 9470 $src3$$constant & 0x3f); 9471 %} 9472 9473 ins_pipe(ialu_reg_reg_shift); 9474 %} 9475 9476 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 9477 iRegL src1, iRegL src2, 9478 immI src3, rFlagsReg cr) %{ 9479 match(Set dst (AndL src1 (URShiftL src2 src3))); 9480 9481 ins_cost(1.9 * INSN_COST); 9482 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 9483 9484 ins_encode %{ 9485 __ andr(as_Register($dst$$reg), 9486 as_Register($src1$$reg), 9487 as_Register($src2$$reg), 9488 Assembler::LSR, 9489 $src3$$constant & 0x3f); 9490 %} 9491 9492 ins_pipe(ialu_reg_reg_shift); 9493 %} 9494 9495 instruct AndI_reg_RShift_reg(iRegINoSp dst, 9496 iRegIorL2I src1, iRegIorL2I src2, 9497 immI src3, rFlagsReg cr) %{ 9498 match(Set dst (AndI src1 (RShiftI src2 src3))); 9499 9500 ins_cost(1.9 * INSN_COST); 9501 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 9502 9503 ins_encode %{ 9504 __ andw(as_Register($dst$$reg), 9505 as_Register($src1$$reg), 9506 as_Register($src2$$reg), 9507 Assembler::ASR, 9508 $src3$$constant & 0x3f); 9509 %} 9510 9511 ins_pipe(ialu_reg_reg_shift); 9512 %} 9513 9514 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 9515 iRegL src1, iRegL src2, 9516 immI src3, rFlagsReg cr) %{ 9517 match(Set dst (AndL src1 (RShiftL src2 src3))); 9518 9519 ins_cost(1.9 * INSN_COST); 9520 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 9521 9522 ins_encode %{ 9523 __ andr(as_Register($dst$$reg), 9524 as_Register($src1$$reg), 9525 as_Register($src2$$reg), 9526 Assembler::ASR, 9527 $src3$$constant & 0x3f); 9528 %} 9529 9530 ins_pipe(ialu_reg_reg_shift); 9531 %} 9532 9533 instruct AndI_reg_LShift_reg(iRegINoSp dst, 9534 iRegIorL2I src1, iRegIorL2I src2, 9535 immI src3, rFlagsReg cr) %{ 9536 match(Set dst (AndI src1 (LShiftI src2 src3))); 9537 9538 ins_cost(1.9 * INSN_COST); 9539 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 9540 9541 ins_encode %{ 9542 __ andw(as_Register($dst$$reg), 9543 as_Register($src1$$reg), 9544 as_Register($src2$$reg), 9545 Assembler::LSL, 9546 $src3$$constant & 0x3f); 9547 %} 9548 9549 ins_pipe(ialu_reg_reg_shift); 9550 %} 9551 9552 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 9553 iRegL src1, iRegL src2, 9554 immI src3, rFlagsReg cr) %{ 9555 match(Set dst (AndL src1 (LShiftL src2 src3))); 9556 9557 ins_cost(1.9 * INSN_COST); 9558 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 9559 9560 ins_encode %{ 9561 __ andr(as_Register($dst$$reg), 9562 as_Register($src1$$reg), 9563 as_Register($src2$$reg), 9564 Assembler::LSL, 9565 $src3$$constant & 0x3f); 9566 %} 9567 9568 ins_pipe(ialu_reg_reg_shift); 9569 %} 9570 9571 instruct XorI_reg_URShift_reg(iRegINoSp dst, 9572 iRegIorL2I src1, iRegIorL2I src2, 9573 immI src3, rFlagsReg cr) %{ 9574 match(Set dst (XorI src1 (URShiftI src2 src3))); 9575 9576 ins_cost(1.9 * INSN_COST); 9577 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 9578 9579 ins_encode %{ 9580 __ eorw(as_Register($dst$$reg), 9581 as_Register($src1$$reg), 9582 as_Register($src2$$reg), 9583 Assembler::LSR, 9584 $src3$$constant & 0x3f); 9585 %} 9586 9587 ins_pipe(ialu_reg_reg_shift); 9588 %} 9589 9590 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 9591 iRegL src1, iRegL src2, 9592 immI src3, rFlagsReg cr) %{ 9593 match(Set dst (XorL src1 (URShiftL src2 src3))); 9594 9595 ins_cost(1.9 * INSN_COST); 9596 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 9597 9598 ins_encode %{ 9599 __ eor(as_Register($dst$$reg), 9600 as_Register($src1$$reg), 9601 as_Register($src2$$reg), 9602 Assembler::LSR, 9603 $src3$$constant & 0x3f); 9604 %} 9605 9606 ins_pipe(ialu_reg_reg_shift); 9607 %} 9608 9609 instruct XorI_reg_RShift_reg(iRegINoSp dst, 9610 iRegIorL2I src1, iRegIorL2I src2, 9611 immI src3, rFlagsReg cr) %{ 9612 match(Set dst (XorI src1 (RShiftI src2 src3))); 9613 9614 ins_cost(1.9 * INSN_COST); 9615 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 9616 9617 ins_encode %{ 9618 __ eorw(as_Register($dst$$reg), 9619 as_Register($src1$$reg), 9620 as_Register($src2$$reg), 9621 Assembler::ASR, 9622 $src3$$constant & 0x3f); 9623 %} 9624 9625 ins_pipe(ialu_reg_reg_shift); 9626 %} 9627 9628 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 9629 iRegL src1, iRegL src2, 9630 immI src3, rFlagsReg cr) %{ 9631 match(Set dst (XorL src1 (RShiftL src2 src3))); 9632 9633 ins_cost(1.9 * INSN_COST); 9634 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 9635 9636 ins_encode %{ 9637 __ eor(as_Register($dst$$reg), 9638 as_Register($src1$$reg), 9639 as_Register($src2$$reg), 9640 Assembler::ASR, 9641 $src3$$constant & 0x3f); 9642 %} 9643 9644 ins_pipe(ialu_reg_reg_shift); 9645 %} 9646 9647 instruct XorI_reg_LShift_reg(iRegINoSp dst, 9648 iRegIorL2I src1, iRegIorL2I src2, 9649 immI src3, rFlagsReg cr) %{ 9650 match(Set dst (XorI src1 (LShiftI src2 src3))); 9651 9652 ins_cost(1.9 * INSN_COST); 9653 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 9654 9655 ins_encode %{ 9656 __ eorw(as_Register($dst$$reg), 9657 as_Register($src1$$reg), 9658 as_Register($src2$$reg), 9659 Assembler::LSL, 9660 $src3$$constant & 0x3f); 9661 %} 9662 9663 ins_pipe(ialu_reg_reg_shift); 9664 %} 9665 9666 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 9667 iRegL src1, iRegL src2, 9668 immI src3, rFlagsReg cr) %{ 9669 match(Set dst (XorL src1 (LShiftL src2 src3))); 9670 9671 ins_cost(1.9 * INSN_COST); 9672 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 9673 9674 ins_encode %{ 9675 __ eor(as_Register($dst$$reg), 9676 as_Register($src1$$reg), 9677 as_Register($src2$$reg), 9678 Assembler::LSL, 9679 $src3$$constant & 0x3f); 9680 %} 9681 9682 ins_pipe(ialu_reg_reg_shift); 9683 %} 9684 9685 instruct OrI_reg_URShift_reg(iRegINoSp dst, 9686 iRegIorL2I src1, iRegIorL2I src2, 9687 immI src3, rFlagsReg cr) %{ 9688 match(Set dst (OrI src1 (URShiftI src2 src3))); 9689 9690 ins_cost(1.9 * INSN_COST); 9691 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 9692 9693 ins_encode %{ 9694 __ orrw(as_Register($dst$$reg), 9695 as_Register($src1$$reg), 9696 as_Register($src2$$reg), 9697 Assembler::LSR, 9698 $src3$$constant & 0x3f); 9699 %} 9700 9701 ins_pipe(ialu_reg_reg_shift); 9702 %} 9703 9704 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 9705 iRegL src1, iRegL src2, 9706 immI src3, rFlagsReg cr) %{ 9707 match(Set dst (OrL src1 (URShiftL src2 src3))); 9708 9709 ins_cost(1.9 * INSN_COST); 9710 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 9711 9712 ins_encode %{ 9713 __ orr(as_Register($dst$$reg), 9714 as_Register($src1$$reg), 9715 as_Register($src2$$reg), 9716 Assembler::LSR, 9717 $src3$$constant & 0x3f); 9718 %} 9719 9720 ins_pipe(ialu_reg_reg_shift); 9721 %} 9722 9723 instruct OrI_reg_RShift_reg(iRegINoSp dst, 9724 iRegIorL2I src1, iRegIorL2I src2, 9725 immI src3, rFlagsReg cr) %{ 9726 match(Set dst (OrI src1 (RShiftI src2 src3))); 9727 9728 ins_cost(1.9 * INSN_COST); 9729 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 9730 9731 ins_encode %{ 9732 __ orrw(as_Register($dst$$reg), 9733 as_Register($src1$$reg), 9734 as_Register($src2$$reg), 9735 Assembler::ASR, 9736 $src3$$constant & 0x3f); 9737 %} 9738 9739 ins_pipe(ialu_reg_reg_shift); 9740 %} 9741 9742 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 9743 iRegL src1, iRegL src2, 9744 immI src3, rFlagsReg cr) %{ 9745 match(Set dst (OrL src1 (RShiftL src2 src3))); 9746 9747 ins_cost(1.9 * INSN_COST); 9748 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 9749 9750 ins_encode %{ 9751 __ orr(as_Register($dst$$reg), 9752 as_Register($src1$$reg), 9753 as_Register($src2$$reg), 9754 Assembler::ASR, 9755 $src3$$constant & 0x3f); 9756 %} 9757 9758 ins_pipe(ialu_reg_reg_shift); 9759 %} 9760 9761 instruct OrI_reg_LShift_reg(iRegINoSp dst, 9762 iRegIorL2I src1, iRegIorL2I src2, 9763 immI src3, rFlagsReg cr) %{ 9764 match(Set dst (OrI src1 (LShiftI src2 src3))); 9765 9766 ins_cost(1.9 * INSN_COST); 9767 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 9768 9769 ins_encode %{ 9770 __ orrw(as_Register($dst$$reg), 9771 as_Register($src1$$reg), 9772 as_Register($src2$$reg), 9773 Assembler::LSL, 9774 $src3$$constant & 0x3f); 9775 %} 9776 9777 ins_pipe(ialu_reg_reg_shift); 9778 %} 9779 9780 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 9781 iRegL src1, iRegL src2, 9782 immI src3, rFlagsReg cr) %{ 9783 match(Set dst (OrL src1 (LShiftL src2 src3))); 9784 9785 ins_cost(1.9 * INSN_COST); 9786 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 9787 9788 ins_encode %{ 9789 __ orr(as_Register($dst$$reg), 9790 as_Register($src1$$reg), 9791 as_Register($src2$$reg), 9792 Assembler::LSL, 9793 $src3$$constant & 0x3f); 9794 %} 9795 9796 ins_pipe(ialu_reg_reg_shift); 9797 %} 9798 9799 instruct AddI_reg_URShift_reg(iRegINoSp dst, 9800 iRegIorL2I src1, iRegIorL2I src2, 9801 immI src3, rFlagsReg cr) %{ 9802 match(Set dst (AddI src1 (URShiftI src2 src3))); 9803 9804 ins_cost(1.9 * INSN_COST); 9805 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 9806 9807 ins_encode %{ 9808 __ addw(as_Register($dst$$reg), 9809 as_Register($src1$$reg), 9810 as_Register($src2$$reg), 9811 Assembler::LSR, 9812 $src3$$constant & 0x3f); 9813 %} 9814 9815 ins_pipe(ialu_reg_reg_shift); 9816 %} 9817 9818 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 9819 iRegL src1, iRegL src2, 9820 immI src3, rFlagsReg cr) %{ 9821 match(Set dst (AddL src1 (URShiftL src2 src3))); 9822 9823 ins_cost(1.9 * INSN_COST); 9824 format %{ "add $dst, $src1, $src2, LSR $src3" %} 9825 9826 ins_encode %{ 9827 __ add(as_Register($dst$$reg), 9828 as_Register($src1$$reg), 9829 as_Register($src2$$reg), 9830 Assembler::LSR, 9831 $src3$$constant & 0x3f); 9832 %} 9833 9834 ins_pipe(ialu_reg_reg_shift); 9835 %} 9836 9837 instruct AddI_reg_RShift_reg(iRegINoSp dst, 9838 iRegIorL2I src1, iRegIorL2I src2, 9839 immI src3, rFlagsReg cr) %{ 9840 match(Set dst (AddI src1 (RShiftI src2 src3))); 9841 9842 ins_cost(1.9 * INSN_COST); 9843 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 9844 9845 ins_encode %{ 9846 __ addw(as_Register($dst$$reg), 9847 as_Register($src1$$reg), 9848 as_Register($src2$$reg), 9849 Assembler::ASR, 9850 $src3$$constant & 0x3f); 9851 %} 9852 9853 ins_pipe(ialu_reg_reg_shift); 9854 %} 9855 9856 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 9857 iRegL src1, iRegL src2, 9858 immI src3, rFlagsReg cr) %{ 9859 match(Set dst (AddL src1 (RShiftL src2 src3))); 9860 9861 ins_cost(1.9 * INSN_COST); 9862 format %{ "add $dst, $src1, $src2, ASR $src3" %} 9863 9864 ins_encode %{ 9865 __ add(as_Register($dst$$reg), 9866 as_Register($src1$$reg), 9867 as_Register($src2$$reg), 9868 Assembler::ASR, 9869 $src3$$constant & 0x3f); 9870 %} 9871 9872 ins_pipe(ialu_reg_reg_shift); 9873 %} 9874 9875 instruct AddI_reg_LShift_reg(iRegINoSp dst, 9876 iRegIorL2I src1, iRegIorL2I src2, 9877 immI src3, rFlagsReg cr) %{ 9878 match(Set dst (AddI src1 (LShiftI src2 src3))); 9879 9880 ins_cost(1.9 * INSN_COST); 9881 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 9882 9883 ins_encode %{ 9884 __ addw(as_Register($dst$$reg), 9885 as_Register($src1$$reg), 9886 as_Register($src2$$reg), 9887 Assembler::LSL, 9888 $src3$$constant & 0x3f); 9889 %} 9890 9891 ins_pipe(ialu_reg_reg_shift); 9892 %} 9893 9894 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 9895 iRegL src1, iRegL src2, 9896 immI src3, rFlagsReg cr) %{ 9897 match(Set dst (AddL src1 (LShiftL src2 src3))); 9898 9899 ins_cost(1.9 * INSN_COST); 9900 format %{ "add $dst, $src1, $src2, LSL $src3" %} 9901 9902 ins_encode %{ 9903 __ add(as_Register($dst$$reg), 9904 as_Register($src1$$reg), 9905 as_Register($src2$$reg), 9906 Assembler::LSL, 9907 $src3$$constant & 0x3f); 9908 %} 9909 9910 ins_pipe(ialu_reg_reg_shift); 9911 %} 9912 9913 instruct SubI_reg_URShift_reg(iRegINoSp dst, 9914 iRegIorL2I src1, iRegIorL2I src2, 9915 immI src3, rFlagsReg cr) %{ 9916 match(Set dst (SubI src1 (URShiftI src2 src3))); 9917 9918 ins_cost(1.9 * INSN_COST); 9919 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 9920 9921 ins_encode %{ 9922 __ subw(as_Register($dst$$reg), 9923 as_Register($src1$$reg), 9924 as_Register($src2$$reg), 9925 Assembler::LSR, 9926 $src3$$constant & 0x3f); 9927 %} 9928 9929 ins_pipe(ialu_reg_reg_shift); 9930 %} 9931 9932 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 9933 iRegL src1, iRegL src2, 9934 immI src3, rFlagsReg cr) %{ 9935 match(Set dst (SubL src1 (URShiftL src2 src3))); 9936 9937 ins_cost(1.9 * INSN_COST); 9938 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 9939 9940 ins_encode %{ 9941 __ sub(as_Register($dst$$reg), 9942 as_Register($src1$$reg), 9943 as_Register($src2$$reg), 9944 Assembler::LSR, 9945 $src3$$constant & 0x3f); 9946 %} 9947 9948 ins_pipe(ialu_reg_reg_shift); 9949 %} 9950 9951 instruct SubI_reg_RShift_reg(iRegINoSp dst, 9952 iRegIorL2I src1, iRegIorL2I src2, 9953 immI src3, rFlagsReg cr) %{ 9954 match(Set dst (SubI src1 (RShiftI src2 src3))); 9955 9956 ins_cost(1.9 * INSN_COST); 9957 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 9958 9959 ins_encode %{ 9960 __ subw(as_Register($dst$$reg), 9961 as_Register($src1$$reg), 9962 as_Register($src2$$reg), 9963 Assembler::ASR, 9964 $src3$$constant & 0x3f); 9965 %} 9966 9967 ins_pipe(ialu_reg_reg_shift); 9968 %} 9969 9970 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 9971 iRegL src1, iRegL src2, 9972 immI src3, rFlagsReg cr) %{ 9973 match(Set dst (SubL src1 (RShiftL src2 src3))); 9974 9975 ins_cost(1.9 * INSN_COST); 9976 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 9977 9978 ins_encode %{ 9979 __ sub(as_Register($dst$$reg), 9980 as_Register($src1$$reg), 9981 as_Register($src2$$reg), 9982 Assembler::ASR, 9983 $src3$$constant & 0x3f); 9984 %} 9985 9986 ins_pipe(ialu_reg_reg_shift); 9987 %} 9988 9989 instruct SubI_reg_LShift_reg(iRegINoSp dst, 9990 iRegIorL2I src1, iRegIorL2I src2, 9991 immI src3, rFlagsReg cr) %{ 9992 match(Set dst (SubI src1 (LShiftI src2 src3))); 9993 9994 ins_cost(1.9 * INSN_COST); 9995 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 9996 9997 ins_encode %{ 9998 __ subw(as_Register($dst$$reg), 9999 as_Register($src1$$reg), 10000 as_Register($src2$$reg), 10001 Assembler::LSL, 10002 $src3$$constant & 0x3f); 10003 %} 10004 10005 ins_pipe(ialu_reg_reg_shift); 10006 %} 10007 10008 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 10009 iRegL src1, iRegL src2, 10010 immI src3, rFlagsReg cr) %{ 10011 match(Set dst (SubL src1 (LShiftL src2 src3))); 10012 10013 ins_cost(1.9 * INSN_COST); 10014 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 10015 10016 ins_encode %{ 10017 __ sub(as_Register($dst$$reg), 10018 as_Register($src1$$reg), 10019 as_Register($src2$$reg), 10020 Assembler::LSL, 10021 $src3$$constant & 0x3f); 10022 %} 10023 10024 ins_pipe(ialu_reg_reg_shift); 10025 %} 10026 10027 10028 10029 // Shift Left followed by Shift Right. 10030 // This idiom is used by the compiler for the i2b bytecode etc. 10031 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 10032 %{ 10033 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 10034 // Make sure we are not going to exceed what sbfm can do. 10035 predicate((unsigned int)n->in(2)->get_int() <= 63 10036 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 10037 10038 ins_cost(INSN_COST * 2); 10039 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 10040 ins_encode %{ 10041 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10042 int s = 63 - lshift; 10043 int r = (rshift - lshift) & 63; 10044 __ sbfm(as_Register($dst$$reg), 10045 as_Register($src$$reg), 10046 r, s); 10047 %} 10048 10049 ins_pipe(ialu_reg_shift); 10050 %} 10051 10052 // Shift Left followed by Shift Right. 10053 // This idiom is used by the compiler for the i2b bytecode etc. 10054 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 10055 %{ 10056 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 10057 // Make sure we are not going to exceed what sbfmw can do. 10058 predicate((unsigned int)n->in(2)->get_int() <= 31 10059 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 10060 10061 ins_cost(INSN_COST * 2); 10062 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 10063 ins_encode %{ 10064 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10065 int s = 31 - lshift; 10066 int r = (rshift - lshift) & 31; 10067 __ sbfmw(as_Register($dst$$reg), 10068 as_Register($src$$reg), 10069 r, s); 10070 %} 10071 10072 ins_pipe(ialu_reg_shift); 10073 %} 10074 10075 // Shift Left followed by Shift Right. 10076 // This idiom is used by the compiler for the i2b bytecode etc. 10077 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 10078 %{ 10079 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 10080 // Make sure we are not going to exceed what ubfm can do. 10081 predicate((unsigned int)n->in(2)->get_int() <= 63 10082 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 10083 10084 ins_cost(INSN_COST * 2); 10085 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 10086 ins_encode %{ 10087 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10088 int s = 63 - lshift; 10089 int r = (rshift - lshift) & 63; 10090 __ ubfm(as_Register($dst$$reg), 10091 as_Register($src$$reg), 10092 r, s); 10093 %} 10094 10095 ins_pipe(ialu_reg_shift); 10096 %} 10097 10098 // Shift Left followed by Shift Right. 10099 // This idiom is used by the compiler for the i2b bytecode etc. 10100 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 10101 %{ 10102 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 10103 // Make sure we are not going to exceed what ubfmw can do. 10104 predicate((unsigned int)n->in(2)->get_int() <= 31 10105 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 10106 10107 ins_cost(INSN_COST * 2); 10108 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 10109 ins_encode %{ 10110 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 10111 int s = 31 - lshift; 10112 int r = (rshift - lshift) & 31; 10113 __ ubfmw(as_Register($dst$$reg), 10114 as_Register($src$$reg), 10115 r, s); 10116 %} 10117 10118 ins_pipe(ialu_reg_shift); 10119 %} 10120 // Bitfield extract with shift & mask 10121 10122 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 10123 %{ 10124 match(Set dst (AndI (URShiftI src rshift) mask)); 10125 10126 ins_cost(INSN_COST); 10127 format %{ "ubfxw $dst, $src, $mask" %} 10128 ins_encode %{ 10129 int rshift = $rshift$$constant; 10130 long mask = $mask$$constant; 10131 int width = exact_log2(mask+1); 10132 __ ubfxw(as_Register($dst$$reg), 10133 as_Register($src$$reg), rshift, width); 10134 %} 10135 ins_pipe(ialu_reg_shift); 10136 %} 10137 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 10138 %{ 10139 match(Set dst (AndL (URShiftL src rshift) mask)); 10140 10141 ins_cost(INSN_COST); 10142 format %{ "ubfx $dst, $src, $mask" %} 10143 ins_encode %{ 10144 int rshift = $rshift$$constant; 10145 long mask = $mask$$constant; 10146 int width = exact_log2(mask+1); 10147 __ ubfx(as_Register($dst$$reg), 10148 as_Register($src$$reg), rshift, width); 10149 %} 10150 ins_pipe(ialu_reg_shift); 10151 %} 10152 10153 // We can use ubfx when extending an And with a mask when we know mask 10154 // is positive. We know that because immI_bitmask guarantees it. 10155 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 10156 %{ 10157 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 10158 10159 ins_cost(INSN_COST * 2); 10160 format %{ "ubfx $dst, $src, $mask" %} 10161 ins_encode %{ 10162 int rshift = $rshift$$constant; 10163 long mask = $mask$$constant; 10164 int width = exact_log2(mask+1); 10165 __ ubfx(as_Register($dst$$reg), 10166 as_Register($src$$reg), rshift, width); 10167 %} 10168 ins_pipe(ialu_reg_shift); 10169 %} 10170 10171 // Rotations 10172 10173 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 10174 %{ 10175 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 10176 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 10177 10178 ins_cost(INSN_COST); 10179 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10180 10181 ins_encode %{ 10182 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10183 $rshift$$constant & 63); 10184 %} 10185 ins_pipe(ialu_reg_reg_extr); 10186 %} 10187 10188 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 10189 %{ 10190 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 10191 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 10192 10193 ins_cost(INSN_COST); 10194 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10195 10196 ins_encode %{ 10197 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10198 $rshift$$constant & 31); 10199 %} 10200 ins_pipe(ialu_reg_reg_extr); 10201 %} 10202 10203 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 10204 %{ 10205 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 10206 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 10207 10208 ins_cost(INSN_COST); 10209 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10210 10211 ins_encode %{ 10212 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10213 $rshift$$constant & 63); 10214 %} 10215 ins_pipe(ialu_reg_reg_extr); 10216 %} 10217 10218 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 10219 %{ 10220 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 10221 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 10222 10223 ins_cost(INSN_COST); 10224 format %{ "extr $dst, $src1, $src2, #$rshift" %} 10225 10226 ins_encode %{ 10227 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 10228 $rshift$$constant & 31); 10229 %} 10230 ins_pipe(ialu_reg_reg_extr); 10231 %} 10232 10233 10234 // rol expander 10235 10236 instruct rolL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 10237 %{ 10238 effect(DEF dst, USE src, USE shift); 10239 10240 format %{ "rol $dst, $src, $shift" %} 10241 ins_cost(INSN_COST * 3); 10242 ins_encode %{ 10243 __ subw(rscratch1, zr, as_Register($shift$$reg)); 10244 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 10245 rscratch1); 10246 %} 10247 ins_pipe(ialu_reg_reg_vshift); 10248 %} 10249 10250 // rol expander 10251 10252 instruct rolI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 10253 %{ 10254 effect(DEF dst, USE src, USE shift); 10255 10256 format %{ "rol $dst, $src, $shift" %} 10257 ins_cost(INSN_COST * 3); 10258 ins_encode %{ 10259 __ subw(rscratch1, zr, as_Register($shift$$reg)); 10260 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 10261 rscratch1); 10262 %} 10263 ins_pipe(ialu_reg_reg_vshift); 10264 %} 10265 10266 instruct rolL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 10267 %{ 10268 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 10269 10270 expand %{ 10271 rolL_rReg(dst, src, shift, cr); 10272 %} 10273 %} 10274 10275 instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10276 %{ 10277 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 10278 10279 expand %{ 10280 rolL_rReg(dst, src, shift, cr); 10281 %} 10282 %} 10283 10284 instruct rolI_rReg_Var_C_32(iRegLNoSp dst, iRegL src, iRegI shift, immI_32 c_32, rFlagsReg cr) 10285 %{ 10286 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 10287 10288 expand %{ 10289 rolL_rReg(dst, src, shift, cr); 10290 %} 10291 %} 10292 10293 instruct rolI_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10294 %{ 10295 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 10296 10297 expand %{ 10298 rolL_rReg(dst, src, shift, cr); 10299 %} 10300 %} 10301 10302 // ror expander 10303 10304 instruct rorL_rReg(iRegLNoSp dst, iRegL src, iRegI shift, rFlagsReg cr) 10305 %{ 10306 effect(DEF dst, USE src, USE shift); 10307 10308 format %{ "ror $dst, $src, $shift" %} 10309 ins_cost(INSN_COST); 10310 ins_encode %{ 10311 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 10312 as_Register($shift$$reg)); 10313 %} 10314 ins_pipe(ialu_reg_reg_vshift); 10315 %} 10316 10317 // ror expander 10318 10319 instruct rorI_rReg(iRegINoSp dst, iRegI src, iRegI shift, rFlagsReg cr) 10320 %{ 10321 effect(DEF dst, USE src, USE shift); 10322 10323 format %{ "ror $dst, $src, $shift" %} 10324 ins_cost(INSN_COST); 10325 ins_encode %{ 10326 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 10327 as_Register($shift$$reg)); 10328 %} 10329 ins_pipe(ialu_reg_reg_vshift); 10330 %} 10331 10332 instruct rorL_rReg_Var_C_64(iRegLNoSp dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 10333 %{ 10334 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 10335 10336 expand %{ 10337 rorL_rReg(dst, src, shift, cr); 10338 %} 10339 %} 10340 10341 instruct rorL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10342 %{ 10343 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 10344 10345 expand %{ 10346 rorL_rReg(dst, src, shift, cr); 10347 %} 10348 %} 10349 10350 instruct rorI_rReg_Var_C_32(iRegLNoSp dst, iRegL src, iRegI shift, immI_32 c_32, rFlagsReg cr) 10351 %{ 10352 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 10353 10354 expand %{ 10355 rorL_rReg(dst, src, shift, cr); 10356 %} 10357 %} 10358 10359 instruct rorI_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 10360 %{ 10361 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 10362 10363 expand %{ 10364 rorL_rReg(dst, src, shift, cr); 10365 %} 10366 %} 10367 10368 // Add/subtract (extended) 10369 10370 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 10371 %{ 10372 match(Set dst (AddL src1 (ConvI2L src2))); 10373 ins_cost(INSN_COST); 10374 format %{ "add $dst, $src1, sxtw $src2" %} 10375 10376 ins_encode %{ 10377 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10378 as_Register($src2$$reg), ext::sxtw); 10379 %} 10380 ins_pipe(ialu_reg_reg); 10381 %}; 10382 10383 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 10384 %{ 10385 match(Set dst (SubL src1 (ConvI2L src2))); 10386 ins_cost(INSN_COST); 10387 format %{ "sub $dst, $src1, sxtw $src2" %} 10388 10389 ins_encode %{ 10390 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10391 as_Register($src2$$reg), ext::sxtw); 10392 %} 10393 ins_pipe(ialu_reg_reg); 10394 %}; 10395 10396 10397 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 10398 %{ 10399 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 10400 ins_cost(INSN_COST); 10401 format %{ "add $dst, $src1, sxth $src2" %} 10402 10403 ins_encode %{ 10404 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10405 as_Register($src2$$reg), ext::sxth); 10406 %} 10407 ins_pipe(ialu_reg_reg); 10408 %} 10409 10410 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 10411 %{ 10412 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 10413 ins_cost(INSN_COST); 10414 format %{ "add $dst, $src1, sxtb $src2" %} 10415 10416 ins_encode %{ 10417 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10418 as_Register($src2$$reg), ext::sxtb); 10419 %} 10420 ins_pipe(ialu_reg_reg); 10421 %} 10422 10423 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 10424 %{ 10425 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 10426 ins_cost(INSN_COST); 10427 format %{ "add $dst, $src1, uxtb $src2" %} 10428 10429 ins_encode %{ 10430 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10431 as_Register($src2$$reg), ext::uxtb); 10432 %} 10433 ins_pipe(ialu_reg_reg); 10434 %} 10435 10436 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 10437 %{ 10438 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 10439 ins_cost(INSN_COST); 10440 format %{ "add $dst, $src1, sxth $src2" %} 10441 10442 ins_encode %{ 10443 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10444 as_Register($src2$$reg), ext::sxth); 10445 %} 10446 ins_pipe(ialu_reg_reg); 10447 %} 10448 10449 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 10450 %{ 10451 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 10452 ins_cost(INSN_COST); 10453 format %{ "add $dst, $src1, sxtw $src2" %} 10454 10455 ins_encode %{ 10456 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10457 as_Register($src2$$reg), ext::sxtw); 10458 %} 10459 ins_pipe(ialu_reg_reg); 10460 %} 10461 10462 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 10463 %{ 10464 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 10465 ins_cost(INSN_COST); 10466 format %{ "add $dst, $src1, sxtb $src2" %} 10467 10468 ins_encode %{ 10469 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10470 as_Register($src2$$reg), ext::sxtb); 10471 %} 10472 ins_pipe(ialu_reg_reg); 10473 %} 10474 10475 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 10476 %{ 10477 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 10478 ins_cost(INSN_COST); 10479 format %{ "add $dst, $src1, uxtb $src2" %} 10480 10481 ins_encode %{ 10482 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10483 as_Register($src2$$reg), ext::uxtb); 10484 %} 10485 ins_pipe(ialu_reg_reg); 10486 %} 10487 10488 10489 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 10490 %{ 10491 match(Set dst (AddI src1 (AndI src2 mask))); 10492 ins_cost(INSN_COST); 10493 format %{ "addw $dst, $src1, $src2, uxtb" %} 10494 10495 ins_encode %{ 10496 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 10497 as_Register($src2$$reg), ext::uxtb); 10498 %} 10499 ins_pipe(ialu_reg_reg); 10500 %} 10501 10502 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 10503 %{ 10504 match(Set dst (AddI src1 (AndI src2 mask))); 10505 ins_cost(INSN_COST); 10506 format %{ "addw $dst, $src1, $src2, uxth" %} 10507 10508 ins_encode %{ 10509 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 10510 as_Register($src2$$reg), ext::uxth); 10511 %} 10512 ins_pipe(ialu_reg_reg); 10513 %} 10514 10515 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 10516 %{ 10517 match(Set dst (AddL src1 (AndL src2 mask))); 10518 ins_cost(INSN_COST); 10519 format %{ "add $dst, $src1, $src2, uxtb" %} 10520 10521 ins_encode %{ 10522 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10523 as_Register($src2$$reg), ext::uxtb); 10524 %} 10525 ins_pipe(ialu_reg_reg); 10526 %} 10527 10528 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 10529 %{ 10530 match(Set dst (AddL src1 (AndL src2 mask))); 10531 ins_cost(INSN_COST); 10532 format %{ "add $dst, $src1, $src2, uxth" %} 10533 10534 ins_encode %{ 10535 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10536 as_Register($src2$$reg), ext::uxth); 10537 %} 10538 ins_pipe(ialu_reg_reg); 10539 %} 10540 10541 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 10542 %{ 10543 match(Set dst (AddL src1 (AndL src2 mask))); 10544 ins_cost(INSN_COST); 10545 format %{ "add $dst, $src1, $src2, uxtw" %} 10546 10547 ins_encode %{ 10548 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 10549 as_Register($src2$$reg), ext::uxtw); 10550 %} 10551 ins_pipe(ialu_reg_reg); 10552 %} 10553 10554 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 10555 %{ 10556 match(Set dst (SubI src1 (AndI src2 mask))); 10557 ins_cost(INSN_COST); 10558 format %{ "subw $dst, $src1, $src2, uxtb" %} 10559 10560 ins_encode %{ 10561 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 10562 as_Register($src2$$reg), ext::uxtb); 10563 %} 10564 ins_pipe(ialu_reg_reg); 10565 %} 10566 10567 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 10568 %{ 10569 match(Set dst (SubI src1 (AndI src2 mask))); 10570 ins_cost(INSN_COST); 10571 format %{ "subw $dst, $src1, $src2, uxth" %} 10572 10573 ins_encode %{ 10574 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 10575 as_Register($src2$$reg), ext::uxth); 10576 %} 10577 ins_pipe(ialu_reg_reg); 10578 %} 10579 10580 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 10581 %{ 10582 match(Set dst (SubL src1 (AndL src2 mask))); 10583 ins_cost(INSN_COST); 10584 format %{ "sub $dst, $src1, $src2, uxtb" %} 10585 10586 ins_encode %{ 10587 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10588 as_Register($src2$$reg), ext::uxtb); 10589 %} 10590 ins_pipe(ialu_reg_reg); 10591 %} 10592 10593 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 10594 %{ 10595 match(Set dst (SubL src1 (AndL src2 mask))); 10596 ins_cost(INSN_COST); 10597 format %{ "sub $dst, $src1, $src2, uxth" %} 10598 10599 ins_encode %{ 10600 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10601 as_Register($src2$$reg), ext::uxth); 10602 %} 10603 ins_pipe(ialu_reg_reg); 10604 %} 10605 10606 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 10607 %{ 10608 match(Set dst (SubL src1 (AndL src2 mask))); 10609 ins_cost(INSN_COST); 10610 format %{ "sub $dst, $src1, $src2, uxtw" %} 10611 10612 ins_encode %{ 10613 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 10614 as_Register($src2$$reg), ext::uxtw); 10615 %} 10616 ins_pipe(ialu_reg_reg); 10617 %} 10618 10619 // END This section of the file is automatically generated. Do not edit -------------- 10620 10621 // ============================================================================ 10622 // Floating Point Arithmetic Instructions 10623 10624 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 10625 match(Set dst (AddF src1 src2)); 10626 10627 ins_cost(INSN_COST * 5); 10628 format %{ "fadds $dst, $src1, $src2" %} 10629 10630 ins_encode %{ 10631 __ fadds(as_FloatRegister($dst$$reg), 10632 as_FloatRegister($src1$$reg), 10633 as_FloatRegister($src2$$reg)); 10634 %} 10635 10636 ins_pipe(pipe_class_default); 10637 %} 10638 10639 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 10640 match(Set dst (AddD src1 src2)); 10641 10642 ins_cost(INSN_COST * 5); 10643 format %{ "faddd $dst, $src1, $src2" %} 10644 10645 ins_encode %{ 10646 __ faddd(as_FloatRegister($dst$$reg), 10647 as_FloatRegister($src1$$reg), 10648 as_FloatRegister($src2$$reg)); 10649 %} 10650 10651 ins_pipe(pipe_class_default); 10652 %} 10653 10654 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 10655 match(Set dst (SubF src1 src2)); 10656 10657 ins_cost(INSN_COST * 5); 10658 format %{ "fsubs $dst, $src1, $src2" %} 10659 10660 ins_encode %{ 10661 __ fsubs(as_FloatRegister($dst$$reg), 10662 as_FloatRegister($src1$$reg), 10663 as_FloatRegister($src2$$reg)); 10664 %} 10665 10666 ins_pipe(pipe_class_default); 10667 %} 10668 10669 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 10670 match(Set dst (SubD src1 src2)); 10671 10672 ins_cost(INSN_COST * 5); 10673 format %{ "fsubd $dst, $src1, $src2" %} 10674 10675 ins_encode %{ 10676 __ fsubd(as_FloatRegister($dst$$reg), 10677 as_FloatRegister($src1$$reg), 10678 as_FloatRegister($src2$$reg)); 10679 %} 10680 10681 ins_pipe(pipe_class_default); 10682 %} 10683 10684 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 10685 match(Set dst (MulF src1 src2)); 10686 10687 ins_cost(INSN_COST * 6); 10688 format %{ "fmuls $dst, $src1, $src2" %} 10689 10690 ins_encode %{ 10691 __ fmuls(as_FloatRegister($dst$$reg), 10692 as_FloatRegister($src1$$reg), 10693 as_FloatRegister($src2$$reg)); 10694 %} 10695 10696 ins_pipe(pipe_class_default); 10697 %} 10698 10699 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 10700 match(Set dst (MulD src1 src2)); 10701 10702 ins_cost(INSN_COST * 6); 10703 format %{ "fmuld $dst, $src1, $src2" %} 10704 10705 ins_encode %{ 10706 __ fmuld(as_FloatRegister($dst$$reg), 10707 as_FloatRegister($src1$$reg), 10708 as_FloatRegister($src2$$reg)); 10709 %} 10710 10711 ins_pipe(pipe_class_default); 10712 %} 10713 10714 // We cannot use these fused mul w add/sub ops because they don't 10715 // produce the same result as the equivalent separated ops 10716 // (essentially they don't round the intermediate result). that's a 10717 // shame. leaving them here in case we can idenitfy cases where it is 10718 // legitimate to use them 10719 10720 10721 // instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 10722 // match(Set dst (AddF (MulF src1 src2) src3)); 10723 10724 // format %{ "fmadds $dst, $src1, $src2, $src3" %} 10725 10726 // ins_encode %{ 10727 // __ fmadds(as_FloatRegister($dst$$reg), 10728 // as_FloatRegister($src1$$reg), 10729 // as_FloatRegister($src2$$reg), 10730 // as_FloatRegister($src3$$reg)); 10731 // %} 10732 10733 // ins_pipe(pipe_class_default); 10734 // %} 10735 10736 // instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 10737 // match(Set dst (AddD (MulD src1 src2) src3)); 10738 10739 // format %{ "fmaddd $dst, $src1, $src2, $src3" %} 10740 10741 // ins_encode %{ 10742 // __ fmaddd(as_FloatRegister($dst$$reg), 10743 // as_FloatRegister($src1$$reg), 10744 // as_FloatRegister($src2$$reg), 10745 // as_FloatRegister($src3$$reg)); 10746 // %} 10747 10748 // ins_pipe(pipe_class_default); 10749 // %} 10750 10751 // instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 10752 // match(Set dst (AddF (MulF (NegF src1) src2) src3)); 10753 // match(Set dst (AddF (NegF (MulF src1 src2)) src3)); 10754 10755 // format %{ "fmsubs $dst, $src1, $src2, $src3" %} 10756 10757 // ins_encode %{ 10758 // __ fmsubs(as_FloatRegister($dst$$reg), 10759 // as_FloatRegister($src1$$reg), 10760 // as_FloatRegister($src2$$reg), 10761 // as_FloatRegister($src3$$reg)); 10762 // %} 10763 10764 // ins_pipe(pipe_class_default); 10765 // %} 10766 10767 // instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 10768 // match(Set dst (AddD (MulD (NegD src1) src2) src3)); 10769 // match(Set dst (AddD (NegD (MulD src1 src2)) src3)); 10770 10771 // format %{ "fmsubd $dst, $src1, $src2, $src3" %} 10772 10773 // ins_encode %{ 10774 // __ fmsubd(as_FloatRegister($dst$$reg), 10775 // as_FloatRegister($src1$$reg), 10776 // as_FloatRegister($src2$$reg), 10777 // as_FloatRegister($src3$$reg)); 10778 // %} 10779 10780 // ins_pipe(pipe_class_default); 10781 // %} 10782 10783 // instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 10784 // match(Set dst (SubF (MulF (NegF src1) src2) src3)); 10785 // match(Set dst (SubF (NegF (MulF src1 src2)) src3)); 10786 10787 // format %{ "fnmadds $dst, $src1, $src2, $src3" %} 10788 10789 // ins_encode %{ 10790 // __ fnmadds(as_FloatRegister($dst$$reg), 10791 // as_FloatRegister($src1$$reg), 10792 // as_FloatRegister($src2$$reg), 10793 // as_FloatRegister($src3$$reg)); 10794 // %} 10795 10796 // ins_pipe(pipe_class_default); 10797 // %} 10798 10799 // instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 10800 // match(Set dst (SubD (MulD (NegD src1) src2) src3)); 10801 // match(Set dst (SubD (NegD (MulD src1 src2)) src3)); 10802 10803 // format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 10804 10805 // ins_encode %{ 10806 // __ fnmaddd(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 mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 10816 // match(Set dst (SubF (MulF src1 src2) src3)); 10817 10818 // format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 10819 10820 // ins_encode %{ 10821 // __ fnmsubs(as_FloatRegister($dst$$reg), 10822 // as_FloatRegister($src1$$reg), 10823 // as_FloatRegister($src2$$reg), 10824 // as_FloatRegister($src3$$reg)); 10825 // %} 10826 10827 // ins_pipe(pipe_class_default); 10828 // %} 10829 10830 // instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 10831 // match(Set dst (SubD (MulD src1 src2) src3)); 10832 10833 // format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 10834 10835 // ins_encode %{ 10836 // // n.b. insn name should be fnmsubd 10837 // __ fnmsub(as_FloatRegister($dst$$reg), 10838 // as_FloatRegister($src1$$reg), 10839 // as_FloatRegister($src2$$reg), 10840 // as_FloatRegister($src3$$reg)); 10841 // %} 10842 10843 // ins_pipe(pipe_class_default); 10844 // %} 10845 10846 10847 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 10848 match(Set dst (DivF src1 src2)); 10849 10850 ins_cost(INSN_COST * 18); 10851 format %{ "fdivs $dst, $src1, $src2" %} 10852 10853 ins_encode %{ 10854 __ fdivs(as_FloatRegister($dst$$reg), 10855 as_FloatRegister($src1$$reg), 10856 as_FloatRegister($src2$$reg)); 10857 %} 10858 10859 ins_pipe(pipe_class_default); 10860 %} 10861 10862 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 10863 match(Set dst (DivD src1 src2)); 10864 10865 ins_cost(INSN_COST * 32); 10866 format %{ "fdivd $dst, $src1, $src2" %} 10867 10868 ins_encode %{ 10869 __ fdivd(as_FloatRegister($dst$$reg), 10870 as_FloatRegister($src1$$reg), 10871 as_FloatRegister($src2$$reg)); 10872 %} 10873 10874 ins_pipe(pipe_class_default); 10875 %} 10876 10877 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 10878 match(Set dst (NegF src)); 10879 10880 ins_cost(INSN_COST * 3); 10881 format %{ "fneg $dst, $src" %} 10882 10883 ins_encode %{ 10884 __ fnegs(as_FloatRegister($dst$$reg), 10885 as_FloatRegister($src$$reg)); 10886 %} 10887 10888 ins_pipe(pipe_class_default); 10889 %} 10890 10891 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 10892 match(Set dst (NegD src)); 10893 10894 ins_cost(INSN_COST * 3); 10895 format %{ "fnegd $dst, $src" %} 10896 10897 ins_encode %{ 10898 __ fnegd(as_FloatRegister($dst$$reg), 10899 as_FloatRegister($src$$reg)); 10900 %} 10901 10902 ins_pipe(pipe_class_default); 10903 %} 10904 10905 instruct absF_reg(vRegF dst, vRegF src) %{ 10906 match(Set dst (AbsF src)); 10907 10908 ins_cost(INSN_COST * 3); 10909 format %{ "fabss $dst, $src" %} 10910 ins_encode %{ 10911 __ fabss(as_FloatRegister($dst$$reg), 10912 as_FloatRegister($src$$reg)); 10913 %} 10914 10915 ins_pipe(pipe_class_default); 10916 %} 10917 10918 instruct absD_reg(vRegD dst, vRegD src) %{ 10919 match(Set dst (AbsD src)); 10920 10921 ins_cost(INSN_COST * 3); 10922 format %{ "fabsd $dst, $src" %} 10923 ins_encode %{ 10924 __ fabsd(as_FloatRegister($dst$$reg), 10925 as_FloatRegister($src$$reg)); 10926 %} 10927 10928 ins_pipe(pipe_class_default); 10929 %} 10930 10931 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 10932 match(Set dst (SqrtD src)); 10933 10934 ins_cost(INSN_COST * 50); 10935 format %{ "fsqrtd $dst, $src" %} 10936 ins_encode %{ 10937 __ fsqrtd(as_FloatRegister($dst$$reg), 10938 as_FloatRegister($src$$reg)); 10939 %} 10940 10941 ins_pipe(pipe_class_default); 10942 %} 10943 10944 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 10945 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 10946 10947 ins_cost(INSN_COST * 50); 10948 format %{ "fsqrts $dst, $src" %} 10949 ins_encode %{ 10950 __ fsqrts(as_FloatRegister($dst$$reg), 10951 as_FloatRegister($src$$reg)); 10952 %} 10953 10954 ins_pipe(pipe_class_default); 10955 %} 10956 10957 // ============================================================================ 10958 // Logical Instructions 10959 10960 // Integer Logical Instructions 10961 10962 // And Instructions 10963 10964 10965 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 10966 match(Set dst (AndI src1 src2)); 10967 10968 format %{ "andw $dst, $src1, $src2\t# int" %} 10969 10970 ins_cost(INSN_COST); 10971 ins_encode %{ 10972 __ andw(as_Register($dst$$reg), 10973 as_Register($src1$$reg), 10974 as_Register($src2$$reg)); 10975 %} 10976 10977 ins_pipe(ialu_reg_reg); 10978 %} 10979 10980 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 10981 match(Set dst (AndI src1 src2)); 10982 10983 format %{ "andsw $dst, $src1, $src2\t# int" %} 10984 10985 ins_cost(INSN_COST); 10986 ins_encode %{ 10987 __ andw(as_Register($dst$$reg), 10988 as_Register($src1$$reg), 10989 (unsigned long)($src2$$constant)); 10990 %} 10991 10992 ins_pipe(ialu_reg_imm); 10993 %} 10994 10995 // Or Instructions 10996 10997 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10998 match(Set dst (OrI src1 src2)); 10999 11000 format %{ "orrw $dst, $src1, $src2\t# int" %} 11001 11002 ins_cost(INSN_COST); 11003 ins_encode %{ 11004 __ orrw(as_Register($dst$$reg), 11005 as_Register($src1$$reg), 11006 as_Register($src2$$reg)); 11007 %} 11008 11009 ins_pipe(ialu_reg_reg); 11010 %} 11011 11012 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 11013 match(Set dst (OrI src1 src2)); 11014 11015 format %{ "orrw $dst, $src1, $src2\t# int" %} 11016 11017 ins_cost(INSN_COST); 11018 ins_encode %{ 11019 __ orrw(as_Register($dst$$reg), 11020 as_Register($src1$$reg), 11021 (unsigned long)($src2$$constant)); 11022 %} 11023 11024 ins_pipe(ialu_reg_imm); 11025 %} 11026 11027 // Xor Instructions 11028 11029 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 11030 match(Set dst (XorI src1 src2)); 11031 11032 format %{ "eorw $dst, $src1, $src2\t# int" %} 11033 11034 ins_cost(INSN_COST); 11035 ins_encode %{ 11036 __ eorw(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 xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 11045 match(Set dst (XorI src1 src2)); 11046 11047 format %{ "eorw $dst, $src1, $src2\t# int" %} 11048 11049 ins_cost(INSN_COST); 11050 ins_encode %{ 11051 __ eorw(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 // Long Logical Instructions 11060 // TODO 11061 11062 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 11063 match(Set dst (AndL src1 src2)); 11064 11065 format %{ "and $dst, $src1, $src2\t# int" %} 11066 11067 ins_cost(INSN_COST); 11068 ins_encode %{ 11069 __ andr(as_Register($dst$$reg), 11070 as_Register($src1$$reg), 11071 as_Register($src2$$reg)); 11072 %} 11073 11074 ins_pipe(ialu_reg_reg); 11075 %} 11076 11077 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 11078 match(Set dst (AndL src1 src2)); 11079 11080 format %{ "and $dst, $src1, $src2\t# int" %} 11081 11082 ins_cost(INSN_COST); 11083 ins_encode %{ 11084 __ andr(as_Register($dst$$reg), 11085 as_Register($src1$$reg), 11086 (unsigned long)($src2$$constant)); 11087 %} 11088 11089 ins_pipe(ialu_reg_imm); 11090 %} 11091 11092 // Or Instructions 11093 11094 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 11095 match(Set dst (OrL src1 src2)); 11096 11097 format %{ "orr $dst, $src1, $src2\t# int" %} 11098 11099 ins_cost(INSN_COST); 11100 ins_encode %{ 11101 __ orr(as_Register($dst$$reg), 11102 as_Register($src1$$reg), 11103 as_Register($src2$$reg)); 11104 %} 11105 11106 ins_pipe(ialu_reg_reg); 11107 %} 11108 11109 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 11110 match(Set dst (OrL src1 src2)); 11111 11112 format %{ "orr $dst, $src1, $src2\t# int" %} 11113 11114 ins_cost(INSN_COST); 11115 ins_encode %{ 11116 __ orr(as_Register($dst$$reg), 11117 as_Register($src1$$reg), 11118 (unsigned long)($src2$$constant)); 11119 %} 11120 11121 ins_pipe(ialu_reg_imm); 11122 %} 11123 11124 // Xor Instructions 11125 11126 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 11127 match(Set dst (XorL src1 src2)); 11128 11129 format %{ "eor $dst, $src1, $src2\t# int" %} 11130 11131 ins_cost(INSN_COST); 11132 ins_encode %{ 11133 __ eor(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 xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 11142 match(Set dst (XorL src1 src2)); 11143 11144 ins_cost(INSN_COST); 11145 format %{ "eor $dst, $src1, $src2\t# int" %} 11146 11147 ins_encode %{ 11148 __ eor(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 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 11157 %{ 11158 match(Set dst (ConvI2L src)); 11159 11160 ins_cost(INSN_COST); 11161 format %{ "sxtw $dst, $src\t# i2l" %} 11162 ins_encode %{ 11163 __ sbfm($dst$$Register, $src$$Register, 0, 31); 11164 %} 11165 ins_pipe(ialu_reg_shift); 11166 %} 11167 11168 // this pattern occurs in bigmath arithmetic 11169 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 11170 %{ 11171 match(Set dst (AndL (ConvI2L src) mask)); 11172 11173 ins_cost(INSN_COST); 11174 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 11175 ins_encode %{ 11176 __ ubfm($dst$$Register, $src$$Register, 0, 31); 11177 %} 11178 11179 ins_pipe(ialu_reg_shift); 11180 %} 11181 11182 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 11183 match(Set dst (ConvL2I src)); 11184 11185 ins_cost(INSN_COST); 11186 format %{ "movw $dst, $src \t// l2i" %} 11187 11188 ins_encode %{ 11189 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 11190 %} 11191 11192 ins_pipe(ialu_reg); 11193 %} 11194 11195 instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 11196 %{ 11197 match(Set dst (Conv2B src)); 11198 effect(KILL cr); 11199 11200 format %{ 11201 "cmpw $src, zr\n\t" 11202 "cset $dst, ne" 11203 %} 11204 11205 ins_encode %{ 11206 __ cmpw(as_Register($src$$reg), zr); 11207 __ cset(as_Register($dst$$reg), Assembler::NE); 11208 %} 11209 11210 ins_pipe(ialu_reg); 11211 %} 11212 11213 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 11214 %{ 11215 match(Set dst (Conv2B src)); 11216 effect(KILL cr); 11217 11218 format %{ 11219 "cmp $src, zr\n\t" 11220 "cset $dst, ne" 11221 %} 11222 11223 ins_encode %{ 11224 __ cmp(as_Register($src$$reg), zr); 11225 __ cset(as_Register($dst$$reg), Assembler::NE); 11226 %} 11227 11228 ins_pipe(ialu_reg); 11229 %} 11230 11231 instruct convD2F_reg(vRegF dst, vRegD src) %{ 11232 match(Set dst (ConvD2F src)); 11233 11234 ins_cost(INSN_COST * 5); 11235 format %{ "fcvtd $dst, $src \t// d2f" %} 11236 11237 ins_encode %{ 11238 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 11239 %} 11240 11241 ins_pipe(pipe_class_default); 11242 %} 11243 11244 instruct convF2D_reg(vRegD dst, vRegF src) %{ 11245 match(Set dst (ConvF2D src)); 11246 11247 ins_cost(INSN_COST * 5); 11248 format %{ "fcvts $dst, $src \t// f2d" %} 11249 11250 ins_encode %{ 11251 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 11252 %} 11253 11254 ins_pipe(pipe_class_default); 11255 %} 11256 11257 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 11258 match(Set dst (ConvF2I src)); 11259 11260 ins_cost(INSN_COST * 5); 11261 format %{ "fcvtzsw $dst, $src \t// f2i" %} 11262 11263 ins_encode %{ 11264 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11265 %} 11266 11267 ins_pipe(pipe_class_default); 11268 %} 11269 11270 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 11271 match(Set dst (ConvF2L src)); 11272 11273 ins_cost(INSN_COST * 5); 11274 format %{ "fcvtzs $dst, $src \t// f2l" %} 11275 11276 ins_encode %{ 11277 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11278 %} 11279 11280 ins_pipe(pipe_class_default); 11281 %} 11282 11283 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 11284 match(Set dst (ConvI2F src)); 11285 11286 ins_cost(INSN_COST * 5); 11287 format %{ "scvtfws $dst, $src \t// i2f" %} 11288 11289 ins_encode %{ 11290 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11291 %} 11292 11293 ins_pipe(pipe_class_default); 11294 %} 11295 11296 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 11297 match(Set dst (ConvL2F src)); 11298 11299 ins_cost(INSN_COST * 5); 11300 format %{ "scvtfs $dst, $src \t// l2f" %} 11301 11302 ins_encode %{ 11303 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11304 %} 11305 11306 ins_pipe(pipe_class_default); 11307 %} 11308 11309 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 11310 match(Set dst (ConvD2I src)); 11311 11312 ins_cost(INSN_COST * 5); 11313 format %{ "fcvtzdw $dst, $src \t// d2i" %} 11314 11315 ins_encode %{ 11316 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11317 %} 11318 11319 ins_pipe(pipe_class_default); 11320 %} 11321 11322 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 11323 match(Set dst (ConvD2L src)); 11324 11325 ins_cost(INSN_COST * 5); 11326 format %{ "fcvtzd $dst, $src \t// d2l" %} 11327 11328 ins_encode %{ 11329 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 11330 %} 11331 11332 ins_pipe(pipe_class_default); 11333 %} 11334 11335 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 11336 match(Set dst (ConvI2D src)); 11337 11338 ins_cost(INSN_COST * 5); 11339 format %{ "scvtfwd $dst, $src \t// i2d" %} 11340 11341 ins_encode %{ 11342 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11343 %} 11344 11345 ins_pipe(pipe_class_default); 11346 %} 11347 11348 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 11349 match(Set dst (ConvL2D src)); 11350 11351 ins_cost(INSN_COST * 5); 11352 format %{ "scvtfd $dst, $src \t// l2d" %} 11353 11354 ins_encode %{ 11355 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 11356 %} 11357 11358 ins_pipe(pipe_class_default); 11359 %} 11360 11361 // stack <-> reg and reg <-> reg shuffles with no conversion 11362 11363 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 11364 11365 match(Set dst (MoveF2I src)); 11366 11367 effect(DEF dst, USE src); 11368 11369 ins_cost(4 * INSN_COST); 11370 11371 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 11372 11373 ins_encode %{ 11374 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 11375 %} 11376 11377 ins_pipe(iload_reg_reg); 11378 11379 %} 11380 11381 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 11382 11383 match(Set dst (MoveI2F src)); 11384 11385 effect(DEF dst, USE src); 11386 11387 ins_cost(4 * INSN_COST); 11388 11389 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 11390 11391 ins_encode %{ 11392 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 11393 %} 11394 11395 ins_pipe(pipe_class_memory); 11396 11397 %} 11398 11399 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 11400 11401 match(Set dst (MoveD2L src)); 11402 11403 effect(DEF dst, USE src); 11404 11405 ins_cost(4 * INSN_COST); 11406 11407 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 11408 11409 ins_encode %{ 11410 __ ldr($dst$$Register, Address(sp, $src$$disp)); 11411 %} 11412 11413 ins_pipe(iload_reg_reg); 11414 11415 %} 11416 11417 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 11418 11419 match(Set dst (MoveL2D src)); 11420 11421 effect(DEF dst, USE src); 11422 11423 ins_cost(4 * INSN_COST); 11424 11425 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 11426 11427 ins_encode %{ 11428 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 11429 %} 11430 11431 ins_pipe(pipe_class_memory); 11432 11433 %} 11434 11435 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 11436 11437 match(Set dst (MoveF2I src)); 11438 11439 effect(DEF dst, USE src); 11440 11441 ins_cost(INSN_COST); 11442 11443 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 11444 11445 ins_encode %{ 11446 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 11447 %} 11448 11449 ins_pipe(pipe_class_memory); 11450 11451 %} 11452 11453 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 11454 11455 match(Set dst (MoveI2F src)); 11456 11457 effect(DEF dst, USE src); 11458 11459 ins_cost(INSN_COST); 11460 11461 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 11462 11463 ins_encode %{ 11464 __ strw($src$$Register, Address(sp, $dst$$disp)); 11465 %} 11466 11467 ins_pipe(istore_reg_reg); 11468 11469 %} 11470 11471 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 11472 11473 match(Set dst (MoveD2L src)); 11474 11475 effect(DEF dst, USE src); 11476 11477 ins_cost(INSN_COST); 11478 11479 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 11480 11481 ins_encode %{ 11482 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 11483 %} 11484 11485 ins_pipe(pipe_class_memory); 11486 11487 %} 11488 11489 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 11490 11491 match(Set dst (MoveL2D src)); 11492 11493 effect(DEF dst, USE src); 11494 11495 ins_cost(INSN_COST); 11496 11497 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 11498 11499 ins_encode %{ 11500 __ str($src$$Register, Address(sp, $dst$$disp)); 11501 %} 11502 11503 ins_pipe(istore_reg_reg); 11504 11505 %} 11506 11507 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 11508 11509 match(Set dst (MoveF2I src)); 11510 11511 effect(DEF dst, USE src); 11512 11513 ins_cost(INSN_COST); 11514 11515 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 11516 11517 ins_encode %{ 11518 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 11519 %} 11520 11521 ins_pipe(pipe_class_memory); 11522 11523 %} 11524 11525 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 11526 11527 match(Set dst (MoveI2F src)); 11528 11529 effect(DEF dst, USE src); 11530 11531 ins_cost(INSN_COST); 11532 11533 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 11534 11535 ins_encode %{ 11536 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 11537 %} 11538 11539 ins_pipe(pipe_class_memory); 11540 11541 %} 11542 11543 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 11544 11545 match(Set dst (MoveD2L src)); 11546 11547 effect(DEF dst, USE src); 11548 11549 ins_cost(INSN_COST); 11550 11551 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 11552 11553 ins_encode %{ 11554 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 11555 %} 11556 11557 ins_pipe(pipe_class_memory); 11558 11559 %} 11560 11561 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 11562 11563 match(Set dst (MoveL2D src)); 11564 11565 effect(DEF dst, USE src); 11566 11567 ins_cost(INSN_COST); 11568 11569 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 11570 11571 ins_encode %{ 11572 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 11573 %} 11574 11575 ins_pipe(pipe_class_memory); 11576 11577 %} 11578 11579 // ============================================================================ 11580 // clearing of an array 11581 11582 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 11583 %{ 11584 match(Set dummy (ClearArray cnt base)); 11585 effect(USE_KILL cnt, USE_KILL base); 11586 11587 ins_cost(4 * INSN_COST); 11588 format %{ "ClearArray $cnt, $base" %} 11589 11590 ins_encode(aarch64_enc_clear_array_reg_reg(cnt, base)); 11591 11592 ins_pipe(pipe_class_memory); 11593 %} 11594 11595 // ============================================================================ 11596 // Overflow Math Instructions 11597 11598 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 11599 %{ 11600 match(Set cr (OverflowAddI op1 op2)); 11601 11602 format %{ "cmnw $op1, $op2\t# overflow check int" %} 11603 ins_cost(INSN_COST); 11604 ins_encode %{ 11605 __ cmnw($op1$$Register, $op2$$Register); 11606 %} 11607 11608 ins_pipe(icmp_reg_reg); 11609 %} 11610 11611 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 11612 %{ 11613 match(Set cr (OverflowAddI op1 op2)); 11614 11615 format %{ "cmnw $op1, $op2\t# overflow check int" %} 11616 ins_cost(INSN_COST); 11617 ins_encode %{ 11618 __ cmnw($op1$$Register, $op2$$constant); 11619 %} 11620 11621 ins_pipe(icmp_reg_imm); 11622 %} 11623 11624 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 11625 %{ 11626 match(Set cr (OverflowAddL op1 op2)); 11627 11628 format %{ "cmn $op1, $op2\t# overflow check long" %} 11629 ins_cost(INSN_COST); 11630 ins_encode %{ 11631 __ cmn($op1$$Register, $op2$$Register); 11632 %} 11633 11634 ins_pipe(icmp_reg_reg); 11635 %} 11636 11637 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 11638 %{ 11639 match(Set cr (OverflowAddL op1 op2)); 11640 11641 format %{ "cmn $op1, $op2\t# overflow check long" %} 11642 ins_cost(INSN_COST); 11643 ins_encode %{ 11644 __ cmn($op1$$Register, $op2$$constant); 11645 %} 11646 11647 ins_pipe(icmp_reg_imm); 11648 %} 11649 11650 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 11651 %{ 11652 match(Set cr (OverflowSubI op1 op2)); 11653 11654 format %{ "cmpw $op1, $op2\t# overflow check int" %} 11655 ins_cost(INSN_COST); 11656 ins_encode %{ 11657 __ cmpw($op1$$Register, $op2$$Register); 11658 %} 11659 11660 ins_pipe(icmp_reg_reg); 11661 %} 11662 11663 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 11664 %{ 11665 match(Set cr (OverflowSubI op1 op2)); 11666 11667 format %{ "cmpw $op1, $op2\t# overflow check int" %} 11668 ins_cost(INSN_COST); 11669 ins_encode %{ 11670 __ cmpw($op1$$Register, $op2$$constant); 11671 %} 11672 11673 ins_pipe(icmp_reg_imm); 11674 %} 11675 11676 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 11677 %{ 11678 match(Set cr (OverflowSubL op1 op2)); 11679 11680 format %{ "cmp $op1, $op2\t# overflow check long" %} 11681 ins_cost(INSN_COST); 11682 ins_encode %{ 11683 __ cmp($op1$$Register, $op2$$Register); 11684 %} 11685 11686 ins_pipe(icmp_reg_reg); 11687 %} 11688 11689 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 11690 %{ 11691 match(Set cr (OverflowSubL op1 op2)); 11692 11693 format %{ "cmp $op1, $op2\t# overflow check long" %} 11694 ins_cost(INSN_COST); 11695 ins_encode %{ 11696 __ cmp($op1$$Register, $op2$$constant); 11697 %} 11698 11699 ins_pipe(icmp_reg_imm); 11700 %} 11701 11702 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 11703 %{ 11704 match(Set cr (OverflowSubI zero op1)); 11705 11706 format %{ "cmpw zr, $op1\t# overflow check int" %} 11707 ins_cost(INSN_COST); 11708 ins_encode %{ 11709 __ cmpw(zr, $op1$$Register); 11710 %} 11711 11712 ins_pipe(icmp_reg_imm); 11713 %} 11714 11715 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 11716 %{ 11717 match(Set cr (OverflowSubL zero op1)); 11718 11719 format %{ "cmp zr, $op1\t# overflow check long" %} 11720 ins_cost(INSN_COST); 11721 ins_encode %{ 11722 __ cmp(zr, $op1$$Register); 11723 %} 11724 11725 ins_pipe(icmp_reg_imm); 11726 %} 11727 11728 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 11729 %{ 11730 match(Set cr (OverflowMulI op1 op2)); 11731 11732 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 11733 "cmp rscratch1, rscratch1, sxtw\n\t" 11734 "movw rscratch1, #0x80000000\n\t" 11735 "cselw rscratch1, rscratch1, zr, NE\n\t" 11736 "cmpw rscratch1, #1" %} 11737 ins_cost(5 * INSN_COST); 11738 ins_encode %{ 11739 __ smull(rscratch1, $op1$$Register, $op2$$Register); 11740 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 11741 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 11742 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 11743 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 11744 %} 11745 11746 ins_pipe(pipe_slow); 11747 %} 11748 11749 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 11750 %{ 11751 match(If cmp (OverflowMulI op1 op2)); 11752 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 11753 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 11754 effect(USE labl, KILL cr); 11755 11756 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 11757 "cmp rscratch1, rscratch1, sxtw\n\t" 11758 "b$cmp $labl" %} 11759 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 11760 ins_encode %{ 11761 Label* L = $labl$$label; 11762 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11763 __ smull(rscratch1, $op1$$Register, $op2$$Register); 11764 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 11765 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 11766 %} 11767 11768 ins_pipe(pipe_serial); 11769 %} 11770 11771 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 11772 %{ 11773 match(Set cr (OverflowMulL op1 op2)); 11774 11775 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 11776 "smulh rscratch2, $op1, $op2\n\t" 11777 "cmp rscratch2, rscratch1, ASR #31\n\t" 11778 "movw rscratch1, #0x80000000\n\t" 11779 "cselw rscratch1, rscratch1, zr, NE\n\t" 11780 "cmpw rscratch1, #1" %} 11781 ins_cost(6 * INSN_COST); 11782 ins_encode %{ 11783 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 11784 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 11785 __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext 11786 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 11787 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 11788 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 11789 %} 11790 11791 ins_pipe(pipe_slow); 11792 %} 11793 11794 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 11795 %{ 11796 match(If cmp (OverflowMulL op1 op2)); 11797 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 11798 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 11799 effect(USE labl, KILL cr); 11800 11801 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 11802 "smulh rscratch2, $op1, $op2\n\t" 11803 "cmp rscratch2, rscratch1, ASR #31\n\t" 11804 "b$cmp $labl" %} 11805 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 11806 ins_encode %{ 11807 Label* L = $labl$$label; 11808 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11809 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 11810 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 11811 __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext 11812 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 11813 %} 11814 11815 ins_pipe(pipe_serial); 11816 %} 11817 11818 // ============================================================================ 11819 // Compare Instructions 11820 11821 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 11822 %{ 11823 match(Set cr (CmpI op1 op2)); 11824 11825 effect(DEF cr, USE op1, USE op2); 11826 11827 ins_cost(INSN_COST); 11828 format %{ "cmpw $op1, $op2" %} 11829 11830 ins_encode(aarch64_enc_cmpw(op1, op2)); 11831 11832 ins_pipe(icmp_reg_reg); 11833 %} 11834 11835 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 11836 %{ 11837 match(Set cr (CmpI op1 zero)); 11838 11839 effect(DEF cr, USE op1); 11840 11841 ins_cost(INSN_COST); 11842 format %{ "cmpw $op1, 0" %} 11843 11844 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 11845 11846 ins_pipe(icmp_reg_imm); 11847 %} 11848 11849 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 11850 %{ 11851 match(Set cr (CmpI op1 op2)); 11852 11853 effect(DEF cr, USE op1); 11854 11855 ins_cost(INSN_COST); 11856 format %{ "cmpw $op1, $op2" %} 11857 11858 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 11859 11860 ins_pipe(icmp_reg_imm); 11861 %} 11862 11863 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 11864 %{ 11865 match(Set cr (CmpI op1 op2)); 11866 11867 effect(DEF cr, USE op1); 11868 11869 ins_cost(INSN_COST * 2); 11870 format %{ "cmpw $op1, $op2" %} 11871 11872 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 11873 11874 ins_pipe(icmp_reg_imm); 11875 %} 11876 11877 // Unsigned compare Instructions; really, same as signed compare 11878 // except it should only be used to feed an If or a CMovI which takes a 11879 // cmpOpU. 11880 11881 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 11882 %{ 11883 match(Set cr (CmpU op1 op2)); 11884 11885 effect(DEF cr, USE op1, USE op2); 11886 11887 ins_cost(INSN_COST); 11888 format %{ "cmpw $op1, $op2\t# unsigned" %} 11889 11890 ins_encode(aarch64_enc_cmpw(op1, op2)); 11891 11892 ins_pipe(icmp_reg_reg); 11893 %} 11894 11895 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 11896 %{ 11897 match(Set cr (CmpU op1 zero)); 11898 11899 effect(DEF cr, USE op1); 11900 11901 ins_cost(INSN_COST); 11902 format %{ "cmpw $op1, #0\t# unsigned" %} 11903 11904 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 11905 11906 ins_pipe(icmp_reg_imm); 11907 %} 11908 11909 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 11910 %{ 11911 match(Set cr (CmpU op1 op2)); 11912 11913 effect(DEF cr, USE op1); 11914 11915 ins_cost(INSN_COST); 11916 format %{ "cmpw $op1, $op2\t# unsigned" %} 11917 11918 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 11919 11920 ins_pipe(icmp_reg_imm); 11921 %} 11922 11923 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 11924 %{ 11925 match(Set cr (CmpU op1 op2)); 11926 11927 effect(DEF cr, USE op1); 11928 11929 ins_cost(INSN_COST * 2); 11930 format %{ "cmpw $op1, $op2\t# unsigned" %} 11931 11932 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 11933 11934 ins_pipe(icmp_reg_imm); 11935 %} 11936 11937 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 11938 %{ 11939 match(Set cr (CmpL op1 op2)); 11940 11941 effect(DEF cr, USE op1, USE op2); 11942 11943 ins_cost(INSN_COST); 11944 format %{ "cmp $op1, $op2" %} 11945 11946 ins_encode(aarch64_enc_cmp(op1, op2)); 11947 11948 ins_pipe(icmp_reg_reg); 11949 %} 11950 11951 instruct compL_reg_immI0(rFlagsReg cr, iRegL op1, immI0 zero) 11952 %{ 11953 match(Set cr (CmpL op1 zero)); 11954 11955 effect(DEF cr, USE op1); 11956 11957 ins_cost(INSN_COST); 11958 format %{ "tst $op1" %} 11959 11960 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 11961 11962 ins_pipe(icmp_reg_imm); 11963 %} 11964 11965 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 11966 %{ 11967 match(Set cr (CmpL op1 op2)); 11968 11969 effect(DEF cr, USE op1); 11970 11971 ins_cost(INSN_COST); 11972 format %{ "cmp $op1, $op2" %} 11973 11974 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 11975 11976 ins_pipe(icmp_reg_imm); 11977 %} 11978 11979 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 11980 %{ 11981 match(Set cr (CmpL op1 op2)); 11982 11983 effect(DEF cr, USE op1); 11984 11985 ins_cost(INSN_COST * 2); 11986 format %{ "cmp $op1, $op2" %} 11987 11988 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 11989 11990 ins_pipe(icmp_reg_imm); 11991 %} 11992 11993 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 11994 %{ 11995 match(Set cr (CmpP op1 op2)); 11996 11997 effect(DEF cr, USE op1, USE op2); 11998 11999 ins_cost(INSN_COST); 12000 format %{ "cmp $op1, $op2\t // ptr" %} 12001 12002 ins_encode(aarch64_enc_cmpp(op1, op2)); 12003 12004 ins_pipe(icmp_reg_reg); 12005 %} 12006 12007 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 12008 %{ 12009 match(Set cr (CmpN op1 op2)); 12010 12011 effect(DEF cr, USE op1, USE op2); 12012 12013 ins_cost(INSN_COST); 12014 format %{ "cmp $op1, $op2\t // compressed ptr" %} 12015 12016 ins_encode(aarch64_enc_cmpn(op1, op2)); 12017 12018 ins_pipe(icmp_reg_reg); 12019 %} 12020 12021 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 12022 %{ 12023 match(Set cr (CmpP op1 zero)); 12024 12025 effect(DEF cr, USE op1, USE zero); 12026 12027 ins_cost(INSN_COST); 12028 format %{ "cmp $op1, 0\t // ptr" %} 12029 12030 ins_encode(aarch64_enc_testp(op1)); 12031 12032 ins_pipe(icmp_reg_imm); 12033 %} 12034 12035 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 12036 %{ 12037 match(Set cr (CmpN op1 zero)); 12038 12039 effect(DEF cr, USE op1, USE zero); 12040 12041 ins_cost(INSN_COST); 12042 format %{ "cmp $op1, 0\t // compressed ptr" %} 12043 12044 ins_encode(aarch64_enc_testn(op1)); 12045 12046 ins_pipe(icmp_reg_imm); 12047 %} 12048 12049 // FP comparisons 12050 // 12051 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 12052 // using normal cmpOp. See declaration of rFlagsReg for details. 12053 12054 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 12055 %{ 12056 match(Set cr (CmpF src1 src2)); 12057 12058 ins_cost(3 * INSN_COST); 12059 format %{ "fcmps $src1, $src2" %} 12060 12061 ins_encode %{ 12062 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 12063 %} 12064 12065 ins_pipe(pipe_class_compare); 12066 %} 12067 12068 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 12069 %{ 12070 match(Set cr (CmpF src1 src2)); 12071 12072 ins_cost(3 * INSN_COST); 12073 format %{ "fcmps $src1, 0.0" %} 12074 12075 ins_encode %{ 12076 __ fcmps(as_FloatRegister($src1$$reg), 0.0D); 12077 %} 12078 12079 ins_pipe(pipe_class_compare); 12080 %} 12081 // FROM HERE 12082 12083 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 12084 %{ 12085 match(Set cr (CmpD src1 src2)); 12086 12087 ins_cost(3 * INSN_COST); 12088 format %{ "fcmpd $src1, $src2" %} 12089 12090 ins_encode %{ 12091 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 12092 %} 12093 12094 ins_pipe(pipe_class_compare); 12095 %} 12096 12097 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 12098 %{ 12099 match(Set cr (CmpD src1 src2)); 12100 12101 ins_cost(3 * INSN_COST); 12102 format %{ "fcmpd $src1, 0.0" %} 12103 12104 ins_encode %{ 12105 __ fcmpd(as_FloatRegister($src1$$reg), 0.0D); 12106 %} 12107 12108 ins_pipe(pipe_class_compare); 12109 %} 12110 12111 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 12112 %{ 12113 match(Set dst (CmpF3 src1 src2)); 12114 effect(KILL cr); 12115 12116 ins_cost(5 * INSN_COST); 12117 format %{ "fcmps $src1, $src2\n\t" 12118 "csinvw($dst, zr, zr, eq\n\t" 12119 "csnegw($dst, $dst, $dst, lt)" 12120 %} 12121 12122 ins_encode %{ 12123 Label done; 12124 FloatRegister s1 = as_FloatRegister($src1$$reg); 12125 FloatRegister s2 = as_FloatRegister($src2$$reg); 12126 Register d = as_Register($dst$$reg); 12127 __ fcmps(s1, s2); 12128 // installs 0 if EQ else -1 12129 __ csinvw(d, zr, zr, Assembler::EQ); 12130 // keeps -1 if less or unordered else installs 1 12131 __ csnegw(d, d, d, Assembler::LT); 12132 __ bind(done); 12133 %} 12134 12135 ins_pipe(pipe_class_default); 12136 12137 %} 12138 12139 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 12140 %{ 12141 match(Set dst (CmpD3 src1 src2)); 12142 effect(KILL cr); 12143 12144 ins_cost(5 * INSN_COST); 12145 format %{ "fcmpd $src1, $src2\n\t" 12146 "csinvw($dst, zr, zr, eq\n\t" 12147 "csnegw($dst, $dst, $dst, lt)" 12148 %} 12149 12150 ins_encode %{ 12151 Label done; 12152 FloatRegister s1 = as_FloatRegister($src1$$reg); 12153 FloatRegister s2 = as_FloatRegister($src2$$reg); 12154 Register d = as_Register($dst$$reg); 12155 __ fcmpd(s1, s2); 12156 // installs 0 if EQ else -1 12157 __ csinvw(d, zr, zr, Assembler::EQ); 12158 // keeps -1 if less or unordered else installs 1 12159 __ csnegw(d, d, d, Assembler::LT); 12160 __ bind(done); 12161 %} 12162 ins_pipe(pipe_class_default); 12163 12164 %} 12165 12166 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 12167 %{ 12168 match(Set dst (CmpF3 src1 zero)); 12169 effect(KILL cr); 12170 12171 ins_cost(5 * INSN_COST); 12172 format %{ "fcmps $src1, 0.0\n\t" 12173 "csinvw($dst, zr, zr, eq\n\t" 12174 "csnegw($dst, $dst, $dst, lt)" 12175 %} 12176 12177 ins_encode %{ 12178 Label done; 12179 FloatRegister s1 = as_FloatRegister($src1$$reg); 12180 Register d = as_Register($dst$$reg); 12181 __ fcmps(s1, 0.0D); 12182 // installs 0 if EQ else -1 12183 __ csinvw(d, zr, zr, Assembler::EQ); 12184 // keeps -1 if less or unordered else installs 1 12185 __ csnegw(d, d, d, Assembler::LT); 12186 __ bind(done); 12187 %} 12188 12189 ins_pipe(pipe_class_default); 12190 12191 %} 12192 12193 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 12194 %{ 12195 match(Set dst (CmpD3 src1 zero)); 12196 effect(KILL cr); 12197 12198 ins_cost(5 * INSN_COST); 12199 format %{ "fcmpd $src1, 0.0\n\t" 12200 "csinvw($dst, zr, zr, eq\n\t" 12201 "csnegw($dst, $dst, $dst, lt)" 12202 %} 12203 12204 ins_encode %{ 12205 Label done; 12206 FloatRegister s1 = as_FloatRegister($src1$$reg); 12207 Register d = as_Register($dst$$reg); 12208 __ fcmpd(s1, 0.0D); 12209 // installs 0 if EQ else -1 12210 __ csinvw(d, zr, zr, Assembler::EQ); 12211 // keeps -1 if less or unordered else installs 1 12212 __ csnegw(d, d, d, Assembler::LT); 12213 __ bind(done); 12214 %} 12215 ins_pipe(pipe_class_default); 12216 12217 %} 12218 12219 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 12220 %{ 12221 match(Set dst (CmpLTMask p q)); 12222 effect(KILL cr); 12223 12224 ins_cost(3 * INSN_COST); 12225 12226 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 12227 "csetw $dst, lt\n\t" 12228 "subw $dst, zr, $dst" 12229 %} 12230 12231 ins_encode %{ 12232 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 12233 __ csetw(as_Register($dst$$reg), Assembler::LT); 12234 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 12235 %} 12236 12237 ins_pipe(ialu_reg_reg); 12238 %} 12239 12240 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 12241 %{ 12242 match(Set dst (CmpLTMask src zero)); 12243 effect(KILL cr); 12244 12245 ins_cost(INSN_COST); 12246 12247 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 12248 12249 ins_encode %{ 12250 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 12251 %} 12252 12253 ins_pipe(ialu_reg_shift); 12254 %} 12255 12256 // ============================================================================ 12257 // Max and Min 12258 12259 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 12260 %{ 12261 match(Set dst (MinI src1 src2)); 12262 12263 effect(DEF dst, USE src1, USE src2, KILL cr); 12264 size(8); 12265 12266 ins_cost(INSN_COST * 3); 12267 format %{ 12268 "cmpw $src1 $src2\t signed int\n\t" 12269 "cselw $dst, $src1, $src2 lt\t" 12270 %} 12271 12272 ins_encode %{ 12273 __ cmpw(as_Register($src1$$reg), 12274 as_Register($src2$$reg)); 12275 __ cselw(as_Register($dst$$reg), 12276 as_Register($src1$$reg), 12277 as_Register($src2$$reg), 12278 Assembler::LT); 12279 %} 12280 12281 ins_pipe(ialu_reg_reg); 12282 %} 12283 // FROM HERE 12284 12285 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 12286 %{ 12287 match(Set dst (MaxI src1 src2)); 12288 12289 effect(DEF dst, USE src1, USE src2, KILL cr); 12290 size(8); 12291 12292 ins_cost(INSN_COST * 3); 12293 format %{ 12294 "cmpw $src1 $src2\t signed int\n\t" 12295 "cselw $dst, $src1, $src2 gt\t" 12296 %} 12297 12298 ins_encode %{ 12299 __ cmpw(as_Register($src1$$reg), 12300 as_Register($src2$$reg)); 12301 __ cselw(as_Register($dst$$reg), 12302 as_Register($src1$$reg), 12303 as_Register($src2$$reg), 12304 Assembler::GT); 12305 %} 12306 12307 ins_pipe(ialu_reg_reg); 12308 %} 12309 12310 // ============================================================================ 12311 // Branch Instructions 12312 12313 // Direct Branch. 12314 instruct branch(label lbl) 12315 %{ 12316 match(Goto); 12317 12318 effect(USE lbl); 12319 12320 ins_cost(BRANCH_COST); 12321 format %{ "b $lbl" %} 12322 12323 ins_encode(aarch64_enc_b(lbl)); 12324 12325 ins_pipe(pipe_branch); 12326 %} 12327 12328 // Conditional Near Branch 12329 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 12330 %{ 12331 // Same match rule as `branchConFar'. 12332 match(If cmp cr); 12333 12334 effect(USE lbl); 12335 12336 ins_cost(BRANCH_COST); 12337 // If set to 1 this indicates that the current instruction is a 12338 // short variant of a long branch. This avoids using this 12339 // instruction in first-pass matching. It will then only be used in 12340 // the `Shorten_branches' pass. 12341 // ins_short_branch(1); 12342 format %{ "b$cmp $lbl" %} 12343 12344 ins_encode(aarch64_enc_br_con(cmp, lbl)); 12345 12346 ins_pipe(pipe_branch_cond); 12347 %} 12348 12349 // Conditional Near Branch Unsigned 12350 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 12351 %{ 12352 // Same match rule as `branchConFar'. 12353 match(If cmp cr); 12354 12355 effect(USE lbl); 12356 12357 ins_cost(BRANCH_COST); 12358 // If set to 1 this indicates that the current instruction is a 12359 // short variant of a long branch. This avoids using this 12360 // instruction in first-pass matching. It will then only be used in 12361 // the `Shorten_branches' pass. 12362 // ins_short_branch(1); 12363 format %{ "b$cmp $lbl\t# unsigned" %} 12364 12365 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 12366 12367 ins_pipe(pipe_branch_cond); 12368 %} 12369 12370 // Make use of CBZ and CBNZ. These instructions, as well as being 12371 // shorter than (cmp; branch), have the additional benefit of not 12372 // killing the flags. 12373 12374 instruct cmpI_imm0_branch(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 12375 match(If cmp (CmpI op1 op2)); 12376 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 12377 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 12378 effect(USE labl); 12379 12380 ins_cost(BRANCH_COST); 12381 format %{ "cbw$cmp $op1, $labl" %} 12382 ins_encode %{ 12383 Label* L = $labl$$label; 12384 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 12385 if (cond == Assembler::EQ) 12386 __ cbzw($op1$$Register, *L); 12387 else 12388 __ cbnzw($op1$$Register, *L); 12389 %} 12390 ins_pipe(pipe_cmp_branch); 12391 %} 12392 12393 instruct cmpL_imm0_branch(cmpOp cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 12394 match(If cmp (CmpL op1 op2)); 12395 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 12396 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 12397 effect(USE labl); 12398 12399 ins_cost(BRANCH_COST); 12400 format %{ "cb$cmp $op1, $labl" %} 12401 ins_encode %{ 12402 Label* L = $labl$$label; 12403 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 12404 if (cond == Assembler::EQ) 12405 __ cbz($op1$$Register, *L); 12406 else 12407 __ cbnz($op1$$Register, *L); 12408 %} 12409 ins_pipe(pipe_cmp_branch); 12410 %} 12411 12412 instruct cmpP_imm0_branch(cmpOp cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 12413 match(If cmp (CmpP op1 op2)); 12414 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 12415 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 12416 effect(USE labl); 12417 12418 ins_cost(BRANCH_COST); 12419 format %{ "cb$cmp $op1, $labl" %} 12420 ins_encode %{ 12421 Label* L = $labl$$label; 12422 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 12423 if (cond == Assembler::EQ) 12424 __ cbz($op1$$Register, *L); 12425 else 12426 __ cbnz($op1$$Register, *L); 12427 %} 12428 ins_pipe(pipe_cmp_branch); 12429 %} 12430 12431 // Conditional Far Branch 12432 // Conditional Far Branch Unsigned 12433 // TODO: fixme 12434 12435 // counted loop end branch near 12436 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 12437 %{ 12438 match(CountedLoopEnd cmp cr); 12439 12440 effect(USE lbl); 12441 12442 ins_cost(BRANCH_COST); 12443 // short variant. 12444 // ins_short_branch(1); 12445 format %{ "b$cmp $lbl \t// counted loop end" %} 12446 12447 ins_encode(aarch64_enc_br_con(cmp, lbl)); 12448 12449 ins_pipe(pipe_branch); 12450 %} 12451 12452 // counted loop end branch near Unsigned 12453 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 12454 %{ 12455 match(CountedLoopEnd cmp cr); 12456 12457 effect(USE lbl); 12458 12459 ins_cost(BRANCH_COST); 12460 // short variant. 12461 // ins_short_branch(1); 12462 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 12463 12464 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 12465 12466 ins_pipe(pipe_branch); 12467 %} 12468 12469 // counted loop end branch far 12470 // counted loop end branch far unsigned 12471 // TODO: fixme 12472 12473 // ============================================================================ 12474 // inlined locking and unlocking 12475 12476 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 12477 %{ 12478 match(Set cr (FastLock object box)); 12479 effect(TEMP tmp, TEMP tmp2); 12480 12481 // TODO 12482 // identify correct cost 12483 ins_cost(5 * INSN_COST); 12484 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 12485 12486 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 12487 12488 ins_pipe(pipe_serial); 12489 %} 12490 12491 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 12492 %{ 12493 match(Set cr (FastUnlock object box)); 12494 effect(TEMP tmp, TEMP tmp2); 12495 12496 ins_cost(5 * INSN_COST); 12497 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 12498 12499 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 12500 12501 ins_pipe(pipe_serial); 12502 %} 12503 12504 12505 // ============================================================================ 12506 // Safepoint Instructions 12507 12508 // TODO 12509 // provide a near and far version of this code 12510 12511 instruct safePoint(iRegP poll) 12512 %{ 12513 match(SafePoint poll); 12514 12515 format %{ 12516 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 12517 %} 12518 ins_encode %{ 12519 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 12520 %} 12521 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 12522 %} 12523 12524 12525 // ============================================================================ 12526 // Procedure Call/Return Instructions 12527 12528 // Call Java Static Instruction 12529 12530 instruct CallStaticJavaDirect(method meth) 12531 %{ 12532 match(CallStaticJava); 12533 12534 effect(USE meth); 12535 12536 predicate(!((CallStaticJavaNode*)n)->is_method_handle_invoke()); 12537 12538 ins_cost(CALL_COST); 12539 12540 format %{ "call,static $meth \t// ==> " %} 12541 12542 ins_encode( aarch64_enc_java_static_call(meth), 12543 aarch64_enc_call_epilog ); 12544 12545 ins_pipe(pipe_class_call); 12546 %} 12547 12548 // TO HERE 12549 12550 // Call Java Static Instruction (method handle version) 12551 12552 instruct CallStaticJavaDirectHandle(method meth, iRegP_FP reg_mh_save) 12553 %{ 12554 match(CallStaticJava); 12555 12556 effect(USE meth); 12557 12558 predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke()); 12559 12560 ins_cost(CALL_COST); 12561 12562 format %{ "call,static $meth \t// (methodhandle) ==> " %} 12563 12564 ins_encode( aarch64_enc_java_handle_call(meth), 12565 aarch64_enc_call_epilog ); 12566 12567 ins_pipe(pipe_class_call); 12568 %} 12569 12570 // Call Java Dynamic Instruction 12571 instruct CallDynamicJavaDirect(method meth) 12572 %{ 12573 match(CallDynamicJava); 12574 12575 effect(USE meth); 12576 12577 ins_cost(CALL_COST); 12578 12579 format %{ "CALL,dynamic $meth \t// ==> " %} 12580 12581 ins_encode( aarch64_enc_java_dynamic_call(meth), 12582 aarch64_enc_call_epilog ); 12583 12584 ins_pipe(pipe_class_call); 12585 %} 12586 12587 // Call Runtime Instruction 12588 12589 instruct CallRuntimeDirect(method meth) 12590 %{ 12591 match(CallRuntime); 12592 12593 effect(USE meth); 12594 12595 ins_cost(CALL_COST); 12596 12597 format %{ "CALL, runtime $meth" %} 12598 12599 ins_encode( aarch64_enc_java_to_runtime(meth) ); 12600 12601 ins_pipe(pipe_class_call); 12602 %} 12603 12604 // Call Runtime Instruction 12605 12606 instruct CallLeafDirect(method meth) 12607 %{ 12608 match(CallLeaf); 12609 12610 effect(USE meth); 12611 12612 ins_cost(CALL_COST); 12613 12614 format %{ "CALL, runtime leaf $meth" %} 12615 12616 ins_encode( aarch64_enc_java_to_runtime(meth) ); 12617 12618 ins_pipe(pipe_class_call); 12619 %} 12620 12621 // Call Runtime Instruction 12622 12623 instruct CallLeafNoFPDirect(method meth) 12624 %{ 12625 match(CallLeafNoFP); 12626 12627 effect(USE meth); 12628 12629 ins_cost(CALL_COST); 12630 12631 format %{ "CALL, runtime leaf nofp $meth" %} 12632 12633 ins_encode( aarch64_enc_java_to_runtime(meth) ); 12634 12635 ins_pipe(pipe_class_call); 12636 %} 12637 12638 // Tail Call; Jump from runtime stub to Java code. 12639 // Also known as an 'interprocedural jump'. 12640 // Target of jump will eventually return to caller. 12641 // TailJump below removes the return address. 12642 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 12643 %{ 12644 match(TailCall jump_target method_oop); 12645 12646 ins_cost(CALL_COST); 12647 12648 format %{ "br $jump_target\t# $method_oop holds method oop" %} 12649 12650 ins_encode(aarch64_enc_tail_call(jump_target)); 12651 12652 ins_pipe(pipe_class_call); 12653 %} 12654 12655 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 12656 %{ 12657 match(TailJump jump_target ex_oop); 12658 12659 ins_cost(CALL_COST); 12660 12661 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 12662 12663 ins_encode(aarch64_enc_tail_jmp(jump_target)); 12664 12665 ins_pipe(pipe_class_call); 12666 %} 12667 12668 // Create exception oop: created by stack-crawling runtime code. 12669 // Created exception is now available to this handler, and is setup 12670 // just prior to jumping to this handler. No code emitted. 12671 // TODO check 12672 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 12673 instruct CreateException(iRegP_R0 ex_oop) 12674 %{ 12675 match(Set ex_oop (CreateEx)); 12676 12677 format %{ " -- \t// exception oop; no code emitted" %} 12678 12679 size(0); 12680 12681 ins_encode( /*empty*/ ); 12682 12683 ins_pipe(pipe_class_empty); 12684 %} 12685 12686 // Rethrow exception: The exception oop will come in the first 12687 // argument position. Then JUMP (not call) to the rethrow stub code. 12688 instruct RethrowException() %{ 12689 match(Rethrow); 12690 ins_cost(CALL_COST); 12691 12692 format %{ "b rethrow_stub" %} 12693 12694 ins_encode( aarch64_enc_rethrow() ); 12695 12696 ins_pipe(pipe_class_call); 12697 %} 12698 12699 12700 // Return Instruction 12701 // epilog node loads ret address into lr as part of frame pop 12702 instruct Ret() 12703 %{ 12704 match(Return); 12705 12706 format %{ "ret\t// return register" %} 12707 12708 ins_encode( aarch64_enc_ret() ); 12709 12710 ins_pipe(pipe_branch); 12711 %} 12712 12713 // Die now. 12714 instruct ShouldNotReachHere() %{ 12715 match(Halt); 12716 12717 ins_cost(CALL_COST); 12718 format %{ "ShouldNotReachHere" %} 12719 12720 ins_encode %{ 12721 // TODO 12722 // implement proper trap call here 12723 __ brk(999); 12724 %} 12725 12726 ins_pipe(pipe_class_default); 12727 %} 12728 12729 // ============================================================================ 12730 // Partial Subtype Check 12731 // 12732 // superklass array for an instance of the superklass. Set a hidden 12733 // internal cache on a hit (cache is checked with exposed code in 12734 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12735 // encoding ALSO sets flags. 12736 12737 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 12738 %{ 12739 match(Set result (PartialSubtypeCheck sub super)); 12740 effect(KILL cr, KILL temp); 12741 12742 ins_cost(1100); // slightly larger than the next version 12743 format %{ "partialSubtypeCheck $result, $sub, $super" %} 12744 12745 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 12746 12747 opcode(0x1); // Force zero of result reg on hit 12748 12749 ins_pipe(pipe_class_memory); 12750 %} 12751 12752 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 12753 %{ 12754 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12755 effect(KILL temp, KILL result); 12756 12757 ins_cost(1100); // slightly larger than the next version 12758 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 12759 12760 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 12761 12762 opcode(0x0); // Don't zero result reg on hit 12763 12764 ins_pipe(pipe_class_memory); 12765 %} 12766 12767 instruct string_compare(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 12768 iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr) 12769 %{ 12770 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12771 effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12772 12773 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 12774 ins_encode %{ 12775 __ string_compare($str1$$Register, $str2$$Register, 12776 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12777 $tmp1$$Register); 12778 %} 12779 ins_pipe(pipe_class_memory); 12780 %} 12781 12782 instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 12783 iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr) 12784 %{ 12785 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12786 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 12787 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 12788 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result" %} 12789 12790 ins_encode %{ 12791 __ string_indexof($str1$$Register, $str2$$Register, 12792 $cnt1$$Register, $cnt2$$Register, 12793 $tmp1$$Register, $tmp2$$Register, 12794 $tmp3$$Register, $tmp4$$Register, 12795 -1, $result$$Register); 12796 %} 12797 ins_pipe(pipe_class_memory); 12798 %} 12799 12800 instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 12801 immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2, 12802 iRegI tmp3, iRegI tmp4, rFlagsReg cr) 12803 %{ 12804 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12805 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 12806 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 12807 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result" %} 12808 12809 ins_encode %{ 12810 int icnt2 = (int)$int_cnt2$$constant; 12811 __ string_indexof($str1$$Register, $str2$$Register, 12812 $cnt1$$Register, zr, 12813 $tmp1$$Register, $tmp2$$Register, 12814 $tmp3$$Register, $tmp4$$Register, 12815 icnt2, $result$$Register); 12816 %} 12817 ins_pipe(pipe_class_memory); 12818 %} 12819 12820 instruct string_equals(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 12821 iRegI_R0 result, iRegP_R10 tmp, rFlagsReg cr) 12822 %{ 12823 match(Set result (StrEquals (Binary str1 str2) cnt)); 12824 effect(KILL tmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 12825 12826 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %} 12827 ins_encode %{ 12828 __ string_equals($str1$$Register, $str2$$Register, 12829 $cnt$$Register, $result$$Register, 12830 $tmp$$Register); 12831 %} 12832 ins_pipe(pipe_class_memory); 12833 %} 12834 12835 instruct array_equals(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 12836 iRegP_R10 tmp, rFlagsReg cr) 12837 %{ 12838 match(Set result (AryEq ary1 ary2)); 12839 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, KILL cr); 12840 12841 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 12842 ins_encode %{ 12843 __ char_arrays_equals($ary1$$Register, $ary2$$Register, 12844 $result$$Register, $tmp$$Register); 12845 %} 12846 ins_pipe(pipe_class_memory); 12847 %} 12848 12849 // encode char[] to byte[] in ISO_8859_1 12850 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 12851 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 12852 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 12853 iRegI_R0 result, rFlagsReg cr) 12854 %{ 12855 match(Set result (EncodeISOArray src (Binary dst len))); 12856 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 12857 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 12858 12859 format %{ "Encode array $src,$dst,$len -> $result" %} 12860 ins_encode %{ 12861 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12862 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 12863 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 12864 %} 12865 ins_pipe( pipe_class_memory ); 12866 %} 12867 12868 // ============================================================================ 12869 // This name is KNOWN by the ADLC and cannot be changed. 12870 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12871 // for this guy. 12872 instruct tlsLoadP(thread_RegP dst) 12873 %{ 12874 match(Set dst (ThreadLocal)); 12875 12876 ins_cost(0); 12877 12878 format %{ " -- \t// $dst=Thread::current(), empty" %} 12879 12880 size(0); 12881 12882 ins_encode( /*empty*/ ); 12883 12884 ins_pipe(pipe_class_empty); 12885 %} 12886 12887 12888 12889 //----------PEEPHOLE RULES----------------------------------------------------- 12890 // These must follow all instruction definitions as they use the names 12891 // defined in the instructions definitions. 12892 // 12893 // peepmatch ( root_instr_name [preceding_instruction]* ); 12894 // 12895 // peepconstraint %{ 12896 // (instruction_number.operand_name relational_op instruction_number.operand_name 12897 // [, ...] ); 12898 // // instruction numbers are zero-based using left to right order in peepmatch 12899 // 12900 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12901 // // provide an instruction_number.operand_name for each operand that appears 12902 // // in the replacement instruction's match rule 12903 // 12904 // ---------VM FLAGS--------------------------------------------------------- 12905 // 12906 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12907 // 12908 // Each peephole rule is given an identifying number starting with zero and 12909 // increasing by one in the order seen by the parser. An individual peephole 12910 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12911 // on the command-line. 12912 // 12913 // ---------CURRENT LIMITATIONS---------------------------------------------- 12914 // 12915 // Only match adjacent instructions in same basic block 12916 // Only equality constraints 12917 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12918 // Only one replacement instruction 12919 // 12920 // ---------EXAMPLE---------------------------------------------------------- 12921 // 12922 // // pertinent parts of existing instructions in architecture description 12923 // instruct movI(iRegINoSp dst, iRegI src) 12924 // %{ 12925 // match(Set dst (CopyI src)); 12926 // %} 12927 // 12928 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 12929 // %{ 12930 // match(Set dst (AddI dst src)); 12931 // effect(KILL cr); 12932 // %} 12933 // 12934 // // Change (inc mov) to lea 12935 // peephole %{ 12936 // // increment preceeded by register-register move 12937 // peepmatch ( incI_iReg movI ); 12938 // // require that the destination register of the increment 12939 // // match the destination register of the move 12940 // peepconstraint ( 0.dst == 1.dst ); 12941 // // construct a replacement instruction that sets 12942 // // the destination to ( move's source register + one ) 12943 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 12944 // %} 12945 // 12946 12947 // Implementation no longer uses movX instructions since 12948 // machine-independent system no longer uses CopyX nodes. 12949 // 12950 // peephole 12951 // %{ 12952 // peepmatch (incI_iReg movI); 12953 // peepconstraint (0.dst == 1.dst); 12954 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 12955 // %} 12956 12957 // peephole 12958 // %{ 12959 // peepmatch (decI_iReg movI); 12960 // peepconstraint (0.dst == 1.dst); 12961 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 12962 // %} 12963 12964 // peephole 12965 // %{ 12966 // peepmatch (addI_iReg_imm movI); 12967 // peepconstraint (0.dst == 1.dst); 12968 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 12969 // %} 12970 12971 // peephole 12972 // %{ 12973 // peepmatch (incL_iReg movL); 12974 // peepconstraint (0.dst == 1.dst); 12975 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 12976 // %} 12977 12978 // peephole 12979 // %{ 12980 // peepmatch (decL_iReg movL); 12981 // peepconstraint (0.dst == 1.dst); 12982 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 12983 // %} 12984 12985 // peephole 12986 // %{ 12987 // peepmatch (addL_iReg_imm movL); 12988 // peepconstraint (0.dst == 1.dst); 12989 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 12990 // %} 12991 12992 // peephole 12993 // %{ 12994 // peepmatch (addP_iReg_imm movP); 12995 // peepconstraint (0.dst == 1.dst); 12996 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 12997 // %} 12998 12999 // // Change load of spilled value to only a spill 13000 // instruct storeI(memory mem, iRegI src) 13001 // %{ 13002 // match(Set mem (StoreI mem src)); 13003 // %} 13004 // 13005 // instruct loadI(iRegINoSp dst, memory mem) 13006 // %{ 13007 // match(Set dst (LoadI mem)); 13008 // %} 13009 // 13010 13011 //----------SMARTSPILL RULES--------------------------------------------------- 13012 // These must follow all instruction definitions as they use the names 13013 // defined in the instructions definitions. 13014 13015 // Local Variables: 13016 // mode: c++ 13017 // End: