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