1 // 2 // Copyright (c) 2014, Red Hat Inc. 3 // Copyright (c) 2003, 2012, Oracle and/or its affiliates. 4 // All rights reserved. 5 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 // 7 // This code is free software; you can redistribute it and/or modify it 8 // under the terms of the GNU General Public License version 2 only, as 9 // published by the Free Software Foundation. 10 // 11 // This code is distributed in the hope that it will be useful, but WITHOUT 12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 // version 2 for more details (a copy is included in the LICENSE file that 15 // accompanied this code). 16 // 17 // You should have received a copy of the GNU General Public License version 18 // 2 along with this work; if not, write to the Free Software Foundation, 19 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 // 21 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 // or visit www.oracle.com if you need additional information or have any 23 // questions. 24 // 25 // 26 27 // AArch64 Architecture Description File 28 29 //----------REGISTER DEFINITION BLOCK------------------------------------------ 30 // This information is used by the matcher and the register allocator to 31 // describe individual registers and classes of registers within the target 32 // archtecture. 33 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name ( register save type, C convention save type, 38 // ideal register type, encoding ); 39 // Register Save Types: 40 // 41 // NS = No-Save: The register allocator assumes that these registers 42 // can be used without saving upon entry to the method, & 43 // that they do not need to be saved at call sites. 44 // 45 // SOC = Save-On-Call: The register allocator assumes that these registers 46 // can be used without saving upon entry to the method, 47 // but that they must be saved at call sites. 48 // 49 // SOE = Save-On-Entry: The register allocator assumes that these registers 50 // must be saved before using them upon entry to the 51 // method, but they do not need to be saved at call 52 // sites. 53 // 54 // AS = Always-Save: The register allocator assumes that these registers 55 // must be saved before using them upon entry to the 56 // method, & that they must be saved at call sites. 57 // 58 // Ideal Register Type is used to determine how to save & restore a 59 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 60 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 61 // 62 // The encoding number is the actual bit-pattern placed into the opcodes. 63 64 // We must define the 64 bit int registers in two 32 bit halves, the 65 // real lower register and a virtual upper half register. upper halves 66 // are used by the register allocator but are not actually supplied as 67 // operands to memory ops. 68 // 69 // follow the C1 compiler in making registers 70 // 71 // r0-r7,r10-r26 volatile (caller save) 72 // r27-r32 system (no save, no allocate) 73 // r8-r9 invisible to the allocator (so we can use them as scratch regs) 74 // 75 // as regards Java usage. we don't use any callee save registers 76 // because this makes it difficult to de-optimise a frame (see comment 77 // in x86 implementation of Deoptimization::unwind_callee_save_values) 78 // 79 80 // General Registers 81 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, r0->as_VMReg() ); 83 reg_def R0_H ( SOC, SOC, Op_RegI, 0, r0->as_VMReg()->next() ); 84 reg_def R1 ( SOC, SOC, Op_RegI, 1, r1->as_VMReg() ); 85 reg_def R1_H ( SOC, SOC, Op_RegI, 1, r1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, r2->as_VMReg() ); 87 reg_def R2_H ( SOC, SOC, Op_RegI, 2, r2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, r3->as_VMReg() ); 89 reg_def R3_H ( SOC, SOC, Op_RegI, 3, r3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, r4->as_VMReg() ); 91 reg_def R4_H ( SOC, SOC, Op_RegI, 4, r4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, r5->as_VMReg() ); 93 reg_def R5_H ( SOC, SOC, Op_RegI, 5, r5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, r6->as_VMReg() ); 95 reg_def R6_H ( SOC, SOC, Op_RegI, 6, r6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, r7->as_VMReg() ); 97 reg_def R7_H ( SOC, SOC, Op_RegI, 7, r7->as_VMReg()->next() ); 98 reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() ); 99 reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 100 reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() ); 101 reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 102 reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() ); 103 reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next()); 104 reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() ); 105 reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next()); 106 reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() ); 107 reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next()); 108 reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() ); 109 reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next()); 110 reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); 111 reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 112 reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); 113 reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 114 reg_def R18 ( SOC, SOC, Op_RegI, 18, r18->as_VMReg() ); 115 reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); 116 reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); 117 reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); 118 reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp 119 reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next()); 120 reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() ); 121 reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next()); 122 reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() ); 123 reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next()); 124 reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() ); 125 reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next()); 126 reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() ); 127 reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next()); 128 reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); 129 reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); 130 reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); 131 reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); 132 reg_def R27 ( NS, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 133 reg_def R27_H ( NS, SOE, Op_RegI, 27, r27->as_VMReg()->next()); 134 reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread 135 reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); 136 reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp 137 reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next()); 138 reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr 139 reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next()); 140 reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp 141 reg_def R31_H ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg()->next()); 142 143 // ---------------------------- 144 // Float/Double Registers 145 // ---------------------------- 146 147 // Double Registers 148 149 // The rules of ADL require that double registers be defined in pairs. 150 // Each pair must be two 32-bit values, but not necessarily a pair of 151 // single float registers. In each pair, ADLC-assigned register numbers 152 // must be adjacent, with the lower number even. Finally, when the 153 // CPU stores such a register pair to memory, the word associated with 154 // the lower ADLC-assigned number must be stored to the lower address. 155 156 // AArch64 has 32 floating-point registers. Each can store a vector of 157 // single or double precision floating-point values up to 8 * 32 158 // floats, 4 * 64 bit floats or 2 * 128 bit floats. We currently only 159 // use the first float or double element of the vector. 160 161 // for Java use float registers v0-v15 are always save on call whereas 162 // the platform ABI treats v8-v15 as callee save). float registers 163 // v16-v31 are SOC as per the platform spec 164 165 reg_def V0 ( SOC, SOC, Op_RegF, 0, v0->as_VMReg() ); 166 reg_def V0_H ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next() ); 167 reg_def V1 ( SOC, SOC, Op_RegF, 1, v1->as_VMReg() ); 168 reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next() ); 169 reg_def V2 ( SOC, SOC, Op_RegF, 2, v2->as_VMReg() ); 170 reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next() ); 171 reg_def V3 ( SOC, SOC, Op_RegF, 3, v3->as_VMReg() ); 172 reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next() ); 173 reg_def V4 ( SOC, SOC, Op_RegF, 4, v4->as_VMReg() ); 174 reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next() ); 175 reg_def V5 ( SOC, SOC, Op_RegF, 5, v5->as_VMReg() ); 176 reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next() ); 177 reg_def V6 ( SOC, SOC, Op_RegF, 6, v6->as_VMReg() ); 178 reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next() ); 179 reg_def V7 ( SOC, SOC, Op_RegF, 7, v7->as_VMReg() ); 180 reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next() ); 181 reg_def V8 ( SOC, SOE, Op_RegF, 8, v8->as_VMReg() ); 182 reg_def V8_H ( SOC, SOE, Op_RegF, 8, v8->as_VMReg()->next() ); 183 reg_def V9 ( SOC, SOE, Op_RegF, 9, v9->as_VMReg() ); 184 reg_def V9_H ( SOC, SOE, Op_RegF, 9, v9->as_VMReg()->next() ); 185 reg_def V10 ( SOC, SOE, Op_RegF, 10, v10->as_VMReg() ); 186 reg_def V10_H( SOC, SOE, Op_RegF, 10, v10->as_VMReg()->next()); 187 reg_def V11 ( SOC, SOE, Op_RegF, 11, v11->as_VMReg() ); 188 reg_def V11_H( SOC, SOE, Op_RegF, 11, v11->as_VMReg()->next()); 189 reg_def V12 ( SOC, SOE, Op_RegF, 12, v12->as_VMReg() ); 190 reg_def V12_H( SOC, SOE, Op_RegF, 12, v12->as_VMReg()->next()); 191 reg_def V13 ( SOC, SOE, Op_RegF, 13, v13->as_VMReg() ); 192 reg_def V13_H( SOC, SOE, Op_RegF, 13, v13->as_VMReg()->next()); 193 reg_def V14 ( SOC, SOE, Op_RegF, 14, v14->as_VMReg() ); 194 reg_def V14_H( SOC, SOE, Op_RegF, 14, v14->as_VMReg()->next()); 195 reg_def V15 ( SOC, SOE, Op_RegF, 15, v15->as_VMReg() ); 196 reg_def V15_H( SOC, SOE, Op_RegF, 15, v15->as_VMReg()->next()); 197 reg_def V16 ( SOC, SOC, Op_RegF, 16, v16->as_VMReg() ); 198 reg_def V16_H( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next()); 199 reg_def V17 ( SOC, SOC, Op_RegF, 17, v17->as_VMReg() ); 200 reg_def V17_H( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next()); 201 reg_def V18 ( SOC, SOC, Op_RegF, 18, v18->as_VMReg() ); 202 reg_def V18_H( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next()); 203 reg_def V19 ( SOC, SOC, Op_RegF, 19, v19->as_VMReg() ); 204 reg_def V19_H( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next()); 205 reg_def V20 ( SOC, SOC, Op_RegF, 20, v20->as_VMReg() ); 206 reg_def V20_H( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next()); 207 reg_def V21 ( SOC, SOC, Op_RegF, 21, v21->as_VMReg() ); 208 reg_def V21_H( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next()); 209 reg_def V22 ( SOC, SOC, Op_RegF, 22, v22->as_VMReg() ); 210 reg_def V22_H( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next()); 211 reg_def V23 ( SOC, SOC, Op_RegF, 23, v23->as_VMReg() ); 212 reg_def V23_H( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next()); 213 reg_def V24 ( SOC, SOC, Op_RegF, 24, v24->as_VMReg() ); 214 reg_def V24_H( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next()); 215 reg_def V25 ( SOC, SOC, Op_RegF, 25, v25->as_VMReg() ); 216 reg_def V25_H( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next()); 217 reg_def V26 ( SOC, SOC, Op_RegF, 26, v26->as_VMReg() ); 218 reg_def V26_H( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next()); 219 reg_def V27 ( SOC, SOC, Op_RegF, 27, v27->as_VMReg() ); 220 reg_def V27_H( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next()); 221 reg_def V28 ( SOC, SOC, Op_RegF, 28, v28->as_VMReg() ); 222 reg_def V28_H( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next()); 223 reg_def V29 ( SOC, SOC, Op_RegF, 29, v29->as_VMReg() ); 224 reg_def V29_H( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next()); 225 reg_def V30 ( SOC, SOC, Op_RegF, 30, v30->as_VMReg() ); 226 reg_def V30_H( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next()); 227 reg_def V31 ( SOC, SOC, Op_RegF, 31, v31->as_VMReg() ); 228 reg_def V31_H( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next()); 229 230 // ---------------------------- 231 // Special Registers 232 // ---------------------------- 233 234 // the AArch64 CSPR status flag register is not directly acessible as 235 // instruction operand. the FPSR status flag register is a system 236 // register which can be written/read using MSR/MRS but again does not 237 // appear as an operand (a code identifying the FSPR occurs as an 238 // immediate value in the instruction). 239 240 reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad()); 241 242 243 // Specify priority of register selection within phases of register 244 // allocation. Highest priority is first. A useful heuristic is to 245 // give registers a low priority when they are required by machine 246 // instructions, like EAX and EDX on I486, and choose no-save registers 247 // before save-on-call, & save-on-call before save-on-entry. Registers 248 // which participate in fixed calling sequences should come last. 249 // Registers which are used as pairs must fall on an even boundary. 250 251 alloc_class chunk0( 252 // volatiles 253 R10, R10_H, 254 R11, R11_H, 255 R12, R12_H, 256 R13, R13_H, 257 R14, R14_H, 258 R15, R15_H, 259 R16, R16_H, 260 R17, R17_H, 261 R18, R18_H, 262 263 // arg registers 264 R0, R0_H, 265 R1, R1_H, 266 R2, R2_H, 267 R3, R3_H, 268 R4, R4_H, 269 R5, R5_H, 270 R6, R6_H, 271 R7, R7_H, 272 273 // non-volatiles 274 R19, R19_H, 275 R20, R20_H, 276 R21, R21_H, 277 R22, R22_H, 278 R23, R23_H, 279 R24, R24_H, 280 R25, R25_H, 281 R26, R26_H, 282 283 // non-allocatable registers 284 285 R27, R27_H, // heapbase 286 R28, R28_H, // thread 287 R29, R29_H, // fp 288 R30, R30_H, // lr 289 R31, R31_H, // sp 290 ); 291 292 alloc_class chunk1( 293 294 // no save 295 V16, V16_H, 296 V17, V17_H, 297 V18, V18_H, 298 V19, V19_H, 299 V20, V20_H, 300 V21, V21_H, 301 V22, V22_H, 302 V23, V23_H, 303 V24, V24_H, 304 V25, V25_H, 305 V26, V26_H, 306 V27, V27_H, 307 V28, V28_H, 308 V29, V29_H, 309 V30, V30_H, 310 V31, V31_H, 311 312 // arg registers 313 V0, V0_H, 314 V1, V1_H, 315 V2, V2_H, 316 V3, V3_H, 317 V4, V4_H, 318 V5, V5_H, 319 V6, V6_H, 320 V7, V7_H, 321 322 // non-volatiles 323 V8, V8_H, 324 V9, V9_H, 325 V10, V10_H, 326 V11, V11_H, 327 V12, V12_H, 328 V13, V13_H, 329 V14, V14_H, 330 V15, V15_H, 331 ); 332 333 alloc_class chunk2(RFLAGS); 334 335 //----------Architecture Description Register Classes-------------------------- 336 // Several register classes are automatically defined based upon information in 337 // this architecture description. 338 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 339 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 340 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 341 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 342 // 343 344 // Class for all 32 bit integer registers -- excludes SP which will 345 // never be used as an integer register 346 reg_class any_reg32( 347 R0, 348 R1, 349 R2, 350 R3, 351 R4, 352 R5, 353 R6, 354 R7, 355 R10, 356 R11, 357 R12, 358 R13, 359 R14, 360 R15, 361 R16, 362 R17, 363 R18, 364 R19, 365 R20, 366 R21, 367 R22, 368 R23, 369 R24, 370 R25, 371 R26, 372 R27, 373 R28, 374 R29, 375 R30 376 ); 377 378 // Singleton class for R0 int register 379 reg_class int_r0_reg(R0); 380 381 // Singleton class for R2 int register 382 reg_class int_r2_reg(R2); 383 384 // Singleton class for R3 int register 385 reg_class int_r3_reg(R3); 386 387 // Singleton class for R4 int register 388 reg_class int_r4_reg(R4); 389 390 // Class for all long integer registers (including RSP) 391 reg_class any_reg( 392 R0, R0_H, 393 R1, R1_H, 394 R2, R2_H, 395 R3, R3_H, 396 R4, R4_H, 397 R5, R5_H, 398 R6, R6_H, 399 R7, R7_H, 400 R10, R10_H, 401 R11, R11_H, 402 R12, R12_H, 403 R13, R13_H, 404 R14, R14_H, 405 R15, R15_H, 406 R16, R16_H, 407 R17, R17_H, 408 R18, R18_H, 409 R19, R19_H, 410 R20, R20_H, 411 R21, R21_H, 412 R22, R22_H, 413 R23, R23_H, 414 R24, R24_H, 415 R25, R25_H, 416 R26, R26_H, 417 R27, R27_H, 418 R28, R28_H, 419 R29, R29_H, 420 R30, R30_H, 421 R31, R31_H 422 ); 423 424 // Class for all non-special integer registers 425 reg_class no_special_reg32( 426 R0, 427 R1, 428 R2, 429 R3, 430 R4, 431 R5, 432 R6, 433 R7, 434 R10, 435 R11, 436 R12, // rmethod 437 R13, 438 R14, 439 R15, 440 R16, 441 R17, 442 R18, 443 R19, 444 R20, 445 R21, 446 R22, 447 R23, 448 R24, 449 R25, 450 R26 451 /* R27, */ // heapbase 452 /* R28, */ // thread 453 /* R29, */ // fp 454 /* R30, */ // lr 455 /* R31 */ // sp 456 ); 457 458 // Class for all non-special long integer registers 459 reg_class no_special_reg( 460 R0, R0_H, 461 R1, R1_H, 462 R2, R2_H, 463 R3, R3_H, 464 R4, R4_H, 465 R5, R5_H, 466 R6, R6_H, 467 R7, R7_H, 468 R10, R10_H, 469 R11, R11_H, 470 R12, R12_H, // rmethod 471 R13, R13_H, 472 R14, R14_H, 473 R15, R15_H, 474 R16, R16_H, 475 R17, R17_H, 476 R18, R18_H, 477 R19, R19_H, 478 R20, R20_H, 479 R21, R21_H, 480 R22, R22_H, 481 R23, R23_H, 482 R24, R24_H, 483 R25, R25_H, 484 R26, R26_H, 485 /* R27, R27_H, */ // heapbase 486 /* R28, R28_H, */ // thread 487 /* R29, R29_H, */ // fp 488 /* R30, R30_H, */ // lr 489 /* R31, R31_H */ // sp 490 ); 491 492 // Class for 64 bit register r0 493 reg_class r0_reg( 494 R0, R0_H 495 ); 496 497 // Class for 64 bit register r1 498 reg_class r1_reg( 499 R1, R1_H 500 ); 501 502 // Class for 64 bit register r2 503 reg_class r2_reg( 504 R2, R2_H 505 ); 506 507 // Class for 64 bit register r3 508 reg_class r3_reg( 509 R3, R3_H 510 ); 511 512 // Class for 64 bit register r4 513 reg_class r4_reg( 514 R4, R4_H 515 ); 516 517 // Class for 64 bit register r5 518 reg_class r5_reg( 519 R5, R5_H 520 ); 521 522 // Class for 64 bit register r10 523 reg_class r10_reg( 524 R10, R10_H 525 ); 526 527 // Class for 64 bit register r11 528 reg_class r11_reg( 529 R11, R11_H 530 ); 531 532 // Class for method register 533 reg_class method_reg( 534 R12, R12_H 535 ); 536 537 // Class for heapbase register 538 reg_class heapbase_reg( 539 R27, R27_H 540 ); 541 542 // Class for thread register 543 reg_class thread_reg( 544 R28, R28_H 545 ); 546 547 // Class for frame pointer register 548 reg_class fp_reg( 549 R29, R29_H 550 ); 551 552 // Class for link register 553 reg_class lr_reg( 554 R30, R30_H 555 ); 556 557 // Class for long sp register 558 reg_class sp_reg( 559 R31, R31_H 560 ); 561 562 // Class for all pointer registers 563 reg_class ptr_reg( 564 R0, R0_H, 565 R1, R1_H, 566 R2, R2_H, 567 R3, R3_H, 568 R4, R4_H, 569 R5, R5_H, 570 R6, R6_H, 571 R7, R7_H, 572 R10, R10_H, 573 R11, R11_H, 574 R12, R12_H, 575 R13, R13_H, 576 R14, R14_H, 577 R15, R15_H, 578 R16, R16_H, 579 R17, R17_H, 580 R18, R18_H, 581 R19, R19_H, 582 R20, R20_H, 583 R21, R21_H, 584 R22, R22_H, 585 R23, R23_H, 586 R24, R24_H, 587 R25, R25_H, 588 R26, R26_H, 589 R27, R27_H, 590 R28, R28_H, 591 R29, R29_H, 592 R30, R30_H, 593 R31, R31_H 594 ); 595 596 // Class for all non_special pointer registers 597 reg_class no_special_ptr_reg( 598 R0, R0_H, 599 R1, R1_H, 600 R2, R2_H, 601 R3, R3_H, 602 R4, R4_H, 603 R5, R5_H, 604 R6, R6_H, 605 R7, R7_H, 606 R10, R10_H, 607 R11, R11_H, 608 R12, R12_H, 609 R13, R13_H, 610 R14, R14_H, 611 R15, R15_H, 612 R16, R16_H, 613 R17, R17_H, 614 R18, R18_H, 615 R19, R19_H, 616 R20, R20_H, 617 R21, R21_H, 618 R22, R22_H, 619 R23, R23_H, 620 R24, R24_H, 621 R25, R25_H, 622 R26, R26_H, 623 /* R27, R27_H, */ // heapbase 624 /* R28, R28_H, */ // thread 625 /* R29, R29_H, */ // fp 626 /* R30, R30_H, */ // lr 627 /* R31, R31_H */ // sp 628 ); 629 630 // Class for all float registers 631 reg_class float_reg( 632 V0, 633 V1, 634 V2, 635 V3, 636 V4, 637 V5, 638 V6, 639 V7, 640 V8, 641 V9, 642 V10, 643 V11, 644 V12, 645 V13, 646 V14, 647 V15, 648 V16, 649 V17, 650 V18, 651 V19, 652 V20, 653 V21, 654 V22, 655 V23, 656 V24, 657 V25, 658 V26, 659 V27, 660 V28, 661 V29, 662 V30, 663 V31 664 ); 665 666 // Double precision float registers have virtual `high halves' that 667 // are needed by the allocator. 668 // Class for all double registers 669 reg_class double_reg( 670 V0, V0_H, 671 V1, V1_H, 672 V2, V2_H, 673 V3, V3_H, 674 V4, V4_H, 675 V5, V5_H, 676 V6, V6_H, 677 V7, V7_H, 678 V8, V8_H, 679 V9, V9_H, 680 V10, V10_H, 681 V11, V11_H, 682 V12, V12_H, 683 V13, V13_H, 684 V14, V14_H, 685 V15, V15_H, 686 V16, V16_H, 687 V17, V17_H, 688 V18, V18_H, 689 V19, V19_H, 690 V20, V20_H, 691 V21, V21_H, 692 V22, V22_H, 693 V23, V23_H, 694 V24, V24_H, 695 V25, V25_H, 696 V26, V26_H, 697 V27, V27_H, 698 V28, V28_H, 699 V29, V29_H, 700 V30, V30_H, 701 V31, V31_H 702 ); 703 704 // Class for 128 bit register v0 705 reg_class v0_reg( 706 V0, V0_H 707 ); 708 709 // Class for 128 bit register v1 710 reg_class v1_reg( 711 V1, V1_H 712 ); 713 714 // Class for 128 bit register v2 715 reg_class v2_reg( 716 V2, V2_H 717 ); 718 719 // Class for 128 bit register v3 720 reg_class v3_reg( 721 V3, V3_H 722 ); 723 724 // Singleton class for condition codes 725 reg_class int_flags(RFLAGS); 726 727 %} 728 729 //----------DEFINITION BLOCK--------------------------------------------------- 730 // Define name --> value mappings to inform the ADLC of an integer valued name 731 // Current support includes integer values in the range [0, 0x7FFFFFFF] 732 // Format: 733 // int_def <name> ( <int_value>, <expression>); 734 // Generated Code in ad_<arch>.hpp 735 // #define <name> (<expression>) 736 // // value == <int_value> 737 // Generated code in ad_<arch>.cpp adlc_verification() 738 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 739 // 740 741 // we follow the ppc-aix port in using a simple cost model which ranks 742 // register operations as cheap, memory ops as more expensive and 743 // branches as most expensive. the first two have a low as well as a 744 // normal cost. huge cost appears to be a way of saying don't do 745 // something 746 747 definitions %{ 748 // The default cost (of a register move instruction). 749 int_def INSN_COST ( 100, 100); 750 int_def BRANCH_COST ( 200, 2 * INSN_COST); 751 int_def CALL_COST ( 200, 2 * INSN_COST); 752 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 753 %} 754 755 756 //----------SOURCE BLOCK------------------------------------------------------- 757 // This is a block of C++ code which provides values, functions, and 758 // definitions necessary in the rest of the architecture description 759 760 source_hpp %{ 761 762 class CallStubImpl { 763 764 //-------------------------------------------------------------- 765 //---< Used for optimization in Compile::shorten_branches >--- 766 //-------------------------------------------------------------- 767 768 public: 769 // Size of call trampoline stub. 770 static uint size_call_trampoline() { 771 return 0; // no call trampolines on this platform 772 } 773 774 // number of relocations needed by a call trampoline stub 775 static uint reloc_call_trampoline() { 776 return 0; // no call trampolines on this platform 777 } 778 }; 779 780 class HandlerImpl { 781 782 public: 783 784 static int emit_exception_handler(CodeBuffer &cbuf); 785 static int emit_deopt_handler(CodeBuffer& cbuf); 786 787 static uint size_exception_handler() { 788 return MacroAssembler::far_branch_size(); 789 } 790 791 static uint size_deopt_handler() { 792 // count one adr and one far branch instruction 793 return 4 * NativeInstruction::instruction_size; 794 } 795 }; 796 797 bool preceded_by_ordered_load(const Node *barrier); 798 799 %} 800 801 source %{ 802 803 // AArch64 has load acquire and store release instructions which we 804 // use for ordered memory accesses, e.g. for volatiles. The ideal 805 // graph generator also inserts memory barriers around volatile 806 // accesses, and we don't want to generate both barriers and acq/rel 807 // instructions. So, when we emit a MemBarAcquire we look back in 808 // the ideal graph for an ordered load and only emit the barrier if 809 // we don't find one. 810 811 bool preceded_by_ordered_load(const Node *barrier) { 812 Node *x = barrier->lookup(TypeFunc::Parms); 813 814 if (! x) 815 return false; 816 817 if (x->is_DecodeNarrowPtr()) 818 x = x->in(1); 819 820 if (x->is_Load()) 821 return ! x->as_Load()->is_unordered(); 822 823 return false; 824 } 825 826 #define __ _masm. 827 828 // advance declaratuons for helper functions to convert register 829 // indices to register objects 830 831 // the ad file has to provide implementations of certain methods 832 // expected by the generic code 833 // 834 // REQUIRED FUNCTIONALITY 835 836 //============================================================================= 837 838 // !!!!! Special hack to get all types of calls to specify the byte offset 839 // from the start of the call to the point where the return address 840 // will point. 841 842 int MachCallStaticJavaNode::ret_addr_offset() 843 { 844 // call should be a simple bl 845 // unless this is a method handle invoke in which case it is 846 // mov(rfp, sp), bl, mov(sp, rfp) 847 int off = 4; 848 if (_method_handle_invoke) { 849 off += 4; 850 } 851 return off; 852 } 853 854 int MachCallDynamicJavaNode::ret_addr_offset() 855 { 856 return 16; // movz, movk, movk, bl 857 } 858 859 int MachCallRuntimeNode::ret_addr_offset() { 860 // for generated stubs the call will be 861 // far_call(addr) 862 // for real runtime callouts it will be six instructions 863 // see aarch64_enc_java_to_runtime 864 // adr(rscratch2, retaddr) 865 // lea(rscratch1, RuntimeAddress(addr) 866 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 867 // blrt rscratch1 868 CodeBlob *cb = CodeCache::find_blob(_entry_point); 869 if (cb) { 870 return MacroAssembler::far_branch_size(); 871 } else { 872 return 6 * NativeInstruction::instruction_size; 873 } 874 } 875 876 // Indicate if the safepoint node needs the polling page as an input 877 878 // the shared code plants the oop data at the start of the generated 879 // code for the safepoint node and that needs ot be at the load 880 // instruction itself. so we cannot plant a mov of the safepoint poll 881 // address followed by a load. setting this to true means the mov is 882 // scheduled as a prior instruction. that's better for scheduling 883 // anyway. 884 885 bool SafePointNode::needs_polling_address_input() 886 { 887 return true; 888 } 889 890 //============================================================================= 891 892 #ifndef PRODUCT 893 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 894 st->print("BREAKPOINT"); 895 } 896 #endif 897 898 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 899 MacroAssembler _masm(&cbuf); 900 __ brk(0); 901 } 902 903 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 904 return MachNode::size(ra_); 905 } 906 907 //============================================================================= 908 909 #ifndef PRODUCT 910 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 911 st->print("nop \t# %d bytes pad for loops and calls", _count); 912 } 913 #endif 914 915 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 916 MacroAssembler _masm(&cbuf); 917 for (int i = 0; i < _count; i++) { 918 __ nop(); 919 } 920 } 921 922 uint MachNopNode::size(PhaseRegAlloc*) const { 923 return _count * NativeInstruction::instruction_size; 924 } 925 926 //============================================================================= 927 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 928 929 int Compile::ConstantTable::calculate_table_base_offset() const { 930 return 0; // absolute addressing, no offset 931 } 932 933 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 934 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 935 ShouldNotReachHere(); 936 } 937 938 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 939 // Empty encoding 940 } 941 942 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 943 return 0; 944 } 945 946 #ifndef PRODUCT 947 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 948 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 949 } 950 #endif 951 952 #ifndef PRODUCT 953 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 954 Compile* C = ra_->C; 955 956 int framesize = C->frame_slots() << LogBytesPerInt; 957 958 if (C->need_stack_bang(framesize)) 959 st->print("# stack bang size=%d\n\t", framesize); 960 961 if (framesize == 0) { 962 // Is this even possible? 963 st->print("stp lr, rfp, [sp, #%d]!", -(2 * wordSize)); 964 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 965 st->print("sub sp, sp, #%d\n\t", framesize); 966 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 967 } else { 968 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 969 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 970 st->print("sub sp, sp, rscratch1"); 971 } 972 } 973 #endif 974 975 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 976 Compile* C = ra_->C; 977 MacroAssembler _masm(&cbuf); 978 979 // n.b. frame size includes space for return pc and rfp 980 const long framesize = C->frame_size_in_bytes(); 981 assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment"); 982 983 // insert a nop at the start of the prolog so we can patch in a 984 // branch if we need to invalidate the method later 985 __ nop(); 986 987 int bangsize = C->bang_size_in_bytes(); 988 if (C->need_stack_bang(bangsize) && UseStackBanging) 989 __ generate_stack_overflow_check(bangsize); 990 991 __ build_frame(framesize); 992 993 if (NotifySimulator) { 994 __ notify(Assembler::method_entry); 995 } 996 997 if (VerifyStackAtCalls) { 998 Unimplemented(); 999 } 1000 1001 C->set_frame_complete(cbuf.insts_size()); 1002 1003 if (C->has_mach_constant_base_node()) { 1004 // NOTE: We set the table base offset here because users might be 1005 // emitted before MachConstantBaseNode. 1006 Compile::ConstantTable& constant_table = C->constant_table(); 1007 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1008 } 1009 } 1010 1011 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1012 { 1013 return MachNode::size(ra_); // too many variables; just compute it 1014 // the hard way 1015 } 1016 1017 int MachPrologNode::reloc() const 1018 { 1019 return 0; 1020 } 1021 1022 //============================================================================= 1023 1024 #ifndef PRODUCT 1025 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1026 Compile* C = ra_->C; 1027 int framesize = C->frame_slots() << LogBytesPerInt; 1028 1029 st->print("# pop frame %d\n\t",framesize); 1030 1031 if (framesize == 0) { 1032 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1033 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1034 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1035 st->print("add sp, sp, #%d\n\t", framesize); 1036 } else { 1037 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1038 st->print("add sp, sp, rscratch1\n\t"); 1039 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1040 } 1041 1042 if (do_polling() && C->is_method_compilation()) { 1043 st->print("# touch polling page\n\t"); 1044 st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page())); 1045 st->print("ldr zr, [rscratch1]"); 1046 } 1047 } 1048 #endif 1049 1050 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1051 Compile* C = ra_->C; 1052 MacroAssembler _masm(&cbuf); 1053 int framesize = C->frame_slots() << LogBytesPerInt; 1054 1055 __ remove_frame(framesize); 1056 1057 if (NotifySimulator) { 1058 __ notify(Assembler::method_reentry); 1059 } 1060 1061 if (do_polling() && C->is_method_compilation()) { 1062 __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type); 1063 } 1064 } 1065 1066 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1067 // Variable size. Determine dynamically. 1068 return MachNode::size(ra_); 1069 } 1070 1071 int MachEpilogNode::reloc() const { 1072 // Return number of relocatable values contained in this instruction. 1073 return 1; // 1 for polling page. 1074 } 1075 1076 const Pipeline * MachEpilogNode::pipeline() const { 1077 return MachNode::pipeline_class(); 1078 } 1079 1080 // This method seems to be obsolete. It is declared in machnode.hpp 1081 // and defined in all *.ad files, but it is never called. Should we 1082 // get rid of it? 1083 int MachEpilogNode::safepoint_offset() const { 1084 assert(do_polling(), "no return for this epilog node"); 1085 return 4; 1086 } 1087 1088 //============================================================================= 1089 1090 // Figure out which register class each belongs in: rc_int, rc_float or 1091 // rc_stack. 1092 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1093 1094 static enum RC rc_class(OptoReg::Name reg) { 1095 1096 if (reg == OptoReg::Bad) { 1097 return rc_bad; 1098 } 1099 1100 // we have 30 int registers * 2 halves 1101 // (rscratch1 and rscratch2 are omitted) 1102 1103 if (reg < 60) { 1104 return rc_int; 1105 } 1106 1107 // we have 32 float register * 2 halves 1108 if (reg < 60 + 64) { 1109 return rc_float; 1110 } 1111 1112 // Between float regs & stack is the flags regs. 1113 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1114 1115 return rc_stack; 1116 } 1117 1118 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1119 Compile* C = ra_->C; 1120 1121 // Get registers to move. 1122 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1123 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1124 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1125 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1126 1127 enum RC src_hi_rc = rc_class(src_hi); 1128 enum RC src_lo_rc = rc_class(src_lo); 1129 enum RC dst_hi_rc = rc_class(dst_hi); 1130 enum RC dst_lo_rc = rc_class(dst_lo); 1131 1132 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1133 1134 if (src_hi != OptoReg::Bad) { 1135 assert((src_lo&1)==0 && src_lo+1==src_hi && 1136 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1137 "expected aligned-adjacent pairs"); 1138 } 1139 1140 if (src_lo == dst_lo && src_hi == dst_hi) { 1141 return 0; // Self copy, no move. 1142 } 1143 1144 switch (src_lo_rc) { 1145 case rc_int: 1146 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1147 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1148 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1149 // 64 bit 1150 if (cbuf) { 1151 MacroAssembler _masm(cbuf); 1152 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1153 as_Register(Matcher::_regEncode[src_lo])); 1154 } else if (st) { 1155 st->print("mov %s, %s\t# shuffle", 1156 Matcher::regName[dst_lo], 1157 Matcher::regName[src_lo]); 1158 } 1159 } else { 1160 // 32 bit 1161 if (cbuf) { 1162 MacroAssembler _masm(cbuf); 1163 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1164 as_Register(Matcher::_regEncode[src_lo])); 1165 } else if (st) { 1166 st->print("movw %s, %s\t# shuffle", 1167 Matcher::regName[dst_lo], 1168 Matcher::regName[src_lo]); 1169 } 1170 } 1171 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1172 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1173 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1174 // 64 bit 1175 if (cbuf) { 1176 MacroAssembler _masm(cbuf); 1177 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1178 as_Register(Matcher::_regEncode[src_lo])); 1179 } else if (st) { 1180 st->print("fmovd %s, %s\t# shuffle", 1181 Matcher::regName[dst_lo], 1182 Matcher::regName[src_lo]); 1183 } 1184 } else { 1185 // 32 bit 1186 if (cbuf) { 1187 MacroAssembler _masm(cbuf); 1188 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1189 as_Register(Matcher::_regEncode[src_lo])); 1190 } else if (st) { 1191 st->print("fmovs %s, %s\t# shuffle", 1192 Matcher::regName[dst_lo], 1193 Matcher::regName[src_lo]); 1194 } 1195 } 1196 } else { // gpr --> stack spill 1197 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1198 int dst_offset = ra_->reg2offset(dst_lo); 1199 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1200 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1201 // 64 bit 1202 if (cbuf) { 1203 MacroAssembler _masm(cbuf); 1204 __ str(as_Register(Matcher::_regEncode[src_lo]), 1205 Address(sp, dst_offset)); 1206 } else if (st) { 1207 st->print("str %s, [sp, #%d]\t# spill", 1208 Matcher::regName[src_lo], 1209 dst_offset); 1210 } 1211 } else { 1212 // 32 bit 1213 if (cbuf) { 1214 MacroAssembler _masm(cbuf); 1215 __ strw(as_Register(Matcher::_regEncode[src_lo]), 1216 Address(sp, dst_offset)); 1217 } else if (st) { 1218 st->print("strw %s, [sp, #%d]\t# spill", 1219 Matcher::regName[src_lo], 1220 dst_offset); 1221 } 1222 } 1223 } 1224 return 4; 1225 case rc_float: 1226 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 1227 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1228 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1229 // 64 bit 1230 if (cbuf) { 1231 MacroAssembler _masm(cbuf); 1232 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 1233 as_FloatRegister(Matcher::_regEncode[src_lo])); 1234 } else if (st) { 1235 st->print("fmovd %s, %s\t# shuffle", 1236 Matcher::regName[dst_lo], 1237 Matcher::regName[src_lo]); 1238 } 1239 } else { 1240 // 32 bit 1241 if (cbuf) { 1242 MacroAssembler _masm(cbuf); 1243 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 1244 as_FloatRegister(Matcher::_regEncode[src_lo])); 1245 } else if (st) { 1246 st->print("fmovs %s, %s\t# shuffle", 1247 Matcher::regName[dst_lo], 1248 Matcher::regName[src_lo]); 1249 } 1250 } 1251 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 1252 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1253 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1254 // 64 bit 1255 if (cbuf) { 1256 MacroAssembler _masm(cbuf); 1257 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1258 as_FloatRegister(Matcher::_regEncode[src_lo])); 1259 } else if (st) { 1260 st->print("fmovd %s, %s\t# shuffle", 1261 Matcher::regName[dst_lo], 1262 Matcher::regName[src_lo]); 1263 } 1264 } else { 1265 // 32 bit 1266 if (cbuf) { 1267 MacroAssembler _masm(cbuf); 1268 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1269 as_FloatRegister(Matcher::_regEncode[src_lo])); 1270 } else if (st) { 1271 st->print("fmovs %s, %s\t# shuffle", 1272 Matcher::regName[dst_lo], 1273 Matcher::regName[src_lo]); 1274 } 1275 } 1276 } else { // fpr --> stack spill 1277 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1278 int dst_offset = ra_->reg2offset(dst_lo); 1279 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1280 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1281 // 64 bit 1282 if (cbuf) { 1283 MacroAssembler _masm(cbuf); 1284 __ strd(as_FloatRegister(Matcher::_regEncode[src_lo]), 1285 Address(sp, dst_offset)); 1286 } else if (st) { 1287 st->print("strd %s, [sp, #%d]\t# spill", 1288 Matcher::regName[src_lo], 1289 dst_offset); 1290 } 1291 } else { 1292 // 32 bit 1293 if (cbuf) { 1294 MacroAssembler _masm(cbuf); 1295 __ strs(as_FloatRegister(Matcher::_regEncode[src_lo]), 1296 Address(sp, dst_offset)); 1297 } else if (st) { 1298 st->print("strs %s, [sp, #%d]\t# spill", 1299 Matcher::regName[src_lo], 1300 dst_offset); 1301 } 1302 } 1303 } 1304 return 4; 1305 case rc_stack: 1306 int src_offset = ra_->reg2offset(src_lo); 1307 if (dst_lo_rc == rc_int) { // stack --> gpr load 1308 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1309 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1310 // 64 bit 1311 if (cbuf) { 1312 MacroAssembler _masm(cbuf); 1313 __ ldr(as_Register(Matcher::_regEncode[dst_lo]), 1314 Address(sp, src_offset)); 1315 } else if (st) { 1316 st->print("ldr %s, [sp, %d]\t# restore", 1317 Matcher::regName[dst_lo], 1318 src_offset); 1319 } 1320 } else { 1321 // 32 bit 1322 if (cbuf) { 1323 MacroAssembler _masm(cbuf); 1324 __ ldrw(as_Register(Matcher::_regEncode[dst_lo]), 1325 Address(sp, src_offset)); 1326 } else if (st) { 1327 st->print("ldr %s, [sp, %d]\t# restore", 1328 Matcher::regName[dst_lo], 1329 src_offset); 1330 } 1331 } 1332 return 4; 1333 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 1334 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1335 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1336 // 64 bit 1337 if (cbuf) { 1338 MacroAssembler _masm(cbuf); 1339 __ ldrd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1340 Address(sp, src_offset)); 1341 } else if (st) { 1342 st->print("ldrd %s, [sp, %d]\t# restore", 1343 Matcher::regName[dst_lo], 1344 src_offset); 1345 } 1346 } else { 1347 // 32 bit 1348 if (cbuf) { 1349 MacroAssembler _masm(cbuf); 1350 __ ldrs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1351 Address(sp, src_offset)); 1352 } else if (st) { 1353 st->print("ldrs %s, [sp, %d]\t# restore", 1354 Matcher::regName[dst_lo], 1355 src_offset); 1356 } 1357 } 1358 return 4; 1359 } else { // stack --> stack copy 1360 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 1361 int dst_offset = ra_->reg2offset(dst_lo); 1362 if (((src_lo & 1) == 0 && src_lo + 1 == src_hi) && 1363 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) { 1364 // 64 bit 1365 if (cbuf) { 1366 MacroAssembler _masm(cbuf); 1367 __ ldr(rscratch1, Address(sp, src_offset)); 1368 __ str(rscratch1, Address(sp, dst_offset)); 1369 } else if (st) { 1370 st->print("ldr rscratch1, [sp, %d]\t# mem-mem spill", 1371 src_offset); 1372 st->print("\n\t"); 1373 st->print("str rscratch1, [sp, %d]", 1374 dst_offset); 1375 } 1376 } else { 1377 // 32 bit 1378 if (cbuf) { 1379 MacroAssembler _masm(cbuf); 1380 __ ldrw(rscratch1, Address(sp, src_offset)); 1381 __ strw(rscratch1, Address(sp, dst_offset)); 1382 } else if (st) { 1383 st->print("ldrw rscratch1, [sp, %d]\t# mem-mem spill", 1384 src_offset); 1385 st->print("\n\t"); 1386 st->print("strw rscratch1, [sp, %d]", 1387 dst_offset); 1388 } 1389 } 1390 return 8; 1391 } 1392 } 1393 1394 assert(false," bad rc_class for spill "); 1395 Unimplemented(); 1396 return 0; 1397 1398 } 1399 1400 #ifndef PRODUCT 1401 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1402 if (!ra_) 1403 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1404 else 1405 implementation(NULL, ra_, false, st); 1406 } 1407 #endif 1408 1409 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1410 implementation(&cbuf, ra_, false, NULL); 1411 } 1412 1413 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1414 return implementation(NULL, ra_, true, NULL); 1415 } 1416 1417 //============================================================================= 1418 1419 #ifndef PRODUCT 1420 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1421 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1422 int reg = ra_->get_reg_first(this); 1423 st->print("add %s, rsp, #%d]\t# box lock", 1424 Matcher::regName[reg], offset); 1425 } 1426 #endif 1427 1428 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1429 MacroAssembler _masm(&cbuf); 1430 1431 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1432 int reg = ra_->get_encode(this); 1433 1434 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 1435 __ add(as_Register(reg), sp, offset); 1436 } else { 1437 ShouldNotReachHere(); 1438 } 1439 } 1440 1441 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1442 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1443 return 4; 1444 } 1445 1446 //============================================================================= 1447 1448 #ifndef PRODUCT 1449 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1450 { 1451 st->print_cr("# MachUEPNode"); 1452 if (UseCompressedClassPointers) { 1453 st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1454 if (Universe::narrow_klass_shift() != 0) { 1455 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1456 } 1457 } else { 1458 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1459 } 1460 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 1461 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 1462 } 1463 #endif 1464 1465 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1466 { 1467 // This is the unverified entry point. 1468 MacroAssembler _masm(&cbuf); 1469 1470 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 1471 Label skip; 1472 // TODO 1473 // can we avoid this skip and still use a reloc? 1474 __ br(Assembler::EQ, skip); 1475 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1476 __ bind(skip); 1477 } 1478 1479 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1480 { 1481 return MachNode::size(ra_); 1482 } 1483 1484 // REQUIRED EMIT CODE 1485 1486 //============================================================================= 1487 1488 // Emit exception handler code. 1489 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 1490 { 1491 // mov rscratch1 #exception_blob_entry_point 1492 // br rscratch1 1493 // Note that the code buffer's insts_mark is always relative to insts. 1494 // That's why we must use the macroassembler to generate a handler. 1495 MacroAssembler _masm(&cbuf); 1496 address base = 1497 __ start_a_stub(size_exception_handler()); 1498 if (base == NULL) return 0; // CodeBuffer::expand failed 1499 int offset = __ offset(); 1500 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1501 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1502 __ end_a_stub(); 1503 return offset; 1504 } 1505 1506 // Emit deopt handler code. 1507 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 1508 { 1509 // Note that the code buffer's insts_mark is always relative to insts. 1510 // That's why we must use the macroassembler to generate a handler. 1511 MacroAssembler _masm(&cbuf); 1512 address base = 1513 __ start_a_stub(size_deopt_handler()); 1514 if (base == NULL) return 0; // CodeBuffer::expand failed 1515 int offset = __ offset(); 1516 1517 __ adr(lr, __ pc()); 1518 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1519 1520 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1521 __ end_a_stub(); 1522 return offset; 1523 } 1524 1525 // REQUIRED MATCHER CODE 1526 1527 //============================================================================= 1528 1529 const bool Matcher::match_rule_supported(int opcode) { 1530 1531 // TODO 1532 // identify extra cases that we might want to provide match rules for 1533 // e.g. Op_StrEquals and other intrinsics 1534 if (!has_match_rule(opcode)) { 1535 return false; 1536 } 1537 1538 return true; // Per default match rules are supported. 1539 } 1540 1541 int Matcher::regnum_to_fpu_offset(int regnum) 1542 { 1543 Unimplemented(); 1544 return 0; 1545 } 1546 1547 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) 1548 { 1549 Unimplemented(); 1550 return false; 1551 } 1552 1553 const bool Matcher::isSimpleConstant64(jlong value) { 1554 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1555 // Probably always true, even if a temp register is required. 1556 return true; 1557 } 1558 1559 // true just means we have fast l2f conversion 1560 const bool Matcher::convL2FSupported(void) { 1561 return true; 1562 } 1563 1564 // Vector width in bytes. 1565 const int Matcher::vector_width_in_bytes(BasicType bt) { 1566 // TODO fixme 1567 return 0; 1568 } 1569 1570 // Limits on vector size (number of elements) loaded into vector. 1571 const int Matcher::max_vector_size(const BasicType bt) { 1572 return vector_width_in_bytes(bt)/type2aelembytes(bt); 1573 } 1574 const int Matcher::min_vector_size(const BasicType bt) { 1575 int max_size = max_vector_size(bt); 1576 // Min size which can be loaded into vector is 4 bytes. 1577 int size = (type2aelembytes(bt) == 1) ? 4 : 2; 1578 return MIN2(size,max_size); 1579 } 1580 1581 // Vector ideal reg. 1582 const int Matcher::vector_ideal_reg(int len) { 1583 // TODO fixme 1584 return Op_RegD; 1585 } 1586 1587 // Only lowest bits of xmm reg are used for vector shift count. 1588 const int Matcher::vector_shift_count_ideal_reg(int size) { 1589 // TODO fixme 1590 return Op_RegL; 1591 } 1592 1593 // AES support not yet implemented 1594 const bool Matcher::pass_original_key_for_aes() { 1595 return false; 1596 } 1597 1598 // x86 supports misaligned vectors store/load. 1599 const bool Matcher::misaligned_vectors_ok() { 1600 // TODO fixme 1601 // return !AlignVector; // can be changed by flag 1602 return false; 1603 } 1604 1605 // false => size gets scaled to BytesPerLong, ok. 1606 const bool Matcher::init_array_count_is_in_bytes = false; 1607 1608 // Threshold size for cleararray. 1609 const int Matcher::init_array_short_size = 18 * BytesPerLong; 1610 1611 // Use conditional move (CMOVL) 1612 const int Matcher::long_cmove_cost() { 1613 // long cmoves are no more expensive than int cmoves 1614 return 0; 1615 } 1616 1617 const int Matcher::float_cmove_cost() { 1618 // float cmoves are no more expensive than int cmoves 1619 return 0; 1620 } 1621 1622 // Does the CPU require late expand (see block.cpp for description of late expand)? 1623 const bool Matcher::require_postalloc_expand = false; 1624 1625 // Should the Matcher clone shifts on addressing modes, expecting them 1626 // to be subsumed into complex addressing expressions or compute them 1627 // into registers? True for Intel but false for most RISCs 1628 const bool Matcher::clone_shift_expressions = false; 1629 1630 // Do we need to mask the count passed to shift instructions or does 1631 // the cpu only look at the lower 5/6 bits anyway? 1632 const bool Matcher::need_masked_shift_count = false; 1633 1634 // This affects two different things: 1635 // - how Decode nodes are matched 1636 // - how ImplicitNullCheck opportunities are recognized 1637 // If true, the matcher will try to remove all Decodes and match them 1638 // (as operands) into nodes. NullChecks are not prepared to deal with 1639 // Decodes by final_graph_reshaping(). 1640 // If false, final_graph_reshaping() forces the decode behind the Cmp 1641 // for a NullCheck. The matcher matches the Decode node into a register. 1642 // Implicit_null_check optimization moves the Decode along with the 1643 // memory operation back up before the NullCheck. 1644 bool Matcher::narrow_oop_use_complex_address() { 1645 return Universe::narrow_oop_shift() == 0; 1646 } 1647 1648 bool Matcher::narrow_klass_use_complex_address() { 1649 // TODO 1650 // decide whether we need to set this to true 1651 return false; 1652 } 1653 1654 // Is it better to copy float constants, or load them directly from 1655 // memory? Intel can load a float constant from a direct address, 1656 // requiring no extra registers. Most RISCs will have to materialize 1657 // an address into a register first, so they would do better to copy 1658 // the constant from stack. 1659 const bool Matcher::rematerialize_float_constants = false; 1660 1661 // If CPU can load and store mis-aligned doubles directly then no 1662 // fixup is needed. Else we split the double into 2 integer pieces 1663 // and move it piece-by-piece. Only happens when passing doubles into 1664 // C code as the Java calling convention forces doubles to be aligned. 1665 const bool Matcher::misaligned_doubles_ok = true; 1666 1667 // No-op on amd64 1668 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 1669 Unimplemented(); 1670 } 1671 1672 // Advertise here if the CPU requires explicit rounding operations to 1673 // implement the UseStrictFP mode. 1674 const bool Matcher::strict_fp_requires_explicit_rounding = false; 1675 1676 // Are floats converted to double when stored to stack during 1677 // deoptimization? 1678 bool Matcher::float_in_double() { return true; } 1679 1680 // Do ints take an entire long register or just half? 1681 // The relevant question is how the int is callee-saved: 1682 // the whole long is written but de-opt'ing will have to extract 1683 // the relevant 32 bits. 1684 const bool Matcher::int_in_long = true; 1685 1686 // Return whether or not this register is ever used as an argument. 1687 // This function is used on startup to build the trampoline stubs in 1688 // generateOptoStub. Registers not mentioned will be killed by the VM 1689 // call in the trampoline, and arguments in those registers not be 1690 // available to the callee. 1691 bool Matcher::can_be_java_arg(int reg) 1692 { 1693 return 1694 reg == R0_num || reg == R0_H_num || 1695 reg == R1_num || reg == R1_H_num || 1696 reg == R2_num || reg == R2_H_num || 1697 reg == R3_num || reg == R3_H_num || 1698 reg == R4_num || reg == R4_H_num || 1699 reg == R5_num || reg == R5_H_num || 1700 reg == R6_num || reg == R6_H_num || 1701 reg == R7_num || reg == R7_H_num || 1702 reg == V0_num || reg == V0_H_num || 1703 reg == V1_num || reg == V1_H_num || 1704 reg == V2_num || reg == V2_H_num || 1705 reg == V3_num || reg == V3_H_num || 1706 reg == V4_num || reg == V4_H_num || 1707 reg == V5_num || reg == V5_H_num || 1708 reg == V6_num || reg == V6_H_num || 1709 reg == V7_num || reg == V7_H_num; 1710 } 1711 1712 bool Matcher::is_spillable_arg(int reg) 1713 { 1714 return can_be_java_arg(reg); 1715 } 1716 1717 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 1718 return false; 1719 } 1720 1721 RegMask Matcher::divI_proj_mask() { 1722 ShouldNotReachHere(); 1723 return RegMask(); 1724 } 1725 1726 // Register for MODI projection of divmodI. 1727 RegMask Matcher::modI_proj_mask() { 1728 ShouldNotReachHere(); 1729 return RegMask(); 1730 } 1731 1732 // Register for DIVL projection of divmodL. 1733 RegMask Matcher::divL_proj_mask() { 1734 ShouldNotReachHere(); 1735 return RegMask(); 1736 } 1737 1738 // Register for MODL projection of divmodL. 1739 RegMask Matcher::modL_proj_mask() { 1740 ShouldNotReachHere(); 1741 return RegMask(); 1742 } 1743 1744 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1745 return RegMask(); 1746 } 1747 1748 // helper for encoding java_to_runtime calls on sim 1749 // 1750 // this is needed to compute the extra arguments required when 1751 // planting a call to the simulator blrt instruction. the TypeFunc 1752 // can be queried to identify the counts for integral, and floating 1753 // arguments and the return type 1754 1755 static void getCallInfo(const TypeFunc *tf, int &gpcnt, int &fpcnt, int &rtype) 1756 { 1757 int gps = 0; 1758 int fps = 0; 1759 const TypeTuple *domain = tf->domain(); 1760 int max = domain->cnt(); 1761 for (int i = TypeFunc::Parms; i < max; i++) { 1762 const Type *t = domain->field_at(i); 1763 switch(t->basic_type()) { 1764 case T_FLOAT: 1765 case T_DOUBLE: 1766 fps++; 1767 default: 1768 gps++; 1769 } 1770 } 1771 gpcnt = gps; 1772 fpcnt = fps; 1773 BasicType rt = tf->return_type(); 1774 switch (rt) { 1775 case T_VOID: 1776 rtype = MacroAssembler::ret_type_void; 1777 break; 1778 default: 1779 rtype = MacroAssembler::ret_type_integral; 1780 break; 1781 case T_FLOAT: 1782 rtype = MacroAssembler::ret_type_float; 1783 break; 1784 case T_DOUBLE: 1785 rtype = MacroAssembler::ret_type_double; 1786 break; 1787 } 1788 } 1789 1790 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 1791 MacroAssembler _masm(&cbuf); \ 1792 { \ 1793 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 1794 guarantee(DISP == 0, "mode not permitted for volatile"); \ 1795 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 1796 __ INSN(REG, as_Register(BASE)); \ 1797 } 1798 1799 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 1800 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 1801 1802 // Used for all non-volatile memory accesses. The use of 1803 // $mem->opcode() to discover whether this pattern uses sign-extended 1804 // offsets is something of a kludge. 1805 static void loadStore(MacroAssembler masm, mem_insn insn, 1806 Register reg, int opcode, 1807 Register base, int index, int size, int disp) 1808 { 1809 Address::extend scale; 1810 1811 // Hooboy, this is fugly. We need a way to communicate to the 1812 // encoder that the index needs to be sign extended, so we have to 1813 // enumerate all the cases. 1814 switch (opcode) { 1815 case INDINDEXSCALEDOFFSETI2L: 1816 case INDINDEXSCALEDI2L: 1817 case INDINDEXSCALEDOFFSETI2LN: 1818 case INDINDEXSCALEDI2LN: 1819 scale = Address::sxtw(size); 1820 break; 1821 default: 1822 scale = Address::lsl(size); 1823 } 1824 1825 if (index == -1) { 1826 (masm.*insn)(reg, Address(base, disp)); 1827 } else { 1828 if (disp == 0) { 1829 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 1830 } else { 1831 masm.lea(rscratch1, Address(base, disp)); 1832 (masm.*insn)(reg, Address(rscratch1, as_Register(index), scale)); 1833 } 1834 } 1835 } 1836 1837 static void loadStore(MacroAssembler masm, mem_float_insn insn, 1838 FloatRegister reg, int opcode, 1839 Register base, int index, int size, int disp) 1840 { 1841 Address::extend scale; 1842 1843 switch (opcode) { 1844 case INDINDEXSCALEDOFFSETI2L: 1845 case INDINDEXSCALEDI2L: 1846 case INDINDEXSCALEDOFFSETI2LN: 1847 case INDINDEXSCALEDI2LN: 1848 scale = Address::sxtw(size); 1849 break; 1850 default: 1851 scale = Address::lsl(size); 1852 } 1853 1854 if (index == -1) { 1855 (masm.*insn)(reg, Address(base, disp)); 1856 } else { 1857 if (disp == 0) { 1858 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 1859 } else { 1860 masm.lea(rscratch1, Address(base, disp)); 1861 (masm.*insn)(reg, Address(rscratch1, as_Register(index), scale)); 1862 } 1863 } 1864 } 1865 1866 %} 1867 1868 1869 1870 //----------ENCODING BLOCK----------------------------------------------------- 1871 // This block specifies the encoding classes used by the compiler to 1872 // output byte streams. Encoding classes are parameterized macros 1873 // used by Machine Instruction Nodes in order to generate the bit 1874 // encoding of the instruction. Operands specify their base encoding 1875 // interface with the interface keyword. There are currently 1876 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1877 // COND_INTER. REG_INTER causes an operand to generate a function 1878 // which returns its register number when queried. CONST_INTER causes 1879 // an operand to generate a function which returns the value of the 1880 // constant when queried. MEMORY_INTER causes an operand to generate 1881 // four functions which return the Base Register, the Index Register, 1882 // the Scale Value, and the Offset Value of the operand when queried. 1883 // COND_INTER causes an operand to generate six functions which return 1884 // the encoding code (ie - encoding bits for the instruction) 1885 // associated with each basic boolean condition for a conditional 1886 // instruction. 1887 // 1888 // Instructions specify two basic values for encoding. Again, a 1889 // function is available to check if the constant displacement is an 1890 // oop. They use the ins_encode keyword to specify their encoding 1891 // classes (which must be a sequence of enc_class names, and their 1892 // parameters, specified in the encoding block), and they use the 1893 // opcode keyword to specify, in order, their primary, secondary, and 1894 // tertiary opcode. Only the opcode sections which a particular 1895 // instruction needs for encoding need to be specified. 1896 encode %{ 1897 // Build emit functions for each basic byte or larger field in the 1898 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1899 // from C++ code in the enc_class source block. Emit functions will 1900 // live in the main source block for now. In future, we can 1901 // generalize this by adding a syntax that specifies the sizes of 1902 // fields in an order, so that the adlc can build the emit functions 1903 // automagically 1904 1905 // catch all for unimplemented encodings 1906 enc_class enc_unimplemented %{ 1907 MacroAssembler _masm(&cbuf); 1908 __ unimplemented("C2 catch all"); 1909 %} 1910 1911 // BEGIN Non-volatile memory access 1912 1913 enc_class aarch64_enc_ldrsbw(iRegI dst, memory mem) %{ 1914 Register dst_reg = as_Register($dst$$reg); 1915 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 1916 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1917 %} 1918 1919 enc_class aarch64_enc_ldrsb(iRegI dst, memory mem) %{ 1920 Register dst_reg = as_Register($dst$$reg); 1921 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 1922 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1923 %} 1924 1925 enc_class aarch64_enc_ldrb(iRegI dst, memory mem) %{ 1926 Register dst_reg = as_Register($dst$$reg); 1927 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 1928 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1929 %} 1930 1931 enc_class aarch64_enc_ldrb(iRegL dst, memory mem) %{ 1932 Register dst_reg = as_Register($dst$$reg); 1933 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 1934 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1935 %} 1936 1937 enc_class aarch64_enc_ldrshw(iRegI dst, memory mem) %{ 1938 Register dst_reg = as_Register($dst$$reg); 1939 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 1940 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1941 %} 1942 1943 enc_class aarch64_enc_ldrsh(iRegI dst, memory mem) %{ 1944 Register dst_reg = as_Register($dst$$reg); 1945 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 1946 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1947 %} 1948 1949 enc_class aarch64_enc_ldrh(iRegI dst, memory mem) %{ 1950 Register dst_reg = as_Register($dst$$reg); 1951 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 1952 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1953 %} 1954 1955 enc_class aarch64_enc_ldrh(iRegL dst, memory mem) %{ 1956 Register dst_reg = as_Register($dst$$reg); 1957 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 1958 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1959 %} 1960 1961 enc_class aarch64_enc_ldrw(iRegI dst, memory mem) %{ 1962 Register dst_reg = as_Register($dst$$reg); 1963 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 1964 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1965 %} 1966 1967 enc_class aarch64_enc_ldrw(iRegL dst, memory mem) %{ 1968 Register dst_reg = as_Register($dst$$reg); 1969 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 1970 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1971 %} 1972 1973 enc_class aarch64_enc_ldrsw(iRegL dst, memory mem) %{ 1974 Register dst_reg = as_Register($dst$$reg); 1975 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 1976 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1977 %} 1978 1979 enc_class aarch64_enc_ldr(iRegL dst, memory mem) %{ 1980 Register dst_reg = as_Register($dst$$reg); 1981 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 1982 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1983 %} 1984 1985 enc_class aarch64_enc_ldrs(vRegF dst, memory mem) %{ 1986 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 1987 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 1988 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1989 %} 1990 1991 enc_class aarch64_enc_ldrd(vRegD dst, memory mem) %{ 1992 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 1993 loadStore(MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 1994 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 1995 %} 1996 1997 enc_class aarch64_enc_strb(iRegI src, memory mem) %{ 1998 Register src_reg = as_Register($src$$reg); 1999 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2000 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2001 %} 2002 2003 enc_class aarch64_enc_strb0(memory mem) %{ 2004 MacroAssembler _masm(&cbuf); 2005 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2006 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2007 %} 2008 2009 enc_class aarch64_enc_strh(iRegI src, memory mem) %{ 2010 Register src_reg = as_Register($src$$reg); 2011 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2012 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2013 %} 2014 2015 enc_class aarch64_enc_strh0(memory mem) %{ 2016 MacroAssembler _masm(&cbuf); 2017 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2018 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2019 %} 2020 2021 enc_class aarch64_enc_strw(iRegI src, memory mem) %{ 2022 Register src_reg = as_Register($src$$reg); 2023 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2024 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2025 %} 2026 2027 enc_class aarch64_enc_strw0(memory mem) %{ 2028 MacroAssembler _masm(&cbuf); 2029 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2030 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2031 %} 2032 2033 enc_class aarch64_enc_str(iRegL src, memory mem) %{ 2034 Register src_reg = as_Register($src$$reg); 2035 // we sometimes get asked to store the stack pointer into the 2036 // current thread -- we cannot do that directly on AArch64 2037 if (src_reg == r31_sp) { 2038 MacroAssembler _masm(&cbuf); 2039 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2040 __ mov(rscratch2, sp); 2041 src_reg = rscratch2; 2042 } 2043 loadStore(MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 2044 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2045 %} 2046 2047 enc_class aarch64_enc_str0(memory mem) %{ 2048 MacroAssembler _masm(&cbuf); 2049 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 2050 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2051 %} 2052 2053 enc_class aarch64_enc_strs(vRegF src, memory mem) %{ 2054 FloatRegister src_reg = as_FloatRegister($src$$reg); 2055 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 2056 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2057 %} 2058 2059 enc_class aarch64_enc_strd(vRegD src, memory mem) %{ 2060 FloatRegister src_reg = as_FloatRegister($src$$reg); 2061 loadStore(MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 2062 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 2063 %} 2064 2065 // END Non-volatile memory access 2066 2067 // volatile loads and stores 2068 2069 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 2070 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2071 rscratch1, stlrb); 2072 %} 2073 2074 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 2075 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2076 rscratch1, stlrh); 2077 %} 2078 2079 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 2080 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2081 rscratch1, stlrw); 2082 %} 2083 2084 2085 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 2086 Register dst_reg = as_Register($dst$$reg); 2087 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2088 rscratch1, ldarb); 2089 __ sxtbw(dst_reg, dst_reg); 2090 %} 2091 2092 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 2093 Register dst_reg = as_Register($dst$$reg); 2094 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2095 rscratch1, ldarb); 2096 __ sxtb(dst_reg, dst_reg); 2097 %} 2098 2099 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 2100 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2101 rscratch1, ldarb); 2102 %} 2103 2104 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 2105 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2106 rscratch1, ldarb); 2107 %} 2108 2109 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 2110 Register dst_reg = as_Register($dst$$reg); 2111 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2112 rscratch1, ldarh); 2113 __ sxthw(dst_reg, dst_reg); 2114 %} 2115 2116 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 2117 Register dst_reg = as_Register($dst$$reg); 2118 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2119 rscratch1, ldarh); 2120 __ sxth(dst_reg, dst_reg); 2121 %} 2122 2123 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 2124 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2125 rscratch1, ldarh); 2126 %} 2127 2128 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 2129 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2130 rscratch1, ldarh); 2131 %} 2132 2133 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 2134 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2135 rscratch1, ldarw); 2136 %} 2137 2138 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 2139 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2140 rscratch1, ldarw); 2141 %} 2142 2143 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 2144 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2145 rscratch1, ldar); 2146 %} 2147 2148 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 2149 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2150 rscratch1, ldarw); 2151 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 2152 %} 2153 2154 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 2155 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2156 rscratch1, ldar); 2157 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 2158 %} 2159 2160 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 2161 Register src_reg = as_Register($src$$reg); 2162 // we sometimes get asked to store the stack pointer into the 2163 // current thread -- we cannot do that directly on AArch64 2164 if (src_reg == r31_sp) { 2165 MacroAssembler _masm(&cbuf); 2166 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 2167 __ mov(rscratch2, sp); 2168 src_reg = rscratch2; 2169 } 2170 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2171 rscratch1, stlr); 2172 %} 2173 2174 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 2175 { 2176 MacroAssembler _masm(&cbuf); 2177 FloatRegister src_reg = as_FloatRegister($src$$reg); 2178 __ fmovs(rscratch2, src_reg); 2179 } 2180 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2181 rscratch1, stlrw); 2182 %} 2183 2184 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 2185 { 2186 MacroAssembler _masm(&cbuf); 2187 FloatRegister src_reg = as_FloatRegister($src$$reg); 2188 __ fmovd(rscratch2, src_reg); 2189 } 2190 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 2191 rscratch1, stlr); 2192 %} 2193 2194 // synchronized read/update encodings 2195 2196 enc_class aarch64_enc_ldaxr(iRegL dst, memory mem) %{ 2197 MacroAssembler _masm(&cbuf); 2198 Register dst_reg = as_Register($dst$$reg); 2199 Register base = as_Register($mem$$base); 2200 int index = $mem$$index; 2201 int scale = $mem$$scale; 2202 int disp = $mem$$disp; 2203 if (index == -1) { 2204 if (disp != 0) { 2205 __ lea(rscratch1, Address(base, disp)); 2206 __ ldaxr(dst_reg, rscratch1); 2207 } else { 2208 // TODO 2209 // should we ever get anything other than this case? 2210 __ ldaxr(dst_reg, base); 2211 } 2212 } else { 2213 Register index_reg = as_Register(index); 2214 if (disp == 0) { 2215 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 2216 __ ldaxr(dst_reg, rscratch1); 2217 } else { 2218 __ lea(rscratch1, Address(base, disp)); 2219 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 2220 __ ldaxr(dst_reg, rscratch1); 2221 } 2222 } 2223 %} 2224 2225 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory mem) %{ 2226 MacroAssembler _masm(&cbuf); 2227 Register src_reg = as_Register($src$$reg); 2228 Register base = as_Register($mem$$base); 2229 int index = $mem$$index; 2230 int scale = $mem$$scale; 2231 int disp = $mem$$disp; 2232 if (index == -1) { 2233 if (disp != 0) { 2234 __ lea(rscratch2, Address(base, disp)); 2235 __ stlxr(rscratch1, src_reg, rscratch2); 2236 } else { 2237 // TODO 2238 // should we ever get anything other than this case? 2239 __ stlxr(rscratch1, src_reg, base); 2240 } 2241 } else { 2242 Register index_reg = as_Register(index); 2243 if (disp == 0) { 2244 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2245 __ stlxr(rscratch1, src_reg, rscratch2); 2246 } else { 2247 __ lea(rscratch2, Address(base, disp)); 2248 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2249 __ stlxr(rscratch1, src_reg, rscratch2); 2250 } 2251 } 2252 __ cmpw(rscratch1, zr); 2253 %} 2254 2255 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 2256 MacroAssembler _masm(&cbuf); 2257 Register old_reg = as_Register($oldval$$reg); 2258 Register new_reg = as_Register($newval$$reg); 2259 Register base = as_Register($mem$$base); 2260 Register addr_reg; 2261 int index = $mem$$index; 2262 int scale = $mem$$scale; 2263 int disp = $mem$$disp; 2264 if (index == -1) { 2265 if (disp != 0) { 2266 __ lea(rscratch2, Address(base, disp)); 2267 addr_reg = rscratch2; 2268 } else { 2269 // TODO 2270 // should we ever get anything other than this case? 2271 addr_reg = base; 2272 } 2273 } else { 2274 Register index_reg = as_Register(index); 2275 if (disp == 0) { 2276 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2277 addr_reg = rscratch2; 2278 } else { 2279 __ lea(rscratch2, Address(base, disp)); 2280 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2281 addr_reg = rscratch2; 2282 } 2283 } 2284 Label retry_load, done; 2285 __ bind(retry_load); 2286 __ ldxr(rscratch1, addr_reg); 2287 __ cmp(rscratch1, old_reg); 2288 __ br(Assembler::NE, done); 2289 __ stlxr(rscratch1, new_reg, addr_reg); 2290 __ cbnzw(rscratch1, retry_load); 2291 __ bind(done); 2292 %} 2293 2294 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 2295 MacroAssembler _masm(&cbuf); 2296 Register old_reg = as_Register($oldval$$reg); 2297 Register new_reg = as_Register($newval$$reg); 2298 Register base = as_Register($mem$$base); 2299 Register addr_reg; 2300 int index = $mem$$index; 2301 int scale = $mem$$scale; 2302 int disp = $mem$$disp; 2303 if (index == -1) { 2304 if (disp != 0) { 2305 __ lea(rscratch2, Address(base, disp)); 2306 addr_reg = rscratch2; 2307 } else { 2308 // TODO 2309 // should we ever get anything other than this case? 2310 addr_reg = base; 2311 } 2312 } else { 2313 Register index_reg = as_Register(index); 2314 if (disp == 0) { 2315 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 2316 addr_reg = rscratch2; 2317 } else { 2318 __ lea(rscratch2, Address(base, disp)); 2319 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 2320 addr_reg = rscratch2; 2321 } 2322 } 2323 Label retry_load, done; 2324 __ bind(retry_load); 2325 __ ldxrw(rscratch1, addr_reg); 2326 __ cmpw(rscratch1, old_reg); 2327 __ br(Assembler::NE, done); 2328 __ stlxrw(rscratch1, new_reg, addr_reg); 2329 __ cbnzw(rscratch1, retry_load); 2330 __ bind(done); 2331 %} 2332 2333 // auxiliary used for CompareAndSwapX to set result register 2334 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 2335 MacroAssembler _masm(&cbuf); 2336 Register res_reg = as_Register($res$$reg); 2337 __ cset(res_reg, Assembler::EQ); 2338 %} 2339 2340 // prefetch encodings 2341 2342 enc_class aarch64_enc_prefetchr(memory mem) %{ 2343 MacroAssembler _masm(&cbuf); 2344 Register base = as_Register($mem$$base); 2345 int index = $mem$$index; 2346 int scale = $mem$$scale; 2347 int disp = $mem$$disp; 2348 if (index == -1) { 2349 __ prfm(Address(base, disp), PLDL1KEEP); 2350 } else { 2351 Register index_reg = as_Register(index); 2352 if (disp == 0) { 2353 __ prfm(Address(base, index_reg, Address::lsl(scale)), PLDL1KEEP); 2354 } else { 2355 __ lea(rscratch1, Address(base, disp)); 2356 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PLDL1KEEP); 2357 } 2358 } 2359 %} 2360 2361 enc_class aarch64_enc_prefetchw(memory mem) %{ 2362 MacroAssembler _masm(&cbuf); 2363 Register base = as_Register($mem$$base); 2364 int index = $mem$$index; 2365 int scale = $mem$$scale; 2366 int disp = $mem$$disp; 2367 if (index == -1) { 2368 __ prfm(Address(base, disp), PSTL1KEEP); 2369 __ nop(); 2370 } else { 2371 Register index_reg = as_Register(index); 2372 if (disp == 0) { 2373 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 2374 } else { 2375 __ lea(rscratch1, Address(base, disp)); 2376 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 2377 } 2378 } 2379 %} 2380 2381 enc_class aarch64_enc_prefetchnta(memory mem) %{ 2382 MacroAssembler _masm(&cbuf); 2383 Register base = as_Register($mem$$base); 2384 int index = $mem$$index; 2385 int scale = $mem$$scale; 2386 int disp = $mem$$disp; 2387 if (index == -1) { 2388 __ prfm(Address(base, disp), PSTL1STRM); 2389 } else { 2390 Register index_reg = as_Register(index); 2391 if (disp == 0) { 2392 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1STRM); 2393 __ nop(); 2394 } else { 2395 __ lea(rscratch1, Address(base, disp)); 2396 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1STRM); 2397 } 2398 } 2399 %} 2400 2401 enc_class aarch64_enc_clear_array_reg_reg(iRegL_R11 cnt, iRegP_R10 base) %{ 2402 MacroAssembler _masm(&cbuf); 2403 Register cnt_reg = as_Register($cnt$$reg); 2404 Register base_reg = as_Register($base$$reg); 2405 // base is word aligned 2406 // cnt is count of words 2407 2408 Label loop; 2409 Label entry; 2410 2411 // Algorithm: 2412 // 2413 // scratch1 = cnt & 7; 2414 // cnt -= scratch1; 2415 // p += scratch1; 2416 // switch (scratch1) { 2417 // do { 2418 // cnt -= 8; 2419 // p[-8] = 0; 2420 // case 7: 2421 // p[-7] = 0; 2422 // case 6: 2423 // p[-6] = 0; 2424 // // ... 2425 // case 1: 2426 // p[-1] = 0; 2427 // case 0: 2428 // p += 8; 2429 // } while (cnt); 2430 // } 2431 2432 const int unroll = 8; // Number of str(zr) instructions we'll unroll 2433 2434 __ andr(rscratch1, cnt_reg, unroll - 1); // tmp1 = cnt % unroll 2435 __ sub(cnt_reg, cnt_reg, rscratch1); // cnt -= unroll 2436 // base_reg always points to the end of the region we're about to zero 2437 __ add(base_reg, base_reg, rscratch1, Assembler::LSL, exact_log2(wordSize)); 2438 __ adr(rscratch2, entry); 2439 __ sub(rscratch2, rscratch2, rscratch1, Assembler::LSL, 2); 2440 __ br(rscratch2); 2441 __ bind(loop); 2442 __ sub(cnt_reg, cnt_reg, unroll); 2443 for (int i = -unroll; i < 0; i++) 2444 __ str(zr, Address(base_reg, i * wordSize)); 2445 __ bind(entry); 2446 __ add(base_reg, base_reg, unroll * wordSize); 2447 __ cbnz(cnt_reg, loop); 2448 %} 2449 2450 /// mov envcodings 2451 2452 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 2453 MacroAssembler _masm(&cbuf); 2454 u_int32_t con = (u_int32_t)$src$$constant; 2455 Register dst_reg = as_Register($dst$$reg); 2456 if (con == 0) { 2457 __ movw(dst_reg, zr); 2458 } else { 2459 __ movw(dst_reg, con); 2460 } 2461 %} 2462 2463 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 2464 MacroAssembler _masm(&cbuf); 2465 Register dst_reg = as_Register($dst$$reg); 2466 u_int64_t con = (u_int64_t)$src$$constant; 2467 if (con == 0) { 2468 __ mov(dst_reg, zr); 2469 } else { 2470 __ mov(dst_reg, con); 2471 } 2472 %} 2473 2474 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 2475 MacroAssembler _masm(&cbuf); 2476 Register dst_reg = as_Register($dst$$reg); 2477 address con = (address)$src$$constant; 2478 if (con == NULL || con == (address)1) { 2479 ShouldNotReachHere(); 2480 } else { 2481 relocInfo::relocType rtype = $src->constant_reloc(); 2482 if (rtype == relocInfo::oop_type) { 2483 __ movoop(dst_reg, (jobject)con, /*immediate*/true); 2484 } else if (rtype == relocInfo::metadata_type) { 2485 __ mov_metadata(dst_reg, (Metadata*)con); 2486 } else { 2487 assert(rtype == relocInfo::none, "unexpected reloc type"); 2488 if (con < (address)(uintptr_t)os::vm_page_size()) { 2489 __ mov(dst_reg, con); 2490 } else { 2491 unsigned long offset; 2492 __ adrp(dst_reg, con, offset); 2493 __ add(dst_reg, dst_reg, offset); 2494 } 2495 } 2496 } 2497 %} 2498 2499 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 2500 MacroAssembler _masm(&cbuf); 2501 Register dst_reg = as_Register($dst$$reg); 2502 __ mov(dst_reg, zr); 2503 %} 2504 2505 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 2506 MacroAssembler _masm(&cbuf); 2507 Register dst_reg = as_Register($dst$$reg); 2508 __ mov(dst_reg, (u_int64_t)1); 2509 %} 2510 2511 enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{ 2512 MacroAssembler _masm(&cbuf); 2513 address page = (address)$src$$constant; 2514 Register dst_reg = as_Register($dst$$reg); 2515 unsigned long off; 2516 __ adrp(dst_reg, Address(page, relocInfo::poll_type), off); 2517 assert(off == 0, "assumed offset == 0"); 2518 %} 2519 2520 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 2521 MacroAssembler _masm(&cbuf); 2522 address page = (address)$src$$constant; 2523 Register dst_reg = as_Register($dst$$reg); 2524 unsigned long off; 2525 __ adrp(dst_reg, ExternalAddress(page), off); 2526 assert(off == 0, "assumed offset == 0"); 2527 %} 2528 2529 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 2530 MacroAssembler _masm(&cbuf); 2531 Register dst_reg = as_Register($dst$$reg); 2532 address con = (address)$src$$constant; 2533 if (con == NULL) { 2534 ShouldNotReachHere(); 2535 } else { 2536 relocInfo::relocType rtype = $src->constant_reloc(); 2537 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 2538 __ set_narrow_oop(dst_reg, (jobject)con); 2539 } 2540 %} 2541 2542 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 2543 MacroAssembler _masm(&cbuf); 2544 Register dst_reg = as_Register($dst$$reg); 2545 __ mov(dst_reg, zr); 2546 %} 2547 2548 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 2549 MacroAssembler _masm(&cbuf); 2550 Register dst_reg = as_Register($dst$$reg); 2551 address con = (address)$src$$constant; 2552 if (con == NULL) { 2553 ShouldNotReachHere(); 2554 } else { 2555 relocInfo::relocType rtype = $src->constant_reloc(); 2556 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 2557 __ set_narrow_klass(dst_reg, (Klass *)con); 2558 } 2559 %} 2560 2561 // arithmetic encodings 2562 2563 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 2564 MacroAssembler _masm(&cbuf); 2565 Register dst_reg = as_Register($dst$$reg); 2566 Register src_reg = as_Register($src1$$reg); 2567 int32_t con = (int32_t)$src2$$constant; 2568 // add has primary == 0, subtract has primary == 1 2569 if ($primary) { con = -con; } 2570 if (con < 0) { 2571 __ subw(dst_reg, src_reg, -con); 2572 } else { 2573 __ addw(dst_reg, src_reg, con); 2574 } 2575 %} 2576 2577 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 2578 MacroAssembler _masm(&cbuf); 2579 Register dst_reg = as_Register($dst$$reg); 2580 Register src_reg = as_Register($src1$$reg); 2581 int32_t con = (int32_t)$src2$$constant; 2582 // add has primary == 0, subtract has primary == 1 2583 if ($primary) { con = -con; } 2584 if (con < 0) { 2585 __ sub(dst_reg, src_reg, -con); 2586 } else { 2587 __ add(dst_reg, src_reg, con); 2588 } 2589 %} 2590 2591 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 2592 MacroAssembler _masm(&cbuf); 2593 Register dst_reg = as_Register($dst$$reg); 2594 Register src1_reg = as_Register($src1$$reg); 2595 Register src2_reg = as_Register($src2$$reg); 2596 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 2597 %} 2598 2599 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 2600 MacroAssembler _masm(&cbuf); 2601 Register dst_reg = as_Register($dst$$reg); 2602 Register src1_reg = as_Register($src1$$reg); 2603 Register src2_reg = as_Register($src2$$reg); 2604 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 2605 %} 2606 2607 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 2608 MacroAssembler _masm(&cbuf); 2609 Register dst_reg = as_Register($dst$$reg); 2610 Register src1_reg = as_Register($src1$$reg); 2611 Register src2_reg = as_Register($src2$$reg); 2612 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 2613 %} 2614 2615 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 2616 MacroAssembler _masm(&cbuf); 2617 Register dst_reg = as_Register($dst$$reg); 2618 Register src1_reg = as_Register($src1$$reg); 2619 Register src2_reg = as_Register($src2$$reg); 2620 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 2621 %} 2622 2623 // compare instruction encodings 2624 2625 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 2626 MacroAssembler _masm(&cbuf); 2627 Register reg1 = as_Register($src1$$reg); 2628 Register reg2 = as_Register($src2$$reg); 2629 __ cmpw(reg1, reg2); 2630 %} 2631 2632 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 2633 MacroAssembler _masm(&cbuf); 2634 Register reg = as_Register($src1$$reg); 2635 int32_t val = $src2$$constant; 2636 if (val >= 0) { 2637 __ subsw(zr, reg, val); 2638 } else { 2639 __ addsw(zr, reg, -val); 2640 } 2641 %} 2642 2643 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 2644 MacroAssembler _masm(&cbuf); 2645 Register reg1 = as_Register($src1$$reg); 2646 u_int32_t val = (u_int32_t)$src2$$constant; 2647 __ movw(rscratch1, val); 2648 __ cmpw(reg1, rscratch1); 2649 %} 2650 2651 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 2652 MacroAssembler _masm(&cbuf); 2653 Register reg1 = as_Register($src1$$reg); 2654 Register reg2 = as_Register($src2$$reg); 2655 __ cmp(reg1, reg2); 2656 %} 2657 2658 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 2659 MacroAssembler _masm(&cbuf); 2660 Register reg = as_Register($src1$$reg); 2661 int64_t val = $src2$$constant; 2662 if (val >= 0) { 2663 __ subs(zr, reg, val); 2664 } else if (val != -val) { 2665 __ adds(zr, reg, -val); 2666 } else { 2667 // aargh, Long.MIN_VALUE is a special case 2668 __ orr(rscratch1, zr, (u_int64_t)val); 2669 __ subs(zr, reg, rscratch1); 2670 } 2671 %} 2672 2673 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 2674 MacroAssembler _masm(&cbuf); 2675 Register reg1 = as_Register($src1$$reg); 2676 u_int64_t val = (u_int64_t)$src2$$constant; 2677 __ mov(rscratch1, val); 2678 __ cmp(reg1, rscratch1); 2679 %} 2680 2681 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 2682 MacroAssembler _masm(&cbuf); 2683 Register reg1 = as_Register($src1$$reg); 2684 Register reg2 = as_Register($src2$$reg); 2685 __ cmp(reg1, reg2); 2686 %} 2687 2688 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 2689 MacroAssembler _masm(&cbuf); 2690 Register reg1 = as_Register($src1$$reg); 2691 Register reg2 = as_Register($src2$$reg); 2692 __ cmpw(reg1, reg2); 2693 %} 2694 2695 enc_class aarch64_enc_testp(iRegP src) %{ 2696 MacroAssembler _masm(&cbuf); 2697 Register reg = as_Register($src$$reg); 2698 __ cmp(reg, zr); 2699 %} 2700 2701 enc_class aarch64_enc_testn(iRegN src) %{ 2702 MacroAssembler _masm(&cbuf); 2703 Register reg = as_Register($src$$reg); 2704 __ cmpw(reg, zr); 2705 %} 2706 2707 enc_class aarch64_enc_b(label lbl) %{ 2708 MacroAssembler _masm(&cbuf); 2709 Label *L = $lbl$$label; 2710 __ b(*L); 2711 %} 2712 2713 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 2714 MacroAssembler _masm(&cbuf); 2715 Label *L = $lbl$$label; 2716 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 2717 %} 2718 2719 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 2720 MacroAssembler _masm(&cbuf); 2721 Label *L = $lbl$$label; 2722 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 2723 %} 2724 2725 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 2726 %{ 2727 Register sub_reg = as_Register($sub$$reg); 2728 Register super_reg = as_Register($super$$reg); 2729 Register temp_reg = as_Register($temp$$reg); 2730 Register result_reg = as_Register($result$$reg); 2731 2732 Label miss; 2733 MacroAssembler _masm(&cbuf); 2734 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 2735 NULL, &miss, 2736 /*set_cond_codes:*/ true); 2737 if ($primary) { 2738 __ mov(result_reg, zr); 2739 } 2740 __ bind(miss); 2741 %} 2742 2743 enc_class aarch64_enc_java_static_call(method meth) %{ 2744 MacroAssembler _masm(&cbuf); 2745 2746 address addr = (address)$meth$$method; 2747 if (!_method) { 2748 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 2749 __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 2750 } else if (_optimized_virtual) { 2751 __ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf); 2752 } else { 2753 __ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf); 2754 } 2755 2756 if (_method) { 2757 // Emit stub for static call 2758 CompiledStaticCall::emit_to_interp_stub(cbuf); 2759 } 2760 %} 2761 2762 enc_class aarch64_enc_java_handle_call(method meth) %{ 2763 MacroAssembler _masm(&cbuf); 2764 relocInfo::relocType reloc; 2765 2766 // RFP is preserved across all calls, even compiled calls. 2767 // Use it to preserve SP. 2768 __ mov(rfp, sp); 2769 2770 const int start_offset = __ offset(); 2771 address addr = (address)$meth$$method; 2772 if (!_method) { 2773 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 2774 __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf); 2775 } else if (_optimized_virtual) { 2776 __ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf); 2777 } else { 2778 __ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf); 2779 } 2780 2781 if (_method) { 2782 // Emit stub for static call 2783 CompiledStaticCall::emit_to_interp_stub(cbuf); 2784 } 2785 2786 // now restore sp 2787 __ mov(sp, rfp); 2788 %} 2789 2790 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 2791 MacroAssembler _masm(&cbuf); 2792 __ ic_call((address)$meth$$method); 2793 %} 2794 2795 enc_class aarch64_enc_call_epilog() %{ 2796 MacroAssembler _masm(&cbuf); 2797 if (VerifyStackAtCalls) { 2798 // Check that stack depth is unchanged: find majik cookie on stack 2799 __ call_Unimplemented(); 2800 } 2801 %} 2802 2803 enc_class aarch64_enc_java_to_runtime(method meth) %{ 2804 MacroAssembler _masm(&cbuf); 2805 2806 // some calls to generated routines (arraycopy code) are scheduled 2807 // by C2 as runtime calls. if so we can call them using a br (they 2808 // will be in a reachable segment) otherwise we have to use a blrt 2809 // which loads the absolute address into a register. 2810 address entry = (address)$meth$$method; 2811 CodeBlob *cb = CodeCache::find_blob(entry); 2812 if (cb) { 2813 __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 2814 } else { 2815 int gpcnt; 2816 int fpcnt; 2817 int rtype; 2818 getCallInfo(tf(), gpcnt, fpcnt, rtype); 2819 Label retaddr; 2820 __ adr(rscratch2, retaddr); 2821 __ lea(rscratch1, RuntimeAddress(entry)); 2822 // Leave a breadcrumb for JavaThread::pd_last_frame(). 2823 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 2824 __ blrt(rscratch1, gpcnt, fpcnt, rtype); 2825 __ bind(retaddr); 2826 __ add(sp, sp, 2 * wordSize); 2827 } 2828 %} 2829 2830 enc_class aarch64_enc_rethrow() %{ 2831 MacroAssembler _masm(&cbuf); 2832 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 2833 %} 2834 2835 enc_class aarch64_enc_ret() %{ 2836 MacroAssembler _masm(&cbuf); 2837 __ ret(lr); 2838 %} 2839 2840 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 2841 MacroAssembler _masm(&cbuf); 2842 Register target_reg = as_Register($jump_target$$reg); 2843 __ br(target_reg); 2844 %} 2845 2846 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 2847 MacroAssembler _masm(&cbuf); 2848 Register target_reg = as_Register($jump_target$$reg); 2849 // exception oop should be in r0 2850 // ret addr has been popped into lr 2851 // callee expects it in r3 2852 __ mov(r3, lr); 2853 __ br(target_reg); 2854 %} 2855 2856 enc_class aarch64_enc_fast_lock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 2857 MacroAssembler _masm(&cbuf); 2858 Register oop = as_Register($object$$reg); 2859 Register box = as_Register($box$$reg); 2860 Register disp_hdr = as_Register($tmp$$reg); 2861 Register tmp = as_Register($tmp2$$reg); 2862 Label cont; 2863 Label object_has_monitor; 2864 Label cas_failed; 2865 2866 assert_different_registers(oop, box, tmp, disp_hdr); 2867 2868 // Load markOop from object into displaced_header. 2869 __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); 2870 2871 // Always do locking in runtime. 2872 if (EmitSync & 0x01) { 2873 __ cmp(oop, zr); 2874 return; 2875 } 2876 2877 if (UseBiasedLocking) { 2878 __ biased_locking_enter(disp_hdr, oop, box, tmp, true, cont); 2879 } 2880 2881 // Handle existing monitor 2882 if (EmitSync & 0x02) { 2883 // we can use AArch64's bit test and branch here but 2884 // markoopDesc does not define a bit index just the bit value 2885 // so assert in case the bit pos changes 2886 # define __monitor_value_log2 1 2887 assert(markOopDesc::monitor_value == (1 << __monitor_value_log2), "incorrect bit position"); 2888 __ tbnz(disp_hdr, __monitor_value_log2, object_has_monitor); 2889 # undef __monitor_value_log2 2890 } 2891 2892 // Set displaced_header to be (markOop of object | UNLOCK_VALUE). 2893 __ orr(disp_hdr, disp_hdr, markOopDesc::unlocked_value); 2894 2895 // Load Compare Value application register. 2896 2897 // Initialize the box. (Must happen before we update the object mark!) 2898 __ str(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 2899 2900 // Compare object markOop with mark and if equal exchange scratch1 2901 // with object markOop. 2902 // Note that this is simply a CAS: it does not generate any 2903 // barriers. These are separately generated by 2904 // membar_acquire_lock(). 2905 { 2906 Label retry_load; 2907 __ bind(retry_load); 2908 __ ldxr(tmp, oop); 2909 __ cmp(tmp, disp_hdr); 2910 __ br(Assembler::NE, cas_failed); 2911 __ stxr(tmp, box, oop); 2912 __ cbzw(tmp, cont); 2913 __ b(retry_load); 2914 } 2915 2916 // Formerly: 2917 // __ cmpxchgptr(/*oldv=*/disp_hdr, 2918 // /*newv=*/box, 2919 // /*addr=*/oop, 2920 // /*tmp=*/tmp, 2921 // cont, 2922 // /*fail*/NULL); 2923 2924 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 2925 2926 // If the compare-and-exchange succeeded, then we found an unlocked 2927 // object, will have now locked it will continue at label cont 2928 2929 __ bind(cas_failed); 2930 // We did not see an unlocked object so try the fast recursive case. 2931 2932 // Check if the owner is self by comparing the value in the 2933 // markOop of object (disp_hdr) with the stack pointer. 2934 __ mov(rscratch1, sp); 2935 __ sub(disp_hdr, disp_hdr, rscratch1); 2936 __ mov(tmp, (address) (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place)); 2937 // If condition is true we are cont and hence we can store 0 as the 2938 // displaced header in the box, which indicates that it is a recursive lock. 2939 __ ands(tmp/*==0?*/, disp_hdr, tmp); 2940 __ str(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes())); 2941 2942 // Handle existing monitor. 2943 if ((EmitSync & 0x02) == 0) { 2944 __ b(cont); 2945 2946 __ bind(object_has_monitor); 2947 // The object's monitor m is unlocked iff m->owner == NULL, 2948 // otherwise m->owner may contain a thread or a stack address. 2949 // 2950 // Try to CAS m->owner from NULL to current thread. 2951 __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value)); 2952 __ mov(disp_hdr, zr); 2953 2954 { 2955 Label retry_load, fail; 2956 __ bind(retry_load); 2957 __ ldxr(rscratch1, tmp); 2958 __ cmp(disp_hdr, rscratch1); 2959 __ br(Assembler::NE, fail); 2960 __ stxr(rscratch1, rthread, tmp); 2961 __ cbnzw(rscratch1, retry_load); 2962 __ bind(fail); 2963 } 2964 2965 // Label next; 2966 // __ cmpxchgptr(/*oldv=*/disp_hdr, 2967 // /*newv=*/rthread, 2968 // /*addr=*/tmp, 2969 // /*tmp=*/rscratch1, 2970 // /*succeed*/next, 2971 // /*fail*/NULL); 2972 // __ bind(next); 2973 2974 // store a non-null value into the box. 2975 __ str(box, Address(box, BasicLock::displaced_header_offset_in_bytes())); 2976 2977 // PPC port checks the following invariants 2978 // #ifdef ASSERT 2979 // bne(flag, cont); 2980 // We have acquired the monitor, check some invariants. 2981 // addw(/*monitor=*/tmp, tmp, -ObjectMonitor::owner_offset_in_bytes()); 2982 // Invariant 1: _recursions should be 0. 2983 // assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size"); 2984 // assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), tmp, 2985 // "monitor->_recursions should be 0", -1); 2986 // Invariant 2: OwnerIsThread shouldn't be 0. 2987 // assert(ObjectMonitor::OwnerIsThread_size_in_bytes() == 4, "unexpected size"); 2988 //assert_mem4_isnot_zero(ObjectMonitor::OwnerIsThread_offset_in_bytes(), tmp, 2989 // "monitor->OwnerIsThread shouldn't be 0", -1); 2990 // #endif 2991 } 2992 2993 __ bind(cont); 2994 // flag == EQ indicates success 2995 // flag == NE indicates failure 2996 2997 %} 2998 2999 // TODO 3000 // reimplement this with custom cmpxchgptr code 3001 // which avoids some of the unnecessary branching 3002 enc_class aarch64_enc_fast_unlock(iRegP object, iRegP box, iRegP tmp, iRegP tmp2) %{ 3003 MacroAssembler _masm(&cbuf); 3004 Register oop = as_Register($object$$reg); 3005 Register box = as_Register($box$$reg); 3006 Register disp_hdr = as_Register($tmp$$reg); 3007 Register tmp = as_Register($tmp2$$reg); 3008 Label cont; 3009 Label object_has_monitor; 3010 Label cas_failed; 3011 3012 assert_different_registers(oop, box, tmp, disp_hdr); 3013 3014 // Always do locking in runtime. 3015 if (EmitSync & 0x01) { 3016 __ cmp(oop, zr); // Oop can't be 0 here => always false. 3017 return; 3018 } 3019 3020 if (UseBiasedLocking) { 3021 __ biased_locking_exit(oop, tmp, cont); 3022 } 3023 3024 // Find the lock address and load the displaced header from the stack. 3025 __ ldr(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes())); 3026 3027 // If the displaced header is 0, we have a recursive unlock. 3028 __ cmp(disp_hdr, zr); 3029 __ br(Assembler::EQ, cont); 3030 3031 3032 // Handle existing monitor. 3033 if ((EmitSync & 0x02) == 0) { 3034 __ ldr(tmp, Address(oop, oopDesc::mark_offset_in_bytes())); 3035 __ tbnz(disp_hdr, exact_log2(markOopDesc::monitor_value), object_has_monitor); 3036 } 3037 3038 // Check if it is still a light weight lock, this is is true if we 3039 // see the stack address of the basicLock in the markOop of the 3040 // object. 3041 3042 { 3043 Label retry_load; 3044 __ bind(retry_load); 3045 __ ldxr(tmp, oop); 3046 __ cmp(box, tmp); 3047 __ br(Assembler::NE, cas_failed); 3048 __ stxr(tmp, disp_hdr, oop); 3049 __ cbzw(tmp, cont); 3050 __ b(retry_load); 3051 } 3052 3053 // __ cmpxchgptr(/*compare_value=*/box, 3054 // /*exchange_value=*/disp_hdr, 3055 // /*where=*/oop, 3056 // /*result=*/tmp, 3057 // cont, 3058 // /*cas_failed*/NULL); 3059 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 3060 3061 __ bind(cas_failed); 3062 3063 // Handle existing monitor. 3064 if ((EmitSync & 0x02) == 0) { 3065 __ b(cont); 3066 3067 __ bind(object_has_monitor); 3068 __ add(tmp, tmp, -markOopDesc::monitor_value); // monitor 3069 __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3070 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); 3071 __ eor(rscratch1, rscratch1, rthread); // Will be 0 if we are the owner. 3072 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if there are 0 recursions 3073 __ cmp(rscratch1, zr); 3074 __ br(Assembler::NE, cont); 3075 3076 __ ldr(rscratch1, Address(tmp, ObjectMonitor::EntryList_offset_in_bytes())); 3077 __ ldr(disp_hdr, Address(tmp, ObjectMonitor::cxq_offset_in_bytes())); 3078 __ orr(rscratch1, rscratch1, disp_hdr); // Will be 0 if both are 0. 3079 __ cmp(rscratch1, zr); 3080 __ cbnz(rscratch1, cont); 3081 // need a release store here 3082 __ lea(tmp, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); 3083 __ stlr(rscratch1, tmp); // rscratch1 is zero 3084 } 3085 3086 __ bind(cont); 3087 // flag == EQ indicates success 3088 // flag == NE indicates failure 3089 %} 3090 3091 %} 3092 3093 //----------FRAME-------------------------------------------------------------- 3094 // Definition of frame structure and management information. 3095 // 3096 // S T A C K L A Y O U T Allocators stack-slot number 3097 // | (to get allocators register number 3098 // G Owned by | | v add OptoReg::stack0()) 3099 // r CALLER | | 3100 // o | +--------+ pad to even-align allocators stack-slot 3101 // w V | pad0 | numbers; owned by CALLER 3102 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3103 // h ^ | in | 5 3104 // | | args | 4 Holes in incoming args owned by SELF 3105 // | | | | 3 3106 // | | +--------+ 3107 // V | | old out| Empty on Intel, window on Sparc 3108 // | old |preserve| Must be even aligned. 3109 // | SP-+--------+----> Matcher::_old_SP, even aligned 3110 // | | in | 3 area for Intel ret address 3111 // Owned by |preserve| Empty on Sparc. 3112 // SELF +--------+ 3113 // | | pad2 | 2 pad to align old SP 3114 // | +--------+ 1 3115 // | | locks | 0 3116 // | +--------+----> OptoReg::stack0(), even aligned 3117 // | | pad1 | 11 pad to align new SP 3118 // | +--------+ 3119 // | | | 10 3120 // | | spills | 9 spills 3121 // V | | 8 (pad0 slot for callee) 3122 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3123 // ^ | out | 7 3124 // | | args | 6 Holes in outgoing args owned by CALLEE 3125 // Owned by +--------+ 3126 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3127 // | new |preserve| Must be even-aligned. 3128 // | SP-+--------+----> Matcher::_new_SP, even aligned 3129 // | | | 3130 // 3131 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3132 // known from SELF's arguments and the Java calling convention. 3133 // Region 6-7 is determined per call site. 3134 // Note 2: If the calling convention leaves holes in the incoming argument 3135 // area, those holes are owned by SELF. Holes in the outgoing area 3136 // are owned by the CALLEE. Holes should not be nessecary in the 3137 // incoming area, as the Java calling convention is completely under 3138 // the control of the AD file. Doubles can be sorted and packed to 3139 // avoid holes. Holes in the outgoing arguments may be nessecary for 3140 // varargs C calling conventions. 3141 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3142 // even aligned with pad0 as needed. 3143 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3144 // (the latter is true on Intel but is it false on AArch64?) 3145 // region 6-11 is even aligned; it may be padded out more so that 3146 // the region from SP to FP meets the minimum stack alignment. 3147 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3148 // alignment. Region 11, pad1, may be dynamically extended so that 3149 // SP meets the minimum alignment. 3150 3151 frame %{ 3152 // What direction does stack grow in (assumed to be same for C & Java) 3153 stack_direction(TOWARDS_LOW); 3154 3155 // These three registers define part of the calling convention 3156 // between compiled code and the interpreter. 3157 3158 // Inline Cache Register or methodOop for I2C. 3159 inline_cache_reg(R12); 3160 3161 // Method Oop Register when calling interpreter. 3162 interpreter_method_oop_reg(R12); 3163 3164 // Number of stack slots consumed by locking an object 3165 sync_stack_slots(2); 3166 3167 // Compiled code's Frame Pointer 3168 frame_pointer(R31); 3169 3170 // Interpreter stores its frame pointer in a register which is 3171 // stored to the stack by I2CAdaptors. 3172 // I2CAdaptors convert from interpreted java to compiled java. 3173 interpreter_frame_pointer(R29); 3174 3175 // Stack alignment requirement 3176 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3177 3178 // Number of stack slots between incoming argument block and the start of 3179 // a new frame. The PROLOG must add this many slots to the stack. The 3180 // EPILOG must remove this many slots. aarch64 needs two slots for 3181 // return address and fp. 3182 // TODO think this is correct but check 3183 in_preserve_stack_slots(4); 3184 3185 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3186 // for calls to C. Supports the var-args backing area for register parms. 3187 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3188 3189 // The after-PROLOG location of the return address. Location of 3190 // return address specifies a type (REG or STACK) and a number 3191 // representing the register number (i.e. - use a register name) or 3192 // stack slot. 3193 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3194 // Otherwise, it is above the locks and verification slot and alignment word 3195 // TODO this may well be correct but need to check why that - 2 is there 3196 // ppc port uses 0 but we definitely need to allow for fixed_slots 3197 // which folds in the space used for monitors 3198 return_addr(STACK - 2 + 3199 round_to((Compile::current()->in_preserve_stack_slots() + 3200 Compile::current()->fixed_slots()), 3201 stack_alignment_in_slots())); 3202 3203 // Body of function which returns an integer array locating 3204 // arguments either in registers or in stack slots. Passed an array 3205 // of ideal registers called "sig" and a "length" count. Stack-slot 3206 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3207 // arguments for a CALLEE. Incoming stack arguments are 3208 // automatically biased by the preserve_stack_slots field above. 3209 3210 calling_convention 3211 %{ 3212 // No difference between ingoing/outgoing just pass false 3213 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3214 %} 3215 3216 c_calling_convention 3217 %{ 3218 // This is obviously always outgoing 3219 (void) SharedRuntime::c_calling_convention(sig_bt, regs, NULL, length); 3220 %} 3221 3222 // Location of compiled Java return values. Same as C for now. 3223 return_value 3224 %{ 3225 // TODO do we allow ideal_reg == Op_RegN??? 3226 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3227 "only return normal values"); 3228 3229 static const int lo[Op_RegL + 1] = { // enum name 3230 0, // Op_Node 3231 0, // Op_Set 3232 R0_num, // Op_RegN 3233 R0_num, // Op_RegI 3234 R0_num, // Op_RegP 3235 V0_num, // Op_RegF 3236 V0_num, // Op_RegD 3237 R0_num // Op_RegL 3238 }; 3239 3240 static const int hi[Op_RegL + 1] = { // enum name 3241 0, // Op_Node 3242 0, // Op_Set 3243 OptoReg::Bad, // Op_RegN 3244 OptoReg::Bad, // Op_RegI 3245 R0_H_num, // Op_RegP 3246 OptoReg::Bad, // Op_RegF 3247 V0_H_num, // Op_RegD 3248 R0_H_num // Op_RegL 3249 }; 3250 3251 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3252 %} 3253 %} 3254 3255 //----------ATTRIBUTES--------------------------------------------------------- 3256 //----------Operand Attributes------------------------------------------------- 3257 op_attrib op_cost(1); // Required cost attribute 3258 3259 //----------Instruction Attributes--------------------------------------------- 3260 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3261 ins_attrib ins_size(32); // Required size attribute (in bits) 3262 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3263 // a non-matching short branch variant 3264 // of some long branch? 3265 ins_attrib ins_alignment(4); // Required alignment attribute (must 3266 // be a power of 2) specifies the 3267 // alignment that some part of the 3268 // instruction (not necessarily the 3269 // start) requires. If > 1, a 3270 // compute_padding() function must be 3271 // provided for the instruction 3272 3273 //----------OPERANDS----------------------------------------------------------- 3274 // Operand definitions must precede instruction definitions for correct parsing 3275 // in the ADLC because operands constitute user defined types which are used in 3276 // instruction definitions. 3277 3278 //----------Simple Operands---------------------------------------------------- 3279 3280 // Integer operands 32 bit 3281 // 32 bit immediate 3282 operand immI() 3283 %{ 3284 match(ConI); 3285 3286 op_cost(0); 3287 format %{ %} 3288 interface(CONST_INTER); 3289 %} 3290 3291 // 32 bit zero 3292 operand immI0() 3293 %{ 3294 predicate(n->get_int() == 0); 3295 match(ConI); 3296 3297 op_cost(0); 3298 format %{ %} 3299 interface(CONST_INTER); 3300 %} 3301 3302 // 32 bit unit increment 3303 operand immI_1() 3304 %{ 3305 predicate(n->get_int() == 1); 3306 match(ConI); 3307 3308 op_cost(0); 3309 format %{ %} 3310 interface(CONST_INTER); 3311 %} 3312 3313 // 32 bit unit decrement 3314 operand immI_M1() 3315 %{ 3316 predicate(n->get_int() == -1); 3317 match(ConI); 3318 3319 op_cost(0); 3320 format %{ %} 3321 interface(CONST_INTER); 3322 %} 3323 3324 operand immI_le_4() 3325 %{ 3326 predicate(n->get_int() <= 4); 3327 match(ConI); 3328 3329 op_cost(0); 3330 format %{ %} 3331 interface(CONST_INTER); 3332 %} 3333 3334 operand immI_31() 3335 %{ 3336 predicate(n->get_int() == 31); 3337 match(ConI); 3338 3339 op_cost(0); 3340 format %{ %} 3341 interface(CONST_INTER); 3342 %} 3343 3344 operand immI_8() 3345 %{ 3346 predicate(n->get_int() == 8); 3347 match(ConI); 3348 3349 op_cost(0); 3350 format %{ %} 3351 interface(CONST_INTER); 3352 %} 3353 3354 operand immI_16() 3355 %{ 3356 predicate(n->get_int() == 16); 3357 match(ConI); 3358 3359 op_cost(0); 3360 format %{ %} 3361 interface(CONST_INTER); 3362 %} 3363 3364 operand immI_24() 3365 %{ 3366 predicate(n->get_int() == 24); 3367 match(ConI); 3368 3369 op_cost(0); 3370 format %{ %} 3371 interface(CONST_INTER); 3372 %} 3373 3374 operand immI_32() 3375 %{ 3376 predicate(n->get_int() == 32); 3377 match(ConI); 3378 3379 op_cost(0); 3380 format %{ %} 3381 interface(CONST_INTER); 3382 %} 3383 3384 operand immI_48() 3385 %{ 3386 predicate(n->get_int() == 48); 3387 match(ConI); 3388 3389 op_cost(0); 3390 format %{ %} 3391 interface(CONST_INTER); 3392 %} 3393 3394 operand immI_56() 3395 %{ 3396 predicate(n->get_int() == 56); 3397 match(ConI); 3398 3399 op_cost(0); 3400 format %{ %} 3401 interface(CONST_INTER); 3402 %} 3403 3404 operand immI_64() 3405 %{ 3406 predicate(n->get_int() == 64); 3407 match(ConI); 3408 3409 op_cost(0); 3410 format %{ %} 3411 interface(CONST_INTER); 3412 %} 3413 3414 operand immI_255() 3415 %{ 3416 predicate(n->get_int() == 255); 3417 match(ConI); 3418 3419 op_cost(0); 3420 format %{ %} 3421 interface(CONST_INTER); 3422 %} 3423 3424 operand immI_65535() 3425 %{ 3426 predicate(n->get_int() == 65535); 3427 match(ConI); 3428 3429 op_cost(0); 3430 format %{ %} 3431 interface(CONST_INTER); 3432 %} 3433 3434 operand immL_63() 3435 %{ 3436 predicate(n->get_int() == 63); 3437 match(ConI); 3438 3439 op_cost(0); 3440 format %{ %} 3441 interface(CONST_INTER); 3442 %} 3443 3444 operand immL_255() 3445 %{ 3446 predicate(n->get_int() == 255); 3447 match(ConI); 3448 3449 op_cost(0); 3450 format %{ %} 3451 interface(CONST_INTER); 3452 %} 3453 3454 operand immL_65535() 3455 %{ 3456 predicate(n->get_long() == 65535L); 3457 match(ConL); 3458 3459 op_cost(0); 3460 format %{ %} 3461 interface(CONST_INTER); 3462 %} 3463 3464 operand immL_4294967295() 3465 %{ 3466 predicate(n->get_long() == 4294967295L); 3467 match(ConL); 3468 3469 op_cost(0); 3470 format %{ %} 3471 interface(CONST_INTER); 3472 %} 3473 3474 operand immL_bitmask() 3475 %{ 3476 predicate(((n->get_long() & 0xc000000000000000l) == 0) 3477 && is_power_of_2(n->get_long() + 1)); 3478 match(ConL); 3479 3480 op_cost(0); 3481 format %{ %} 3482 interface(CONST_INTER); 3483 %} 3484 3485 operand immI_bitmask() 3486 %{ 3487 predicate(((n->get_int() & 0xc0000000) == 0) 3488 && is_power_of_2(n->get_int() + 1)); 3489 match(ConI); 3490 3491 op_cost(0); 3492 format %{ %} 3493 interface(CONST_INTER); 3494 %} 3495 3496 // Scale values for scaled offset addressing modes (up to long but not quad) 3497 operand immIScale() 3498 %{ 3499 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3500 match(ConI); 3501 3502 op_cost(0); 3503 format %{ %} 3504 interface(CONST_INTER); 3505 %} 3506 3507 // 26 bit signed offset -- for pc-relative branches 3508 operand immI26() 3509 %{ 3510 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 3511 match(ConI); 3512 3513 op_cost(0); 3514 format %{ %} 3515 interface(CONST_INTER); 3516 %} 3517 3518 // 19 bit signed offset -- for pc-relative loads 3519 operand immI19() 3520 %{ 3521 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 3522 match(ConI); 3523 3524 op_cost(0); 3525 format %{ %} 3526 interface(CONST_INTER); 3527 %} 3528 3529 // 12 bit unsigned offset -- for base plus immediate loads 3530 operand immIU12() 3531 %{ 3532 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 3533 match(ConI); 3534 3535 op_cost(0); 3536 format %{ %} 3537 interface(CONST_INTER); 3538 %} 3539 3540 operand immLU12() 3541 %{ 3542 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 3543 match(ConL); 3544 3545 op_cost(0); 3546 format %{ %} 3547 interface(CONST_INTER); 3548 %} 3549 3550 // Offset for scaled or unscaled immediate loads and stores 3551 operand immIOffset() 3552 %{ 3553 predicate(Address::offset_ok_for_immed(n->get_int())); 3554 match(ConI); 3555 3556 op_cost(0); 3557 format %{ %} 3558 interface(CONST_INTER); 3559 %} 3560 3561 operand immLoffset() 3562 %{ 3563 predicate(Address::offset_ok_for_immed(n->get_long())); 3564 match(ConL); 3565 3566 op_cost(0); 3567 format %{ %} 3568 interface(CONST_INTER); 3569 %} 3570 3571 // 32 bit integer valid for add sub immediate 3572 operand immIAddSub() 3573 %{ 3574 predicate(Assembler::operand_valid_for_add_sub_immediate((long)n->get_int())); 3575 match(ConI); 3576 op_cost(0); 3577 format %{ %} 3578 interface(CONST_INTER); 3579 %} 3580 3581 // 32 bit unsigned integer valid for logical immediate 3582 // TODO -- check this is right when e.g the mask is 0x80000000 3583 operand immILog() 3584 %{ 3585 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (unsigned long)n->get_int())); 3586 match(ConI); 3587 3588 op_cost(0); 3589 format %{ %} 3590 interface(CONST_INTER); 3591 %} 3592 3593 // Integer operands 64 bit 3594 // 64 bit immediate 3595 operand immL() 3596 %{ 3597 match(ConL); 3598 3599 op_cost(0); 3600 format %{ %} 3601 interface(CONST_INTER); 3602 %} 3603 3604 // 64 bit zero 3605 operand immL0() 3606 %{ 3607 predicate(n->get_long() == 0); 3608 match(ConL); 3609 3610 op_cost(0); 3611 format %{ %} 3612 interface(CONST_INTER); 3613 %} 3614 3615 // 64 bit unit increment 3616 operand immL_1() 3617 %{ 3618 predicate(n->get_long() == 1); 3619 match(ConL); 3620 3621 op_cost(0); 3622 format %{ %} 3623 interface(CONST_INTER); 3624 %} 3625 3626 // 64 bit unit decrement 3627 operand immL_M1() 3628 %{ 3629 predicate(n->get_long() == -1); 3630 match(ConL); 3631 3632 op_cost(0); 3633 format %{ %} 3634 interface(CONST_INTER); 3635 %} 3636 3637 // 32 bit offset of pc in thread anchor 3638 3639 operand immL_pc_off() 3640 %{ 3641 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 3642 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 3643 match(ConL); 3644 3645 op_cost(0); 3646 format %{ %} 3647 interface(CONST_INTER); 3648 %} 3649 3650 // 64 bit integer valid for add sub immediate 3651 operand immLAddSub() 3652 %{ 3653 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 3654 match(ConL); 3655 op_cost(0); 3656 format %{ %} 3657 interface(CONST_INTER); 3658 %} 3659 3660 // 64 bit integer valid for logical immediate 3661 operand immLLog() 3662 %{ 3663 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (unsigned long)n->get_long())); 3664 match(ConL); 3665 op_cost(0); 3666 format %{ %} 3667 interface(CONST_INTER); 3668 %} 3669 3670 // Long Immediate: low 32-bit mask 3671 operand immL_32bits() 3672 %{ 3673 predicate(n->get_long() == 0xFFFFFFFFL); 3674 match(ConL); 3675 op_cost(0); 3676 format %{ %} 3677 interface(CONST_INTER); 3678 %} 3679 3680 // Pointer operands 3681 // Pointer Immediate 3682 operand immP() 3683 %{ 3684 match(ConP); 3685 3686 op_cost(0); 3687 format %{ %} 3688 interface(CONST_INTER); 3689 %} 3690 3691 // NULL Pointer Immediate 3692 operand immP0() 3693 %{ 3694 predicate(n->get_ptr() == 0); 3695 match(ConP); 3696 3697 op_cost(0); 3698 format %{ %} 3699 interface(CONST_INTER); 3700 %} 3701 3702 // Pointer Immediate One 3703 // this is used in object initialization (initial object header) 3704 operand immP_1() 3705 %{ 3706 predicate(n->get_ptr() == 1); 3707 match(ConP); 3708 3709 op_cost(0); 3710 format %{ %} 3711 interface(CONST_INTER); 3712 %} 3713 3714 // Polling Page Pointer Immediate 3715 operand immPollPage() 3716 %{ 3717 predicate((address)n->get_ptr() == os::get_polling_page()); 3718 match(ConP); 3719 3720 op_cost(0); 3721 format %{ %} 3722 interface(CONST_INTER); 3723 %} 3724 3725 // Card Table Byte Map Base 3726 operand immByteMapBase() 3727 %{ 3728 // Get base of card map 3729 predicate((jbyte*)n->get_ptr() == 3730 ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base); 3731 match(ConP); 3732 3733 op_cost(0); 3734 format %{ %} 3735 interface(CONST_INTER); 3736 %} 3737 3738 // Pointer Immediate Minus One 3739 // this is used when we want to write the current PC to the thread anchor 3740 operand immP_M1() 3741 %{ 3742 predicate(n->get_ptr() == -1); 3743 match(ConP); 3744 3745 op_cost(0); 3746 format %{ %} 3747 interface(CONST_INTER); 3748 %} 3749 3750 // Pointer Immediate Minus Two 3751 // this is used when we want to write the current PC to the thread anchor 3752 operand immP_M2() 3753 %{ 3754 predicate(n->get_ptr() == -2); 3755 match(ConP); 3756 3757 op_cost(0); 3758 format %{ %} 3759 interface(CONST_INTER); 3760 %} 3761 3762 // Float and Double operands 3763 // Double Immediate 3764 operand immD() 3765 %{ 3766 match(ConD); 3767 op_cost(0); 3768 format %{ %} 3769 interface(CONST_INTER); 3770 %} 3771 3772 // constant 'double +0.0'. 3773 operand immD0() 3774 %{ 3775 predicate((n->getd() == 0) && 3776 (fpclassify(n->getd()) == FP_ZERO) && (signbit(n->getd()) == 0)); 3777 match(ConD); 3778 op_cost(0); 3779 format %{ %} 3780 interface(CONST_INTER); 3781 %} 3782 3783 // constant 'double +0.0'. 3784 operand immDPacked() 3785 %{ 3786 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 3787 match(ConD); 3788 op_cost(0); 3789 format %{ %} 3790 interface(CONST_INTER); 3791 %} 3792 3793 // Float Immediate 3794 operand immF() 3795 %{ 3796 match(ConF); 3797 op_cost(0); 3798 format %{ %} 3799 interface(CONST_INTER); 3800 %} 3801 3802 // constant 'float +0.0'. 3803 operand immF0() 3804 %{ 3805 predicate((n->getf() == 0) && 3806 (fpclassify(n->getf()) == FP_ZERO) && (signbit(n->getf()) == 0)); 3807 match(ConF); 3808 op_cost(0); 3809 format %{ %} 3810 interface(CONST_INTER); 3811 %} 3812 3813 // 3814 operand immFPacked() 3815 %{ 3816 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 3817 match(ConF); 3818 op_cost(0); 3819 format %{ %} 3820 interface(CONST_INTER); 3821 %} 3822 3823 // Narrow pointer operands 3824 // Narrow Pointer Immediate 3825 operand immN() 3826 %{ 3827 match(ConN); 3828 3829 op_cost(0); 3830 format %{ %} 3831 interface(CONST_INTER); 3832 %} 3833 3834 // Narrow NULL Pointer Immediate 3835 operand immN0() 3836 %{ 3837 predicate(n->get_narrowcon() == 0); 3838 match(ConN); 3839 3840 op_cost(0); 3841 format %{ %} 3842 interface(CONST_INTER); 3843 %} 3844 3845 operand immNKlass() 3846 %{ 3847 match(ConNKlass); 3848 3849 op_cost(0); 3850 format %{ %} 3851 interface(CONST_INTER); 3852 %} 3853 3854 // Integer 32 bit Register Operands 3855 // Integer 32 bitRegister (excludes SP) 3856 operand iRegI() 3857 %{ 3858 constraint(ALLOC_IN_RC(any_reg32)); 3859 match(RegI); 3860 match(iRegINoSp); 3861 op_cost(0); 3862 format %{ %} 3863 interface(REG_INTER); 3864 %} 3865 3866 // Integer 32 bit Register not Special 3867 operand iRegINoSp() 3868 %{ 3869 constraint(ALLOC_IN_RC(no_special_reg32)); 3870 match(RegI); 3871 op_cost(0); 3872 format %{ %} 3873 interface(REG_INTER); 3874 %} 3875 3876 // Integer 64 bit Register Operands 3877 // Integer 64 bit Register (includes SP) 3878 operand iRegL() 3879 %{ 3880 constraint(ALLOC_IN_RC(any_reg)); 3881 match(RegL); 3882 match(iRegLNoSp); 3883 op_cost(0); 3884 format %{ %} 3885 interface(REG_INTER); 3886 %} 3887 3888 // Integer 64 bit Register not Special 3889 operand iRegLNoSp() 3890 %{ 3891 constraint(ALLOC_IN_RC(no_special_reg)); 3892 match(RegL); 3893 format %{ %} 3894 interface(REG_INTER); 3895 %} 3896 3897 // Pointer Register Operands 3898 // Pointer Register 3899 operand iRegP() 3900 %{ 3901 constraint(ALLOC_IN_RC(ptr_reg)); 3902 match(RegP); 3903 match(iRegPNoSp); 3904 match(iRegP_R0); 3905 //match(iRegP_R2); 3906 //match(iRegP_R4); 3907 //match(iRegP_R5); 3908 match(thread_RegP); 3909 op_cost(0); 3910 format %{ %} 3911 interface(REG_INTER); 3912 %} 3913 3914 // Pointer 64 bit Register not Special 3915 operand iRegPNoSp() 3916 %{ 3917 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 3918 match(RegP); 3919 // match(iRegP); 3920 // match(iRegP_R0); 3921 // match(iRegP_R2); 3922 // match(iRegP_R4); 3923 // match(iRegP_R5); 3924 // match(thread_RegP); 3925 op_cost(0); 3926 format %{ %} 3927 interface(REG_INTER); 3928 %} 3929 3930 // Pointer 64 bit Register R0 only 3931 operand iRegP_R0() 3932 %{ 3933 constraint(ALLOC_IN_RC(r0_reg)); 3934 match(RegP); 3935 // match(iRegP); 3936 match(iRegPNoSp); 3937 op_cost(0); 3938 format %{ %} 3939 interface(REG_INTER); 3940 %} 3941 3942 // Pointer 64 bit Register R1 only 3943 operand iRegP_R1() 3944 %{ 3945 constraint(ALLOC_IN_RC(r1_reg)); 3946 match(RegP); 3947 // match(iRegP); 3948 match(iRegPNoSp); 3949 op_cost(0); 3950 format %{ %} 3951 interface(REG_INTER); 3952 %} 3953 3954 // Pointer 64 bit Register R2 only 3955 operand iRegP_R2() 3956 %{ 3957 constraint(ALLOC_IN_RC(r2_reg)); 3958 match(RegP); 3959 // match(iRegP); 3960 match(iRegPNoSp); 3961 op_cost(0); 3962 format %{ %} 3963 interface(REG_INTER); 3964 %} 3965 3966 // Pointer 64 bit Register R3 only 3967 operand iRegP_R3() 3968 %{ 3969 constraint(ALLOC_IN_RC(r3_reg)); 3970 match(RegP); 3971 // match(iRegP); 3972 match(iRegPNoSp); 3973 op_cost(0); 3974 format %{ %} 3975 interface(REG_INTER); 3976 %} 3977 3978 // Pointer 64 bit Register R4 only 3979 operand iRegP_R4() 3980 %{ 3981 constraint(ALLOC_IN_RC(r4_reg)); 3982 match(RegP); 3983 // match(iRegP); 3984 match(iRegPNoSp); 3985 op_cost(0); 3986 format %{ %} 3987 interface(REG_INTER); 3988 %} 3989 3990 // Pointer 64 bit Register R5 only 3991 operand iRegP_R5() 3992 %{ 3993 constraint(ALLOC_IN_RC(r5_reg)); 3994 match(RegP); 3995 // match(iRegP); 3996 match(iRegPNoSp); 3997 op_cost(0); 3998 format %{ %} 3999 interface(REG_INTER); 4000 %} 4001 4002 // Pointer 64 bit Register R10 only 4003 operand iRegP_R10() 4004 %{ 4005 constraint(ALLOC_IN_RC(r10_reg)); 4006 match(RegP); 4007 // match(iRegP); 4008 match(iRegPNoSp); 4009 op_cost(0); 4010 format %{ %} 4011 interface(REG_INTER); 4012 %} 4013 4014 // Long 64 bit Register R11 only 4015 operand iRegL_R11() 4016 %{ 4017 constraint(ALLOC_IN_RC(r11_reg)); 4018 match(RegL); 4019 match(iRegLNoSp); 4020 op_cost(0); 4021 format %{ %} 4022 interface(REG_INTER); 4023 %} 4024 4025 // Pointer 64 bit Register FP only 4026 operand iRegP_FP() 4027 %{ 4028 constraint(ALLOC_IN_RC(fp_reg)); 4029 match(RegP); 4030 // match(iRegP); 4031 op_cost(0); 4032 format %{ %} 4033 interface(REG_INTER); 4034 %} 4035 4036 // Register R0 only 4037 operand iRegI_R0() 4038 %{ 4039 constraint(ALLOC_IN_RC(int_r0_reg)); 4040 match(RegI); 4041 match(iRegINoSp); 4042 op_cost(0); 4043 format %{ %} 4044 interface(REG_INTER); 4045 %} 4046 4047 // Register R2 only 4048 operand iRegI_R2() 4049 %{ 4050 constraint(ALLOC_IN_RC(int_r2_reg)); 4051 match(RegI); 4052 match(iRegINoSp); 4053 op_cost(0); 4054 format %{ %} 4055 interface(REG_INTER); 4056 %} 4057 4058 // Register R3 only 4059 operand iRegI_R3() 4060 %{ 4061 constraint(ALLOC_IN_RC(int_r3_reg)); 4062 match(RegI); 4063 match(iRegINoSp); 4064 op_cost(0); 4065 format %{ %} 4066 interface(REG_INTER); 4067 %} 4068 4069 4070 // Register R2 only 4071 operand iRegI_R4() 4072 %{ 4073 constraint(ALLOC_IN_RC(int_r4_reg)); 4074 match(RegI); 4075 match(iRegINoSp); 4076 op_cost(0); 4077 format %{ %} 4078 interface(REG_INTER); 4079 %} 4080 4081 4082 // Pointer Register Operands 4083 // Narrow Pointer Register 4084 operand iRegN() 4085 %{ 4086 constraint(ALLOC_IN_RC(any_reg32)); 4087 match(RegN); 4088 match(iRegNNoSp); 4089 op_cost(0); 4090 format %{ %} 4091 interface(REG_INTER); 4092 %} 4093 4094 // Integer 64 bit Register not Special 4095 operand iRegNNoSp() 4096 %{ 4097 constraint(ALLOC_IN_RC(no_special_reg32)); 4098 match(RegN); 4099 op_cost(0); 4100 format %{ %} 4101 interface(REG_INTER); 4102 %} 4103 4104 // heap base register -- used for encoding immN0 4105 4106 operand iRegIHeapbase() 4107 %{ 4108 constraint(ALLOC_IN_RC(heapbase_reg)); 4109 match(RegI); 4110 op_cost(0); 4111 format %{ %} 4112 interface(REG_INTER); 4113 %} 4114 4115 // Float Register 4116 // Float register operands 4117 operand vRegF() 4118 %{ 4119 constraint(ALLOC_IN_RC(float_reg)); 4120 match(RegF); 4121 4122 op_cost(0); 4123 format %{ %} 4124 interface(REG_INTER); 4125 %} 4126 4127 // Double Register 4128 // Double register operands 4129 operand vRegD() 4130 %{ 4131 constraint(ALLOC_IN_RC(double_reg)); 4132 match(RegD); 4133 4134 op_cost(0); 4135 format %{ %} 4136 interface(REG_INTER); 4137 %} 4138 4139 operand vRegD_V0() 4140 %{ 4141 constraint(ALLOC_IN_RC(v0_reg)); 4142 match(RegD); 4143 op_cost(0); 4144 format %{ %} 4145 interface(REG_INTER); 4146 %} 4147 4148 operand vRegD_V1() 4149 %{ 4150 constraint(ALLOC_IN_RC(v1_reg)); 4151 match(RegD); 4152 op_cost(0); 4153 format %{ %} 4154 interface(REG_INTER); 4155 %} 4156 4157 operand vRegD_V2() 4158 %{ 4159 constraint(ALLOC_IN_RC(v2_reg)); 4160 match(RegD); 4161 op_cost(0); 4162 format %{ %} 4163 interface(REG_INTER); 4164 %} 4165 4166 operand vRegD_V3() 4167 %{ 4168 constraint(ALLOC_IN_RC(v3_reg)); 4169 match(RegD); 4170 op_cost(0); 4171 format %{ %} 4172 interface(REG_INTER); 4173 %} 4174 4175 // Flags register, used as output of signed compare instructions 4176 4177 // note that on AArch64 we also use this register as the output for 4178 // for floating point compare instructions (CmpF CmpD). this ensures 4179 // that ordered inequality tests use GT, GE, LT or LE none of which 4180 // pass through cases where the result is unordered i.e. one or both 4181 // inputs to the compare is a NaN. this means that the ideal code can 4182 // replace e.g. a GT with an LE and not end up capturing the NaN case 4183 // (where the comparison should always fail). EQ and NE tests are 4184 // always generated in ideal code so that unordered folds into the NE 4185 // case, matching the behaviour of AArch64 NE. 4186 // 4187 // This differs from x86 where the outputs of FP compares use a 4188 // special FP flags registers and where compares based on this 4189 // register are distinguished into ordered inequalities (cmpOpUCF) and 4190 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 4191 // to explicitly handle the unordered case in branches. x86 also has 4192 // to include extra CMoveX rules to accept a cmpOpUCF input. 4193 4194 operand rFlagsReg() 4195 %{ 4196 constraint(ALLOC_IN_RC(int_flags)); 4197 match(RegFlags); 4198 4199 op_cost(0); 4200 format %{ "RFLAGS" %} 4201 interface(REG_INTER); 4202 %} 4203 4204 // Flags register, used as output of unsigned compare instructions 4205 operand rFlagsRegU() 4206 %{ 4207 constraint(ALLOC_IN_RC(int_flags)); 4208 match(RegFlags); 4209 4210 op_cost(0); 4211 format %{ "RFLAGSU" %} 4212 interface(REG_INTER); 4213 %} 4214 4215 // Special Registers 4216 4217 // Method Register 4218 operand inline_cache_RegP(iRegP reg) 4219 %{ 4220 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 4221 match(reg); 4222 match(iRegPNoSp); 4223 op_cost(0); 4224 format %{ %} 4225 interface(REG_INTER); 4226 %} 4227 4228 operand interpreter_method_oop_RegP(iRegP reg) 4229 %{ 4230 constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg 4231 match(reg); 4232 match(iRegPNoSp); 4233 op_cost(0); 4234 format %{ %} 4235 interface(REG_INTER); 4236 %} 4237 4238 // Thread Register 4239 operand thread_RegP(iRegP reg) 4240 %{ 4241 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 4242 match(reg); 4243 op_cost(0); 4244 format %{ %} 4245 interface(REG_INTER); 4246 %} 4247 4248 operand lr_RegP(iRegP reg) 4249 %{ 4250 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 4251 match(reg); 4252 op_cost(0); 4253 format %{ %} 4254 interface(REG_INTER); 4255 %} 4256 4257 //----------Memory Operands---------------------------------------------------- 4258 4259 operand indirect(iRegP reg) 4260 %{ 4261 constraint(ALLOC_IN_RC(ptr_reg)); 4262 match(reg); 4263 op_cost(0); 4264 format %{ "[$reg]" %} 4265 interface(MEMORY_INTER) %{ 4266 base($reg); 4267 index(0xffffffff); 4268 scale(0x0); 4269 disp(0x0); 4270 %} 4271 %} 4272 4273 operand indIndexScaledOffsetI(iRegP reg, iRegL lreg, immIScale scale, immIU12 off) 4274 %{ 4275 constraint(ALLOC_IN_RC(ptr_reg)); 4276 match(AddP (AddP reg (LShiftL lreg scale)) off); 4277 op_cost(INSN_COST); 4278 format %{ "$reg, $lreg lsl($scale), $off" %} 4279 interface(MEMORY_INTER) %{ 4280 base($reg); 4281 index($lreg); 4282 scale($scale); 4283 disp($off); 4284 %} 4285 %} 4286 4287 operand indIndexScaledOffsetL(iRegP reg, iRegL lreg, immIScale scale, immLU12 off) 4288 %{ 4289 constraint(ALLOC_IN_RC(ptr_reg)); 4290 match(AddP (AddP reg (LShiftL lreg scale)) off); 4291 op_cost(INSN_COST); 4292 format %{ "$reg, $lreg lsl($scale), $off" %} 4293 interface(MEMORY_INTER) %{ 4294 base($reg); 4295 index($lreg); 4296 scale($scale); 4297 disp($off); 4298 %} 4299 %} 4300 4301 operand indIndexScaledOffsetI2L(iRegP reg, iRegI ireg, immIScale scale, immLU12 off) 4302 %{ 4303 constraint(ALLOC_IN_RC(ptr_reg)); 4304 match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off); 4305 op_cost(INSN_COST); 4306 format %{ "$reg, $ireg sxtw($scale), $off I2L" %} 4307 interface(MEMORY_INTER) %{ 4308 base($reg); 4309 index($ireg); 4310 scale($scale); 4311 disp($off); 4312 %} 4313 %} 4314 4315 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 4316 %{ 4317 constraint(ALLOC_IN_RC(ptr_reg)); 4318 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 4319 op_cost(0); 4320 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 4321 interface(MEMORY_INTER) %{ 4322 base($reg); 4323 index($ireg); 4324 scale($scale); 4325 disp(0x0); 4326 %} 4327 %} 4328 4329 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 4330 %{ 4331 constraint(ALLOC_IN_RC(ptr_reg)); 4332 match(AddP reg (LShiftL lreg scale)); 4333 op_cost(0); 4334 format %{ "$reg, $lreg lsl($scale)" %} 4335 interface(MEMORY_INTER) %{ 4336 base($reg); 4337 index($lreg); 4338 scale($scale); 4339 disp(0x0); 4340 %} 4341 %} 4342 4343 operand indIndex(iRegP reg, iRegL lreg) 4344 %{ 4345 constraint(ALLOC_IN_RC(ptr_reg)); 4346 match(AddP reg lreg); 4347 op_cost(0); 4348 format %{ "$reg, $lreg" %} 4349 interface(MEMORY_INTER) %{ 4350 base($reg); 4351 index($lreg); 4352 scale(0x0); 4353 disp(0x0); 4354 %} 4355 %} 4356 4357 operand indOffI(iRegP reg, immIOffset off) 4358 %{ 4359 constraint(ALLOC_IN_RC(ptr_reg)); 4360 match(AddP reg off); 4361 op_cost(INSN_COST); 4362 format %{ "[$reg, $off]" %} 4363 interface(MEMORY_INTER) %{ 4364 base($reg); 4365 index(0xffffffff); 4366 scale(0x0); 4367 disp($off); 4368 %} 4369 %} 4370 4371 operand indOffL(iRegP reg, immLoffset off) 4372 %{ 4373 constraint(ALLOC_IN_RC(ptr_reg)); 4374 match(AddP reg off); 4375 op_cost(0); 4376 format %{ "[$reg, $off]" %} 4377 interface(MEMORY_INTER) %{ 4378 base($reg); 4379 index(0xffffffff); 4380 scale(0x0); 4381 disp($off); 4382 %} 4383 %} 4384 4385 4386 operand indirectN(iRegN reg) 4387 %{ 4388 predicate(Universe::narrow_oop_shift() == 0); 4389 constraint(ALLOC_IN_RC(ptr_reg)); 4390 match(DecodeN reg); 4391 op_cost(0); 4392 format %{ "[$reg]\t# narrow" %} 4393 interface(MEMORY_INTER) %{ 4394 base($reg); 4395 index(0xffffffff); 4396 scale(0x0); 4397 disp(0x0); 4398 %} 4399 %} 4400 4401 operand indIndexScaledOffsetIN(iRegN reg, iRegL lreg, immIScale scale, immIU12 off) 4402 %{ 4403 predicate(Universe::narrow_oop_shift() == 0); 4404 constraint(ALLOC_IN_RC(ptr_reg)); 4405 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4406 op_cost(0); 4407 format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %} 4408 interface(MEMORY_INTER) %{ 4409 base($reg); 4410 index($lreg); 4411 scale($scale); 4412 disp($off); 4413 %} 4414 %} 4415 4416 operand indIndexScaledOffsetLN(iRegN reg, iRegL lreg, immIScale scale, immLU12 off) 4417 %{ 4418 predicate(Universe::narrow_oop_shift() == 0); 4419 constraint(ALLOC_IN_RC(ptr_reg)); 4420 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4421 op_cost(INSN_COST); 4422 format %{ "$reg, $lreg lsl($scale), $off\t# narrow" %} 4423 interface(MEMORY_INTER) %{ 4424 base($reg); 4425 index($lreg); 4426 scale($scale); 4427 disp($off); 4428 %} 4429 %} 4430 4431 operand indIndexScaledOffsetI2LN(iRegN reg, iRegI ireg, immIScale scale, immLU12 off) 4432 %{ 4433 predicate(Universe::narrow_oop_shift() == 0); 4434 constraint(ALLOC_IN_RC(ptr_reg)); 4435 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)) off); 4436 op_cost(INSN_COST); 4437 format %{ "$reg, $ireg sxtw($scale), $off I2L\t# narrow" %} 4438 interface(MEMORY_INTER) %{ 4439 base($reg); 4440 index($ireg); 4441 scale($scale); 4442 disp($off); 4443 %} 4444 %} 4445 4446 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 4447 %{ 4448 predicate(Universe::narrow_oop_shift() == 0); 4449 constraint(ALLOC_IN_RC(ptr_reg)); 4450 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 4451 op_cost(0); 4452 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 4453 interface(MEMORY_INTER) %{ 4454 base($reg); 4455 index($ireg); 4456 scale($scale); 4457 disp(0x0); 4458 %} 4459 %} 4460 4461 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 4462 %{ 4463 predicate(Universe::narrow_oop_shift() == 0); 4464 constraint(ALLOC_IN_RC(ptr_reg)); 4465 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4466 op_cost(0); 4467 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 4468 interface(MEMORY_INTER) %{ 4469 base($reg); 4470 index($lreg); 4471 scale($scale); 4472 disp(0x0); 4473 %} 4474 %} 4475 4476 operand indIndexN(iRegN reg, iRegL lreg) 4477 %{ 4478 predicate(Universe::narrow_oop_shift() == 0); 4479 constraint(ALLOC_IN_RC(ptr_reg)); 4480 match(AddP (DecodeN reg) lreg); 4481 op_cost(0); 4482 format %{ "$reg, $lreg\t# narrow" %} 4483 interface(MEMORY_INTER) %{ 4484 base($reg); 4485 index($lreg); 4486 scale(0x0); 4487 disp(0x0); 4488 %} 4489 %} 4490 4491 operand indOffIN(iRegN reg, immIOffset off) 4492 %{ 4493 predicate(Universe::narrow_oop_shift() == 0); 4494 constraint(ALLOC_IN_RC(ptr_reg)); 4495 match(AddP (DecodeN reg) off); 4496 op_cost(0); 4497 format %{ "[$reg, $off]\t# narrow" %} 4498 interface(MEMORY_INTER) %{ 4499 base($reg); 4500 index(0xffffffff); 4501 scale(0x0); 4502 disp($off); 4503 %} 4504 %} 4505 4506 operand indOffLN(iRegN reg, immLoffset off) 4507 %{ 4508 predicate(Universe::narrow_oop_shift() == 0); 4509 constraint(ALLOC_IN_RC(ptr_reg)); 4510 match(AddP (DecodeN reg) off); 4511 op_cost(0); 4512 format %{ "[$reg, $off]\t# narrow" %} 4513 interface(MEMORY_INTER) %{ 4514 base($reg); 4515 index(0xffffffff); 4516 scale(0x0); 4517 disp($off); 4518 %} 4519 %} 4520 4521 4522 4523 // AArch64 opto stubs need to write to the pc slot in the thread anchor 4524 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 4525 %{ 4526 constraint(ALLOC_IN_RC(ptr_reg)); 4527 match(AddP reg off); 4528 op_cost(0); 4529 format %{ "[$reg, $off]" %} 4530 interface(MEMORY_INTER) %{ 4531 base($reg); 4532 index(0xffffffff); 4533 scale(0x0); 4534 disp($off); 4535 %} 4536 %} 4537 4538 //----------Special Memory Operands-------------------------------------------- 4539 // Stack Slot Operand - This operand is used for loading and storing temporary 4540 // values on the stack where a match requires a value to 4541 // flow through memory. 4542 operand stackSlotP(sRegP reg) 4543 %{ 4544 constraint(ALLOC_IN_RC(stack_slots)); 4545 op_cost(100); 4546 // No match rule because this operand is only generated in matching 4547 // match(RegP); 4548 format %{ "[$reg]" %} 4549 interface(MEMORY_INTER) %{ 4550 base(0x1e); // RSP 4551 index(0x0); // No Index 4552 scale(0x0); // No Scale 4553 disp($reg); // Stack Offset 4554 %} 4555 %} 4556 4557 operand stackSlotI(sRegI reg) 4558 %{ 4559 constraint(ALLOC_IN_RC(stack_slots)); 4560 // No match rule because this operand is only generated in matching 4561 // match(RegI); 4562 format %{ "[$reg]" %} 4563 interface(MEMORY_INTER) %{ 4564 base(0x1e); // RSP 4565 index(0x0); // No Index 4566 scale(0x0); // No Scale 4567 disp($reg); // Stack Offset 4568 %} 4569 %} 4570 4571 operand stackSlotF(sRegF reg) 4572 %{ 4573 constraint(ALLOC_IN_RC(stack_slots)); 4574 // No match rule because this operand is only generated in matching 4575 // match(RegF); 4576 format %{ "[$reg]" %} 4577 interface(MEMORY_INTER) %{ 4578 base(0x1e); // RSP 4579 index(0x0); // No Index 4580 scale(0x0); // No Scale 4581 disp($reg); // Stack Offset 4582 %} 4583 %} 4584 4585 operand stackSlotD(sRegD reg) 4586 %{ 4587 constraint(ALLOC_IN_RC(stack_slots)); 4588 // No match rule because this operand is only generated in matching 4589 // match(RegD); 4590 format %{ "[$reg]" %} 4591 interface(MEMORY_INTER) %{ 4592 base(0x1e); // RSP 4593 index(0x0); // No Index 4594 scale(0x0); // No Scale 4595 disp($reg); // Stack Offset 4596 %} 4597 %} 4598 4599 operand stackSlotL(sRegL reg) 4600 %{ 4601 constraint(ALLOC_IN_RC(stack_slots)); 4602 // No match rule because this operand is only generated in matching 4603 // match(RegL); 4604 format %{ "[$reg]" %} 4605 interface(MEMORY_INTER) %{ 4606 base(0x1e); // RSP 4607 index(0x0); // No Index 4608 scale(0x0); // No Scale 4609 disp($reg); // Stack Offset 4610 %} 4611 %} 4612 4613 // Operands for expressing Control Flow 4614 // NOTE: Label is a predefined operand which should not be redefined in 4615 // the AD file. It is generically handled within the ADLC. 4616 4617 //----------Conditional Branch Operands---------------------------------------- 4618 // Comparison Op - This is the operation of the comparison, and is limited to 4619 // the following set of codes: 4620 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4621 // 4622 // Other attributes of the comparison, such as unsignedness, are specified 4623 // by the comparison instruction that sets a condition code flags register. 4624 // That result is represented by a flags operand whose subtype is appropriate 4625 // to the unsignedness (etc.) of the comparison. 4626 // 4627 // Later, the instruction which matches both the Comparison Op (a Bool) and 4628 // the flags (produced by the Cmp) specifies the coding of the comparison op 4629 // by matching a specific subtype of Bool operand below, such as cmpOpU. 4630 4631 // used for signed integral comparisons and fp comparisons 4632 4633 operand cmpOp() 4634 %{ 4635 match(Bool); 4636 4637 format %{ "" %} 4638 interface(COND_INTER) %{ 4639 equal(0x0, "eq"); 4640 not_equal(0x1, "ne"); 4641 less(0xb, "lt"); 4642 greater_equal(0xa, "ge"); 4643 less_equal(0xd, "le"); 4644 greater(0xc, "gt"); 4645 overflow(0x6, "vs"); 4646 no_overflow(0x7, "vc"); 4647 %} 4648 %} 4649 4650 // used for unsigned integral comparisons 4651 4652 operand cmpOpU() 4653 %{ 4654 match(Bool); 4655 4656 format %{ "" %} 4657 interface(COND_INTER) %{ 4658 equal(0x0, "eq"); 4659 not_equal(0x1, "ne"); 4660 less(0x3, "lo"); 4661 greater_equal(0x2, "hs"); 4662 less_equal(0x9, "ls"); 4663 greater(0x8, "hi"); 4664 overflow(0x6, "vs"); 4665 no_overflow(0x7, "vc"); 4666 %} 4667 %} 4668 4669 // Special operand allowing long args to int ops to be truncated for free 4670 4671 operand iRegL2I(iRegL reg) %{ 4672 4673 op_cost(0); 4674 4675 match(ConvL2I reg); 4676 4677 format %{ "l2i($reg)" %} 4678 4679 interface(REG_INTER) 4680 %} 4681 4682 4683 //----------OPERAND CLASSES---------------------------------------------------- 4684 // Operand Classes are groups of operands that are used as to simplify 4685 // instruction definitions by not requiring the AD writer to specify 4686 // separate instructions for every form of operand when the 4687 // instruction accepts multiple operand types with the same basic 4688 // encoding and format. The classic case of this is memory operands. 4689 4690 // memory is used to define read/write location for load/store 4691 // instruction defs. we can turn a memory op into an Address 4692 4693 opclass memory(indirect, indIndexScaledOffsetI, indIndexScaledOffsetL, indIndexScaledOffsetI2L, indIndexScaled, indIndexScaledI2L, indIndex, indOffI, indOffL, 4694 indirectN, indIndexScaledOffsetIN, indIndexScaledOffsetLN, indIndexScaledOffsetI2LN, indIndexScaledN, indIndexScaledI2LN, indIndexN, indOffIN, indOffLN); 4695 4696 4697 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 4698 // operations. it allows the src to be either an iRegI or a (ConvL2I 4699 // iRegL). in the latter case the l2i normally planted for a ConvL2I 4700 // can be elided because the 32-bit instruction will just employ the 4701 // lower 32 bits anyway. 4702 // 4703 // n.b. this does not elide all L2I conversions. if the truncated 4704 // value is consumed by more than one operation then the ConvL2I 4705 // cannot be bundled into the consuming nodes so an l2i gets planted 4706 // (actually a movw $dst $src) and the downstream instructions consume 4707 // the result of the l2i as an iRegI input. That's a shame since the 4708 // movw is actually redundant but its not too costly. 4709 4710 opclass iRegIorL2I(iRegI, iRegL2I); 4711 4712 //----------PIPELINE----------------------------------------------------------- 4713 // Rules which define the behavior of the target architectures pipeline. 4714 // Integer ALU reg operation 4715 pipeline %{ 4716 4717 attributes %{ 4718 // ARM instructions are of fixed length 4719 fixed_size_instructions; // Fixed size instructions TODO does 4720 max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 4721 // ARM instructions come in 32-bit word units 4722 instruction_unit_size = 4; // An instruction is 4 bytes long 4723 instruction_fetch_unit_size = 64; // The processor fetches one line 4724 instruction_fetch_units = 1; // of 64 bytes 4725 4726 // List of nop instructions 4727 nops( MachNop ); 4728 %} 4729 4730 // We don't use an actual pipeline model so don't care about resources 4731 // or description. we do use pipeline classes to introduce fixed 4732 // latencies 4733 4734 //----------RESOURCES---------------------------------------------------------- 4735 // Resources are the functional units available to the machine 4736 4737 resources( INS0, INS1, INS01 = INS0 | INS1, 4738 ALU0, ALU1, ALU = ALU0 | ALU1, 4739 MAC, 4740 DIV, 4741 BRANCH, 4742 LDST, 4743 NEON_FP); 4744 4745 //----------PIPELINE DESCRIPTION----------------------------------------------- 4746 // Pipeline Description specifies the stages in the machine's pipeline 4747 4748 pipe_desc(ISS, EX1, EX2, WR); 4749 4750 //----------PIPELINE CLASSES--------------------------------------------------- 4751 // Pipeline Classes describe the stages in which input and output are 4752 // referenced by the hardware pipeline. 4753 4754 //------- Integer ALU operations -------------------------- 4755 4756 // Integer ALU reg-reg operation 4757 // Operands needed in EX1, result generated in EX2 4758 // Eg. ADD x0, x1, x2 4759 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4760 %{ 4761 single_instruction; 4762 dst : EX2(write); 4763 src1 : EX1(read); 4764 src2 : EX1(read); 4765 INS01 : ISS; // Dual issue as instruction 0 or 1 4766 ALU : EX2; 4767 %} 4768 4769 // Integer ALU reg-reg operation with constant shift 4770 // Shifted register must be available in LATE_ISS instead of EX1 4771 // Eg. ADD x0, x1, x2, LSL #2 4772 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 4773 %{ 4774 single_instruction; 4775 dst : EX2(write); 4776 src1 : EX1(read); 4777 src2 : ISS(read); 4778 INS01 : ISS; 4779 ALU : EX2; 4780 %} 4781 4782 // Integer ALU reg operation with constant shift 4783 // Eg. LSL x0, x1, #shift 4784 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 4785 %{ 4786 single_instruction; 4787 dst : EX2(write); 4788 src1 : ISS(read); 4789 INS01 : ISS; 4790 ALU : EX2; 4791 %} 4792 4793 // Integer ALU reg-reg operation with variable shift 4794 // Both operands must be available in LATE_ISS instead of EX1 4795 // Result is available in EX1 instead of EX2 4796 // Eg. LSLV x0, x1, x2 4797 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 4798 %{ 4799 single_instruction; 4800 dst : EX1(write); 4801 src1 : ISS(read); 4802 src2 : ISS(read); 4803 INS01 : ISS; 4804 ALU : EX1; 4805 %} 4806 4807 // Integer ALU reg-reg operation with extract 4808 // As for _vshift above, but result generated in EX2 4809 // Eg. EXTR x0, x1, x2, #N 4810 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 4811 %{ 4812 single_instruction; 4813 dst : EX2(write); 4814 src1 : ISS(read); 4815 src2 : ISS(read); 4816 INS1 : ISS; // Can only dual issue as Instruction 1 4817 ALU : EX1; 4818 %} 4819 4820 // Integer ALU reg operation 4821 // Eg. NEG x0, x1 4822 pipe_class ialu_reg(iRegI dst, iRegI src) 4823 %{ 4824 single_instruction; 4825 dst : EX2(write); 4826 src : EX1(read); 4827 INS01 : ISS; 4828 ALU : EX2; 4829 %} 4830 4831 // Integer ALU reg mmediate operation 4832 // Eg. ADD x0, x1, #N 4833 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 4834 %{ 4835 single_instruction; 4836 dst : EX2(write); 4837 src1 : EX1(read); 4838 INS01 : ISS; 4839 ALU : EX2; 4840 %} 4841 4842 // Integer ALU immediate operation (no source operands) 4843 // Eg. MOV x0, #N 4844 pipe_class ialu_imm(iRegI dst) 4845 %{ 4846 single_instruction; 4847 dst : EX1(write); 4848 INS01 : ISS; 4849 ALU : EX1; 4850 %} 4851 4852 //------- Compare operation ------------------------------- 4853 4854 // Compare reg-reg 4855 // Eg. CMP x0, x1 4856 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 4857 %{ 4858 single_instruction; 4859 // fixed_latency(16); 4860 cr : EX2(write); 4861 op1 : EX1(read); 4862 op2 : EX1(read); 4863 INS01 : ISS; 4864 ALU : EX2; 4865 %} 4866 4867 // Compare reg-reg 4868 // Eg. CMP x0, #N 4869 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 4870 %{ 4871 single_instruction; 4872 // fixed_latency(16); 4873 cr : EX2(write); 4874 op1 : EX1(read); 4875 INS01 : ISS; 4876 ALU : EX2; 4877 %} 4878 4879 //------- Conditional instructions ------------------------ 4880 4881 // Conditional no operands 4882 // Eg. CSINC x0, zr, zr, <cond> 4883 pipe_class icond_none(iRegI dst, rFlagsReg cr) 4884 %{ 4885 single_instruction; 4886 cr : EX1(read); 4887 dst : EX2(write); 4888 INS01 : ISS; 4889 ALU : EX2; 4890 %} 4891 4892 // Conditional 2 operand 4893 // EG. CSEL X0, X1, X2, <cond> 4894 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 4895 %{ 4896 single_instruction; 4897 cr : EX1(read); 4898 src1 : EX1(read); 4899 src2 : EX1(read); 4900 dst : EX2(write); 4901 INS01 : ISS; 4902 ALU : EX2; 4903 %} 4904 4905 // Conditional 2 operand 4906 // EG. CSEL X0, X1, X2, <cond> 4907 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 4908 %{ 4909 single_instruction; 4910 cr : EX1(read); 4911 src : EX1(read); 4912 dst : EX2(write); 4913 INS01 : ISS; 4914 ALU : EX2; 4915 %} 4916 4917 //------- Multiply pipeline operations -------------------- 4918 4919 // Multiply reg-reg 4920 // Eg. MUL w0, w1, w2 4921 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4922 %{ 4923 single_instruction; 4924 dst : WR(write); 4925 src1 : ISS(read); 4926 src2 : ISS(read); 4927 INS01 : ISS; 4928 MAC : WR; 4929 %} 4930 4931 // Multiply accumulate 4932 // Eg. MADD w0, w1, w2, w3 4933 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 4934 %{ 4935 single_instruction; 4936 dst : WR(write); 4937 src1 : ISS(read); 4938 src2 : ISS(read); 4939 src3 : ISS(read); 4940 INS01 : ISS; 4941 MAC : WR; 4942 %} 4943 4944 // Eg. MUL w0, w1, w2 4945 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4946 %{ 4947 single_instruction; 4948 fixed_latency(3); // Maximum latency for 64 bit mul 4949 dst : WR(write); 4950 src1 : ISS(read); 4951 src2 : ISS(read); 4952 INS01 : ISS; 4953 MAC : WR; 4954 %} 4955 4956 // Multiply accumulate 4957 // Eg. MADD w0, w1, w2, w3 4958 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 4959 %{ 4960 single_instruction; 4961 fixed_latency(3); // Maximum latency for 64 bit mul 4962 dst : WR(write); 4963 src1 : ISS(read); 4964 src2 : ISS(read); 4965 src3 : ISS(read); 4966 INS01 : ISS; 4967 MAC : WR; 4968 %} 4969 4970 //------- Divide pipeline operations -------------------- 4971 4972 // Eg. SDIV w0, w1, w2 4973 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4974 %{ 4975 single_instruction; 4976 fixed_latency(8); // Maximum latency for 32 bit divide 4977 dst : WR(write); 4978 src1 : ISS(read); 4979 src2 : ISS(read); 4980 INS0 : ISS; // Can only dual issue as instruction 0 4981 DIV : WR; 4982 %} 4983 4984 // Eg. SDIV x0, x1, x2 4985 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 4986 %{ 4987 single_instruction; 4988 fixed_latency(16); // Maximum latency for 64 bit divide 4989 dst : WR(write); 4990 src1 : ISS(read); 4991 src2 : ISS(read); 4992 INS0 : ISS; // Can only dual issue as instruction 0 4993 DIV : WR; 4994 %} 4995 4996 //------- Load pipeline operations ------------------------ 4997 4998 // Load - prefetch 4999 // Eg. PFRM <mem> 5000 pipe_class iload_prefetch(memory mem) 5001 %{ 5002 single_instruction; 5003 mem : ISS(read); 5004 INS01 : ISS; 5005 LDST : WR; 5006 %} 5007 5008 // Load - reg, mem 5009 // Eg. LDR x0, <mem> 5010 pipe_class iload_reg_mem(iRegI dst, memory mem) 5011 %{ 5012 single_instruction; 5013 dst : WR(write); 5014 mem : ISS(read); 5015 INS01 : ISS; 5016 LDST : WR; 5017 %} 5018 5019 // Load - reg, reg 5020 // Eg. LDR x0, [sp, x1] 5021 pipe_class iload_reg_reg(iRegI dst, iRegI src) 5022 %{ 5023 single_instruction; 5024 dst : WR(write); 5025 src : ISS(read); 5026 INS01 : ISS; 5027 LDST : WR; 5028 %} 5029 5030 //------- Store pipeline operations ----------------------- 5031 5032 // Store - zr, mem 5033 // Eg. STR zr, <mem> 5034 pipe_class istore_mem(memory mem) 5035 %{ 5036 single_instruction; 5037 mem : ISS(read); 5038 INS01 : ISS; 5039 LDST : WR; 5040 %} 5041 5042 // Store - reg, mem 5043 // Eg. STR x0, <mem> 5044 pipe_class istore_reg_mem(iRegI src, memory mem) 5045 %{ 5046 single_instruction; 5047 mem : ISS(read); 5048 src : EX2(read); 5049 INS01 : ISS; 5050 LDST : WR; 5051 %} 5052 5053 // Store - reg, reg 5054 // Eg. STR x0, [sp, x1] 5055 pipe_class istore_reg_reg(iRegI dst, iRegI src) 5056 %{ 5057 single_instruction; 5058 dst : ISS(read); 5059 src : EX2(read); 5060 INS01 : ISS; 5061 LDST : WR; 5062 %} 5063 5064 //------- Store pipeline operations ----------------------- 5065 5066 // Branch 5067 pipe_class pipe_branch() 5068 %{ 5069 single_instruction; 5070 INS01 : ISS; 5071 BRANCH : EX1; 5072 %} 5073 5074 // Conditional branch 5075 pipe_class pipe_branch_cond(rFlagsReg cr) 5076 %{ 5077 single_instruction; 5078 cr : EX1(read); 5079 INS01 : ISS; 5080 BRANCH : EX1; 5081 %} 5082 5083 // Compare & Branch 5084 // EG. CBZ/CBNZ 5085 pipe_class pipe_cmp_branch(iRegI op1) 5086 %{ 5087 single_instruction; 5088 op1 : EX1(read); 5089 INS01 : ISS; 5090 BRANCH : EX1; 5091 %} 5092 5093 //------- Synchronisation operations ---------------------- 5094 5095 // Any operation requiring serialization. 5096 // EG. DMB/Atomic Ops/Load Acquire/Str Release 5097 pipe_class pipe_serial() 5098 %{ 5099 single_instruction; 5100 force_serialization; 5101 fixed_latency(16); 5102 INS01 : ISS(2); // Cannot dual issue with any other instruction 5103 LDST : WR; 5104 %} 5105 5106 // Generic big/slow expanded idiom - also serialized 5107 pipe_class pipe_slow() 5108 %{ 5109 instruction_count(10); 5110 multiple_bundles; 5111 force_serialization; 5112 fixed_latency(16); 5113 INS01 : ISS(2); // Cannot dual issue with any other instruction 5114 LDST : WR; 5115 %} 5116 5117 // Empty pipeline class 5118 pipe_class pipe_class_empty() 5119 %{ 5120 single_instruction; 5121 fixed_latency(0); 5122 %} 5123 5124 // Default pipeline class. 5125 pipe_class pipe_class_default() 5126 %{ 5127 single_instruction; 5128 fixed_latency(2); 5129 %} 5130 5131 // Pipeline class for compares. 5132 pipe_class pipe_class_compare() 5133 %{ 5134 single_instruction; 5135 fixed_latency(16); 5136 %} 5137 5138 // Pipeline class for memory operations. 5139 pipe_class pipe_class_memory() 5140 %{ 5141 single_instruction; 5142 fixed_latency(16); 5143 %} 5144 5145 // Pipeline class for call. 5146 pipe_class pipe_class_call() 5147 %{ 5148 single_instruction; 5149 fixed_latency(100); 5150 %} 5151 5152 // Define the class for the Nop node. 5153 define %{ 5154 MachNop = pipe_class_empty; 5155 %} 5156 5157 %} 5158 //----------INSTRUCTIONS------------------------------------------------------- 5159 // 5160 // match -- States which machine-independent subtree may be replaced 5161 // by this instruction. 5162 // ins_cost -- The estimated cost of this instruction is used by instruction 5163 // selection to identify a minimum cost tree of machine 5164 // instructions that matches a tree of machine-independent 5165 // instructions. 5166 // format -- A string providing the disassembly for this instruction. 5167 // The value of an instruction's operand may be inserted 5168 // by referring to it with a '$' prefix. 5169 // opcode -- Three instruction opcodes may be provided. These are referred 5170 // to within an encode class as $primary, $secondary, and $tertiary 5171 // rrspectively. The primary opcode is commonly used to 5172 // indicate the type of machine instruction, while secondary 5173 // and tertiary are often used for prefix options or addressing 5174 // modes. 5175 // ins_encode -- A list of encode classes with parameters. The encode class 5176 // name must have been defined in an 'enc_class' specification 5177 // in the encode section of the architecture description. 5178 5179 // ============================================================================ 5180 // Memory (Load/Store) Instructions 5181 5182 // Load Instructions 5183 5184 // Load Byte (8 bit signed) 5185 instruct loadB(iRegINoSp dst, memory mem) 5186 %{ 5187 match(Set dst (LoadB mem)); 5188 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5189 5190 ins_cost(4 * INSN_COST); 5191 format %{ "ldrsbw $dst, $mem\t# byte" %} 5192 5193 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 5194 5195 ins_pipe(iload_reg_mem); 5196 %} 5197 5198 // Load Byte (8 bit signed) into long 5199 instruct loadB2L(iRegLNoSp dst, memory mem) 5200 %{ 5201 match(Set dst (ConvI2L (LoadB mem))); 5202 predicate(UseBarriersForVolatile || n->in(1)->as_Load()->is_unordered()); 5203 5204 ins_cost(4 * INSN_COST); 5205 format %{ "ldrsb $dst, $mem\t# byte" %} 5206 5207 ins_encode(aarch64_enc_ldrsb(dst, mem)); 5208 5209 ins_pipe(iload_reg_mem); 5210 %} 5211 5212 // Load Byte (8 bit unsigned) 5213 instruct loadUB(iRegINoSp dst, memory mem) 5214 %{ 5215 match(Set dst (LoadUB mem)); 5216 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5217 5218 ins_cost(4 * INSN_COST); 5219 format %{ "ldrbw $dst, $mem\t# byte" %} 5220 5221 ins_encode(aarch64_enc_ldrb(dst, mem)); 5222 5223 ins_pipe(iload_reg_mem); 5224 %} 5225 5226 // Load Byte (8 bit unsigned) into long 5227 instruct loadUB2L(iRegLNoSp dst, memory mem) 5228 %{ 5229 match(Set dst (ConvI2L (LoadUB mem))); 5230 predicate(UseBarriersForVolatile || n->in(1)->as_Load()->is_unordered()); 5231 5232 ins_cost(4 * INSN_COST); 5233 format %{ "ldrb $dst, $mem\t# byte" %} 5234 5235 ins_encode(aarch64_enc_ldrb(dst, mem)); 5236 5237 ins_pipe(iload_reg_mem); 5238 %} 5239 5240 // Load Short (16 bit signed) 5241 instruct loadS(iRegINoSp dst, memory mem) 5242 %{ 5243 match(Set dst (LoadS mem)); 5244 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5245 5246 ins_cost(4 * INSN_COST); 5247 format %{ "ldrshw $dst, $mem\t# short" %} 5248 5249 ins_encode(aarch64_enc_ldrshw(dst, mem)); 5250 5251 ins_pipe(iload_reg_mem); 5252 %} 5253 5254 // Load Short (16 bit signed) into long 5255 instruct loadS2L(iRegLNoSp dst, memory mem) 5256 %{ 5257 match(Set dst (ConvI2L (LoadS mem))); 5258 predicate(UseBarriersForVolatile || n->in(1)->as_Load()->is_unordered()); 5259 5260 ins_cost(4 * INSN_COST); 5261 format %{ "ldrsh $dst, $mem\t# short" %} 5262 5263 ins_encode(aarch64_enc_ldrsh(dst, mem)); 5264 5265 ins_pipe(iload_reg_mem); 5266 %} 5267 5268 // Load Char (16 bit unsigned) 5269 instruct loadUS(iRegINoSp dst, memory mem) 5270 %{ 5271 match(Set dst (LoadUS mem)); 5272 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5273 5274 ins_cost(4 * INSN_COST); 5275 format %{ "ldrh $dst, $mem\t# short" %} 5276 5277 ins_encode(aarch64_enc_ldrh(dst, mem)); 5278 5279 ins_pipe(iload_reg_mem); 5280 %} 5281 5282 // Load Short/Char (16 bit unsigned) into long 5283 instruct loadUS2L(iRegLNoSp dst, memory mem) 5284 %{ 5285 match(Set dst (ConvI2L (LoadUS mem))); 5286 predicate(UseBarriersForVolatile || n->in(1)->as_Load()->is_unordered()); 5287 5288 ins_cost(4 * INSN_COST); 5289 format %{ "ldrh $dst, $mem\t# short" %} 5290 5291 ins_encode(aarch64_enc_ldrh(dst, mem)); 5292 5293 ins_pipe(iload_reg_mem); 5294 %} 5295 5296 // Load Integer (32 bit signed) 5297 instruct loadI(iRegINoSp dst, memory mem) 5298 %{ 5299 match(Set dst (LoadI mem)); 5300 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5301 5302 ins_cost(4 * INSN_COST); 5303 format %{ "ldrw $dst, $mem\t# int" %} 5304 5305 ins_encode(aarch64_enc_ldrw(dst, mem)); 5306 5307 ins_pipe(iload_reg_mem); 5308 %} 5309 5310 // Load Integer (32 bit signed) into long 5311 instruct loadI2L(iRegLNoSp dst, memory mem) 5312 %{ 5313 match(Set dst (ConvI2L (LoadI mem))); 5314 predicate(UseBarriersForVolatile || n->in(1)->as_Load()->is_unordered()); 5315 5316 ins_cost(4 * INSN_COST); 5317 format %{ "ldrsw $dst, $mem\t# int" %} 5318 5319 ins_encode(aarch64_enc_ldrsw(dst, mem)); 5320 5321 ins_pipe(iload_reg_mem); 5322 %} 5323 5324 // Load Integer (32 bit unsigned) into long 5325 instruct loadUI2L(iRegLNoSp dst, memory mem, immL_32bits mask) 5326 %{ 5327 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5328 predicate(UseBarriersForVolatile || n->in(1)->in(1)->as_Load()->is_unordered()); 5329 5330 ins_cost(4 * INSN_COST); 5331 format %{ "ldrw $dst, $mem\t# int" %} 5332 5333 ins_encode(aarch64_enc_ldrw(dst, mem)); 5334 5335 ins_pipe(iload_reg_mem); 5336 %} 5337 5338 // Load Long (64 bit signed) 5339 instruct loadL(iRegLNoSp dst, memory mem) 5340 %{ 5341 match(Set dst (LoadL mem)); 5342 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5343 5344 ins_cost(4 * INSN_COST); 5345 format %{ "ldr $dst, $mem\t# int" %} 5346 5347 ins_encode(aarch64_enc_ldr(dst, mem)); 5348 5349 ins_pipe(iload_reg_mem); 5350 %} 5351 5352 // Load Range 5353 instruct loadRange(iRegINoSp dst, memory mem) 5354 %{ 5355 match(Set dst (LoadRange mem)); 5356 5357 ins_cost(4 * INSN_COST); 5358 format %{ "ldrw $dst, $mem\t# range" %} 5359 5360 ins_encode(aarch64_enc_ldrw(dst, mem)); 5361 5362 ins_pipe(iload_reg_mem); 5363 %} 5364 5365 // Load Pointer 5366 instruct loadP(iRegPNoSp dst, memory mem) 5367 %{ 5368 match(Set dst (LoadP mem)); 5369 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5370 5371 ins_cost(4 * INSN_COST); 5372 format %{ "ldr $dst, $mem\t# ptr" %} 5373 5374 ins_encode(aarch64_enc_ldr(dst, mem)); 5375 5376 ins_pipe(iload_reg_mem); 5377 %} 5378 5379 // Load Compressed Pointer 5380 instruct loadN(iRegNNoSp dst, memory mem) 5381 %{ 5382 match(Set dst (LoadN mem)); 5383 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5384 5385 ins_cost(4 * INSN_COST); 5386 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 5387 5388 ins_encode(aarch64_enc_ldrw(dst, mem)); 5389 5390 ins_pipe(iload_reg_mem); 5391 %} 5392 5393 // Load Klass Pointer 5394 instruct loadKlass(iRegPNoSp dst, memory mem) 5395 %{ 5396 match(Set dst (LoadKlass mem)); 5397 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5398 5399 ins_cost(4 * INSN_COST); 5400 format %{ "ldr $dst, $mem\t# class" %} 5401 5402 ins_encode(aarch64_enc_ldr(dst, mem)); 5403 5404 ins_pipe(iload_reg_mem); 5405 %} 5406 5407 // Load Narrow Klass Pointer 5408 instruct loadNKlass(iRegNNoSp dst, memory mem) 5409 %{ 5410 match(Set dst (LoadNKlass mem)); 5411 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5412 5413 ins_cost(4 * INSN_COST); 5414 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 5415 5416 ins_encode(aarch64_enc_ldrw(dst, mem)); 5417 5418 ins_pipe(iload_reg_mem); 5419 %} 5420 5421 // Load Float 5422 instruct loadF(vRegF dst, memory mem) 5423 %{ 5424 match(Set dst (LoadF mem)); 5425 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5426 5427 ins_cost(4 * INSN_COST); 5428 format %{ "ldrs $dst, $mem\t# float" %} 5429 5430 ins_encode( aarch64_enc_ldrs(dst, mem) ); 5431 5432 ins_pipe(pipe_class_memory); 5433 %} 5434 5435 // Load Double 5436 instruct loadD(vRegD dst, memory mem) 5437 %{ 5438 match(Set dst (LoadD mem)); 5439 predicate(UseBarriersForVolatile || n->as_Load()->is_unordered()); 5440 5441 ins_cost(4 * INSN_COST); 5442 format %{ "ldrd $dst, $mem\t# double" %} 5443 5444 ins_encode( aarch64_enc_ldrd(dst, mem) ); 5445 5446 ins_pipe(pipe_class_memory); 5447 %} 5448 5449 5450 // Load Int Constant 5451 instruct loadConI(iRegINoSp dst, immI src) 5452 %{ 5453 match(Set dst src); 5454 5455 ins_cost(INSN_COST); 5456 format %{ "mov $dst, $src\t# int" %} 5457 5458 ins_encode( aarch64_enc_movw_imm(dst, src) ); 5459 5460 ins_pipe(ialu_imm); 5461 %} 5462 5463 // Load Long Constant 5464 instruct loadConL(iRegLNoSp dst, immL src) 5465 %{ 5466 match(Set dst src); 5467 5468 ins_cost(INSN_COST); 5469 format %{ "mov $dst, $src\t# long" %} 5470 5471 ins_encode( aarch64_enc_mov_imm(dst, src) ); 5472 5473 ins_pipe(ialu_imm); 5474 %} 5475 5476 // Load Pointer Constant 5477 5478 instruct loadConP(iRegPNoSp dst, immP con) 5479 %{ 5480 match(Set dst con); 5481 5482 ins_cost(INSN_COST * 4); 5483 format %{ 5484 "mov $dst, $con\t# ptr\n\t" 5485 %} 5486 5487 ins_encode(aarch64_enc_mov_p(dst, con)); 5488 5489 ins_pipe(ialu_imm); 5490 %} 5491 5492 // Load Null Pointer Constant 5493 5494 instruct loadConP0(iRegPNoSp dst, immP0 con) 5495 %{ 5496 match(Set dst con); 5497 5498 ins_cost(INSN_COST); 5499 format %{ "mov $dst, $con\t# NULL ptr" %} 5500 5501 ins_encode(aarch64_enc_mov_p0(dst, con)); 5502 5503 ins_pipe(ialu_imm); 5504 %} 5505 5506 // Load Pointer Constant One 5507 5508 instruct loadConP1(iRegPNoSp dst, immP_1 con) 5509 %{ 5510 match(Set dst con); 5511 5512 ins_cost(INSN_COST); 5513 format %{ "mov $dst, $con\t# NULL ptr" %} 5514 5515 ins_encode(aarch64_enc_mov_p1(dst, con)); 5516 5517 ins_pipe(ialu_imm); 5518 %} 5519 5520 // Load Poll Page Constant 5521 5522 instruct loadConPollPage(iRegPNoSp dst, immPollPage con) 5523 %{ 5524 match(Set dst con); 5525 5526 ins_cost(INSN_COST); 5527 format %{ "adr $dst, $con\t# Poll Page Ptr" %} 5528 5529 ins_encode(aarch64_enc_mov_poll_page(dst, con)); 5530 5531 ins_pipe(ialu_imm); 5532 %} 5533 5534 // Load Byte Map Base Constant 5535 5536 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 5537 %{ 5538 match(Set dst con); 5539 5540 ins_cost(INSN_COST); 5541 format %{ "adr $dst, $con\t# Byte Map Base" %} 5542 5543 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 5544 5545 ins_pipe(ialu_imm); 5546 %} 5547 5548 // Load Narrow Pointer Constant 5549 5550 instruct loadConN(iRegNNoSp dst, immN con) 5551 %{ 5552 match(Set dst con); 5553 5554 ins_cost(INSN_COST * 4); 5555 format %{ "mov $dst, $con\t# compressed ptr" %} 5556 5557 ins_encode(aarch64_enc_mov_n(dst, con)); 5558 5559 ins_pipe(ialu_imm); 5560 %} 5561 5562 // Load Narrow Null Pointer Constant 5563 5564 instruct loadConN0(iRegNNoSp dst, immN0 con) 5565 %{ 5566 match(Set dst con); 5567 5568 ins_cost(INSN_COST); 5569 format %{ "mov $dst, $con\t# compressed NULL ptr" %} 5570 5571 ins_encode(aarch64_enc_mov_n0(dst, con)); 5572 5573 ins_pipe(ialu_imm); 5574 %} 5575 5576 // Load Narrow Klass Constant 5577 5578 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 5579 %{ 5580 match(Set dst con); 5581 5582 ins_cost(INSN_COST); 5583 format %{ "mov $dst, $con\t# compressed klass ptr" %} 5584 5585 ins_encode(aarch64_enc_mov_nk(dst, con)); 5586 5587 ins_pipe(ialu_imm); 5588 %} 5589 5590 // Load Packed Float Constant 5591 5592 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 5593 match(Set dst con); 5594 ins_cost(INSN_COST * 4); 5595 format %{ "fmovs $dst, $con"%} 5596 ins_encode %{ 5597 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 5598 %} 5599 5600 ins_pipe(pipe_class_default); 5601 %} 5602 5603 // Load Float Constant 5604 5605 instruct loadConF(vRegF dst, immF con) %{ 5606 match(Set dst con); 5607 5608 ins_cost(INSN_COST * 4); 5609 5610 format %{ 5611 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 5612 %} 5613 5614 ins_encode %{ 5615 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 5616 %} 5617 5618 ins_pipe(pipe_class_default); 5619 %} 5620 5621 // Load Packed Double Constant 5622 5623 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 5624 match(Set dst con); 5625 ins_cost(INSN_COST); 5626 format %{ "fmovd $dst, $con"%} 5627 ins_encode %{ 5628 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 5629 %} 5630 5631 ins_pipe(pipe_class_default); 5632 %} 5633 5634 // Load Double Constant 5635 5636 instruct loadConD(vRegD dst, immD con) %{ 5637 match(Set dst con); 5638 5639 ins_cost(INSN_COST * 5); 5640 format %{ 5641 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 5642 %} 5643 5644 ins_encode %{ 5645 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 5646 %} 5647 5648 ins_pipe(pipe_class_default); 5649 %} 5650 5651 // Store Instructions 5652 5653 // Store CMS card-mark Immediate 5654 instruct storeimmCM0(immI0 zero, memory mem) 5655 %{ 5656 match(Set mem (StoreCM mem zero)); 5657 5658 ins_cost(INSN_COST); 5659 format %{ "strb zr, $mem\t# byte" %} 5660 5661 ins_encode(aarch64_enc_strb0(mem)); 5662 5663 ins_pipe(istore_mem); 5664 %} 5665 5666 // Store Byte 5667 instruct storeB(iRegI src, memory mem) 5668 %{ 5669 match(Set mem (StoreB mem src)); 5670 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5671 5672 ins_cost(INSN_COST); 5673 format %{ "strb $src, $mem\t# byte" %} 5674 5675 ins_encode(aarch64_enc_strb(src, mem)); 5676 5677 ins_pipe(istore_reg_mem); 5678 %} 5679 5680 5681 instruct storeimmB0(immI0 zero, memory mem) 5682 %{ 5683 match(Set mem (StoreB mem zero)); 5684 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5685 5686 ins_cost(INSN_COST); 5687 format %{ "strb zr, $mem\t# byte" %} 5688 5689 ins_encode(aarch64_enc_strb0(mem)); 5690 5691 ins_pipe(istore_mem); 5692 %} 5693 5694 // Store Char/Short 5695 instruct storeC(iRegI src, memory mem) 5696 %{ 5697 match(Set mem (StoreC mem src)); 5698 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5699 5700 ins_cost(INSN_COST); 5701 format %{ "strh $src, $mem\t# short" %} 5702 5703 ins_encode(aarch64_enc_strh(src, mem)); 5704 5705 ins_pipe(istore_reg_mem); 5706 %} 5707 5708 instruct storeimmC0(immI0 zero, memory mem) 5709 %{ 5710 match(Set mem (StoreC mem zero)); 5711 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5712 5713 ins_cost(INSN_COST); 5714 format %{ "strh zr, $mem\t# short" %} 5715 5716 ins_encode(aarch64_enc_strh0(mem)); 5717 5718 ins_pipe(istore_mem); 5719 %} 5720 5721 // Store Integer 5722 5723 instruct storeI(iRegIorL2I src, memory mem) 5724 %{ 5725 match(Set mem(StoreI mem src)); 5726 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5727 5728 ins_cost(INSN_COST); 5729 format %{ "strw $src, $mem\t# int" %} 5730 5731 ins_encode(aarch64_enc_strw(src, mem)); 5732 5733 ins_pipe(istore_reg_mem); 5734 %} 5735 5736 instruct storeimmI0(immI0 zero, memory mem) 5737 %{ 5738 match(Set mem(StoreI mem zero)); 5739 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5740 5741 ins_cost(INSN_COST); 5742 format %{ "strw zr, $mem\t# int" %} 5743 5744 ins_encode(aarch64_enc_strw0(mem)); 5745 5746 ins_pipe(istore_mem); 5747 %} 5748 5749 // Store Long (64 bit signed) 5750 instruct storeL(iRegL src, memory mem) 5751 %{ 5752 match(Set mem (StoreL mem src)); 5753 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5754 5755 ins_cost(INSN_COST); 5756 format %{ "str $src, $mem\t# int" %} 5757 5758 ins_encode(aarch64_enc_str(src, mem)); 5759 5760 ins_pipe(istore_reg_mem); 5761 %} 5762 5763 // Store Long (64 bit signed) 5764 instruct storeimmL0(immL0 zero, memory mem) 5765 %{ 5766 match(Set mem (StoreL mem zero)); 5767 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5768 5769 ins_cost(INSN_COST); 5770 format %{ "str zr, $mem\t# int" %} 5771 5772 ins_encode(aarch64_enc_str0(mem)); 5773 5774 ins_pipe(istore_mem); 5775 %} 5776 5777 // Store Pointer 5778 instruct storeP(iRegP src, memory mem) 5779 %{ 5780 match(Set mem (StoreP mem src)); 5781 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5782 5783 ins_cost(INSN_COST); 5784 format %{ "str $src, $mem\t# ptr" %} 5785 5786 ins_encode(aarch64_enc_str(src, mem)); 5787 5788 ins_pipe(istore_reg_mem); 5789 %} 5790 5791 // Store Pointer 5792 instruct storeimmP0(immP0 zero, memory mem) 5793 %{ 5794 match(Set mem (StoreP mem zero)); 5795 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5796 5797 ins_cost(INSN_COST); 5798 format %{ "str zr, $mem\t# ptr" %} 5799 5800 ins_encode(aarch64_enc_str0(mem)); 5801 5802 ins_pipe(istore_mem); 5803 %} 5804 5805 // Store Compressed Pointer 5806 instruct storeN(iRegN src, memory mem) 5807 %{ 5808 match(Set mem (StoreN mem src)); 5809 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5810 5811 ins_cost(INSN_COST); 5812 format %{ "strw $src, $mem\t# compressed ptr" %} 5813 5814 ins_encode(aarch64_enc_strw(src, mem)); 5815 5816 ins_pipe(istore_reg_mem); 5817 %} 5818 5819 instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory mem) 5820 %{ 5821 match(Set mem (StoreN mem zero)); 5822 predicate(Universe::narrow_oop_base() == NULL && 5823 Universe::narrow_klass_base() == NULL && 5824 (UseBarriersForVolatile || n->as_Store()->is_unordered())); 5825 5826 ins_cost(INSN_COST); 5827 format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} 5828 5829 ins_encode(aarch64_enc_strw(heapbase, mem)); 5830 5831 ins_pipe(istore_reg_mem); 5832 %} 5833 5834 // Store Float 5835 instruct storeF(vRegF src, memory mem) 5836 %{ 5837 match(Set mem (StoreF mem src)); 5838 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5839 5840 ins_cost(INSN_COST); 5841 format %{ "strs $src, $mem\t# float" %} 5842 5843 ins_encode( aarch64_enc_strs(src, mem) ); 5844 5845 ins_pipe(pipe_class_memory); 5846 %} 5847 5848 // TODO 5849 // implement storeImmF0 and storeFImmPacked 5850 5851 // Store Double 5852 instruct storeD(vRegD src, memory mem) 5853 %{ 5854 match(Set mem (StoreD mem src)); 5855 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5856 5857 ins_cost(INSN_COST); 5858 format %{ "strd $src, $mem\t# double" %} 5859 5860 ins_encode( aarch64_enc_strd(src, mem) ); 5861 5862 ins_pipe(pipe_class_memory); 5863 %} 5864 5865 // Store Compressed Klass Pointer 5866 instruct storeNKlass(iRegN src, memory mem) 5867 %{ 5868 predicate(UseBarriersForVolatile || n->as_Store()->is_unordered()); 5869 match(Set mem (StoreNKlass mem src)); 5870 5871 ins_cost(INSN_COST); 5872 format %{ "strw $src, $mem\t# compressed klass ptr" %} 5873 5874 ins_encode(aarch64_enc_strw(src, mem)); 5875 5876 ins_pipe(istore_reg_mem); 5877 %} 5878 5879 // TODO 5880 // implement storeImmD0 and storeDImmPacked 5881 5882 // prefetch instructions 5883 // Must be safe to execute with invalid address (cannot fault). 5884 5885 instruct prefetchr( memory mem ) %{ 5886 match(PrefetchRead mem); 5887 5888 ins_cost(INSN_COST); 5889 format %{ "prfm $mem, PLDL1KEEP\t# Prefetch into level 1 cache read keep" %} 5890 5891 ins_encode( aarch64_enc_prefetchr(mem) ); 5892 5893 ins_pipe(iload_prefetch); 5894 %} 5895 5896 instruct prefetchw( memory mem ) %{ 5897 match(PrefetchAllocation mem); 5898 5899 ins_cost(INSN_COST); 5900 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 5901 5902 ins_encode( aarch64_enc_prefetchw(mem) ); 5903 5904 ins_pipe(iload_prefetch); 5905 %} 5906 5907 instruct prefetchnta( memory mem ) %{ 5908 match(PrefetchWrite mem); 5909 5910 ins_cost(INSN_COST); 5911 format %{ "prfm $mem, PSTL1STRM\t# Prefetch into level 1 cache write streaming" %} 5912 5913 ins_encode( aarch64_enc_prefetchnta(mem) ); 5914 5915 ins_pipe(iload_prefetch); 5916 %} 5917 5918 // ---------------- volatile loads and stores ---------------- 5919 5920 // Load Byte (8 bit signed) 5921 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 5922 %{ 5923 match(Set dst (LoadB mem)); 5924 5925 ins_cost(VOLATILE_REF_COST); 5926 format %{ "ldarsb $dst, $mem\t# byte" %} 5927 5928 ins_encode(aarch64_enc_ldarsb(dst, mem)); 5929 5930 ins_pipe(pipe_serial); 5931 %} 5932 5933 // Load Byte (8 bit signed) into long 5934 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 5935 %{ 5936 match(Set dst (ConvI2L (LoadB mem))); 5937 5938 ins_cost(VOLATILE_REF_COST); 5939 format %{ "ldarsb $dst, $mem\t# byte" %} 5940 5941 ins_encode(aarch64_enc_ldarsb(dst, mem)); 5942 5943 ins_pipe(pipe_serial); 5944 %} 5945 5946 // Load Byte (8 bit unsigned) 5947 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 5948 %{ 5949 match(Set dst (LoadUB mem)); 5950 5951 ins_cost(VOLATILE_REF_COST); 5952 format %{ "ldarb $dst, $mem\t# byte" %} 5953 5954 ins_encode(aarch64_enc_ldarb(dst, mem)); 5955 5956 ins_pipe(pipe_serial); 5957 %} 5958 5959 // Load Byte (8 bit unsigned) into long 5960 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 5961 %{ 5962 match(Set dst (ConvI2L (LoadUB mem))); 5963 5964 ins_cost(VOLATILE_REF_COST); 5965 format %{ "ldarb $dst, $mem\t# byte" %} 5966 5967 ins_encode(aarch64_enc_ldarb(dst, mem)); 5968 5969 ins_pipe(pipe_serial); 5970 %} 5971 5972 // Load Short (16 bit signed) 5973 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 5974 %{ 5975 match(Set dst (LoadS mem)); 5976 5977 ins_cost(VOLATILE_REF_COST); 5978 format %{ "ldarshw $dst, $mem\t# short" %} 5979 5980 ins_encode(aarch64_enc_ldarshw(dst, mem)); 5981 5982 ins_pipe(pipe_serial); 5983 %} 5984 5985 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 5986 %{ 5987 match(Set dst (LoadUS mem)); 5988 5989 ins_cost(VOLATILE_REF_COST); 5990 format %{ "ldarhw $dst, $mem\t# short" %} 5991 5992 ins_encode(aarch64_enc_ldarhw(dst, mem)); 5993 5994 ins_pipe(pipe_serial); 5995 %} 5996 5997 // Load Short/Char (16 bit unsigned) into long 5998 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 5999 %{ 6000 match(Set dst (ConvI2L (LoadUS mem))); 6001 6002 ins_cost(VOLATILE_REF_COST); 6003 format %{ "ldarh $dst, $mem\t# short" %} 6004 6005 ins_encode(aarch64_enc_ldarh(dst, mem)); 6006 6007 ins_pipe(pipe_serial); 6008 %} 6009 6010 // Load Short/Char (16 bit signed) into long 6011 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6012 %{ 6013 match(Set dst (ConvI2L (LoadS mem))); 6014 6015 ins_cost(VOLATILE_REF_COST); 6016 format %{ "ldarh $dst, $mem\t# short" %} 6017 6018 ins_encode(aarch64_enc_ldarsh(dst, mem)); 6019 6020 ins_pipe(pipe_serial); 6021 %} 6022 6023 // Load Integer (32 bit signed) 6024 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 6025 %{ 6026 match(Set dst (LoadI mem)); 6027 6028 ins_cost(VOLATILE_REF_COST); 6029 format %{ "ldarw $dst, $mem\t# int" %} 6030 6031 ins_encode(aarch64_enc_ldarw(dst, mem)); 6032 6033 ins_pipe(pipe_serial); 6034 %} 6035 6036 // Load Integer (32 bit unsigned) into long 6037 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 6038 %{ 6039 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6040 6041 ins_cost(VOLATILE_REF_COST); 6042 format %{ "ldarw $dst, $mem\t# int" %} 6043 6044 ins_encode(aarch64_enc_ldarw(dst, mem)); 6045 6046 ins_pipe(pipe_serial); 6047 %} 6048 6049 // Load Long (64 bit signed) 6050 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 6051 %{ 6052 match(Set dst (LoadL mem)); 6053 6054 ins_cost(VOLATILE_REF_COST); 6055 format %{ "ldar $dst, $mem\t# int" %} 6056 6057 ins_encode(aarch64_enc_ldar(dst, mem)); 6058 6059 ins_pipe(pipe_serial); 6060 %} 6061 6062 // Load Pointer 6063 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 6064 %{ 6065 match(Set dst (LoadP mem)); 6066 6067 ins_cost(VOLATILE_REF_COST); 6068 format %{ "ldar $dst, $mem\t# ptr" %} 6069 6070 ins_encode(aarch64_enc_ldar(dst, mem)); 6071 6072 ins_pipe(pipe_serial); 6073 %} 6074 6075 // Load Compressed Pointer 6076 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 6077 %{ 6078 match(Set dst (LoadN mem)); 6079 6080 ins_cost(VOLATILE_REF_COST); 6081 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 6082 6083 ins_encode(aarch64_enc_ldarw(dst, mem)); 6084 6085 ins_pipe(pipe_serial); 6086 %} 6087 6088 // Load Float 6089 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 6090 %{ 6091 match(Set dst (LoadF mem)); 6092 6093 ins_cost(VOLATILE_REF_COST); 6094 format %{ "ldars $dst, $mem\t# float" %} 6095 6096 ins_encode( aarch64_enc_fldars(dst, mem) ); 6097 6098 ins_pipe(pipe_serial); 6099 %} 6100 6101 // Load Double 6102 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 6103 %{ 6104 match(Set dst (LoadD mem)); 6105 6106 ins_cost(VOLATILE_REF_COST); 6107 format %{ "ldard $dst, $mem\t# double" %} 6108 6109 ins_encode( aarch64_enc_fldard(dst, mem) ); 6110 6111 ins_pipe(pipe_serial); 6112 %} 6113 6114 // Store Byte 6115 instruct storeB_volatile(iRegI src, /* sync_memory*/indirect mem) 6116 %{ 6117 match(Set mem (StoreB mem src)); 6118 6119 ins_cost(VOLATILE_REF_COST); 6120 format %{ "stlrb $src, $mem\t# byte" %} 6121 6122 ins_encode(aarch64_enc_stlrb(src, mem)); 6123 6124 ins_pipe(pipe_class_memory); 6125 %} 6126 6127 // Store Char/Short 6128 instruct storeC_volatile(iRegI src, /* sync_memory*/indirect mem) 6129 %{ 6130 match(Set mem (StoreC mem src)); 6131 6132 ins_cost(VOLATILE_REF_COST); 6133 format %{ "stlrh $src, $mem\t# short" %} 6134 6135 ins_encode(aarch64_enc_stlrh(src, mem)); 6136 6137 ins_pipe(pipe_class_memory); 6138 %} 6139 6140 // Store Integer 6141 6142 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 6143 %{ 6144 match(Set mem(StoreI mem src)); 6145 6146 ins_cost(VOLATILE_REF_COST); 6147 format %{ "stlrw $src, $mem\t# int" %} 6148 6149 ins_encode(aarch64_enc_stlrw(src, mem)); 6150 6151 ins_pipe(pipe_class_memory); 6152 %} 6153 6154 // Store Long (64 bit signed) 6155 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 6156 %{ 6157 match(Set mem (StoreL mem src)); 6158 6159 ins_cost(VOLATILE_REF_COST); 6160 format %{ "stlr $src, $mem\t# int" %} 6161 6162 ins_encode(aarch64_enc_stlr(src, mem)); 6163 6164 ins_pipe(pipe_class_memory); 6165 %} 6166 6167 // Store Pointer 6168 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 6169 %{ 6170 match(Set mem (StoreP mem src)); 6171 6172 ins_cost(VOLATILE_REF_COST); 6173 format %{ "stlr $src, $mem\t# ptr" %} 6174 6175 ins_encode(aarch64_enc_stlr(src, mem)); 6176 6177 ins_pipe(pipe_class_memory); 6178 %} 6179 6180 // Store Compressed Pointer 6181 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 6182 %{ 6183 match(Set mem (StoreN mem src)); 6184 6185 ins_cost(VOLATILE_REF_COST); 6186 format %{ "stlrw $src, $mem\t# compressed ptr" %} 6187 6188 ins_encode(aarch64_enc_stlrw(src, mem)); 6189 6190 ins_pipe(pipe_class_memory); 6191 %} 6192 6193 // Store Float 6194 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 6195 %{ 6196 match(Set mem (StoreF mem src)); 6197 6198 ins_cost(VOLATILE_REF_COST); 6199 format %{ "stlrs $src, $mem\t# float" %} 6200 6201 ins_encode( aarch64_enc_fstlrs(src, mem) ); 6202 6203 ins_pipe(pipe_class_memory); 6204 %} 6205 6206 // TODO 6207 // implement storeImmF0 and storeFImmPacked 6208 6209 // Store Double 6210 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 6211 %{ 6212 match(Set mem (StoreD mem src)); 6213 6214 ins_cost(VOLATILE_REF_COST); 6215 format %{ "stlrd $src, $mem\t# double" %} 6216 6217 ins_encode( aarch64_enc_fstlrd(src, mem) ); 6218 6219 ins_pipe(pipe_class_memory); 6220 %} 6221 6222 // ---------------- end of volatile loads and stores ---------------- 6223 6224 // ============================================================================ 6225 // BSWAP Instructions 6226 6227 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 6228 match(Set dst (ReverseBytesI src)); 6229 6230 ins_cost(INSN_COST); 6231 format %{ "revw $dst, $src" %} 6232 6233 ins_encode %{ 6234 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 6235 %} 6236 6237 ins_pipe(ialu_reg); 6238 %} 6239 6240 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 6241 match(Set dst (ReverseBytesL src)); 6242 6243 ins_cost(INSN_COST); 6244 format %{ "rev $dst, $src" %} 6245 6246 ins_encode %{ 6247 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 6248 %} 6249 6250 ins_pipe(ialu_reg); 6251 %} 6252 6253 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 6254 match(Set dst (ReverseBytesUS src)); 6255 6256 ins_cost(INSN_COST); 6257 format %{ "rev16w $dst, $src" %} 6258 6259 ins_encode %{ 6260 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 6261 %} 6262 6263 ins_pipe(ialu_reg); 6264 %} 6265 6266 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 6267 match(Set dst (ReverseBytesS src)); 6268 6269 ins_cost(INSN_COST); 6270 format %{ "rev16w $dst, $src\n\t" 6271 "sbfmw $dst, $dst, #0, #15" %} 6272 6273 ins_encode %{ 6274 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 6275 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 6276 %} 6277 6278 ins_pipe(ialu_reg); 6279 %} 6280 6281 // ============================================================================ 6282 // Zero Count Instructions 6283 6284 instruct countLeadingZerosI(iRegI dst, iRegI src) %{ 6285 match(Set dst (CountLeadingZerosI src)); 6286 6287 ins_cost(INSN_COST); 6288 format %{ "clzw $dst, $src" %} 6289 ins_encode %{ 6290 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 6291 %} 6292 6293 ins_pipe(ialu_reg); 6294 %} 6295 6296 instruct countLeadingZerosL(iRegI dst, iRegL src) %{ 6297 match(Set dst (CountLeadingZerosL src)); 6298 6299 ins_cost(INSN_COST); 6300 format %{ "clz $dst, $src" %} 6301 ins_encode %{ 6302 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 6303 %} 6304 6305 ins_pipe(ialu_reg); 6306 %} 6307 6308 instruct countTrailingZerosI(iRegI dst, iRegI src) %{ 6309 match(Set dst (CountTrailingZerosI src)); 6310 6311 ins_cost(INSN_COST * 2); 6312 format %{ "rbitw $dst, $src\n\t" 6313 "clzw $dst, $dst" %} 6314 ins_encode %{ 6315 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 6316 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 6317 %} 6318 6319 ins_pipe(ialu_reg); 6320 %} 6321 6322 instruct countTrailingZerosL(iRegI dst, iRegL src) %{ 6323 match(Set dst (CountTrailingZerosL src)); 6324 6325 ins_cost(INSN_COST * 2); 6326 format %{ "rbit $dst, $src\n\t" 6327 "clz $dst, $dst" %} 6328 ins_encode %{ 6329 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 6330 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 6331 %} 6332 6333 ins_pipe(ialu_reg); 6334 %} 6335 6336 // ============================================================================ 6337 // MemBar Instruction 6338 6339 instruct load_fence() %{ 6340 match(LoadFence); 6341 ins_cost(VOLATILE_REF_COST); 6342 6343 format %{ "load_fence" %} 6344 6345 ins_encode %{ 6346 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 6347 %} 6348 ins_pipe(pipe_serial); 6349 %} 6350 6351 instruct unnecessary_membar_acquire() %{ 6352 predicate(! UseBarriersForVolatile && preceded_by_ordered_load(n)); 6353 match(MemBarAcquire); 6354 ins_cost(0); 6355 6356 format %{ "membar_acquire (elided)" %} 6357 6358 ins_encode %{ 6359 __ block_comment("membar_acquire (elided)"); 6360 %} 6361 6362 ins_pipe(pipe_class_empty); 6363 %} 6364 6365 instruct membar_acquire() %{ 6366 match(MemBarAcquire); 6367 ins_cost(VOLATILE_REF_COST); 6368 6369 format %{ "membar_acquire" %} 6370 6371 ins_encode %{ 6372 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 6373 %} 6374 6375 ins_pipe(pipe_serial); 6376 %} 6377 6378 6379 instruct membar_acquire_lock() %{ 6380 match(MemBarAcquireLock); 6381 ins_cost(VOLATILE_REF_COST); 6382 6383 format %{ "membar_acquire_lock" %} 6384 6385 ins_encode %{ 6386 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 6387 %} 6388 6389 ins_pipe(pipe_serial); 6390 %} 6391 6392 instruct store_fence() %{ 6393 match(StoreFence); 6394 ins_cost(VOLATILE_REF_COST); 6395 6396 format %{ "store_fence" %} 6397 6398 ins_encode %{ 6399 __ membar(Assembler::LoadStore|Assembler::StoreStore); 6400 %} 6401 ins_pipe(pipe_serial); 6402 %} 6403 6404 instruct membar_release() %{ 6405 match(MemBarRelease); 6406 ins_cost(VOLATILE_REF_COST); 6407 6408 format %{ "membar_release" %} 6409 6410 ins_encode %{ 6411 __ membar(Assembler::LoadStore|Assembler::StoreStore); 6412 %} 6413 ins_pipe(pipe_serial); 6414 %} 6415 6416 instruct membar_storestore() %{ 6417 match(MemBarStoreStore); 6418 ins_cost(VOLATILE_REF_COST); 6419 6420 format %{ "MEMBAR-store-store" %} 6421 6422 ins_encode %{ 6423 __ membar(Assembler::StoreStore); 6424 %} 6425 ins_pipe(pipe_serial); 6426 %} 6427 6428 instruct membar_release_lock() %{ 6429 match(MemBarReleaseLock); 6430 ins_cost(VOLATILE_REF_COST); 6431 6432 format %{ "membar_release_lock" %} 6433 6434 ins_encode %{ 6435 __ membar(Assembler::LoadStore|Assembler::StoreStore); 6436 %} 6437 6438 ins_pipe(pipe_serial); 6439 %} 6440 6441 instruct membar_volatile() %{ 6442 match(MemBarVolatile); 6443 ins_cost(VOLATILE_REF_COST*100); 6444 6445 format %{ "membar_volatile" %} 6446 6447 ins_encode %{ 6448 __ membar(Assembler::StoreLoad); 6449 %} 6450 6451 ins_pipe(pipe_serial); 6452 %} 6453 6454 // ============================================================================ 6455 // Cast/Convert Instructions 6456 6457 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 6458 match(Set dst (CastX2P src)); 6459 6460 ins_cost(INSN_COST); 6461 format %{ "mov $dst, $src\t# long -> ptr" %} 6462 6463 ins_encode %{ 6464 if ($dst$$reg != $src$$reg) { 6465 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 6466 } 6467 %} 6468 6469 ins_pipe(ialu_reg); 6470 %} 6471 6472 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 6473 match(Set dst (CastP2X src)); 6474 6475 ins_cost(INSN_COST); 6476 format %{ "mov $dst, $src\t# ptr -> long" %} 6477 6478 ins_encode %{ 6479 if ($dst$$reg != $src$$reg) { 6480 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 6481 } 6482 %} 6483 6484 ins_pipe(ialu_reg); 6485 %} 6486 6487 // Convert oop into int for vectors alignment masking 6488 instruct convP2I(iRegINoSp dst, iRegP src) %{ 6489 match(Set dst (ConvL2I (CastP2X src))); 6490 6491 ins_cost(INSN_COST); 6492 format %{ "movw $dst, $src\t# ptr -> int" %} 6493 ins_encode %{ 6494 __ movw($dst$$Register, $src$$Register); 6495 %} 6496 6497 ins_pipe(ialu_reg); 6498 %} 6499 6500 // Convert compressed oop into int for vectors alignment masking 6501 // in case of 32bit oops (heap < 4Gb). 6502 instruct convN2I(iRegINoSp dst, iRegN src) 6503 %{ 6504 predicate(Universe::narrow_oop_shift() == 0); 6505 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6506 6507 ins_cost(INSN_COST); 6508 format %{ "mov dst, $src\t# compressed ptr -> int" %} 6509 ins_encode %{ 6510 __ movw($dst$$Register, $src$$Register); 6511 %} 6512 6513 ins_pipe(ialu_reg); 6514 %} 6515 6516 6517 // Convert oop pointer into compressed form 6518 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 6519 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6520 match(Set dst (EncodeP src)); 6521 effect(KILL cr); 6522 ins_cost(INSN_COST * 3); 6523 format %{ "encode_heap_oop $dst, $src" %} 6524 ins_encode %{ 6525 Register s = $src$$Register; 6526 Register d = $dst$$Register; 6527 __ encode_heap_oop(d, s); 6528 %} 6529 ins_pipe(ialu_reg); 6530 %} 6531 6532 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 6533 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6534 match(Set dst (EncodeP src)); 6535 ins_cost(INSN_COST * 3); 6536 format %{ "encode_heap_oop_not_null $dst, $src" %} 6537 ins_encode %{ 6538 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6539 %} 6540 ins_pipe(ialu_reg); 6541 %} 6542 6543 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 6544 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6545 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6546 match(Set dst (DecodeN src)); 6547 ins_cost(INSN_COST * 3); 6548 format %{ "decode_heap_oop $dst, $src" %} 6549 ins_encode %{ 6550 Register s = $src$$Register; 6551 Register d = $dst$$Register; 6552 __ decode_heap_oop(d, s); 6553 %} 6554 ins_pipe(ialu_reg); 6555 %} 6556 6557 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 6558 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6559 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6560 match(Set dst (DecodeN src)); 6561 ins_cost(INSN_COST * 3); 6562 format %{ "decode_heap_oop_not_null $dst, $src" %} 6563 ins_encode %{ 6564 Register s = $src$$Register; 6565 Register d = $dst$$Register; 6566 __ decode_heap_oop_not_null(d, s); 6567 %} 6568 ins_pipe(ialu_reg); 6569 %} 6570 6571 // n.b. AArch64 implementations of encode_klass_not_null and 6572 // decode_klass_not_null do not modify the flags register so, unlike 6573 // Intel, we don't kill CR as a side effect here 6574 6575 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 6576 match(Set dst (EncodePKlass src)); 6577 6578 ins_cost(INSN_COST * 3); 6579 format %{ "encode_klass_not_null $dst,$src" %} 6580 6581 ins_encode %{ 6582 Register src_reg = as_Register($src$$reg); 6583 Register dst_reg = as_Register($dst$$reg); 6584 __ encode_klass_not_null(dst_reg, src_reg); 6585 %} 6586 6587 ins_pipe(ialu_reg); 6588 %} 6589 6590 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 6591 match(Set dst (DecodeNKlass src)); 6592 6593 ins_cost(INSN_COST * 3); 6594 format %{ "decode_klass_not_null $dst,$src" %} 6595 6596 ins_encode %{ 6597 Register src_reg = as_Register($src$$reg); 6598 Register dst_reg = as_Register($dst$$reg); 6599 if (dst_reg != src_reg) { 6600 __ decode_klass_not_null(dst_reg, src_reg); 6601 } else { 6602 __ decode_klass_not_null(dst_reg); 6603 } 6604 %} 6605 6606 ins_pipe(ialu_reg); 6607 %} 6608 6609 instruct checkCastPP(iRegPNoSp dst) 6610 %{ 6611 match(Set dst (CheckCastPP dst)); 6612 6613 size(0); 6614 format %{ "# checkcastPP of $dst" %} 6615 ins_encode(/* empty encoding */); 6616 ins_pipe(pipe_class_empty); 6617 %} 6618 6619 instruct castPP(iRegPNoSp dst) 6620 %{ 6621 match(Set dst (CastPP dst)); 6622 6623 size(0); 6624 format %{ "# castPP of $dst" %} 6625 ins_encode(/* empty encoding */); 6626 ins_pipe(pipe_class_empty); 6627 %} 6628 6629 instruct castII(iRegI dst) 6630 %{ 6631 match(Set dst (CastII dst)); 6632 6633 size(0); 6634 format %{ "# castII of $dst" %} 6635 ins_encode(/* empty encoding */); 6636 ins_cost(0); 6637 ins_pipe(pipe_class_empty); 6638 %} 6639 6640 // ============================================================================ 6641 // Atomic operation instructions 6642 // 6643 // Intel and SPARC both implement Ideal Node LoadPLocked and 6644 // Store{PIL}Conditional instructions using a normal load for the 6645 // LoadPLocked and a CAS for the Store{PIL}Conditional. 6646 // 6647 // The ideal code appears only to use LoadPLocked/StorePLocked as a 6648 // pair to lock object allocations from Eden space when not using 6649 // TLABs. 6650 // 6651 // There does not appear to be a Load{IL}Locked Ideal Node and the 6652 // Ideal code appears to use Store{IL}Conditional as an alias for CAS 6653 // and to use StoreIConditional only for 32-bit and StoreLConditional 6654 // only for 64-bit. 6655 // 6656 // We implement LoadPLocked and StorePLocked instructions using, 6657 // respectively the AArch64 hw load-exclusive and store-conditional 6658 // instructions. Whereas we must implement each of 6659 // Store{IL}Conditional using a CAS which employs a pair of 6660 // instructions comprising a load-exclusive followed by a 6661 // store-conditional. 6662 6663 6664 // Locked-load (linked load) of the current heap-top 6665 // used when updating the eden heap top 6666 // implemented using ldaxr on AArch64 6667 6668 instruct loadPLocked(iRegPNoSp dst, indirect mem) 6669 %{ 6670 match(Set dst (LoadPLocked mem)); 6671 6672 ins_cost(VOLATILE_REF_COST); 6673 6674 format %{ "ldaxr $dst, $mem\t# ptr linked acquire" %} 6675 6676 ins_encode(aarch64_enc_ldaxr(dst, mem)); 6677 6678 ins_pipe(pipe_serial); 6679 %} 6680 6681 // Conditional-store of the updated heap-top. 6682 // Used during allocation of the shared heap. 6683 // Sets flag (EQ) on success. 6684 // implemented using stlxr on AArch64. 6685 6686 instruct storePConditional(memory heap_top_ptr, iRegP oldval, iRegP newval, rFlagsReg cr) 6687 %{ 6688 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 6689 6690 ins_cost(VOLATILE_REF_COST); 6691 6692 // TODO 6693 // do we need to do a store-conditional release or can we just use a 6694 // plain store-conditional? 6695 6696 format %{ 6697 "stlxr rscratch1, $newval, $heap_top_ptr\t# ptr cond release" 6698 "cmpw rscratch1, zr\t# EQ on successful write" 6699 %} 6700 6701 ins_encode(aarch64_enc_stlxr(newval, heap_top_ptr)); 6702 6703 ins_pipe(pipe_serial); 6704 %} 6705 6706 // this has to be implemented as a CAS 6707 instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) 6708 %{ 6709 match(Set cr (StoreLConditional mem (Binary oldval newval))); 6710 6711 ins_cost(VOLATILE_REF_COST); 6712 6713 format %{ 6714 "cmpxchg rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 6715 "cmpw rscratch1, zr\t# EQ on successful write" 6716 %} 6717 6718 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval)); 6719 6720 ins_pipe(pipe_slow); 6721 %} 6722 6723 // this has to be implemented as a CAS 6724 instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) 6725 %{ 6726 match(Set cr (StoreIConditional mem (Binary oldval newval))); 6727 6728 ins_cost(VOLATILE_REF_COST); 6729 6730 format %{ 6731 "cmpxchgw rscratch1, $mem, $oldval, $newval, $mem\t# if $mem == $oldval then $mem <-- $newval" 6732 "cmpw rscratch1, zr\t# EQ on successful write" 6733 %} 6734 6735 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval)); 6736 6737 ins_pipe(pipe_slow); 6738 %} 6739 6740 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 6741 // can't match them 6742 6743 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 6744 6745 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 6746 6747 effect(KILL cr); 6748 6749 format %{ 6750 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 6751 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 6752 %} 6753 6754 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 6755 aarch64_enc_cset_eq(res)); 6756 6757 ins_pipe(pipe_slow); 6758 %} 6759 6760 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 6761 6762 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 6763 6764 effect(KILL cr); 6765 6766 format %{ 6767 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 6768 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 6769 %} 6770 6771 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 6772 aarch64_enc_cset_eq(res)); 6773 6774 ins_pipe(pipe_slow); 6775 %} 6776 6777 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 6778 6779 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 6780 6781 effect(KILL cr); 6782 6783 format %{ 6784 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 6785 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 6786 %} 6787 6788 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 6789 aarch64_enc_cset_eq(res)); 6790 6791 ins_pipe(pipe_slow); 6792 %} 6793 6794 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 6795 6796 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 6797 6798 effect(KILL cr); 6799 6800 format %{ 6801 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 6802 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 6803 %} 6804 6805 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 6806 aarch64_enc_cset_eq(res)); 6807 6808 ins_pipe(pipe_slow); 6809 %} 6810 6811 6812 instruct get_and_setI(indirect mem, iRegINoSp newv, iRegI prev) %{ 6813 match(Set prev (GetAndSetI mem newv)); 6814 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 6815 ins_encode %{ 6816 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6817 %} 6818 ins_pipe(pipe_serial); 6819 %} 6820 6821 instruct get_and_setL(indirect mem, iRegLNoSp newv, iRegL prev) %{ 6822 match(Set prev (GetAndSetL mem newv)); 6823 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 6824 ins_encode %{ 6825 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6826 %} 6827 ins_pipe(pipe_serial); 6828 %} 6829 6830 instruct get_and_setN(indirect mem, iRegNNoSp newv, iRegI prev) %{ 6831 match(Set prev (GetAndSetN mem newv)); 6832 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 6833 ins_encode %{ 6834 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6835 %} 6836 ins_pipe(pipe_serial); 6837 %} 6838 6839 instruct get_and_setP(indirect mem, iRegPNoSp newv, iRegP prev) %{ 6840 match(Set prev (GetAndSetP mem newv)); 6841 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 6842 ins_encode %{ 6843 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 6844 %} 6845 ins_pipe(pipe_serial); 6846 %} 6847 6848 6849 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 6850 match(Set newval (GetAndAddL mem incr)); 6851 ins_cost(INSN_COST * 10); 6852 format %{ "get_and_addL $newval, [$mem], $incr" %} 6853 ins_encode %{ 6854 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6855 %} 6856 ins_pipe(pipe_serial); 6857 %} 6858 6859 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 6860 predicate(n->as_LoadStore()->result_not_used()); 6861 match(Set dummy (GetAndAddL mem incr)); 6862 ins_cost(INSN_COST * 9); 6863 format %{ "get_and_addL [$mem], $incr" %} 6864 ins_encode %{ 6865 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 6866 %} 6867 ins_pipe(pipe_serial); 6868 %} 6869 6870 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 6871 match(Set newval (GetAndAddL mem incr)); 6872 ins_cost(INSN_COST * 10); 6873 format %{ "get_and_addL $newval, [$mem], $incr" %} 6874 ins_encode %{ 6875 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6876 %} 6877 ins_pipe(pipe_serial); 6878 %} 6879 6880 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 6881 predicate(n->as_LoadStore()->result_not_used()); 6882 match(Set dummy (GetAndAddL mem incr)); 6883 ins_cost(INSN_COST * 9); 6884 format %{ "get_and_addL [$mem], $incr" %} 6885 ins_encode %{ 6886 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 6887 %} 6888 ins_pipe(pipe_serial); 6889 %} 6890 6891 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 6892 match(Set newval (GetAndAddI mem incr)); 6893 ins_cost(INSN_COST * 10); 6894 format %{ "get_and_addI $newval, [$mem], $incr" %} 6895 ins_encode %{ 6896 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 6897 %} 6898 ins_pipe(pipe_serial); 6899 %} 6900 6901 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 6902 predicate(n->as_LoadStore()->result_not_used()); 6903 match(Set dummy (GetAndAddI mem incr)); 6904 ins_cost(INSN_COST * 9); 6905 format %{ "get_and_addI [$mem], $incr" %} 6906 ins_encode %{ 6907 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 6908 %} 6909 ins_pipe(pipe_serial); 6910 %} 6911 6912 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 6913 match(Set newval (GetAndAddI mem incr)); 6914 ins_cost(INSN_COST * 10); 6915 format %{ "get_and_addI $newval, [$mem], $incr" %} 6916 ins_encode %{ 6917 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 6918 %} 6919 ins_pipe(pipe_serial); 6920 %} 6921 6922 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 6923 predicate(n->as_LoadStore()->result_not_used()); 6924 match(Set dummy (GetAndAddI mem incr)); 6925 ins_cost(INSN_COST * 9); 6926 format %{ "get_and_addI [$mem], $incr" %} 6927 ins_encode %{ 6928 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 6929 %} 6930 ins_pipe(pipe_serial); 6931 %} 6932 6933 // Manifest a CmpL result in an integer register. 6934 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 6935 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 6936 %{ 6937 match(Set dst (CmpL3 src1 src2)); 6938 effect(KILL flags); 6939 6940 ins_cost(INSN_COST * 6); 6941 format %{ 6942 "cmp $src1, $src2" 6943 "csetw $dst, ne" 6944 "cnegw $dst, lt" 6945 %} 6946 // format %{ "CmpL3 $dst, $src1, $src2" %} 6947 ins_encode %{ 6948 __ cmp($src1$$Register, $src2$$Register); 6949 __ csetw($dst$$Register, Assembler::NE); 6950 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 6951 %} 6952 6953 ins_pipe(pipe_class_default); 6954 %} 6955 6956 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 6957 %{ 6958 match(Set dst (CmpL3 src1 src2)); 6959 effect(KILL flags); 6960 6961 ins_cost(INSN_COST * 6); 6962 format %{ 6963 "cmp $src1, $src2" 6964 "csetw $dst, ne" 6965 "cnegw $dst, lt" 6966 %} 6967 ins_encode %{ 6968 int32_t con = (int32_t)$src2$$constant; 6969 if (con < 0) { 6970 __ adds(zr, $src1$$Register, -con); 6971 } else { 6972 __ subs(zr, $src1$$Register, con); 6973 } 6974 __ csetw($dst$$Register, Assembler::NE); 6975 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 6976 %} 6977 6978 ins_pipe(pipe_class_default); 6979 %} 6980 6981 // ============================================================================ 6982 // Conditional Move Instructions 6983 6984 // n.b. we have identical rules for both a signed compare op (cmpOp) 6985 // and an unsigned compare op (cmpOpU). it would be nice if we could 6986 // define an op class which merged both inputs and use it to type the 6987 // argument to a single rule. unfortunatelyt his fails because the 6988 // opclass does not live up to the COND_INTER interface of its 6989 // component operands. When the generic code tries to negate the 6990 // operand it ends up running the generci Machoper::negate method 6991 // which throws a ShouldNotHappen. So, we have to provide two flavours 6992 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 6993 6994 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegI src1, iRegI src2) %{ 6995 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 6996 6997 ins_cost(INSN_COST * 2); 6998 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 6999 7000 ins_encode %{ 7001 __ cselw(as_Register($dst$$reg), 7002 as_Register($src2$$reg), 7003 as_Register($src1$$reg), 7004 (Assembler::Condition)$cmp$$cmpcode); 7005 %} 7006 7007 ins_pipe(icond_reg_reg); 7008 %} 7009 7010 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegI src1, iRegI src2) %{ 7011 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 7012 7013 ins_cost(INSN_COST * 2); 7014 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 7015 7016 ins_encode %{ 7017 __ cselw(as_Register($dst$$reg), 7018 as_Register($src2$$reg), 7019 as_Register($src1$$reg), 7020 (Assembler::Condition)$cmp$$cmpcode); 7021 %} 7022 7023 ins_pipe(icond_reg_reg); 7024 %} 7025 7026 // special cases where one arg is zero 7027 7028 // n.b. this is selected in preference to the rule above because it 7029 // avoids loading constant 0 into a source register 7030 7031 // TODO 7032 // we ought only to be able to cull one of these variants as the ideal 7033 // transforms ought always to order the zero consistently (to left/right?) 7034 7035 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegI src) %{ 7036 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 7037 7038 ins_cost(INSN_COST * 2); 7039 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 7040 7041 ins_encode %{ 7042 __ cselw(as_Register($dst$$reg), 7043 as_Register($src$$reg), 7044 zr, 7045 (Assembler::Condition)$cmp$$cmpcode); 7046 %} 7047 7048 ins_pipe(icond_reg); 7049 %} 7050 7051 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegI src) %{ 7052 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 7053 7054 ins_cost(INSN_COST * 2); 7055 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 7056 7057 ins_encode %{ 7058 __ cselw(as_Register($dst$$reg), 7059 as_Register($src$$reg), 7060 zr, 7061 (Assembler::Condition)$cmp$$cmpcode); 7062 %} 7063 7064 ins_pipe(icond_reg); 7065 %} 7066 7067 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegI src, immI0 zero) %{ 7068 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 7069 7070 ins_cost(INSN_COST * 2); 7071 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 7072 7073 ins_encode %{ 7074 __ cselw(as_Register($dst$$reg), 7075 zr, 7076 as_Register($src$$reg), 7077 (Assembler::Condition)$cmp$$cmpcode); 7078 %} 7079 7080 ins_pipe(icond_reg); 7081 %} 7082 7083 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegI src, immI0 zero) %{ 7084 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 7085 7086 ins_cost(INSN_COST * 2); 7087 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 7088 7089 ins_encode %{ 7090 __ cselw(as_Register($dst$$reg), 7091 zr, 7092 as_Register($src$$reg), 7093 (Assembler::Condition)$cmp$$cmpcode); 7094 %} 7095 7096 ins_pipe(icond_reg); 7097 %} 7098 7099 // special case for creating a boolean 0 or 1 7100 7101 // n.b. this is selected in preference to the rule above because it 7102 // avoids loading constants 0 and 1 into a source register 7103 7104 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 7105 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 7106 7107 ins_cost(INSN_COST * 2); 7108 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 7109 7110 ins_encode %{ 7111 // equivalently 7112 // cset(as_Register($dst$$reg), 7113 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 7114 __ csincw(as_Register($dst$$reg), 7115 zr, 7116 zr, 7117 (Assembler::Condition)$cmp$$cmpcode); 7118 %} 7119 7120 ins_pipe(icond_none); 7121 %} 7122 7123 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 7124 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 7125 7126 ins_cost(INSN_COST * 2); 7127 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 7128 7129 ins_encode %{ 7130 // equivalently 7131 // cset(as_Register($dst$$reg), 7132 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 7133 __ csincw(as_Register($dst$$reg), 7134 zr, 7135 zr, 7136 (Assembler::Condition)$cmp$$cmpcode); 7137 %} 7138 7139 ins_pipe(icond_none); 7140 %} 7141 7142 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7143 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 7144 7145 ins_cost(INSN_COST * 2); 7146 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 7147 7148 ins_encode %{ 7149 __ csel(as_Register($dst$$reg), 7150 as_Register($src2$$reg), 7151 as_Register($src1$$reg), 7152 (Assembler::Condition)$cmp$$cmpcode); 7153 %} 7154 7155 ins_pipe(icond_reg_reg); 7156 %} 7157 7158 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7159 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 7160 7161 ins_cost(INSN_COST * 2); 7162 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 7163 7164 ins_encode %{ 7165 __ csel(as_Register($dst$$reg), 7166 as_Register($src2$$reg), 7167 as_Register($src1$$reg), 7168 (Assembler::Condition)$cmp$$cmpcode); 7169 %} 7170 7171 ins_pipe(icond_reg_reg); 7172 %} 7173 7174 // special cases where one arg is zero 7175 7176 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 7177 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 7178 7179 ins_cost(INSN_COST * 2); 7180 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 7181 7182 ins_encode %{ 7183 __ csel(as_Register($dst$$reg), 7184 zr, 7185 as_Register($src$$reg), 7186 (Assembler::Condition)$cmp$$cmpcode); 7187 %} 7188 7189 ins_pipe(icond_reg); 7190 %} 7191 7192 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 7193 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 7194 7195 ins_cost(INSN_COST * 2); 7196 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 7197 7198 ins_encode %{ 7199 __ csel(as_Register($dst$$reg), 7200 zr, 7201 as_Register($src$$reg), 7202 (Assembler::Condition)$cmp$$cmpcode); 7203 %} 7204 7205 ins_pipe(icond_reg); 7206 %} 7207 7208 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 7209 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 7210 7211 ins_cost(INSN_COST * 2); 7212 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 7213 7214 ins_encode %{ 7215 __ csel(as_Register($dst$$reg), 7216 as_Register($src$$reg), 7217 zr, 7218 (Assembler::Condition)$cmp$$cmpcode); 7219 %} 7220 7221 ins_pipe(icond_reg); 7222 %} 7223 7224 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 7225 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 7226 7227 ins_cost(INSN_COST * 2); 7228 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 7229 7230 ins_encode %{ 7231 __ csel(as_Register($dst$$reg), 7232 as_Register($src$$reg), 7233 zr, 7234 (Assembler::Condition)$cmp$$cmpcode); 7235 %} 7236 7237 ins_pipe(icond_reg); 7238 %} 7239 7240 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 7241 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 7242 7243 ins_cost(INSN_COST * 2); 7244 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 7245 7246 ins_encode %{ 7247 __ csel(as_Register($dst$$reg), 7248 as_Register($src2$$reg), 7249 as_Register($src1$$reg), 7250 (Assembler::Condition)$cmp$$cmpcode); 7251 %} 7252 7253 ins_pipe(icond_reg_reg); 7254 %} 7255 7256 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 7257 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 7258 7259 ins_cost(INSN_COST * 2); 7260 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 7261 7262 ins_encode %{ 7263 __ csel(as_Register($dst$$reg), 7264 as_Register($src2$$reg), 7265 as_Register($src1$$reg), 7266 (Assembler::Condition)$cmp$$cmpcode); 7267 %} 7268 7269 ins_pipe(icond_reg_reg); 7270 %} 7271 7272 // special cases where one arg is zero 7273 7274 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 7275 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 7276 7277 ins_cost(INSN_COST * 2); 7278 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 7279 7280 ins_encode %{ 7281 __ csel(as_Register($dst$$reg), 7282 zr, 7283 as_Register($src$$reg), 7284 (Assembler::Condition)$cmp$$cmpcode); 7285 %} 7286 7287 ins_pipe(icond_reg); 7288 %} 7289 7290 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 7291 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 7292 7293 ins_cost(INSN_COST * 2); 7294 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 7295 7296 ins_encode %{ 7297 __ csel(as_Register($dst$$reg), 7298 zr, 7299 as_Register($src$$reg), 7300 (Assembler::Condition)$cmp$$cmpcode); 7301 %} 7302 7303 ins_pipe(icond_reg); 7304 %} 7305 7306 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 7307 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 7308 7309 ins_cost(INSN_COST * 2); 7310 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 7311 7312 ins_encode %{ 7313 __ csel(as_Register($dst$$reg), 7314 as_Register($src$$reg), 7315 zr, 7316 (Assembler::Condition)$cmp$$cmpcode); 7317 %} 7318 7319 ins_pipe(icond_reg); 7320 %} 7321 7322 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 7323 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 7324 7325 ins_cost(INSN_COST * 2); 7326 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 7327 7328 ins_encode %{ 7329 __ csel(as_Register($dst$$reg), 7330 as_Register($src$$reg), 7331 zr, 7332 (Assembler::Condition)$cmp$$cmpcode); 7333 %} 7334 7335 ins_pipe(icond_reg); 7336 %} 7337 7338 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 7339 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 7340 7341 ins_cost(INSN_COST * 2); 7342 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 7343 7344 ins_encode %{ 7345 __ cselw(as_Register($dst$$reg), 7346 as_Register($src2$$reg), 7347 as_Register($src1$$reg), 7348 (Assembler::Condition)$cmp$$cmpcode); 7349 %} 7350 7351 ins_pipe(icond_reg_reg); 7352 %} 7353 7354 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 7355 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 7356 7357 ins_cost(INSN_COST * 2); 7358 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 7359 7360 ins_encode %{ 7361 __ cselw(as_Register($dst$$reg), 7362 as_Register($src2$$reg), 7363 as_Register($src1$$reg), 7364 (Assembler::Condition)$cmp$$cmpcode); 7365 %} 7366 7367 ins_pipe(icond_reg_reg); 7368 %} 7369 7370 // special cases where one arg is zero 7371 7372 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 7373 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 7374 7375 ins_cost(INSN_COST * 2); 7376 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 7377 7378 ins_encode %{ 7379 __ cselw(as_Register($dst$$reg), 7380 zr, 7381 as_Register($src$$reg), 7382 (Assembler::Condition)$cmp$$cmpcode); 7383 %} 7384 7385 ins_pipe(icond_reg); 7386 %} 7387 7388 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 7389 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 7390 7391 ins_cost(INSN_COST * 2); 7392 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 7393 7394 ins_encode %{ 7395 __ cselw(as_Register($dst$$reg), 7396 zr, 7397 as_Register($src$$reg), 7398 (Assembler::Condition)$cmp$$cmpcode); 7399 %} 7400 7401 ins_pipe(icond_reg); 7402 %} 7403 7404 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 7405 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 7406 7407 ins_cost(INSN_COST * 2); 7408 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 7409 7410 ins_encode %{ 7411 __ cselw(as_Register($dst$$reg), 7412 as_Register($src$$reg), 7413 zr, 7414 (Assembler::Condition)$cmp$$cmpcode); 7415 %} 7416 7417 ins_pipe(icond_reg); 7418 %} 7419 7420 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 7421 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 7422 7423 ins_cost(INSN_COST * 2); 7424 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 7425 7426 ins_encode %{ 7427 __ cselw(as_Register($dst$$reg), 7428 as_Register($src$$reg), 7429 zr, 7430 (Assembler::Condition)$cmp$$cmpcode); 7431 %} 7432 7433 ins_pipe(icond_reg); 7434 %} 7435 7436 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 7437 %{ 7438 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 7439 7440 ins_cost(INSN_COST * 3); 7441 7442 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 7443 ins_encode %{ 7444 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 7445 __ fcsels(as_FloatRegister($dst$$reg), 7446 as_FloatRegister($src2$$reg), 7447 as_FloatRegister($src1$$reg), 7448 cond); 7449 %} 7450 7451 ins_pipe(pipe_class_default); 7452 %} 7453 7454 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 7455 %{ 7456 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 7457 7458 ins_cost(INSN_COST * 3); 7459 7460 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 7461 ins_encode %{ 7462 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 7463 __ fcsels(as_FloatRegister($dst$$reg), 7464 as_FloatRegister($src2$$reg), 7465 as_FloatRegister($src1$$reg), 7466 cond); 7467 %} 7468 7469 ins_pipe(pipe_class_default); 7470 %} 7471 7472 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 7473 %{ 7474 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 7475 7476 ins_cost(INSN_COST * 3); 7477 7478 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 7479 ins_encode %{ 7480 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 7481 __ fcseld(as_FloatRegister($dst$$reg), 7482 as_FloatRegister($src2$$reg), 7483 as_FloatRegister($src1$$reg), 7484 cond); 7485 %} 7486 7487 ins_pipe(pipe_class_default); 7488 %} 7489 7490 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 7491 %{ 7492 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 7493 7494 ins_cost(INSN_COST * 3); 7495 7496 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 7497 ins_encode %{ 7498 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 7499 __ fcseld(as_FloatRegister($dst$$reg), 7500 as_FloatRegister($src2$$reg), 7501 as_FloatRegister($src1$$reg), 7502 cond); 7503 %} 7504 7505 ins_pipe(pipe_class_default); 7506 %} 7507 7508 // ============================================================================ 7509 // Arithmetic Instructions 7510 // 7511 7512 // Integer Addition 7513 7514 // TODO 7515 // these currently employ operations which do not set CR and hence are 7516 // not flagged as killing CR but we would like to isolate the cases 7517 // where we want to set flags from those where we don't. need to work 7518 // out how to do that. 7519 7520 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7521 match(Set dst (AddI src1 src2)); 7522 7523 ins_cost(INSN_COST); 7524 format %{ "addw $dst, $src1, $src2" %} 7525 7526 ins_encode %{ 7527 __ addw(as_Register($dst$$reg), 7528 as_Register($src1$$reg), 7529 as_Register($src2$$reg)); 7530 %} 7531 7532 ins_pipe(ialu_reg_reg); 7533 %} 7534 7535 instruct addI_reg_imm(iRegINoSp dst, iRegI src1, immIAddSub src2) %{ 7536 match(Set dst (AddI src1 src2)); 7537 7538 ins_cost(INSN_COST); 7539 format %{ "addw $dst, $src1, $src2" %} 7540 7541 // use opcode to indicate that this is an add not a sub 7542 opcode(0x0); 7543 7544 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 7545 7546 ins_pipe(ialu_reg_imm); 7547 %} 7548 7549 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 7550 match(Set dst (AddI (ConvL2I src1) src2)); 7551 7552 ins_cost(INSN_COST); 7553 format %{ "addw $dst, $src1, $src2" %} 7554 7555 // use opcode to indicate that this is an add not a sub 7556 opcode(0x0); 7557 7558 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 7559 7560 ins_pipe(ialu_reg_imm); 7561 %} 7562 7563 // Pointer Addition 7564 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 7565 match(Set dst (AddP src1 src2)); 7566 7567 ins_cost(INSN_COST); 7568 format %{ "add $dst, $src1, $src2\t# ptr" %} 7569 7570 ins_encode %{ 7571 __ add(as_Register($dst$$reg), 7572 as_Register($src1$$reg), 7573 as_Register($src2$$reg)); 7574 %} 7575 7576 ins_pipe(ialu_reg_reg); 7577 %} 7578 7579 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 7580 match(Set dst (AddP src1 (ConvI2L src2))); 7581 7582 ins_cost(INSN_COST); 7583 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 7584 7585 ins_encode %{ 7586 __ add(as_Register($dst$$reg), 7587 as_Register($src1$$reg), 7588 as_Register($src2$$reg), ext::sxtw); 7589 %} 7590 7591 ins_pipe(ialu_reg_reg); 7592 %} 7593 7594 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 7595 match(Set dst (AddP src1 (LShiftL src2 scale))); 7596 7597 ins_cost(1.9 * INSN_COST); 7598 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 7599 7600 ins_encode %{ 7601 __ lea(as_Register($dst$$reg), 7602 Address(as_Register($src1$$reg), as_Register($src2$$reg), 7603 Address::lsl($scale$$constant))); 7604 %} 7605 7606 ins_pipe(ialu_reg_reg_shift); 7607 %} 7608 7609 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 7610 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 7611 7612 ins_cost(1.9 * INSN_COST); 7613 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 7614 7615 ins_encode %{ 7616 __ lea(as_Register($dst$$reg), 7617 Address(as_Register($src1$$reg), as_Register($src2$$reg), 7618 Address::sxtw($scale$$constant))); 7619 %} 7620 7621 ins_pipe(ialu_reg_reg_shift); 7622 %} 7623 7624 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 7625 match(Set dst (LShiftL (ConvI2L src) scale)); 7626 7627 ins_cost(INSN_COST); 7628 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 7629 7630 ins_encode %{ 7631 __ sbfiz(as_Register($dst$$reg), 7632 as_Register($src$$reg), 7633 $scale$$constant & 63, MIN(32, (-$scale$$constant) & 63)); 7634 %} 7635 7636 ins_pipe(ialu_reg_shift); 7637 %} 7638 7639 // Pointer Immediate Addition 7640 // n.b. this needs to be more expensive than using an indirect memory 7641 // operand 7642 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 7643 match(Set dst (AddP src1 src2)); 7644 7645 ins_cost(INSN_COST); 7646 format %{ "add $dst, $src1, $src2\t# ptr" %} 7647 7648 // use opcode to indicate that this is an add not a sub 7649 opcode(0x0); 7650 7651 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 7652 7653 ins_pipe(ialu_reg_imm); 7654 %} 7655 7656 // Long Addition 7657 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7658 7659 match(Set dst (AddL src1 src2)); 7660 7661 ins_cost(INSN_COST); 7662 format %{ "add $dst, $src1, $src2" %} 7663 7664 ins_encode %{ 7665 __ add(as_Register($dst$$reg), 7666 as_Register($src1$$reg), 7667 as_Register($src2$$reg)); 7668 %} 7669 7670 ins_pipe(ialu_reg_reg); 7671 %} 7672 7673 // No constant pool entries requiredLong Immediate Addition. 7674 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 7675 match(Set dst (AddL src1 src2)); 7676 7677 ins_cost(INSN_COST); 7678 format %{ "add $dst, $src1, $src2" %} 7679 7680 // use opcode to indicate that this is an add not a sub 7681 opcode(0x0); 7682 7683 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 7684 7685 ins_pipe(ialu_reg_imm); 7686 %} 7687 7688 // Integer Subtraction 7689 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7690 match(Set dst (SubI src1 src2)); 7691 7692 ins_cost(INSN_COST); 7693 format %{ "subw $dst, $src1, $src2" %} 7694 7695 ins_encode %{ 7696 __ subw(as_Register($dst$$reg), 7697 as_Register($src1$$reg), 7698 as_Register($src2$$reg)); 7699 %} 7700 7701 ins_pipe(ialu_reg_reg); 7702 %} 7703 7704 // Immediate Subtraction 7705 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 7706 match(Set dst (SubI src1 src2)); 7707 7708 ins_cost(INSN_COST); 7709 format %{ "subw $dst, $src1, $src2" %} 7710 7711 // use opcode to indicate that this is a sub not an add 7712 opcode(0x1); 7713 7714 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 7715 7716 ins_pipe(ialu_reg_imm); 7717 %} 7718 7719 // Long Subtraction 7720 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7721 7722 match(Set dst (SubL src1 src2)); 7723 7724 ins_cost(INSN_COST); 7725 format %{ "sub $dst, $src1, $src2" %} 7726 7727 ins_encode %{ 7728 __ sub(as_Register($dst$$reg), 7729 as_Register($src1$$reg), 7730 as_Register($src2$$reg)); 7731 %} 7732 7733 ins_pipe(ialu_reg_reg); 7734 %} 7735 7736 // No constant pool entries requiredLong Immediate Subtraction. 7737 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 7738 match(Set dst (SubL src1 src2)); 7739 7740 ins_cost(INSN_COST); 7741 format %{ "sub$dst, $src1, $src2" %} 7742 7743 // use opcode to indicate that this is a sub not an add 7744 opcode(0x1); 7745 7746 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 7747 7748 ins_pipe(ialu_reg_imm); 7749 %} 7750 7751 // Integer Negation (special case for sub) 7752 7753 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 7754 match(Set dst (SubI zero src)); 7755 7756 ins_cost(INSN_COST); 7757 format %{ "negw $dst, $src\t# int" %} 7758 7759 ins_encode %{ 7760 __ negw(as_Register($dst$$reg), 7761 as_Register($src$$reg)); 7762 %} 7763 7764 ins_pipe(ialu_reg); 7765 %} 7766 7767 // Long Negation 7768 7769 instruct negL_reg(iRegLNoSp dst, iRegIorL2I src, immL0 zero, rFlagsReg cr) %{ 7770 match(Set dst (SubL zero src)); 7771 7772 ins_cost(INSN_COST); 7773 format %{ "neg $dst, $src\t# long" %} 7774 7775 ins_encode %{ 7776 __ neg(as_Register($dst$$reg), 7777 as_Register($src$$reg)); 7778 %} 7779 7780 ins_pipe(ialu_reg); 7781 %} 7782 7783 // Integer Multiply 7784 7785 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7786 match(Set dst (MulI src1 src2)); 7787 7788 ins_cost(INSN_COST * 3); 7789 format %{ "mulw $dst, $src1, $src2" %} 7790 7791 ins_encode %{ 7792 __ mulw(as_Register($dst$$reg), 7793 as_Register($src1$$reg), 7794 as_Register($src2$$reg)); 7795 %} 7796 7797 ins_pipe(imul_reg_reg); 7798 %} 7799 7800 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7801 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 7802 7803 ins_cost(INSN_COST * 3); 7804 format %{ "smull $dst, $src1, $src2" %} 7805 7806 ins_encode %{ 7807 __ smull(as_Register($dst$$reg), 7808 as_Register($src1$$reg), 7809 as_Register($src2$$reg)); 7810 %} 7811 7812 ins_pipe(imul_reg_reg); 7813 %} 7814 7815 // Long Multiply 7816 7817 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7818 match(Set dst (MulL src1 src2)); 7819 7820 ins_cost(INSN_COST * 5); 7821 format %{ "mul $dst, $src1, $src2" %} 7822 7823 ins_encode %{ 7824 __ mul(as_Register($dst$$reg), 7825 as_Register($src1$$reg), 7826 as_Register($src2$$reg)); 7827 %} 7828 7829 ins_pipe(lmul_reg_reg); 7830 %} 7831 7832 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 7833 %{ 7834 match(Set dst (MulHiL src1 src2)); 7835 7836 ins_cost(INSN_COST * 7); 7837 format %{ "smulh $dst, $src1, $src2, \t# mulhi" %} 7838 7839 ins_encode %{ 7840 __ smulh(as_Register($dst$$reg), 7841 as_Register($src1$$reg), 7842 as_Register($src2$$reg)); 7843 %} 7844 7845 ins_pipe(lmul_reg_reg); 7846 %} 7847 7848 // Combined Integer Multiply & Add/Sub 7849 7850 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 7851 match(Set dst (AddI src3 (MulI src1 src2))); 7852 7853 ins_cost(INSN_COST * 3); 7854 format %{ "madd $dst, $src1, $src2, $src3" %} 7855 7856 ins_encode %{ 7857 __ maddw(as_Register($dst$$reg), 7858 as_Register($src1$$reg), 7859 as_Register($src2$$reg), 7860 as_Register($src3$$reg)); 7861 %} 7862 7863 ins_pipe(imac_reg_reg); 7864 %} 7865 7866 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 7867 match(Set dst (SubI src3 (MulI src1 src2))); 7868 7869 ins_cost(INSN_COST * 3); 7870 format %{ "msub $dst, $src1, $src2, $src3" %} 7871 7872 ins_encode %{ 7873 __ msubw(as_Register($dst$$reg), 7874 as_Register($src1$$reg), 7875 as_Register($src2$$reg), 7876 as_Register($src3$$reg)); 7877 %} 7878 7879 ins_pipe(imac_reg_reg); 7880 %} 7881 7882 // Combined Long Multiply & Add/Sub 7883 7884 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 7885 match(Set dst (AddL src3 (MulL src1 src2))); 7886 7887 ins_cost(INSN_COST * 5); 7888 format %{ "madd $dst, $src1, $src2, $src3" %} 7889 7890 ins_encode %{ 7891 __ madd(as_Register($dst$$reg), 7892 as_Register($src1$$reg), 7893 as_Register($src2$$reg), 7894 as_Register($src3$$reg)); 7895 %} 7896 7897 ins_pipe(lmac_reg_reg); 7898 %} 7899 7900 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 7901 match(Set dst (SubL src3 (MulL src1 src2))); 7902 7903 ins_cost(INSN_COST * 5); 7904 format %{ "msub $dst, $src1, $src2, $src3" %} 7905 7906 ins_encode %{ 7907 __ msub(as_Register($dst$$reg), 7908 as_Register($src1$$reg), 7909 as_Register($src2$$reg), 7910 as_Register($src3$$reg)); 7911 %} 7912 7913 ins_pipe(lmac_reg_reg); 7914 %} 7915 7916 // Integer Divide 7917 7918 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7919 match(Set dst (DivI src1 src2)); 7920 7921 ins_cost(INSN_COST * 19); 7922 format %{ "sdivw $dst, $src1, $src2" %} 7923 7924 ins_encode(aarch64_enc_divw(dst, src1, src2)); 7925 ins_pipe(idiv_reg_reg); 7926 %} 7927 7928 instruct signExtract(iRegINoSp dst, iRegI src1, immI_31 div1, immI_31 div2) %{ 7929 match(Set dst (URShiftI (RShiftI src1 div1) div2)); 7930 ins_cost(INSN_COST); 7931 format %{ "lsrw $dst, $src1, $div1" %} 7932 ins_encode %{ 7933 __ lsrw(as_Register($dst$$reg), as_Register($src1$$reg), 31); 7934 %} 7935 ins_pipe(ialu_reg_shift); 7936 %} 7937 7938 instruct div2Round(iRegINoSp dst, iRegI src, immI_31 div1, immI_31 div2) %{ 7939 match(Set dst (AddI src (URShiftI (RShiftI src div1) div2))); 7940 ins_cost(INSN_COST); 7941 format %{ "addw $dst, $src, LSR $div1" %} 7942 7943 ins_encode %{ 7944 __ addw(as_Register($dst$$reg), 7945 as_Register($src$$reg), 7946 as_Register($src$$reg), 7947 Assembler::LSR, 31); 7948 %} 7949 ins_pipe(ialu_reg); 7950 %} 7951 7952 // Long Divide 7953 7954 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 7955 match(Set dst (DivL src1 src2)); 7956 7957 ins_cost(INSN_COST * 35); 7958 format %{ "sdiv $dst, $src1, $src2" %} 7959 7960 ins_encode(aarch64_enc_div(dst, src1, src2)); 7961 ins_pipe(ldiv_reg_reg); 7962 %} 7963 7964 instruct signExtractL(iRegLNoSp dst, iRegL src1, immL_63 div1, immL_63 div2) %{ 7965 match(Set dst (URShiftL (RShiftL src1 div1) div2)); 7966 ins_cost(INSN_COST); 7967 format %{ "lsr $dst, $src1, $div1" %} 7968 ins_encode %{ 7969 __ lsr(as_Register($dst$$reg), as_Register($src1$$reg), 63); 7970 %} 7971 ins_pipe(ialu_reg_shift); 7972 %} 7973 7974 instruct div2RoundL(iRegLNoSp dst, iRegL src, immL_63 div1, immL_63 div2) %{ 7975 match(Set dst (AddL src (URShiftL (RShiftL src div1) div2))); 7976 ins_cost(INSN_COST); 7977 format %{ "add $dst, $src, $div1" %} 7978 7979 ins_encode %{ 7980 __ add(as_Register($dst$$reg), 7981 as_Register($src$$reg), 7982 as_Register($src$$reg), 7983 Assembler::LSR, 63); 7984 %} 7985 ins_pipe(ialu_reg); 7986 %} 7987 7988 // Integer Remainder 7989 7990 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 7991 match(Set dst (ModI src1 src2)); 7992 7993 ins_cost(INSN_COST * 22); 7994 format %{ "sdivw rscratch1, $src1, $src2\n\t" 7995 "msubw($dst, rscratch1, $src2, $src1" %} 7996 7997 ins_encode(aarch64_enc_modw(dst, src1, src2)); 7998 ins_pipe(idiv_reg_reg); 7999 %} 8000 8001 // Long Remainder 8002 8003 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 8004 match(Set dst (ModL src1 src2)); 8005 8006 ins_cost(INSN_COST * 38); 8007 format %{ "sdiv rscratch1, $src1, $src2\n" 8008 "msub($dst, rscratch1, $src2, $src1" %} 8009 8010 ins_encode(aarch64_enc_mod(dst, src1, src2)); 8011 ins_pipe(ldiv_reg_reg); 8012 %} 8013 8014 // Integer Shifts 8015 8016 // Shift Left Register 8017 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8018 match(Set dst (LShiftI src1 src2)); 8019 8020 ins_cost(INSN_COST * 2); 8021 format %{ "lslvw $dst, $src1, $src2" %} 8022 8023 ins_encode %{ 8024 __ lslvw(as_Register($dst$$reg), 8025 as_Register($src1$$reg), 8026 as_Register($src2$$reg)); 8027 %} 8028 8029 ins_pipe(ialu_reg_reg_vshift); 8030 %} 8031 8032 // Shift Left Immediate 8033 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8034 match(Set dst (LShiftI src1 src2)); 8035 8036 ins_cost(INSN_COST); 8037 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 8038 8039 ins_encode %{ 8040 __ lslw(as_Register($dst$$reg), 8041 as_Register($src1$$reg), 8042 $src2$$constant & 0x1f); 8043 %} 8044 8045 ins_pipe(ialu_reg_shift); 8046 %} 8047 8048 // Shift Right Logical Register 8049 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8050 match(Set dst (URShiftI src1 src2)); 8051 8052 ins_cost(INSN_COST * 2); 8053 format %{ "lsrvw $dst, $src1, $src2" %} 8054 8055 ins_encode %{ 8056 __ lsrvw(as_Register($dst$$reg), 8057 as_Register($src1$$reg), 8058 as_Register($src2$$reg)); 8059 %} 8060 8061 ins_pipe(ialu_reg_reg_vshift); 8062 %} 8063 8064 // Shift Right Logical Immediate 8065 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8066 match(Set dst (URShiftI src1 src2)); 8067 8068 ins_cost(INSN_COST); 8069 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 8070 8071 ins_encode %{ 8072 __ lsrw(as_Register($dst$$reg), 8073 as_Register($src1$$reg), 8074 $src2$$constant & 0x1f); 8075 %} 8076 8077 ins_pipe(ialu_reg_shift); 8078 %} 8079 8080 // Shift Right Arithmetic Register 8081 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 8082 match(Set dst (RShiftI src1 src2)); 8083 8084 ins_cost(INSN_COST * 2); 8085 format %{ "asrvw $dst, $src1, $src2" %} 8086 8087 ins_encode %{ 8088 __ asrvw(as_Register($dst$$reg), 8089 as_Register($src1$$reg), 8090 as_Register($src2$$reg)); 8091 %} 8092 8093 ins_pipe(ialu_reg_reg_vshift); 8094 %} 8095 8096 // Shift Right Arithmetic Immediate 8097 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 8098 match(Set dst (RShiftI src1 src2)); 8099 8100 ins_cost(INSN_COST); 8101 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 8102 8103 ins_encode %{ 8104 __ asrw(as_Register($dst$$reg), 8105 as_Register($src1$$reg), 8106 $src2$$constant & 0x1f); 8107 %} 8108 8109 ins_pipe(ialu_reg_shift); 8110 %} 8111 8112 // Combined Int Mask and Right Shift (using UBFM) 8113 // TODO 8114 8115 // Long Shifts 8116 8117 // Shift Left Register 8118 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 8119 match(Set dst (LShiftL src1 src2)); 8120 8121 ins_cost(INSN_COST * 2); 8122 format %{ "lslv $dst, $src1, $src2" %} 8123 8124 ins_encode %{ 8125 __ lslv(as_Register($dst$$reg), 8126 as_Register($src1$$reg), 8127 as_Register($src2$$reg)); 8128 %} 8129 8130 ins_pipe(ialu_reg_reg_vshift); 8131 %} 8132 8133 // Shift Left Immediate 8134 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 8135 match(Set dst (LShiftL src1 src2)); 8136 8137 ins_cost(INSN_COST); 8138 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 8139 8140 ins_encode %{ 8141 __ lsl(as_Register($dst$$reg), 8142 as_Register($src1$$reg), 8143 $src2$$constant & 0x3f); 8144 %} 8145 8146 ins_pipe(ialu_reg_shift); 8147 %} 8148 8149 // Shift Right Logical Register 8150 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 8151 match(Set dst (URShiftL src1 src2)); 8152 8153 ins_cost(INSN_COST * 2); 8154 format %{ "lsrv $dst, $src1, $src2" %} 8155 8156 ins_encode %{ 8157 __ lsrv(as_Register($dst$$reg), 8158 as_Register($src1$$reg), 8159 as_Register($src2$$reg)); 8160 %} 8161 8162 ins_pipe(ialu_reg_reg_vshift); 8163 %} 8164 8165 // Shift Right Logical Immediate 8166 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 8167 match(Set dst (URShiftL src1 src2)); 8168 8169 ins_cost(INSN_COST); 8170 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 8171 8172 ins_encode %{ 8173 __ lsr(as_Register($dst$$reg), 8174 as_Register($src1$$reg), 8175 $src2$$constant & 0x3f); 8176 %} 8177 8178 ins_pipe(ialu_reg_shift); 8179 %} 8180 8181 // A special-case pattern for card table stores. 8182 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 8183 match(Set dst (URShiftL (CastP2X src1) src2)); 8184 8185 ins_cost(INSN_COST); 8186 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 8187 8188 ins_encode %{ 8189 __ lsr(as_Register($dst$$reg), 8190 as_Register($src1$$reg), 8191 $src2$$constant & 0x3f); 8192 %} 8193 8194 ins_pipe(ialu_reg_shift); 8195 %} 8196 8197 // Shift Right Arithmetic Register 8198 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 8199 match(Set dst (RShiftL src1 src2)); 8200 8201 ins_cost(INSN_COST * 2); 8202 format %{ "asrv $dst, $src1, $src2" %} 8203 8204 ins_encode %{ 8205 __ asrv(as_Register($dst$$reg), 8206 as_Register($src1$$reg), 8207 as_Register($src2$$reg)); 8208 %} 8209 8210 ins_pipe(ialu_reg_reg_vshift); 8211 %} 8212 8213 // Shift Right Arithmetic Immediate 8214 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 8215 match(Set dst (RShiftL src1 src2)); 8216 8217 ins_cost(INSN_COST); 8218 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 8219 8220 ins_encode %{ 8221 __ asr(as_Register($dst$$reg), 8222 as_Register($src1$$reg), 8223 $src2$$constant & 0x3f); 8224 %} 8225 8226 ins_pipe(ialu_reg_shift); 8227 %} 8228 8229 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8230 8231 instruct regL_not_reg(iRegLNoSp dst, 8232 iRegL src1, immL_M1 m1, 8233 rFlagsReg cr) %{ 8234 match(Set dst (XorL src1 m1)); 8235 ins_cost(INSN_COST); 8236 format %{ "eon $dst, $src1, zr" %} 8237 8238 ins_encode %{ 8239 __ eon(as_Register($dst$$reg), 8240 as_Register($src1$$reg), 8241 zr, 8242 Assembler::LSL, 0); 8243 %} 8244 8245 ins_pipe(ialu_reg); 8246 %} 8247 instruct regI_not_reg(iRegINoSp dst, 8248 iRegI src1, immI_M1 m1, 8249 rFlagsReg cr) %{ 8250 match(Set dst (XorI src1 m1)); 8251 ins_cost(INSN_COST); 8252 format %{ "eonw $dst, $src1, zr" %} 8253 8254 ins_encode %{ 8255 __ eonw(as_Register($dst$$reg), 8256 as_Register($src1$$reg), 8257 zr, 8258 Assembler::LSL, 0); 8259 %} 8260 8261 ins_pipe(ialu_reg); 8262 %} 8263 8264 instruct AndI_reg_not_reg(iRegINoSp dst, 8265 iRegI src1, iRegI src2, immI_M1 m1, 8266 rFlagsReg cr) %{ 8267 match(Set dst (AndI src1 (XorI src2 m1))); 8268 ins_cost(INSN_COST); 8269 format %{ "bic $dst, $src1, $src2" %} 8270 8271 ins_encode %{ 8272 __ bic(as_Register($dst$$reg), 8273 as_Register($src1$$reg), 8274 as_Register($src2$$reg), 8275 Assembler::LSL, 0); 8276 %} 8277 8278 ins_pipe(ialu_reg_reg); 8279 %} 8280 8281 instruct AndL_reg_not_reg(iRegLNoSp dst, 8282 iRegL src1, iRegL src2, immL_M1 m1, 8283 rFlagsReg cr) %{ 8284 match(Set dst (AndL src1 (XorL src2 m1))); 8285 ins_cost(INSN_COST); 8286 format %{ "bic $dst, $src1, $src2" %} 8287 8288 ins_encode %{ 8289 __ bic(as_Register($dst$$reg), 8290 as_Register($src1$$reg), 8291 as_Register($src2$$reg), 8292 Assembler::LSL, 0); 8293 %} 8294 8295 ins_pipe(ialu_reg_reg); 8296 %} 8297 8298 instruct OrI_reg_not_reg(iRegINoSp dst, 8299 iRegI src1, iRegI src2, immI_M1 m1, 8300 rFlagsReg cr) %{ 8301 match(Set dst (OrI src1 (XorI src2 m1))); 8302 ins_cost(INSN_COST); 8303 format %{ "orn $dst, $src1, $src2" %} 8304 8305 ins_encode %{ 8306 __ orn(as_Register($dst$$reg), 8307 as_Register($src1$$reg), 8308 as_Register($src2$$reg), 8309 Assembler::LSL, 0); 8310 %} 8311 8312 ins_pipe(ialu_reg_reg); 8313 %} 8314 8315 instruct OrL_reg_not_reg(iRegLNoSp dst, 8316 iRegL src1, iRegL src2, immL_M1 m1, 8317 rFlagsReg cr) %{ 8318 match(Set dst (OrL src1 (XorL src2 m1))); 8319 ins_cost(INSN_COST); 8320 format %{ "orn $dst, $src1, $src2" %} 8321 8322 ins_encode %{ 8323 __ orn(as_Register($dst$$reg), 8324 as_Register($src1$$reg), 8325 as_Register($src2$$reg), 8326 Assembler::LSL, 0); 8327 %} 8328 8329 ins_pipe(ialu_reg_reg); 8330 %} 8331 8332 instruct XorI_reg_not_reg(iRegINoSp dst, 8333 iRegI src1, iRegI src2, immI_M1 m1, 8334 rFlagsReg cr) %{ 8335 match(Set dst (XorI m1 (XorI src2 src1))); 8336 ins_cost(INSN_COST); 8337 format %{ "eon $dst, $src1, $src2" %} 8338 8339 ins_encode %{ 8340 __ eon(as_Register($dst$$reg), 8341 as_Register($src1$$reg), 8342 as_Register($src2$$reg), 8343 Assembler::LSL, 0); 8344 %} 8345 8346 ins_pipe(ialu_reg_reg); 8347 %} 8348 8349 instruct XorL_reg_not_reg(iRegLNoSp dst, 8350 iRegL src1, iRegL src2, immL_M1 m1, 8351 rFlagsReg cr) %{ 8352 match(Set dst (XorL m1 (XorL src2 src1))); 8353 ins_cost(INSN_COST); 8354 format %{ "eon $dst, $src1, $src2" %} 8355 8356 ins_encode %{ 8357 __ eon(as_Register($dst$$reg), 8358 as_Register($src1$$reg), 8359 as_Register($src2$$reg), 8360 Assembler::LSL, 0); 8361 %} 8362 8363 ins_pipe(ialu_reg_reg); 8364 %} 8365 8366 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 8367 iRegI src1, iRegI src2, 8368 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8369 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 8370 ins_cost(1.9 * INSN_COST); 8371 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 8372 8373 ins_encode %{ 8374 __ bicw(as_Register($dst$$reg), 8375 as_Register($src1$$reg), 8376 as_Register($src2$$reg), 8377 Assembler::LSR, 8378 $src3$$constant & 0x3f); 8379 %} 8380 8381 ins_pipe(ialu_reg_reg_shift); 8382 %} 8383 8384 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 8385 iRegL src1, iRegL src2, 8386 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8387 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 8388 ins_cost(1.9 * INSN_COST); 8389 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 8390 8391 ins_encode %{ 8392 __ bic(as_Register($dst$$reg), 8393 as_Register($src1$$reg), 8394 as_Register($src2$$reg), 8395 Assembler::LSR, 8396 $src3$$constant & 0x3f); 8397 %} 8398 8399 ins_pipe(ialu_reg_reg_shift); 8400 %} 8401 8402 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 8403 iRegI src1, iRegI src2, 8404 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8405 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 8406 ins_cost(1.9 * INSN_COST); 8407 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 8408 8409 ins_encode %{ 8410 __ bicw(as_Register($dst$$reg), 8411 as_Register($src1$$reg), 8412 as_Register($src2$$reg), 8413 Assembler::ASR, 8414 $src3$$constant & 0x3f); 8415 %} 8416 8417 ins_pipe(ialu_reg_reg_shift); 8418 %} 8419 8420 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 8421 iRegL src1, iRegL src2, 8422 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8423 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 8424 ins_cost(1.9 * INSN_COST); 8425 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 8426 8427 ins_encode %{ 8428 __ bic(as_Register($dst$$reg), 8429 as_Register($src1$$reg), 8430 as_Register($src2$$reg), 8431 Assembler::ASR, 8432 $src3$$constant & 0x3f); 8433 %} 8434 8435 ins_pipe(ialu_reg_reg_shift); 8436 %} 8437 8438 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 8439 iRegI src1, iRegI src2, 8440 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8441 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 8442 ins_cost(1.9 * INSN_COST); 8443 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 8444 8445 ins_encode %{ 8446 __ bicw(as_Register($dst$$reg), 8447 as_Register($src1$$reg), 8448 as_Register($src2$$reg), 8449 Assembler::LSL, 8450 $src3$$constant & 0x3f); 8451 %} 8452 8453 ins_pipe(ialu_reg_reg_shift); 8454 %} 8455 8456 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 8457 iRegL src1, iRegL src2, 8458 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8459 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 8460 ins_cost(1.9 * INSN_COST); 8461 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 8462 8463 ins_encode %{ 8464 __ bic(as_Register($dst$$reg), 8465 as_Register($src1$$reg), 8466 as_Register($src2$$reg), 8467 Assembler::LSL, 8468 $src3$$constant & 0x3f); 8469 %} 8470 8471 ins_pipe(ialu_reg_reg_shift); 8472 %} 8473 8474 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 8475 iRegI src1, iRegI src2, 8476 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8477 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 8478 ins_cost(1.9 * INSN_COST); 8479 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 8480 8481 ins_encode %{ 8482 __ eonw(as_Register($dst$$reg), 8483 as_Register($src1$$reg), 8484 as_Register($src2$$reg), 8485 Assembler::LSR, 8486 $src3$$constant & 0x3f); 8487 %} 8488 8489 ins_pipe(ialu_reg_reg_shift); 8490 %} 8491 8492 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 8493 iRegL src1, iRegL src2, 8494 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8495 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 8496 ins_cost(1.9 * INSN_COST); 8497 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 8498 8499 ins_encode %{ 8500 __ eon(as_Register($dst$$reg), 8501 as_Register($src1$$reg), 8502 as_Register($src2$$reg), 8503 Assembler::LSR, 8504 $src3$$constant & 0x3f); 8505 %} 8506 8507 ins_pipe(ialu_reg_reg_shift); 8508 %} 8509 8510 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 8511 iRegI src1, iRegI src2, 8512 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8513 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 8514 ins_cost(1.9 * INSN_COST); 8515 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 8516 8517 ins_encode %{ 8518 __ eonw(as_Register($dst$$reg), 8519 as_Register($src1$$reg), 8520 as_Register($src2$$reg), 8521 Assembler::ASR, 8522 $src3$$constant & 0x3f); 8523 %} 8524 8525 ins_pipe(ialu_reg_reg_shift); 8526 %} 8527 8528 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 8529 iRegL src1, iRegL src2, 8530 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8531 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 8532 ins_cost(1.9 * INSN_COST); 8533 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 8534 8535 ins_encode %{ 8536 __ eon(as_Register($dst$$reg), 8537 as_Register($src1$$reg), 8538 as_Register($src2$$reg), 8539 Assembler::ASR, 8540 $src3$$constant & 0x3f); 8541 %} 8542 8543 ins_pipe(ialu_reg_reg_shift); 8544 %} 8545 8546 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 8547 iRegI src1, iRegI src2, 8548 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8549 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 8550 ins_cost(1.9 * INSN_COST); 8551 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 8552 8553 ins_encode %{ 8554 __ eonw(as_Register($dst$$reg), 8555 as_Register($src1$$reg), 8556 as_Register($src2$$reg), 8557 Assembler::LSL, 8558 $src3$$constant & 0x3f); 8559 %} 8560 8561 ins_pipe(ialu_reg_reg_shift); 8562 %} 8563 8564 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 8565 iRegL src1, iRegL src2, 8566 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8567 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 8568 ins_cost(1.9 * INSN_COST); 8569 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 8570 8571 ins_encode %{ 8572 __ eon(as_Register($dst$$reg), 8573 as_Register($src1$$reg), 8574 as_Register($src2$$reg), 8575 Assembler::LSL, 8576 $src3$$constant & 0x3f); 8577 %} 8578 8579 ins_pipe(ialu_reg_reg_shift); 8580 %} 8581 8582 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 8583 iRegI src1, iRegI src2, 8584 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8585 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 8586 ins_cost(1.9 * INSN_COST); 8587 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 8588 8589 ins_encode %{ 8590 __ ornw(as_Register($dst$$reg), 8591 as_Register($src1$$reg), 8592 as_Register($src2$$reg), 8593 Assembler::LSR, 8594 $src3$$constant & 0x3f); 8595 %} 8596 8597 ins_pipe(ialu_reg_reg_shift); 8598 %} 8599 8600 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 8601 iRegL src1, iRegL src2, 8602 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8603 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 8604 ins_cost(1.9 * INSN_COST); 8605 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 8606 8607 ins_encode %{ 8608 __ orn(as_Register($dst$$reg), 8609 as_Register($src1$$reg), 8610 as_Register($src2$$reg), 8611 Assembler::LSR, 8612 $src3$$constant & 0x3f); 8613 %} 8614 8615 ins_pipe(ialu_reg_reg_shift); 8616 %} 8617 8618 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 8619 iRegI src1, iRegI src2, 8620 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8621 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 8622 ins_cost(1.9 * INSN_COST); 8623 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 8624 8625 ins_encode %{ 8626 __ ornw(as_Register($dst$$reg), 8627 as_Register($src1$$reg), 8628 as_Register($src2$$reg), 8629 Assembler::ASR, 8630 $src3$$constant & 0x3f); 8631 %} 8632 8633 ins_pipe(ialu_reg_reg_shift); 8634 %} 8635 8636 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 8637 iRegL src1, iRegL src2, 8638 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8639 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 8640 ins_cost(1.9 * INSN_COST); 8641 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 8642 8643 ins_encode %{ 8644 __ orn(as_Register($dst$$reg), 8645 as_Register($src1$$reg), 8646 as_Register($src2$$reg), 8647 Assembler::ASR, 8648 $src3$$constant & 0x3f); 8649 %} 8650 8651 ins_pipe(ialu_reg_reg_shift); 8652 %} 8653 8654 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 8655 iRegI src1, iRegI src2, 8656 immI src3, immI_M1 src4, rFlagsReg cr) %{ 8657 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 8658 ins_cost(1.9 * INSN_COST); 8659 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 8660 8661 ins_encode %{ 8662 __ ornw(as_Register($dst$$reg), 8663 as_Register($src1$$reg), 8664 as_Register($src2$$reg), 8665 Assembler::LSL, 8666 $src3$$constant & 0x3f); 8667 %} 8668 8669 ins_pipe(ialu_reg_reg_shift); 8670 %} 8671 8672 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 8673 iRegL src1, iRegL src2, 8674 immI src3, immL_M1 src4, rFlagsReg cr) %{ 8675 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 8676 ins_cost(1.9 * INSN_COST); 8677 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 8678 8679 ins_encode %{ 8680 __ orn(as_Register($dst$$reg), 8681 as_Register($src1$$reg), 8682 as_Register($src2$$reg), 8683 Assembler::LSL, 8684 $src3$$constant & 0x3f); 8685 %} 8686 8687 ins_pipe(ialu_reg_reg_shift); 8688 %} 8689 8690 instruct AndI_reg_URShift_reg(iRegINoSp dst, 8691 iRegI src1, iRegI src2, 8692 immI src3, rFlagsReg cr) %{ 8693 match(Set dst (AndI src1 (URShiftI src2 src3))); 8694 8695 ins_cost(1.9 * INSN_COST); 8696 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 8697 8698 ins_encode %{ 8699 __ andw(as_Register($dst$$reg), 8700 as_Register($src1$$reg), 8701 as_Register($src2$$reg), 8702 Assembler::LSR, 8703 $src3$$constant & 0x3f); 8704 %} 8705 8706 ins_pipe(ialu_reg_reg_shift); 8707 %} 8708 8709 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 8710 iRegL src1, iRegL src2, 8711 immI src3, rFlagsReg cr) %{ 8712 match(Set dst (AndL src1 (URShiftL src2 src3))); 8713 8714 ins_cost(1.9 * INSN_COST); 8715 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 8716 8717 ins_encode %{ 8718 __ andr(as_Register($dst$$reg), 8719 as_Register($src1$$reg), 8720 as_Register($src2$$reg), 8721 Assembler::LSR, 8722 $src3$$constant & 0x3f); 8723 %} 8724 8725 ins_pipe(ialu_reg_reg_shift); 8726 %} 8727 8728 instruct AndI_reg_RShift_reg(iRegINoSp dst, 8729 iRegI src1, iRegI src2, 8730 immI src3, rFlagsReg cr) %{ 8731 match(Set dst (AndI src1 (RShiftI src2 src3))); 8732 8733 ins_cost(1.9 * INSN_COST); 8734 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 8735 8736 ins_encode %{ 8737 __ andw(as_Register($dst$$reg), 8738 as_Register($src1$$reg), 8739 as_Register($src2$$reg), 8740 Assembler::ASR, 8741 $src3$$constant & 0x3f); 8742 %} 8743 8744 ins_pipe(ialu_reg_reg_shift); 8745 %} 8746 8747 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 8748 iRegL src1, iRegL src2, 8749 immI src3, rFlagsReg cr) %{ 8750 match(Set dst (AndL src1 (RShiftL src2 src3))); 8751 8752 ins_cost(1.9 * INSN_COST); 8753 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 8754 8755 ins_encode %{ 8756 __ andr(as_Register($dst$$reg), 8757 as_Register($src1$$reg), 8758 as_Register($src2$$reg), 8759 Assembler::ASR, 8760 $src3$$constant & 0x3f); 8761 %} 8762 8763 ins_pipe(ialu_reg_reg_shift); 8764 %} 8765 8766 instruct AndI_reg_LShift_reg(iRegINoSp dst, 8767 iRegI src1, iRegI src2, 8768 immI src3, rFlagsReg cr) %{ 8769 match(Set dst (AndI src1 (LShiftI src2 src3))); 8770 8771 ins_cost(1.9 * INSN_COST); 8772 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 8773 8774 ins_encode %{ 8775 __ andw(as_Register($dst$$reg), 8776 as_Register($src1$$reg), 8777 as_Register($src2$$reg), 8778 Assembler::LSL, 8779 $src3$$constant & 0x3f); 8780 %} 8781 8782 ins_pipe(ialu_reg_reg_shift); 8783 %} 8784 8785 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 8786 iRegL src1, iRegL src2, 8787 immI src3, rFlagsReg cr) %{ 8788 match(Set dst (AndL src1 (LShiftL src2 src3))); 8789 8790 ins_cost(1.9 * INSN_COST); 8791 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 8792 8793 ins_encode %{ 8794 __ andr(as_Register($dst$$reg), 8795 as_Register($src1$$reg), 8796 as_Register($src2$$reg), 8797 Assembler::LSL, 8798 $src3$$constant & 0x3f); 8799 %} 8800 8801 ins_pipe(ialu_reg_reg_shift); 8802 %} 8803 8804 instruct XorI_reg_URShift_reg(iRegINoSp dst, 8805 iRegI src1, iRegI src2, 8806 immI src3, rFlagsReg cr) %{ 8807 match(Set dst (XorI src1 (URShiftI src2 src3))); 8808 8809 ins_cost(1.9 * INSN_COST); 8810 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 8811 8812 ins_encode %{ 8813 __ eorw(as_Register($dst$$reg), 8814 as_Register($src1$$reg), 8815 as_Register($src2$$reg), 8816 Assembler::LSR, 8817 $src3$$constant & 0x3f); 8818 %} 8819 8820 ins_pipe(ialu_reg_reg_shift); 8821 %} 8822 8823 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 8824 iRegL src1, iRegL src2, 8825 immI src3, rFlagsReg cr) %{ 8826 match(Set dst (XorL src1 (URShiftL src2 src3))); 8827 8828 ins_cost(1.9 * INSN_COST); 8829 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 8830 8831 ins_encode %{ 8832 __ eor(as_Register($dst$$reg), 8833 as_Register($src1$$reg), 8834 as_Register($src2$$reg), 8835 Assembler::LSR, 8836 $src3$$constant & 0x3f); 8837 %} 8838 8839 ins_pipe(ialu_reg_reg_shift); 8840 %} 8841 8842 instruct XorI_reg_RShift_reg(iRegINoSp dst, 8843 iRegI src1, iRegI src2, 8844 immI src3, rFlagsReg cr) %{ 8845 match(Set dst (XorI src1 (RShiftI src2 src3))); 8846 8847 ins_cost(1.9 * INSN_COST); 8848 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 8849 8850 ins_encode %{ 8851 __ eorw(as_Register($dst$$reg), 8852 as_Register($src1$$reg), 8853 as_Register($src2$$reg), 8854 Assembler::ASR, 8855 $src3$$constant & 0x3f); 8856 %} 8857 8858 ins_pipe(ialu_reg_reg_shift); 8859 %} 8860 8861 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 8862 iRegL src1, iRegL src2, 8863 immI src3, rFlagsReg cr) %{ 8864 match(Set dst (XorL src1 (RShiftL src2 src3))); 8865 8866 ins_cost(1.9 * INSN_COST); 8867 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 8868 8869 ins_encode %{ 8870 __ eor(as_Register($dst$$reg), 8871 as_Register($src1$$reg), 8872 as_Register($src2$$reg), 8873 Assembler::ASR, 8874 $src3$$constant & 0x3f); 8875 %} 8876 8877 ins_pipe(ialu_reg_reg_shift); 8878 %} 8879 8880 instruct XorI_reg_LShift_reg(iRegINoSp dst, 8881 iRegI src1, iRegI src2, 8882 immI src3, rFlagsReg cr) %{ 8883 match(Set dst (XorI src1 (LShiftI src2 src3))); 8884 8885 ins_cost(1.9 * INSN_COST); 8886 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 8887 8888 ins_encode %{ 8889 __ eorw(as_Register($dst$$reg), 8890 as_Register($src1$$reg), 8891 as_Register($src2$$reg), 8892 Assembler::LSL, 8893 $src3$$constant & 0x3f); 8894 %} 8895 8896 ins_pipe(ialu_reg_reg_shift); 8897 %} 8898 8899 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 8900 iRegL src1, iRegL src2, 8901 immI src3, rFlagsReg cr) %{ 8902 match(Set dst (XorL src1 (LShiftL src2 src3))); 8903 8904 ins_cost(1.9 * INSN_COST); 8905 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 8906 8907 ins_encode %{ 8908 __ eor(as_Register($dst$$reg), 8909 as_Register($src1$$reg), 8910 as_Register($src2$$reg), 8911 Assembler::LSL, 8912 $src3$$constant & 0x3f); 8913 %} 8914 8915 ins_pipe(ialu_reg_reg_shift); 8916 %} 8917 8918 instruct OrI_reg_URShift_reg(iRegINoSp dst, 8919 iRegI src1, iRegI src2, 8920 immI src3, rFlagsReg cr) %{ 8921 match(Set dst (OrI src1 (URShiftI src2 src3))); 8922 8923 ins_cost(1.9 * INSN_COST); 8924 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 8925 8926 ins_encode %{ 8927 __ orrw(as_Register($dst$$reg), 8928 as_Register($src1$$reg), 8929 as_Register($src2$$reg), 8930 Assembler::LSR, 8931 $src3$$constant & 0x3f); 8932 %} 8933 8934 ins_pipe(ialu_reg_reg_shift); 8935 %} 8936 8937 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 8938 iRegL src1, iRegL src2, 8939 immI src3, rFlagsReg cr) %{ 8940 match(Set dst (OrL src1 (URShiftL src2 src3))); 8941 8942 ins_cost(1.9 * INSN_COST); 8943 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 8944 8945 ins_encode %{ 8946 __ orr(as_Register($dst$$reg), 8947 as_Register($src1$$reg), 8948 as_Register($src2$$reg), 8949 Assembler::LSR, 8950 $src3$$constant & 0x3f); 8951 %} 8952 8953 ins_pipe(ialu_reg_reg_shift); 8954 %} 8955 8956 instruct OrI_reg_RShift_reg(iRegINoSp dst, 8957 iRegI src1, iRegI src2, 8958 immI src3, rFlagsReg cr) %{ 8959 match(Set dst (OrI src1 (RShiftI src2 src3))); 8960 8961 ins_cost(1.9 * INSN_COST); 8962 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 8963 8964 ins_encode %{ 8965 __ orrw(as_Register($dst$$reg), 8966 as_Register($src1$$reg), 8967 as_Register($src2$$reg), 8968 Assembler::ASR, 8969 $src3$$constant & 0x3f); 8970 %} 8971 8972 ins_pipe(ialu_reg_reg_shift); 8973 %} 8974 8975 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 8976 iRegL src1, iRegL src2, 8977 immI src3, rFlagsReg cr) %{ 8978 match(Set dst (OrL src1 (RShiftL src2 src3))); 8979 8980 ins_cost(1.9 * INSN_COST); 8981 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 8982 8983 ins_encode %{ 8984 __ orr(as_Register($dst$$reg), 8985 as_Register($src1$$reg), 8986 as_Register($src2$$reg), 8987 Assembler::ASR, 8988 $src3$$constant & 0x3f); 8989 %} 8990 8991 ins_pipe(ialu_reg_reg_shift); 8992 %} 8993 8994 instruct OrI_reg_LShift_reg(iRegINoSp dst, 8995 iRegI src1, iRegI src2, 8996 immI src3, rFlagsReg cr) %{ 8997 match(Set dst (OrI src1 (LShiftI src2 src3))); 8998 8999 ins_cost(1.9 * INSN_COST); 9000 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 9001 9002 ins_encode %{ 9003 __ orrw(as_Register($dst$$reg), 9004 as_Register($src1$$reg), 9005 as_Register($src2$$reg), 9006 Assembler::LSL, 9007 $src3$$constant & 0x3f); 9008 %} 9009 9010 ins_pipe(ialu_reg_reg_shift); 9011 %} 9012 9013 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 9014 iRegL src1, iRegL src2, 9015 immI src3, rFlagsReg cr) %{ 9016 match(Set dst (OrL src1 (LShiftL src2 src3))); 9017 9018 ins_cost(1.9 * INSN_COST); 9019 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 9020 9021 ins_encode %{ 9022 __ orr(as_Register($dst$$reg), 9023 as_Register($src1$$reg), 9024 as_Register($src2$$reg), 9025 Assembler::LSL, 9026 $src3$$constant & 0x3f); 9027 %} 9028 9029 ins_pipe(ialu_reg_reg_shift); 9030 %} 9031 9032 instruct AddI_reg_URShift_reg(iRegINoSp dst, 9033 iRegI src1, iRegI src2, 9034 immI src3, rFlagsReg cr) %{ 9035 match(Set dst (AddI src1 (URShiftI src2 src3))); 9036 9037 ins_cost(1.9 * INSN_COST); 9038 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 9039 9040 ins_encode %{ 9041 __ addw(as_Register($dst$$reg), 9042 as_Register($src1$$reg), 9043 as_Register($src2$$reg), 9044 Assembler::LSR, 9045 $src3$$constant & 0x3f); 9046 %} 9047 9048 ins_pipe(ialu_reg_reg_shift); 9049 %} 9050 9051 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 9052 iRegL src1, iRegL src2, 9053 immI src3, rFlagsReg cr) %{ 9054 match(Set dst (AddL src1 (URShiftL src2 src3))); 9055 9056 ins_cost(1.9 * INSN_COST); 9057 format %{ "add $dst, $src1, $src2, LSR $src3" %} 9058 9059 ins_encode %{ 9060 __ add(as_Register($dst$$reg), 9061 as_Register($src1$$reg), 9062 as_Register($src2$$reg), 9063 Assembler::LSR, 9064 $src3$$constant & 0x3f); 9065 %} 9066 9067 ins_pipe(ialu_reg_reg_shift); 9068 %} 9069 9070 instruct AddI_reg_RShift_reg(iRegINoSp dst, 9071 iRegI src1, iRegI src2, 9072 immI src3, rFlagsReg cr) %{ 9073 match(Set dst (AddI src1 (RShiftI src2 src3))); 9074 9075 ins_cost(1.9 * INSN_COST); 9076 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 9077 9078 ins_encode %{ 9079 __ addw(as_Register($dst$$reg), 9080 as_Register($src1$$reg), 9081 as_Register($src2$$reg), 9082 Assembler::ASR, 9083 $src3$$constant & 0x3f); 9084 %} 9085 9086 ins_pipe(ialu_reg_reg_shift); 9087 %} 9088 9089 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 9090 iRegL src1, iRegL src2, 9091 immI src3, rFlagsReg cr) %{ 9092 match(Set dst (AddL src1 (RShiftL src2 src3))); 9093 9094 ins_cost(1.9 * INSN_COST); 9095 format %{ "add $dst, $src1, $src2, ASR $src3" %} 9096 9097 ins_encode %{ 9098 __ add(as_Register($dst$$reg), 9099 as_Register($src1$$reg), 9100 as_Register($src2$$reg), 9101 Assembler::ASR, 9102 $src3$$constant & 0x3f); 9103 %} 9104 9105 ins_pipe(ialu_reg_reg_shift); 9106 %} 9107 9108 instruct AddI_reg_LShift_reg(iRegINoSp dst, 9109 iRegI src1, iRegI src2, 9110 immI src3, rFlagsReg cr) %{ 9111 match(Set dst (AddI src1 (LShiftI src2 src3))); 9112 9113 ins_cost(1.9 * INSN_COST); 9114 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 9115 9116 ins_encode %{ 9117 __ addw(as_Register($dst$$reg), 9118 as_Register($src1$$reg), 9119 as_Register($src2$$reg), 9120 Assembler::LSL, 9121 $src3$$constant & 0x3f); 9122 %} 9123 9124 ins_pipe(ialu_reg_reg_shift); 9125 %} 9126 9127 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 9128 iRegL src1, iRegL src2, 9129 immI src3, rFlagsReg cr) %{ 9130 match(Set dst (AddL src1 (LShiftL src2 src3))); 9131 9132 ins_cost(1.9 * INSN_COST); 9133 format %{ "add $dst, $src1, $src2, LSL $src3" %} 9134 9135 ins_encode %{ 9136 __ add(as_Register($dst$$reg), 9137 as_Register($src1$$reg), 9138 as_Register($src2$$reg), 9139 Assembler::LSL, 9140 $src3$$constant & 0x3f); 9141 %} 9142 9143 ins_pipe(ialu_reg_reg_shift); 9144 %} 9145 9146 instruct SubI_reg_URShift_reg(iRegINoSp dst, 9147 iRegI src1, iRegI src2, 9148 immI src3, rFlagsReg cr) %{ 9149 match(Set dst (SubI src1 (URShiftI src2 src3))); 9150 9151 ins_cost(1.9 * INSN_COST); 9152 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 9153 9154 ins_encode %{ 9155 __ subw(as_Register($dst$$reg), 9156 as_Register($src1$$reg), 9157 as_Register($src2$$reg), 9158 Assembler::LSR, 9159 $src3$$constant & 0x3f); 9160 %} 9161 9162 ins_pipe(ialu_reg_reg_shift); 9163 %} 9164 9165 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 9166 iRegL src1, iRegL src2, 9167 immI src3, rFlagsReg cr) %{ 9168 match(Set dst (SubL src1 (URShiftL src2 src3))); 9169 9170 ins_cost(1.9 * INSN_COST); 9171 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 9172 9173 ins_encode %{ 9174 __ sub(as_Register($dst$$reg), 9175 as_Register($src1$$reg), 9176 as_Register($src2$$reg), 9177 Assembler::LSR, 9178 $src3$$constant & 0x3f); 9179 %} 9180 9181 ins_pipe(ialu_reg_reg_shift); 9182 %} 9183 9184 instruct SubI_reg_RShift_reg(iRegINoSp dst, 9185 iRegI src1, iRegI src2, 9186 immI src3, rFlagsReg cr) %{ 9187 match(Set dst (SubI src1 (RShiftI src2 src3))); 9188 9189 ins_cost(1.9 * INSN_COST); 9190 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 9191 9192 ins_encode %{ 9193 __ subw(as_Register($dst$$reg), 9194 as_Register($src1$$reg), 9195 as_Register($src2$$reg), 9196 Assembler::ASR, 9197 $src3$$constant & 0x3f); 9198 %} 9199 9200 ins_pipe(ialu_reg_reg_shift); 9201 %} 9202 9203 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 9204 iRegL src1, iRegL src2, 9205 immI src3, rFlagsReg cr) %{ 9206 match(Set dst (SubL src1 (RShiftL src2 src3))); 9207 9208 ins_cost(1.9 * INSN_COST); 9209 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 9210 9211 ins_encode %{ 9212 __ sub(as_Register($dst$$reg), 9213 as_Register($src1$$reg), 9214 as_Register($src2$$reg), 9215 Assembler::ASR, 9216 $src3$$constant & 0x3f); 9217 %} 9218 9219 ins_pipe(ialu_reg_reg_shift); 9220 %} 9221 9222 instruct SubI_reg_LShift_reg(iRegINoSp dst, 9223 iRegI src1, iRegI src2, 9224 immI src3, rFlagsReg cr) %{ 9225 match(Set dst (SubI src1 (LShiftI src2 src3))); 9226 9227 ins_cost(1.9 * INSN_COST); 9228 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 9229 9230 ins_encode %{ 9231 __ subw(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 SubL_reg_LShift_reg(iRegLNoSp dst, 9242 iRegL src1, iRegL src2, 9243 immI src3, rFlagsReg cr) %{ 9244 match(Set dst (SubL src1 (LShiftL src2 src3))); 9245 9246 ins_cost(1.9 * INSN_COST); 9247 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 9248 9249 ins_encode %{ 9250 __ sub(as_Register($dst$$reg), 9251 as_Register($src1$$reg), 9252 as_Register($src2$$reg), 9253 Assembler::LSL, 9254 $src3$$constant & 0x3f); 9255 %} 9256 9257 ins_pipe(ialu_reg_reg_shift); 9258 %} 9259 9260 9261 9262 // Shift Left followed by Shift Right. 9263 // This idiom is used by the compiler for the i2b bytecode etc. 9264 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 9265 %{ 9266 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 9267 // Make sure we are not going to exceed what sbfm can do. 9268 predicate((unsigned int)n->in(2)->get_int() <= 63 9269 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 9270 9271 ins_cost(INSN_COST * 2); 9272 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 9273 ins_encode %{ 9274 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 9275 int s = 63 - lshift; 9276 int r = (rshift - lshift) & 63; 9277 __ sbfm(as_Register($dst$$reg), 9278 as_Register($src$$reg), 9279 r, s); 9280 %} 9281 9282 ins_pipe(ialu_reg_shift); 9283 %} 9284 9285 // Shift Left followed by Shift Right. 9286 // This idiom is used by the compiler for the i2b bytecode etc. 9287 instruct sbfmwI(iRegINoSp dst, iRegI src, immI lshift_count, immI rshift_count) 9288 %{ 9289 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 9290 // Make sure we are not going to exceed what sbfmw can do. 9291 predicate((unsigned int)n->in(2)->get_int() <= 31 9292 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 9293 9294 ins_cost(INSN_COST * 2); 9295 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 9296 ins_encode %{ 9297 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 9298 int s = 31 - lshift; 9299 int r = (rshift - lshift) & 31; 9300 __ sbfmw(as_Register($dst$$reg), 9301 as_Register($src$$reg), 9302 r, s); 9303 %} 9304 9305 ins_pipe(ialu_reg_shift); 9306 %} 9307 9308 // Shift Left followed by Shift Right. 9309 // This idiom is used by the compiler for the i2b bytecode etc. 9310 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 9311 %{ 9312 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 9313 // Make sure we are not going to exceed what ubfm can do. 9314 predicate((unsigned int)n->in(2)->get_int() <= 63 9315 && (unsigned int)n->in(1)->in(2)->get_int() <= 63); 9316 9317 ins_cost(INSN_COST * 2); 9318 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 9319 ins_encode %{ 9320 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 9321 int s = 63 - lshift; 9322 int r = (rshift - lshift) & 63; 9323 __ ubfm(as_Register($dst$$reg), 9324 as_Register($src$$reg), 9325 r, s); 9326 %} 9327 9328 ins_pipe(ialu_reg_shift); 9329 %} 9330 9331 // Shift Left followed by Shift Right. 9332 // This idiom is used by the compiler for the i2b bytecode etc. 9333 instruct ubfmwI(iRegINoSp dst, iRegI src, immI lshift_count, immI rshift_count) 9334 %{ 9335 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 9336 // Make sure we are not going to exceed what ubfmw can do. 9337 predicate((unsigned int)n->in(2)->get_int() <= 31 9338 && (unsigned int)n->in(1)->in(2)->get_int() <= 31); 9339 9340 ins_cost(INSN_COST * 2); 9341 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 9342 ins_encode %{ 9343 int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant; 9344 int s = 31 - lshift; 9345 int r = (rshift - lshift) & 31; 9346 __ ubfmw(as_Register($dst$$reg), 9347 as_Register($src$$reg), 9348 r, s); 9349 %} 9350 9351 ins_pipe(ialu_reg_shift); 9352 %} 9353 // Bitfield extract with shift & mask 9354 9355 instruct ubfxwI(iRegINoSp dst, iRegI src, immI rshift, immI_bitmask mask) 9356 %{ 9357 match(Set dst (AndI (URShiftI src rshift) mask)); 9358 9359 ins_cost(INSN_COST); 9360 format %{ "ubfxw $dst, $src, $mask" %} 9361 ins_encode %{ 9362 int rshift = $rshift$$constant; 9363 long mask = $mask$$constant; 9364 int width = exact_log2(mask+1); 9365 __ ubfxw(as_Register($dst$$reg), 9366 as_Register($src$$reg), rshift, width); 9367 %} 9368 ins_pipe(ialu_reg_shift); 9369 %} 9370 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 9371 %{ 9372 match(Set dst (AndL (URShiftL src rshift) mask)); 9373 9374 ins_cost(INSN_COST); 9375 format %{ "ubfx $dst, $src, $mask" %} 9376 ins_encode %{ 9377 int rshift = $rshift$$constant; 9378 long mask = $mask$$constant; 9379 int width = exact_log2(mask+1); 9380 __ ubfx(as_Register($dst$$reg), 9381 as_Register($src$$reg), rshift, width); 9382 %} 9383 ins_pipe(ialu_reg_shift); 9384 %} 9385 9386 // We can use ubfx when extending an And with a mask when we know mask 9387 // is positive. We know that because immI_bitmask guarantees it. 9388 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 9389 %{ 9390 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 9391 9392 ins_cost(INSN_COST * 2); 9393 format %{ "ubfx $dst, $src, $mask" %} 9394 ins_encode %{ 9395 int rshift = $rshift$$constant; 9396 long mask = $mask$$constant; 9397 int width = exact_log2(mask+1); 9398 __ ubfx(as_Register($dst$$reg), 9399 as_Register($src$$reg), rshift, width); 9400 %} 9401 ins_pipe(ialu_reg_shift); 9402 %} 9403 9404 // Rotations 9405 9406 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 9407 %{ 9408 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 9409 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 9410 9411 ins_cost(INSN_COST); 9412 format %{ "extr $dst, $src1, $src2, #$rshift" %} 9413 9414 ins_encode %{ 9415 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 9416 $rshift$$constant & 63); 9417 %} 9418 ins_pipe(ialu_reg_reg_extr); 9419 %} 9420 9421 instruct extrOrI(iRegINoSp dst, iRegI src1, iRegI src2, immI lshift, immI rshift, rFlagsReg cr) 9422 %{ 9423 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 9424 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 9425 9426 ins_cost(INSN_COST); 9427 format %{ "extr $dst, $src1, $src2, #$rshift" %} 9428 9429 ins_encode %{ 9430 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 9431 $rshift$$constant & 31); 9432 %} 9433 ins_pipe(ialu_reg_reg_extr); 9434 %} 9435 9436 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 9437 %{ 9438 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 9439 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 63)); 9440 9441 ins_cost(INSN_COST); 9442 format %{ "extr $dst, $src1, $src2, #$rshift" %} 9443 9444 ins_encode %{ 9445 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 9446 $rshift$$constant & 63); 9447 %} 9448 ins_pipe(ialu_reg_reg_extr); 9449 %} 9450 9451 instruct extrAddI(iRegINoSp dst, iRegI src1, iRegI src2, immI lshift, immI rshift, rFlagsReg cr) 9452 %{ 9453 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 9454 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 31)); 9455 9456 ins_cost(INSN_COST); 9457 format %{ "extr $dst, $src1, $src2, #$rshift" %} 9458 9459 ins_encode %{ 9460 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 9461 $rshift$$constant & 31); 9462 %} 9463 ins_pipe(ialu_reg_reg_extr); 9464 %} 9465 9466 9467 // rol expander 9468 9469 instruct rolL_rReg(iRegL dst, iRegL src, iRegI shift, rFlagsReg cr) 9470 %{ 9471 effect(DEF dst, USE src, USE shift); 9472 9473 format %{ "rol $dst, $src, $shift" %} 9474 ins_cost(INSN_COST * 3); 9475 ins_encode %{ 9476 __ subw(rscratch1, zr, as_Register($shift$$reg)); 9477 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 9478 rscratch1); 9479 %} 9480 ins_pipe(ialu_reg_reg_vshift); 9481 %} 9482 9483 // rol expander 9484 9485 instruct rolI_rReg(iRegI dst, iRegI src, iRegI shift, rFlagsReg cr) 9486 %{ 9487 effect(DEF dst, USE src, USE shift); 9488 9489 format %{ "rol $dst, $src, $shift" %} 9490 ins_cost(INSN_COST * 3); 9491 ins_encode %{ 9492 __ subw(rscratch1, zr, as_Register($shift$$reg)); 9493 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 9494 rscratch1); 9495 %} 9496 ins_pipe(ialu_reg_reg_vshift); 9497 %} 9498 9499 instruct rolL_rReg_Var_C_64(iRegL dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 9500 %{ 9501 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c_64 shift)))); 9502 9503 expand %{ 9504 rolL_rReg(dst, src, shift, cr); 9505 %} 9506 %} 9507 9508 instruct rolL_rReg_Var_C0(iRegL dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 9509 %{ 9510 match(Set dst (OrL (LShiftL src shift) (URShiftL src (SubI c0 shift)))); 9511 9512 expand %{ 9513 rolL_rReg(dst, src, shift, cr); 9514 %} 9515 %} 9516 9517 instruct rolI_rReg_Var_C_32(iRegL dst, iRegL src, iRegI shift, immI_32 c_32, rFlagsReg cr) 9518 %{ 9519 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift)))); 9520 9521 expand %{ 9522 rolL_rReg(dst, src, shift, cr); 9523 %} 9524 %} 9525 9526 instruct rolI_rReg_Var_C0(iRegL dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 9527 %{ 9528 match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift)))); 9529 9530 expand %{ 9531 rolL_rReg(dst, src, shift, cr); 9532 %} 9533 %} 9534 9535 // ror expander 9536 9537 instruct rorL_rReg(iRegL dst, iRegL src, iRegI shift, rFlagsReg cr) 9538 %{ 9539 effect(DEF dst, USE src, USE shift); 9540 9541 format %{ "ror $dst, $src, $shift" %} 9542 ins_cost(INSN_COST); 9543 ins_encode %{ 9544 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), 9545 as_Register($shift$$reg)); 9546 %} 9547 ins_pipe(ialu_reg_reg_vshift); 9548 %} 9549 9550 // ror expander 9551 9552 instruct rorI_rReg(iRegI dst, iRegI src, iRegI shift, rFlagsReg cr) 9553 %{ 9554 effect(DEF dst, USE src, USE shift); 9555 9556 format %{ "ror $dst, $src, $shift" %} 9557 ins_cost(INSN_COST); 9558 ins_encode %{ 9559 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), 9560 as_Register($shift$$reg)); 9561 %} 9562 ins_pipe(ialu_reg_reg_vshift); 9563 %} 9564 9565 instruct rorL_rReg_Var_C_64(iRegL dst, iRegL src, iRegI shift, immI_64 c_64, rFlagsReg cr) 9566 %{ 9567 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c_64 shift)))); 9568 9569 expand %{ 9570 rorL_rReg(dst, src, shift, cr); 9571 %} 9572 %} 9573 9574 instruct rorL_rReg_Var_C0(iRegL dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 9575 %{ 9576 match(Set dst (OrL (URShiftL src shift) (LShiftL src (SubI c0 shift)))); 9577 9578 expand %{ 9579 rorL_rReg(dst, src, shift, cr); 9580 %} 9581 %} 9582 9583 instruct rorI_rReg_Var_C_32(iRegL dst, iRegL src, iRegI shift, immI_32 c_32, rFlagsReg cr) 9584 %{ 9585 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c_32 shift)))); 9586 9587 expand %{ 9588 rorL_rReg(dst, src, shift, cr); 9589 %} 9590 %} 9591 9592 instruct rorI_rReg_Var_C0(iRegL dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr) 9593 %{ 9594 match(Set dst (OrI (URShiftI src shift) (LShiftI src (SubI c0 shift)))); 9595 9596 expand %{ 9597 rorL_rReg(dst, src, shift, cr); 9598 %} 9599 %} 9600 9601 // Add/subtract (extended) 9602 9603 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 9604 %{ 9605 match(Set dst (AddL src1 (ConvI2L src2))); 9606 ins_cost(INSN_COST); 9607 format %{ "add $dst, $src1, sxtw $src2" %} 9608 9609 ins_encode %{ 9610 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9611 as_Register($src2$$reg), ext::sxtw); 9612 %} 9613 ins_pipe(ialu_reg_reg); 9614 %}; 9615 9616 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 9617 %{ 9618 match(Set dst (SubL src1 (ConvI2L src2))); 9619 ins_cost(INSN_COST); 9620 format %{ "sub $dst, $src1, sxtw $src2" %} 9621 9622 ins_encode %{ 9623 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 9624 as_Register($src2$$reg), ext::sxtw); 9625 %} 9626 ins_pipe(ialu_reg_reg); 9627 %}; 9628 9629 9630 instruct AddExtI_sxth(iRegINoSp dst, iRegI src1, iRegI src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 9631 %{ 9632 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 9633 ins_cost(INSN_COST); 9634 format %{ "add $dst, $src1, sxth $src2" %} 9635 9636 ins_encode %{ 9637 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9638 as_Register($src2$$reg), ext::sxth); 9639 %} 9640 ins_pipe(ialu_reg_reg); 9641 %} 9642 9643 instruct AddExtI_sxtb(iRegINoSp dst, iRegI src1, iRegI src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 9644 %{ 9645 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 9646 ins_cost(INSN_COST); 9647 format %{ "add $dst, $src1, sxtb $src2" %} 9648 9649 ins_encode %{ 9650 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9651 as_Register($src2$$reg), ext::sxtb); 9652 %} 9653 ins_pipe(ialu_reg_reg); 9654 %} 9655 9656 instruct AddExtI_uxtb(iRegINoSp dst, iRegI src1, iRegI src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 9657 %{ 9658 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 9659 ins_cost(INSN_COST); 9660 format %{ "add $dst, $src1, uxtb $src2" %} 9661 9662 ins_encode %{ 9663 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9664 as_Register($src2$$reg), ext::uxtb); 9665 %} 9666 ins_pipe(ialu_reg_reg); 9667 %} 9668 9669 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 9670 %{ 9671 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 9672 ins_cost(INSN_COST); 9673 format %{ "add $dst, $src1, sxth $src2" %} 9674 9675 ins_encode %{ 9676 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9677 as_Register($src2$$reg), ext::sxth); 9678 %} 9679 ins_pipe(ialu_reg_reg); 9680 %} 9681 9682 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 9683 %{ 9684 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 9685 ins_cost(INSN_COST); 9686 format %{ "add $dst, $src1, sxtw $src2" %} 9687 9688 ins_encode %{ 9689 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9690 as_Register($src2$$reg), ext::sxtw); 9691 %} 9692 ins_pipe(ialu_reg_reg); 9693 %} 9694 9695 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 9696 %{ 9697 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 9698 ins_cost(INSN_COST); 9699 format %{ "add $dst, $src1, sxtb $src2" %} 9700 9701 ins_encode %{ 9702 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9703 as_Register($src2$$reg), ext::sxtb); 9704 %} 9705 ins_pipe(ialu_reg_reg); 9706 %} 9707 9708 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 9709 %{ 9710 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 9711 ins_cost(INSN_COST); 9712 format %{ "add $dst, $src1, uxtb $src2" %} 9713 9714 ins_encode %{ 9715 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9716 as_Register($src2$$reg), ext::uxtb); 9717 %} 9718 ins_pipe(ialu_reg_reg); 9719 %} 9720 9721 9722 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_255 mask, rFlagsReg cr) 9723 %{ 9724 match(Set dst (AddI src1 (AndI src2 mask))); 9725 ins_cost(INSN_COST); 9726 format %{ "addw $dst, $src1, $src2, uxtb" %} 9727 9728 ins_encode %{ 9729 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 9730 as_Register($src2$$reg), ext::uxtb); 9731 %} 9732 ins_pipe(ialu_reg_reg); 9733 %} 9734 9735 instruct AddExtI_uxth_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_65535 mask, rFlagsReg cr) 9736 %{ 9737 match(Set dst (AddI src1 (AndI src2 mask))); 9738 ins_cost(INSN_COST); 9739 format %{ "addw $dst, $src1, $src2, uxth" %} 9740 9741 ins_encode %{ 9742 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 9743 as_Register($src2$$reg), ext::uxth); 9744 %} 9745 ins_pipe(ialu_reg_reg); 9746 %} 9747 9748 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 9749 %{ 9750 match(Set dst (AddL src1 (AndL src2 mask))); 9751 ins_cost(INSN_COST); 9752 format %{ "add $dst, $src1, $src2, uxtb" %} 9753 9754 ins_encode %{ 9755 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9756 as_Register($src2$$reg), ext::uxtb); 9757 %} 9758 ins_pipe(ialu_reg_reg); 9759 %} 9760 9761 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 9762 %{ 9763 match(Set dst (AddL src1 (AndL src2 mask))); 9764 ins_cost(INSN_COST); 9765 format %{ "add $dst, $src1, $src2, uxth" %} 9766 9767 ins_encode %{ 9768 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9769 as_Register($src2$$reg), ext::uxth); 9770 %} 9771 ins_pipe(ialu_reg_reg); 9772 %} 9773 9774 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 9775 %{ 9776 match(Set dst (AddL src1 (AndL src2 mask))); 9777 ins_cost(INSN_COST); 9778 format %{ "add $dst, $src1, $src2, uxtw" %} 9779 9780 ins_encode %{ 9781 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 9782 as_Register($src2$$reg), ext::uxtw); 9783 %} 9784 ins_pipe(ialu_reg_reg); 9785 %} 9786 9787 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_255 mask, rFlagsReg cr) 9788 %{ 9789 match(Set dst (SubI src1 (AndI src2 mask))); 9790 ins_cost(INSN_COST); 9791 format %{ "subw $dst, $src1, $src2, uxtb" %} 9792 9793 ins_encode %{ 9794 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 9795 as_Register($src2$$reg), ext::uxtb); 9796 %} 9797 ins_pipe(ialu_reg_reg); 9798 %} 9799 9800 instruct SubExtI_uxth_and(iRegINoSp dst, iRegI src1, iRegI src2, immI_65535 mask, rFlagsReg cr) 9801 %{ 9802 match(Set dst (SubI src1 (AndI src2 mask))); 9803 ins_cost(INSN_COST); 9804 format %{ "subw $dst, $src1, $src2, uxth" %} 9805 9806 ins_encode %{ 9807 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 9808 as_Register($src2$$reg), ext::uxth); 9809 %} 9810 ins_pipe(ialu_reg_reg); 9811 %} 9812 9813 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 9814 %{ 9815 match(Set dst (SubL src1 (AndL src2 mask))); 9816 ins_cost(INSN_COST); 9817 format %{ "sub $dst, $src1, $src2, uxtb" %} 9818 9819 ins_encode %{ 9820 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 9821 as_Register($src2$$reg), ext::uxtb); 9822 %} 9823 ins_pipe(ialu_reg_reg); 9824 %} 9825 9826 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 9827 %{ 9828 match(Set dst (SubL src1 (AndL src2 mask))); 9829 ins_cost(INSN_COST); 9830 format %{ "sub $dst, $src1, $src2, uxth" %} 9831 9832 ins_encode %{ 9833 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 9834 as_Register($src2$$reg), ext::uxth); 9835 %} 9836 ins_pipe(ialu_reg_reg); 9837 %} 9838 9839 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 9840 %{ 9841 match(Set dst (SubL src1 (AndL src2 mask))); 9842 ins_cost(INSN_COST); 9843 format %{ "sub $dst, $src1, $src2, uxtw" %} 9844 9845 ins_encode %{ 9846 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 9847 as_Register($src2$$reg), ext::uxtw); 9848 %} 9849 ins_pipe(ialu_reg_reg); 9850 %} 9851 9852 // END This section of the file is automatically generated. Do not edit -------------- 9853 9854 // ============================================================================ 9855 // Floating Point Arithmetic Instructions 9856 9857 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 9858 match(Set dst (AddF src1 src2)); 9859 9860 ins_cost(INSN_COST * 5); 9861 format %{ "fadds $dst, $src1, $src2" %} 9862 9863 ins_encode %{ 9864 __ fadds(as_FloatRegister($dst$$reg), 9865 as_FloatRegister($src1$$reg), 9866 as_FloatRegister($src2$$reg)); 9867 %} 9868 9869 ins_pipe(pipe_class_default); 9870 %} 9871 9872 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 9873 match(Set dst (AddD src1 src2)); 9874 9875 ins_cost(INSN_COST * 5); 9876 format %{ "faddd $dst, $src1, $src2" %} 9877 9878 ins_encode %{ 9879 __ faddd(as_FloatRegister($dst$$reg), 9880 as_FloatRegister($src1$$reg), 9881 as_FloatRegister($src2$$reg)); 9882 %} 9883 9884 ins_pipe(pipe_class_default); 9885 %} 9886 9887 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 9888 match(Set dst (SubF src1 src2)); 9889 9890 ins_cost(INSN_COST * 5); 9891 format %{ "fsubs $dst, $src1, $src2" %} 9892 9893 ins_encode %{ 9894 __ fsubs(as_FloatRegister($dst$$reg), 9895 as_FloatRegister($src1$$reg), 9896 as_FloatRegister($src2$$reg)); 9897 %} 9898 9899 ins_pipe(pipe_class_default); 9900 %} 9901 9902 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 9903 match(Set dst (SubD src1 src2)); 9904 9905 ins_cost(INSN_COST * 5); 9906 format %{ "fsubd $dst, $src1, $src2" %} 9907 9908 ins_encode %{ 9909 __ fsubd(as_FloatRegister($dst$$reg), 9910 as_FloatRegister($src1$$reg), 9911 as_FloatRegister($src2$$reg)); 9912 %} 9913 9914 ins_pipe(pipe_class_default); 9915 %} 9916 9917 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 9918 match(Set dst (MulF src1 src2)); 9919 9920 ins_cost(INSN_COST * 6); 9921 format %{ "fmuls $dst, $src1, $src2" %} 9922 9923 ins_encode %{ 9924 __ fmuls(as_FloatRegister($dst$$reg), 9925 as_FloatRegister($src1$$reg), 9926 as_FloatRegister($src2$$reg)); 9927 %} 9928 9929 ins_pipe(pipe_class_default); 9930 %} 9931 9932 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 9933 match(Set dst (MulD src1 src2)); 9934 9935 ins_cost(INSN_COST * 6); 9936 format %{ "fmuld $dst, $src1, $src2" %} 9937 9938 ins_encode %{ 9939 __ fmuld(as_FloatRegister($dst$$reg), 9940 as_FloatRegister($src1$$reg), 9941 as_FloatRegister($src2$$reg)); 9942 %} 9943 9944 ins_pipe(pipe_class_default); 9945 %} 9946 9947 // We cannot use these fused mul w add/sub ops because they don't 9948 // produce the same result as the equivalent separated ops 9949 // (essentially they don't round the intermediate result). that's a 9950 // shame. leaving them here in case we can idenitfy cases where it is 9951 // legitimate to use them 9952 9953 9954 // instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 9955 // match(Set dst (AddF (MulF src1 src2) src3)); 9956 9957 // format %{ "fmadds $dst, $src1, $src2, $src3" %} 9958 9959 // ins_encode %{ 9960 // __ fmadds(as_FloatRegister($dst$$reg), 9961 // as_FloatRegister($src1$$reg), 9962 // as_FloatRegister($src2$$reg), 9963 // as_FloatRegister($src3$$reg)); 9964 // %} 9965 9966 // ins_pipe(pipe_class_default); 9967 // %} 9968 9969 // instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 9970 // match(Set dst (AddD (MulD src1 src2) src3)); 9971 9972 // format %{ "fmaddd $dst, $src1, $src2, $src3" %} 9973 9974 // ins_encode %{ 9975 // __ fmaddd(as_FloatRegister($dst$$reg), 9976 // as_FloatRegister($src1$$reg), 9977 // as_FloatRegister($src2$$reg), 9978 // as_FloatRegister($src3$$reg)); 9979 // %} 9980 9981 // ins_pipe(pipe_class_default); 9982 // %} 9983 9984 // instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 9985 // match(Set dst (AddF (MulF (NegF src1) src2) src3)); 9986 // match(Set dst (AddF (NegF (MulF src1 src2)) src3)); 9987 9988 // format %{ "fmsubs $dst, $src1, $src2, $src3" %} 9989 9990 // ins_encode %{ 9991 // __ fmsubs(as_FloatRegister($dst$$reg), 9992 // as_FloatRegister($src1$$reg), 9993 // as_FloatRegister($src2$$reg), 9994 // as_FloatRegister($src3$$reg)); 9995 // %} 9996 9997 // ins_pipe(pipe_class_default); 9998 // %} 9999 10000 // instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 10001 // match(Set dst (AddD (MulD (NegD src1) src2) src3)); 10002 // match(Set dst (AddD (NegD (MulD src1 src2)) src3)); 10003 10004 // format %{ "fmsubd $dst, $src1, $src2, $src3" %} 10005 10006 // ins_encode %{ 10007 // __ fmsubd(as_FloatRegister($dst$$reg), 10008 // as_FloatRegister($src1$$reg), 10009 // as_FloatRegister($src2$$reg), 10010 // as_FloatRegister($src3$$reg)); 10011 // %} 10012 10013 // ins_pipe(pipe_class_default); 10014 // %} 10015 10016 // instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 10017 // match(Set dst (SubF (MulF (NegF src1) src2) src3)); 10018 // match(Set dst (SubF (NegF (MulF src1 src2)) src3)); 10019 10020 // format %{ "fnmadds $dst, $src1, $src2, $src3" %} 10021 10022 // ins_encode %{ 10023 // __ fnmadds(as_FloatRegister($dst$$reg), 10024 // as_FloatRegister($src1$$reg), 10025 // as_FloatRegister($src2$$reg), 10026 // as_FloatRegister($src3$$reg)); 10027 // %} 10028 10029 // ins_pipe(pipe_class_default); 10030 // %} 10031 10032 // instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 10033 // match(Set dst (SubD (MulD (NegD src1) src2) src3)); 10034 // match(Set dst (SubD (NegD (MulD src1 src2)) src3)); 10035 10036 // format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 10037 10038 // ins_encode %{ 10039 // __ fnmaddd(as_FloatRegister($dst$$reg), 10040 // as_FloatRegister($src1$$reg), 10041 // as_FloatRegister($src2$$reg), 10042 // as_FloatRegister($src3$$reg)); 10043 // %} 10044 10045 // ins_pipe(pipe_class_default); 10046 // %} 10047 10048 // instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 10049 // match(Set dst (SubF (MulF src1 src2) src3)); 10050 10051 // format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 10052 10053 // ins_encode %{ 10054 // __ fnmsubs(as_FloatRegister($dst$$reg), 10055 // as_FloatRegister($src1$$reg), 10056 // as_FloatRegister($src2$$reg), 10057 // as_FloatRegister($src3$$reg)); 10058 // %} 10059 10060 // ins_pipe(pipe_class_default); 10061 // %} 10062 10063 // instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 10064 // match(Set dst (SubD (MulD src1 src2) src3)); 10065 10066 // format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 10067 10068 // ins_encode %{ 10069 // // n.b. insn name should be fnmsubd 10070 // __ fnmsub(as_FloatRegister($dst$$reg), 10071 // as_FloatRegister($src1$$reg), 10072 // as_FloatRegister($src2$$reg), 10073 // as_FloatRegister($src3$$reg)); 10074 // %} 10075 10076 // ins_pipe(pipe_class_default); 10077 // %} 10078 10079 10080 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 10081 match(Set dst (DivF src1 src2)); 10082 10083 ins_cost(INSN_COST * 18); 10084 format %{ "fdivs $dst, $src1, $src2" %} 10085 10086 ins_encode %{ 10087 __ fdivs(as_FloatRegister($dst$$reg), 10088 as_FloatRegister($src1$$reg), 10089 as_FloatRegister($src2$$reg)); 10090 %} 10091 10092 ins_pipe(pipe_class_default); 10093 %} 10094 10095 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 10096 match(Set dst (DivD src1 src2)); 10097 10098 ins_cost(INSN_COST * 32); 10099 format %{ "fdivd $dst, $src1, $src2" %} 10100 10101 ins_encode %{ 10102 __ fdivd(as_FloatRegister($dst$$reg), 10103 as_FloatRegister($src1$$reg), 10104 as_FloatRegister($src2$$reg)); 10105 %} 10106 10107 ins_pipe(pipe_class_default); 10108 %} 10109 10110 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 10111 match(Set dst (NegF src)); 10112 10113 ins_cost(INSN_COST * 3); 10114 format %{ "fneg $dst, $src" %} 10115 10116 ins_encode %{ 10117 __ fnegs(as_FloatRegister($dst$$reg), 10118 as_FloatRegister($src$$reg)); 10119 %} 10120 10121 ins_pipe(pipe_class_default); 10122 %} 10123 10124 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 10125 match(Set dst (NegD src)); 10126 10127 ins_cost(INSN_COST * 3); 10128 format %{ "fnegd $dst, $src" %} 10129 10130 ins_encode %{ 10131 __ fnegd(as_FloatRegister($dst$$reg), 10132 as_FloatRegister($src$$reg)); 10133 %} 10134 10135 ins_pipe(pipe_class_default); 10136 %} 10137 10138 instruct absF_reg(vRegF dst, vRegF src) %{ 10139 match(Set dst (AbsF src)); 10140 10141 ins_cost(INSN_COST * 3); 10142 format %{ "fabss $dst, $src" %} 10143 ins_encode %{ 10144 __ fabss(as_FloatRegister($dst$$reg), 10145 as_FloatRegister($src$$reg)); 10146 %} 10147 10148 ins_pipe(pipe_class_default); 10149 %} 10150 10151 instruct absD_reg(vRegD dst, vRegD src) %{ 10152 match(Set dst (AbsD src)); 10153 10154 ins_cost(INSN_COST * 3); 10155 format %{ "fabsd $dst, $src" %} 10156 ins_encode %{ 10157 __ fabsd(as_FloatRegister($dst$$reg), 10158 as_FloatRegister($src$$reg)); 10159 %} 10160 10161 ins_pipe(pipe_class_default); 10162 %} 10163 10164 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 10165 match(Set dst (SqrtD src)); 10166 10167 ins_cost(INSN_COST * 50); 10168 format %{ "fsqrtd $dst, $src" %} 10169 ins_encode %{ 10170 __ fsqrtd(as_FloatRegister($dst$$reg), 10171 as_FloatRegister($src$$reg)); 10172 %} 10173 10174 ins_pipe(pipe_class_default); 10175 %} 10176 10177 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 10178 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 10179 10180 ins_cost(INSN_COST * 50); 10181 format %{ "fsqrts $dst, $src" %} 10182 ins_encode %{ 10183 __ fsqrts(as_FloatRegister($dst$$reg), 10184 as_FloatRegister($src$$reg)); 10185 %} 10186 10187 ins_pipe(pipe_class_default); 10188 %} 10189 10190 // ============================================================================ 10191 // Logical Instructions 10192 10193 // Integer Logical Instructions 10194 10195 // And Instructions 10196 10197 10198 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 10199 match(Set dst (AndI src1 src2)); 10200 10201 format %{ "andw $dst, $src1, $src2\t# int" %} 10202 10203 ins_cost(INSN_COST); 10204 ins_encode %{ 10205 __ andw(as_Register($dst$$reg), 10206 as_Register($src1$$reg), 10207 as_Register($src2$$reg)); 10208 %} 10209 10210 ins_pipe(ialu_reg_reg); 10211 %} 10212 10213 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 10214 match(Set dst (AndI src1 src2)); 10215 10216 format %{ "andsw $dst, $src1, $src2\t# int" %} 10217 10218 ins_cost(INSN_COST); 10219 ins_encode %{ 10220 __ andw(as_Register($dst$$reg), 10221 as_Register($src1$$reg), 10222 (unsigned long)($src2$$constant)); 10223 %} 10224 10225 ins_pipe(ialu_reg_imm); 10226 %} 10227 10228 // Or Instructions 10229 10230 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10231 match(Set dst (OrI src1 src2)); 10232 10233 format %{ "orrw $dst, $src1, $src2\t# int" %} 10234 10235 ins_cost(INSN_COST); 10236 ins_encode %{ 10237 __ orrw(as_Register($dst$$reg), 10238 as_Register($src1$$reg), 10239 as_Register($src2$$reg)); 10240 %} 10241 10242 ins_pipe(ialu_reg_reg); 10243 %} 10244 10245 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 10246 match(Set dst (OrI src1 src2)); 10247 10248 format %{ "orrw $dst, $src1, $src2\t# int" %} 10249 10250 ins_cost(INSN_COST); 10251 ins_encode %{ 10252 __ orrw(as_Register($dst$$reg), 10253 as_Register($src1$$reg), 10254 (unsigned long)($src2$$constant)); 10255 %} 10256 10257 ins_pipe(ialu_reg_imm); 10258 %} 10259 10260 // Xor Instructions 10261 10262 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10263 match(Set dst (XorI src1 src2)); 10264 10265 format %{ "eorw $dst, $src1, $src2\t# int" %} 10266 10267 ins_cost(INSN_COST); 10268 ins_encode %{ 10269 __ eorw(as_Register($dst$$reg), 10270 as_Register($src1$$reg), 10271 as_Register($src2$$reg)); 10272 %} 10273 10274 ins_pipe(ialu_reg_reg); 10275 %} 10276 10277 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 10278 match(Set dst (XorI src1 src2)); 10279 10280 format %{ "eorw $dst, $src1, $src2\t# int" %} 10281 10282 ins_cost(INSN_COST); 10283 ins_encode %{ 10284 __ eorw(as_Register($dst$$reg), 10285 as_Register($src1$$reg), 10286 (unsigned long)($src2$$constant)); 10287 %} 10288 10289 ins_pipe(ialu_reg_imm); 10290 %} 10291 10292 // Long Logical Instructions 10293 // TODO 10294 10295 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 10296 match(Set dst (AndL src1 src2)); 10297 10298 format %{ "and $dst, $src1, $src2\t# int" %} 10299 10300 ins_cost(INSN_COST); 10301 ins_encode %{ 10302 __ andr(as_Register($dst$$reg), 10303 as_Register($src1$$reg), 10304 as_Register($src2$$reg)); 10305 %} 10306 10307 ins_pipe(ialu_reg_reg); 10308 %} 10309 10310 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 10311 match(Set dst (AndL src1 src2)); 10312 10313 format %{ "and $dst, $src1, $src2\t# int" %} 10314 10315 ins_cost(INSN_COST); 10316 ins_encode %{ 10317 __ andr(as_Register($dst$$reg), 10318 as_Register($src1$$reg), 10319 (unsigned long)($src2$$constant)); 10320 %} 10321 10322 ins_pipe(ialu_reg_imm); 10323 %} 10324 10325 // Or Instructions 10326 10327 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10328 match(Set dst (OrL src1 src2)); 10329 10330 format %{ "orr $dst, $src1, $src2\t# int" %} 10331 10332 ins_cost(INSN_COST); 10333 ins_encode %{ 10334 __ orr(as_Register($dst$$reg), 10335 as_Register($src1$$reg), 10336 as_Register($src2$$reg)); 10337 %} 10338 10339 ins_pipe(ialu_reg_reg); 10340 %} 10341 10342 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 10343 match(Set dst (OrL src1 src2)); 10344 10345 format %{ "orr $dst, $src1, $src2\t# int" %} 10346 10347 ins_cost(INSN_COST); 10348 ins_encode %{ 10349 __ orr(as_Register($dst$$reg), 10350 as_Register($src1$$reg), 10351 (unsigned long)($src2$$constant)); 10352 %} 10353 10354 ins_pipe(ialu_reg_imm); 10355 %} 10356 10357 // Xor Instructions 10358 10359 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10360 match(Set dst (XorL src1 src2)); 10361 10362 format %{ "eor $dst, $src1, $src2\t# int" %} 10363 10364 ins_cost(INSN_COST); 10365 ins_encode %{ 10366 __ eor(as_Register($dst$$reg), 10367 as_Register($src1$$reg), 10368 as_Register($src2$$reg)); 10369 %} 10370 10371 ins_pipe(ialu_reg_reg); 10372 %} 10373 10374 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 10375 match(Set dst (XorL src1 src2)); 10376 10377 ins_cost(INSN_COST); 10378 format %{ "eor $dst, $src1, $src2\t# int" %} 10379 10380 ins_encode %{ 10381 __ eor(as_Register($dst$$reg), 10382 as_Register($src1$$reg), 10383 (unsigned long)($src2$$constant)); 10384 %} 10385 10386 ins_pipe(ialu_reg_imm); 10387 %} 10388 10389 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 10390 %{ 10391 match(Set dst (ConvI2L src)); 10392 10393 ins_cost(INSN_COST); 10394 format %{ "sxtw $dst, $src\t# i2l" %} 10395 ins_encode %{ 10396 __ sbfm($dst$$Register, $src$$Register, 0, 31); 10397 %} 10398 ins_pipe(ialu_reg_shift); 10399 %} 10400 10401 // this pattern occurs in bigmath arithmetic 10402 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegI src, immL_32bits mask) 10403 %{ 10404 match(Set dst (AndL (ConvI2L src) mask)); 10405 10406 ins_cost(INSN_COST); 10407 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 10408 ins_encode %{ 10409 __ ubfm($dst$$Register, $src$$Register, 0, 31); 10410 %} 10411 10412 ins_pipe(ialu_reg_shift); 10413 %} 10414 10415 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 10416 match(Set dst (ConvL2I src)); 10417 10418 ins_cost(INSN_COST); 10419 format %{ "movw $dst, $src \t// l2i" %} 10420 10421 ins_encode %{ 10422 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 10423 %} 10424 10425 ins_pipe(ialu_reg); 10426 %} 10427 10428 instruct convI2B(iRegINoSp dst, iRegI src, rFlagsReg cr) 10429 %{ 10430 match(Set dst (Conv2B src)); 10431 effect(KILL cr); 10432 10433 format %{ 10434 "cmpw $src, zr\n\t" 10435 "cset $dst, ne" 10436 %} 10437 10438 ins_encode %{ 10439 __ cmpw(as_Register($src$$reg), zr); 10440 __ cset(as_Register($dst$$reg), Assembler::NE); 10441 %} 10442 10443 ins_pipe(ialu_reg); 10444 %} 10445 10446 instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr) 10447 %{ 10448 match(Set dst (Conv2B src)); 10449 effect(KILL cr); 10450 10451 format %{ 10452 "cmp $src, zr\n\t" 10453 "cset $dst, ne" 10454 %} 10455 10456 ins_encode %{ 10457 __ cmp(as_Register($src$$reg), zr); 10458 __ cset(as_Register($dst$$reg), Assembler::NE); 10459 %} 10460 10461 ins_pipe(ialu_reg); 10462 %} 10463 10464 instruct convD2F_reg(vRegF dst, vRegD src) %{ 10465 match(Set dst (ConvD2F src)); 10466 10467 ins_cost(INSN_COST * 5); 10468 format %{ "fcvtd $dst, $src \t// d2f" %} 10469 10470 ins_encode %{ 10471 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 10472 %} 10473 10474 ins_pipe(pipe_class_default); 10475 %} 10476 10477 instruct convF2D_reg(vRegD dst, vRegF src) %{ 10478 match(Set dst (ConvF2D src)); 10479 10480 ins_cost(INSN_COST * 5); 10481 format %{ "fcvts $dst, $src \t// f2d" %} 10482 10483 ins_encode %{ 10484 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 10485 %} 10486 10487 ins_pipe(pipe_class_default); 10488 %} 10489 10490 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 10491 match(Set dst (ConvF2I src)); 10492 10493 ins_cost(INSN_COST * 5); 10494 format %{ "fcvtzsw $dst, $src \t// f2i" %} 10495 10496 ins_encode %{ 10497 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 10498 %} 10499 10500 ins_pipe(pipe_class_default); 10501 %} 10502 10503 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 10504 match(Set dst (ConvF2L src)); 10505 10506 ins_cost(INSN_COST * 5); 10507 format %{ "fcvtzs $dst, $src \t// f2l" %} 10508 10509 ins_encode %{ 10510 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 10511 %} 10512 10513 ins_pipe(pipe_class_default); 10514 %} 10515 10516 instruct convI2F_reg_reg(vRegF dst, iRegI src) %{ 10517 match(Set dst (ConvI2F src)); 10518 10519 ins_cost(INSN_COST * 5); 10520 format %{ "scvtfws $dst, $src \t// i2f" %} 10521 10522 ins_encode %{ 10523 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 10524 %} 10525 10526 ins_pipe(pipe_class_default); 10527 %} 10528 10529 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 10530 match(Set dst (ConvL2F src)); 10531 10532 ins_cost(INSN_COST * 5); 10533 format %{ "scvtfs $dst, $src \t// l2f" %} 10534 10535 ins_encode %{ 10536 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 10537 %} 10538 10539 ins_pipe(pipe_class_default); 10540 %} 10541 10542 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 10543 match(Set dst (ConvD2I src)); 10544 10545 ins_cost(INSN_COST * 5); 10546 format %{ "fcvtzdw $dst, $src \t// d2i" %} 10547 10548 ins_encode %{ 10549 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 10550 %} 10551 10552 ins_pipe(pipe_class_default); 10553 %} 10554 10555 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 10556 match(Set dst (ConvD2L src)); 10557 10558 ins_cost(INSN_COST * 5); 10559 format %{ "fcvtzd $dst, $src \t// d2l" %} 10560 10561 ins_encode %{ 10562 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 10563 %} 10564 10565 ins_pipe(pipe_class_default); 10566 %} 10567 10568 instruct convI2D_reg_reg(vRegD dst, iRegI src) %{ 10569 match(Set dst (ConvI2D src)); 10570 10571 ins_cost(INSN_COST * 5); 10572 format %{ "scvtfwd $dst, $src \t// i2d" %} 10573 10574 ins_encode %{ 10575 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 10576 %} 10577 10578 ins_pipe(pipe_class_default); 10579 %} 10580 10581 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 10582 match(Set dst (ConvL2D src)); 10583 10584 ins_cost(INSN_COST * 5); 10585 format %{ "scvtfd $dst, $src \t// l2d" %} 10586 10587 ins_encode %{ 10588 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 10589 %} 10590 10591 ins_pipe(pipe_class_default); 10592 %} 10593 10594 // stack <-> reg and reg <-> reg shuffles with no conversion 10595 10596 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 10597 10598 match(Set dst (MoveF2I src)); 10599 10600 effect(DEF dst, USE src); 10601 10602 ins_cost(4 * INSN_COST); 10603 10604 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 10605 10606 ins_encode %{ 10607 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 10608 %} 10609 10610 ins_pipe(iload_reg_reg); 10611 10612 %} 10613 10614 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 10615 10616 match(Set dst (MoveI2F src)); 10617 10618 effect(DEF dst, USE src); 10619 10620 ins_cost(4 * INSN_COST); 10621 10622 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 10623 10624 ins_encode %{ 10625 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 10626 %} 10627 10628 ins_pipe(pipe_class_memory); 10629 10630 %} 10631 10632 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 10633 10634 match(Set dst (MoveD2L src)); 10635 10636 effect(DEF dst, USE src); 10637 10638 ins_cost(4 * INSN_COST); 10639 10640 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 10641 10642 ins_encode %{ 10643 __ ldr($dst$$Register, Address(sp, $src$$disp)); 10644 %} 10645 10646 ins_pipe(iload_reg_reg); 10647 10648 %} 10649 10650 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 10651 10652 match(Set dst (MoveL2D src)); 10653 10654 effect(DEF dst, USE src); 10655 10656 ins_cost(4 * INSN_COST); 10657 10658 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 10659 10660 ins_encode %{ 10661 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 10662 %} 10663 10664 ins_pipe(pipe_class_memory); 10665 10666 %} 10667 10668 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 10669 10670 match(Set dst (MoveF2I src)); 10671 10672 effect(DEF dst, USE src); 10673 10674 ins_cost(INSN_COST); 10675 10676 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 10677 10678 ins_encode %{ 10679 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 10680 %} 10681 10682 ins_pipe(pipe_class_memory); 10683 10684 %} 10685 10686 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 10687 10688 match(Set dst (MoveI2F src)); 10689 10690 effect(DEF dst, USE src); 10691 10692 ins_cost(INSN_COST); 10693 10694 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 10695 10696 ins_encode %{ 10697 __ strw($src$$Register, Address(sp, $dst$$disp)); 10698 %} 10699 10700 ins_pipe(istore_reg_reg); 10701 10702 %} 10703 10704 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 10705 10706 match(Set dst (MoveD2L src)); 10707 10708 effect(DEF dst, USE src); 10709 10710 ins_cost(INSN_COST); 10711 10712 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 10713 10714 ins_encode %{ 10715 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 10716 %} 10717 10718 ins_pipe(pipe_class_memory); 10719 10720 %} 10721 10722 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 10723 10724 match(Set dst (MoveL2D src)); 10725 10726 effect(DEF dst, USE src); 10727 10728 ins_cost(INSN_COST); 10729 10730 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 10731 10732 ins_encode %{ 10733 __ str($src$$Register, Address(sp, $dst$$disp)); 10734 %} 10735 10736 ins_pipe(istore_reg_reg); 10737 10738 %} 10739 10740 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 10741 10742 match(Set dst (MoveF2I src)); 10743 10744 effect(DEF dst, USE src); 10745 10746 ins_cost(INSN_COST); 10747 10748 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 10749 10750 ins_encode %{ 10751 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 10752 %} 10753 10754 ins_pipe(pipe_class_memory); 10755 10756 %} 10757 10758 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 10759 10760 match(Set dst (MoveI2F src)); 10761 10762 effect(DEF dst, USE src); 10763 10764 ins_cost(INSN_COST); 10765 10766 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 10767 10768 ins_encode %{ 10769 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 10770 %} 10771 10772 ins_pipe(pipe_class_memory); 10773 10774 %} 10775 10776 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 10777 10778 match(Set dst (MoveD2L src)); 10779 10780 effect(DEF dst, USE src); 10781 10782 ins_cost(INSN_COST); 10783 10784 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 10785 10786 ins_encode %{ 10787 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 10788 %} 10789 10790 ins_pipe(pipe_class_memory); 10791 10792 %} 10793 10794 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 10795 10796 match(Set dst (MoveL2D src)); 10797 10798 effect(DEF dst, USE src); 10799 10800 ins_cost(INSN_COST); 10801 10802 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 10803 10804 ins_encode %{ 10805 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 10806 %} 10807 10808 ins_pipe(pipe_class_memory); 10809 10810 %} 10811 10812 // ============================================================================ 10813 // clearing of an array 10814 10815 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) 10816 %{ 10817 match(Set dummy (ClearArray cnt base)); 10818 effect(USE_KILL cnt, USE_KILL base); 10819 10820 ins_cost(4 * INSN_COST); 10821 format %{ "ClearArray $cnt, $base" %} 10822 10823 ins_encode(aarch64_enc_clear_array_reg_reg(cnt, base)); 10824 10825 ins_pipe(pipe_class_memory); 10826 %} 10827 10828 // ============================================================================ 10829 // Overflow Math Instructions 10830 10831 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 10832 %{ 10833 match(Set cr (OverflowAddI op1 op2)); 10834 10835 format %{ "cmnw $op1, $op2\t# overflow check int" %} 10836 ins_cost(INSN_COST); 10837 ins_encode %{ 10838 __ cmnw($op1$$Register, $op2$$Register); 10839 %} 10840 10841 ins_pipe(icmp_reg_reg); 10842 %} 10843 10844 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegI op1, immIAddSub op2) 10845 %{ 10846 match(Set cr (OverflowAddI op1 op2)); 10847 10848 format %{ "cmnw $op1, $op2\t# overflow check int" %} 10849 ins_cost(INSN_COST); 10850 ins_encode %{ 10851 __ cmnw($op1$$Register, $op2$$constant); 10852 %} 10853 10854 ins_pipe(icmp_reg_imm); 10855 %} 10856 10857 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 10858 %{ 10859 match(Set cr (OverflowAddL op1 op2)); 10860 10861 format %{ "cmn $op1, $op2\t# overflow check long" %} 10862 ins_cost(INSN_COST); 10863 ins_encode %{ 10864 __ cmn($op1$$Register, $op2$$Register); 10865 %} 10866 10867 ins_pipe(icmp_reg_reg); 10868 %} 10869 10870 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 10871 %{ 10872 match(Set cr (OverflowAddL op1 op2)); 10873 10874 format %{ "cmn $op1, $op2\t# overflow check long" %} 10875 ins_cost(INSN_COST); 10876 ins_encode %{ 10877 __ cmn($op1$$Register, $op2$$constant); 10878 %} 10879 10880 ins_pipe(icmp_reg_imm); 10881 %} 10882 10883 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 10884 %{ 10885 match(Set cr (OverflowSubI op1 op2)); 10886 10887 format %{ "cmpw $op1, $op2\t# overflow check int" %} 10888 ins_cost(INSN_COST); 10889 ins_encode %{ 10890 __ cmpw($op1$$Register, $op2$$Register); 10891 %} 10892 10893 ins_pipe(icmp_reg_reg); 10894 %} 10895 10896 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegI op1, immIAddSub op2) 10897 %{ 10898 match(Set cr (OverflowSubI op1 op2)); 10899 10900 format %{ "cmpw $op1, $op2\t# overflow check int" %} 10901 ins_cost(INSN_COST); 10902 ins_encode %{ 10903 __ cmpw($op1$$Register, $op2$$constant); 10904 %} 10905 10906 ins_pipe(icmp_reg_imm); 10907 %} 10908 10909 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 10910 %{ 10911 match(Set cr (OverflowSubL op1 op2)); 10912 10913 format %{ "cmp $op1, $op2\t# overflow check long" %} 10914 ins_cost(INSN_COST); 10915 ins_encode %{ 10916 __ cmp($op1$$Register, $op2$$Register); 10917 %} 10918 10919 ins_pipe(icmp_reg_reg); 10920 %} 10921 10922 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 10923 %{ 10924 match(Set cr (OverflowSubL op1 op2)); 10925 10926 format %{ "cmp $op1, $op2\t# overflow check long" %} 10927 ins_cost(INSN_COST); 10928 ins_encode %{ 10929 __ cmp($op1$$Register, $op2$$constant); 10930 %} 10931 10932 ins_pipe(icmp_reg_imm); 10933 %} 10934 10935 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegI op1) 10936 %{ 10937 match(Set cr (OverflowSubI zero op1)); 10938 10939 format %{ "cmpw zr, $op1\t# overflow check int" %} 10940 ins_cost(INSN_COST); 10941 ins_encode %{ 10942 __ cmpw(zr, $op1$$Register); 10943 %} 10944 10945 ins_pipe(icmp_reg_imm); 10946 %} 10947 10948 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 10949 %{ 10950 match(Set cr (OverflowSubL zero op1)); 10951 10952 format %{ "cmp zr, $op1\t# overflow check long" %} 10953 ins_cost(INSN_COST); 10954 ins_encode %{ 10955 __ cmp(zr, $op1$$Register); 10956 %} 10957 10958 ins_pipe(icmp_reg_imm); 10959 %} 10960 10961 instruct overflowMulI_reg(rFlagsReg cr, iRegI op1, iRegI op2) 10962 %{ 10963 match(Set cr (OverflowMulI op1 op2)); 10964 10965 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 10966 "cmp rscratch1, rscratch1, sxtw\n\t" 10967 "movw rscratch1, #0x80000000\n\t" 10968 "cselw rscratch1, rscratch1, zr, NE\n\t" 10969 "cmpw rscratch1, #1" %} 10970 ins_cost(5 * INSN_COST); 10971 ins_encode %{ 10972 __ smull(rscratch1, $op1$$Register, $op2$$Register); 10973 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 10974 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 10975 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 10976 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 10977 %} 10978 10979 ins_pipe(pipe_slow); 10980 %} 10981 10982 instruct overflowMulI_reg_branch(cmpOp cmp, iRegI op1, iRegI op2, label labl, rFlagsReg cr) 10983 %{ 10984 match(If cmp (OverflowMulI op1 op2)); 10985 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 10986 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 10987 effect(USE labl, KILL cr); 10988 10989 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 10990 "cmp rscratch1, rscratch1, sxtw\n\t" 10991 "b$cmp $labl" %} 10992 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 10993 ins_encode %{ 10994 Label* L = $labl$$label; 10995 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10996 __ smull(rscratch1, $op1$$Register, $op2$$Register); 10997 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 10998 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 10999 %} 11000 11001 ins_pipe(pipe_serial); 11002 %} 11003 11004 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 11005 %{ 11006 match(Set cr (OverflowMulL op1 op2)); 11007 11008 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 11009 "smulh rscratch2, $op1, $op2\n\t" 11010 "cmp rscratch2, rscratch1, ASR #31\n\t" 11011 "movw rscratch1, #0x80000000\n\t" 11012 "cselw rscratch1, rscratch1, zr, NE\n\t" 11013 "cmpw rscratch1, #1" %} 11014 ins_cost(6 * INSN_COST); 11015 ins_encode %{ 11016 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 11017 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 11018 __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext 11019 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 11020 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 11021 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 11022 %} 11023 11024 ins_pipe(pipe_slow); 11025 %} 11026 11027 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 11028 %{ 11029 match(If cmp (OverflowMulL op1 op2)); 11030 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 11031 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 11032 effect(USE labl, KILL cr); 11033 11034 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 11035 "smulh rscratch2, $op1, $op2\n\t" 11036 "cmp rscratch2, rscratch1, ASR #31\n\t" 11037 "b$cmp $labl" %} 11038 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 11039 ins_encode %{ 11040 Label* L = $labl$$label; 11041 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11042 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 11043 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 11044 __ cmp(rscratch2, rscratch1, Assembler::ASR, 31); // Top is pure sign ext 11045 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 11046 %} 11047 11048 ins_pipe(pipe_serial); 11049 %} 11050 11051 // ============================================================================ 11052 // Compare Instructions 11053 11054 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 11055 %{ 11056 match(Set cr (CmpI op1 op2)); 11057 11058 effect(DEF cr, USE op1, USE op2); 11059 11060 ins_cost(INSN_COST); 11061 format %{ "cmpw $op1, $op2" %} 11062 11063 ins_encode(aarch64_enc_cmpw(op1, op2)); 11064 11065 ins_pipe(icmp_reg_reg); 11066 %} 11067 11068 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 11069 %{ 11070 match(Set cr (CmpI op1 zero)); 11071 11072 effect(DEF cr, USE op1); 11073 11074 ins_cost(INSN_COST); 11075 format %{ "cmpw $op1, 0" %} 11076 11077 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 11078 11079 ins_pipe(icmp_reg_imm); 11080 %} 11081 11082 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 11083 %{ 11084 match(Set cr (CmpI op1 op2)); 11085 11086 effect(DEF cr, USE op1); 11087 11088 ins_cost(INSN_COST); 11089 format %{ "cmpw $op1, $op2" %} 11090 11091 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 11092 11093 ins_pipe(icmp_reg_imm); 11094 %} 11095 11096 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 11097 %{ 11098 match(Set cr (CmpI op1 op2)); 11099 11100 effect(DEF cr, USE op1); 11101 11102 ins_cost(INSN_COST * 2); 11103 format %{ "cmpw $op1, $op2" %} 11104 11105 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 11106 11107 ins_pipe(icmp_reg_imm); 11108 %} 11109 11110 // Unsigned compare Instructions; really, same as signed compare 11111 // except it should only be used to feed an If or a CMovI which takes a 11112 // cmpOpU. 11113 11114 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 11115 %{ 11116 match(Set cr (CmpU op1 op2)); 11117 11118 effect(DEF cr, USE op1, USE op2); 11119 11120 ins_cost(INSN_COST); 11121 format %{ "cmpw $op1, $op2\t# unsigned" %} 11122 11123 ins_encode(aarch64_enc_cmpw(op1, op2)); 11124 11125 ins_pipe(icmp_reg_reg); 11126 %} 11127 11128 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 11129 %{ 11130 match(Set cr (CmpU op1 zero)); 11131 11132 effect(DEF cr, USE op1); 11133 11134 ins_cost(INSN_COST); 11135 format %{ "cmpw $op1, #0\t# unsigned" %} 11136 11137 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 11138 11139 ins_pipe(icmp_reg_imm); 11140 %} 11141 11142 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 11143 %{ 11144 match(Set cr (CmpU op1 op2)); 11145 11146 effect(DEF cr, USE op1); 11147 11148 ins_cost(INSN_COST); 11149 format %{ "cmpw $op1, $op2\t# unsigned" %} 11150 11151 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 11152 11153 ins_pipe(icmp_reg_imm); 11154 %} 11155 11156 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 11157 %{ 11158 match(Set cr (CmpU op1 op2)); 11159 11160 effect(DEF cr, USE op1); 11161 11162 ins_cost(INSN_COST * 2); 11163 format %{ "cmpw $op1, $op2\t# unsigned" %} 11164 11165 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 11166 11167 ins_pipe(icmp_reg_imm); 11168 %} 11169 11170 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 11171 %{ 11172 match(Set cr (CmpL op1 op2)); 11173 11174 effect(DEF cr, USE op1, USE op2); 11175 11176 ins_cost(INSN_COST); 11177 format %{ "cmp $op1, $op2" %} 11178 11179 ins_encode(aarch64_enc_cmp(op1, op2)); 11180 11181 ins_pipe(icmp_reg_reg); 11182 %} 11183 11184 instruct compL_reg_immI0(rFlagsReg cr, iRegL op1, immI0 zero) 11185 %{ 11186 match(Set cr (CmpL op1 zero)); 11187 11188 effect(DEF cr, USE op1); 11189 11190 ins_cost(INSN_COST); 11191 format %{ "tst $op1" %} 11192 11193 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 11194 11195 ins_pipe(icmp_reg_imm); 11196 %} 11197 11198 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 11199 %{ 11200 match(Set cr (CmpL op1 op2)); 11201 11202 effect(DEF cr, USE op1); 11203 11204 ins_cost(INSN_COST); 11205 format %{ "cmp $op1, $op2" %} 11206 11207 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 11208 11209 ins_pipe(icmp_reg_imm); 11210 %} 11211 11212 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 11213 %{ 11214 match(Set cr (CmpL op1 op2)); 11215 11216 effect(DEF cr, USE op1); 11217 11218 ins_cost(INSN_COST * 2); 11219 format %{ "cmp $op1, $op2" %} 11220 11221 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 11222 11223 ins_pipe(icmp_reg_imm); 11224 %} 11225 11226 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 11227 %{ 11228 match(Set cr (CmpP op1 op2)); 11229 11230 effect(DEF cr, USE op1, USE op2); 11231 11232 ins_cost(INSN_COST); 11233 format %{ "cmp $op1, $op2\t // ptr" %} 11234 11235 ins_encode(aarch64_enc_cmpp(op1, op2)); 11236 11237 ins_pipe(icmp_reg_reg); 11238 %} 11239 11240 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 11241 %{ 11242 match(Set cr (CmpN op1 op2)); 11243 11244 effect(DEF cr, USE op1, USE op2); 11245 11246 ins_cost(INSN_COST); 11247 format %{ "cmp $op1, $op2\t // compressed ptr" %} 11248 11249 ins_encode(aarch64_enc_cmpn(op1, op2)); 11250 11251 ins_pipe(icmp_reg_reg); 11252 %} 11253 11254 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 11255 %{ 11256 match(Set cr (CmpP op1 zero)); 11257 11258 effect(DEF cr, USE op1, USE zero); 11259 11260 ins_cost(INSN_COST); 11261 format %{ "cmp $op1, 0\t // ptr" %} 11262 11263 ins_encode(aarch64_enc_testp(op1)); 11264 11265 ins_pipe(icmp_reg_imm); 11266 %} 11267 11268 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 11269 %{ 11270 match(Set cr (CmpN op1 zero)); 11271 11272 effect(DEF cr, USE op1, USE zero); 11273 11274 ins_cost(INSN_COST); 11275 format %{ "cmp $op1, 0\t // compressed ptr" %} 11276 11277 ins_encode(aarch64_enc_testn(op1)); 11278 11279 ins_pipe(icmp_reg_imm); 11280 %} 11281 11282 // FP comparisons 11283 // 11284 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 11285 // using normal cmpOp. See declaration of rFlagsReg for details. 11286 11287 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 11288 %{ 11289 match(Set cr (CmpF src1 src2)); 11290 11291 ins_cost(3 * INSN_COST); 11292 format %{ "fcmps $src1, $src2" %} 11293 11294 ins_encode %{ 11295 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 11296 %} 11297 11298 ins_pipe(pipe_class_compare); 11299 %} 11300 11301 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 11302 %{ 11303 match(Set cr (CmpF src1 src2)); 11304 11305 ins_cost(3 * INSN_COST); 11306 format %{ "fcmps $src1, 0.0" %} 11307 11308 ins_encode %{ 11309 __ fcmps(as_FloatRegister($src1$$reg), 0.0D); 11310 %} 11311 11312 ins_pipe(pipe_class_compare); 11313 %} 11314 // FROM HERE 11315 11316 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 11317 %{ 11318 match(Set cr (CmpD src1 src2)); 11319 11320 ins_cost(3 * INSN_COST); 11321 format %{ "fcmpd $src1, $src2" %} 11322 11323 ins_encode %{ 11324 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 11325 %} 11326 11327 ins_pipe(pipe_class_compare); 11328 %} 11329 11330 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 11331 %{ 11332 match(Set cr (CmpD src1 src2)); 11333 11334 ins_cost(3 * INSN_COST); 11335 format %{ "fcmpd $src1, 0.0" %} 11336 11337 ins_encode %{ 11338 __ fcmpd(as_FloatRegister($src1$$reg), 0.0D); 11339 %} 11340 11341 ins_pipe(pipe_class_compare); 11342 %} 11343 11344 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 11345 %{ 11346 match(Set dst (CmpF3 src1 src2)); 11347 effect(KILL cr); 11348 11349 ins_cost(5 * INSN_COST); 11350 format %{ "fcmps $src1, $src2\n\t" 11351 "csinvw($dst, zr, zr, eq\n\t" 11352 "csnegw($dst, $dst, $dst, lt)" 11353 %} 11354 11355 ins_encode %{ 11356 Label done; 11357 FloatRegister s1 = as_FloatRegister($src1$$reg); 11358 FloatRegister s2 = as_FloatRegister($src2$$reg); 11359 Register d = as_Register($dst$$reg); 11360 __ fcmps(s1, s2); 11361 // installs 0 if EQ else -1 11362 __ csinvw(d, zr, zr, Assembler::EQ); 11363 // keeps -1 if less or unordered else installs 1 11364 __ csnegw(d, d, d, Assembler::LT); 11365 __ bind(done); 11366 %} 11367 11368 ins_pipe(pipe_class_default); 11369 11370 %} 11371 11372 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 11373 %{ 11374 match(Set dst (CmpD3 src1 src2)); 11375 effect(KILL cr); 11376 11377 ins_cost(5 * INSN_COST); 11378 format %{ "fcmpd $src1, $src2\n\t" 11379 "csinvw($dst, zr, zr, eq\n\t" 11380 "csnegw($dst, $dst, $dst, lt)" 11381 %} 11382 11383 ins_encode %{ 11384 Label done; 11385 FloatRegister s1 = as_FloatRegister($src1$$reg); 11386 FloatRegister s2 = as_FloatRegister($src2$$reg); 11387 Register d = as_Register($dst$$reg); 11388 __ fcmpd(s1, s2); 11389 // installs 0 if EQ else -1 11390 __ csinvw(d, zr, zr, Assembler::EQ); 11391 // keeps -1 if less or unordered else installs 1 11392 __ csnegw(d, d, d, Assembler::LT); 11393 __ bind(done); 11394 %} 11395 ins_pipe(pipe_class_default); 11396 11397 %} 11398 11399 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 11400 %{ 11401 match(Set dst (CmpF3 src1 zero)); 11402 effect(KILL cr); 11403 11404 ins_cost(5 * INSN_COST); 11405 format %{ "fcmps $src1, 0.0\n\t" 11406 "csinvw($dst, zr, zr, eq\n\t" 11407 "csnegw($dst, $dst, $dst, lt)" 11408 %} 11409 11410 ins_encode %{ 11411 Label done; 11412 FloatRegister s1 = as_FloatRegister($src1$$reg); 11413 Register d = as_Register($dst$$reg); 11414 __ fcmps(s1, 0.0D); 11415 // installs 0 if EQ else -1 11416 __ csinvw(d, zr, zr, Assembler::EQ); 11417 // keeps -1 if less or unordered else installs 1 11418 __ csnegw(d, d, d, Assembler::LT); 11419 __ bind(done); 11420 %} 11421 11422 ins_pipe(pipe_class_default); 11423 11424 %} 11425 11426 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 11427 %{ 11428 match(Set dst (CmpD3 src1 zero)); 11429 effect(KILL cr); 11430 11431 ins_cost(5 * INSN_COST); 11432 format %{ "fcmpd $src1, 0.0\n\t" 11433 "csinvw($dst, zr, zr, eq\n\t" 11434 "csnegw($dst, $dst, $dst, lt)" 11435 %} 11436 11437 ins_encode %{ 11438 Label done; 11439 FloatRegister s1 = as_FloatRegister($src1$$reg); 11440 Register d = as_Register($dst$$reg); 11441 __ fcmpd(s1, 0.0D); 11442 // installs 0 if EQ else -1 11443 __ csinvw(d, zr, zr, Assembler::EQ); 11444 // keeps -1 if less or unordered else installs 1 11445 __ csnegw(d, d, d, Assembler::LT); 11446 __ bind(done); 11447 %} 11448 ins_pipe(pipe_class_default); 11449 11450 %} 11451 11452 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegI p, iRegI q, rFlagsReg cr) 11453 %{ 11454 match(Set dst (CmpLTMask p q)); 11455 effect(KILL cr); 11456 11457 ins_cost(3 * INSN_COST); 11458 11459 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 11460 "csetw $dst, lt\n\t" 11461 "subw $dst, zr, $dst" 11462 %} 11463 11464 ins_encode %{ 11465 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 11466 __ csetw(as_Register($dst$$reg), Assembler::LT); 11467 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 11468 %} 11469 11470 ins_pipe(ialu_reg_reg); 11471 %} 11472 11473 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegI src, immI0 zero, rFlagsReg cr) 11474 %{ 11475 match(Set dst (CmpLTMask src zero)); 11476 effect(KILL cr); 11477 11478 ins_cost(INSN_COST); 11479 11480 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 11481 11482 ins_encode %{ 11483 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 11484 %} 11485 11486 ins_pipe(ialu_reg_shift); 11487 %} 11488 11489 // ============================================================================ 11490 // Max and Min 11491 11492 instruct minI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 11493 %{ 11494 match(Set dst (MinI src1 src2)); 11495 11496 effect(DEF dst, USE src1, USE src2, KILL cr); 11497 size(8); 11498 11499 ins_cost(INSN_COST * 3); 11500 format %{ 11501 "cmpw $src1 $src2\t signed int\n\t" 11502 "cselw $dst, $src1, $src2 lt\t" 11503 %} 11504 11505 ins_encode %{ 11506 __ cmpw(as_Register($src1$$reg), 11507 as_Register($src2$$reg)); 11508 __ cselw(as_Register($dst$$reg), 11509 as_Register($src1$$reg), 11510 as_Register($src2$$reg), 11511 Assembler::LT); 11512 %} 11513 11514 ins_pipe(ialu_reg_reg); 11515 %} 11516 // FROM HERE 11517 11518 instruct maxI_rReg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 11519 %{ 11520 match(Set dst (MaxI src1 src2)); 11521 11522 effect(DEF dst, USE src1, USE src2, KILL cr); 11523 size(8); 11524 11525 ins_cost(INSN_COST * 3); 11526 format %{ 11527 "cmpw $src1 $src2\t signed int\n\t" 11528 "cselw $dst, $src1, $src2 gt\t" 11529 %} 11530 11531 ins_encode %{ 11532 __ cmpw(as_Register($src1$$reg), 11533 as_Register($src2$$reg)); 11534 __ cselw(as_Register($dst$$reg), 11535 as_Register($src1$$reg), 11536 as_Register($src2$$reg), 11537 Assembler::GT); 11538 %} 11539 11540 ins_pipe(ialu_reg_reg); 11541 %} 11542 11543 // ============================================================================ 11544 // Branch Instructions 11545 11546 // Direct Branch. 11547 instruct branch(label lbl) 11548 %{ 11549 match(Goto); 11550 11551 effect(USE lbl); 11552 11553 ins_cost(BRANCH_COST); 11554 format %{ "b $lbl" %} 11555 11556 ins_encode(aarch64_enc_b(lbl)); 11557 11558 ins_pipe(pipe_branch); 11559 %} 11560 11561 // Conditional Near Branch 11562 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 11563 %{ 11564 // Same match rule as `branchConFar'. 11565 match(If cmp cr); 11566 11567 effect(USE lbl); 11568 11569 ins_cost(BRANCH_COST); 11570 // If set to 1 this indicates that the current instruction is a 11571 // short variant of a long branch. This avoids using this 11572 // instruction in first-pass matching. It will then only be used in 11573 // the `Shorten_branches' pass. 11574 // ins_short_branch(1); 11575 format %{ "b$cmp $lbl" %} 11576 11577 ins_encode(aarch64_enc_br_con(cmp, lbl)); 11578 11579 ins_pipe(pipe_branch_cond); 11580 %} 11581 11582 // Conditional Near Branch Unsigned 11583 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 11584 %{ 11585 // Same match rule as `branchConFar'. 11586 match(If cmp cr); 11587 11588 effect(USE lbl); 11589 11590 ins_cost(BRANCH_COST); 11591 // If set to 1 this indicates that the current instruction is a 11592 // short variant of a long branch. This avoids using this 11593 // instruction in first-pass matching. It will then only be used in 11594 // the `Shorten_branches' pass. 11595 // ins_short_branch(1); 11596 format %{ "b$cmp $lbl\t# unsigned" %} 11597 11598 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 11599 11600 ins_pipe(pipe_branch_cond); 11601 %} 11602 11603 // Make use of CBZ and CBNZ. These instructions, as well as being 11604 // shorter than (cmp; branch), have the additional benefit of not 11605 // killing the flags. 11606 11607 instruct cmpI_imm0_branch(cmpOp cmp, iRegI op1, immI0 op2, label labl, rFlagsReg cr) %{ 11608 match(If cmp (CmpI op1 op2)); 11609 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 11610 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 11611 effect(USE labl); 11612 11613 ins_cost(BRANCH_COST); 11614 format %{ "cbw$cmp $op1, $labl" %} 11615 ins_encode %{ 11616 Label* L = $labl$$label; 11617 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11618 if (cond == Assembler::EQ) 11619 __ cbzw($op1$$Register, *L); 11620 else 11621 __ cbnzw($op1$$Register, *L); 11622 %} 11623 ins_pipe(pipe_cmp_branch); 11624 %} 11625 11626 instruct cmpL_imm0_branch(cmpOp cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 11627 match(If cmp (CmpL op1 op2)); 11628 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 11629 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 11630 effect(USE labl); 11631 11632 ins_cost(BRANCH_COST); 11633 format %{ "cb$cmp $op1, $labl" %} 11634 ins_encode %{ 11635 Label* L = $labl$$label; 11636 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11637 if (cond == Assembler::EQ) 11638 __ cbz($op1$$Register, *L); 11639 else 11640 __ cbnz($op1$$Register, *L); 11641 %} 11642 ins_pipe(pipe_cmp_branch); 11643 %} 11644 11645 instruct cmpP_imm0_branch(cmpOp cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 11646 match(If cmp (CmpP op1 op2)); 11647 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne 11648 || n->in(1)->as_Bool()->_test._test == BoolTest::eq); 11649 effect(USE labl); 11650 11651 ins_cost(BRANCH_COST); 11652 format %{ "cb$cmp $op1, $labl" %} 11653 ins_encode %{ 11654 Label* L = $labl$$label; 11655 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 11656 if (cond == Assembler::EQ) 11657 __ cbz($op1$$Register, *L); 11658 else 11659 __ cbnz($op1$$Register, *L); 11660 %} 11661 ins_pipe(pipe_cmp_branch); 11662 %} 11663 11664 // Conditional Far Branch 11665 // Conditional Far Branch Unsigned 11666 // TODO: fixme 11667 11668 // counted loop end branch near 11669 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 11670 %{ 11671 match(CountedLoopEnd cmp cr); 11672 11673 effect(USE lbl); 11674 11675 ins_cost(BRANCH_COST); 11676 // short variant. 11677 // ins_short_branch(1); 11678 format %{ "b$cmp $lbl \t// counted loop end" %} 11679 11680 ins_encode(aarch64_enc_br_con(cmp, lbl)); 11681 11682 ins_pipe(pipe_branch); 11683 %} 11684 11685 // counted loop end branch near Unsigned 11686 instruct branchLoopEndU(cmpOpU cmp, rFlagsRegU cr, label lbl) 11687 %{ 11688 match(CountedLoopEnd cmp cr); 11689 11690 effect(USE lbl); 11691 11692 ins_cost(BRANCH_COST); 11693 // short variant. 11694 // ins_short_branch(1); 11695 format %{ "b$cmp $lbl \t// counted loop end unsigned" %} 11696 11697 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 11698 11699 ins_pipe(pipe_branch); 11700 %} 11701 11702 // counted loop end branch far 11703 // counted loop end branch far unsigned 11704 // TODO: fixme 11705 11706 // ============================================================================ 11707 // inlined locking and unlocking 11708 11709 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 11710 %{ 11711 match(Set cr (FastLock object box)); 11712 effect(TEMP tmp, TEMP tmp2); 11713 11714 // TODO 11715 // identify correct cost 11716 ins_cost(5 * INSN_COST); 11717 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 11718 11719 ins_encode(aarch64_enc_fast_lock(object, box, tmp, tmp2)); 11720 11721 ins_pipe(pipe_serial); 11722 %} 11723 11724 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 11725 %{ 11726 match(Set cr (FastUnlock object box)); 11727 effect(TEMP tmp, TEMP tmp2); 11728 11729 ins_cost(5 * INSN_COST); 11730 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 11731 11732 ins_encode(aarch64_enc_fast_unlock(object, box, tmp, tmp2)); 11733 11734 ins_pipe(pipe_serial); 11735 %} 11736 11737 11738 // ============================================================================ 11739 // Safepoint Instructions 11740 11741 // TODO 11742 // provide a near and far version of this code 11743 11744 instruct safePoint(iRegP poll) 11745 %{ 11746 match(SafePoint poll); 11747 11748 format %{ 11749 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 11750 %} 11751 ins_encode %{ 11752 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 11753 %} 11754 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 11755 %} 11756 11757 11758 // ============================================================================ 11759 // Procedure Call/Return Instructions 11760 11761 // Call Java Static Instruction 11762 11763 instruct CallStaticJavaDirect(method meth) 11764 %{ 11765 match(CallStaticJava); 11766 11767 effect(USE meth); 11768 11769 predicate(!((CallStaticJavaNode*)n)->is_method_handle_invoke()); 11770 11771 ins_cost(CALL_COST); 11772 11773 format %{ "call,static $meth \t// ==> " %} 11774 11775 ins_encode( aarch64_enc_java_static_call(meth), 11776 aarch64_enc_call_epilog ); 11777 11778 ins_pipe(pipe_class_call); 11779 %} 11780 11781 // TO HERE 11782 11783 // Call Java Static Instruction (method handle version) 11784 11785 instruct CallStaticJavaDirectHandle(method meth, iRegP_FP reg_mh_save) 11786 %{ 11787 match(CallStaticJava); 11788 11789 effect(USE meth); 11790 11791 predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke()); 11792 11793 ins_cost(CALL_COST); 11794 11795 format %{ "call,static $meth \t// (methodhandle) ==> " %} 11796 11797 ins_encode( aarch64_enc_java_handle_call(meth), 11798 aarch64_enc_call_epilog ); 11799 11800 ins_pipe(pipe_class_call); 11801 %} 11802 11803 // Call Java Dynamic Instruction 11804 instruct CallDynamicJavaDirect(method meth) 11805 %{ 11806 match(CallDynamicJava); 11807 11808 effect(USE meth); 11809 11810 ins_cost(CALL_COST); 11811 11812 format %{ "CALL,dynamic $meth \t// ==> " %} 11813 11814 ins_encode( aarch64_enc_java_dynamic_call(meth), 11815 aarch64_enc_call_epilog ); 11816 11817 ins_pipe(pipe_class_call); 11818 %} 11819 11820 // Call Runtime Instruction 11821 11822 instruct CallRuntimeDirect(method meth) 11823 %{ 11824 match(CallRuntime); 11825 11826 effect(USE meth); 11827 11828 ins_cost(CALL_COST); 11829 11830 format %{ "CALL, runtime $meth" %} 11831 11832 ins_encode( aarch64_enc_java_to_runtime(meth) ); 11833 11834 ins_pipe(pipe_class_call); 11835 %} 11836 11837 // Call Runtime Instruction 11838 11839 instruct CallLeafDirect(method meth) 11840 %{ 11841 match(CallLeaf); 11842 11843 effect(USE meth); 11844 11845 ins_cost(CALL_COST); 11846 11847 format %{ "CALL, runtime leaf $meth" %} 11848 11849 ins_encode( aarch64_enc_java_to_runtime(meth) ); 11850 11851 ins_pipe(pipe_class_call); 11852 %} 11853 11854 // Call Runtime Instruction 11855 11856 instruct CallLeafNoFPDirect(method meth) 11857 %{ 11858 match(CallLeafNoFP); 11859 11860 effect(USE meth); 11861 11862 ins_cost(CALL_COST); 11863 11864 format %{ "CALL, runtime leaf nofp $meth" %} 11865 11866 ins_encode( aarch64_enc_java_to_runtime(meth) ); 11867 11868 ins_pipe(pipe_class_call); 11869 %} 11870 11871 // Tail Call; Jump from runtime stub to Java code. 11872 // Also known as an 'interprocedural jump'. 11873 // Target of jump will eventually return to caller. 11874 // TailJump below removes the return address. 11875 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_oop) 11876 %{ 11877 match(TailCall jump_target method_oop); 11878 11879 ins_cost(CALL_COST); 11880 11881 format %{ "br $jump_target\t# $method_oop holds method oop" %} 11882 11883 ins_encode(aarch64_enc_tail_call(jump_target)); 11884 11885 ins_pipe(pipe_class_call); 11886 %} 11887 11888 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 11889 %{ 11890 match(TailJump jump_target ex_oop); 11891 11892 ins_cost(CALL_COST); 11893 11894 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 11895 11896 ins_encode(aarch64_enc_tail_jmp(jump_target)); 11897 11898 ins_pipe(pipe_class_call); 11899 %} 11900 11901 // Create exception oop: created by stack-crawling runtime code. 11902 // Created exception is now available to this handler, and is setup 11903 // just prior to jumping to this handler. No code emitted. 11904 // TODO check 11905 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 11906 instruct CreateException(iRegP_R0 ex_oop) 11907 %{ 11908 match(Set ex_oop (CreateEx)); 11909 11910 format %{ " -- \t// exception oop; no code emitted" %} 11911 11912 size(0); 11913 11914 ins_encode( /*empty*/ ); 11915 11916 ins_pipe(pipe_class_empty); 11917 %} 11918 11919 // Rethrow exception: The exception oop will come in the first 11920 // argument position. Then JUMP (not call) to the rethrow stub code. 11921 instruct RethrowException() %{ 11922 match(Rethrow); 11923 ins_cost(CALL_COST); 11924 11925 format %{ "b rethrow_stub" %} 11926 11927 ins_encode( aarch64_enc_rethrow() ); 11928 11929 ins_pipe(pipe_class_call); 11930 %} 11931 11932 11933 // Return Instruction 11934 // epilog node loads ret address into lr as part of frame pop 11935 instruct Ret() 11936 %{ 11937 match(Return); 11938 11939 format %{ "ret\t// return register" %} 11940 11941 ins_encode( aarch64_enc_ret() ); 11942 11943 ins_pipe(pipe_branch); 11944 %} 11945 11946 // Die now. 11947 instruct ShouldNotReachHere() %{ 11948 match(Halt); 11949 11950 ins_cost(CALL_COST); 11951 format %{ "ShouldNotReachHere" %} 11952 11953 ins_encode %{ 11954 // TODO 11955 // implement proper trap call here 11956 __ brk(999); 11957 %} 11958 11959 ins_pipe(pipe_class_default); 11960 %} 11961 11962 // ============================================================================ 11963 // Partial Subtype Check 11964 // 11965 // superklass array for an instance of the superklass. Set a hidden 11966 // internal cache on a hit (cache is checked with exposed code in 11967 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11968 // encoding ALSO sets flags. 11969 11970 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 11971 %{ 11972 match(Set result (PartialSubtypeCheck sub super)); 11973 effect(KILL cr, KILL temp); 11974 11975 ins_cost(1100); // slightly larger than the next version 11976 format %{ "partialSubtypeCheck $result, $sub, $super" %} 11977 11978 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 11979 11980 opcode(0x1); // Force zero of result reg on hit 11981 11982 ins_pipe(pipe_class_memory); 11983 %} 11984 11985 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 11986 %{ 11987 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11988 effect(KILL temp, KILL result); 11989 11990 ins_cost(1100); // slightly larger than the next version 11991 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 11992 11993 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 11994 11995 opcode(0x0); // Don't zero result reg on hit 11996 11997 ins_pipe(pipe_class_memory); 11998 %} 11999 12000 instruct string_compare(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 12001 iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr) 12002 %{ 12003 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12004 effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12005 12006 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 12007 ins_encode %{ 12008 __ string_compare($str1$$Register, $str2$$Register, 12009 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12010 $tmp1$$Register); 12011 %} 12012 ins_pipe(pipe_class_memory); 12013 %} 12014 12015 instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 12016 iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr) 12017 %{ 12018 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12019 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 12020 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 12021 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result" %} 12022 12023 ins_encode %{ 12024 __ string_indexof($str1$$Register, $str2$$Register, 12025 $cnt1$$Register, $cnt2$$Register, 12026 $tmp1$$Register, $tmp2$$Register, 12027 $tmp3$$Register, $tmp4$$Register, 12028 -1, $result$$Register); 12029 %} 12030 ins_pipe(pipe_class_memory); 12031 %} 12032 12033 instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 12034 immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2, 12035 iRegI tmp3, iRegI tmp4, rFlagsReg cr) 12036 %{ 12037 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12038 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 12039 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 12040 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result" %} 12041 12042 ins_encode %{ 12043 int icnt2 = (int)$int_cnt2$$constant; 12044 __ string_indexof($str1$$Register, $str2$$Register, 12045 $cnt1$$Register, zr, 12046 $tmp1$$Register, $tmp2$$Register, 12047 $tmp3$$Register, $tmp4$$Register, 12048 icnt2, $result$$Register); 12049 %} 12050 ins_pipe(pipe_class_memory); 12051 %} 12052 12053 instruct string_equals(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 12054 iRegI_R0 result, iRegP_R10 tmp, rFlagsReg cr) 12055 %{ 12056 match(Set result (StrEquals (Binary str1 str2) cnt)); 12057 effect(KILL tmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 12058 12059 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %} 12060 ins_encode %{ 12061 __ string_equals($str1$$Register, $str2$$Register, 12062 $cnt$$Register, $result$$Register, 12063 $tmp$$Register); 12064 %} 12065 ins_pipe(pipe_class_memory); 12066 %} 12067 12068 instruct array_equals(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 12069 iRegP_R10 tmp, rFlagsReg cr) 12070 %{ 12071 match(Set result (AryEq ary1 ary2)); 12072 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, KILL cr); 12073 12074 format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} 12075 ins_encode %{ 12076 __ char_arrays_equals($ary1$$Register, $ary2$$Register, 12077 $result$$Register, $tmp$$Register); 12078 %} 12079 ins_pipe(pipe_class_memory); 12080 %} 12081 12082 // encode char[] to byte[] in ISO_8859_1 12083 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 12084 vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, 12085 vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, 12086 iRegI_R0 result, rFlagsReg cr) 12087 %{ 12088 match(Set result (EncodeISOArray src (Binary dst len))); 12089 effect(USE_KILL src, USE_KILL dst, USE_KILL len, 12090 KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); 12091 12092 format %{ "Encode array $src,$dst,$len -> $result" %} 12093 ins_encode %{ 12094 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12095 $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, 12096 $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); 12097 %} 12098 ins_pipe( pipe_class_memory ); 12099 %} 12100 12101 // ============================================================================ 12102 // This name is KNOWN by the ADLC and cannot be changed. 12103 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12104 // for this guy. 12105 instruct tlsLoadP(thread_RegP dst) 12106 %{ 12107 match(Set dst (ThreadLocal)); 12108 12109 ins_cost(0); 12110 12111 format %{ " -- \t// $dst=Thread::current(), empty" %} 12112 12113 size(0); 12114 12115 ins_encode( /*empty*/ ); 12116 12117 ins_pipe(pipe_class_empty); 12118 %} 12119 12120 12121 12122 //----------PEEPHOLE RULES----------------------------------------------------- 12123 // These must follow all instruction definitions as they use the names 12124 // defined in the instructions definitions. 12125 // 12126 // peepmatch ( root_instr_name [preceding_instruction]* ); 12127 // 12128 // peepconstraint %{ 12129 // (instruction_number.operand_name relational_op instruction_number.operand_name 12130 // [, ...] ); 12131 // // instruction numbers are zero-based using left to right order in peepmatch 12132 // 12133 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12134 // // provide an instruction_number.operand_name for each operand that appears 12135 // // in the replacement instruction's match rule 12136 // 12137 // ---------VM FLAGS--------------------------------------------------------- 12138 // 12139 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12140 // 12141 // Each peephole rule is given an identifying number starting with zero and 12142 // increasing by one in the order seen by the parser. An individual peephole 12143 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12144 // on the command-line. 12145 // 12146 // ---------CURRENT LIMITATIONS---------------------------------------------- 12147 // 12148 // Only match adjacent instructions in same basic block 12149 // Only equality constraints 12150 // Only constraints between operands, not (0.dest_reg == RAX_enc) 12151 // Only one replacement instruction 12152 // 12153 // ---------EXAMPLE---------------------------------------------------------- 12154 // 12155 // // pertinent parts of existing instructions in architecture description 12156 // instruct movI(iRegINoSp dst, iRegI src) 12157 // %{ 12158 // match(Set dst (CopyI src)); 12159 // %} 12160 // 12161 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 12162 // %{ 12163 // match(Set dst (AddI dst src)); 12164 // effect(KILL cr); 12165 // %} 12166 // 12167 // // Change (inc mov) to lea 12168 // peephole %{ 12169 // // increment preceeded by register-register move 12170 // peepmatch ( incI_iReg movI ); 12171 // // require that the destination register of the increment 12172 // // match the destination register of the move 12173 // peepconstraint ( 0.dst == 1.dst ); 12174 // // construct a replacement instruction that sets 12175 // // the destination to ( move's source register + one ) 12176 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 12177 // %} 12178 // 12179 12180 // Implementation no longer uses movX instructions since 12181 // machine-independent system no longer uses CopyX nodes. 12182 // 12183 // peephole 12184 // %{ 12185 // peepmatch (incI_iReg movI); 12186 // peepconstraint (0.dst == 1.dst); 12187 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 12188 // %} 12189 12190 // peephole 12191 // %{ 12192 // peepmatch (decI_iReg movI); 12193 // peepconstraint (0.dst == 1.dst); 12194 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 12195 // %} 12196 12197 // peephole 12198 // %{ 12199 // peepmatch (addI_iReg_imm movI); 12200 // peepconstraint (0.dst == 1.dst); 12201 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 12202 // %} 12203 12204 // peephole 12205 // %{ 12206 // peepmatch (incL_iReg movL); 12207 // peepconstraint (0.dst == 1.dst); 12208 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 12209 // %} 12210 12211 // peephole 12212 // %{ 12213 // peepmatch (decL_iReg movL); 12214 // peepconstraint (0.dst == 1.dst); 12215 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 12216 // %} 12217 12218 // peephole 12219 // %{ 12220 // peepmatch (addL_iReg_imm movL); 12221 // peepconstraint (0.dst == 1.dst); 12222 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 12223 // %} 12224 12225 // peephole 12226 // %{ 12227 // peepmatch (addP_iReg_imm movP); 12228 // peepconstraint (0.dst == 1.dst); 12229 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 12230 // %} 12231 12232 // // Change load of spilled value to only a spill 12233 // instruct storeI(memory mem, iRegI src) 12234 // %{ 12235 // match(Set mem (StoreI mem src)); 12236 // %} 12237 // 12238 // instruct loadI(iRegINoSp dst, memory mem) 12239 // %{ 12240 // match(Set dst (LoadI mem)); 12241 // %} 12242 // 12243 12244 //----------SMARTSPILL RULES--------------------------------------------------- 12245 // These must follow all instruction definitions as they use the names 12246 // defined in the instructions definitions. 12247 12248 // Local Variables: 12249 // mode: c++ 12250 // End: