1 // 2 // Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2014, 2021, 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 // architecture. 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 non-allocatable (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 R8 ( NS, SOC, Op_RegI, 8, r8->as_VMReg() ); // rscratch1, non-allocatable 98 reg_def R8_H ( NS, SOC, Op_RegI, 8, r8->as_VMReg()->next() ); 99 reg_def R9 ( NS, SOC, Op_RegI, 9, r9->as_VMReg() ); // rscratch2, non-allocatable 100 reg_def R9_H ( NS, SOC, Op_RegI, 9, r9->as_VMReg()->next() ); 101 reg_def R10 ( SOC, SOC, Op_RegI, 10, r10->as_VMReg() ); 102 reg_def R10_H ( SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 103 reg_def R11 ( SOC, SOC, Op_RegI, 11, r11->as_VMReg() ); 104 reg_def R11_H ( SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 105 reg_def R12 ( SOC, SOC, Op_RegI, 12, r12->as_VMReg() ); 106 reg_def R12_H ( SOC, SOC, Op_RegI, 12, r12->as_VMReg()->next()); 107 reg_def R13 ( SOC, SOC, Op_RegI, 13, r13->as_VMReg() ); 108 reg_def R13_H ( SOC, SOC, Op_RegI, 13, r13->as_VMReg()->next()); 109 reg_def R14 ( SOC, SOC, Op_RegI, 14, r14->as_VMReg() ); 110 reg_def R14_H ( SOC, SOC, Op_RegI, 14, r14->as_VMReg()->next()); 111 reg_def R15 ( SOC, SOC, Op_RegI, 15, r15->as_VMReg() ); 112 reg_def R15_H ( SOC, SOC, Op_RegI, 15, r15->as_VMReg()->next()); 113 reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); 114 reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); 115 reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); 116 reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); 117 reg_def R18 ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg() ); 118 reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg()->next()); 119 reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); 120 reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); 121 reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp 122 reg_def R20_H ( SOC, SOE, Op_RegI, 20, r20->as_VMReg()->next()); 123 reg_def R21 ( SOC, SOE, Op_RegI, 21, r21->as_VMReg() ); 124 reg_def R21_H ( SOC, SOE, Op_RegI, 21, r21->as_VMReg()->next()); 125 reg_def R22 ( SOC, SOE, Op_RegI, 22, r22->as_VMReg() ); 126 reg_def R22_H ( SOC, SOE, Op_RegI, 22, r22->as_VMReg()->next()); 127 reg_def R23 ( SOC, SOE, Op_RegI, 23, r23->as_VMReg() ); 128 reg_def R23_H ( SOC, SOE, Op_RegI, 23, r23->as_VMReg()->next()); 129 reg_def R24 ( SOC, SOE, Op_RegI, 24, r24->as_VMReg() ); 130 reg_def R24_H ( SOC, SOE, Op_RegI, 24, r24->as_VMReg()->next()); 131 reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() ); 132 reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next()); 133 reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() ); 134 reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next()); 135 reg_def R27 ( SOC, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase 136 reg_def R27_H ( SOC, SOE, Op_RegI, 27, r27->as_VMReg()->next()); 137 reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread 138 reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next()); 139 reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp 140 reg_def R29_H ( NS, NS, Op_RegI, 29, r29->as_VMReg()->next()); 141 reg_def R30 ( NS, NS, Op_RegI, 30, r30->as_VMReg() ); // lr 142 reg_def R30_H ( NS, NS, Op_RegI, 30, r30->as_VMReg()->next()); 143 reg_def R31 ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg() ); // sp 144 reg_def R31_H ( NS, NS, Op_RegI, 31, r31_sp->as_VMReg()->next()); 145 146 // ---------------------------- 147 // Float/Double/Vector Registers 148 // ---------------------------- 149 150 // Double Registers 151 152 // The rules of ADL require that double registers be defined in pairs. 153 // Each pair must be two 32-bit values, but not necessarily a pair of 154 // single float registers. In each pair, ADLC-assigned register numbers 155 // must be adjacent, with the lower number even. Finally, when the 156 // CPU stores such a register pair to memory, the word associated with 157 // the lower ADLC-assigned number must be stored to the lower address. 158 159 // AArch64 has 32 floating-point registers. Each can store a vector of 160 // single or double precision floating-point values up to 8 * 32 161 // floats, 4 * 64 bit floats or 2 * 128 bit floats. We currently only 162 // use the first float or double element of the vector. 163 164 // for Java use float registers v0-v15 are always save on call whereas 165 // the platform ABI treats v8-v15 as callee save). float registers 166 // v16-v31 are SOC as per the platform spec 167 168 // For SVE vector registers, we simply extend vector register size to 8 169 // 'logical' slots. This is nominally 256 bits but it actually covers 170 // all possible 'physical' SVE vector register lengths from 128 ~ 2048 171 // bits. The 'physical' SVE vector register length is detected during 172 // startup, so the register allocator is able to identify the correct 173 // number of bytes needed for an SVE spill/unspill. 174 // Note that a vector register with 4 slots denotes a 128-bit NEON 175 // register allowing it to be distinguished from the corresponding SVE 176 // vector register when the SVE vector length is 128 bits. 177 178 reg_def V0 ( SOC, SOC, Op_RegF, 0, v0->as_VMReg() ); 179 reg_def V0_H ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next() ); 180 reg_def V0_J ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(2) ); 181 reg_def V0_K ( SOC, SOC, Op_RegF, 0, v0->as_VMReg()->next(3) ); 182 183 reg_def V1 ( SOC, SOC, Op_RegF, 1, v1->as_VMReg() ); 184 reg_def V1_H ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next() ); 185 reg_def V1_J ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(2) ); 186 reg_def V1_K ( SOC, SOC, Op_RegF, 1, v1->as_VMReg()->next(3) ); 187 188 reg_def V2 ( SOC, SOC, Op_RegF, 2, v2->as_VMReg() ); 189 reg_def V2_H ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next() ); 190 reg_def V2_J ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(2) ); 191 reg_def V2_K ( SOC, SOC, Op_RegF, 2, v2->as_VMReg()->next(3) ); 192 193 reg_def V3 ( SOC, SOC, Op_RegF, 3, v3->as_VMReg() ); 194 reg_def V3_H ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next() ); 195 reg_def V3_J ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(2) ); 196 reg_def V3_K ( SOC, SOC, Op_RegF, 3, v3->as_VMReg()->next(3) ); 197 198 reg_def V4 ( SOC, SOC, Op_RegF, 4, v4->as_VMReg() ); 199 reg_def V4_H ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next() ); 200 reg_def V4_J ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(2) ); 201 reg_def V4_K ( SOC, SOC, Op_RegF, 4, v4->as_VMReg()->next(3) ); 202 203 reg_def V5 ( SOC, SOC, Op_RegF, 5, v5->as_VMReg() ); 204 reg_def V5_H ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next() ); 205 reg_def V5_J ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(2) ); 206 reg_def V5_K ( SOC, SOC, Op_RegF, 5, v5->as_VMReg()->next(3) ); 207 208 reg_def V6 ( SOC, SOC, Op_RegF, 6, v6->as_VMReg() ); 209 reg_def V6_H ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next() ); 210 reg_def V6_J ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(2) ); 211 reg_def V6_K ( SOC, SOC, Op_RegF, 6, v6->as_VMReg()->next(3) ); 212 213 reg_def V7 ( SOC, SOC, Op_RegF, 7, v7->as_VMReg() ); 214 reg_def V7_H ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next() ); 215 reg_def V7_J ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(2) ); 216 reg_def V7_K ( SOC, SOC, Op_RegF, 7, v7->as_VMReg()->next(3) ); 217 218 reg_def V8 ( SOC, SOE, Op_RegF, 8, v8->as_VMReg() ); 219 reg_def V8_H ( SOC, SOE, Op_RegF, 8, v8->as_VMReg()->next() ); 220 reg_def V8_J ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(2) ); 221 reg_def V8_K ( SOC, SOC, Op_RegF, 8, v8->as_VMReg()->next(3) ); 222 223 reg_def V9 ( SOC, SOE, Op_RegF, 9, v9->as_VMReg() ); 224 reg_def V9_H ( SOC, SOE, Op_RegF, 9, v9->as_VMReg()->next() ); 225 reg_def V9_J ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(2) ); 226 reg_def V9_K ( SOC, SOC, Op_RegF, 9, v9->as_VMReg()->next(3) ); 227 228 reg_def V10 ( SOC, SOE, Op_RegF, 10, v10->as_VMReg() ); 229 reg_def V10_H ( SOC, SOE, Op_RegF, 10, v10->as_VMReg()->next() ); 230 reg_def V10_J ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(2) ); 231 reg_def V10_K ( SOC, SOC, Op_RegF, 10, v10->as_VMReg()->next(3) ); 232 233 reg_def V11 ( SOC, SOE, Op_RegF, 11, v11->as_VMReg() ); 234 reg_def V11_H ( SOC, SOE, Op_RegF, 11, v11->as_VMReg()->next() ); 235 reg_def V11_J ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(2) ); 236 reg_def V11_K ( SOC, SOC, Op_RegF, 11, v11->as_VMReg()->next(3) ); 237 238 reg_def V12 ( SOC, SOE, Op_RegF, 12, v12->as_VMReg() ); 239 reg_def V12_H ( SOC, SOE, Op_RegF, 12, v12->as_VMReg()->next() ); 240 reg_def V12_J ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(2) ); 241 reg_def V12_K ( SOC, SOC, Op_RegF, 12, v12->as_VMReg()->next(3) ); 242 243 reg_def V13 ( SOC, SOE, Op_RegF, 13, v13->as_VMReg() ); 244 reg_def V13_H ( SOC, SOE, Op_RegF, 13, v13->as_VMReg()->next() ); 245 reg_def V13_J ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(2) ); 246 reg_def V13_K ( SOC, SOC, Op_RegF, 13, v13->as_VMReg()->next(3) ); 247 248 reg_def V14 ( SOC, SOE, Op_RegF, 14, v14->as_VMReg() ); 249 reg_def V14_H ( SOC, SOE, Op_RegF, 14, v14->as_VMReg()->next() ); 250 reg_def V14_J ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(2) ); 251 reg_def V14_K ( SOC, SOC, Op_RegF, 14, v14->as_VMReg()->next(3) ); 252 253 reg_def V15 ( SOC, SOE, Op_RegF, 15, v15->as_VMReg() ); 254 reg_def V15_H ( SOC, SOE, Op_RegF, 15, v15->as_VMReg()->next() ); 255 reg_def V15_J ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(2) ); 256 reg_def V15_K ( SOC, SOC, Op_RegF, 15, v15->as_VMReg()->next(3) ); 257 258 reg_def V16 ( SOC, SOC, Op_RegF, 16, v16->as_VMReg() ); 259 reg_def V16_H ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next() ); 260 reg_def V16_J ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(2) ); 261 reg_def V16_K ( SOC, SOC, Op_RegF, 16, v16->as_VMReg()->next(3) ); 262 263 reg_def V17 ( SOC, SOC, Op_RegF, 17, v17->as_VMReg() ); 264 reg_def V17_H ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next() ); 265 reg_def V17_J ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(2) ); 266 reg_def V17_K ( SOC, SOC, Op_RegF, 17, v17->as_VMReg()->next(3) ); 267 268 reg_def V18 ( SOC, SOC, Op_RegF, 18, v18->as_VMReg() ); 269 reg_def V18_H ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next() ); 270 reg_def V18_J ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(2) ); 271 reg_def V18_K ( SOC, SOC, Op_RegF, 18, v18->as_VMReg()->next(3) ); 272 273 reg_def V19 ( SOC, SOC, Op_RegF, 19, v19->as_VMReg() ); 274 reg_def V19_H ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next() ); 275 reg_def V19_J ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(2) ); 276 reg_def V19_K ( SOC, SOC, Op_RegF, 19, v19->as_VMReg()->next(3) ); 277 278 reg_def V20 ( SOC, SOC, Op_RegF, 20, v20->as_VMReg() ); 279 reg_def V20_H ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next() ); 280 reg_def V20_J ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(2) ); 281 reg_def V20_K ( SOC, SOC, Op_RegF, 20, v20->as_VMReg()->next(3) ); 282 283 reg_def V21 ( SOC, SOC, Op_RegF, 21, v21->as_VMReg() ); 284 reg_def V21_H ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next() ); 285 reg_def V21_J ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(2) ); 286 reg_def V21_K ( SOC, SOC, Op_RegF, 21, v21->as_VMReg()->next(3) ); 287 288 reg_def V22 ( SOC, SOC, Op_RegF, 22, v22->as_VMReg() ); 289 reg_def V22_H ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next() ); 290 reg_def V22_J ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(2) ); 291 reg_def V22_K ( SOC, SOC, Op_RegF, 22, v22->as_VMReg()->next(3) ); 292 293 reg_def V23 ( SOC, SOC, Op_RegF, 23, v23->as_VMReg() ); 294 reg_def V23_H ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next() ); 295 reg_def V23_J ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(2) ); 296 reg_def V23_K ( SOC, SOC, Op_RegF, 23, v23->as_VMReg()->next(3) ); 297 298 reg_def V24 ( SOC, SOC, Op_RegF, 24, v24->as_VMReg() ); 299 reg_def V24_H ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next() ); 300 reg_def V24_J ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(2) ); 301 reg_def V24_K ( SOC, SOC, Op_RegF, 24, v24->as_VMReg()->next(3) ); 302 303 reg_def V25 ( SOC, SOC, Op_RegF, 25, v25->as_VMReg() ); 304 reg_def V25_H ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next() ); 305 reg_def V25_J ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(2) ); 306 reg_def V25_K ( SOC, SOC, Op_RegF, 25, v25->as_VMReg()->next(3) ); 307 308 reg_def V26 ( SOC, SOC, Op_RegF, 26, v26->as_VMReg() ); 309 reg_def V26_H ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next() ); 310 reg_def V26_J ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(2) ); 311 reg_def V26_K ( SOC, SOC, Op_RegF, 26, v26->as_VMReg()->next(3) ); 312 313 reg_def V27 ( SOC, SOC, Op_RegF, 27, v27->as_VMReg() ); 314 reg_def V27_H ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next() ); 315 reg_def V27_J ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(2) ); 316 reg_def V27_K ( SOC, SOC, Op_RegF, 27, v27->as_VMReg()->next(3) ); 317 318 reg_def V28 ( SOC, SOC, Op_RegF, 28, v28->as_VMReg() ); 319 reg_def V28_H ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next() ); 320 reg_def V28_J ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(2) ); 321 reg_def V28_K ( SOC, SOC, Op_RegF, 28, v28->as_VMReg()->next(3) ); 322 323 reg_def V29 ( SOC, SOC, Op_RegF, 29, v29->as_VMReg() ); 324 reg_def V29_H ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next() ); 325 reg_def V29_J ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(2) ); 326 reg_def V29_K ( SOC, SOC, Op_RegF, 29, v29->as_VMReg()->next(3) ); 327 328 reg_def V30 ( SOC, SOC, Op_RegF, 30, v30->as_VMReg() ); 329 reg_def V30_H ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next() ); 330 reg_def V30_J ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(2) ); 331 reg_def V30_K ( SOC, SOC, Op_RegF, 30, v30->as_VMReg()->next(3) ); 332 333 reg_def V31 ( SOC, SOC, Op_RegF, 31, v31->as_VMReg() ); 334 reg_def V31_H ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next() ); 335 reg_def V31_J ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(2) ); 336 reg_def V31_K ( SOC, SOC, Op_RegF, 31, v31->as_VMReg()->next(3) ); 337 338 // ---------------------------- 339 // SVE Predicate Registers 340 // ---------------------------- 341 reg_def P0 (SOC, SOC, Op_RegVectMask, 0, p0->as_VMReg()); 342 reg_def P1 (SOC, SOC, Op_RegVectMask, 1, p1->as_VMReg()); 343 reg_def P2 (SOC, SOC, Op_RegVectMask, 2, p2->as_VMReg()); 344 reg_def P3 (SOC, SOC, Op_RegVectMask, 3, p3->as_VMReg()); 345 reg_def P4 (SOC, SOC, Op_RegVectMask, 4, p4->as_VMReg()); 346 reg_def P5 (SOC, SOC, Op_RegVectMask, 5, p5->as_VMReg()); 347 reg_def P6 (SOC, SOC, Op_RegVectMask, 6, p6->as_VMReg()); 348 reg_def P7 (SOC, SOC, Op_RegVectMask, 7, p7->as_VMReg()); 349 reg_def P8 (SOC, SOC, Op_RegVectMask, 8, p8->as_VMReg()); 350 reg_def P9 (SOC, SOC, Op_RegVectMask, 9, p9->as_VMReg()); 351 reg_def P10 (SOC, SOC, Op_RegVectMask, 10, p10->as_VMReg()); 352 reg_def P11 (SOC, SOC, Op_RegVectMask, 11, p11->as_VMReg()); 353 reg_def P12 (SOC, SOC, Op_RegVectMask, 12, p12->as_VMReg()); 354 reg_def P13 (SOC, SOC, Op_RegVectMask, 13, p13->as_VMReg()); 355 reg_def P14 (SOC, SOC, Op_RegVectMask, 14, p14->as_VMReg()); 356 reg_def P15 (SOC, SOC, Op_RegVectMask, 15, p15->as_VMReg()); 357 358 // ---------------------------- 359 // Special Registers 360 // ---------------------------- 361 362 // the AArch64 CSPR status flag register is not directly accessible as 363 // instruction operand. the FPSR status flag register is a system 364 // register which can be written/read using MSR/MRS but again does not 365 // appear as an operand (a code identifying the FSPR occurs as an 366 // immediate value in the instruction). 367 368 reg_def RFLAGS(SOC, SOC, 0, 32, VMRegImpl::Bad()); 369 370 // Specify priority of register selection within phases of register 371 // allocation. Highest priority is first. A useful heuristic is to 372 // give registers a low priority when they are required by machine 373 // instructions, like EAX and EDX on I486, and choose no-save registers 374 // before save-on-call, & save-on-call before save-on-entry. Registers 375 // which participate in fixed calling sequences should come last. 376 // Registers which are used as pairs must fall on an even boundary. 377 378 alloc_class chunk0( 379 // volatiles 380 R10, R10_H, 381 R11, R11_H, 382 R12, R12_H, 383 R13, R13_H, 384 R14, R14_H, 385 R15, R15_H, 386 R16, R16_H, 387 R17, R17_H, 388 R18, R18_H, 389 390 // arg registers 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 400 // non-volatiles 401 R19, R19_H, 402 R20, R20_H, 403 R21, R21_H, 404 R22, R22_H, 405 R23, R23_H, 406 R24, R24_H, 407 R25, R25_H, 408 R26, R26_H, 409 410 // non-allocatable registers 411 412 R27, R27_H, // heapbase 413 R28, R28_H, // thread 414 R29, R29_H, // fp 415 R30, R30_H, // lr 416 R31, R31_H, // sp 417 R8, R8_H, // rscratch1 418 R9, R9_H, // rscratch2 419 ); 420 421 alloc_class chunk1( 422 423 // no save 424 V16, V16_H, V16_J, V16_K, 425 V17, V17_H, V17_J, V17_K, 426 V18, V18_H, V18_J, V18_K, 427 V19, V19_H, V19_J, V19_K, 428 V20, V20_H, V20_J, V20_K, 429 V21, V21_H, V21_J, V21_K, 430 V22, V22_H, V22_J, V22_K, 431 V23, V23_H, V23_J, V23_K, 432 V24, V24_H, V24_J, V24_K, 433 V25, V25_H, V25_J, V25_K, 434 V26, V26_H, V26_J, V26_K, 435 V27, V27_H, V27_J, V27_K, 436 V28, V28_H, V28_J, V28_K, 437 V29, V29_H, V29_J, V29_K, 438 V30, V30_H, V30_J, V30_K, 439 V31, V31_H, V31_J, V31_K, 440 441 // arg registers 442 V0, V0_H, V0_J, V0_K, 443 V1, V1_H, V1_J, V1_K, 444 V2, V2_H, V2_J, V2_K, 445 V3, V3_H, V3_J, V3_K, 446 V4, V4_H, V4_J, V4_K, 447 V5, V5_H, V5_J, V5_K, 448 V6, V6_H, V6_J, V6_K, 449 V7, V7_H, V7_J, V7_K, 450 451 // non-volatiles 452 V8, V8_H, V8_J, V8_K, 453 V9, V9_H, V9_J, V9_K, 454 V10, V10_H, V10_J, V10_K, 455 V11, V11_H, V11_J, V11_K, 456 V12, V12_H, V12_J, V12_K, 457 V13, V13_H, V13_J, V13_K, 458 V14, V14_H, V14_J, V14_K, 459 V15, V15_H, V15_J, V15_K, 460 ); 461 462 alloc_class chunk2 ( 463 // Governing predicates for load/store and arithmetic 464 P0, 465 P1, 466 P2, 467 P3, 468 P4, 469 P5, 470 P6, 471 472 // Extra predicates 473 P8, 474 P9, 475 P10, 476 P11, 477 P12, 478 P13, 479 P14, 480 P15, 481 482 // Preserved for all-true predicate 483 P7, 484 ); 485 486 alloc_class chunk3(RFLAGS); 487 488 //----------Architecture Description Register Classes-------------------------- 489 // Several register classes are automatically defined based upon information in 490 // this architecture description. 491 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 492 // 2) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 493 // 494 495 // Class for all 32 bit general purpose registers 496 reg_class all_reg32( 497 R0, 498 R1, 499 R2, 500 R3, 501 R4, 502 R5, 503 R6, 504 R7, 505 R10, 506 R11, 507 R12, 508 R13, 509 R14, 510 R15, 511 R16, 512 R17, 513 R18, 514 R19, 515 R20, 516 R21, 517 R22, 518 R23, 519 R24, 520 R25, 521 R26, 522 R27, 523 R28, 524 R29, 525 R30, 526 R31 527 ); 528 529 530 // Class for all 32 bit integer registers (excluding SP which 531 // will never be used as an integer register) 532 reg_class any_reg32 %{ 533 return _ANY_REG32_mask; 534 %} 535 536 // Singleton class for R0 int register 537 reg_class int_r0_reg(R0); 538 539 // Singleton class for R2 int register 540 reg_class int_r2_reg(R2); 541 542 // Singleton class for R3 int register 543 reg_class int_r3_reg(R3); 544 545 // Singleton class for R4 int register 546 reg_class int_r4_reg(R4); 547 548 // Singleton class for R31 int register 549 reg_class int_r31_reg(R31); 550 551 // Class for all 64 bit general purpose registers 552 reg_class all_reg( 553 R0, R0_H, 554 R1, R1_H, 555 R2, R2_H, 556 R3, R3_H, 557 R4, R4_H, 558 R5, R5_H, 559 R6, R6_H, 560 R7, R7_H, 561 R10, R10_H, 562 R11, R11_H, 563 R12, R12_H, 564 R13, R13_H, 565 R14, R14_H, 566 R15, R15_H, 567 R16, R16_H, 568 R17, R17_H, 569 R18, R18_H, 570 R19, R19_H, 571 R20, R20_H, 572 R21, R21_H, 573 R22, R22_H, 574 R23, R23_H, 575 R24, R24_H, 576 R25, R25_H, 577 R26, R26_H, 578 R27, R27_H, 579 R28, R28_H, 580 R29, R29_H, 581 R30, R30_H, 582 R31, R31_H 583 ); 584 585 // Class for all long integer registers (including SP) 586 reg_class any_reg %{ 587 return _ANY_REG_mask; 588 %} 589 590 // Class for non-allocatable 32 bit registers 591 reg_class non_allocatable_reg32( 592 #ifdef R18_RESERVED 593 // See comment in register_aarch64.hpp 594 R18, // tls on Windows 595 #endif 596 R28, // thread 597 R30, // lr 598 R31 // sp 599 ); 600 601 // Class for non-allocatable 64 bit registers 602 reg_class non_allocatable_reg( 603 #ifdef R18_RESERVED 604 // See comment in register_aarch64.hpp 605 R18, R18_H, // tls on Windows, platform register on macOS 606 #endif 607 R28, R28_H, // thread 608 R30, R30_H, // lr 609 R31, R31_H // sp 610 ); 611 612 // Class for all non-special integer registers 613 reg_class no_special_reg32 %{ 614 return _NO_SPECIAL_REG32_mask; 615 %} 616 617 // Class for all non-special long integer registers 618 reg_class no_special_reg %{ 619 return _NO_SPECIAL_REG_mask; 620 %} 621 622 // Class for 64 bit register r0 623 reg_class r0_reg( 624 R0, R0_H 625 ); 626 627 // Class for 64 bit register r1 628 reg_class r1_reg( 629 R1, R1_H 630 ); 631 632 // Class for 64 bit register r2 633 reg_class r2_reg( 634 R2, R2_H 635 ); 636 637 // Class for 64 bit register r3 638 reg_class r3_reg( 639 R3, R3_H 640 ); 641 642 // Class for 64 bit register r4 643 reg_class r4_reg( 644 R4, R4_H 645 ); 646 647 // Class for 64 bit register r5 648 reg_class r5_reg( 649 R5, R5_H 650 ); 651 652 // Class for 64 bit register r10 653 reg_class r10_reg( 654 R10, R10_H 655 ); 656 657 // Class for 64 bit register r11 658 reg_class r11_reg( 659 R11, R11_H 660 ); 661 662 // Class for method register 663 reg_class method_reg( 664 R12, R12_H 665 ); 666 667 // Class for thread register 668 reg_class thread_reg( 669 R28, R28_H 670 ); 671 672 // Class for frame pointer register 673 reg_class fp_reg( 674 R29, R29_H 675 ); 676 677 // Class for link register 678 reg_class lr_reg( 679 R30, R30_H 680 ); 681 682 // Class for long sp register 683 reg_class sp_reg( 684 R31, R31_H 685 ); 686 687 // Class for all pointer registers 688 reg_class ptr_reg %{ 689 return _PTR_REG_mask; 690 %} 691 692 // Class for all non_special pointer registers 693 reg_class no_special_ptr_reg %{ 694 return _NO_SPECIAL_PTR_REG_mask; 695 %} 696 697 // Class for all float registers 698 reg_class float_reg( 699 V0, 700 V1, 701 V2, 702 V3, 703 V4, 704 V5, 705 V6, 706 V7, 707 V8, 708 V9, 709 V10, 710 V11, 711 V12, 712 V13, 713 V14, 714 V15, 715 V16, 716 V17, 717 V18, 718 V19, 719 V20, 720 V21, 721 V22, 722 V23, 723 V24, 724 V25, 725 V26, 726 V27, 727 V28, 728 V29, 729 V30, 730 V31 731 ); 732 733 // Double precision float registers have virtual `high halves' that 734 // are needed by the allocator. 735 // Class for all double registers 736 reg_class double_reg( 737 V0, V0_H, 738 V1, V1_H, 739 V2, V2_H, 740 V3, V3_H, 741 V4, V4_H, 742 V5, V5_H, 743 V6, V6_H, 744 V7, V7_H, 745 V8, V8_H, 746 V9, V9_H, 747 V10, V10_H, 748 V11, V11_H, 749 V12, V12_H, 750 V13, V13_H, 751 V14, V14_H, 752 V15, V15_H, 753 V16, V16_H, 754 V17, V17_H, 755 V18, V18_H, 756 V19, V19_H, 757 V20, V20_H, 758 V21, V21_H, 759 V22, V22_H, 760 V23, V23_H, 761 V24, V24_H, 762 V25, V25_H, 763 V26, V26_H, 764 V27, V27_H, 765 V28, V28_H, 766 V29, V29_H, 767 V30, V30_H, 768 V31, V31_H 769 ); 770 771 // Class for all SVE vector registers. 772 reg_class vectora_reg ( 773 V0, V0_H, V0_J, V0_K, 774 V1, V1_H, V1_J, V1_K, 775 V2, V2_H, V2_J, V2_K, 776 V3, V3_H, V3_J, V3_K, 777 V4, V4_H, V4_J, V4_K, 778 V5, V5_H, V5_J, V5_K, 779 V6, V6_H, V6_J, V6_K, 780 V7, V7_H, V7_J, V7_K, 781 V8, V8_H, V8_J, V8_K, 782 V9, V9_H, V9_J, V9_K, 783 V10, V10_H, V10_J, V10_K, 784 V11, V11_H, V11_J, V11_K, 785 V12, V12_H, V12_J, V12_K, 786 V13, V13_H, V13_J, V13_K, 787 V14, V14_H, V14_J, V14_K, 788 V15, V15_H, V15_J, V15_K, 789 V16, V16_H, V16_J, V16_K, 790 V17, V17_H, V17_J, V17_K, 791 V18, V18_H, V18_J, V18_K, 792 V19, V19_H, V19_J, V19_K, 793 V20, V20_H, V20_J, V20_K, 794 V21, V21_H, V21_J, V21_K, 795 V22, V22_H, V22_J, V22_K, 796 V23, V23_H, V23_J, V23_K, 797 V24, V24_H, V24_J, V24_K, 798 V25, V25_H, V25_J, V25_K, 799 V26, V26_H, V26_J, V26_K, 800 V27, V27_H, V27_J, V27_K, 801 V28, V28_H, V28_J, V28_K, 802 V29, V29_H, V29_J, V29_K, 803 V30, V30_H, V30_J, V30_K, 804 V31, V31_H, V31_J, V31_K, 805 ); 806 807 // Class for all 64bit vector registers 808 reg_class vectord_reg( 809 V0, V0_H, 810 V1, V1_H, 811 V2, V2_H, 812 V3, V3_H, 813 V4, V4_H, 814 V5, V5_H, 815 V6, V6_H, 816 V7, V7_H, 817 V8, V8_H, 818 V9, V9_H, 819 V10, V10_H, 820 V11, V11_H, 821 V12, V12_H, 822 V13, V13_H, 823 V14, V14_H, 824 V15, V15_H, 825 V16, V16_H, 826 V17, V17_H, 827 V18, V18_H, 828 V19, V19_H, 829 V20, V20_H, 830 V21, V21_H, 831 V22, V22_H, 832 V23, V23_H, 833 V24, V24_H, 834 V25, V25_H, 835 V26, V26_H, 836 V27, V27_H, 837 V28, V28_H, 838 V29, V29_H, 839 V30, V30_H, 840 V31, V31_H 841 ); 842 843 // Class for all 128bit vector registers 844 reg_class vectorx_reg( 845 V0, V0_H, V0_J, V0_K, 846 V1, V1_H, V1_J, V1_K, 847 V2, V2_H, V2_J, V2_K, 848 V3, V3_H, V3_J, V3_K, 849 V4, V4_H, V4_J, V4_K, 850 V5, V5_H, V5_J, V5_K, 851 V6, V6_H, V6_J, V6_K, 852 V7, V7_H, V7_J, V7_K, 853 V8, V8_H, V8_J, V8_K, 854 V9, V9_H, V9_J, V9_K, 855 V10, V10_H, V10_J, V10_K, 856 V11, V11_H, V11_J, V11_K, 857 V12, V12_H, V12_J, V12_K, 858 V13, V13_H, V13_J, V13_K, 859 V14, V14_H, V14_J, V14_K, 860 V15, V15_H, V15_J, V15_K, 861 V16, V16_H, V16_J, V16_K, 862 V17, V17_H, V17_J, V17_K, 863 V18, V18_H, V18_J, V18_K, 864 V19, V19_H, V19_J, V19_K, 865 V20, V20_H, V20_J, V20_K, 866 V21, V21_H, V21_J, V21_K, 867 V22, V22_H, V22_J, V22_K, 868 V23, V23_H, V23_J, V23_K, 869 V24, V24_H, V24_J, V24_K, 870 V25, V25_H, V25_J, V25_K, 871 V26, V26_H, V26_J, V26_K, 872 V27, V27_H, V27_J, V27_K, 873 V28, V28_H, V28_J, V28_K, 874 V29, V29_H, V29_J, V29_K, 875 V30, V30_H, V30_J, V30_K, 876 V31, V31_H, V31_J, V31_K 877 ); 878 879 // Class for 128 bit register v0 880 reg_class v0_reg( 881 V0, V0_H 882 ); 883 884 // Class for 128 bit register v1 885 reg_class v1_reg( 886 V1, V1_H 887 ); 888 889 // Class for 128 bit register v2 890 reg_class v2_reg( 891 V2, V2_H 892 ); 893 894 // Class for 128 bit register v3 895 reg_class v3_reg( 896 V3, V3_H 897 ); 898 899 // Class for 128 bit register v4 900 reg_class v4_reg( 901 V4, V4_H 902 ); 903 904 // Class for 128 bit register v5 905 reg_class v5_reg( 906 V5, V5_H 907 ); 908 909 // Class for 128 bit register v6 910 reg_class v6_reg( 911 V6, V6_H 912 ); 913 914 // Class for 128 bit register v7 915 reg_class v7_reg( 916 V7, V7_H 917 ); 918 919 // Class for 128 bit register v8 920 reg_class v8_reg( 921 V8, V8_H 922 ); 923 924 // Class for 128 bit register v9 925 reg_class v9_reg( 926 V9, V9_H 927 ); 928 929 // Class for 128 bit register v10 930 reg_class v10_reg( 931 V10, V10_H 932 ); 933 934 // Class for 128 bit register v11 935 reg_class v11_reg( 936 V11, V11_H 937 ); 938 939 // Class for 128 bit register v12 940 reg_class v12_reg( 941 V12, V12_H 942 ); 943 944 // Class for 128 bit register v13 945 reg_class v13_reg( 946 V13, V13_H 947 ); 948 949 // Class for 128 bit register v14 950 reg_class v14_reg( 951 V14, V14_H 952 ); 953 954 // Class for 128 bit register v15 955 reg_class v15_reg( 956 V15, V15_H 957 ); 958 959 // Class for 128 bit register v16 960 reg_class v16_reg( 961 V16, V16_H 962 ); 963 964 // Class for 128 bit register v17 965 reg_class v17_reg( 966 V17, V17_H 967 ); 968 969 // Class for 128 bit register v18 970 reg_class v18_reg( 971 V18, V18_H 972 ); 973 974 // Class for 128 bit register v19 975 reg_class v19_reg( 976 V19, V19_H 977 ); 978 979 // Class for 128 bit register v20 980 reg_class v20_reg( 981 V20, V20_H 982 ); 983 984 // Class for 128 bit register v21 985 reg_class v21_reg( 986 V21, V21_H 987 ); 988 989 // Class for 128 bit register v22 990 reg_class v22_reg( 991 V22, V22_H 992 ); 993 994 // Class for 128 bit register v23 995 reg_class v23_reg( 996 V23, V23_H 997 ); 998 999 // Class for 128 bit register v24 1000 reg_class v24_reg( 1001 V24, V24_H 1002 ); 1003 1004 // Class for 128 bit register v25 1005 reg_class v25_reg( 1006 V25, V25_H 1007 ); 1008 1009 // Class for 128 bit register v26 1010 reg_class v26_reg( 1011 V26, V26_H 1012 ); 1013 1014 // Class for 128 bit register v27 1015 reg_class v27_reg( 1016 V27, V27_H 1017 ); 1018 1019 // Class for 128 bit register v28 1020 reg_class v28_reg( 1021 V28, V28_H 1022 ); 1023 1024 // Class for 128 bit register v29 1025 reg_class v29_reg( 1026 V29, V29_H 1027 ); 1028 1029 // Class for 128 bit register v30 1030 reg_class v30_reg( 1031 V30, V30_H 1032 ); 1033 1034 // Class for 128 bit register v31 1035 reg_class v31_reg( 1036 V31, V31_H 1037 ); 1038 1039 // Class for all SVE predicate registers. 1040 reg_class pr_reg ( 1041 P0, 1042 P1, 1043 P2, 1044 P3, 1045 P4, 1046 P5, 1047 P6, 1048 // P7, non-allocatable, preserved with all elements preset to TRUE. 1049 P8, 1050 P9, 1051 P10, 1052 P11, 1053 P12, 1054 P13, 1055 P14, 1056 P15 1057 ); 1058 1059 // Class for SVE governing predicate registers, which are used 1060 // to determine the active elements of a predicated instruction. 1061 reg_class gov_pr ( 1062 P0, 1063 P1, 1064 P2, 1065 P3, 1066 P4, 1067 P5, 1068 P6, 1069 // P7, non-allocatable, preserved with all elements preset to TRUE. 1070 ); 1071 1072 reg_class p0_reg(P0); 1073 reg_class p1_reg(P1); 1074 1075 // Singleton class for condition codes 1076 reg_class int_flags(RFLAGS); 1077 1078 %} 1079 1080 //----------DEFINITION BLOCK--------------------------------------------------- 1081 // Define name --> value mappings to inform the ADLC of an integer valued name 1082 // Current support includes integer values in the range [0, 0x7FFFFFFF] 1083 // Format: 1084 // int_def <name> ( <int_value>, <expression>); 1085 // Generated Code in ad_<arch>.hpp 1086 // #define <name> (<expression>) 1087 // // value == <int_value> 1088 // Generated code in ad_<arch>.cpp adlc_verification() 1089 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 1090 // 1091 1092 // we follow the ppc-aix port in using a simple cost model which ranks 1093 // register operations as cheap, memory ops as more expensive and 1094 // branches as most expensive. the first two have a low as well as a 1095 // normal cost. huge cost appears to be a way of saying don't do 1096 // something 1097 1098 definitions %{ 1099 // The default cost (of a register move instruction). 1100 int_def INSN_COST ( 100, 100); 1101 int_def BRANCH_COST ( 200, 2 * INSN_COST); 1102 int_def CALL_COST ( 200, 2 * INSN_COST); 1103 int_def VOLATILE_REF_COST ( 1000, 10 * INSN_COST); 1104 %} 1105 1106 1107 //----------SOURCE BLOCK------------------------------------------------------- 1108 // This is a block of C++ code which provides values, functions, and 1109 // definitions necessary in the rest of the architecture description 1110 1111 source_hpp %{ 1112 1113 #include "asm/macroAssembler.hpp" 1114 #include "gc/shared/barrierSetAssembler.hpp" 1115 #include "gc/shared/cardTable.hpp" 1116 #include "gc/shared/cardTableBarrierSet.hpp" 1117 #include "gc/shared/collectedHeap.hpp" 1118 #include "opto/addnode.hpp" 1119 #include "opto/convertnode.hpp" 1120 #include "runtime/objectMonitor.hpp" 1121 1122 extern RegMask _ANY_REG32_mask; 1123 extern RegMask _ANY_REG_mask; 1124 extern RegMask _PTR_REG_mask; 1125 extern RegMask _NO_SPECIAL_REG32_mask; 1126 extern RegMask _NO_SPECIAL_REG_mask; 1127 extern RegMask _NO_SPECIAL_PTR_REG_mask; 1128 1129 class CallStubImpl { 1130 1131 //-------------------------------------------------------------- 1132 //---< Used for optimization in Compile::shorten_branches >--- 1133 //-------------------------------------------------------------- 1134 1135 public: 1136 // Size of call trampoline stub. 1137 static uint size_call_trampoline() { 1138 return 0; // no call trampolines on this platform 1139 } 1140 1141 // number of relocations needed by a call trampoline stub 1142 static uint reloc_call_trampoline() { 1143 return 0; // no call trampolines on this platform 1144 } 1145 }; 1146 1147 class HandlerImpl { 1148 1149 public: 1150 1151 static int emit_exception_handler(CodeBuffer &cbuf); 1152 static int emit_deopt_handler(CodeBuffer& cbuf); 1153 1154 static uint size_exception_handler() { 1155 return MacroAssembler::far_codestub_branch_size(); 1156 } 1157 1158 static uint size_deopt_handler() { 1159 // count one adr and one far branch instruction 1160 return NativeInstruction::instruction_size + MacroAssembler::far_codestub_branch_size(); 1161 } 1162 }; 1163 1164 class Node::PD { 1165 public: 1166 enum NodeFlags { 1167 _last_flag = Node::_last_flag 1168 }; 1169 }; 1170 1171 bool is_CAS(int opcode, bool maybe_volatile); 1172 1173 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb 1174 1175 bool unnecessary_acquire(const Node *barrier); 1176 bool needs_acquiring_load(const Node *load); 1177 1178 // predicates controlling emit of str<x>/stlr<x> and associated dmbs 1179 1180 bool unnecessary_release(const Node *barrier); 1181 bool unnecessary_volatile(const Node *barrier); 1182 bool needs_releasing_store(const Node *store); 1183 1184 // predicate controlling translation of CompareAndSwapX 1185 bool needs_acquiring_load_exclusive(const Node *load); 1186 1187 // predicate controlling addressing modes 1188 bool size_fits_all_mem_uses(AddPNode* addp, int shift); 1189 1190 // Convert BootTest condition to Assembler condition. 1191 // Replicate the logic of cmpOpOper::ccode() and cmpOpUOper::ccode(). 1192 Assembler::Condition to_assembler_cond(BoolTest::mask cond); 1193 %} 1194 1195 source %{ 1196 1197 // Derived RegMask with conditionally allocatable registers 1198 1199 void PhaseOutput::pd_perform_mach_node_analysis() { 1200 } 1201 1202 int MachNode::pd_alignment_required() const { 1203 return 1; 1204 } 1205 1206 int MachNode::compute_padding(int current_offset) const { 1207 return 0; 1208 } 1209 1210 RegMask _ANY_REG32_mask; 1211 RegMask _ANY_REG_mask; 1212 RegMask _PTR_REG_mask; 1213 RegMask _NO_SPECIAL_REG32_mask; 1214 RegMask _NO_SPECIAL_REG_mask; 1215 RegMask _NO_SPECIAL_PTR_REG_mask; 1216 1217 void reg_mask_init() { 1218 // We derive below RegMask(s) from the ones which are auto-generated from 1219 // adlc register classes to make AArch64 rheapbase (r27) and rfp (r29) 1220 // registers conditionally reserved. 1221 1222 _ANY_REG32_mask = _ALL_REG32_mask; 1223 _ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg())); 1224 1225 _ANY_REG_mask = _ALL_REG_mask; 1226 1227 _PTR_REG_mask = _ALL_REG_mask; 1228 1229 _NO_SPECIAL_REG32_mask = _ALL_REG32_mask; 1230 _NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask); 1231 1232 _NO_SPECIAL_REG_mask = _ALL_REG_mask; 1233 _NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1234 1235 _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask; 1236 _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); 1237 1238 // r27 is not allocatable when compressed oops is on and heapbase is not 1239 // zero, compressed klass pointers doesn't use r27 after JDK-8234794 1240 if (UseCompressedOops && (CompressedOops::ptrs_base() != nullptr)) { 1241 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); 1242 _NO_SPECIAL_REG_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); 1243 _NO_SPECIAL_PTR_REG_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); 1244 } 1245 1246 // r29 is not allocatable when PreserveFramePointer is on 1247 if (PreserveFramePointer) { 1248 _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1249 _NO_SPECIAL_REG_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1250 _NO_SPECIAL_PTR_REG_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg())); 1251 } 1252 } 1253 1254 // Optimizaton of volatile gets and puts 1255 // ------------------------------------- 1256 // 1257 // AArch64 has ldar<x> and stlr<x> instructions which we can safely 1258 // use to implement volatile reads and writes. For a volatile read 1259 // we simply need 1260 // 1261 // ldar<x> 1262 // 1263 // and for a volatile write we need 1264 // 1265 // stlr<x> 1266 // 1267 // Alternatively, we can implement them by pairing a normal 1268 // load/store with a memory barrier. For a volatile read we need 1269 // 1270 // ldr<x> 1271 // dmb ishld 1272 // 1273 // for a volatile write 1274 // 1275 // dmb ish 1276 // str<x> 1277 // dmb ish 1278 // 1279 // We can also use ldaxr and stlxr to implement compare and swap CAS 1280 // sequences. These are normally translated to an instruction 1281 // sequence like the following 1282 // 1283 // dmb ish 1284 // retry: 1285 // ldxr<x> rval raddr 1286 // cmp rval rold 1287 // b.ne done 1288 // stlxr<x> rval, rnew, rold 1289 // cbnz rval retry 1290 // done: 1291 // cset r0, eq 1292 // dmb ishld 1293 // 1294 // Note that the exclusive store is already using an stlxr 1295 // instruction. That is required to ensure visibility to other 1296 // threads of the exclusive write (assuming it succeeds) before that 1297 // of any subsequent writes. 1298 // 1299 // The following instruction sequence is an improvement on the above 1300 // 1301 // retry: 1302 // ldaxr<x> rval raddr 1303 // cmp rval rold 1304 // b.ne done 1305 // stlxr<x> rval, rnew, rold 1306 // cbnz rval retry 1307 // done: 1308 // cset r0, eq 1309 // 1310 // We don't need the leading dmb ish since the stlxr guarantees 1311 // visibility of prior writes in the case that the swap is 1312 // successful. Crucially we don't have to worry about the case where 1313 // the swap is not successful since no valid program should be 1314 // relying on visibility of prior changes by the attempting thread 1315 // in the case where the CAS fails. 1316 // 1317 // Similarly, we don't need the trailing dmb ishld if we substitute 1318 // an ldaxr instruction since that will provide all the guarantees we 1319 // require regarding observation of changes made by other threads 1320 // before any change to the CAS address observed by the load. 1321 // 1322 // In order to generate the desired instruction sequence we need to 1323 // be able to identify specific 'signature' ideal graph node 1324 // sequences which i) occur as a translation of a volatile reads or 1325 // writes or CAS operations and ii) do not occur through any other 1326 // translation or graph transformation. We can then provide 1327 // alternative aldc matching rules which translate these node 1328 // sequences to the desired machine code sequences. Selection of the 1329 // alternative rules can be implemented by predicates which identify 1330 // the relevant node sequences. 1331 // 1332 // The ideal graph generator translates a volatile read to the node 1333 // sequence 1334 // 1335 // LoadX[mo_acquire] 1336 // MemBarAcquire 1337 // 1338 // As a special case when using the compressed oops optimization we 1339 // may also see this variant 1340 // 1341 // LoadN[mo_acquire] 1342 // DecodeN 1343 // MemBarAcquire 1344 // 1345 // A volatile write is translated to the node sequence 1346 // 1347 // MemBarRelease 1348 // StoreX[mo_release] {CardMark}-optional 1349 // MemBarVolatile 1350 // 1351 // n.b. the above node patterns are generated with a strict 1352 // 'signature' configuration of input and output dependencies (see 1353 // the predicates below for exact details). The card mark may be as 1354 // simple as a few extra nodes or, in a few GC configurations, may 1355 // include more complex control flow between the leading and 1356 // trailing memory barriers. However, whatever the card mark 1357 // configuration these signatures are unique to translated volatile 1358 // reads/stores -- they will not appear as a result of any other 1359 // bytecode translation or inlining nor as a consequence of 1360 // optimizing transforms. 1361 // 1362 // We also want to catch inlined unsafe volatile gets and puts and 1363 // be able to implement them using either ldar<x>/stlr<x> or some 1364 // combination of ldr<x>/stlr<x> and dmb instructions. 1365 // 1366 // Inlined unsafe volatiles puts manifest as a minor variant of the 1367 // normal volatile put node sequence containing an extra cpuorder 1368 // membar 1369 // 1370 // MemBarRelease 1371 // MemBarCPUOrder 1372 // StoreX[mo_release] {CardMark}-optional 1373 // MemBarCPUOrder 1374 // MemBarVolatile 1375 // 1376 // n.b. as an aside, a cpuorder membar is not itself subject to 1377 // matching and translation by adlc rules. However, the rule 1378 // predicates need to detect its presence in order to correctly 1379 // select the desired adlc rules. 1380 // 1381 // Inlined unsafe volatile gets manifest as a slightly different 1382 // node sequence to a normal volatile get because of the 1383 // introduction of some CPUOrder memory barriers to bracket the 1384 // Load. However, but the same basic skeleton of a LoadX feeding a 1385 // MemBarAcquire, possibly through an optional DecodeN, is still 1386 // present 1387 // 1388 // MemBarCPUOrder 1389 // || \\ 1390 // MemBarCPUOrder LoadX[mo_acquire] 1391 // || | 1392 // || {DecodeN} optional 1393 // || / 1394 // MemBarAcquire 1395 // 1396 // In this case the acquire membar does not directly depend on the 1397 // load. However, we can be sure that the load is generated from an 1398 // inlined unsafe volatile get if we see it dependent on this unique 1399 // sequence of membar nodes. Similarly, given an acquire membar we 1400 // can know that it was added because of an inlined unsafe volatile 1401 // get if it is fed and feeds a cpuorder membar and if its feed 1402 // membar also feeds an acquiring load. 1403 // 1404 // Finally an inlined (Unsafe) CAS operation is translated to the 1405 // following ideal graph 1406 // 1407 // MemBarRelease 1408 // MemBarCPUOrder 1409 // CompareAndSwapX {CardMark}-optional 1410 // MemBarCPUOrder 1411 // MemBarAcquire 1412 // 1413 // So, where we can identify these volatile read and write 1414 // signatures we can choose to plant either of the above two code 1415 // sequences. For a volatile read we can simply plant a normal 1416 // ldr<x> and translate the MemBarAcquire to a dmb. However, we can 1417 // also choose to inhibit translation of the MemBarAcquire and 1418 // inhibit planting of the ldr<x>, instead planting an ldar<x>. 1419 // 1420 // When we recognise a volatile store signature we can choose to 1421 // plant at a dmb ish as a translation for the MemBarRelease, a 1422 // normal str<x> and then a dmb ish for the MemBarVolatile. 1423 // Alternatively, we can inhibit translation of the MemBarRelease 1424 // and MemBarVolatile and instead plant a simple stlr<x> 1425 // instruction. 1426 // 1427 // when we recognise a CAS signature we can choose to plant a dmb 1428 // ish as a translation for the MemBarRelease, the conventional 1429 // macro-instruction sequence for the CompareAndSwap node (which 1430 // uses ldxr<x>) and then a dmb ishld for the MemBarAcquire. 1431 // Alternatively, we can elide generation of the dmb instructions 1432 // and plant the alternative CompareAndSwap macro-instruction 1433 // sequence (which uses ldaxr<x>). 1434 // 1435 // Of course, the above only applies when we see these signature 1436 // configurations. We still want to plant dmb instructions in any 1437 // other cases where we may see a MemBarAcquire, MemBarRelease or 1438 // MemBarVolatile. For example, at the end of a constructor which 1439 // writes final/volatile fields we will see a MemBarRelease 1440 // instruction and this needs a 'dmb ish' lest we risk the 1441 // constructed object being visible without making the 1442 // final/volatile field writes visible. 1443 // 1444 // n.b. the translation rules below which rely on detection of the 1445 // volatile signatures and insert ldar<x> or stlr<x> are failsafe. 1446 // If we see anything other than the signature configurations we 1447 // always just translate the loads and stores to ldr<x> and str<x> 1448 // and translate acquire, release and volatile membars to the 1449 // relevant dmb instructions. 1450 // 1451 1452 // is_CAS(int opcode, bool maybe_volatile) 1453 // 1454 // return true if opcode is one of the possible CompareAndSwapX 1455 // values otherwise false. 1456 1457 bool is_CAS(int opcode, bool maybe_volatile) 1458 { 1459 switch(opcode) { 1460 // We handle these 1461 case Op_CompareAndSwapI: 1462 case Op_CompareAndSwapL: 1463 case Op_CompareAndSwapP: 1464 case Op_CompareAndSwapN: 1465 case Op_ShenandoahCompareAndSwapP: 1466 case Op_ShenandoahCompareAndSwapN: 1467 case Op_CompareAndSwapB: 1468 case Op_CompareAndSwapS: 1469 case Op_GetAndSetI: 1470 case Op_GetAndSetL: 1471 case Op_GetAndSetP: 1472 case Op_GetAndSetN: 1473 case Op_GetAndAddI: 1474 case Op_GetAndAddL: 1475 return true; 1476 case Op_CompareAndExchangeI: 1477 case Op_CompareAndExchangeN: 1478 case Op_CompareAndExchangeB: 1479 case Op_CompareAndExchangeS: 1480 case Op_CompareAndExchangeL: 1481 case Op_CompareAndExchangeP: 1482 case Op_WeakCompareAndSwapB: 1483 case Op_WeakCompareAndSwapS: 1484 case Op_WeakCompareAndSwapI: 1485 case Op_WeakCompareAndSwapL: 1486 case Op_WeakCompareAndSwapP: 1487 case Op_WeakCompareAndSwapN: 1488 case Op_ShenandoahWeakCompareAndSwapP: 1489 case Op_ShenandoahWeakCompareAndSwapN: 1490 case Op_ShenandoahCompareAndExchangeP: 1491 case Op_ShenandoahCompareAndExchangeN: 1492 return maybe_volatile; 1493 default: 1494 return false; 1495 } 1496 } 1497 1498 // helper to determine the maximum number of Phi nodes we may need to 1499 // traverse when searching from a card mark membar for the merge mem 1500 // feeding a trailing membar or vice versa 1501 1502 // predicates controlling emit of ldr<x>/ldar<x> 1503 1504 bool unnecessary_acquire(const Node *barrier) 1505 { 1506 assert(barrier->is_MemBar(), "expecting a membar"); 1507 1508 MemBarNode* mb = barrier->as_MemBar(); 1509 1510 if (mb->trailing_load()) { 1511 return true; 1512 } 1513 1514 if (mb->trailing_load_store()) { 1515 Node* load_store = mb->in(MemBarNode::Precedent); 1516 assert(load_store->is_LoadStore(), "unexpected graph shape"); 1517 return is_CAS(load_store->Opcode(), true); 1518 } 1519 1520 return false; 1521 } 1522 1523 bool needs_acquiring_load(const Node *n) 1524 { 1525 assert(n->is_Load(), "expecting a load"); 1526 LoadNode *ld = n->as_Load(); 1527 return ld->is_acquire(); 1528 } 1529 1530 bool unnecessary_release(const Node *n) 1531 { 1532 assert((n->is_MemBar() && 1533 n->Opcode() == Op_MemBarRelease), 1534 "expecting a release membar"); 1535 1536 MemBarNode *barrier = n->as_MemBar(); 1537 if (!barrier->leading()) { 1538 return false; 1539 } else { 1540 Node* trailing = barrier->trailing_membar(); 1541 MemBarNode* trailing_mb = trailing->as_MemBar(); 1542 assert(trailing_mb->trailing(), "Not a trailing membar?"); 1543 assert(trailing_mb->leading_membar() == n, "inconsistent leading/trailing membars"); 1544 1545 Node* mem = trailing_mb->in(MemBarNode::Precedent); 1546 if (mem->is_Store()) { 1547 assert(mem->as_Store()->is_release(), ""); 1548 assert(trailing_mb->Opcode() == Op_MemBarVolatile, ""); 1549 return true; 1550 } else { 1551 assert(mem->is_LoadStore(), ""); 1552 assert(trailing_mb->Opcode() == Op_MemBarAcquire, ""); 1553 return is_CAS(mem->Opcode(), true); 1554 } 1555 } 1556 return false; 1557 } 1558 1559 bool unnecessary_volatile(const Node *n) 1560 { 1561 // assert n->is_MemBar(); 1562 MemBarNode *mbvol = n->as_MemBar(); 1563 1564 bool release = mbvol->trailing_store(); 1565 assert(!release || (mbvol->in(MemBarNode::Precedent)->is_Store() && mbvol->in(MemBarNode::Precedent)->as_Store()->is_release()), ""); 1566 #ifdef ASSERT 1567 if (release) { 1568 Node* leading = mbvol->leading_membar(); 1569 assert(leading->Opcode() == Op_MemBarRelease, ""); 1570 assert(leading->as_MemBar()->leading_store(), ""); 1571 assert(leading->as_MemBar()->trailing_membar() == mbvol, ""); 1572 } 1573 #endif 1574 1575 return release; 1576 } 1577 1578 // predicates controlling emit of str<x>/stlr<x> 1579 1580 bool needs_releasing_store(const Node *n) 1581 { 1582 // assert n->is_Store(); 1583 StoreNode *st = n->as_Store(); 1584 return st->trailing_membar() != nullptr; 1585 } 1586 1587 // predicate controlling translation of CAS 1588 // 1589 // returns true if CAS needs to use an acquiring load otherwise false 1590 1591 bool needs_acquiring_load_exclusive(const Node *n) 1592 { 1593 assert(is_CAS(n->Opcode(), true), "expecting a compare and swap"); 1594 LoadStoreNode* ldst = n->as_LoadStore(); 1595 if (is_CAS(n->Opcode(), false)) { 1596 assert(ldst->trailing_membar() != nullptr, "expected trailing membar"); 1597 } else { 1598 return ldst->trailing_membar() != nullptr; 1599 } 1600 1601 // so we can just return true here 1602 return true; 1603 } 1604 1605 #define __ _masm. 1606 1607 // advance declarations for helper functions to convert register 1608 // indices to register objects 1609 1610 // the ad file has to provide implementations of certain methods 1611 // expected by the generic code 1612 // 1613 // REQUIRED FUNCTIONALITY 1614 1615 //============================================================================= 1616 1617 // !!!!! Special hack to get all types of calls to specify the byte offset 1618 // from the start of the call to the point where the return address 1619 // will point. 1620 1621 int MachCallStaticJavaNode::ret_addr_offset() 1622 { 1623 // call should be a simple bl 1624 int off = 4; 1625 return off; 1626 } 1627 1628 int MachCallDynamicJavaNode::ret_addr_offset() 1629 { 1630 return 16; // movz, movk, movk, bl 1631 } 1632 1633 int MachCallRuntimeNode::ret_addr_offset() { 1634 // for generated stubs the call will be 1635 // bl(addr) 1636 // or with far branches 1637 // bl(trampoline_stub) 1638 // for real runtime callouts it will be six instructions 1639 // see aarch64_enc_java_to_runtime 1640 // adr(rscratch2, retaddr) 1641 // lea(rscratch1, RuntimeAddress(addr) 1642 // stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))) 1643 // blr(rscratch1) 1644 CodeBlob *cb = CodeCache::find_blob(_entry_point); 1645 if (cb) { 1646 return 1 * NativeInstruction::instruction_size; 1647 } else if (_entry_point == nullptr) { 1648 // See CallLeafNoFPIndirect 1649 return 1 * NativeInstruction::instruction_size; 1650 } else { 1651 return 6 * NativeInstruction::instruction_size; 1652 } 1653 } 1654 1655 //============================================================================= 1656 1657 #ifndef PRODUCT 1658 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1659 st->print("BREAKPOINT"); 1660 } 1661 #endif 1662 1663 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1664 C2_MacroAssembler _masm(&cbuf); 1665 __ brk(0); 1666 } 1667 1668 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1669 return MachNode::size(ra_); 1670 } 1671 1672 //============================================================================= 1673 1674 #ifndef PRODUCT 1675 void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const { 1676 st->print("nop \t# %d bytes pad for loops and calls", _count); 1677 } 1678 #endif 1679 1680 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const { 1681 C2_MacroAssembler _masm(&cbuf); 1682 for (int i = 0; i < _count; i++) { 1683 __ nop(); 1684 } 1685 } 1686 1687 uint MachNopNode::size(PhaseRegAlloc*) const { 1688 return _count * NativeInstruction::instruction_size; 1689 } 1690 1691 //============================================================================= 1692 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 1693 1694 int ConstantTable::calculate_table_base_offset() const { 1695 return 0; // absolute addressing, no offset 1696 } 1697 1698 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 1699 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1700 ShouldNotReachHere(); 1701 } 1702 1703 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1704 // Empty encoding 1705 } 1706 1707 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1708 return 0; 1709 } 1710 1711 #ifndef PRODUCT 1712 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1713 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1714 } 1715 #endif 1716 1717 #ifndef PRODUCT 1718 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1719 Compile* C = ra_->C; 1720 1721 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1722 1723 if (C->output()->need_stack_bang(framesize)) 1724 st->print("# stack bang size=%d\n\t", framesize); 1725 1726 if (VM_Version::use_rop_protection()) { 1727 st->print("ldr zr, [lr]\n\t"); 1728 st->print("paciaz\n\t"); 1729 } 1730 if (framesize < ((1 << 9) + 2 * wordSize)) { 1731 st->print("sub sp, sp, #%d\n\t", framesize); 1732 st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize); 1733 if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize); 1734 } else { 1735 st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize)); 1736 if (PreserveFramePointer) st->print("mov rfp, sp\n\t"); 1737 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1738 st->print("sub sp, sp, rscratch1"); 1739 } 1740 if (C->stub_function() == nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 1741 st->print("\n\t"); 1742 st->print("ldr rscratch1, [guard]\n\t"); 1743 st->print("dmb ishld\n\t"); 1744 st->print("ldr rscratch2, [rthread, #thread_disarmed_guard_value_offset]\n\t"); 1745 st->print("cmp rscratch1, rscratch2\n\t"); 1746 st->print("b.eq skip"); 1747 st->print("\n\t"); 1748 st->print("blr #nmethod_entry_barrier_stub\n\t"); 1749 st->print("b skip\n\t"); 1750 st->print("guard: int\n\t"); 1751 st->print("\n\t"); 1752 st->print("skip:\n\t"); 1753 } 1754 } 1755 #endif 1756 1757 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1758 Compile* C = ra_->C; 1759 C2_MacroAssembler _masm(&cbuf); 1760 1761 // insert a nop at the start of the prolog so we can patch in a 1762 // branch if we need to invalidate the method later 1763 __ nop(); 1764 1765 __ verified_entry(C, 0); 1766 1767 if (C->stub_function() == nullptr) { 1768 __ entry_barrier(); 1769 } 1770 1771 if (!Compile::current()->output()->in_scratch_emit_size()) { 1772 __ bind(*_verified_entry); 1773 } 1774 1775 if (VerifyStackAtCalls) { 1776 Unimplemented(); 1777 } 1778 1779 C->output()->set_frame_complete(cbuf.insts_size()); 1780 1781 if (C->has_mach_constant_base_node()) { 1782 // NOTE: We set the table base offset here because users might be 1783 // emitted before MachConstantBaseNode. 1784 ConstantTable& constant_table = C->output()->constant_table(); 1785 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1786 } 1787 } 1788 1789 int MachPrologNode::reloc() const 1790 { 1791 return 0; 1792 } 1793 1794 //============================================================================= 1795 1796 #ifndef PRODUCT 1797 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1798 Compile* C = ra_->C; 1799 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1800 1801 st->print("# pop frame %d\n\t",framesize); 1802 1803 if (framesize == 0) { 1804 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1805 } else if (framesize < ((1 << 9) + 2 * wordSize)) { 1806 st->print("ldp lr, rfp, [sp,#%d]\n\t", framesize - 2 * wordSize); 1807 st->print("add sp, sp, #%d\n\t", framesize); 1808 } else { 1809 st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize); 1810 st->print("add sp, sp, rscratch1\n\t"); 1811 st->print("ldp lr, rfp, [sp],#%d\n\t", (2 * wordSize)); 1812 } 1813 if (VM_Version::use_rop_protection()) { 1814 st->print("autiaz\n\t"); 1815 st->print("ldr zr, [lr]\n\t"); 1816 } 1817 1818 if (do_polling() && C->is_method_compilation()) { 1819 st->print("# test polling word\n\t"); 1820 st->print("ldr rscratch1, [rthread],#%d\n\t", in_bytes(JavaThread::polling_word_offset())); 1821 st->print("cmp sp, rscratch1\n\t"); 1822 st->print("bhi #slow_path"); 1823 } 1824 } 1825 #endif 1826 1827 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1828 Compile* C = ra_->C; 1829 C2_MacroAssembler _masm(&cbuf); 1830 int framesize = C->output()->frame_slots() << LogBytesPerInt; 1831 1832 __ remove_frame(framesize, C->needs_stack_repair()); 1833 1834 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1835 __ reserved_stack_check(); 1836 } 1837 1838 if (do_polling() && C->is_method_compilation()) { 1839 Label dummy_label; 1840 Label* code_stub = &dummy_label; 1841 if (!C->output()->in_scratch_emit_size()) { 1842 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 1843 C->output()->add_stub(stub); 1844 code_stub = &stub->entry(); 1845 } 1846 __ relocate(relocInfo::poll_return_type); 1847 __ safepoint_poll(*code_stub, true /* at_return */, false /* acquire */, true /* in_nmethod */); 1848 } 1849 } 1850 1851 int MachEpilogNode::reloc() const { 1852 // Return number of relocatable values contained in this instruction. 1853 return 1; // 1 for polling page. 1854 } 1855 1856 const Pipeline * MachEpilogNode::pipeline() const { 1857 return MachNode::pipeline_class(); 1858 } 1859 1860 //============================================================================= 1861 1862 // Figure out which register class each belongs in: rc_int, rc_float or 1863 // rc_stack. 1864 enum RC { rc_bad, rc_int, rc_float, rc_predicate, rc_stack }; 1865 1866 static enum RC rc_class(OptoReg::Name reg) { 1867 1868 if (reg == OptoReg::Bad) { 1869 return rc_bad; 1870 } 1871 1872 // we have 32 int registers * 2 halves 1873 int slots_of_int_registers = Register::number_of_registers * Register::max_slots_per_register; 1874 1875 if (reg < slots_of_int_registers) { 1876 return rc_int; 1877 } 1878 1879 // we have 32 float register * 8 halves 1880 int slots_of_float_registers = FloatRegister::number_of_registers * FloatRegister::max_slots_per_register; 1881 if (reg < slots_of_int_registers + slots_of_float_registers) { 1882 return rc_float; 1883 } 1884 1885 int slots_of_predicate_registers = PRegister::number_of_registers * PRegister::max_slots_per_register; 1886 if (reg < slots_of_int_registers + slots_of_float_registers + slots_of_predicate_registers) { 1887 return rc_predicate; 1888 } 1889 1890 // Between predicate regs & stack is the flags. 1891 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1892 1893 return rc_stack; 1894 } 1895 1896 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1897 Compile* C = ra_->C; 1898 1899 // Get registers to move. 1900 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1901 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1902 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1903 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1904 1905 enum RC src_hi_rc = rc_class(src_hi); 1906 enum RC src_lo_rc = rc_class(src_lo); 1907 enum RC dst_hi_rc = rc_class(dst_hi); 1908 enum RC dst_lo_rc = rc_class(dst_lo); 1909 1910 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1911 1912 if (src_hi != OptoReg::Bad && !bottom_type()->isa_vectmask()) { 1913 assert((src_lo&1)==0 && src_lo+1==src_hi && 1914 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1915 "expected aligned-adjacent pairs"); 1916 } 1917 1918 if (src_lo == dst_lo && src_hi == dst_hi) { 1919 return 0; // Self copy, no move. 1920 } 1921 1922 bool is64 = (src_lo & 1) == 0 && src_lo + 1 == src_hi && 1923 (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi; 1924 int src_offset = ra_->reg2offset(src_lo); 1925 int dst_offset = ra_->reg2offset(dst_lo); 1926 1927 if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) { 1928 uint ireg = ideal_reg(); 1929 if (ireg == Op_VecA && cbuf) { 1930 C2_MacroAssembler _masm(cbuf); 1931 int sve_vector_reg_size_in_bytes = Matcher::scalable_vector_reg_size(T_BYTE); 1932 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1933 // stack->stack 1934 __ spill_copy_sve_vector_stack_to_stack(src_offset, dst_offset, 1935 sve_vector_reg_size_in_bytes); 1936 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1937 __ spill_sve_vector(as_FloatRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo), 1938 sve_vector_reg_size_in_bytes); 1939 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1940 __ unspill_sve_vector(as_FloatRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo), 1941 sve_vector_reg_size_in_bytes); 1942 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1943 __ sve_orr(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1944 as_FloatRegister(Matcher::_regEncode[src_lo]), 1945 as_FloatRegister(Matcher::_regEncode[src_lo])); 1946 } else { 1947 ShouldNotReachHere(); 1948 } 1949 } else if (cbuf) { 1950 assert(ireg == Op_VecD || ireg == Op_VecX, "must be 64 bit or 128 bit vector"); 1951 C2_MacroAssembler _masm(cbuf); 1952 assert((src_lo_rc != rc_int && dst_lo_rc != rc_int), "sanity"); 1953 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1954 // stack->stack 1955 assert((src_offset & 7) == 0 && (dst_offset & 7) == 0, "unaligned stack offset"); 1956 if (ireg == Op_VecD) { 1957 __ unspill(rscratch1, true, src_offset); 1958 __ spill(rscratch1, true, dst_offset); 1959 } else { 1960 __ spill_copy128(src_offset, dst_offset); 1961 } 1962 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1963 __ mov(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1964 ireg == Op_VecD ? __ T8B : __ T16B, 1965 as_FloatRegister(Matcher::_regEncode[src_lo])); 1966 } else if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1967 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 1968 ireg == Op_VecD ? __ D : __ Q, 1969 ra_->reg2offset(dst_lo)); 1970 } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_float) { 1971 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1972 ireg == Op_VecD ? __ D : __ Q, 1973 ra_->reg2offset(src_lo)); 1974 } else { 1975 ShouldNotReachHere(); 1976 } 1977 } 1978 } else if (cbuf) { 1979 C2_MacroAssembler _masm(cbuf); 1980 switch (src_lo_rc) { 1981 case rc_int: 1982 if (dst_lo_rc == rc_int) { // gpr --> gpr copy 1983 if (is64) { 1984 __ mov(as_Register(Matcher::_regEncode[dst_lo]), 1985 as_Register(Matcher::_regEncode[src_lo])); 1986 } else { 1987 C2_MacroAssembler _masm(cbuf); 1988 __ movw(as_Register(Matcher::_regEncode[dst_lo]), 1989 as_Register(Matcher::_regEncode[src_lo])); 1990 } 1991 } else if (dst_lo_rc == rc_float) { // gpr --> fpr copy 1992 if (is64) { 1993 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1994 as_Register(Matcher::_regEncode[src_lo])); 1995 } else { 1996 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 1997 as_Register(Matcher::_regEncode[src_lo])); 1998 } 1999 } else { // gpr --> stack spill 2000 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2001 __ spill(as_Register(Matcher::_regEncode[src_lo]), is64, dst_offset); 2002 } 2003 break; 2004 case rc_float: 2005 if (dst_lo_rc == rc_int) { // fpr --> gpr copy 2006 if (is64) { 2007 __ fmovd(as_Register(Matcher::_regEncode[dst_lo]), 2008 as_FloatRegister(Matcher::_regEncode[src_lo])); 2009 } else { 2010 __ fmovs(as_Register(Matcher::_regEncode[dst_lo]), 2011 as_FloatRegister(Matcher::_regEncode[src_lo])); 2012 } 2013 } else if (dst_lo_rc == rc_float) { // fpr --> fpr copy 2014 if (is64) { 2015 __ fmovd(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2016 as_FloatRegister(Matcher::_regEncode[src_lo])); 2017 } else { 2018 __ fmovs(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2019 as_FloatRegister(Matcher::_regEncode[src_lo])); 2020 } 2021 } else { // fpr --> stack spill 2022 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2023 __ spill(as_FloatRegister(Matcher::_regEncode[src_lo]), 2024 is64 ? __ D : __ S, dst_offset); 2025 } 2026 break; 2027 case rc_stack: 2028 if (dst_lo_rc == rc_int) { // stack --> gpr load 2029 __ unspill(as_Register(Matcher::_regEncode[dst_lo]), is64, src_offset); 2030 } else if (dst_lo_rc == rc_float) { // stack --> fpr load 2031 __ unspill(as_FloatRegister(Matcher::_regEncode[dst_lo]), 2032 is64 ? __ D : __ S, src_offset); 2033 } else if (dst_lo_rc == rc_predicate) { 2034 __ unspill_sve_predicate(as_PRegister(Matcher::_regEncode[dst_lo]), ra_->reg2offset(src_lo), 2035 Matcher::scalable_vector_reg_size(T_BYTE) >> 3); 2036 } else { // stack --> stack copy 2037 assert(dst_lo_rc == rc_stack, "spill to bad register class"); 2038 if (ideal_reg() == Op_RegVectMask) { 2039 __ spill_copy_sve_predicate_stack_to_stack(src_offset, dst_offset, 2040 Matcher::scalable_vector_reg_size(T_BYTE) >> 3); 2041 } else { 2042 __ unspill(rscratch1, is64, src_offset); 2043 __ spill(rscratch1, is64, dst_offset); 2044 } 2045 } 2046 break; 2047 case rc_predicate: 2048 if (dst_lo_rc == rc_predicate) { 2049 __ sve_mov(as_PRegister(Matcher::_regEncode[dst_lo]), as_PRegister(Matcher::_regEncode[src_lo])); 2050 } else if (dst_lo_rc == rc_stack) { 2051 __ spill_sve_predicate(as_PRegister(Matcher::_regEncode[src_lo]), ra_->reg2offset(dst_lo), 2052 Matcher::scalable_vector_reg_size(T_BYTE) >> 3); 2053 } else { 2054 assert(false, "bad src and dst rc_class combination."); 2055 ShouldNotReachHere(); 2056 } 2057 break; 2058 default: 2059 assert(false, "bad rc_class for spill"); 2060 ShouldNotReachHere(); 2061 } 2062 } 2063 2064 if (st) { 2065 st->print("spill "); 2066 if (src_lo_rc == rc_stack) { 2067 st->print("[sp, #%d] -> ", ra_->reg2offset(src_lo)); 2068 } else { 2069 st->print("%s -> ", Matcher::regName[src_lo]); 2070 } 2071 if (dst_lo_rc == rc_stack) { 2072 st->print("[sp, #%d]", ra_->reg2offset(dst_lo)); 2073 } else { 2074 st->print("%s", Matcher::regName[dst_lo]); 2075 } 2076 if (bottom_type()->isa_vect() && !bottom_type()->isa_vectmask()) { 2077 int vsize = 0; 2078 switch (ideal_reg()) { 2079 case Op_VecD: 2080 vsize = 64; 2081 break; 2082 case Op_VecX: 2083 vsize = 128; 2084 break; 2085 case Op_VecA: 2086 vsize = Matcher::scalable_vector_reg_size(T_BYTE) * 8; 2087 break; 2088 default: 2089 assert(false, "bad register type for spill"); 2090 ShouldNotReachHere(); 2091 } 2092 st->print("\t# vector spill size = %d", vsize); 2093 } else if (ideal_reg() == Op_RegVectMask) { 2094 assert(Matcher::supports_scalable_vector(), "bad register type for spill"); 2095 int vsize = Matcher::scalable_predicate_reg_slots() * 32; 2096 st->print("\t# predicate spill size = %d", vsize); 2097 } else { 2098 st->print("\t# spill size = %d", is64 ? 64 : 32); 2099 } 2100 } 2101 2102 return 0; 2103 2104 } 2105 2106 #ifndef PRODUCT 2107 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2108 if (!ra_) 2109 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 2110 else 2111 implementation(nullptr, ra_, false, st); 2112 } 2113 #endif 2114 2115 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2116 implementation(&cbuf, ra_, false, nullptr); 2117 } 2118 2119 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 2120 return MachNode::size(ra_); 2121 } 2122 2123 //============================================================================= 2124 2125 #ifndef PRODUCT 2126 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 2127 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2128 int reg = ra_->get_reg_first(this); 2129 st->print("add %s, rsp, #%d]\t# box lock", 2130 Matcher::regName[reg], offset); 2131 } 2132 #endif 2133 2134 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 2135 C2_MacroAssembler _masm(&cbuf); 2136 2137 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2138 int reg = ra_->get_encode(this); 2139 2140 // This add will handle any 24-bit signed offset. 24 bits allows an 2141 // 8 megabyte stack frame. 2142 __ add(as_Register(reg), sp, offset); 2143 } 2144 2145 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 2146 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 2147 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 2148 2149 if (Assembler::operand_valid_for_add_sub_immediate(offset)) { 2150 return NativeInstruction::instruction_size; 2151 } else { 2152 return 2 * NativeInstruction::instruction_size; 2153 } 2154 } 2155 2156 ///============================================================================= 2157 #ifndef PRODUCT 2158 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 2159 { 2160 st->print_cr("# MachVEPNode"); 2161 if (!_verified) { 2162 st->print_cr("\t load_class"); 2163 } else { 2164 st->print_cr("\t unpack_inline_arg"); 2165 } 2166 } 2167 #endif 2168 2169 void MachVEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2170 { 2171 C2_MacroAssembler _masm(&cbuf); 2172 2173 if (!_verified) { 2174 Label skip; 2175 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2176 __ br(Assembler::EQ, skip); 2177 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2178 __ bind(skip); 2179 2180 } else { 2181 // insert a nop at the start of the prolog so we can patch in a 2182 // branch if we need to invalidate the method later 2183 __ nop(); 2184 2185 // TODO 8284443 Avoid creation of temporary frame 2186 if (ra_->C->stub_function() == nullptr) { 2187 __ verified_entry(ra_->C, 0); 2188 __ entry_barrier(); 2189 int framesize = ra_->C->output()->frame_slots() << LogBytesPerInt; 2190 __ remove_frame(framesize, false); 2191 } 2192 // Unpack inline type args passed as oop and then jump to 2193 // the verified entry point (skipping the unverified entry). 2194 int sp_inc = __ unpack_inline_args(ra_->C, _receiver_only); 2195 // Emit code for verified entry and save increment for stack repair on return 2196 __ verified_entry(ra_->C, sp_inc); 2197 if (Compile::current()->output()->in_scratch_emit_size()) { 2198 Label dummy_verified_entry; 2199 __ b(dummy_verified_entry); 2200 } else { 2201 __ b(*_verified_entry); 2202 } 2203 } 2204 } 2205 2206 //============================================================================= 2207 #ifndef PRODUCT 2208 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 2209 { 2210 st->print_cr("# MachUEPNode"); 2211 if (UseCompressedClassPointers) { 2212 st->print_cr("\tldrw rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2213 st->print_cr("\tldrw r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass"); 2214 st->print_cr("\tcmpw rscratch1, r10"); 2215 } else { 2216 st->print_cr("\tldr rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2217 st->print_cr("\tldr r10, [rscratch2 + CompiledICData::speculated_klass_offset()]\t# compressed klass"); 2218 st->print_cr("\tcmp rscratch1, r10"); 2219 } 2220 st->print_cr("\tbne, SharedRuntime::_ic_miss_stub"); 2221 } 2222 #endif 2223 2224 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 2225 { 2226 // This is the unverified entry point. 2227 C2_MacroAssembler _masm(&cbuf); 2228 __ ic_check(InteriorEntryAlignment); 2229 } 2230 2231 // REQUIRED EMIT CODE 2232 2233 //============================================================================= 2234 2235 // Emit exception handler code. 2236 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2237 { 2238 // mov rscratch1 #exception_blob_entry_point 2239 // br rscratch1 2240 // Note that the code buffer's insts_mark is always relative to insts. 2241 // That's why we must use the macroassembler to generate a handler. 2242 C2_MacroAssembler _masm(&cbuf); 2243 address base = __ start_a_stub(size_exception_handler()); 2244 if (base == nullptr) { 2245 ciEnv::current()->record_failure("CodeCache is full"); 2246 return 0; // CodeBuffer::expand failed 2247 } 2248 int offset = __ offset(); 2249 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2250 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2251 __ end_a_stub(); 2252 return offset; 2253 } 2254 2255 // Emit deopt handler code. 2256 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2257 { 2258 // Note that the code buffer's insts_mark is always relative to insts. 2259 // That's why we must use the macroassembler to generate a handler. 2260 C2_MacroAssembler _masm(&cbuf); 2261 address base = __ start_a_stub(size_deopt_handler()); 2262 if (base == nullptr) { 2263 ciEnv::current()->record_failure("CodeCache is full"); 2264 return 0; // CodeBuffer::expand failed 2265 } 2266 int offset = __ offset(); 2267 2268 __ adr(lr, __ pc()); 2269 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2270 2271 assert(__ offset() - offset == (int) size_deopt_handler(), "overflow"); 2272 __ end_a_stub(); 2273 return offset; 2274 } 2275 2276 // REQUIRED MATCHER CODE 2277 2278 //============================================================================= 2279 2280 bool Matcher::match_rule_supported(int opcode) { 2281 if (!has_match_rule(opcode)) 2282 return false; 2283 2284 switch (opcode) { 2285 case Op_OnSpinWait: 2286 return VM_Version::supports_on_spin_wait(); 2287 case Op_CacheWB: 2288 case Op_CacheWBPreSync: 2289 case Op_CacheWBPostSync: 2290 if (!VM_Version::supports_data_cache_line_flush()) { 2291 return false; 2292 } 2293 break; 2294 case Op_ExpandBits: 2295 case Op_CompressBits: 2296 if (!VM_Version::supports_svebitperm()) { 2297 return false; 2298 } 2299 break; 2300 case Op_FmaF: 2301 case Op_FmaD: 2302 case Op_FmaVF: 2303 case Op_FmaVD: 2304 if (!UseFMA) { 2305 return false; 2306 } 2307 break; 2308 } 2309 2310 return true; // Per default match rules are supported. 2311 } 2312 2313 const RegMask* Matcher::predicate_reg_mask(void) { 2314 return &_PR_REG_mask; 2315 } 2316 2317 const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { 2318 return new TypeVectMask(elemTy, length); 2319 } 2320 2321 // Vector calling convention not yet implemented. 2322 bool Matcher::supports_vector_calling_convention(void) { 2323 return false; 2324 } 2325 2326 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 2327 Unimplemented(); 2328 return OptoRegPair(0, 0); 2329 } 2330 2331 // Is this branch offset short enough that a short branch can be used? 2332 // 2333 // NOTE: If the platform does not provide any short branch variants, then 2334 // this method should return false for offset 0. 2335 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2336 // The passed offset is relative to address of the branch. 2337 2338 return (-32768 <= offset && offset < 32768); 2339 } 2340 2341 // Vector width in bytes. 2342 int Matcher::vector_width_in_bytes(BasicType bt) { 2343 // The MaxVectorSize should have been set by detecting SVE max vector register size. 2344 int size = MIN2((UseSVE > 0) ? 256 : 16, (int)MaxVectorSize); 2345 // Minimum 2 values in vector 2346 if (size < 2*type2aelembytes(bt)) size = 0; 2347 // But never < 4 2348 if (size < 4) size = 0; 2349 return size; 2350 } 2351 2352 // Limits on vector size (number of elements) loaded into vector. 2353 int Matcher::max_vector_size(const BasicType bt) { 2354 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2355 } 2356 2357 int Matcher::min_vector_size(const BasicType bt) { 2358 int max_size = max_vector_size(bt); 2359 // Limit the min vector size to 8 bytes. 2360 int size = 8 / type2aelembytes(bt); 2361 if (bt == T_BYTE) { 2362 // To support vector api shuffle/rearrange. 2363 size = 4; 2364 } else if (bt == T_BOOLEAN) { 2365 // To support vector api load/store mask. 2366 size = 2; 2367 } 2368 if (size < 2) size = 2; 2369 return MIN2(size, max_size); 2370 } 2371 2372 int Matcher::max_vector_size_auto_vectorization(const BasicType bt) { 2373 return Matcher::max_vector_size(bt); 2374 } 2375 2376 // Actual max scalable vector register length. 2377 int Matcher::scalable_vector_reg_size(const BasicType bt) { 2378 return Matcher::max_vector_size(bt); 2379 } 2380 2381 // Vector ideal reg. 2382 uint Matcher::vector_ideal_reg(int len) { 2383 if (UseSVE > 0 && 16 < len && len <= 256) { 2384 return Op_VecA; 2385 } 2386 switch(len) { 2387 // For 16-bit/32-bit mask vector, reuse VecD. 2388 case 2: 2389 case 4: 2390 case 8: return Op_VecD; 2391 case 16: return Op_VecX; 2392 } 2393 ShouldNotReachHere(); 2394 return 0; 2395 } 2396 2397 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg, bool is_temp) { 2398 assert(Matcher::is_generic_vector(generic_opnd), "not generic"); 2399 switch (ideal_reg) { 2400 case Op_VecA: return new vecAOper(); 2401 case Op_VecD: return new vecDOper(); 2402 case Op_VecX: return new vecXOper(); 2403 } 2404 ShouldNotReachHere(); 2405 return nullptr; 2406 } 2407 2408 bool Matcher::is_reg2reg_move(MachNode* m) { 2409 return false; 2410 } 2411 2412 bool Matcher::is_generic_vector(MachOper* opnd) { 2413 return opnd->opcode() == VREG; 2414 } 2415 2416 // Return whether or not this register is ever used as an argument. 2417 // This function is used on startup to build the trampoline stubs in 2418 // generateOptoStub. Registers not mentioned will be killed by the VM 2419 // call in the trampoline, and arguments in those registers not be 2420 // available to the callee. 2421 bool Matcher::can_be_java_arg(int reg) 2422 { 2423 return 2424 reg == R0_num || reg == R0_H_num || 2425 reg == R1_num || reg == R1_H_num || 2426 reg == R2_num || reg == R2_H_num || 2427 reg == R3_num || reg == R3_H_num || 2428 reg == R4_num || reg == R4_H_num || 2429 reg == R5_num || reg == R5_H_num || 2430 reg == R6_num || reg == R6_H_num || 2431 reg == R7_num || reg == R7_H_num || 2432 reg == V0_num || reg == V0_H_num || 2433 reg == V1_num || reg == V1_H_num || 2434 reg == V2_num || reg == V2_H_num || 2435 reg == V3_num || reg == V3_H_num || 2436 reg == V4_num || reg == V4_H_num || 2437 reg == V5_num || reg == V5_H_num || 2438 reg == V6_num || reg == V6_H_num || 2439 reg == V7_num || reg == V7_H_num; 2440 } 2441 2442 bool Matcher::is_spillable_arg(int reg) 2443 { 2444 return can_be_java_arg(reg); 2445 } 2446 2447 uint Matcher::int_pressure_limit() 2448 { 2449 // JDK-8183543: When taking the number of available registers as int 2450 // register pressure threshold, the jtreg test: 2451 // test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java 2452 // failed due to C2 compilation failure with 2453 // "COMPILE SKIPPED: failed spill-split-recycle sanity check". 2454 // 2455 // A derived pointer is live at CallNode and then is flagged by RA 2456 // as a spilled LRG. Spilling heuristics(Spill-USE) explicitly skip 2457 // derived pointers and lastly fail to spill after reaching maximum 2458 // number of iterations. Lowering the default pressure threshold to 2459 // (_NO_SPECIAL_REG32_mask.Size() minus 1) forces CallNode to become 2460 // a high register pressure area of the code so that split_DEF can 2461 // generate DefinitionSpillCopy for the derived pointer. 2462 uint default_int_pressure_threshold = _NO_SPECIAL_REG32_mask.Size() - 1; 2463 if (!PreserveFramePointer) { 2464 // When PreserveFramePointer is off, frame pointer is allocatable, 2465 // but different from other SOC registers, it is excluded from 2466 // fatproj's mask because its save type is No-Save. Decrease 1 to 2467 // ensure high pressure at fatproj when PreserveFramePointer is off. 2468 // See check_pressure_at_fatproj(). 2469 default_int_pressure_threshold--; 2470 } 2471 return (INTPRESSURE == -1) ? default_int_pressure_threshold : INTPRESSURE; 2472 } 2473 2474 uint Matcher::float_pressure_limit() 2475 { 2476 // _FLOAT_REG_mask is generated by adlc from the float_reg register class. 2477 return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.Size() : FLOATPRESSURE; 2478 } 2479 2480 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2481 return false; 2482 } 2483 2484 RegMask Matcher::divI_proj_mask() { 2485 ShouldNotReachHere(); 2486 return RegMask(); 2487 } 2488 2489 // Register for MODI projection of divmodI. 2490 RegMask Matcher::modI_proj_mask() { 2491 ShouldNotReachHere(); 2492 return RegMask(); 2493 } 2494 2495 // Register for DIVL projection of divmodL. 2496 RegMask Matcher::divL_proj_mask() { 2497 ShouldNotReachHere(); 2498 return RegMask(); 2499 } 2500 2501 // Register for MODL projection of divmodL. 2502 RegMask Matcher::modL_proj_mask() { 2503 ShouldNotReachHere(); 2504 return RegMask(); 2505 } 2506 2507 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2508 return FP_REG_mask(); 2509 } 2510 2511 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2512 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2513 Node* u = addp->fast_out(i); 2514 if (u->is_LoadStore()) { 2515 // On AArch64, LoadStoreNodes (i.e. compare and swap 2516 // instructions) only take register indirect as an operand, so 2517 // any attempt to use an AddPNode as an input to a LoadStoreNode 2518 // must fail. 2519 return false; 2520 } 2521 if (u->is_Mem()) { 2522 int opsize = u->as_Mem()->memory_size(); 2523 assert(opsize > 0, "unexpected memory operand size"); 2524 if (u->as_Mem()->memory_size() != (1<<shift)) { 2525 return false; 2526 } 2527 } 2528 } 2529 return true; 2530 } 2531 2532 // Convert BootTest condition to Assembler condition. 2533 // Replicate the logic of cmpOpOper::ccode() and cmpOpUOper::ccode(). 2534 Assembler::Condition to_assembler_cond(BoolTest::mask cond) { 2535 Assembler::Condition result; 2536 switch(cond) { 2537 case BoolTest::eq: 2538 result = Assembler::EQ; break; 2539 case BoolTest::ne: 2540 result = Assembler::NE; break; 2541 case BoolTest::le: 2542 result = Assembler::LE; break; 2543 case BoolTest::ge: 2544 result = Assembler::GE; break; 2545 case BoolTest::lt: 2546 result = Assembler::LT; break; 2547 case BoolTest::gt: 2548 result = Assembler::GT; break; 2549 case BoolTest::ule: 2550 result = Assembler::LS; break; 2551 case BoolTest::uge: 2552 result = Assembler::HS; break; 2553 case BoolTest::ult: 2554 result = Assembler::LO; break; 2555 case BoolTest::ugt: 2556 result = Assembler::HI; break; 2557 case BoolTest::overflow: 2558 result = Assembler::VS; break; 2559 case BoolTest::no_overflow: 2560 result = Assembler::VC; break; 2561 default: 2562 ShouldNotReachHere(); 2563 return Assembler::Condition(-1); 2564 } 2565 2566 // Check conversion 2567 if (cond & BoolTest::unsigned_compare) { 2568 assert(cmpOpUOper((BoolTest::mask)((int)cond & ~(BoolTest::unsigned_compare))).ccode() == result, "Invalid conversion"); 2569 } else { 2570 assert(cmpOpOper(cond).ccode() == result, "Invalid conversion"); 2571 } 2572 2573 return result; 2574 } 2575 2576 // Binary src (Replicate con) 2577 static bool is_valid_sve_arith_imm_pattern(Node* n, Node* m) { 2578 if (n == nullptr || m == nullptr) { 2579 return false; 2580 } 2581 2582 if (UseSVE == 0 || m->Opcode() != Op_Replicate) { 2583 return false; 2584 } 2585 2586 Node* imm_node = m->in(1); 2587 if (!imm_node->is_Con()) { 2588 return false; 2589 } 2590 2591 const Type* t = imm_node->bottom_type(); 2592 if (!(t->isa_int() || t->isa_long())) { 2593 return false; 2594 } 2595 2596 switch (n->Opcode()) { 2597 case Op_AndV: 2598 case Op_OrV: 2599 case Op_XorV: { 2600 Assembler::SIMD_RegVariant T = Assembler::elemType_to_regVariant(Matcher::vector_element_basic_type(n)); 2601 uint64_t value = t->isa_long() ? (uint64_t)imm_node->get_long() : (uint64_t)imm_node->get_int(); 2602 return Assembler::operand_valid_for_sve_logical_immediate(Assembler::regVariant_to_elemBits(T), value); 2603 } 2604 case Op_AddVB: 2605 return (imm_node->get_int() <= 255 && imm_node->get_int() >= -255); 2606 case Op_AddVS: 2607 case Op_AddVI: 2608 return Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)imm_node->get_int()); 2609 case Op_AddVL: 2610 return Assembler::operand_valid_for_sve_add_sub_immediate(imm_node->get_long()); 2611 default: 2612 return false; 2613 } 2614 } 2615 2616 // (XorV src (Replicate m1)) 2617 // (XorVMask src (MaskAll m1)) 2618 static bool is_vector_bitwise_not_pattern(Node* n, Node* m) { 2619 if (n != nullptr && m != nullptr) { 2620 return (n->Opcode() == Op_XorV || n->Opcode() == Op_XorVMask) && 2621 VectorNode::is_all_ones_vector(m); 2622 } 2623 return false; 2624 } 2625 2626 // Should the matcher clone input 'm' of node 'n'? 2627 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 2628 if (is_vshift_con_pattern(n, m) || 2629 is_vector_bitwise_not_pattern(n, m) || 2630 is_valid_sve_arith_imm_pattern(n, m)) { 2631 mstack.push(m, Visit); 2632 return true; 2633 } 2634 return false; 2635 } 2636 2637 // Should the Matcher clone shifts on addressing modes, expecting them 2638 // to be subsumed into complex addressing expressions or compute them 2639 // into registers? 2640 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2641 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2642 return true; 2643 } 2644 2645 Node *off = m->in(AddPNode::Offset); 2646 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2647 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2648 // Are there other uses besides address expressions? 2649 !is_visited(off)) { 2650 address_visited.set(off->_idx); // Flag as address_visited 2651 mstack.push(off->in(2), Visit); 2652 Node *conv = off->in(1); 2653 if (conv->Opcode() == Op_ConvI2L && 2654 // Are there other uses besides address expressions? 2655 !is_visited(conv)) { 2656 address_visited.set(conv->_idx); // Flag as address_visited 2657 mstack.push(conv->in(1), Pre_Visit); 2658 } else { 2659 mstack.push(conv, Pre_Visit); 2660 } 2661 address_visited.test_set(m->_idx); // Flag as address_visited 2662 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2663 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2664 return true; 2665 } else if (off->Opcode() == Op_ConvI2L && 2666 // Are there other uses besides address expressions? 2667 !is_visited(off)) { 2668 address_visited.test_set(m->_idx); // Flag as address_visited 2669 address_visited.set(off->_idx); // Flag as address_visited 2670 mstack.push(off->in(1), Pre_Visit); 2671 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2672 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2673 return true; 2674 } 2675 return false; 2676 } 2677 2678 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2679 C2_MacroAssembler _masm(&cbuf); \ 2680 { \ 2681 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2682 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2683 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2684 __ INSN(REG, as_Register(BASE)); \ 2685 } 2686 2687 2688 static Address mem2address(int opcode, Register base, int index, int size, int disp) 2689 { 2690 Address::extend scale; 2691 2692 // Hooboy, this is fugly. We need a way to communicate to the 2693 // encoder that the index needs to be sign extended, so we have to 2694 // enumerate all the cases. 2695 switch (opcode) { 2696 case INDINDEXSCALEDI2L: 2697 case INDINDEXSCALEDI2LN: 2698 case INDINDEXI2L: 2699 case INDINDEXI2LN: 2700 scale = Address::sxtw(size); 2701 break; 2702 default: 2703 scale = Address::lsl(size); 2704 } 2705 2706 if (index == -1) { 2707 return Address(base, disp); 2708 } else { 2709 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2710 return Address(base, as_Register(index), scale); 2711 } 2712 } 2713 2714 2715 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2716 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr); 2717 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2718 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2719 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2720 2721 // Used for all non-volatile memory accesses. The use of 2722 // $mem->opcode() to discover whether this pattern uses sign-extended 2723 // offsets is something of a kludge. 2724 static void loadStore(C2_MacroAssembler masm, mem_insn insn, 2725 Register reg, int opcode, 2726 Register base, int index, int scale, int disp, 2727 int size_in_memory) 2728 { 2729 Address addr = mem2address(opcode, base, index, scale, disp); 2730 if (addr.getMode() == Address::base_plus_offset) { 2731 /* If we get an out-of-range offset it is a bug in the compiler, 2732 so we assert here. */ 2733 assert(Address::offset_ok_for_immed(addr.offset(), exact_log2(size_in_memory)), 2734 "c2 compiler bug"); 2735 /* Fix up any out-of-range offsets. */ 2736 assert_different_registers(rscratch1, base); 2737 assert_different_registers(rscratch1, reg); 2738 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2739 } 2740 (masm.*insn)(reg, addr); 2741 } 2742 2743 static void loadStore(C2_MacroAssembler masm, mem_float_insn insn, 2744 FloatRegister reg, int opcode, 2745 Register base, int index, int size, int disp, 2746 int size_in_memory) 2747 { 2748 Address::extend scale; 2749 2750 switch (opcode) { 2751 case INDINDEXSCALEDI2L: 2752 case INDINDEXSCALEDI2LN: 2753 scale = Address::sxtw(size); 2754 break; 2755 default: 2756 scale = Address::lsl(size); 2757 } 2758 2759 if (index == -1) { 2760 /* If we get an out-of-range offset it is a bug in the compiler, 2761 so we assert here. */ 2762 assert(Address::offset_ok_for_immed(disp, exact_log2(size_in_memory)), "c2 compiler bug"); 2763 /* Fix up any out-of-range offsets. */ 2764 assert_different_registers(rscratch1, base); 2765 Address addr = Address(base, disp); 2766 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2767 (masm.*insn)(reg, addr); 2768 } else { 2769 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2770 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2771 } 2772 } 2773 2774 static void loadStore(C2_MacroAssembler masm, mem_vector_insn insn, 2775 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2776 int opcode, Register base, int index, int size, int disp) 2777 { 2778 if (index == -1) { 2779 (masm.*insn)(reg, T, Address(base, disp)); 2780 } else { 2781 assert(disp == 0, "unsupported address mode"); 2782 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2783 } 2784 } 2785 2786 %} 2787 2788 2789 2790 //----------ENCODING BLOCK----------------------------------------------------- 2791 // This block specifies the encoding classes used by the compiler to 2792 // output byte streams. Encoding classes are parameterized macros 2793 // used by Machine Instruction Nodes in order to generate the bit 2794 // encoding of the instruction. Operands specify their base encoding 2795 // interface with the interface keyword. There are currently 2796 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2797 // COND_INTER. REG_INTER causes an operand to generate a function 2798 // which returns its register number when queried. CONST_INTER causes 2799 // an operand to generate a function which returns the value of the 2800 // constant when queried. MEMORY_INTER causes an operand to generate 2801 // four functions which return the Base Register, the Index Register, 2802 // the Scale Value, and the Offset Value of the operand when queried. 2803 // COND_INTER causes an operand to generate six functions which return 2804 // the encoding code (ie - encoding bits for the instruction) 2805 // associated with each basic boolean condition for a conditional 2806 // instruction. 2807 // 2808 // Instructions specify two basic values for encoding. Again, a 2809 // function is available to check if the constant displacement is an 2810 // oop. They use the ins_encode keyword to specify their encoding 2811 // classes (which must be a sequence of enc_class names, and their 2812 // parameters, specified in the encoding block), and they use the 2813 // opcode keyword to specify, in order, their primary, secondary, and 2814 // tertiary opcode. Only the opcode sections which a particular 2815 // instruction needs for encoding need to be specified. 2816 encode %{ 2817 // Build emit functions for each basic byte or larger field in the 2818 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2819 // from C++ code in the enc_class source block. Emit functions will 2820 // live in the main source block for now. In future, we can 2821 // generalize this by adding a syntax that specifies the sizes of 2822 // fields in an order, so that the adlc can build the emit functions 2823 // automagically 2824 2825 // catch all for unimplemented encodings 2826 enc_class enc_unimplemented %{ 2827 C2_MacroAssembler _masm(&cbuf); 2828 __ unimplemented("C2 catch all"); 2829 %} 2830 2831 // BEGIN Non-volatile memory access 2832 2833 // This encoding class is generated automatically from ad_encode.m4. 2834 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2835 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{ 2836 Register dst_reg = as_Register($dst$$reg); 2837 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2838 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2839 %} 2840 2841 // This encoding class is generated automatically from ad_encode.m4. 2842 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2843 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{ 2844 Register dst_reg = as_Register($dst$$reg); 2845 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2846 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2847 %} 2848 2849 // This encoding class is generated automatically from ad_encode.m4. 2850 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2851 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{ 2852 Register dst_reg = as_Register($dst$$reg); 2853 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2854 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2855 %} 2856 2857 // This encoding class is generated automatically from ad_encode.m4. 2858 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2859 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{ 2860 Register dst_reg = as_Register($dst$$reg); 2861 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2862 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2863 %} 2864 2865 // This encoding class is generated automatically from ad_encode.m4. 2866 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2867 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{ 2868 Register dst_reg = as_Register($dst$$reg); 2869 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2870 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2871 %} 2872 2873 // This encoding class is generated automatically from ad_encode.m4. 2874 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2875 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{ 2876 Register dst_reg = as_Register($dst$$reg); 2877 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2878 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2879 %} 2880 2881 // This encoding class is generated automatically from ad_encode.m4. 2882 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2883 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{ 2884 Register dst_reg = as_Register($dst$$reg); 2885 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2886 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2887 %} 2888 2889 // This encoding class is generated automatically from ad_encode.m4. 2890 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2891 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{ 2892 Register dst_reg = as_Register($dst$$reg); 2893 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2894 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2895 %} 2896 2897 // This encoding class is generated automatically from ad_encode.m4. 2898 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2899 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{ 2900 Register dst_reg = as_Register($dst$$reg); 2901 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2902 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2903 %} 2904 2905 // This encoding class is generated automatically from ad_encode.m4. 2906 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2907 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{ 2908 Register dst_reg = as_Register($dst$$reg); 2909 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2910 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2911 %} 2912 2913 // This encoding class is generated automatically from ad_encode.m4. 2914 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2915 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{ 2916 Register dst_reg = as_Register($dst$$reg); 2917 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2918 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2919 %} 2920 2921 // This encoding class is generated automatically from ad_encode.m4. 2922 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2923 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{ 2924 Register dst_reg = as_Register($dst$$reg); 2925 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2926 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2927 %} 2928 2929 // This encoding class is generated automatically from ad_encode.m4. 2930 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2931 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{ 2932 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2933 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2934 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2935 %} 2936 2937 // This encoding class is generated automatically from ad_encode.m4. 2938 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2939 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{ 2940 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2941 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2942 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2943 %} 2944 2945 // This encoding class is generated automatically from ad_encode.m4. 2946 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2947 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{ 2948 Register src_reg = as_Register($src$$reg); 2949 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2950 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2951 %} 2952 2953 // This encoding class is generated automatically from ad_encode.m4. 2954 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2955 enc_class aarch64_enc_strb0(memory1 mem) %{ 2956 C2_MacroAssembler _masm(&cbuf); 2957 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2958 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2959 %} 2960 2961 // This encoding class is generated automatically from ad_encode.m4. 2962 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2963 enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{ 2964 Register src_reg = as_Register($src$$reg); 2965 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2966 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2967 %} 2968 2969 // This encoding class is generated automatically from ad_encode.m4. 2970 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2971 enc_class aarch64_enc_strh0(memory2 mem) %{ 2972 C2_MacroAssembler _masm(&cbuf); 2973 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2974 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2975 %} 2976 2977 // This encoding class is generated automatically from ad_encode.m4. 2978 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2979 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{ 2980 Register src_reg = as_Register($src$$reg); 2981 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2982 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2983 %} 2984 2985 // This encoding class is generated automatically from ad_encode.m4. 2986 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2987 enc_class aarch64_enc_strw0(memory4 mem) %{ 2988 C2_MacroAssembler _masm(&cbuf); 2989 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2990 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2991 %} 2992 2993 // This encoding class is generated automatically from ad_encode.m4. 2994 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2995 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{ 2996 Register src_reg = as_Register($src$$reg); 2997 // we sometimes get asked to store the stack pointer into the 2998 // current thread -- we cannot do that directly on AArch64 2999 if (src_reg == r31_sp) { 3000 C2_MacroAssembler _masm(&cbuf); 3001 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3002 __ mov(rscratch2, sp); 3003 src_reg = rscratch2; 3004 } 3005 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 3006 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3007 %} 3008 3009 // This encoding class is generated automatically from ad_encode.m4. 3010 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3011 enc_class aarch64_enc_str0(memory8 mem) %{ 3012 C2_MacroAssembler _masm(&cbuf); 3013 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 3014 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3015 %} 3016 3017 // This encoding class is generated automatically from ad_encode.m4. 3018 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3019 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{ 3020 FloatRegister src_reg = as_FloatRegister($src$$reg); 3021 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 3022 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 3023 %} 3024 3025 // This encoding class is generated automatically from ad_encode.m4. 3026 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3027 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{ 3028 FloatRegister src_reg = as_FloatRegister($src$$reg); 3029 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 3030 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3031 %} 3032 3033 // This encoding class is generated automatically from ad_encode.m4. 3034 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3035 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{ 3036 C2_MacroAssembler _masm(&cbuf); 3037 __ membar(Assembler::StoreStore); 3038 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 3039 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 3040 %} 3041 3042 // END Non-volatile memory access 3043 3044 // Vector loads and stores 3045 enc_class aarch64_enc_ldrvH(vReg dst, memory mem) %{ 3046 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3047 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::H, 3048 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3049 %} 3050 3051 enc_class aarch64_enc_ldrvS(vReg dst, memory mem) %{ 3052 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3053 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 3054 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3055 %} 3056 3057 enc_class aarch64_enc_ldrvD(vReg dst, memory mem) %{ 3058 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3059 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 3060 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3061 %} 3062 3063 enc_class aarch64_enc_ldrvQ(vReg dst, memory mem) %{ 3064 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3065 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 3066 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3067 %} 3068 3069 enc_class aarch64_enc_strvH(vReg src, memory mem) %{ 3070 FloatRegister src_reg = as_FloatRegister($src$$reg); 3071 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::H, 3072 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3073 %} 3074 3075 enc_class aarch64_enc_strvS(vReg src, memory mem) %{ 3076 FloatRegister src_reg = as_FloatRegister($src$$reg); 3077 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 3078 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3079 %} 3080 3081 enc_class aarch64_enc_strvD(vReg src, memory mem) %{ 3082 FloatRegister src_reg = as_FloatRegister($src$$reg); 3083 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 3084 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3085 %} 3086 3087 enc_class aarch64_enc_strvQ(vReg src, memory mem) %{ 3088 FloatRegister src_reg = as_FloatRegister($src$$reg); 3089 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 3090 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3091 %} 3092 3093 // volatile loads and stores 3094 3095 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 3096 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3097 rscratch1, stlrb); 3098 %} 3099 3100 enc_class aarch64_enc_stlrb0(memory mem) %{ 3101 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3102 rscratch1, stlrb); 3103 %} 3104 3105 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 3106 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3107 rscratch1, stlrh); 3108 %} 3109 3110 enc_class aarch64_enc_stlrh0(memory mem) %{ 3111 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3112 rscratch1, stlrh); 3113 %} 3114 3115 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 3116 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3117 rscratch1, stlrw); 3118 %} 3119 3120 enc_class aarch64_enc_stlrw0(memory mem) %{ 3121 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3122 rscratch1, stlrw); 3123 %} 3124 3125 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 3126 Register dst_reg = as_Register($dst$$reg); 3127 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3128 rscratch1, ldarb); 3129 __ sxtbw(dst_reg, dst_reg); 3130 %} 3131 3132 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 3133 Register dst_reg = as_Register($dst$$reg); 3134 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3135 rscratch1, ldarb); 3136 __ sxtb(dst_reg, dst_reg); 3137 %} 3138 3139 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 3140 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3141 rscratch1, ldarb); 3142 %} 3143 3144 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 3145 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3146 rscratch1, ldarb); 3147 %} 3148 3149 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 3150 Register dst_reg = as_Register($dst$$reg); 3151 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3152 rscratch1, ldarh); 3153 __ sxthw(dst_reg, dst_reg); 3154 %} 3155 3156 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 3157 Register dst_reg = as_Register($dst$$reg); 3158 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3159 rscratch1, ldarh); 3160 __ sxth(dst_reg, dst_reg); 3161 %} 3162 3163 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 3164 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3165 rscratch1, ldarh); 3166 %} 3167 3168 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 3169 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3170 rscratch1, ldarh); 3171 %} 3172 3173 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 3174 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3175 rscratch1, ldarw); 3176 %} 3177 3178 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 3179 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3180 rscratch1, ldarw); 3181 %} 3182 3183 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 3184 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3185 rscratch1, ldar); 3186 %} 3187 3188 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 3189 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3190 rscratch1, ldarw); 3191 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 3192 %} 3193 3194 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 3195 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3196 rscratch1, ldar); 3197 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 3198 %} 3199 3200 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 3201 Register src_reg = as_Register($src$$reg); 3202 // we sometimes get asked to store the stack pointer into the 3203 // current thread -- we cannot do that directly on AArch64 3204 if (src_reg == r31_sp) { 3205 C2_MacroAssembler _masm(&cbuf); 3206 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3207 __ mov(rscratch2, sp); 3208 src_reg = rscratch2; 3209 } 3210 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3211 rscratch1, stlr); 3212 %} 3213 3214 enc_class aarch64_enc_stlr0(memory mem) %{ 3215 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3216 rscratch1, stlr); 3217 %} 3218 3219 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 3220 { 3221 C2_MacroAssembler _masm(&cbuf); 3222 FloatRegister src_reg = as_FloatRegister($src$$reg); 3223 __ fmovs(rscratch2, src_reg); 3224 } 3225 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3226 rscratch1, stlrw); 3227 %} 3228 3229 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 3230 { 3231 C2_MacroAssembler _masm(&cbuf); 3232 FloatRegister src_reg = as_FloatRegister($src$$reg); 3233 __ fmovd(rscratch2, src_reg); 3234 } 3235 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3236 rscratch1, stlr); 3237 %} 3238 3239 // synchronized read/update encodings 3240 3241 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{ 3242 C2_MacroAssembler _masm(&cbuf); 3243 Register dst_reg = as_Register($dst$$reg); 3244 Register base = as_Register($mem$$base); 3245 int index = $mem$$index; 3246 int scale = $mem$$scale; 3247 int disp = $mem$$disp; 3248 if (index == -1) { 3249 if (disp != 0) { 3250 __ lea(rscratch1, Address(base, disp)); 3251 __ ldaxr(dst_reg, rscratch1); 3252 } else { 3253 // TODO 3254 // should we ever get anything other than this case? 3255 __ ldaxr(dst_reg, base); 3256 } 3257 } else { 3258 Register index_reg = as_Register(index); 3259 if (disp == 0) { 3260 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3261 __ ldaxr(dst_reg, rscratch1); 3262 } else { 3263 __ lea(rscratch1, Address(base, disp)); 3264 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3265 __ ldaxr(dst_reg, rscratch1); 3266 } 3267 } 3268 %} 3269 3270 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{ 3271 C2_MacroAssembler _masm(&cbuf); 3272 Register src_reg = as_Register($src$$reg); 3273 Register base = as_Register($mem$$base); 3274 int index = $mem$$index; 3275 int scale = $mem$$scale; 3276 int disp = $mem$$disp; 3277 if (index == -1) { 3278 if (disp != 0) { 3279 __ lea(rscratch2, Address(base, disp)); 3280 __ stlxr(rscratch1, src_reg, rscratch2); 3281 } else { 3282 // TODO 3283 // should we ever get anything other than this case? 3284 __ stlxr(rscratch1, src_reg, base); 3285 } 3286 } else { 3287 Register index_reg = as_Register(index); 3288 if (disp == 0) { 3289 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3290 __ stlxr(rscratch1, src_reg, rscratch2); 3291 } else { 3292 __ lea(rscratch2, Address(base, disp)); 3293 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3294 __ stlxr(rscratch1, src_reg, rscratch2); 3295 } 3296 } 3297 __ cmpw(rscratch1, zr); 3298 %} 3299 3300 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3301 C2_MacroAssembler _masm(&cbuf); 3302 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3303 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3304 Assembler::xword, /*acquire*/ false, /*release*/ true, 3305 /*weak*/ false, noreg); 3306 %} 3307 3308 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3309 C2_MacroAssembler _masm(&cbuf); 3310 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3311 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3312 Assembler::word, /*acquire*/ false, /*release*/ true, 3313 /*weak*/ false, noreg); 3314 %} 3315 3316 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3317 C2_MacroAssembler _masm(&cbuf); 3318 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3319 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3320 Assembler::halfword, /*acquire*/ false, /*release*/ true, 3321 /*weak*/ false, noreg); 3322 %} 3323 3324 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3325 C2_MacroAssembler _masm(&cbuf); 3326 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3327 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3328 Assembler::byte, /*acquire*/ false, /*release*/ true, 3329 /*weak*/ false, noreg); 3330 %} 3331 3332 3333 // The only difference between aarch64_enc_cmpxchg and 3334 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3335 // CompareAndSwap sequence to serve as a barrier on acquiring a 3336 // lock. 3337 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3338 C2_MacroAssembler _masm(&cbuf); 3339 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3340 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3341 Assembler::xword, /*acquire*/ true, /*release*/ true, 3342 /*weak*/ false, noreg); 3343 %} 3344 3345 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3346 C2_MacroAssembler _masm(&cbuf); 3347 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3348 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3349 Assembler::word, /*acquire*/ true, /*release*/ true, 3350 /*weak*/ false, noreg); 3351 %} 3352 3353 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3354 C2_MacroAssembler _masm(&cbuf); 3355 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3356 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3357 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3358 /*weak*/ false, noreg); 3359 %} 3360 3361 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3362 C2_MacroAssembler _masm(&cbuf); 3363 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3364 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3365 Assembler::byte, /*acquire*/ true, /*release*/ true, 3366 /*weak*/ false, noreg); 3367 %} 3368 3369 // auxiliary used for CompareAndSwapX to set result register 3370 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3371 C2_MacroAssembler _masm(&cbuf); 3372 Register res_reg = as_Register($res$$reg); 3373 __ cset(res_reg, Assembler::EQ); 3374 %} 3375 3376 // prefetch encodings 3377 3378 enc_class aarch64_enc_prefetchw(memory mem) %{ 3379 C2_MacroAssembler _masm(&cbuf); 3380 Register base = as_Register($mem$$base); 3381 int index = $mem$$index; 3382 int scale = $mem$$scale; 3383 int disp = $mem$$disp; 3384 if (index == -1) { 3385 __ prfm(Address(base, disp), PSTL1KEEP); 3386 } else { 3387 Register index_reg = as_Register(index); 3388 if (disp == 0) { 3389 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3390 } else { 3391 __ lea(rscratch1, Address(base, disp)); 3392 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3393 } 3394 } 3395 %} 3396 3397 /// mov envcodings 3398 3399 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3400 C2_MacroAssembler _masm(&cbuf); 3401 uint32_t con = (uint32_t)$src$$constant; 3402 Register dst_reg = as_Register($dst$$reg); 3403 if (con == 0) { 3404 __ movw(dst_reg, zr); 3405 } else { 3406 __ movw(dst_reg, con); 3407 } 3408 %} 3409 3410 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3411 C2_MacroAssembler _masm(&cbuf); 3412 Register dst_reg = as_Register($dst$$reg); 3413 uint64_t con = (uint64_t)$src$$constant; 3414 if (con == 0) { 3415 __ mov(dst_reg, zr); 3416 } else { 3417 __ mov(dst_reg, con); 3418 } 3419 %} 3420 3421 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3422 C2_MacroAssembler _masm(&cbuf); 3423 Register dst_reg = as_Register($dst$$reg); 3424 address con = (address)$src$$constant; 3425 if (con == nullptr || con == (address)1) { 3426 ShouldNotReachHere(); 3427 } else { 3428 relocInfo::relocType rtype = $src->constant_reloc(); 3429 if (rtype == relocInfo::oop_type) { 3430 __ movoop(dst_reg, (jobject)con); 3431 } else if (rtype == relocInfo::metadata_type) { 3432 __ mov_metadata(dst_reg, (Metadata*)con); 3433 } else { 3434 assert(rtype == relocInfo::none, "unexpected reloc type"); 3435 if (! __ is_valid_AArch64_address(con) || 3436 con < (address)(uintptr_t)os::vm_page_size()) { 3437 __ mov(dst_reg, con); 3438 } else { 3439 uint64_t offset; 3440 __ adrp(dst_reg, con, offset); 3441 __ add(dst_reg, dst_reg, offset); 3442 } 3443 } 3444 } 3445 %} 3446 3447 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3448 C2_MacroAssembler _masm(&cbuf); 3449 Register dst_reg = as_Register($dst$$reg); 3450 __ mov(dst_reg, zr); 3451 %} 3452 3453 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3454 C2_MacroAssembler _masm(&cbuf); 3455 Register dst_reg = as_Register($dst$$reg); 3456 __ mov(dst_reg, (uint64_t)1); 3457 %} 3458 3459 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3460 C2_MacroAssembler _masm(&cbuf); 3461 __ load_byte_map_base($dst$$Register); 3462 %} 3463 3464 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3465 C2_MacroAssembler _masm(&cbuf); 3466 Register dst_reg = as_Register($dst$$reg); 3467 address con = (address)$src$$constant; 3468 if (con == nullptr) { 3469 ShouldNotReachHere(); 3470 } else { 3471 relocInfo::relocType rtype = $src->constant_reloc(); 3472 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3473 __ set_narrow_oop(dst_reg, (jobject)con); 3474 } 3475 %} 3476 3477 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3478 C2_MacroAssembler _masm(&cbuf); 3479 Register dst_reg = as_Register($dst$$reg); 3480 __ mov(dst_reg, zr); 3481 %} 3482 3483 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3484 C2_MacroAssembler _masm(&cbuf); 3485 Register dst_reg = as_Register($dst$$reg); 3486 address con = (address)$src$$constant; 3487 if (con == nullptr) { 3488 ShouldNotReachHere(); 3489 } else { 3490 relocInfo::relocType rtype = $src->constant_reloc(); 3491 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3492 __ set_narrow_klass(dst_reg, (Klass *)con); 3493 } 3494 %} 3495 3496 // arithmetic encodings 3497 3498 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3499 C2_MacroAssembler _masm(&cbuf); 3500 Register dst_reg = as_Register($dst$$reg); 3501 Register src_reg = as_Register($src1$$reg); 3502 int32_t con = (int32_t)$src2$$constant; 3503 // add has primary == 0, subtract has primary == 1 3504 if ($primary) { con = -con; } 3505 if (con < 0) { 3506 __ subw(dst_reg, src_reg, -con); 3507 } else { 3508 __ addw(dst_reg, src_reg, con); 3509 } 3510 %} 3511 3512 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3513 C2_MacroAssembler _masm(&cbuf); 3514 Register dst_reg = as_Register($dst$$reg); 3515 Register src_reg = as_Register($src1$$reg); 3516 int32_t con = (int32_t)$src2$$constant; 3517 // add has primary == 0, subtract has primary == 1 3518 if ($primary) { con = -con; } 3519 if (con < 0) { 3520 __ sub(dst_reg, src_reg, -con); 3521 } else { 3522 __ add(dst_reg, src_reg, con); 3523 } 3524 %} 3525 3526 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3527 C2_MacroAssembler _masm(&cbuf); 3528 Register dst_reg = as_Register($dst$$reg); 3529 Register src1_reg = as_Register($src1$$reg); 3530 Register src2_reg = as_Register($src2$$reg); 3531 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3532 %} 3533 3534 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3535 C2_MacroAssembler _masm(&cbuf); 3536 Register dst_reg = as_Register($dst$$reg); 3537 Register src1_reg = as_Register($src1$$reg); 3538 Register src2_reg = as_Register($src2$$reg); 3539 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3540 %} 3541 3542 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3543 C2_MacroAssembler _masm(&cbuf); 3544 Register dst_reg = as_Register($dst$$reg); 3545 Register src1_reg = as_Register($src1$$reg); 3546 Register src2_reg = as_Register($src2$$reg); 3547 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3548 %} 3549 3550 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3551 C2_MacroAssembler _masm(&cbuf); 3552 Register dst_reg = as_Register($dst$$reg); 3553 Register src1_reg = as_Register($src1$$reg); 3554 Register src2_reg = as_Register($src2$$reg); 3555 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3556 %} 3557 3558 // compare instruction encodings 3559 3560 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3561 C2_MacroAssembler _masm(&cbuf); 3562 Register reg1 = as_Register($src1$$reg); 3563 Register reg2 = as_Register($src2$$reg); 3564 __ cmpw(reg1, reg2); 3565 %} 3566 3567 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3568 C2_MacroAssembler _masm(&cbuf); 3569 Register reg = as_Register($src1$$reg); 3570 int32_t val = $src2$$constant; 3571 if (val >= 0) { 3572 __ subsw(zr, reg, val); 3573 } else { 3574 __ addsw(zr, reg, -val); 3575 } 3576 %} 3577 3578 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3579 C2_MacroAssembler _masm(&cbuf); 3580 Register reg1 = as_Register($src1$$reg); 3581 uint32_t val = (uint32_t)$src2$$constant; 3582 __ movw(rscratch1, val); 3583 __ cmpw(reg1, rscratch1); 3584 %} 3585 3586 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3587 C2_MacroAssembler _masm(&cbuf); 3588 Register reg1 = as_Register($src1$$reg); 3589 Register reg2 = as_Register($src2$$reg); 3590 __ cmp(reg1, reg2); 3591 %} 3592 3593 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3594 C2_MacroAssembler _masm(&cbuf); 3595 Register reg = as_Register($src1$$reg); 3596 int64_t val = $src2$$constant; 3597 if (val >= 0) { 3598 __ subs(zr, reg, val); 3599 } else if (val != -val) { 3600 __ adds(zr, reg, -val); 3601 } else { 3602 // aargh, Long.MIN_VALUE is a special case 3603 __ orr(rscratch1, zr, (uint64_t)val); 3604 __ subs(zr, reg, rscratch1); 3605 } 3606 %} 3607 3608 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3609 C2_MacroAssembler _masm(&cbuf); 3610 Register reg1 = as_Register($src1$$reg); 3611 uint64_t val = (uint64_t)$src2$$constant; 3612 __ mov(rscratch1, val); 3613 __ cmp(reg1, rscratch1); 3614 %} 3615 3616 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3617 C2_MacroAssembler _masm(&cbuf); 3618 Register reg1 = as_Register($src1$$reg); 3619 Register reg2 = as_Register($src2$$reg); 3620 __ cmp(reg1, reg2); 3621 %} 3622 3623 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3624 C2_MacroAssembler _masm(&cbuf); 3625 Register reg1 = as_Register($src1$$reg); 3626 Register reg2 = as_Register($src2$$reg); 3627 __ cmpw(reg1, reg2); 3628 %} 3629 3630 enc_class aarch64_enc_testp(iRegP src) %{ 3631 C2_MacroAssembler _masm(&cbuf); 3632 Register reg = as_Register($src$$reg); 3633 __ cmp(reg, zr); 3634 %} 3635 3636 enc_class aarch64_enc_testn(iRegN src) %{ 3637 C2_MacroAssembler _masm(&cbuf); 3638 Register reg = as_Register($src$$reg); 3639 __ cmpw(reg, zr); 3640 %} 3641 3642 enc_class aarch64_enc_b(label lbl) %{ 3643 C2_MacroAssembler _masm(&cbuf); 3644 Label *L = $lbl$$label; 3645 __ b(*L); 3646 %} 3647 3648 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3649 C2_MacroAssembler _masm(&cbuf); 3650 Label *L = $lbl$$label; 3651 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3652 %} 3653 3654 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3655 C2_MacroAssembler _masm(&cbuf); 3656 Label *L = $lbl$$label; 3657 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3658 %} 3659 3660 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3661 %{ 3662 Register sub_reg = as_Register($sub$$reg); 3663 Register super_reg = as_Register($super$$reg); 3664 Register temp_reg = as_Register($temp$$reg); 3665 Register result_reg = as_Register($result$$reg); 3666 3667 Label miss; 3668 C2_MacroAssembler _masm(&cbuf); 3669 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3670 nullptr, &miss, 3671 /*set_cond_codes:*/ true); 3672 if ($primary) { 3673 __ mov(result_reg, zr); 3674 } 3675 __ bind(miss); 3676 %} 3677 3678 enc_class aarch64_enc_java_static_call(method meth) %{ 3679 C2_MacroAssembler _masm(&cbuf); 3680 3681 address addr = (address)$meth$$method; 3682 address call; 3683 if (!_method) { 3684 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3685 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type)); 3686 if (call == nullptr) { 3687 ciEnv::current()->record_failure("CodeCache is full"); 3688 return; 3689 } 3690 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 3691 // The NOP here is purely to ensure that eliding a call to 3692 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 3693 __ nop(); 3694 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 3695 } else { 3696 int method_index = resolved_method_index(cbuf); 3697 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3698 : static_call_Relocation::spec(method_index); 3699 call = __ trampoline_call(Address(addr, rspec)); 3700 if (call == nullptr) { 3701 ciEnv::current()->record_failure("CodeCache is full"); 3702 return; 3703 } 3704 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 3705 // Calls of the same statically bound method can share 3706 // a stub to the interpreter. 3707 cbuf.shared_stub_to_interp_for(_method, call - cbuf.insts_begin()); 3708 } else { 3709 // Emit stub for static call 3710 address stub = CompiledDirectCall::emit_to_interp_stub(cbuf, call); 3711 if (stub == nullptr) { 3712 ciEnv::current()->record_failure("CodeCache is full"); 3713 return; 3714 } 3715 } 3716 } 3717 3718 __ post_call_nop(); 3719 3720 // Only non uncommon_trap calls need to reinitialize ptrue. 3721 if (Compile::current()->max_vector_size() > 0 && uncommon_trap_request() == 0) { 3722 __ reinitialize_ptrue(); 3723 } 3724 %} 3725 3726 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3727 C2_MacroAssembler _masm(&cbuf); 3728 int method_index = resolved_method_index(cbuf); 3729 address call = __ ic_call((address)$meth$$method, method_index); 3730 if (call == nullptr) { 3731 ciEnv::current()->record_failure("CodeCache is full"); 3732 return; 3733 } 3734 __ post_call_nop(); 3735 if (Compile::current()->max_vector_size() > 0) { 3736 __ reinitialize_ptrue(); 3737 } 3738 %} 3739 3740 enc_class aarch64_enc_call_epilog() %{ 3741 C2_MacroAssembler _masm(&cbuf); 3742 if (VerifyStackAtCalls) { 3743 // Check that stack depth is unchanged: find majik cookie on stack 3744 __ call_Unimplemented(); 3745 } 3746 if (tf()->returns_inline_type_as_fields() && !_method->is_method_handle_intrinsic()) { 3747 // The last return value is not set by the callee but used to pass IsInit information to compiled code. 3748 // Search for the corresponding projection, get the register and emit code that initialized it. 3749 uint con = (tf()->range_cc()->cnt() - 1); 3750 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { 3751 ProjNode* proj = fast_out(i)->as_Proj(); 3752 if (proj->_con == con) { 3753 // Set IsInit if r0 is non-null (a non-null value is returned buffered or scalarized) 3754 OptoReg::Name optoReg = ra_->get_reg_first(proj); 3755 VMReg reg = OptoReg::as_VMReg(optoReg, ra_->_framesize, OptoReg::reg2stack(ra_->_matcher._new_SP)); 3756 Register toReg = reg->is_reg() ? reg->as_Register() : rscratch1; 3757 __ cmp(r0, zr); 3758 __ cset(toReg, Assembler::NE); 3759 if (reg->is_stack()) { 3760 int st_off = reg->reg2stack() * VMRegImpl::stack_slot_size; 3761 __ str(toReg, Address(sp, st_off)); 3762 } 3763 break; 3764 } 3765 } 3766 if (return_value_is_used()) { 3767 // An inline type is returned as fields in multiple registers. 3768 // R0 either contains an oop if the inline type is buffered or a pointer 3769 // to the corresponding InlineKlass with the lowest bit set to 1. Zero r0 3770 // if the lowest bit is set to allow C2 to use the oop after null checking. 3771 // r0 &= (r0 & 1) - 1 3772 __ andr(rscratch1, r0, 0x1); 3773 __ sub(rscratch1, rscratch1, 0x1); 3774 __ andr(r0, r0, rscratch1); 3775 } 3776 } 3777 %} 3778 3779 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3780 C2_MacroAssembler _masm(&cbuf); 3781 3782 // some calls to generated routines (arraycopy code) are scheduled 3783 // by C2 as runtime calls. if so we can call them using a br (they 3784 // will be in a reachable segment) otherwise we have to use a blr 3785 // which loads the absolute address into a register. 3786 address entry = (address)$meth$$method; 3787 CodeBlob *cb = CodeCache::find_blob(entry); 3788 if (cb) { 3789 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3790 if (call == nullptr) { 3791 ciEnv::current()->record_failure("CodeCache is full"); 3792 return; 3793 } 3794 __ post_call_nop(); 3795 } else { 3796 Label retaddr; 3797 __ adr(rscratch2, retaddr); 3798 __ lea(rscratch1, RuntimeAddress(entry)); 3799 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3800 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3801 __ blr(rscratch1); 3802 __ bind(retaddr); 3803 __ post_call_nop(); 3804 __ add(sp, sp, 2 * wordSize); 3805 } 3806 if (Compile::current()->max_vector_size() > 0) { 3807 __ reinitialize_ptrue(); 3808 } 3809 %} 3810 3811 enc_class aarch64_enc_rethrow() %{ 3812 C2_MacroAssembler _masm(&cbuf); 3813 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3814 %} 3815 3816 enc_class aarch64_enc_ret() %{ 3817 C2_MacroAssembler _masm(&cbuf); 3818 #ifdef ASSERT 3819 if (Compile::current()->max_vector_size() > 0) { 3820 __ verify_ptrue(); 3821 } 3822 #endif 3823 __ ret(lr); 3824 %} 3825 3826 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3827 C2_MacroAssembler _masm(&cbuf); 3828 Register target_reg = as_Register($jump_target$$reg); 3829 __ br(target_reg); 3830 %} 3831 3832 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3833 C2_MacroAssembler _masm(&cbuf); 3834 Register target_reg = as_Register($jump_target$$reg); 3835 // exception oop should be in r0 3836 // ret addr has been popped into lr 3837 // callee expects it in r3 3838 __ mov(r3, lr); 3839 __ br(target_reg); 3840 %} 3841 3842 %} 3843 3844 //----------FRAME-------------------------------------------------------------- 3845 // Definition of frame structure and management information. 3846 // 3847 // S T A C K L A Y O U T Allocators stack-slot number 3848 // | (to get allocators register number 3849 // G Owned by | | v add OptoReg::stack0()) 3850 // r CALLER | | 3851 // o | +--------+ pad to even-align allocators stack-slot 3852 // w V | pad0 | numbers; owned by CALLER 3853 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3854 // h ^ | in | 5 3855 // | | args | 4 Holes in incoming args owned by SELF 3856 // | | | | 3 3857 // | | +--------+ 3858 // V | | old out| Empty on Intel, window on Sparc 3859 // | old |preserve| Must be even aligned. 3860 // | SP-+--------+----> Matcher::_old_SP, even aligned 3861 // | | in | 3 area for Intel ret address 3862 // Owned by |preserve| Empty on Sparc. 3863 // SELF +--------+ 3864 // | | pad2 | 2 pad to align old SP 3865 // | +--------+ 1 3866 // | | locks | 0 3867 // | +--------+----> OptoReg::stack0(), even aligned 3868 // | | pad1 | 11 pad to align new SP 3869 // | +--------+ 3870 // | | | 10 3871 // | | spills | 9 spills 3872 // V | | 8 (pad0 slot for callee) 3873 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3874 // ^ | out | 7 3875 // | | args | 6 Holes in outgoing args owned by CALLEE 3876 // Owned by +--------+ 3877 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3878 // | new |preserve| Must be even-aligned. 3879 // | SP-+--------+----> Matcher::_new_SP, even aligned 3880 // | | | 3881 // 3882 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3883 // known from SELF's arguments and the Java calling convention. 3884 // Region 6-7 is determined per call site. 3885 // Note 2: If the calling convention leaves holes in the incoming argument 3886 // area, those holes are owned by SELF. Holes in the outgoing area 3887 // are owned by the CALLEE. Holes should not be necessary in the 3888 // incoming area, as the Java calling convention is completely under 3889 // the control of the AD file. Doubles can be sorted and packed to 3890 // avoid holes. Holes in the outgoing arguments may be necessary for 3891 // varargs C calling conventions. 3892 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3893 // even aligned with pad0 as needed. 3894 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3895 // (the latter is true on Intel but is it false on AArch64?) 3896 // region 6-11 is even aligned; it may be padded out more so that 3897 // the region from SP to FP meets the minimum stack alignment. 3898 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3899 // alignment. Region 11, pad1, may be dynamically extended so that 3900 // SP meets the minimum alignment. 3901 3902 frame %{ 3903 // These three registers define part of the calling convention 3904 // between compiled code and the interpreter. 3905 3906 // Inline Cache Register or Method for I2C. 3907 inline_cache_reg(R12); 3908 3909 // Number of stack slots consumed by locking an object 3910 sync_stack_slots(2); 3911 3912 // Compiled code's Frame Pointer 3913 frame_pointer(R31); 3914 3915 // Interpreter stores its frame pointer in a register which is 3916 // stored to the stack by I2CAdaptors. 3917 // I2CAdaptors convert from interpreted java to compiled java. 3918 interpreter_frame_pointer(R29); 3919 3920 // Stack alignment requirement 3921 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3922 3923 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3924 // for calls to C. Supports the var-args backing area for register parms. 3925 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3926 3927 // The after-PROLOG location of the return address. Location of 3928 // return address specifies a type (REG or STACK) and a number 3929 // representing the register number (i.e. - use a register name) or 3930 // stack slot. 3931 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3932 // Otherwise, it is above the locks and verification slot and alignment word 3933 // TODO this may well be correct but need to check why that - 2 is there 3934 // ppc port uses 0 but we definitely need to allow for fixed_slots 3935 // which folds in the space used for monitors 3936 return_addr(STACK - 2 + 3937 align_up((Compile::current()->in_preserve_stack_slots() + 3938 Compile::current()->fixed_slots()), 3939 stack_alignment_in_slots())); 3940 3941 // Location of compiled Java return values. Same as C for now. 3942 return_value 3943 %{ 3944 // TODO do we allow ideal_reg == Op_RegN??? 3945 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3946 "only return normal values"); 3947 3948 static const int lo[Op_RegL + 1] = { // enum name 3949 0, // Op_Node 3950 0, // Op_Set 3951 R0_num, // Op_RegN 3952 R0_num, // Op_RegI 3953 R0_num, // Op_RegP 3954 V0_num, // Op_RegF 3955 V0_num, // Op_RegD 3956 R0_num // Op_RegL 3957 }; 3958 3959 static const int hi[Op_RegL + 1] = { // enum name 3960 0, // Op_Node 3961 0, // Op_Set 3962 OptoReg::Bad, // Op_RegN 3963 OptoReg::Bad, // Op_RegI 3964 R0_H_num, // Op_RegP 3965 OptoReg::Bad, // Op_RegF 3966 V0_H_num, // Op_RegD 3967 R0_H_num // Op_RegL 3968 }; 3969 3970 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3971 %} 3972 %} 3973 3974 //----------ATTRIBUTES--------------------------------------------------------- 3975 //----------Operand Attributes------------------------------------------------- 3976 op_attrib op_cost(1); // Required cost attribute 3977 3978 //----------Instruction Attributes--------------------------------------------- 3979 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3980 ins_attrib ins_size(32); // Required size attribute (in bits) 3981 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3982 // a non-matching short branch variant 3983 // of some long branch? 3984 ins_attrib ins_alignment(4); // Required alignment attribute (must 3985 // be a power of 2) specifies the 3986 // alignment that some part of the 3987 // instruction (not necessarily the 3988 // start) requires. If > 1, a 3989 // compute_padding() function must be 3990 // provided for the instruction 3991 3992 //----------OPERANDS----------------------------------------------------------- 3993 // Operand definitions must precede instruction definitions for correct parsing 3994 // in the ADLC because operands constitute user defined types which are used in 3995 // instruction definitions. 3996 3997 //----------Simple Operands---------------------------------------------------- 3998 3999 // Integer operands 32 bit 4000 // 32 bit immediate 4001 operand immI() 4002 %{ 4003 match(ConI); 4004 4005 op_cost(0); 4006 format %{ %} 4007 interface(CONST_INTER); 4008 %} 4009 4010 // 32 bit zero 4011 operand immI0() 4012 %{ 4013 predicate(n->get_int() == 0); 4014 match(ConI); 4015 4016 op_cost(0); 4017 format %{ %} 4018 interface(CONST_INTER); 4019 %} 4020 4021 // 32 bit unit increment 4022 operand immI_1() 4023 %{ 4024 predicate(n->get_int() == 1); 4025 match(ConI); 4026 4027 op_cost(0); 4028 format %{ %} 4029 interface(CONST_INTER); 4030 %} 4031 4032 // 32 bit unit decrement 4033 operand immI_M1() 4034 %{ 4035 predicate(n->get_int() == -1); 4036 match(ConI); 4037 4038 op_cost(0); 4039 format %{ %} 4040 interface(CONST_INTER); 4041 %} 4042 4043 // Shift values for add/sub extension shift 4044 operand immIExt() 4045 %{ 4046 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 4047 match(ConI); 4048 4049 op_cost(0); 4050 format %{ %} 4051 interface(CONST_INTER); 4052 %} 4053 4054 operand immI_gt_1() 4055 %{ 4056 predicate(n->get_int() > 1); 4057 match(ConI); 4058 4059 op_cost(0); 4060 format %{ %} 4061 interface(CONST_INTER); 4062 %} 4063 4064 operand immI_le_4() 4065 %{ 4066 predicate(n->get_int() <= 4); 4067 match(ConI); 4068 4069 op_cost(0); 4070 format %{ %} 4071 interface(CONST_INTER); 4072 %} 4073 4074 operand immI_16() 4075 %{ 4076 predicate(n->get_int() == 16); 4077 match(ConI); 4078 4079 op_cost(0); 4080 format %{ %} 4081 interface(CONST_INTER); 4082 %} 4083 4084 operand immI_24() 4085 %{ 4086 predicate(n->get_int() == 24); 4087 match(ConI); 4088 4089 op_cost(0); 4090 format %{ %} 4091 interface(CONST_INTER); 4092 %} 4093 4094 operand immI_32() 4095 %{ 4096 predicate(n->get_int() == 32); 4097 match(ConI); 4098 4099 op_cost(0); 4100 format %{ %} 4101 interface(CONST_INTER); 4102 %} 4103 4104 operand immI_48() 4105 %{ 4106 predicate(n->get_int() == 48); 4107 match(ConI); 4108 4109 op_cost(0); 4110 format %{ %} 4111 interface(CONST_INTER); 4112 %} 4113 4114 operand immI_56() 4115 %{ 4116 predicate(n->get_int() == 56); 4117 match(ConI); 4118 4119 op_cost(0); 4120 format %{ %} 4121 interface(CONST_INTER); 4122 %} 4123 4124 operand immI_63() 4125 %{ 4126 predicate(n->get_int() == 63); 4127 match(ConI); 4128 4129 op_cost(0); 4130 format %{ %} 4131 interface(CONST_INTER); 4132 %} 4133 4134 operand immI_64() 4135 %{ 4136 predicate(n->get_int() == 64); 4137 match(ConI); 4138 4139 op_cost(0); 4140 format %{ %} 4141 interface(CONST_INTER); 4142 %} 4143 4144 operand immI_255() 4145 %{ 4146 predicate(n->get_int() == 255); 4147 match(ConI); 4148 4149 op_cost(0); 4150 format %{ %} 4151 interface(CONST_INTER); 4152 %} 4153 4154 operand immI_65535() 4155 %{ 4156 predicate(n->get_int() == 65535); 4157 match(ConI); 4158 4159 op_cost(0); 4160 format %{ %} 4161 interface(CONST_INTER); 4162 %} 4163 4164 operand immI_positive() 4165 %{ 4166 predicate(n->get_int() > 0); 4167 match(ConI); 4168 4169 op_cost(0); 4170 format %{ %} 4171 interface(CONST_INTER); 4172 %} 4173 4174 // BoolTest condition for signed compare 4175 operand immI_cmp_cond() 4176 %{ 4177 predicate(!Matcher::is_unsigned_booltest_pred(n->get_int())); 4178 match(ConI); 4179 4180 op_cost(0); 4181 format %{ %} 4182 interface(CONST_INTER); 4183 %} 4184 4185 // BoolTest condition for unsigned compare 4186 operand immI_cmpU_cond() 4187 %{ 4188 predicate(Matcher::is_unsigned_booltest_pred(n->get_int())); 4189 match(ConI); 4190 4191 op_cost(0); 4192 format %{ %} 4193 interface(CONST_INTER); 4194 %} 4195 4196 operand immL_255() 4197 %{ 4198 predicate(n->get_long() == 255L); 4199 match(ConL); 4200 4201 op_cost(0); 4202 format %{ %} 4203 interface(CONST_INTER); 4204 %} 4205 4206 operand immL_65535() 4207 %{ 4208 predicate(n->get_long() == 65535L); 4209 match(ConL); 4210 4211 op_cost(0); 4212 format %{ %} 4213 interface(CONST_INTER); 4214 %} 4215 4216 operand immL_4294967295() 4217 %{ 4218 predicate(n->get_long() == 4294967295L); 4219 match(ConL); 4220 4221 op_cost(0); 4222 format %{ %} 4223 interface(CONST_INTER); 4224 %} 4225 4226 operand immL_bitmask() 4227 %{ 4228 predicate((n->get_long() != 0) 4229 && ((n->get_long() & 0xc000000000000000l) == 0) 4230 && is_power_of_2(n->get_long() + 1)); 4231 match(ConL); 4232 4233 op_cost(0); 4234 format %{ %} 4235 interface(CONST_INTER); 4236 %} 4237 4238 operand immI_bitmask() 4239 %{ 4240 predicate((n->get_int() != 0) 4241 && ((n->get_int() & 0xc0000000) == 0) 4242 && is_power_of_2(n->get_int() + 1)); 4243 match(ConI); 4244 4245 op_cost(0); 4246 format %{ %} 4247 interface(CONST_INTER); 4248 %} 4249 4250 operand immL_positive_bitmaskI() 4251 %{ 4252 predicate((n->get_long() != 0) 4253 && ((julong)n->get_long() < 0x80000000ULL) 4254 && is_power_of_2(n->get_long() + 1)); 4255 match(ConL); 4256 4257 op_cost(0); 4258 format %{ %} 4259 interface(CONST_INTER); 4260 %} 4261 4262 // Scale values for scaled offset addressing modes (up to long but not quad) 4263 operand immIScale() 4264 %{ 4265 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4266 match(ConI); 4267 4268 op_cost(0); 4269 format %{ %} 4270 interface(CONST_INTER); 4271 %} 4272 4273 // 26 bit signed offset -- for pc-relative branches 4274 operand immI26() 4275 %{ 4276 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4277 match(ConI); 4278 4279 op_cost(0); 4280 format %{ %} 4281 interface(CONST_INTER); 4282 %} 4283 4284 // 19 bit signed offset -- for pc-relative loads 4285 operand immI19() 4286 %{ 4287 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4288 match(ConI); 4289 4290 op_cost(0); 4291 format %{ %} 4292 interface(CONST_INTER); 4293 %} 4294 4295 // 5 bit signed integer 4296 operand immI5() 4297 %{ 4298 predicate(Assembler::is_simm(n->get_int(), 5)); 4299 match(ConI); 4300 4301 op_cost(0); 4302 format %{ %} 4303 interface(CONST_INTER); 4304 %} 4305 4306 // 7 bit unsigned integer 4307 operand immIU7() 4308 %{ 4309 predicate(Assembler::is_uimm(n->get_int(), 7)); 4310 match(ConI); 4311 4312 op_cost(0); 4313 format %{ %} 4314 interface(CONST_INTER); 4315 %} 4316 4317 // 12 bit unsigned offset -- for base plus immediate loads 4318 operand immIU12() 4319 %{ 4320 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4321 match(ConI); 4322 4323 op_cost(0); 4324 format %{ %} 4325 interface(CONST_INTER); 4326 %} 4327 4328 operand immLU12() 4329 %{ 4330 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4331 match(ConL); 4332 4333 op_cost(0); 4334 format %{ %} 4335 interface(CONST_INTER); 4336 %} 4337 4338 // Offset for scaled or unscaled immediate loads and stores 4339 operand immIOffset() 4340 %{ 4341 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4342 match(ConI); 4343 4344 op_cost(0); 4345 format %{ %} 4346 interface(CONST_INTER); 4347 %} 4348 4349 operand immIOffset1() 4350 %{ 4351 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4352 match(ConI); 4353 4354 op_cost(0); 4355 format %{ %} 4356 interface(CONST_INTER); 4357 %} 4358 4359 operand immIOffset2() 4360 %{ 4361 predicate(Address::offset_ok_for_immed(n->get_int(), 1)); 4362 match(ConI); 4363 4364 op_cost(0); 4365 format %{ %} 4366 interface(CONST_INTER); 4367 %} 4368 4369 operand immIOffset4() 4370 %{ 4371 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4372 match(ConI); 4373 4374 op_cost(0); 4375 format %{ %} 4376 interface(CONST_INTER); 4377 %} 4378 4379 operand immIOffset8() 4380 %{ 4381 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4382 match(ConI); 4383 4384 op_cost(0); 4385 format %{ %} 4386 interface(CONST_INTER); 4387 %} 4388 4389 operand immIOffset16() 4390 %{ 4391 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4392 match(ConI); 4393 4394 op_cost(0); 4395 format %{ %} 4396 interface(CONST_INTER); 4397 %} 4398 4399 operand immLoffset() 4400 %{ 4401 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4402 match(ConL); 4403 4404 op_cost(0); 4405 format %{ %} 4406 interface(CONST_INTER); 4407 %} 4408 4409 operand immLoffset1() 4410 %{ 4411 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4412 match(ConL); 4413 4414 op_cost(0); 4415 format %{ %} 4416 interface(CONST_INTER); 4417 %} 4418 4419 operand immLoffset2() 4420 %{ 4421 predicate(Address::offset_ok_for_immed(n->get_long(), 1)); 4422 match(ConL); 4423 4424 op_cost(0); 4425 format %{ %} 4426 interface(CONST_INTER); 4427 %} 4428 4429 operand immLoffset4() 4430 %{ 4431 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4432 match(ConL); 4433 4434 op_cost(0); 4435 format %{ %} 4436 interface(CONST_INTER); 4437 %} 4438 4439 operand immLoffset8() 4440 %{ 4441 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4442 match(ConL); 4443 4444 op_cost(0); 4445 format %{ %} 4446 interface(CONST_INTER); 4447 %} 4448 4449 operand immLoffset16() 4450 %{ 4451 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4452 match(ConL); 4453 4454 op_cost(0); 4455 format %{ %} 4456 interface(CONST_INTER); 4457 %} 4458 4459 // 5 bit signed long integer 4460 operand immL5() 4461 %{ 4462 predicate(Assembler::is_simm(n->get_long(), 5)); 4463 match(ConL); 4464 4465 op_cost(0); 4466 format %{ %} 4467 interface(CONST_INTER); 4468 %} 4469 4470 // 7 bit unsigned long integer 4471 operand immLU7() 4472 %{ 4473 predicate(Assembler::is_uimm(n->get_long(), 7)); 4474 match(ConL); 4475 4476 op_cost(0); 4477 format %{ %} 4478 interface(CONST_INTER); 4479 %} 4480 4481 // 8 bit signed value. 4482 operand immI8() 4483 %{ 4484 predicate(n->get_int() <= 127 && n->get_int() >= -128); 4485 match(ConI); 4486 4487 op_cost(0); 4488 format %{ %} 4489 interface(CONST_INTER); 4490 %} 4491 4492 // 8 bit signed value (simm8), or #simm8 LSL 8. 4493 operand immI8_shift8() 4494 %{ 4495 predicate((n->get_int() <= 127 && n->get_int() >= -128) || 4496 (n->get_int() <= 32512 && n->get_int() >= -32768 && (n->get_int() & 0xff) == 0)); 4497 match(ConI); 4498 4499 op_cost(0); 4500 format %{ %} 4501 interface(CONST_INTER); 4502 %} 4503 4504 // 8 bit signed value (simm8), or #simm8 LSL 8. 4505 operand immL8_shift8() 4506 %{ 4507 predicate((n->get_long() <= 127 && n->get_long() >= -128) || 4508 (n->get_long() <= 32512 && n->get_long() >= -32768 && (n->get_long() & 0xff) == 0)); 4509 match(ConL); 4510 4511 op_cost(0); 4512 format %{ %} 4513 interface(CONST_INTER); 4514 %} 4515 4516 // 8 bit integer valid for vector add sub immediate 4517 operand immBAddSubV() 4518 %{ 4519 predicate(n->get_int() <= 255 && n->get_int() >= -255); 4520 match(ConI); 4521 4522 op_cost(0); 4523 format %{ %} 4524 interface(CONST_INTER); 4525 %} 4526 4527 // 32 bit integer valid for add sub immediate 4528 operand immIAddSub() 4529 %{ 4530 predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int())); 4531 match(ConI); 4532 op_cost(0); 4533 format %{ %} 4534 interface(CONST_INTER); 4535 %} 4536 4537 // 32 bit integer valid for vector add sub immediate 4538 operand immIAddSubV() 4539 %{ 4540 predicate(Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)n->get_int())); 4541 match(ConI); 4542 4543 op_cost(0); 4544 format %{ %} 4545 interface(CONST_INTER); 4546 %} 4547 4548 // 32 bit unsigned integer valid for logical immediate 4549 4550 operand immBLog() 4551 %{ 4552 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerByte, (uint64_t)n->get_int())); 4553 match(ConI); 4554 4555 op_cost(0); 4556 format %{ %} 4557 interface(CONST_INTER); 4558 %} 4559 4560 operand immSLog() 4561 %{ 4562 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerShort, (uint64_t)n->get_int())); 4563 match(ConI); 4564 4565 op_cost(0); 4566 format %{ %} 4567 interface(CONST_INTER); 4568 %} 4569 4570 operand immILog() 4571 %{ 4572 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int())); 4573 match(ConI); 4574 4575 op_cost(0); 4576 format %{ %} 4577 interface(CONST_INTER); 4578 %} 4579 4580 // Integer operands 64 bit 4581 // 64 bit immediate 4582 operand immL() 4583 %{ 4584 match(ConL); 4585 4586 op_cost(0); 4587 format %{ %} 4588 interface(CONST_INTER); 4589 %} 4590 4591 // 64 bit zero 4592 operand immL0() 4593 %{ 4594 predicate(n->get_long() == 0); 4595 match(ConL); 4596 4597 op_cost(0); 4598 format %{ %} 4599 interface(CONST_INTER); 4600 %} 4601 4602 // 64 bit unit increment 4603 operand immL_1() 4604 %{ 4605 predicate(n->get_long() == 1); 4606 match(ConL); 4607 4608 op_cost(0); 4609 format %{ %} 4610 interface(CONST_INTER); 4611 %} 4612 4613 // 64 bit unit decrement 4614 operand immL_M1() 4615 %{ 4616 predicate(n->get_long() == -1); 4617 match(ConL); 4618 4619 op_cost(0); 4620 format %{ %} 4621 interface(CONST_INTER); 4622 %} 4623 4624 // 32 bit offset of pc in thread anchor 4625 4626 operand immL_pc_off() 4627 %{ 4628 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4629 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4630 match(ConL); 4631 4632 op_cost(0); 4633 format %{ %} 4634 interface(CONST_INTER); 4635 %} 4636 4637 // 64 bit integer valid for add sub immediate 4638 operand immLAddSub() 4639 %{ 4640 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4641 match(ConL); 4642 op_cost(0); 4643 format %{ %} 4644 interface(CONST_INTER); 4645 %} 4646 4647 // 64 bit integer valid for addv subv immediate 4648 operand immLAddSubV() 4649 %{ 4650 predicate(Assembler::operand_valid_for_sve_add_sub_immediate(n->get_long())); 4651 match(ConL); 4652 4653 op_cost(0); 4654 format %{ %} 4655 interface(CONST_INTER); 4656 %} 4657 4658 // 64 bit integer valid for logical immediate 4659 operand immLLog() 4660 %{ 4661 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long())); 4662 match(ConL); 4663 op_cost(0); 4664 format %{ %} 4665 interface(CONST_INTER); 4666 %} 4667 4668 // Long Immediate: low 32-bit mask 4669 operand immL_32bits() 4670 %{ 4671 predicate(n->get_long() == 0xFFFFFFFFL); 4672 match(ConL); 4673 op_cost(0); 4674 format %{ %} 4675 interface(CONST_INTER); 4676 %} 4677 4678 // Pointer operands 4679 // Pointer Immediate 4680 operand immP() 4681 %{ 4682 match(ConP); 4683 4684 op_cost(0); 4685 format %{ %} 4686 interface(CONST_INTER); 4687 %} 4688 4689 // Null Pointer Immediate 4690 operand immP0() 4691 %{ 4692 predicate(n->get_ptr() == 0); 4693 match(ConP); 4694 4695 op_cost(0); 4696 format %{ %} 4697 interface(CONST_INTER); 4698 %} 4699 4700 // Pointer Immediate One 4701 // this is used in object initialization (initial object header) 4702 operand immP_1() 4703 %{ 4704 predicate(n->get_ptr() == 1); 4705 match(ConP); 4706 4707 op_cost(0); 4708 format %{ %} 4709 interface(CONST_INTER); 4710 %} 4711 4712 // Card Table Byte Map Base 4713 operand immByteMapBase() 4714 %{ 4715 // Get base of card map 4716 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4717 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4718 match(ConP); 4719 4720 op_cost(0); 4721 format %{ %} 4722 interface(CONST_INTER); 4723 %} 4724 4725 // Pointer Immediate Minus One 4726 // this is used when we want to write the current PC to the thread anchor 4727 operand immP_M1() 4728 %{ 4729 predicate(n->get_ptr() == -1); 4730 match(ConP); 4731 4732 op_cost(0); 4733 format %{ %} 4734 interface(CONST_INTER); 4735 %} 4736 4737 // Pointer Immediate Minus Two 4738 // this is used when we want to write the current PC to the thread anchor 4739 operand immP_M2() 4740 %{ 4741 predicate(n->get_ptr() == -2); 4742 match(ConP); 4743 4744 op_cost(0); 4745 format %{ %} 4746 interface(CONST_INTER); 4747 %} 4748 4749 // Float and Double operands 4750 // Double Immediate 4751 operand immD() 4752 %{ 4753 match(ConD); 4754 op_cost(0); 4755 format %{ %} 4756 interface(CONST_INTER); 4757 %} 4758 4759 // Double Immediate: +0.0d 4760 operand immD0() 4761 %{ 4762 predicate(jlong_cast(n->getd()) == 0); 4763 match(ConD); 4764 4765 op_cost(0); 4766 format %{ %} 4767 interface(CONST_INTER); 4768 %} 4769 4770 // constant 'double +0.0'. 4771 operand immDPacked() 4772 %{ 4773 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4774 match(ConD); 4775 op_cost(0); 4776 format %{ %} 4777 interface(CONST_INTER); 4778 %} 4779 4780 // Float Immediate 4781 operand immF() 4782 %{ 4783 match(ConF); 4784 op_cost(0); 4785 format %{ %} 4786 interface(CONST_INTER); 4787 %} 4788 4789 // Float Immediate: +0.0f. 4790 operand immF0() 4791 %{ 4792 predicate(jint_cast(n->getf()) == 0); 4793 match(ConF); 4794 4795 op_cost(0); 4796 format %{ %} 4797 interface(CONST_INTER); 4798 %} 4799 4800 // 4801 operand immFPacked() 4802 %{ 4803 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4804 match(ConF); 4805 op_cost(0); 4806 format %{ %} 4807 interface(CONST_INTER); 4808 %} 4809 4810 // Narrow pointer operands 4811 // Narrow Pointer Immediate 4812 operand immN() 4813 %{ 4814 match(ConN); 4815 4816 op_cost(0); 4817 format %{ %} 4818 interface(CONST_INTER); 4819 %} 4820 4821 // Narrow Null Pointer Immediate 4822 operand immN0() 4823 %{ 4824 predicate(n->get_narrowcon() == 0); 4825 match(ConN); 4826 4827 op_cost(0); 4828 format %{ %} 4829 interface(CONST_INTER); 4830 %} 4831 4832 operand immNKlass() 4833 %{ 4834 match(ConNKlass); 4835 4836 op_cost(0); 4837 format %{ %} 4838 interface(CONST_INTER); 4839 %} 4840 4841 // Integer 32 bit Register Operands 4842 // Integer 32 bitRegister (excludes SP) 4843 operand iRegI() 4844 %{ 4845 constraint(ALLOC_IN_RC(any_reg32)); 4846 match(RegI); 4847 match(iRegINoSp); 4848 op_cost(0); 4849 format %{ %} 4850 interface(REG_INTER); 4851 %} 4852 4853 // Integer 32 bit Register not Special 4854 operand iRegINoSp() 4855 %{ 4856 constraint(ALLOC_IN_RC(no_special_reg32)); 4857 match(RegI); 4858 op_cost(0); 4859 format %{ %} 4860 interface(REG_INTER); 4861 %} 4862 4863 // Integer 64 bit Register Operands 4864 // Integer 64 bit Register (includes SP) 4865 operand iRegL() 4866 %{ 4867 constraint(ALLOC_IN_RC(any_reg)); 4868 match(RegL); 4869 match(iRegLNoSp); 4870 op_cost(0); 4871 format %{ %} 4872 interface(REG_INTER); 4873 %} 4874 4875 // Integer 64 bit Register not Special 4876 operand iRegLNoSp() 4877 %{ 4878 constraint(ALLOC_IN_RC(no_special_reg)); 4879 match(RegL); 4880 match(iRegL_R0); 4881 format %{ %} 4882 interface(REG_INTER); 4883 %} 4884 4885 // Pointer Register Operands 4886 // Pointer Register 4887 operand iRegP() 4888 %{ 4889 constraint(ALLOC_IN_RC(ptr_reg)); 4890 match(RegP); 4891 match(iRegPNoSp); 4892 match(iRegP_R0); 4893 //match(iRegP_R2); 4894 //match(iRegP_R4); 4895 match(iRegP_R5); 4896 match(thread_RegP); 4897 op_cost(0); 4898 format %{ %} 4899 interface(REG_INTER); 4900 %} 4901 4902 // Pointer 64 bit Register not Special 4903 operand iRegPNoSp() 4904 %{ 4905 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4906 match(RegP); 4907 // match(iRegP); 4908 // match(iRegP_R0); 4909 // match(iRegP_R2); 4910 // match(iRegP_R4); 4911 // match(iRegP_R5); 4912 // match(thread_RegP); 4913 op_cost(0); 4914 format %{ %} 4915 interface(REG_INTER); 4916 %} 4917 4918 // Pointer 64 bit Register R0 only 4919 operand iRegP_R0() 4920 %{ 4921 constraint(ALLOC_IN_RC(r0_reg)); 4922 match(RegP); 4923 // match(iRegP); 4924 match(iRegPNoSp); 4925 op_cost(0); 4926 format %{ %} 4927 interface(REG_INTER); 4928 %} 4929 4930 // Pointer 64 bit Register R1 only 4931 operand iRegP_R1() 4932 %{ 4933 constraint(ALLOC_IN_RC(r1_reg)); 4934 match(RegP); 4935 // match(iRegP); 4936 match(iRegPNoSp); 4937 op_cost(0); 4938 format %{ %} 4939 interface(REG_INTER); 4940 %} 4941 4942 // Pointer 64 bit Register R2 only 4943 operand iRegP_R2() 4944 %{ 4945 constraint(ALLOC_IN_RC(r2_reg)); 4946 match(RegP); 4947 // match(iRegP); 4948 match(iRegPNoSp); 4949 op_cost(0); 4950 format %{ %} 4951 interface(REG_INTER); 4952 %} 4953 4954 // Pointer 64 bit Register R3 only 4955 operand iRegP_R3() 4956 %{ 4957 constraint(ALLOC_IN_RC(r3_reg)); 4958 match(RegP); 4959 // match(iRegP); 4960 match(iRegPNoSp); 4961 op_cost(0); 4962 format %{ %} 4963 interface(REG_INTER); 4964 %} 4965 4966 // Pointer 64 bit Register R4 only 4967 operand iRegP_R4() 4968 %{ 4969 constraint(ALLOC_IN_RC(r4_reg)); 4970 match(RegP); 4971 // match(iRegP); 4972 match(iRegPNoSp); 4973 op_cost(0); 4974 format %{ %} 4975 interface(REG_INTER); 4976 %} 4977 4978 // Pointer 64 bit Register R5 only 4979 operand iRegP_R5() 4980 %{ 4981 constraint(ALLOC_IN_RC(r5_reg)); 4982 match(RegP); 4983 // match(iRegP); 4984 match(iRegPNoSp); 4985 op_cost(0); 4986 format %{ %} 4987 interface(REG_INTER); 4988 %} 4989 4990 // Pointer 64 bit Register R10 only 4991 operand iRegP_R10() 4992 %{ 4993 constraint(ALLOC_IN_RC(r10_reg)); 4994 match(RegP); 4995 // match(iRegP); 4996 match(iRegPNoSp); 4997 op_cost(0); 4998 format %{ %} 4999 interface(REG_INTER); 5000 %} 5001 5002 // Long 64 bit Register R0 only 5003 operand iRegL_R0() 5004 %{ 5005 constraint(ALLOC_IN_RC(r0_reg)); 5006 match(RegL); 5007 match(iRegLNoSp); 5008 op_cost(0); 5009 format %{ %} 5010 interface(REG_INTER); 5011 %} 5012 5013 // Long 64 bit Register R2 only 5014 operand iRegL_R2() 5015 %{ 5016 constraint(ALLOC_IN_RC(r2_reg)); 5017 match(RegL); 5018 match(iRegLNoSp); 5019 op_cost(0); 5020 format %{ %} 5021 interface(REG_INTER); 5022 %} 5023 5024 // Long 64 bit Register R3 only 5025 operand iRegL_R3() 5026 %{ 5027 constraint(ALLOC_IN_RC(r3_reg)); 5028 match(RegL); 5029 match(iRegLNoSp); 5030 op_cost(0); 5031 format %{ %} 5032 interface(REG_INTER); 5033 %} 5034 5035 // Long 64 bit Register R11 only 5036 operand iRegL_R11() 5037 %{ 5038 constraint(ALLOC_IN_RC(r11_reg)); 5039 match(RegL); 5040 match(iRegLNoSp); 5041 op_cost(0); 5042 format %{ %} 5043 interface(REG_INTER); 5044 %} 5045 5046 // Pointer 64 bit Register FP only 5047 operand iRegP_FP() 5048 %{ 5049 constraint(ALLOC_IN_RC(fp_reg)); 5050 match(RegP); 5051 // match(iRegP); 5052 op_cost(0); 5053 format %{ %} 5054 interface(REG_INTER); 5055 %} 5056 5057 // Register R0 only 5058 operand iRegI_R0() 5059 %{ 5060 constraint(ALLOC_IN_RC(int_r0_reg)); 5061 match(RegI); 5062 match(iRegINoSp); 5063 op_cost(0); 5064 format %{ %} 5065 interface(REG_INTER); 5066 %} 5067 5068 // Register R2 only 5069 operand iRegI_R2() 5070 %{ 5071 constraint(ALLOC_IN_RC(int_r2_reg)); 5072 match(RegI); 5073 match(iRegINoSp); 5074 op_cost(0); 5075 format %{ %} 5076 interface(REG_INTER); 5077 %} 5078 5079 // Register R3 only 5080 operand iRegI_R3() 5081 %{ 5082 constraint(ALLOC_IN_RC(int_r3_reg)); 5083 match(RegI); 5084 match(iRegINoSp); 5085 op_cost(0); 5086 format %{ %} 5087 interface(REG_INTER); 5088 %} 5089 5090 5091 // Register R4 only 5092 operand iRegI_R4() 5093 %{ 5094 constraint(ALLOC_IN_RC(int_r4_reg)); 5095 match(RegI); 5096 match(iRegINoSp); 5097 op_cost(0); 5098 format %{ %} 5099 interface(REG_INTER); 5100 %} 5101 5102 5103 // Pointer Register Operands 5104 // Narrow Pointer Register 5105 operand iRegN() 5106 %{ 5107 constraint(ALLOC_IN_RC(any_reg32)); 5108 match(RegN); 5109 match(iRegNNoSp); 5110 op_cost(0); 5111 format %{ %} 5112 interface(REG_INTER); 5113 %} 5114 5115 operand iRegN_R0() 5116 %{ 5117 constraint(ALLOC_IN_RC(r0_reg)); 5118 match(iRegN); 5119 op_cost(0); 5120 format %{ %} 5121 interface(REG_INTER); 5122 %} 5123 5124 operand iRegN_R2() 5125 %{ 5126 constraint(ALLOC_IN_RC(r2_reg)); 5127 match(iRegN); 5128 op_cost(0); 5129 format %{ %} 5130 interface(REG_INTER); 5131 %} 5132 5133 operand iRegN_R3() 5134 %{ 5135 constraint(ALLOC_IN_RC(r3_reg)); 5136 match(iRegN); 5137 op_cost(0); 5138 format %{ %} 5139 interface(REG_INTER); 5140 %} 5141 5142 // Integer 64 bit Register not Special 5143 operand iRegNNoSp() 5144 %{ 5145 constraint(ALLOC_IN_RC(no_special_reg32)); 5146 match(RegN); 5147 op_cost(0); 5148 format %{ %} 5149 interface(REG_INTER); 5150 %} 5151 5152 // Float Register 5153 // Float register operands 5154 operand vRegF() 5155 %{ 5156 constraint(ALLOC_IN_RC(float_reg)); 5157 match(RegF); 5158 5159 op_cost(0); 5160 format %{ %} 5161 interface(REG_INTER); 5162 %} 5163 5164 // Double Register 5165 // Double register operands 5166 operand vRegD() 5167 %{ 5168 constraint(ALLOC_IN_RC(double_reg)); 5169 match(RegD); 5170 5171 op_cost(0); 5172 format %{ %} 5173 interface(REG_INTER); 5174 %} 5175 5176 // Generic vector class. This will be used for 5177 // all vector operands, including NEON and SVE. 5178 operand vReg() 5179 %{ 5180 constraint(ALLOC_IN_RC(dynamic)); 5181 match(VecA); 5182 match(VecD); 5183 match(VecX); 5184 5185 op_cost(0); 5186 format %{ %} 5187 interface(REG_INTER); 5188 %} 5189 5190 operand vecA() 5191 %{ 5192 constraint(ALLOC_IN_RC(vectora_reg)); 5193 match(VecA); 5194 5195 op_cost(0); 5196 format %{ %} 5197 interface(REG_INTER); 5198 %} 5199 5200 operand vecD() 5201 %{ 5202 constraint(ALLOC_IN_RC(vectord_reg)); 5203 match(VecD); 5204 5205 op_cost(0); 5206 format %{ %} 5207 interface(REG_INTER); 5208 %} 5209 5210 operand vecX() 5211 %{ 5212 constraint(ALLOC_IN_RC(vectorx_reg)); 5213 match(VecX); 5214 5215 op_cost(0); 5216 format %{ %} 5217 interface(REG_INTER); 5218 %} 5219 5220 operand vRegD_V0() 5221 %{ 5222 constraint(ALLOC_IN_RC(v0_reg)); 5223 match(RegD); 5224 op_cost(0); 5225 format %{ %} 5226 interface(REG_INTER); 5227 %} 5228 5229 operand vRegD_V1() 5230 %{ 5231 constraint(ALLOC_IN_RC(v1_reg)); 5232 match(RegD); 5233 op_cost(0); 5234 format %{ %} 5235 interface(REG_INTER); 5236 %} 5237 5238 operand vRegD_V2() 5239 %{ 5240 constraint(ALLOC_IN_RC(v2_reg)); 5241 match(RegD); 5242 op_cost(0); 5243 format %{ %} 5244 interface(REG_INTER); 5245 %} 5246 5247 operand vRegD_V3() 5248 %{ 5249 constraint(ALLOC_IN_RC(v3_reg)); 5250 match(RegD); 5251 op_cost(0); 5252 format %{ %} 5253 interface(REG_INTER); 5254 %} 5255 5256 operand vRegD_V4() 5257 %{ 5258 constraint(ALLOC_IN_RC(v4_reg)); 5259 match(RegD); 5260 op_cost(0); 5261 format %{ %} 5262 interface(REG_INTER); 5263 %} 5264 5265 operand vRegD_V5() 5266 %{ 5267 constraint(ALLOC_IN_RC(v5_reg)); 5268 match(RegD); 5269 op_cost(0); 5270 format %{ %} 5271 interface(REG_INTER); 5272 %} 5273 5274 operand vRegD_V6() 5275 %{ 5276 constraint(ALLOC_IN_RC(v6_reg)); 5277 match(RegD); 5278 op_cost(0); 5279 format %{ %} 5280 interface(REG_INTER); 5281 %} 5282 5283 operand vRegD_V7() 5284 %{ 5285 constraint(ALLOC_IN_RC(v7_reg)); 5286 match(RegD); 5287 op_cost(0); 5288 format %{ %} 5289 interface(REG_INTER); 5290 %} 5291 5292 operand vRegD_V8() 5293 %{ 5294 constraint(ALLOC_IN_RC(v8_reg)); 5295 match(RegD); 5296 op_cost(0); 5297 format %{ %} 5298 interface(REG_INTER); 5299 %} 5300 5301 operand vRegD_V9() 5302 %{ 5303 constraint(ALLOC_IN_RC(v9_reg)); 5304 match(RegD); 5305 op_cost(0); 5306 format %{ %} 5307 interface(REG_INTER); 5308 %} 5309 5310 operand vRegD_V10() 5311 %{ 5312 constraint(ALLOC_IN_RC(v10_reg)); 5313 match(RegD); 5314 op_cost(0); 5315 format %{ %} 5316 interface(REG_INTER); 5317 %} 5318 5319 operand vRegD_V11() 5320 %{ 5321 constraint(ALLOC_IN_RC(v11_reg)); 5322 match(RegD); 5323 op_cost(0); 5324 format %{ %} 5325 interface(REG_INTER); 5326 %} 5327 5328 operand vRegD_V12() 5329 %{ 5330 constraint(ALLOC_IN_RC(v12_reg)); 5331 match(RegD); 5332 op_cost(0); 5333 format %{ %} 5334 interface(REG_INTER); 5335 %} 5336 5337 operand vRegD_V13() 5338 %{ 5339 constraint(ALLOC_IN_RC(v13_reg)); 5340 match(RegD); 5341 op_cost(0); 5342 format %{ %} 5343 interface(REG_INTER); 5344 %} 5345 5346 operand vRegD_V14() 5347 %{ 5348 constraint(ALLOC_IN_RC(v14_reg)); 5349 match(RegD); 5350 op_cost(0); 5351 format %{ %} 5352 interface(REG_INTER); 5353 %} 5354 5355 operand vRegD_V15() 5356 %{ 5357 constraint(ALLOC_IN_RC(v15_reg)); 5358 match(RegD); 5359 op_cost(0); 5360 format %{ %} 5361 interface(REG_INTER); 5362 %} 5363 5364 operand vRegD_V16() 5365 %{ 5366 constraint(ALLOC_IN_RC(v16_reg)); 5367 match(RegD); 5368 op_cost(0); 5369 format %{ %} 5370 interface(REG_INTER); 5371 %} 5372 5373 operand vRegD_V17() 5374 %{ 5375 constraint(ALLOC_IN_RC(v17_reg)); 5376 match(RegD); 5377 op_cost(0); 5378 format %{ %} 5379 interface(REG_INTER); 5380 %} 5381 5382 operand vRegD_V18() 5383 %{ 5384 constraint(ALLOC_IN_RC(v18_reg)); 5385 match(RegD); 5386 op_cost(0); 5387 format %{ %} 5388 interface(REG_INTER); 5389 %} 5390 5391 operand vRegD_V19() 5392 %{ 5393 constraint(ALLOC_IN_RC(v19_reg)); 5394 match(RegD); 5395 op_cost(0); 5396 format %{ %} 5397 interface(REG_INTER); 5398 %} 5399 5400 operand vRegD_V20() 5401 %{ 5402 constraint(ALLOC_IN_RC(v20_reg)); 5403 match(RegD); 5404 op_cost(0); 5405 format %{ %} 5406 interface(REG_INTER); 5407 %} 5408 5409 operand vRegD_V21() 5410 %{ 5411 constraint(ALLOC_IN_RC(v21_reg)); 5412 match(RegD); 5413 op_cost(0); 5414 format %{ %} 5415 interface(REG_INTER); 5416 %} 5417 5418 operand vRegD_V22() 5419 %{ 5420 constraint(ALLOC_IN_RC(v22_reg)); 5421 match(RegD); 5422 op_cost(0); 5423 format %{ %} 5424 interface(REG_INTER); 5425 %} 5426 5427 operand vRegD_V23() 5428 %{ 5429 constraint(ALLOC_IN_RC(v23_reg)); 5430 match(RegD); 5431 op_cost(0); 5432 format %{ %} 5433 interface(REG_INTER); 5434 %} 5435 5436 operand vRegD_V24() 5437 %{ 5438 constraint(ALLOC_IN_RC(v24_reg)); 5439 match(RegD); 5440 op_cost(0); 5441 format %{ %} 5442 interface(REG_INTER); 5443 %} 5444 5445 operand vRegD_V25() 5446 %{ 5447 constraint(ALLOC_IN_RC(v25_reg)); 5448 match(RegD); 5449 op_cost(0); 5450 format %{ %} 5451 interface(REG_INTER); 5452 %} 5453 5454 operand vRegD_V26() 5455 %{ 5456 constraint(ALLOC_IN_RC(v26_reg)); 5457 match(RegD); 5458 op_cost(0); 5459 format %{ %} 5460 interface(REG_INTER); 5461 %} 5462 5463 operand vRegD_V27() 5464 %{ 5465 constraint(ALLOC_IN_RC(v27_reg)); 5466 match(RegD); 5467 op_cost(0); 5468 format %{ %} 5469 interface(REG_INTER); 5470 %} 5471 5472 operand vRegD_V28() 5473 %{ 5474 constraint(ALLOC_IN_RC(v28_reg)); 5475 match(RegD); 5476 op_cost(0); 5477 format %{ %} 5478 interface(REG_INTER); 5479 %} 5480 5481 operand vRegD_V29() 5482 %{ 5483 constraint(ALLOC_IN_RC(v29_reg)); 5484 match(RegD); 5485 op_cost(0); 5486 format %{ %} 5487 interface(REG_INTER); 5488 %} 5489 5490 operand vRegD_V30() 5491 %{ 5492 constraint(ALLOC_IN_RC(v30_reg)); 5493 match(RegD); 5494 op_cost(0); 5495 format %{ %} 5496 interface(REG_INTER); 5497 %} 5498 5499 operand vRegD_V31() 5500 %{ 5501 constraint(ALLOC_IN_RC(v31_reg)); 5502 match(RegD); 5503 op_cost(0); 5504 format %{ %} 5505 interface(REG_INTER); 5506 %} 5507 5508 operand pReg() 5509 %{ 5510 constraint(ALLOC_IN_RC(pr_reg)); 5511 match(RegVectMask); 5512 match(pRegGov); 5513 op_cost(0); 5514 format %{ %} 5515 interface(REG_INTER); 5516 %} 5517 5518 operand pRegGov() 5519 %{ 5520 constraint(ALLOC_IN_RC(gov_pr)); 5521 match(RegVectMask); 5522 match(pReg); 5523 op_cost(0); 5524 format %{ %} 5525 interface(REG_INTER); 5526 %} 5527 5528 operand pRegGov_P0() 5529 %{ 5530 constraint(ALLOC_IN_RC(p0_reg)); 5531 match(RegVectMask); 5532 op_cost(0); 5533 format %{ %} 5534 interface(REG_INTER); 5535 %} 5536 5537 operand pRegGov_P1() 5538 %{ 5539 constraint(ALLOC_IN_RC(p1_reg)); 5540 match(RegVectMask); 5541 op_cost(0); 5542 format %{ %} 5543 interface(REG_INTER); 5544 %} 5545 5546 // Flags register, used as output of signed compare instructions 5547 5548 // note that on AArch64 we also use this register as the output for 5549 // for floating point compare instructions (CmpF CmpD). this ensures 5550 // that ordered inequality tests use GT, GE, LT or LE none of which 5551 // pass through cases where the result is unordered i.e. one or both 5552 // inputs to the compare is a NaN. this means that the ideal code can 5553 // replace e.g. a GT with an LE and not end up capturing the NaN case 5554 // (where the comparison should always fail). EQ and NE tests are 5555 // always generated in ideal code so that unordered folds into the NE 5556 // case, matching the behaviour of AArch64 NE. 5557 // 5558 // This differs from x86 where the outputs of FP compares use a 5559 // special FP flags registers and where compares based on this 5560 // register are distinguished into ordered inequalities (cmpOpUCF) and 5561 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5562 // to explicitly handle the unordered case in branches. x86 also has 5563 // to include extra CMoveX rules to accept a cmpOpUCF input. 5564 5565 operand rFlagsReg() 5566 %{ 5567 constraint(ALLOC_IN_RC(int_flags)); 5568 match(RegFlags); 5569 5570 op_cost(0); 5571 format %{ "RFLAGS" %} 5572 interface(REG_INTER); 5573 %} 5574 5575 // Flags register, used as output of unsigned compare instructions 5576 operand rFlagsRegU() 5577 %{ 5578 constraint(ALLOC_IN_RC(int_flags)); 5579 match(RegFlags); 5580 5581 op_cost(0); 5582 format %{ "RFLAGSU" %} 5583 interface(REG_INTER); 5584 %} 5585 5586 // Special Registers 5587 5588 // Method Register 5589 operand inline_cache_RegP(iRegP reg) 5590 %{ 5591 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5592 match(reg); 5593 match(iRegPNoSp); 5594 op_cost(0); 5595 format %{ %} 5596 interface(REG_INTER); 5597 %} 5598 5599 // Thread Register 5600 operand thread_RegP(iRegP reg) 5601 %{ 5602 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5603 match(reg); 5604 op_cost(0); 5605 format %{ %} 5606 interface(REG_INTER); 5607 %} 5608 5609 operand lr_RegP(iRegP reg) 5610 %{ 5611 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5612 match(reg); 5613 op_cost(0); 5614 format %{ %} 5615 interface(REG_INTER); 5616 %} 5617 5618 //----------Memory Operands---------------------------------------------------- 5619 5620 operand indirect(iRegP reg) 5621 %{ 5622 constraint(ALLOC_IN_RC(ptr_reg)); 5623 match(reg); 5624 op_cost(0); 5625 format %{ "[$reg]" %} 5626 interface(MEMORY_INTER) %{ 5627 base($reg); 5628 index(0xffffffff); 5629 scale(0x0); 5630 disp(0x0); 5631 %} 5632 %} 5633 5634 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5635 %{ 5636 constraint(ALLOC_IN_RC(ptr_reg)); 5637 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5638 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5639 op_cost(0); 5640 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5641 interface(MEMORY_INTER) %{ 5642 base($reg); 5643 index($ireg); 5644 scale($scale); 5645 disp(0x0); 5646 %} 5647 %} 5648 5649 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5650 %{ 5651 constraint(ALLOC_IN_RC(ptr_reg)); 5652 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5653 match(AddP reg (LShiftL lreg scale)); 5654 op_cost(0); 5655 format %{ "$reg, $lreg lsl($scale)" %} 5656 interface(MEMORY_INTER) %{ 5657 base($reg); 5658 index($lreg); 5659 scale($scale); 5660 disp(0x0); 5661 %} 5662 %} 5663 5664 operand indIndexI2L(iRegP reg, iRegI ireg) 5665 %{ 5666 constraint(ALLOC_IN_RC(ptr_reg)); 5667 match(AddP reg (ConvI2L ireg)); 5668 op_cost(0); 5669 format %{ "$reg, $ireg, 0, I2L" %} 5670 interface(MEMORY_INTER) %{ 5671 base($reg); 5672 index($ireg); 5673 scale(0x0); 5674 disp(0x0); 5675 %} 5676 %} 5677 5678 operand indIndex(iRegP reg, iRegL lreg) 5679 %{ 5680 constraint(ALLOC_IN_RC(ptr_reg)); 5681 match(AddP reg lreg); 5682 op_cost(0); 5683 format %{ "$reg, $lreg" %} 5684 interface(MEMORY_INTER) %{ 5685 base($reg); 5686 index($lreg); 5687 scale(0x0); 5688 disp(0x0); 5689 %} 5690 %} 5691 5692 operand indOffI(iRegP reg, immIOffset off) 5693 %{ 5694 constraint(ALLOC_IN_RC(ptr_reg)); 5695 match(AddP reg off); 5696 op_cost(0); 5697 format %{ "[$reg, $off]" %} 5698 interface(MEMORY_INTER) %{ 5699 base($reg); 5700 index(0xffffffff); 5701 scale(0x0); 5702 disp($off); 5703 %} 5704 %} 5705 5706 operand indOffI1(iRegP reg, immIOffset1 off) 5707 %{ 5708 constraint(ALLOC_IN_RC(ptr_reg)); 5709 match(AddP reg off); 5710 op_cost(0); 5711 format %{ "[$reg, $off]" %} 5712 interface(MEMORY_INTER) %{ 5713 base($reg); 5714 index(0xffffffff); 5715 scale(0x0); 5716 disp($off); 5717 %} 5718 %} 5719 5720 operand indOffI2(iRegP reg, immIOffset2 off) 5721 %{ 5722 constraint(ALLOC_IN_RC(ptr_reg)); 5723 match(AddP reg off); 5724 op_cost(0); 5725 format %{ "[$reg, $off]" %} 5726 interface(MEMORY_INTER) %{ 5727 base($reg); 5728 index(0xffffffff); 5729 scale(0x0); 5730 disp($off); 5731 %} 5732 %} 5733 5734 operand indOffI4(iRegP reg, immIOffset4 off) 5735 %{ 5736 constraint(ALLOC_IN_RC(ptr_reg)); 5737 match(AddP reg off); 5738 op_cost(0); 5739 format %{ "[$reg, $off]" %} 5740 interface(MEMORY_INTER) %{ 5741 base($reg); 5742 index(0xffffffff); 5743 scale(0x0); 5744 disp($off); 5745 %} 5746 %} 5747 5748 operand indOffI8(iRegP reg, immIOffset8 off) 5749 %{ 5750 constraint(ALLOC_IN_RC(ptr_reg)); 5751 match(AddP reg off); 5752 op_cost(0); 5753 format %{ "[$reg, $off]" %} 5754 interface(MEMORY_INTER) %{ 5755 base($reg); 5756 index(0xffffffff); 5757 scale(0x0); 5758 disp($off); 5759 %} 5760 %} 5761 5762 operand indOffI16(iRegP reg, immIOffset16 off) 5763 %{ 5764 constraint(ALLOC_IN_RC(ptr_reg)); 5765 match(AddP reg off); 5766 op_cost(0); 5767 format %{ "[$reg, $off]" %} 5768 interface(MEMORY_INTER) %{ 5769 base($reg); 5770 index(0xffffffff); 5771 scale(0x0); 5772 disp($off); 5773 %} 5774 %} 5775 5776 operand indOffL(iRegP reg, immLoffset off) 5777 %{ 5778 constraint(ALLOC_IN_RC(ptr_reg)); 5779 match(AddP reg off); 5780 op_cost(0); 5781 format %{ "[$reg, $off]" %} 5782 interface(MEMORY_INTER) %{ 5783 base($reg); 5784 index(0xffffffff); 5785 scale(0x0); 5786 disp($off); 5787 %} 5788 %} 5789 5790 operand indOffL1(iRegP reg, immLoffset1 off) 5791 %{ 5792 constraint(ALLOC_IN_RC(ptr_reg)); 5793 match(AddP reg off); 5794 op_cost(0); 5795 format %{ "[$reg, $off]" %} 5796 interface(MEMORY_INTER) %{ 5797 base($reg); 5798 index(0xffffffff); 5799 scale(0x0); 5800 disp($off); 5801 %} 5802 %} 5803 5804 operand indOffL2(iRegP reg, immLoffset2 off) 5805 %{ 5806 constraint(ALLOC_IN_RC(ptr_reg)); 5807 match(AddP reg off); 5808 op_cost(0); 5809 format %{ "[$reg, $off]" %} 5810 interface(MEMORY_INTER) %{ 5811 base($reg); 5812 index(0xffffffff); 5813 scale(0x0); 5814 disp($off); 5815 %} 5816 %} 5817 5818 operand indOffL4(iRegP reg, immLoffset4 off) 5819 %{ 5820 constraint(ALLOC_IN_RC(ptr_reg)); 5821 match(AddP reg off); 5822 op_cost(0); 5823 format %{ "[$reg, $off]" %} 5824 interface(MEMORY_INTER) %{ 5825 base($reg); 5826 index(0xffffffff); 5827 scale(0x0); 5828 disp($off); 5829 %} 5830 %} 5831 5832 operand indOffL8(iRegP reg, immLoffset8 off) 5833 %{ 5834 constraint(ALLOC_IN_RC(ptr_reg)); 5835 match(AddP reg off); 5836 op_cost(0); 5837 format %{ "[$reg, $off]" %} 5838 interface(MEMORY_INTER) %{ 5839 base($reg); 5840 index(0xffffffff); 5841 scale(0x0); 5842 disp($off); 5843 %} 5844 %} 5845 5846 operand indOffL16(iRegP reg, immLoffset16 off) 5847 %{ 5848 constraint(ALLOC_IN_RC(ptr_reg)); 5849 match(AddP reg off); 5850 op_cost(0); 5851 format %{ "[$reg, $off]" %} 5852 interface(MEMORY_INTER) %{ 5853 base($reg); 5854 index(0xffffffff); 5855 scale(0x0); 5856 disp($off); 5857 %} 5858 %} 5859 5860 operand indirectN(iRegN reg) 5861 %{ 5862 predicate(CompressedOops::shift() == 0); 5863 constraint(ALLOC_IN_RC(ptr_reg)); 5864 match(DecodeN reg); 5865 op_cost(0); 5866 format %{ "[$reg]\t# narrow" %} 5867 interface(MEMORY_INTER) %{ 5868 base($reg); 5869 index(0xffffffff); 5870 scale(0x0); 5871 disp(0x0); 5872 %} 5873 %} 5874 5875 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5876 %{ 5877 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5878 constraint(ALLOC_IN_RC(ptr_reg)); 5879 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5880 op_cost(0); 5881 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5882 interface(MEMORY_INTER) %{ 5883 base($reg); 5884 index($ireg); 5885 scale($scale); 5886 disp(0x0); 5887 %} 5888 %} 5889 5890 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5891 %{ 5892 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5893 constraint(ALLOC_IN_RC(ptr_reg)); 5894 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5895 op_cost(0); 5896 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5897 interface(MEMORY_INTER) %{ 5898 base($reg); 5899 index($lreg); 5900 scale($scale); 5901 disp(0x0); 5902 %} 5903 %} 5904 5905 operand indIndexI2LN(iRegN reg, iRegI ireg) 5906 %{ 5907 predicate(CompressedOops::shift() == 0); 5908 constraint(ALLOC_IN_RC(ptr_reg)); 5909 match(AddP (DecodeN reg) (ConvI2L ireg)); 5910 op_cost(0); 5911 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5912 interface(MEMORY_INTER) %{ 5913 base($reg); 5914 index($ireg); 5915 scale(0x0); 5916 disp(0x0); 5917 %} 5918 %} 5919 5920 operand indIndexN(iRegN reg, iRegL lreg) 5921 %{ 5922 predicate(CompressedOops::shift() == 0); 5923 constraint(ALLOC_IN_RC(ptr_reg)); 5924 match(AddP (DecodeN reg) lreg); 5925 op_cost(0); 5926 format %{ "$reg, $lreg\t# narrow" %} 5927 interface(MEMORY_INTER) %{ 5928 base($reg); 5929 index($lreg); 5930 scale(0x0); 5931 disp(0x0); 5932 %} 5933 %} 5934 5935 operand indOffIN(iRegN reg, immIOffset off) 5936 %{ 5937 predicate(CompressedOops::shift() == 0); 5938 constraint(ALLOC_IN_RC(ptr_reg)); 5939 match(AddP (DecodeN reg) off); 5940 op_cost(0); 5941 format %{ "[$reg, $off]\t# narrow" %} 5942 interface(MEMORY_INTER) %{ 5943 base($reg); 5944 index(0xffffffff); 5945 scale(0x0); 5946 disp($off); 5947 %} 5948 %} 5949 5950 operand indOffLN(iRegN reg, immLoffset off) 5951 %{ 5952 predicate(CompressedOops::shift() == 0); 5953 constraint(ALLOC_IN_RC(ptr_reg)); 5954 match(AddP (DecodeN reg) off); 5955 op_cost(0); 5956 format %{ "[$reg, $off]\t# narrow" %} 5957 interface(MEMORY_INTER) %{ 5958 base($reg); 5959 index(0xffffffff); 5960 scale(0x0); 5961 disp($off); 5962 %} 5963 %} 5964 5965 5966 5967 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5968 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5969 %{ 5970 constraint(ALLOC_IN_RC(ptr_reg)); 5971 match(AddP reg off); 5972 op_cost(0); 5973 format %{ "[$reg, $off]" %} 5974 interface(MEMORY_INTER) %{ 5975 base($reg); 5976 index(0xffffffff); 5977 scale(0x0); 5978 disp($off); 5979 %} 5980 %} 5981 5982 //----------Special Memory Operands-------------------------------------------- 5983 // Stack Slot Operand - This operand is used for loading and storing temporary 5984 // values on the stack where a match requires a value to 5985 // flow through memory. 5986 operand stackSlotP(sRegP reg) 5987 %{ 5988 constraint(ALLOC_IN_RC(stack_slots)); 5989 op_cost(100); 5990 // No match rule because this operand is only generated in matching 5991 // match(RegP); 5992 format %{ "[$reg]" %} 5993 interface(MEMORY_INTER) %{ 5994 base(0x1e); // RSP 5995 index(0x0); // No Index 5996 scale(0x0); // No Scale 5997 disp($reg); // Stack Offset 5998 %} 5999 %} 6000 6001 operand stackSlotI(sRegI reg) 6002 %{ 6003 constraint(ALLOC_IN_RC(stack_slots)); 6004 // No match rule because this operand is only generated in matching 6005 // match(RegI); 6006 format %{ "[$reg]" %} 6007 interface(MEMORY_INTER) %{ 6008 base(0x1e); // RSP 6009 index(0x0); // No Index 6010 scale(0x0); // No Scale 6011 disp($reg); // Stack Offset 6012 %} 6013 %} 6014 6015 operand stackSlotF(sRegF reg) 6016 %{ 6017 constraint(ALLOC_IN_RC(stack_slots)); 6018 // No match rule because this operand is only generated in matching 6019 // match(RegF); 6020 format %{ "[$reg]" %} 6021 interface(MEMORY_INTER) %{ 6022 base(0x1e); // RSP 6023 index(0x0); // No Index 6024 scale(0x0); // No Scale 6025 disp($reg); // Stack Offset 6026 %} 6027 %} 6028 6029 operand stackSlotD(sRegD reg) 6030 %{ 6031 constraint(ALLOC_IN_RC(stack_slots)); 6032 // No match rule because this operand is only generated in matching 6033 // match(RegD); 6034 format %{ "[$reg]" %} 6035 interface(MEMORY_INTER) %{ 6036 base(0x1e); // RSP 6037 index(0x0); // No Index 6038 scale(0x0); // No Scale 6039 disp($reg); // Stack Offset 6040 %} 6041 %} 6042 6043 operand stackSlotL(sRegL reg) 6044 %{ 6045 constraint(ALLOC_IN_RC(stack_slots)); 6046 // No match rule because this operand is only generated in matching 6047 // match(RegL); 6048 format %{ "[$reg]" %} 6049 interface(MEMORY_INTER) %{ 6050 base(0x1e); // RSP 6051 index(0x0); // No Index 6052 scale(0x0); // No Scale 6053 disp($reg); // Stack Offset 6054 %} 6055 %} 6056 6057 // Operands for expressing Control Flow 6058 // NOTE: Label is a predefined operand which should not be redefined in 6059 // the AD file. It is generically handled within the ADLC. 6060 6061 //----------Conditional Branch Operands---------------------------------------- 6062 // Comparison Op - This is the operation of the comparison, and is limited to 6063 // the following set of codes: 6064 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 6065 // 6066 // Other attributes of the comparison, such as unsignedness, are specified 6067 // by the comparison instruction that sets a condition code flags register. 6068 // That result is represented by a flags operand whose subtype is appropriate 6069 // to the unsignedness (etc.) of the comparison. 6070 // 6071 // Later, the instruction which matches both the Comparison Op (a Bool) and 6072 // the flags (produced by the Cmp) specifies the coding of the comparison op 6073 // by matching a specific subtype of Bool operand below, such as cmpOpU. 6074 6075 // used for signed integral comparisons and fp comparisons 6076 6077 operand cmpOp() 6078 %{ 6079 match(Bool); 6080 6081 format %{ "" %} 6082 interface(COND_INTER) %{ 6083 equal(0x0, "eq"); 6084 not_equal(0x1, "ne"); 6085 less(0xb, "lt"); 6086 greater_equal(0xa, "ge"); 6087 less_equal(0xd, "le"); 6088 greater(0xc, "gt"); 6089 overflow(0x6, "vs"); 6090 no_overflow(0x7, "vc"); 6091 %} 6092 %} 6093 6094 // used for unsigned integral comparisons 6095 6096 operand cmpOpU() 6097 %{ 6098 match(Bool); 6099 6100 format %{ "" %} 6101 interface(COND_INTER) %{ 6102 equal(0x0, "eq"); 6103 not_equal(0x1, "ne"); 6104 less(0x3, "lo"); 6105 greater_equal(0x2, "hs"); 6106 less_equal(0x9, "ls"); 6107 greater(0x8, "hi"); 6108 overflow(0x6, "vs"); 6109 no_overflow(0x7, "vc"); 6110 %} 6111 %} 6112 6113 // used for certain integral comparisons which can be 6114 // converted to cbxx or tbxx instructions 6115 6116 operand cmpOpEqNe() 6117 %{ 6118 match(Bool); 6119 op_cost(0); 6120 predicate(n->as_Bool()->_test._test == BoolTest::ne 6121 || n->as_Bool()->_test._test == BoolTest::eq); 6122 6123 format %{ "" %} 6124 interface(COND_INTER) %{ 6125 equal(0x0, "eq"); 6126 not_equal(0x1, "ne"); 6127 less(0xb, "lt"); 6128 greater_equal(0xa, "ge"); 6129 less_equal(0xd, "le"); 6130 greater(0xc, "gt"); 6131 overflow(0x6, "vs"); 6132 no_overflow(0x7, "vc"); 6133 %} 6134 %} 6135 6136 // used for certain integral comparisons which can be 6137 // converted to cbxx or tbxx instructions 6138 6139 operand cmpOpLtGe() 6140 %{ 6141 match(Bool); 6142 op_cost(0); 6143 6144 predicate(n->as_Bool()->_test._test == BoolTest::lt 6145 || n->as_Bool()->_test._test == BoolTest::ge); 6146 6147 format %{ "" %} 6148 interface(COND_INTER) %{ 6149 equal(0x0, "eq"); 6150 not_equal(0x1, "ne"); 6151 less(0xb, "lt"); 6152 greater_equal(0xa, "ge"); 6153 less_equal(0xd, "le"); 6154 greater(0xc, "gt"); 6155 overflow(0x6, "vs"); 6156 no_overflow(0x7, "vc"); 6157 %} 6158 %} 6159 6160 // used for certain unsigned integral comparisons which can be 6161 // converted to cbxx or tbxx instructions 6162 6163 operand cmpOpUEqNeLtGe() 6164 %{ 6165 match(Bool); 6166 op_cost(0); 6167 6168 predicate(n->as_Bool()->_test._test == BoolTest::eq 6169 || n->as_Bool()->_test._test == BoolTest::ne 6170 || n->as_Bool()->_test._test == BoolTest::lt 6171 || n->as_Bool()->_test._test == BoolTest::ge); 6172 6173 format %{ "" %} 6174 interface(COND_INTER) %{ 6175 equal(0x0, "eq"); 6176 not_equal(0x1, "ne"); 6177 less(0xb, "lt"); 6178 greater_equal(0xa, "ge"); 6179 less_equal(0xd, "le"); 6180 greater(0xc, "gt"); 6181 overflow(0x6, "vs"); 6182 no_overflow(0x7, "vc"); 6183 %} 6184 %} 6185 6186 // Special operand allowing long args to int ops to be truncated for free 6187 6188 operand iRegL2I(iRegL reg) %{ 6189 6190 op_cost(0); 6191 6192 match(ConvL2I reg); 6193 6194 format %{ "l2i($reg)" %} 6195 6196 interface(REG_INTER) 6197 %} 6198 6199 opclass vmem2(indirect, indIndex, indOffI2, indOffL2); 6200 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 6201 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 6202 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 6203 6204 //----------OPERAND CLASSES---------------------------------------------------- 6205 // Operand Classes are groups of operands that are used as to simplify 6206 // instruction definitions by not requiring the AD writer to specify 6207 // separate instructions for every form of operand when the 6208 // instruction accepts multiple operand types with the same basic 6209 // encoding and format. The classic case of this is memory operands. 6210 6211 // memory is used to define read/write location for load/store 6212 // instruction defs. we can turn a memory op into an Address 6213 6214 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1, 6215 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 6216 6217 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2, 6218 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 6219 6220 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4, 6221 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6222 6223 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8, 6224 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6225 6226 // All of the memory operands. For the pipeline description. 6227 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, 6228 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, 6229 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6230 6231 6232 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 6233 // operations. it allows the src to be either an iRegI or a (ConvL2I 6234 // iRegL). in the latter case the l2i normally planted for a ConvL2I 6235 // can be elided because the 32-bit instruction will just employ the 6236 // lower 32 bits anyway. 6237 // 6238 // n.b. this does not elide all L2I conversions. if the truncated 6239 // value is consumed by more than one operation then the ConvL2I 6240 // cannot be bundled into the consuming nodes so an l2i gets planted 6241 // (actually a movw $dst $src) and the downstream instructions consume 6242 // the result of the l2i as an iRegI input. That's a shame since the 6243 // movw is actually redundant but its not too costly. 6244 6245 opclass iRegIorL2I(iRegI, iRegL2I); 6246 6247 //----------PIPELINE----------------------------------------------------------- 6248 // Rules which define the behavior of the target architectures pipeline. 6249 6250 // For specific pipelines, eg A53, define the stages of that pipeline 6251 //pipe_desc(ISS, EX1, EX2, WR); 6252 #define ISS S0 6253 #define EX1 S1 6254 #define EX2 S2 6255 #define WR S3 6256 6257 // Integer ALU reg operation 6258 pipeline %{ 6259 6260 attributes %{ 6261 // ARM instructions are of fixed length 6262 fixed_size_instructions; // Fixed size instructions TODO does 6263 max_instructions_per_bundle = 4; // A53 = 2, A57 = 4 6264 // ARM instructions come in 32-bit word units 6265 instruction_unit_size = 4; // An instruction is 4 bytes long 6266 instruction_fetch_unit_size = 64; // The processor fetches one line 6267 instruction_fetch_units = 1; // of 64 bytes 6268 6269 // List of nop instructions 6270 nops( MachNop ); 6271 %} 6272 6273 // We don't use an actual pipeline model so don't care about resources 6274 // or description. we do use pipeline classes to introduce fixed 6275 // latencies 6276 6277 //----------RESOURCES---------------------------------------------------------- 6278 // Resources are the functional units available to the machine 6279 6280 resources( INS0, INS1, INS01 = INS0 | INS1, 6281 ALU0, ALU1, ALU = ALU0 | ALU1, 6282 MAC, 6283 DIV, 6284 BRANCH, 6285 LDST, 6286 NEON_FP); 6287 6288 //----------PIPELINE DESCRIPTION----------------------------------------------- 6289 // Pipeline Description specifies the stages in the machine's pipeline 6290 6291 // Define the pipeline as a generic 6 stage pipeline 6292 pipe_desc(S0, S1, S2, S3, S4, S5); 6293 6294 //----------PIPELINE CLASSES--------------------------------------------------- 6295 // Pipeline Classes describe the stages in which input and output are 6296 // referenced by the hardware pipeline. 6297 6298 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 6299 %{ 6300 single_instruction; 6301 src1 : S1(read); 6302 src2 : S2(read); 6303 dst : S5(write); 6304 INS01 : ISS; 6305 NEON_FP : S5; 6306 %} 6307 6308 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 6309 %{ 6310 single_instruction; 6311 src1 : S1(read); 6312 src2 : S2(read); 6313 dst : S5(write); 6314 INS01 : ISS; 6315 NEON_FP : S5; 6316 %} 6317 6318 pipe_class fp_uop_s(vRegF dst, vRegF src) 6319 %{ 6320 single_instruction; 6321 src : S1(read); 6322 dst : S5(write); 6323 INS01 : ISS; 6324 NEON_FP : S5; 6325 %} 6326 6327 pipe_class fp_uop_d(vRegD dst, vRegD src) 6328 %{ 6329 single_instruction; 6330 src : S1(read); 6331 dst : S5(write); 6332 INS01 : ISS; 6333 NEON_FP : S5; 6334 %} 6335 6336 pipe_class fp_d2f(vRegF dst, vRegD src) 6337 %{ 6338 single_instruction; 6339 src : S1(read); 6340 dst : S5(write); 6341 INS01 : ISS; 6342 NEON_FP : S5; 6343 %} 6344 6345 pipe_class fp_f2d(vRegD dst, vRegF src) 6346 %{ 6347 single_instruction; 6348 src : S1(read); 6349 dst : S5(write); 6350 INS01 : ISS; 6351 NEON_FP : S5; 6352 %} 6353 6354 pipe_class fp_f2i(iRegINoSp dst, vRegF src) 6355 %{ 6356 single_instruction; 6357 src : S1(read); 6358 dst : S5(write); 6359 INS01 : ISS; 6360 NEON_FP : S5; 6361 %} 6362 6363 pipe_class fp_f2l(iRegLNoSp dst, vRegF src) 6364 %{ 6365 single_instruction; 6366 src : S1(read); 6367 dst : S5(write); 6368 INS01 : ISS; 6369 NEON_FP : S5; 6370 %} 6371 6372 pipe_class fp_i2f(vRegF dst, iRegIorL2I src) 6373 %{ 6374 single_instruction; 6375 src : S1(read); 6376 dst : S5(write); 6377 INS01 : ISS; 6378 NEON_FP : S5; 6379 %} 6380 6381 pipe_class fp_l2f(vRegF dst, iRegL src) 6382 %{ 6383 single_instruction; 6384 src : S1(read); 6385 dst : S5(write); 6386 INS01 : ISS; 6387 NEON_FP : S5; 6388 %} 6389 6390 pipe_class fp_d2i(iRegINoSp dst, vRegD src) 6391 %{ 6392 single_instruction; 6393 src : S1(read); 6394 dst : S5(write); 6395 INS01 : ISS; 6396 NEON_FP : S5; 6397 %} 6398 6399 pipe_class fp_d2l(iRegLNoSp dst, vRegD src) 6400 %{ 6401 single_instruction; 6402 src : S1(read); 6403 dst : S5(write); 6404 INS01 : ISS; 6405 NEON_FP : S5; 6406 %} 6407 6408 pipe_class fp_i2d(vRegD dst, iRegIorL2I src) 6409 %{ 6410 single_instruction; 6411 src : S1(read); 6412 dst : S5(write); 6413 INS01 : ISS; 6414 NEON_FP : S5; 6415 %} 6416 6417 pipe_class fp_l2d(vRegD dst, iRegIorL2I src) 6418 %{ 6419 single_instruction; 6420 src : S1(read); 6421 dst : S5(write); 6422 INS01 : ISS; 6423 NEON_FP : S5; 6424 %} 6425 6426 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 6427 %{ 6428 single_instruction; 6429 src1 : S1(read); 6430 src2 : S2(read); 6431 dst : S5(write); 6432 INS0 : ISS; 6433 NEON_FP : S5; 6434 %} 6435 6436 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 6437 %{ 6438 single_instruction; 6439 src1 : S1(read); 6440 src2 : S2(read); 6441 dst : S5(write); 6442 INS0 : ISS; 6443 NEON_FP : S5; 6444 %} 6445 6446 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 6447 %{ 6448 single_instruction; 6449 cr : S1(read); 6450 src1 : S1(read); 6451 src2 : S1(read); 6452 dst : S3(write); 6453 INS01 : ISS; 6454 NEON_FP : S3; 6455 %} 6456 6457 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 6458 %{ 6459 single_instruction; 6460 cr : S1(read); 6461 src1 : S1(read); 6462 src2 : S1(read); 6463 dst : S3(write); 6464 INS01 : ISS; 6465 NEON_FP : S3; 6466 %} 6467 6468 pipe_class fp_imm_s(vRegF dst) 6469 %{ 6470 single_instruction; 6471 dst : S3(write); 6472 INS01 : ISS; 6473 NEON_FP : S3; 6474 %} 6475 6476 pipe_class fp_imm_d(vRegD dst) 6477 %{ 6478 single_instruction; 6479 dst : S3(write); 6480 INS01 : ISS; 6481 NEON_FP : S3; 6482 %} 6483 6484 pipe_class fp_load_constant_s(vRegF dst) 6485 %{ 6486 single_instruction; 6487 dst : S4(write); 6488 INS01 : ISS; 6489 NEON_FP : S4; 6490 %} 6491 6492 pipe_class fp_load_constant_d(vRegD dst) 6493 %{ 6494 single_instruction; 6495 dst : S4(write); 6496 INS01 : ISS; 6497 NEON_FP : S4; 6498 %} 6499 6500 //------- Integer ALU operations -------------------------- 6501 6502 // Integer ALU reg-reg operation 6503 // Operands needed in EX1, result generated in EX2 6504 // Eg. ADD x0, x1, x2 6505 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6506 %{ 6507 single_instruction; 6508 dst : EX2(write); 6509 src1 : EX1(read); 6510 src2 : EX1(read); 6511 INS01 : ISS; // Dual issue as instruction 0 or 1 6512 ALU : EX2; 6513 %} 6514 6515 // Integer ALU reg-reg operation with constant shift 6516 // Shifted register must be available in LATE_ISS instead of EX1 6517 // Eg. ADD x0, x1, x2, LSL #2 6518 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6519 %{ 6520 single_instruction; 6521 dst : EX2(write); 6522 src1 : EX1(read); 6523 src2 : ISS(read); 6524 INS01 : ISS; 6525 ALU : EX2; 6526 %} 6527 6528 // Integer ALU reg operation with constant shift 6529 // Eg. LSL x0, x1, #shift 6530 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6531 %{ 6532 single_instruction; 6533 dst : EX2(write); 6534 src1 : ISS(read); 6535 INS01 : ISS; 6536 ALU : EX2; 6537 %} 6538 6539 // Integer ALU reg-reg operation with variable shift 6540 // Both operands must be available in LATE_ISS instead of EX1 6541 // Result is available in EX1 instead of EX2 6542 // Eg. LSLV x0, x1, x2 6543 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6544 %{ 6545 single_instruction; 6546 dst : EX1(write); 6547 src1 : ISS(read); 6548 src2 : ISS(read); 6549 INS01 : ISS; 6550 ALU : EX1; 6551 %} 6552 6553 // Integer ALU reg-reg operation with extract 6554 // As for _vshift above, but result generated in EX2 6555 // Eg. EXTR x0, x1, x2, #N 6556 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6557 %{ 6558 single_instruction; 6559 dst : EX2(write); 6560 src1 : ISS(read); 6561 src2 : ISS(read); 6562 INS1 : ISS; // Can only dual issue as Instruction 1 6563 ALU : EX1; 6564 %} 6565 6566 // Integer ALU reg operation 6567 // Eg. NEG x0, x1 6568 pipe_class ialu_reg(iRegI dst, iRegI src) 6569 %{ 6570 single_instruction; 6571 dst : EX2(write); 6572 src : EX1(read); 6573 INS01 : ISS; 6574 ALU : EX2; 6575 %} 6576 6577 // Integer ALU reg mmediate operation 6578 // Eg. ADD x0, x1, #N 6579 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6580 %{ 6581 single_instruction; 6582 dst : EX2(write); 6583 src1 : EX1(read); 6584 INS01 : ISS; 6585 ALU : EX2; 6586 %} 6587 6588 // Integer ALU immediate operation (no source operands) 6589 // Eg. MOV x0, #N 6590 pipe_class ialu_imm(iRegI dst) 6591 %{ 6592 single_instruction; 6593 dst : EX1(write); 6594 INS01 : ISS; 6595 ALU : EX1; 6596 %} 6597 6598 //------- Compare operation ------------------------------- 6599 6600 // Compare reg-reg 6601 // Eg. CMP x0, x1 6602 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6603 %{ 6604 single_instruction; 6605 // fixed_latency(16); 6606 cr : EX2(write); 6607 op1 : EX1(read); 6608 op2 : EX1(read); 6609 INS01 : ISS; 6610 ALU : EX2; 6611 %} 6612 6613 // Compare reg-reg 6614 // Eg. CMP x0, #N 6615 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6616 %{ 6617 single_instruction; 6618 // fixed_latency(16); 6619 cr : EX2(write); 6620 op1 : EX1(read); 6621 INS01 : ISS; 6622 ALU : EX2; 6623 %} 6624 6625 //------- Conditional instructions ------------------------ 6626 6627 // Conditional no operands 6628 // Eg. CSINC x0, zr, zr, <cond> 6629 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6630 %{ 6631 single_instruction; 6632 cr : EX1(read); 6633 dst : EX2(write); 6634 INS01 : ISS; 6635 ALU : EX2; 6636 %} 6637 6638 // Conditional 2 operand 6639 // EG. CSEL X0, X1, X2, <cond> 6640 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6641 %{ 6642 single_instruction; 6643 cr : EX1(read); 6644 src1 : EX1(read); 6645 src2 : EX1(read); 6646 dst : EX2(write); 6647 INS01 : ISS; 6648 ALU : EX2; 6649 %} 6650 6651 // Conditional 2 operand 6652 // EG. CSEL X0, X1, X2, <cond> 6653 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6654 %{ 6655 single_instruction; 6656 cr : EX1(read); 6657 src : EX1(read); 6658 dst : EX2(write); 6659 INS01 : ISS; 6660 ALU : EX2; 6661 %} 6662 6663 //------- Multiply pipeline operations -------------------- 6664 6665 // Multiply reg-reg 6666 // Eg. MUL w0, w1, w2 6667 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6668 %{ 6669 single_instruction; 6670 dst : WR(write); 6671 src1 : ISS(read); 6672 src2 : ISS(read); 6673 INS01 : ISS; 6674 MAC : WR; 6675 %} 6676 6677 // Multiply accumulate 6678 // Eg. MADD w0, w1, w2, w3 6679 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6680 %{ 6681 single_instruction; 6682 dst : WR(write); 6683 src1 : ISS(read); 6684 src2 : ISS(read); 6685 src3 : ISS(read); 6686 INS01 : ISS; 6687 MAC : WR; 6688 %} 6689 6690 // Eg. MUL w0, w1, w2 6691 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6692 %{ 6693 single_instruction; 6694 fixed_latency(3); // Maximum latency for 64 bit mul 6695 dst : WR(write); 6696 src1 : ISS(read); 6697 src2 : ISS(read); 6698 INS01 : ISS; 6699 MAC : WR; 6700 %} 6701 6702 // Multiply accumulate 6703 // Eg. MADD w0, w1, w2, w3 6704 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6705 %{ 6706 single_instruction; 6707 fixed_latency(3); // Maximum latency for 64 bit mul 6708 dst : WR(write); 6709 src1 : ISS(read); 6710 src2 : ISS(read); 6711 src3 : ISS(read); 6712 INS01 : ISS; 6713 MAC : WR; 6714 %} 6715 6716 //------- Divide pipeline operations -------------------- 6717 6718 // Eg. SDIV w0, w1, w2 6719 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6720 %{ 6721 single_instruction; 6722 fixed_latency(8); // Maximum latency for 32 bit divide 6723 dst : WR(write); 6724 src1 : ISS(read); 6725 src2 : ISS(read); 6726 INS0 : ISS; // Can only dual issue as instruction 0 6727 DIV : WR; 6728 %} 6729 6730 // Eg. SDIV x0, x1, x2 6731 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6732 %{ 6733 single_instruction; 6734 fixed_latency(16); // Maximum latency for 64 bit divide 6735 dst : WR(write); 6736 src1 : ISS(read); 6737 src2 : ISS(read); 6738 INS0 : ISS; // Can only dual issue as instruction 0 6739 DIV : WR; 6740 %} 6741 6742 //------- Load pipeline operations ------------------------ 6743 6744 // Load - prefetch 6745 // Eg. PFRM <mem> 6746 pipe_class iload_prefetch(memory mem) 6747 %{ 6748 single_instruction; 6749 mem : ISS(read); 6750 INS01 : ISS; 6751 LDST : WR; 6752 %} 6753 6754 // Load - reg, mem 6755 // Eg. LDR x0, <mem> 6756 pipe_class iload_reg_mem(iRegI dst, memory mem) 6757 %{ 6758 single_instruction; 6759 dst : WR(write); 6760 mem : ISS(read); 6761 INS01 : ISS; 6762 LDST : WR; 6763 %} 6764 6765 // Load - reg, reg 6766 // Eg. LDR x0, [sp, x1] 6767 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6768 %{ 6769 single_instruction; 6770 dst : WR(write); 6771 src : ISS(read); 6772 INS01 : ISS; 6773 LDST : WR; 6774 %} 6775 6776 //------- Store pipeline operations ----------------------- 6777 6778 // Store - zr, mem 6779 // Eg. STR zr, <mem> 6780 pipe_class istore_mem(memory mem) 6781 %{ 6782 single_instruction; 6783 mem : ISS(read); 6784 INS01 : ISS; 6785 LDST : WR; 6786 %} 6787 6788 // Store - reg, mem 6789 // Eg. STR x0, <mem> 6790 pipe_class istore_reg_mem(iRegI src, memory mem) 6791 %{ 6792 single_instruction; 6793 mem : ISS(read); 6794 src : EX2(read); 6795 INS01 : ISS; 6796 LDST : WR; 6797 %} 6798 6799 // Store - reg, reg 6800 // Eg. STR x0, [sp, x1] 6801 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6802 %{ 6803 single_instruction; 6804 dst : ISS(read); 6805 src : EX2(read); 6806 INS01 : ISS; 6807 LDST : WR; 6808 %} 6809 6810 //------- Store pipeline operations ----------------------- 6811 6812 // Branch 6813 pipe_class pipe_branch() 6814 %{ 6815 single_instruction; 6816 INS01 : ISS; 6817 BRANCH : EX1; 6818 %} 6819 6820 // Conditional branch 6821 pipe_class pipe_branch_cond(rFlagsReg cr) 6822 %{ 6823 single_instruction; 6824 cr : EX1(read); 6825 INS01 : ISS; 6826 BRANCH : EX1; 6827 %} 6828 6829 // Compare & Branch 6830 // EG. CBZ/CBNZ 6831 pipe_class pipe_cmp_branch(iRegI op1) 6832 %{ 6833 single_instruction; 6834 op1 : EX1(read); 6835 INS01 : ISS; 6836 BRANCH : EX1; 6837 %} 6838 6839 //------- Synchronisation operations ---------------------- 6840 6841 // Any operation requiring serialization. 6842 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6843 pipe_class pipe_serial() 6844 %{ 6845 single_instruction; 6846 force_serialization; 6847 fixed_latency(16); 6848 INS01 : ISS(2); // Cannot dual issue with any other instruction 6849 LDST : WR; 6850 %} 6851 6852 // Generic big/slow expanded idiom - also serialized 6853 pipe_class pipe_slow() 6854 %{ 6855 instruction_count(10); 6856 multiple_bundles; 6857 force_serialization; 6858 fixed_latency(16); 6859 INS01 : ISS(2); // Cannot dual issue with any other instruction 6860 LDST : WR; 6861 %} 6862 6863 // Empty pipeline class 6864 pipe_class pipe_class_empty() 6865 %{ 6866 single_instruction; 6867 fixed_latency(0); 6868 %} 6869 6870 // Default pipeline class. 6871 pipe_class pipe_class_default() 6872 %{ 6873 single_instruction; 6874 fixed_latency(2); 6875 %} 6876 6877 // Pipeline class for compares. 6878 pipe_class pipe_class_compare() 6879 %{ 6880 single_instruction; 6881 fixed_latency(16); 6882 %} 6883 6884 // Pipeline class for memory operations. 6885 pipe_class pipe_class_memory() 6886 %{ 6887 single_instruction; 6888 fixed_latency(16); 6889 %} 6890 6891 // Pipeline class for call. 6892 pipe_class pipe_class_call() 6893 %{ 6894 single_instruction; 6895 fixed_latency(100); 6896 %} 6897 6898 // Define the class for the Nop node. 6899 define %{ 6900 MachNop = pipe_class_empty; 6901 %} 6902 6903 %} 6904 //----------INSTRUCTIONS------------------------------------------------------- 6905 // 6906 // match -- States which machine-independent subtree may be replaced 6907 // by this instruction. 6908 // ins_cost -- The estimated cost of this instruction is used by instruction 6909 // selection to identify a minimum cost tree of machine 6910 // instructions that matches a tree of machine-independent 6911 // instructions. 6912 // format -- A string providing the disassembly for this instruction. 6913 // The value of an instruction's operand may be inserted 6914 // by referring to it with a '$' prefix. 6915 // opcode -- Three instruction opcodes may be provided. These are referred 6916 // to within an encode class as $primary, $secondary, and $tertiary 6917 // rrspectively. The primary opcode is commonly used to 6918 // indicate the type of machine instruction, while secondary 6919 // and tertiary are often used for prefix options or addressing 6920 // modes. 6921 // ins_encode -- A list of encode classes with parameters. The encode class 6922 // name must have been defined in an 'enc_class' specification 6923 // in the encode section of the architecture description. 6924 6925 // ============================================================================ 6926 // Memory (Load/Store) Instructions 6927 6928 // Load Instructions 6929 6930 // Load Byte (8 bit signed) 6931 instruct loadB(iRegINoSp dst, memory1 mem) 6932 %{ 6933 match(Set dst (LoadB mem)); 6934 predicate(!needs_acquiring_load(n)); 6935 6936 ins_cost(4 * INSN_COST); 6937 format %{ "ldrsbw $dst, $mem\t# byte" %} 6938 6939 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6940 6941 ins_pipe(iload_reg_mem); 6942 %} 6943 6944 // Load Byte (8 bit signed) into long 6945 instruct loadB2L(iRegLNoSp dst, memory1 mem) 6946 %{ 6947 match(Set dst (ConvI2L (LoadB mem))); 6948 predicate(!needs_acquiring_load(n->in(1))); 6949 6950 ins_cost(4 * INSN_COST); 6951 format %{ "ldrsb $dst, $mem\t# byte" %} 6952 6953 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6954 6955 ins_pipe(iload_reg_mem); 6956 %} 6957 6958 // Load Byte (8 bit unsigned) 6959 instruct loadUB(iRegINoSp dst, memory1 mem) 6960 %{ 6961 match(Set dst (LoadUB mem)); 6962 predicate(!needs_acquiring_load(n)); 6963 6964 ins_cost(4 * INSN_COST); 6965 format %{ "ldrbw $dst, $mem\t# byte" %} 6966 6967 ins_encode(aarch64_enc_ldrb(dst, mem)); 6968 6969 ins_pipe(iload_reg_mem); 6970 %} 6971 6972 // Load Byte (8 bit unsigned) into long 6973 instruct loadUB2L(iRegLNoSp dst, memory1 mem) 6974 %{ 6975 match(Set dst (ConvI2L (LoadUB mem))); 6976 predicate(!needs_acquiring_load(n->in(1))); 6977 6978 ins_cost(4 * INSN_COST); 6979 format %{ "ldrb $dst, $mem\t# byte" %} 6980 6981 ins_encode(aarch64_enc_ldrb(dst, mem)); 6982 6983 ins_pipe(iload_reg_mem); 6984 %} 6985 6986 // Load Short (16 bit signed) 6987 instruct loadS(iRegINoSp dst, memory2 mem) 6988 %{ 6989 match(Set dst (LoadS mem)); 6990 predicate(!needs_acquiring_load(n)); 6991 6992 ins_cost(4 * INSN_COST); 6993 format %{ "ldrshw $dst, $mem\t# short" %} 6994 6995 ins_encode(aarch64_enc_ldrshw(dst, mem)); 6996 6997 ins_pipe(iload_reg_mem); 6998 %} 6999 7000 // Load Short (16 bit signed) into long 7001 instruct loadS2L(iRegLNoSp dst, memory2 mem) 7002 %{ 7003 match(Set dst (ConvI2L (LoadS mem))); 7004 predicate(!needs_acquiring_load(n->in(1))); 7005 7006 ins_cost(4 * INSN_COST); 7007 format %{ "ldrsh $dst, $mem\t# short" %} 7008 7009 ins_encode(aarch64_enc_ldrsh(dst, mem)); 7010 7011 ins_pipe(iload_reg_mem); 7012 %} 7013 7014 // Load Char (16 bit unsigned) 7015 instruct loadUS(iRegINoSp dst, memory2 mem) 7016 %{ 7017 match(Set dst (LoadUS mem)); 7018 predicate(!needs_acquiring_load(n)); 7019 7020 ins_cost(4 * INSN_COST); 7021 format %{ "ldrh $dst, $mem\t# short" %} 7022 7023 ins_encode(aarch64_enc_ldrh(dst, mem)); 7024 7025 ins_pipe(iload_reg_mem); 7026 %} 7027 7028 // Load Short/Char (16 bit unsigned) into long 7029 instruct loadUS2L(iRegLNoSp dst, memory2 mem) 7030 %{ 7031 match(Set dst (ConvI2L (LoadUS mem))); 7032 predicate(!needs_acquiring_load(n->in(1))); 7033 7034 ins_cost(4 * INSN_COST); 7035 format %{ "ldrh $dst, $mem\t# short" %} 7036 7037 ins_encode(aarch64_enc_ldrh(dst, mem)); 7038 7039 ins_pipe(iload_reg_mem); 7040 %} 7041 7042 // Load Integer (32 bit signed) 7043 instruct loadI(iRegINoSp dst, memory4 mem) 7044 %{ 7045 match(Set dst (LoadI mem)); 7046 predicate(!needs_acquiring_load(n)); 7047 7048 ins_cost(4 * INSN_COST); 7049 format %{ "ldrw $dst, $mem\t# int" %} 7050 7051 ins_encode(aarch64_enc_ldrw(dst, mem)); 7052 7053 ins_pipe(iload_reg_mem); 7054 %} 7055 7056 // Load Integer (32 bit signed) into long 7057 instruct loadI2L(iRegLNoSp dst, memory4 mem) 7058 %{ 7059 match(Set dst (ConvI2L (LoadI mem))); 7060 predicate(!needs_acquiring_load(n->in(1))); 7061 7062 ins_cost(4 * INSN_COST); 7063 format %{ "ldrsw $dst, $mem\t# int" %} 7064 7065 ins_encode(aarch64_enc_ldrsw(dst, mem)); 7066 7067 ins_pipe(iload_reg_mem); 7068 %} 7069 7070 // Load Integer (32 bit unsigned) into long 7071 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask) 7072 %{ 7073 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7074 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 7075 7076 ins_cost(4 * INSN_COST); 7077 format %{ "ldrw $dst, $mem\t# int" %} 7078 7079 ins_encode(aarch64_enc_ldrw(dst, mem)); 7080 7081 ins_pipe(iload_reg_mem); 7082 %} 7083 7084 // Load Long (64 bit signed) 7085 instruct loadL(iRegLNoSp dst, memory8 mem) 7086 %{ 7087 match(Set dst (LoadL mem)); 7088 predicate(!needs_acquiring_load(n)); 7089 7090 ins_cost(4 * INSN_COST); 7091 format %{ "ldr $dst, $mem\t# int" %} 7092 7093 ins_encode(aarch64_enc_ldr(dst, mem)); 7094 7095 ins_pipe(iload_reg_mem); 7096 %} 7097 7098 // Load Range 7099 instruct loadRange(iRegINoSp dst, memory4 mem) 7100 %{ 7101 match(Set dst (LoadRange mem)); 7102 7103 ins_cost(4 * INSN_COST); 7104 format %{ "ldrw $dst, $mem\t# range" %} 7105 7106 ins_encode(aarch64_enc_ldrw(dst, mem)); 7107 7108 ins_pipe(iload_reg_mem); 7109 %} 7110 7111 // Load Pointer 7112 instruct loadP(iRegPNoSp dst, memory8 mem) 7113 %{ 7114 match(Set dst (LoadP mem)); 7115 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 7116 7117 ins_cost(4 * INSN_COST); 7118 format %{ "ldr $dst, $mem\t# ptr" %} 7119 7120 ins_encode(aarch64_enc_ldr(dst, mem)); 7121 7122 ins_pipe(iload_reg_mem); 7123 %} 7124 7125 // Load Compressed Pointer 7126 instruct loadN(iRegNNoSp dst, memory4 mem) 7127 %{ 7128 match(Set dst (LoadN mem)); 7129 predicate(!needs_acquiring_load(n)); 7130 7131 ins_cost(4 * INSN_COST); 7132 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 7133 7134 ins_encode(aarch64_enc_ldrw(dst, mem)); 7135 7136 ins_pipe(iload_reg_mem); 7137 %} 7138 7139 // Load Klass Pointer 7140 instruct loadKlass(iRegPNoSp dst, memory8 mem) 7141 %{ 7142 match(Set dst (LoadKlass mem)); 7143 predicate(!needs_acquiring_load(n)); 7144 7145 ins_cost(4 * INSN_COST); 7146 format %{ "ldr $dst, $mem\t# class" %} 7147 7148 ins_encode(aarch64_enc_ldr(dst, mem)); 7149 7150 ins_pipe(iload_reg_mem); 7151 %} 7152 7153 // Load Narrow Klass Pointer 7154 instruct loadNKlass(iRegNNoSp dst, memory4 mem) 7155 %{ 7156 match(Set dst (LoadNKlass mem)); 7157 predicate(!needs_acquiring_load(n)); 7158 7159 ins_cost(4 * INSN_COST); 7160 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 7161 7162 ins_encode(aarch64_enc_ldrw(dst, mem)); 7163 7164 ins_pipe(iload_reg_mem); 7165 %} 7166 7167 // Load Float 7168 instruct loadF(vRegF dst, memory4 mem) 7169 %{ 7170 match(Set dst (LoadF mem)); 7171 predicate(!needs_acquiring_load(n)); 7172 7173 ins_cost(4 * INSN_COST); 7174 format %{ "ldrs $dst, $mem\t# float" %} 7175 7176 ins_encode( aarch64_enc_ldrs(dst, mem) ); 7177 7178 ins_pipe(pipe_class_memory); 7179 %} 7180 7181 // Load Double 7182 instruct loadD(vRegD dst, memory8 mem) 7183 %{ 7184 match(Set dst (LoadD mem)); 7185 predicate(!needs_acquiring_load(n)); 7186 7187 ins_cost(4 * INSN_COST); 7188 format %{ "ldrd $dst, $mem\t# double" %} 7189 7190 ins_encode( aarch64_enc_ldrd(dst, mem) ); 7191 7192 ins_pipe(pipe_class_memory); 7193 %} 7194 7195 7196 // Load Int Constant 7197 instruct loadConI(iRegINoSp dst, immI src) 7198 %{ 7199 match(Set dst src); 7200 7201 ins_cost(INSN_COST); 7202 format %{ "mov $dst, $src\t# int" %} 7203 7204 ins_encode( aarch64_enc_movw_imm(dst, src) ); 7205 7206 ins_pipe(ialu_imm); 7207 %} 7208 7209 // Load Long Constant 7210 instruct loadConL(iRegLNoSp dst, immL src) 7211 %{ 7212 match(Set dst src); 7213 7214 ins_cost(INSN_COST); 7215 format %{ "mov $dst, $src\t# long" %} 7216 7217 ins_encode( aarch64_enc_mov_imm(dst, src) ); 7218 7219 ins_pipe(ialu_imm); 7220 %} 7221 7222 // Load Pointer Constant 7223 7224 instruct loadConP(iRegPNoSp dst, immP con) 7225 %{ 7226 match(Set dst con); 7227 7228 ins_cost(INSN_COST * 4); 7229 format %{ 7230 "mov $dst, $con\t# ptr" 7231 %} 7232 7233 ins_encode(aarch64_enc_mov_p(dst, con)); 7234 7235 ins_pipe(ialu_imm); 7236 %} 7237 7238 // Load Null Pointer Constant 7239 7240 instruct loadConP0(iRegPNoSp dst, immP0 con) 7241 %{ 7242 match(Set dst con); 7243 7244 ins_cost(INSN_COST); 7245 format %{ "mov $dst, $con\t# null pointer" %} 7246 7247 ins_encode(aarch64_enc_mov_p0(dst, con)); 7248 7249 ins_pipe(ialu_imm); 7250 %} 7251 7252 // Load Pointer Constant One 7253 7254 instruct loadConP1(iRegPNoSp dst, immP_1 con) 7255 %{ 7256 match(Set dst con); 7257 7258 ins_cost(INSN_COST); 7259 format %{ "mov $dst, $con\t# null pointer" %} 7260 7261 ins_encode(aarch64_enc_mov_p1(dst, con)); 7262 7263 ins_pipe(ialu_imm); 7264 %} 7265 7266 // Load Byte Map Base Constant 7267 7268 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 7269 %{ 7270 match(Set dst con); 7271 7272 ins_cost(INSN_COST); 7273 format %{ "adr $dst, $con\t# Byte Map Base" %} 7274 7275 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 7276 7277 ins_pipe(ialu_imm); 7278 %} 7279 7280 // Load Narrow Pointer Constant 7281 7282 instruct loadConN(iRegNNoSp dst, immN con) 7283 %{ 7284 match(Set dst con); 7285 7286 ins_cost(INSN_COST * 4); 7287 format %{ "mov $dst, $con\t# compressed ptr" %} 7288 7289 ins_encode(aarch64_enc_mov_n(dst, con)); 7290 7291 ins_pipe(ialu_imm); 7292 %} 7293 7294 // Load Narrow Null Pointer Constant 7295 7296 instruct loadConN0(iRegNNoSp dst, immN0 con) 7297 %{ 7298 match(Set dst con); 7299 7300 ins_cost(INSN_COST); 7301 format %{ "mov $dst, $con\t# compressed null pointer" %} 7302 7303 ins_encode(aarch64_enc_mov_n0(dst, con)); 7304 7305 ins_pipe(ialu_imm); 7306 %} 7307 7308 // Load Narrow Klass Constant 7309 7310 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 7311 %{ 7312 match(Set dst con); 7313 7314 ins_cost(INSN_COST); 7315 format %{ "mov $dst, $con\t# compressed klass ptr" %} 7316 7317 ins_encode(aarch64_enc_mov_nk(dst, con)); 7318 7319 ins_pipe(ialu_imm); 7320 %} 7321 7322 // Load Packed Float Constant 7323 7324 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 7325 match(Set dst con); 7326 ins_cost(INSN_COST * 4); 7327 format %{ "fmovs $dst, $con"%} 7328 ins_encode %{ 7329 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 7330 %} 7331 7332 ins_pipe(fp_imm_s); 7333 %} 7334 7335 // Load Float Constant 7336 7337 instruct loadConF(vRegF dst, immF con) %{ 7338 match(Set dst con); 7339 7340 ins_cost(INSN_COST * 4); 7341 7342 format %{ 7343 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7344 %} 7345 7346 ins_encode %{ 7347 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 7348 %} 7349 7350 ins_pipe(fp_load_constant_s); 7351 %} 7352 7353 // Load Packed Double Constant 7354 7355 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 7356 match(Set dst con); 7357 ins_cost(INSN_COST); 7358 format %{ "fmovd $dst, $con"%} 7359 ins_encode %{ 7360 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 7361 %} 7362 7363 ins_pipe(fp_imm_d); 7364 %} 7365 7366 // Load Double Constant 7367 7368 instruct loadConD(vRegD dst, immD con) %{ 7369 match(Set dst con); 7370 7371 ins_cost(INSN_COST * 5); 7372 format %{ 7373 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7374 %} 7375 7376 ins_encode %{ 7377 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 7378 %} 7379 7380 ins_pipe(fp_load_constant_d); 7381 %} 7382 7383 // Store Instructions 7384 7385 // Store CMS card-mark Immediate 7386 instruct storeimmCM0(immI0 zero, memory1 mem) 7387 %{ 7388 match(Set mem (StoreCM mem zero)); 7389 7390 ins_cost(INSN_COST); 7391 format %{ "storestore (elided)\n\t" 7392 "strb zr, $mem\t# byte" %} 7393 7394 ins_encode(aarch64_enc_strb0(mem)); 7395 7396 ins_pipe(istore_mem); 7397 %} 7398 7399 // Store CMS card-mark Immediate with intervening StoreStore 7400 // needed when using CMS with no conditional card marking 7401 instruct storeimmCM0_ordered(immI0 zero, memory1 mem) 7402 %{ 7403 match(Set mem (StoreCM mem zero)); 7404 7405 ins_cost(INSN_COST * 2); 7406 format %{ "storestore\n\t" 7407 "dmb ishst" 7408 "\n\tstrb zr, $mem\t# byte" %} 7409 7410 ins_encode(aarch64_enc_strb0_ordered(mem)); 7411 7412 ins_pipe(istore_mem); 7413 %} 7414 7415 // Store Byte 7416 instruct storeB(iRegIorL2I src, memory1 mem) 7417 %{ 7418 match(Set mem (StoreB mem src)); 7419 predicate(!needs_releasing_store(n)); 7420 7421 ins_cost(INSN_COST); 7422 format %{ "strb $src, $mem\t# byte" %} 7423 7424 ins_encode(aarch64_enc_strb(src, mem)); 7425 7426 ins_pipe(istore_reg_mem); 7427 %} 7428 7429 7430 instruct storeimmB0(immI0 zero, memory1 mem) 7431 %{ 7432 match(Set mem (StoreB mem zero)); 7433 predicate(!needs_releasing_store(n)); 7434 7435 ins_cost(INSN_COST); 7436 format %{ "strb rscractch2, $mem\t# byte" %} 7437 7438 ins_encode(aarch64_enc_strb0(mem)); 7439 7440 ins_pipe(istore_mem); 7441 %} 7442 7443 // Store Char/Short 7444 instruct storeC(iRegIorL2I src, memory2 mem) 7445 %{ 7446 match(Set mem (StoreC mem src)); 7447 predicate(!needs_releasing_store(n)); 7448 7449 ins_cost(INSN_COST); 7450 format %{ "strh $src, $mem\t# short" %} 7451 7452 ins_encode(aarch64_enc_strh(src, mem)); 7453 7454 ins_pipe(istore_reg_mem); 7455 %} 7456 7457 instruct storeimmC0(immI0 zero, memory2 mem) 7458 %{ 7459 match(Set mem (StoreC mem zero)); 7460 predicate(!needs_releasing_store(n)); 7461 7462 ins_cost(INSN_COST); 7463 format %{ "strh zr, $mem\t# short" %} 7464 7465 ins_encode(aarch64_enc_strh0(mem)); 7466 7467 ins_pipe(istore_mem); 7468 %} 7469 7470 // Store Integer 7471 7472 instruct storeI(iRegIorL2I src, memory4 mem) 7473 %{ 7474 match(Set mem(StoreI mem src)); 7475 predicate(!needs_releasing_store(n)); 7476 7477 ins_cost(INSN_COST); 7478 format %{ "strw $src, $mem\t# int" %} 7479 7480 ins_encode(aarch64_enc_strw(src, mem)); 7481 7482 ins_pipe(istore_reg_mem); 7483 %} 7484 7485 instruct storeimmI0(immI0 zero, memory4 mem) 7486 %{ 7487 match(Set mem(StoreI mem zero)); 7488 predicate(!needs_releasing_store(n)); 7489 7490 ins_cost(INSN_COST); 7491 format %{ "strw zr, $mem\t# int" %} 7492 7493 ins_encode(aarch64_enc_strw0(mem)); 7494 7495 ins_pipe(istore_mem); 7496 %} 7497 7498 // Store Long (64 bit signed) 7499 instruct storeL(iRegL src, memory8 mem) 7500 %{ 7501 match(Set mem (StoreL mem src)); 7502 predicate(!needs_releasing_store(n)); 7503 7504 ins_cost(INSN_COST); 7505 format %{ "str $src, $mem\t# int" %} 7506 7507 ins_encode(aarch64_enc_str(src, mem)); 7508 7509 ins_pipe(istore_reg_mem); 7510 %} 7511 7512 // Store Long (64 bit signed) 7513 instruct storeimmL0(immL0 zero, memory8 mem) 7514 %{ 7515 match(Set mem (StoreL mem zero)); 7516 predicate(!needs_releasing_store(n)); 7517 7518 ins_cost(INSN_COST); 7519 format %{ "str zr, $mem\t# int" %} 7520 7521 ins_encode(aarch64_enc_str0(mem)); 7522 7523 ins_pipe(istore_mem); 7524 %} 7525 7526 // Store Pointer 7527 instruct storeP(iRegP src, memory8 mem) 7528 %{ 7529 match(Set mem (StoreP mem src)); 7530 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0); 7531 7532 ins_cost(INSN_COST); 7533 format %{ "str $src, $mem\t# ptr" %} 7534 7535 ins_encode(aarch64_enc_str(src, mem)); 7536 7537 ins_pipe(istore_reg_mem); 7538 %} 7539 7540 // Store Pointer 7541 instruct storeimmP0(immP0 zero, memory8 mem) 7542 %{ 7543 match(Set mem (StoreP mem zero)); 7544 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0); 7545 7546 ins_cost(INSN_COST); 7547 format %{ "str zr, $mem\t# ptr" %} 7548 7549 ins_encode(aarch64_enc_str0(mem)); 7550 7551 ins_pipe(istore_mem); 7552 %} 7553 7554 // Store Compressed Pointer 7555 instruct storeN(iRegN src, memory4 mem) 7556 %{ 7557 match(Set mem (StoreN mem src)); 7558 predicate(!needs_releasing_store(n)); 7559 7560 ins_cost(INSN_COST); 7561 format %{ "strw $src, $mem\t# compressed ptr" %} 7562 7563 ins_encode(aarch64_enc_strw(src, mem)); 7564 7565 ins_pipe(istore_reg_mem); 7566 %} 7567 7568 instruct storeImmN0(immN0 zero, memory4 mem) 7569 %{ 7570 match(Set mem (StoreN mem zero)); 7571 predicate(!needs_releasing_store(n)); 7572 7573 ins_cost(INSN_COST); 7574 format %{ "strw zr, $mem\t# compressed ptr" %} 7575 7576 ins_encode(aarch64_enc_strw0(mem)); 7577 7578 ins_pipe(istore_mem); 7579 %} 7580 7581 // Store Float 7582 instruct storeF(vRegF src, memory4 mem) 7583 %{ 7584 match(Set mem (StoreF mem src)); 7585 predicate(!needs_releasing_store(n)); 7586 7587 ins_cost(INSN_COST); 7588 format %{ "strs $src, $mem\t# float" %} 7589 7590 ins_encode( aarch64_enc_strs(src, mem) ); 7591 7592 ins_pipe(pipe_class_memory); 7593 %} 7594 7595 // TODO 7596 // implement storeImmF0 and storeFImmPacked 7597 7598 // Store Double 7599 instruct storeD(vRegD src, memory8 mem) 7600 %{ 7601 match(Set mem (StoreD mem src)); 7602 predicate(!needs_releasing_store(n)); 7603 7604 ins_cost(INSN_COST); 7605 format %{ "strd $src, $mem\t# double" %} 7606 7607 ins_encode( aarch64_enc_strd(src, mem) ); 7608 7609 ins_pipe(pipe_class_memory); 7610 %} 7611 7612 // Store Compressed Klass Pointer 7613 instruct storeNKlass(iRegN src, memory4 mem) 7614 %{ 7615 predicate(!needs_releasing_store(n)); 7616 match(Set mem (StoreNKlass mem src)); 7617 7618 ins_cost(INSN_COST); 7619 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7620 7621 ins_encode(aarch64_enc_strw(src, mem)); 7622 7623 ins_pipe(istore_reg_mem); 7624 %} 7625 7626 // TODO 7627 // implement storeImmD0 and storeDImmPacked 7628 7629 // prefetch instructions 7630 // Must be safe to execute with invalid address (cannot fault). 7631 7632 instruct prefetchalloc( memory8 mem ) %{ 7633 match(PrefetchAllocation mem); 7634 7635 ins_cost(INSN_COST); 7636 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7637 7638 ins_encode( aarch64_enc_prefetchw(mem) ); 7639 7640 ins_pipe(iload_prefetch); 7641 %} 7642 7643 // ---------------- volatile loads and stores ---------------- 7644 7645 // Load Byte (8 bit signed) 7646 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7647 %{ 7648 match(Set dst (LoadB mem)); 7649 7650 ins_cost(VOLATILE_REF_COST); 7651 format %{ "ldarsb $dst, $mem\t# byte" %} 7652 7653 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7654 7655 ins_pipe(pipe_serial); 7656 %} 7657 7658 // Load Byte (8 bit signed) into long 7659 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7660 %{ 7661 match(Set dst (ConvI2L (LoadB mem))); 7662 7663 ins_cost(VOLATILE_REF_COST); 7664 format %{ "ldarsb $dst, $mem\t# byte" %} 7665 7666 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7667 7668 ins_pipe(pipe_serial); 7669 %} 7670 7671 // Load Byte (8 bit unsigned) 7672 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7673 %{ 7674 match(Set dst (LoadUB mem)); 7675 7676 ins_cost(VOLATILE_REF_COST); 7677 format %{ "ldarb $dst, $mem\t# byte" %} 7678 7679 ins_encode(aarch64_enc_ldarb(dst, mem)); 7680 7681 ins_pipe(pipe_serial); 7682 %} 7683 7684 // Load Byte (8 bit unsigned) into long 7685 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7686 %{ 7687 match(Set dst (ConvI2L (LoadUB mem))); 7688 7689 ins_cost(VOLATILE_REF_COST); 7690 format %{ "ldarb $dst, $mem\t# byte" %} 7691 7692 ins_encode(aarch64_enc_ldarb(dst, mem)); 7693 7694 ins_pipe(pipe_serial); 7695 %} 7696 7697 // Load Short (16 bit signed) 7698 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7699 %{ 7700 match(Set dst (LoadS mem)); 7701 7702 ins_cost(VOLATILE_REF_COST); 7703 format %{ "ldarshw $dst, $mem\t# short" %} 7704 7705 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7706 7707 ins_pipe(pipe_serial); 7708 %} 7709 7710 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7711 %{ 7712 match(Set dst (LoadUS mem)); 7713 7714 ins_cost(VOLATILE_REF_COST); 7715 format %{ "ldarhw $dst, $mem\t# short" %} 7716 7717 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7718 7719 ins_pipe(pipe_serial); 7720 %} 7721 7722 // Load Short/Char (16 bit unsigned) into long 7723 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7724 %{ 7725 match(Set dst (ConvI2L (LoadUS mem))); 7726 7727 ins_cost(VOLATILE_REF_COST); 7728 format %{ "ldarh $dst, $mem\t# short" %} 7729 7730 ins_encode(aarch64_enc_ldarh(dst, mem)); 7731 7732 ins_pipe(pipe_serial); 7733 %} 7734 7735 // Load Short/Char (16 bit signed) into long 7736 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7737 %{ 7738 match(Set dst (ConvI2L (LoadS mem))); 7739 7740 ins_cost(VOLATILE_REF_COST); 7741 format %{ "ldarh $dst, $mem\t# short" %} 7742 7743 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7744 7745 ins_pipe(pipe_serial); 7746 %} 7747 7748 // Load Integer (32 bit signed) 7749 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7750 %{ 7751 match(Set dst (LoadI mem)); 7752 7753 ins_cost(VOLATILE_REF_COST); 7754 format %{ "ldarw $dst, $mem\t# int" %} 7755 7756 ins_encode(aarch64_enc_ldarw(dst, mem)); 7757 7758 ins_pipe(pipe_serial); 7759 %} 7760 7761 // Load Integer (32 bit unsigned) into long 7762 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7763 %{ 7764 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7765 7766 ins_cost(VOLATILE_REF_COST); 7767 format %{ "ldarw $dst, $mem\t# int" %} 7768 7769 ins_encode(aarch64_enc_ldarw(dst, mem)); 7770 7771 ins_pipe(pipe_serial); 7772 %} 7773 7774 // Load Long (64 bit signed) 7775 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7776 %{ 7777 match(Set dst (LoadL mem)); 7778 7779 ins_cost(VOLATILE_REF_COST); 7780 format %{ "ldar $dst, $mem\t# int" %} 7781 7782 ins_encode(aarch64_enc_ldar(dst, mem)); 7783 7784 ins_pipe(pipe_serial); 7785 %} 7786 7787 // Load Pointer 7788 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7789 %{ 7790 match(Set dst (LoadP mem)); 7791 predicate(n->as_Load()->barrier_data() == 0); 7792 7793 ins_cost(VOLATILE_REF_COST); 7794 format %{ "ldar $dst, $mem\t# ptr" %} 7795 7796 ins_encode(aarch64_enc_ldar(dst, mem)); 7797 7798 ins_pipe(pipe_serial); 7799 %} 7800 7801 // Load Compressed Pointer 7802 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7803 %{ 7804 match(Set dst (LoadN mem)); 7805 7806 ins_cost(VOLATILE_REF_COST); 7807 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7808 7809 ins_encode(aarch64_enc_ldarw(dst, mem)); 7810 7811 ins_pipe(pipe_serial); 7812 %} 7813 7814 // Load Float 7815 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7816 %{ 7817 match(Set dst (LoadF mem)); 7818 7819 ins_cost(VOLATILE_REF_COST); 7820 format %{ "ldars $dst, $mem\t# float" %} 7821 7822 ins_encode( aarch64_enc_fldars(dst, mem) ); 7823 7824 ins_pipe(pipe_serial); 7825 %} 7826 7827 // Load Double 7828 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7829 %{ 7830 match(Set dst (LoadD mem)); 7831 7832 ins_cost(VOLATILE_REF_COST); 7833 format %{ "ldard $dst, $mem\t# double" %} 7834 7835 ins_encode( aarch64_enc_fldard(dst, mem) ); 7836 7837 ins_pipe(pipe_serial); 7838 %} 7839 7840 // Store Byte 7841 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7842 %{ 7843 match(Set mem (StoreB mem src)); 7844 7845 ins_cost(VOLATILE_REF_COST); 7846 format %{ "stlrb $src, $mem\t# byte" %} 7847 7848 ins_encode(aarch64_enc_stlrb(src, mem)); 7849 7850 ins_pipe(pipe_class_memory); 7851 %} 7852 7853 instruct storeimmB0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7854 %{ 7855 match(Set mem (StoreB mem zero)); 7856 7857 ins_cost(VOLATILE_REF_COST); 7858 format %{ "stlrb zr, $mem\t# byte" %} 7859 7860 ins_encode(aarch64_enc_stlrb0(mem)); 7861 7862 ins_pipe(pipe_class_memory); 7863 %} 7864 7865 // Store Char/Short 7866 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7867 %{ 7868 match(Set mem (StoreC mem src)); 7869 7870 ins_cost(VOLATILE_REF_COST); 7871 format %{ "stlrh $src, $mem\t# short" %} 7872 7873 ins_encode(aarch64_enc_stlrh(src, mem)); 7874 7875 ins_pipe(pipe_class_memory); 7876 %} 7877 7878 instruct storeimmC0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7879 %{ 7880 match(Set mem (StoreC mem zero)); 7881 7882 ins_cost(VOLATILE_REF_COST); 7883 format %{ "stlrh zr, $mem\t# short" %} 7884 7885 ins_encode(aarch64_enc_stlrh0(mem)); 7886 7887 ins_pipe(pipe_class_memory); 7888 %} 7889 7890 // Store Integer 7891 7892 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7893 %{ 7894 match(Set mem(StoreI mem src)); 7895 7896 ins_cost(VOLATILE_REF_COST); 7897 format %{ "stlrw $src, $mem\t# int" %} 7898 7899 ins_encode(aarch64_enc_stlrw(src, mem)); 7900 7901 ins_pipe(pipe_class_memory); 7902 %} 7903 7904 instruct storeimmI0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7905 %{ 7906 match(Set mem(StoreI mem zero)); 7907 7908 ins_cost(VOLATILE_REF_COST); 7909 format %{ "stlrw zr, $mem\t# int" %} 7910 7911 ins_encode(aarch64_enc_stlrw0(mem)); 7912 7913 ins_pipe(pipe_class_memory); 7914 %} 7915 7916 // Store Long (64 bit signed) 7917 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7918 %{ 7919 match(Set mem (StoreL mem src)); 7920 7921 ins_cost(VOLATILE_REF_COST); 7922 format %{ "stlr $src, $mem\t# int" %} 7923 7924 ins_encode(aarch64_enc_stlr(src, mem)); 7925 7926 ins_pipe(pipe_class_memory); 7927 %} 7928 7929 instruct storeimmL0_volatile(immL0 zero, /* sync_memory*/indirect mem) 7930 %{ 7931 match(Set mem (StoreL mem zero)); 7932 7933 ins_cost(VOLATILE_REF_COST); 7934 format %{ "stlr zr, $mem\t# int" %} 7935 7936 ins_encode(aarch64_enc_stlr0(mem)); 7937 7938 ins_pipe(pipe_class_memory); 7939 %} 7940 7941 // Store Pointer 7942 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7943 %{ 7944 match(Set mem (StoreP mem src)); 7945 predicate(n->as_Store()->barrier_data() == 0); 7946 7947 ins_cost(VOLATILE_REF_COST); 7948 format %{ "stlr $src, $mem\t# ptr" %} 7949 7950 ins_encode(aarch64_enc_stlr(src, mem)); 7951 7952 ins_pipe(pipe_class_memory); 7953 %} 7954 7955 instruct storeimmP0_volatile(immP0 zero, /* sync_memory*/indirect mem) 7956 %{ 7957 match(Set mem (StoreP mem zero)); 7958 predicate(n->as_Store()->barrier_data() == 0); 7959 7960 ins_cost(VOLATILE_REF_COST); 7961 format %{ "stlr zr, $mem\t# ptr" %} 7962 7963 ins_encode(aarch64_enc_stlr0(mem)); 7964 7965 ins_pipe(pipe_class_memory); 7966 %} 7967 7968 // Store Compressed Pointer 7969 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7970 %{ 7971 match(Set mem (StoreN mem src)); 7972 7973 ins_cost(VOLATILE_REF_COST); 7974 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7975 7976 ins_encode(aarch64_enc_stlrw(src, mem)); 7977 7978 ins_pipe(pipe_class_memory); 7979 %} 7980 7981 instruct storeimmN0_volatile(immN0 zero, /* sync_memory*/indirect mem) 7982 %{ 7983 match(Set mem (StoreN mem zero)); 7984 7985 ins_cost(VOLATILE_REF_COST); 7986 format %{ "stlrw zr, $mem\t# compressed ptr" %} 7987 7988 ins_encode(aarch64_enc_stlrw0(mem)); 7989 7990 ins_pipe(pipe_class_memory); 7991 %} 7992 7993 // Store Float 7994 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 7995 %{ 7996 match(Set mem (StoreF mem src)); 7997 7998 ins_cost(VOLATILE_REF_COST); 7999 format %{ "stlrs $src, $mem\t# float" %} 8000 8001 ins_encode( aarch64_enc_fstlrs(src, mem) ); 8002 8003 ins_pipe(pipe_class_memory); 8004 %} 8005 8006 // TODO 8007 // implement storeImmF0 and storeFImmPacked 8008 8009 // Store Double 8010 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 8011 %{ 8012 match(Set mem (StoreD mem src)); 8013 8014 ins_cost(VOLATILE_REF_COST); 8015 format %{ "stlrd $src, $mem\t# double" %} 8016 8017 ins_encode( aarch64_enc_fstlrd(src, mem) ); 8018 8019 ins_pipe(pipe_class_memory); 8020 %} 8021 8022 // ---------------- end of volatile loads and stores ---------------- 8023 8024 instruct cacheWB(indirect addr) 8025 %{ 8026 predicate(VM_Version::supports_data_cache_line_flush()); 8027 match(CacheWB addr); 8028 8029 ins_cost(100); 8030 format %{"cache wb $addr" %} 8031 ins_encode %{ 8032 assert($addr->index_position() < 0, "should be"); 8033 assert($addr$$disp == 0, "should be"); 8034 __ cache_wb(Address($addr$$base$$Register, 0)); 8035 %} 8036 ins_pipe(pipe_slow); // XXX 8037 %} 8038 8039 instruct cacheWBPreSync() 8040 %{ 8041 predicate(VM_Version::supports_data_cache_line_flush()); 8042 match(CacheWBPreSync); 8043 8044 ins_cost(100); 8045 format %{"cache wb presync" %} 8046 ins_encode %{ 8047 __ cache_wbsync(true); 8048 %} 8049 ins_pipe(pipe_slow); // XXX 8050 %} 8051 8052 instruct cacheWBPostSync() 8053 %{ 8054 predicate(VM_Version::supports_data_cache_line_flush()); 8055 match(CacheWBPostSync); 8056 8057 ins_cost(100); 8058 format %{"cache wb postsync" %} 8059 ins_encode %{ 8060 __ cache_wbsync(false); 8061 %} 8062 ins_pipe(pipe_slow); // XXX 8063 %} 8064 8065 // ============================================================================ 8066 // BSWAP Instructions 8067 8068 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 8069 match(Set dst (ReverseBytesI src)); 8070 8071 ins_cost(INSN_COST); 8072 format %{ "revw $dst, $src" %} 8073 8074 ins_encode %{ 8075 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 8076 %} 8077 8078 ins_pipe(ialu_reg); 8079 %} 8080 8081 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 8082 match(Set dst (ReverseBytesL src)); 8083 8084 ins_cost(INSN_COST); 8085 format %{ "rev $dst, $src" %} 8086 8087 ins_encode %{ 8088 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 8089 %} 8090 8091 ins_pipe(ialu_reg); 8092 %} 8093 8094 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 8095 match(Set dst (ReverseBytesUS src)); 8096 8097 ins_cost(INSN_COST); 8098 format %{ "rev16w $dst, $src" %} 8099 8100 ins_encode %{ 8101 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 8102 %} 8103 8104 ins_pipe(ialu_reg); 8105 %} 8106 8107 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 8108 match(Set dst (ReverseBytesS src)); 8109 8110 ins_cost(INSN_COST); 8111 format %{ "rev16w $dst, $src\n\t" 8112 "sbfmw $dst, $dst, #0, #15" %} 8113 8114 ins_encode %{ 8115 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 8116 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 8117 %} 8118 8119 ins_pipe(ialu_reg); 8120 %} 8121 8122 // ============================================================================ 8123 // Zero Count Instructions 8124 8125 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8126 match(Set dst (CountLeadingZerosI src)); 8127 8128 ins_cost(INSN_COST); 8129 format %{ "clzw $dst, $src" %} 8130 ins_encode %{ 8131 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 8132 %} 8133 8134 ins_pipe(ialu_reg); 8135 %} 8136 8137 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 8138 match(Set dst (CountLeadingZerosL src)); 8139 8140 ins_cost(INSN_COST); 8141 format %{ "clz $dst, $src" %} 8142 ins_encode %{ 8143 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 8144 %} 8145 8146 ins_pipe(ialu_reg); 8147 %} 8148 8149 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8150 match(Set dst (CountTrailingZerosI src)); 8151 8152 ins_cost(INSN_COST * 2); 8153 format %{ "rbitw $dst, $src\n\t" 8154 "clzw $dst, $dst" %} 8155 ins_encode %{ 8156 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 8157 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 8158 %} 8159 8160 ins_pipe(ialu_reg); 8161 %} 8162 8163 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 8164 match(Set dst (CountTrailingZerosL src)); 8165 8166 ins_cost(INSN_COST * 2); 8167 format %{ "rbit $dst, $src\n\t" 8168 "clz $dst, $dst" %} 8169 ins_encode %{ 8170 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 8171 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 8172 %} 8173 8174 ins_pipe(ialu_reg); 8175 %} 8176 8177 //---------- Population Count Instructions ------------------------------------- 8178 // 8179 8180 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 8181 match(Set dst (PopCountI src)); 8182 effect(TEMP tmp); 8183 ins_cost(INSN_COST * 13); 8184 8185 format %{ "movw $src, $src\n\t" 8186 "mov $tmp, $src\t# vector (1D)\n\t" 8187 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8188 "addv $tmp, $tmp\t# vector (8B)\n\t" 8189 "mov $dst, $tmp\t# vector (1D)" %} 8190 ins_encode %{ 8191 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 8192 __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); 8193 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8194 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8195 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8196 %} 8197 8198 ins_pipe(pipe_class_default); 8199 %} 8200 8201 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ 8202 match(Set dst (PopCountI (LoadI mem))); 8203 effect(TEMP tmp); 8204 ins_cost(INSN_COST * 13); 8205 8206 format %{ "ldrs $tmp, $mem\n\t" 8207 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8208 "addv $tmp, $tmp\t# vector (8B)\n\t" 8209 "mov $dst, $tmp\t# vector (1D)" %} 8210 ins_encode %{ 8211 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8212 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 8213 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 8214 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8215 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8216 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8217 %} 8218 8219 ins_pipe(pipe_class_default); 8220 %} 8221 8222 // Note: Long.bitCount(long) returns an int. 8223 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 8224 match(Set dst (PopCountL src)); 8225 effect(TEMP tmp); 8226 ins_cost(INSN_COST * 13); 8227 8228 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 8229 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8230 "addv $tmp, $tmp\t# vector (8B)\n\t" 8231 "mov $dst, $tmp\t# vector (1D)" %} 8232 ins_encode %{ 8233 __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); 8234 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8235 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8236 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8237 %} 8238 8239 ins_pipe(pipe_class_default); 8240 %} 8241 8242 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ 8243 match(Set dst (PopCountL (LoadL mem))); 8244 effect(TEMP tmp); 8245 ins_cost(INSN_COST * 13); 8246 8247 format %{ "ldrd $tmp, $mem\n\t" 8248 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8249 "addv $tmp, $tmp\t# vector (8B)\n\t" 8250 "mov $dst, $tmp\t# vector (1D)" %} 8251 ins_encode %{ 8252 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8253 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 8254 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 8255 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8256 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8257 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8258 %} 8259 8260 ins_pipe(pipe_class_default); 8261 %} 8262 8263 // ============================================================================ 8264 // VerifyVectorAlignment Instruction 8265 8266 instruct verify_vector_alignment(iRegP addr, immL_positive_bitmaskI mask, rFlagsReg cr) %{ 8267 match(Set addr (VerifyVectorAlignment addr mask)); 8268 effect(KILL cr); 8269 format %{ "verify_vector_alignment $addr $mask \t! verify alignment" %} 8270 ins_encode %{ 8271 Label Lskip; 8272 // check if masked bits of addr are zero 8273 __ tst($addr$$Register, $mask$$constant); 8274 __ br(Assembler::EQ, Lskip); 8275 __ stop("verify_vector_alignment found a misaligned vector memory access"); 8276 __ bind(Lskip); 8277 %} 8278 ins_pipe(pipe_slow); 8279 %} 8280 8281 // ============================================================================ 8282 // MemBar Instruction 8283 8284 instruct load_fence() %{ 8285 match(LoadFence); 8286 ins_cost(VOLATILE_REF_COST); 8287 8288 format %{ "load_fence" %} 8289 8290 ins_encode %{ 8291 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8292 %} 8293 ins_pipe(pipe_serial); 8294 %} 8295 8296 instruct unnecessary_membar_acquire() %{ 8297 predicate(unnecessary_acquire(n)); 8298 match(MemBarAcquire); 8299 ins_cost(0); 8300 8301 format %{ "membar_acquire (elided)" %} 8302 8303 ins_encode %{ 8304 __ block_comment("membar_acquire (elided)"); 8305 %} 8306 8307 ins_pipe(pipe_class_empty); 8308 %} 8309 8310 instruct membar_acquire() %{ 8311 match(MemBarAcquire); 8312 ins_cost(VOLATILE_REF_COST); 8313 8314 format %{ "membar_acquire\n\t" 8315 "dmb ish" %} 8316 8317 ins_encode %{ 8318 __ block_comment("membar_acquire"); 8319 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8320 %} 8321 8322 ins_pipe(pipe_serial); 8323 %} 8324 8325 8326 instruct membar_acquire_lock() %{ 8327 match(MemBarAcquireLock); 8328 ins_cost(VOLATILE_REF_COST); 8329 8330 format %{ "membar_acquire_lock (elided)" %} 8331 8332 ins_encode %{ 8333 __ block_comment("membar_acquire_lock (elided)"); 8334 %} 8335 8336 ins_pipe(pipe_serial); 8337 %} 8338 8339 instruct store_fence() %{ 8340 match(StoreFence); 8341 ins_cost(VOLATILE_REF_COST); 8342 8343 format %{ "store_fence" %} 8344 8345 ins_encode %{ 8346 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8347 %} 8348 ins_pipe(pipe_serial); 8349 %} 8350 8351 instruct unnecessary_membar_release() %{ 8352 predicate(unnecessary_release(n)); 8353 match(MemBarRelease); 8354 ins_cost(0); 8355 8356 format %{ "membar_release (elided)" %} 8357 8358 ins_encode %{ 8359 __ block_comment("membar_release (elided)"); 8360 %} 8361 ins_pipe(pipe_serial); 8362 %} 8363 8364 instruct membar_release() %{ 8365 match(MemBarRelease); 8366 ins_cost(VOLATILE_REF_COST); 8367 8368 format %{ "membar_release\n\t" 8369 "dmb ish" %} 8370 8371 ins_encode %{ 8372 __ block_comment("membar_release"); 8373 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8374 %} 8375 ins_pipe(pipe_serial); 8376 %} 8377 8378 instruct membar_storestore() %{ 8379 match(MemBarStoreStore); 8380 match(StoreStoreFence); 8381 ins_cost(VOLATILE_REF_COST); 8382 8383 format %{ "MEMBAR-store-store" %} 8384 8385 ins_encode %{ 8386 __ membar(Assembler::StoreStore); 8387 %} 8388 ins_pipe(pipe_serial); 8389 %} 8390 8391 instruct membar_release_lock() %{ 8392 match(MemBarReleaseLock); 8393 ins_cost(VOLATILE_REF_COST); 8394 8395 format %{ "membar_release_lock (elided)" %} 8396 8397 ins_encode %{ 8398 __ block_comment("membar_release_lock (elided)"); 8399 %} 8400 8401 ins_pipe(pipe_serial); 8402 %} 8403 8404 instruct unnecessary_membar_volatile() %{ 8405 predicate(unnecessary_volatile(n)); 8406 match(MemBarVolatile); 8407 ins_cost(0); 8408 8409 format %{ "membar_volatile (elided)" %} 8410 8411 ins_encode %{ 8412 __ block_comment("membar_volatile (elided)"); 8413 %} 8414 8415 ins_pipe(pipe_serial); 8416 %} 8417 8418 instruct membar_volatile() %{ 8419 match(MemBarVolatile); 8420 ins_cost(VOLATILE_REF_COST*100); 8421 8422 format %{ "membar_volatile\n\t" 8423 "dmb ish"%} 8424 8425 ins_encode %{ 8426 __ block_comment("membar_volatile"); 8427 __ membar(Assembler::StoreLoad); 8428 %} 8429 8430 ins_pipe(pipe_serial); 8431 %} 8432 8433 // ============================================================================ 8434 // Cast/Convert Instructions 8435 8436 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8437 match(Set dst (CastX2P src)); 8438 8439 ins_cost(INSN_COST); 8440 format %{ "mov $dst, $src\t# long -> ptr" %} 8441 8442 ins_encode %{ 8443 if ($dst$$reg != $src$$reg) { 8444 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8445 } 8446 %} 8447 8448 ins_pipe(ialu_reg); 8449 %} 8450 8451 instruct castN2X(iRegLNoSp dst, iRegN src) %{ 8452 match(Set dst (CastP2X src)); 8453 8454 ins_cost(INSN_COST); 8455 format %{ "mov $dst, $src\t# ptr -> long" %} 8456 8457 ins_encode %{ 8458 if ($dst$$reg != $src$$reg) { 8459 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8460 } 8461 %} 8462 8463 ins_pipe(ialu_reg); 8464 %} 8465 8466 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8467 match(Set dst (CastP2X src)); 8468 8469 ins_cost(INSN_COST); 8470 format %{ "mov $dst, $src\t# ptr -> long" %} 8471 8472 ins_encode %{ 8473 if ($dst$$reg != $src$$reg) { 8474 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8475 } 8476 %} 8477 8478 ins_pipe(ialu_reg); 8479 %} 8480 8481 // Convert oop into int for vectors alignment masking 8482 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8483 match(Set dst (ConvL2I (CastP2X src))); 8484 8485 ins_cost(INSN_COST); 8486 format %{ "movw $dst, $src\t# ptr -> int" %} 8487 ins_encode %{ 8488 __ movw($dst$$Register, $src$$Register); 8489 %} 8490 8491 ins_pipe(ialu_reg); 8492 %} 8493 8494 // Convert compressed oop into int for vectors alignment masking 8495 // in case of 32bit oops (heap < 4Gb). 8496 instruct convN2I(iRegINoSp dst, iRegN src) 8497 %{ 8498 predicate(CompressedOops::shift() == 0); 8499 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8500 8501 ins_cost(INSN_COST); 8502 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8503 ins_encode %{ 8504 __ movw($dst$$Register, $src$$Register); 8505 %} 8506 8507 ins_pipe(ialu_reg); 8508 %} 8509 8510 8511 // Convert oop pointer into compressed form 8512 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8513 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8514 match(Set dst (EncodeP src)); 8515 effect(KILL cr); 8516 ins_cost(INSN_COST * 3); 8517 format %{ "encode_heap_oop $dst, $src" %} 8518 ins_encode %{ 8519 Register s = $src$$Register; 8520 Register d = $dst$$Register; 8521 __ encode_heap_oop(d, s); 8522 %} 8523 ins_pipe(ialu_reg); 8524 %} 8525 8526 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8527 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8528 match(Set dst (EncodeP src)); 8529 ins_cost(INSN_COST * 3); 8530 format %{ "encode_heap_oop_not_null $dst, $src" %} 8531 ins_encode %{ 8532 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8533 %} 8534 ins_pipe(ialu_reg); 8535 %} 8536 8537 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8538 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8539 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8540 match(Set dst (DecodeN src)); 8541 ins_cost(INSN_COST * 3); 8542 format %{ "decode_heap_oop $dst, $src" %} 8543 ins_encode %{ 8544 Register s = $src$$Register; 8545 Register d = $dst$$Register; 8546 __ decode_heap_oop(d, s); 8547 %} 8548 ins_pipe(ialu_reg); 8549 %} 8550 8551 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8552 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8553 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8554 match(Set dst (DecodeN src)); 8555 ins_cost(INSN_COST * 3); 8556 format %{ "decode_heap_oop_not_null $dst, $src" %} 8557 ins_encode %{ 8558 Register s = $src$$Register; 8559 Register d = $dst$$Register; 8560 __ decode_heap_oop_not_null(d, s); 8561 %} 8562 ins_pipe(ialu_reg); 8563 %} 8564 8565 // n.b. AArch64 implementations of encode_klass_not_null and 8566 // decode_klass_not_null do not modify the flags register so, unlike 8567 // Intel, we don't kill CR as a side effect here 8568 8569 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8570 match(Set dst (EncodePKlass src)); 8571 8572 ins_cost(INSN_COST * 3); 8573 format %{ "encode_klass_not_null $dst,$src" %} 8574 8575 ins_encode %{ 8576 Register src_reg = as_Register($src$$reg); 8577 Register dst_reg = as_Register($dst$$reg); 8578 __ encode_klass_not_null(dst_reg, src_reg); 8579 %} 8580 8581 ins_pipe(ialu_reg); 8582 %} 8583 8584 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8585 match(Set dst (DecodeNKlass src)); 8586 8587 ins_cost(INSN_COST * 3); 8588 format %{ "decode_klass_not_null $dst,$src" %} 8589 8590 ins_encode %{ 8591 Register src_reg = as_Register($src$$reg); 8592 Register dst_reg = as_Register($dst$$reg); 8593 if (dst_reg != src_reg) { 8594 __ decode_klass_not_null(dst_reg, src_reg); 8595 } else { 8596 __ decode_klass_not_null(dst_reg); 8597 } 8598 %} 8599 8600 ins_pipe(ialu_reg); 8601 %} 8602 8603 instruct checkCastPP(iRegPNoSp dst) 8604 %{ 8605 match(Set dst (CheckCastPP dst)); 8606 8607 size(0); 8608 format %{ "# checkcastPP of $dst" %} 8609 ins_encode(/* empty encoding */); 8610 ins_pipe(pipe_class_empty); 8611 %} 8612 8613 instruct castPP(iRegPNoSp dst) 8614 %{ 8615 match(Set dst (CastPP dst)); 8616 8617 size(0); 8618 format %{ "# castPP of $dst" %} 8619 ins_encode(/* empty encoding */); 8620 ins_pipe(pipe_class_empty); 8621 %} 8622 8623 instruct castII(iRegI dst) 8624 %{ 8625 match(Set dst (CastII dst)); 8626 8627 size(0); 8628 format %{ "# castII of $dst" %} 8629 ins_encode(/* empty encoding */); 8630 ins_cost(0); 8631 ins_pipe(pipe_class_empty); 8632 %} 8633 8634 instruct castLL(iRegL dst) 8635 %{ 8636 match(Set dst (CastLL dst)); 8637 8638 size(0); 8639 format %{ "# castLL of $dst" %} 8640 ins_encode(/* empty encoding */); 8641 ins_cost(0); 8642 ins_pipe(pipe_class_empty); 8643 %} 8644 8645 instruct castFF(vRegF dst) 8646 %{ 8647 match(Set dst (CastFF dst)); 8648 8649 size(0); 8650 format %{ "# castFF of $dst" %} 8651 ins_encode(/* empty encoding */); 8652 ins_cost(0); 8653 ins_pipe(pipe_class_empty); 8654 %} 8655 8656 instruct castDD(vRegD dst) 8657 %{ 8658 match(Set dst (CastDD dst)); 8659 8660 size(0); 8661 format %{ "# castDD of $dst" %} 8662 ins_encode(/* empty encoding */); 8663 ins_cost(0); 8664 ins_pipe(pipe_class_empty); 8665 %} 8666 8667 instruct castVV(vReg dst) 8668 %{ 8669 match(Set dst (CastVV dst)); 8670 8671 size(0); 8672 format %{ "# castVV of $dst" %} 8673 ins_encode(/* empty encoding */); 8674 ins_cost(0); 8675 ins_pipe(pipe_class_empty); 8676 %} 8677 8678 instruct castVVMask(pRegGov dst) 8679 %{ 8680 match(Set dst (CastVV dst)); 8681 8682 size(0); 8683 format %{ "# castVV of $dst" %} 8684 ins_encode(/* empty encoding */); 8685 ins_cost(0); 8686 ins_pipe(pipe_class_empty); 8687 %} 8688 8689 // ============================================================================ 8690 // Atomic operation instructions 8691 // 8692 8693 // standard CompareAndSwapX when we are using barriers 8694 // these have higher priority than the rules selected by a predicate 8695 8696 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8697 // can't match them 8698 8699 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8700 8701 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8702 ins_cost(2 * VOLATILE_REF_COST); 8703 8704 effect(KILL cr); 8705 8706 format %{ 8707 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8708 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8709 %} 8710 8711 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8712 aarch64_enc_cset_eq(res)); 8713 8714 ins_pipe(pipe_slow); 8715 %} 8716 8717 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8718 8719 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8720 ins_cost(2 * VOLATILE_REF_COST); 8721 8722 effect(KILL cr); 8723 8724 format %{ 8725 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8726 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8727 %} 8728 8729 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8730 aarch64_enc_cset_eq(res)); 8731 8732 ins_pipe(pipe_slow); 8733 %} 8734 8735 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8736 8737 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8738 ins_cost(2 * VOLATILE_REF_COST); 8739 8740 effect(KILL cr); 8741 8742 format %{ 8743 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8744 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8745 %} 8746 8747 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8748 aarch64_enc_cset_eq(res)); 8749 8750 ins_pipe(pipe_slow); 8751 %} 8752 8753 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8754 8755 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8756 ins_cost(2 * VOLATILE_REF_COST); 8757 8758 effect(KILL cr); 8759 8760 format %{ 8761 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8762 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8763 %} 8764 8765 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8766 aarch64_enc_cset_eq(res)); 8767 8768 ins_pipe(pipe_slow); 8769 %} 8770 8771 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8772 8773 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8774 predicate(n->as_LoadStore()->barrier_data() == 0); 8775 ins_cost(2 * VOLATILE_REF_COST); 8776 8777 effect(KILL cr); 8778 8779 format %{ 8780 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8781 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8782 %} 8783 8784 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8785 aarch64_enc_cset_eq(res)); 8786 8787 ins_pipe(pipe_slow); 8788 %} 8789 8790 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8791 8792 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8793 ins_cost(2 * VOLATILE_REF_COST); 8794 8795 effect(KILL cr); 8796 8797 format %{ 8798 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8799 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8800 %} 8801 8802 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8803 aarch64_enc_cset_eq(res)); 8804 8805 ins_pipe(pipe_slow); 8806 %} 8807 8808 // alternative CompareAndSwapX when we are eliding barriers 8809 8810 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8811 8812 predicate(needs_acquiring_load_exclusive(n)); 8813 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8814 ins_cost(VOLATILE_REF_COST); 8815 8816 effect(KILL cr); 8817 8818 format %{ 8819 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8820 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8821 %} 8822 8823 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8824 aarch64_enc_cset_eq(res)); 8825 8826 ins_pipe(pipe_slow); 8827 %} 8828 8829 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8830 8831 predicate(needs_acquiring_load_exclusive(n)); 8832 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8833 ins_cost(VOLATILE_REF_COST); 8834 8835 effect(KILL cr); 8836 8837 format %{ 8838 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8839 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8840 %} 8841 8842 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8843 aarch64_enc_cset_eq(res)); 8844 8845 ins_pipe(pipe_slow); 8846 %} 8847 8848 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8849 8850 predicate(needs_acquiring_load_exclusive(n)); 8851 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8852 ins_cost(VOLATILE_REF_COST); 8853 8854 effect(KILL cr); 8855 8856 format %{ 8857 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8858 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8859 %} 8860 8861 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8862 aarch64_enc_cset_eq(res)); 8863 8864 ins_pipe(pipe_slow); 8865 %} 8866 8867 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8868 8869 predicate(needs_acquiring_load_exclusive(n)); 8870 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8871 ins_cost(VOLATILE_REF_COST); 8872 8873 effect(KILL cr); 8874 8875 format %{ 8876 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8877 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8878 %} 8879 8880 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8881 aarch64_enc_cset_eq(res)); 8882 8883 ins_pipe(pipe_slow); 8884 %} 8885 8886 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8887 8888 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8889 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8890 ins_cost(VOLATILE_REF_COST); 8891 8892 effect(KILL cr); 8893 8894 format %{ 8895 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8896 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8897 %} 8898 8899 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8900 aarch64_enc_cset_eq(res)); 8901 8902 ins_pipe(pipe_slow); 8903 %} 8904 8905 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8906 8907 predicate(needs_acquiring_load_exclusive(n)); 8908 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8909 ins_cost(VOLATILE_REF_COST); 8910 8911 effect(KILL cr); 8912 8913 format %{ 8914 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8915 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8916 %} 8917 8918 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8919 aarch64_enc_cset_eq(res)); 8920 8921 ins_pipe(pipe_slow); 8922 %} 8923 8924 8925 // --------------------------------------------------------------------- 8926 8927 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8928 8929 // Sundry CAS operations. Note that release is always true, 8930 // regardless of the memory ordering of the CAS. This is because we 8931 // need the volatile case to be sequentially consistent but there is 8932 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8933 // can't check the type of memory ordering here, so we always emit a 8934 // STLXR. 8935 8936 // This section is generated from cas.m4 8937 8938 8939 // This pattern is generated automatically from cas.m4. 8940 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8941 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8942 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8943 ins_cost(2 * VOLATILE_REF_COST); 8944 effect(TEMP_DEF res, KILL cr); 8945 format %{ 8946 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8947 %} 8948 ins_encode %{ 8949 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8950 Assembler::byte, /*acquire*/ false, /*release*/ true, 8951 /*weak*/ false, $res$$Register); 8952 __ sxtbw($res$$Register, $res$$Register); 8953 %} 8954 ins_pipe(pipe_slow); 8955 %} 8956 8957 // This pattern is generated automatically from cas.m4. 8958 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8959 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8960 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8961 ins_cost(2 * VOLATILE_REF_COST); 8962 effect(TEMP_DEF res, KILL cr); 8963 format %{ 8964 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8965 %} 8966 ins_encode %{ 8967 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8968 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8969 /*weak*/ false, $res$$Register); 8970 __ sxthw($res$$Register, $res$$Register); 8971 %} 8972 ins_pipe(pipe_slow); 8973 %} 8974 8975 // This pattern is generated automatically from cas.m4. 8976 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8977 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8978 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8979 ins_cost(2 * VOLATILE_REF_COST); 8980 effect(TEMP_DEF res, KILL cr); 8981 format %{ 8982 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8983 %} 8984 ins_encode %{ 8985 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8986 Assembler::word, /*acquire*/ false, /*release*/ true, 8987 /*weak*/ false, $res$$Register); 8988 %} 8989 ins_pipe(pipe_slow); 8990 %} 8991 8992 // This pattern is generated automatically from cas.m4. 8993 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8994 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8995 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8996 ins_cost(2 * VOLATILE_REF_COST); 8997 effect(TEMP_DEF res, KILL cr); 8998 format %{ 8999 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9000 %} 9001 ins_encode %{ 9002 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9003 Assembler::xword, /*acquire*/ false, /*release*/ true, 9004 /*weak*/ false, $res$$Register); 9005 %} 9006 ins_pipe(pipe_slow); 9007 %} 9008 9009 // This pattern is generated automatically from cas.m4. 9010 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9011 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9012 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 9013 ins_cost(2 * VOLATILE_REF_COST); 9014 effect(TEMP_DEF res, KILL cr); 9015 format %{ 9016 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9017 %} 9018 ins_encode %{ 9019 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9020 Assembler::word, /*acquire*/ false, /*release*/ true, 9021 /*weak*/ false, $res$$Register); 9022 %} 9023 ins_pipe(pipe_slow); 9024 %} 9025 9026 // This pattern is generated automatically from cas.m4. 9027 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9028 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9029 predicate(n->as_LoadStore()->barrier_data() == 0); 9030 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 9031 ins_cost(2 * VOLATILE_REF_COST); 9032 effect(TEMP_DEF res, KILL cr); 9033 format %{ 9034 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9035 %} 9036 ins_encode %{ 9037 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9038 Assembler::xword, /*acquire*/ false, /*release*/ true, 9039 /*weak*/ false, $res$$Register); 9040 %} 9041 ins_pipe(pipe_slow); 9042 %} 9043 9044 // This pattern is generated automatically from cas.m4. 9045 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9046 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9047 predicate(needs_acquiring_load_exclusive(n)); 9048 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 9049 ins_cost(VOLATILE_REF_COST); 9050 effect(TEMP_DEF res, KILL cr); 9051 format %{ 9052 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9053 %} 9054 ins_encode %{ 9055 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9056 Assembler::byte, /*acquire*/ true, /*release*/ true, 9057 /*weak*/ false, $res$$Register); 9058 __ sxtbw($res$$Register, $res$$Register); 9059 %} 9060 ins_pipe(pipe_slow); 9061 %} 9062 9063 // This pattern is generated automatically from cas.m4. 9064 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9065 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9066 predicate(needs_acquiring_load_exclusive(n)); 9067 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 9068 ins_cost(VOLATILE_REF_COST); 9069 effect(TEMP_DEF res, KILL cr); 9070 format %{ 9071 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9072 %} 9073 ins_encode %{ 9074 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9075 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9076 /*weak*/ false, $res$$Register); 9077 __ sxthw($res$$Register, $res$$Register); 9078 %} 9079 ins_pipe(pipe_slow); 9080 %} 9081 9082 // This pattern is generated automatically from cas.m4. 9083 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9084 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9085 predicate(needs_acquiring_load_exclusive(n)); 9086 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 9087 ins_cost(VOLATILE_REF_COST); 9088 effect(TEMP_DEF res, KILL cr); 9089 format %{ 9090 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9091 %} 9092 ins_encode %{ 9093 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9094 Assembler::word, /*acquire*/ true, /*release*/ true, 9095 /*weak*/ false, $res$$Register); 9096 %} 9097 ins_pipe(pipe_slow); 9098 %} 9099 9100 // This pattern is generated automatically from cas.m4. 9101 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9102 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9103 predicate(needs_acquiring_load_exclusive(n)); 9104 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 9105 ins_cost(VOLATILE_REF_COST); 9106 effect(TEMP_DEF res, KILL cr); 9107 format %{ 9108 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9109 %} 9110 ins_encode %{ 9111 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9112 Assembler::xword, /*acquire*/ true, /*release*/ true, 9113 /*weak*/ false, $res$$Register); 9114 %} 9115 ins_pipe(pipe_slow); 9116 %} 9117 9118 // This pattern is generated automatically from cas.m4. 9119 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9120 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9121 predicate(needs_acquiring_load_exclusive(n)); 9122 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 9123 ins_cost(VOLATILE_REF_COST); 9124 effect(TEMP_DEF res, KILL cr); 9125 format %{ 9126 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9127 %} 9128 ins_encode %{ 9129 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9130 Assembler::word, /*acquire*/ true, /*release*/ true, 9131 /*weak*/ false, $res$$Register); 9132 %} 9133 ins_pipe(pipe_slow); 9134 %} 9135 9136 // This pattern is generated automatically from cas.m4. 9137 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9138 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9139 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9140 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 9141 ins_cost(VOLATILE_REF_COST); 9142 effect(TEMP_DEF res, KILL cr); 9143 format %{ 9144 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9145 %} 9146 ins_encode %{ 9147 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9148 Assembler::xword, /*acquire*/ true, /*release*/ true, 9149 /*weak*/ false, $res$$Register); 9150 %} 9151 ins_pipe(pipe_slow); 9152 %} 9153 9154 // This pattern is generated automatically from cas.m4. 9155 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9156 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9157 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9158 ins_cost(2 * VOLATILE_REF_COST); 9159 effect(KILL cr); 9160 format %{ 9161 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9162 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9163 %} 9164 ins_encode %{ 9165 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9166 Assembler::byte, /*acquire*/ false, /*release*/ true, 9167 /*weak*/ true, noreg); 9168 __ csetw($res$$Register, Assembler::EQ); 9169 %} 9170 ins_pipe(pipe_slow); 9171 %} 9172 9173 // This pattern is generated automatically from cas.m4. 9174 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9175 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9176 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9177 ins_cost(2 * VOLATILE_REF_COST); 9178 effect(KILL cr); 9179 format %{ 9180 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9181 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9182 %} 9183 ins_encode %{ 9184 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9185 Assembler::halfword, /*acquire*/ false, /*release*/ true, 9186 /*weak*/ true, noreg); 9187 __ csetw($res$$Register, Assembler::EQ); 9188 %} 9189 ins_pipe(pipe_slow); 9190 %} 9191 9192 // This pattern is generated automatically from cas.m4. 9193 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9194 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9195 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9196 ins_cost(2 * VOLATILE_REF_COST); 9197 effect(KILL cr); 9198 format %{ 9199 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9200 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9201 %} 9202 ins_encode %{ 9203 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9204 Assembler::word, /*acquire*/ false, /*release*/ true, 9205 /*weak*/ true, noreg); 9206 __ csetw($res$$Register, Assembler::EQ); 9207 %} 9208 ins_pipe(pipe_slow); 9209 %} 9210 9211 // This pattern is generated automatically from cas.m4. 9212 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9213 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9214 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9215 ins_cost(2 * VOLATILE_REF_COST); 9216 effect(KILL cr); 9217 format %{ 9218 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9219 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9220 %} 9221 ins_encode %{ 9222 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9223 Assembler::xword, /*acquire*/ false, /*release*/ true, 9224 /*weak*/ true, noreg); 9225 __ csetw($res$$Register, Assembler::EQ); 9226 %} 9227 ins_pipe(pipe_slow); 9228 %} 9229 9230 // This pattern is generated automatically from cas.m4. 9231 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9232 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9233 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9234 ins_cost(2 * VOLATILE_REF_COST); 9235 effect(KILL cr); 9236 format %{ 9237 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9238 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9239 %} 9240 ins_encode %{ 9241 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9242 Assembler::word, /*acquire*/ false, /*release*/ true, 9243 /*weak*/ true, noreg); 9244 __ csetw($res$$Register, Assembler::EQ); 9245 %} 9246 ins_pipe(pipe_slow); 9247 %} 9248 9249 // This pattern is generated automatically from cas.m4. 9250 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9251 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9252 predicate(n->as_LoadStore()->barrier_data() == 0); 9253 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9254 ins_cost(2 * VOLATILE_REF_COST); 9255 effect(KILL cr); 9256 format %{ 9257 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9258 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9259 %} 9260 ins_encode %{ 9261 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9262 Assembler::xword, /*acquire*/ false, /*release*/ true, 9263 /*weak*/ true, noreg); 9264 __ csetw($res$$Register, Assembler::EQ); 9265 %} 9266 ins_pipe(pipe_slow); 9267 %} 9268 9269 // This pattern is generated automatically from cas.m4. 9270 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9271 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9272 predicate(needs_acquiring_load_exclusive(n)); 9273 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9274 ins_cost(VOLATILE_REF_COST); 9275 effect(KILL cr); 9276 format %{ 9277 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9278 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9279 %} 9280 ins_encode %{ 9281 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9282 Assembler::byte, /*acquire*/ true, /*release*/ true, 9283 /*weak*/ true, noreg); 9284 __ csetw($res$$Register, Assembler::EQ); 9285 %} 9286 ins_pipe(pipe_slow); 9287 %} 9288 9289 // This pattern is generated automatically from cas.m4. 9290 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9291 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9292 predicate(needs_acquiring_load_exclusive(n)); 9293 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9294 ins_cost(VOLATILE_REF_COST); 9295 effect(KILL cr); 9296 format %{ 9297 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9298 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9299 %} 9300 ins_encode %{ 9301 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9302 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9303 /*weak*/ true, noreg); 9304 __ csetw($res$$Register, Assembler::EQ); 9305 %} 9306 ins_pipe(pipe_slow); 9307 %} 9308 9309 // This pattern is generated automatically from cas.m4. 9310 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9311 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9312 predicate(needs_acquiring_load_exclusive(n)); 9313 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9314 ins_cost(VOLATILE_REF_COST); 9315 effect(KILL cr); 9316 format %{ 9317 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9318 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9319 %} 9320 ins_encode %{ 9321 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9322 Assembler::word, /*acquire*/ true, /*release*/ true, 9323 /*weak*/ true, noreg); 9324 __ csetw($res$$Register, Assembler::EQ); 9325 %} 9326 ins_pipe(pipe_slow); 9327 %} 9328 9329 // This pattern is generated automatically from cas.m4. 9330 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9331 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9332 predicate(needs_acquiring_load_exclusive(n)); 9333 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9334 ins_cost(VOLATILE_REF_COST); 9335 effect(KILL cr); 9336 format %{ 9337 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9338 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9339 %} 9340 ins_encode %{ 9341 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9342 Assembler::xword, /*acquire*/ true, /*release*/ true, 9343 /*weak*/ true, noreg); 9344 __ csetw($res$$Register, Assembler::EQ); 9345 %} 9346 ins_pipe(pipe_slow); 9347 %} 9348 9349 // This pattern is generated automatically from cas.m4. 9350 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9351 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9352 predicate(needs_acquiring_load_exclusive(n)); 9353 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9354 ins_cost(VOLATILE_REF_COST); 9355 effect(KILL cr); 9356 format %{ 9357 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9358 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9359 %} 9360 ins_encode %{ 9361 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9362 Assembler::word, /*acquire*/ true, /*release*/ true, 9363 /*weak*/ true, noreg); 9364 __ csetw($res$$Register, Assembler::EQ); 9365 %} 9366 ins_pipe(pipe_slow); 9367 %} 9368 9369 // This pattern is generated automatically from cas.m4. 9370 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9371 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9372 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9373 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9374 ins_cost(VOLATILE_REF_COST); 9375 effect(KILL cr); 9376 format %{ 9377 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9378 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9379 %} 9380 ins_encode %{ 9381 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9382 Assembler::xword, /*acquire*/ true, /*release*/ true, 9383 /*weak*/ true, noreg); 9384 __ csetw($res$$Register, Assembler::EQ); 9385 %} 9386 ins_pipe(pipe_slow); 9387 %} 9388 9389 // END This section of the file is automatically generated. Do not edit -------------- 9390 // --------------------------------------------------------------------- 9391 9392 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 9393 match(Set prev (GetAndSetI mem newv)); 9394 ins_cost(2 * VOLATILE_REF_COST); 9395 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9396 ins_encode %{ 9397 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9398 %} 9399 ins_pipe(pipe_serial); 9400 %} 9401 9402 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9403 match(Set prev (GetAndSetL mem newv)); 9404 ins_cost(2 * VOLATILE_REF_COST); 9405 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9406 ins_encode %{ 9407 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9408 %} 9409 ins_pipe(pipe_serial); 9410 %} 9411 9412 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 9413 match(Set prev (GetAndSetN mem newv)); 9414 ins_cost(2 * VOLATILE_REF_COST); 9415 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9416 ins_encode %{ 9417 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9418 %} 9419 ins_pipe(pipe_serial); 9420 %} 9421 9422 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9423 predicate(n->as_LoadStore()->barrier_data() == 0); 9424 match(Set prev (GetAndSetP mem newv)); 9425 ins_cost(2 * VOLATILE_REF_COST); 9426 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9427 ins_encode %{ 9428 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9429 %} 9430 ins_pipe(pipe_serial); 9431 %} 9432 9433 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 9434 predicate(needs_acquiring_load_exclusive(n)); 9435 match(Set prev (GetAndSetI mem newv)); 9436 ins_cost(VOLATILE_REF_COST); 9437 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9438 ins_encode %{ 9439 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9440 %} 9441 ins_pipe(pipe_serial); 9442 %} 9443 9444 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9445 predicate(needs_acquiring_load_exclusive(n)); 9446 match(Set prev (GetAndSetL mem newv)); 9447 ins_cost(VOLATILE_REF_COST); 9448 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9449 ins_encode %{ 9450 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9451 %} 9452 ins_pipe(pipe_serial); 9453 %} 9454 9455 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 9456 predicate(needs_acquiring_load_exclusive(n)); 9457 match(Set prev (GetAndSetN mem newv)); 9458 ins_cost(VOLATILE_REF_COST); 9459 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9460 ins_encode %{ 9461 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9462 %} 9463 ins_pipe(pipe_serial); 9464 %} 9465 9466 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9467 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9468 match(Set prev (GetAndSetP mem newv)); 9469 ins_cost(VOLATILE_REF_COST); 9470 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9471 ins_encode %{ 9472 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9473 %} 9474 ins_pipe(pipe_serial); 9475 %} 9476 9477 9478 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9479 match(Set newval (GetAndAddL mem incr)); 9480 ins_cost(2 * VOLATILE_REF_COST + 1); 9481 format %{ "get_and_addL $newval, [$mem], $incr" %} 9482 ins_encode %{ 9483 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9484 %} 9485 ins_pipe(pipe_serial); 9486 %} 9487 9488 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 9489 predicate(n->as_LoadStore()->result_not_used()); 9490 match(Set dummy (GetAndAddL mem incr)); 9491 ins_cost(2 * VOLATILE_REF_COST); 9492 format %{ "get_and_addL [$mem], $incr" %} 9493 ins_encode %{ 9494 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 9495 %} 9496 ins_pipe(pipe_serial); 9497 %} 9498 9499 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9500 match(Set newval (GetAndAddL mem incr)); 9501 ins_cost(2 * VOLATILE_REF_COST + 1); 9502 format %{ "get_and_addL $newval, [$mem], $incr" %} 9503 ins_encode %{ 9504 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9505 %} 9506 ins_pipe(pipe_serial); 9507 %} 9508 9509 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9510 predicate(n->as_LoadStore()->result_not_used()); 9511 match(Set dummy (GetAndAddL mem incr)); 9512 ins_cost(2 * VOLATILE_REF_COST); 9513 format %{ "get_and_addL [$mem], $incr" %} 9514 ins_encode %{ 9515 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9516 %} 9517 ins_pipe(pipe_serial); 9518 %} 9519 9520 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9521 match(Set newval (GetAndAddI mem incr)); 9522 ins_cost(2 * VOLATILE_REF_COST + 1); 9523 format %{ "get_and_addI $newval, [$mem], $incr" %} 9524 ins_encode %{ 9525 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9526 %} 9527 ins_pipe(pipe_serial); 9528 %} 9529 9530 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9531 predicate(n->as_LoadStore()->result_not_used()); 9532 match(Set dummy (GetAndAddI mem incr)); 9533 ins_cost(2 * VOLATILE_REF_COST); 9534 format %{ "get_and_addI [$mem], $incr" %} 9535 ins_encode %{ 9536 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9537 %} 9538 ins_pipe(pipe_serial); 9539 %} 9540 9541 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9542 match(Set newval (GetAndAddI mem incr)); 9543 ins_cost(2 * VOLATILE_REF_COST + 1); 9544 format %{ "get_and_addI $newval, [$mem], $incr" %} 9545 ins_encode %{ 9546 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9547 %} 9548 ins_pipe(pipe_serial); 9549 %} 9550 9551 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9552 predicate(n->as_LoadStore()->result_not_used()); 9553 match(Set dummy (GetAndAddI mem incr)); 9554 ins_cost(2 * VOLATILE_REF_COST); 9555 format %{ "get_and_addI [$mem], $incr" %} 9556 ins_encode %{ 9557 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9558 %} 9559 ins_pipe(pipe_serial); 9560 %} 9561 9562 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9563 predicate(needs_acquiring_load_exclusive(n)); 9564 match(Set newval (GetAndAddL mem incr)); 9565 ins_cost(VOLATILE_REF_COST + 1); 9566 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9567 ins_encode %{ 9568 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9569 %} 9570 ins_pipe(pipe_serial); 9571 %} 9572 9573 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9574 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9575 match(Set dummy (GetAndAddL mem incr)); 9576 ins_cost(VOLATILE_REF_COST); 9577 format %{ "get_and_addL_acq [$mem], $incr" %} 9578 ins_encode %{ 9579 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9580 %} 9581 ins_pipe(pipe_serial); 9582 %} 9583 9584 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9585 predicate(needs_acquiring_load_exclusive(n)); 9586 match(Set newval (GetAndAddL mem incr)); 9587 ins_cost(VOLATILE_REF_COST + 1); 9588 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9589 ins_encode %{ 9590 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9591 %} 9592 ins_pipe(pipe_serial); 9593 %} 9594 9595 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9596 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9597 match(Set dummy (GetAndAddL mem incr)); 9598 ins_cost(VOLATILE_REF_COST); 9599 format %{ "get_and_addL_acq [$mem], $incr" %} 9600 ins_encode %{ 9601 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9602 %} 9603 ins_pipe(pipe_serial); 9604 %} 9605 9606 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9607 predicate(needs_acquiring_load_exclusive(n)); 9608 match(Set newval (GetAndAddI mem incr)); 9609 ins_cost(VOLATILE_REF_COST + 1); 9610 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9611 ins_encode %{ 9612 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9613 %} 9614 ins_pipe(pipe_serial); 9615 %} 9616 9617 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9618 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9619 match(Set dummy (GetAndAddI mem incr)); 9620 ins_cost(VOLATILE_REF_COST); 9621 format %{ "get_and_addI_acq [$mem], $incr" %} 9622 ins_encode %{ 9623 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9624 %} 9625 ins_pipe(pipe_serial); 9626 %} 9627 9628 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9629 predicate(needs_acquiring_load_exclusive(n)); 9630 match(Set newval (GetAndAddI mem incr)); 9631 ins_cost(VOLATILE_REF_COST + 1); 9632 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9633 ins_encode %{ 9634 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9635 %} 9636 ins_pipe(pipe_serial); 9637 %} 9638 9639 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9640 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9641 match(Set dummy (GetAndAddI mem incr)); 9642 ins_cost(VOLATILE_REF_COST); 9643 format %{ "get_and_addI_acq [$mem], $incr" %} 9644 ins_encode %{ 9645 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9646 %} 9647 ins_pipe(pipe_serial); 9648 %} 9649 9650 // Manifest a CmpU result in an integer register. 9651 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9652 instruct cmpU3_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg flags) 9653 %{ 9654 match(Set dst (CmpU3 src1 src2)); 9655 effect(KILL flags); 9656 9657 ins_cost(INSN_COST * 3); 9658 format %{ 9659 "cmpw $src1, $src2\n\t" 9660 "csetw $dst, ne\n\t" 9661 "cnegw $dst, lo\t# CmpU3(reg)" 9662 %} 9663 ins_encode %{ 9664 __ cmpw($src1$$Register, $src2$$Register); 9665 __ csetw($dst$$Register, Assembler::NE); 9666 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9667 %} 9668 9669 ins_pipe(pipe_class_default); 9670 %} 9671 9672 instruct cmpU3_reg_imm(iRegINoSp dst, iRegI src1, immIAddSub src2, rFlagsReg flags) 9673 %{ 9674 match(Set dst (CmpU3 src1 src2)); 9675 effect(KILL flags); 9676 9677 ins_cost(INSN_COST * 3); 9678 format %{ 9679 "subsw zr, $src1, $src2\n\t" 9680 "csetw $dst, ne\n\t" 9681 "cnegw $dst, lo\t# CmpU3(imm)" 9682 %} 9683 ins_encode %{ 9684 __ subsw(zr, $src1$$Register, (int32_t)$src2$$constant); 9685 __ csetw($dst$$Register, Assembler::NE); 9686 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9687 %} 9688 9689 ins_pipe(pipe_class_default); 9690 %} 9691 9692 // Manifest a CmpUL result in an integer register. 9693 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9694 instruct cmpUL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9695 %{ 9696 match(Set dst (CmpUL3 src1 src2)); 9697 effect(KILL flags); 9698 9699 ins_cost(INSN_COST * 3); 9700 format %{ 9701 "cmp $src1, $src2\n\t" 9702 "csetw $dst, ne\n\t" 9703 "cnegw $dst, lo\t# CmpUL3(reg)" 9704 %} 9705 ins_encode %{ 9706 __ cmp($src1$$Register, $src2$$Register); 9707 __ csetw($dst$$Register, Assembler::NE); 9708 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9709 %} 9710 9711 ins_pipe(pipe_class_default); 9712 %} 9713 9714 instruct cmpUL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9715 %{ 9716 match(Set dst (CmpUL3 src1 src2)); 9717 effect(KILL flags); 9718 9719 ins_cost(INSN_COST * 3); 9720 format %{ 9721 "subs zr, $src1, $src2\n\t" 9722 "csetw $dst, ne\n\t" 9723 "cnegw $dst, lo\t# CmpUL3(imm)" 9724 %} 9725 ins_encode %{ 9726 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant); 9727 __ csetw($dst$$Register, Assembler::NE); 9728 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9729 %} 9730 9731 ins_pipe(pipe_class_default); 9732 %} 9733 9734 // Manifest a CmpL result in an integer register. 9735 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9736 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9737 %{ 9738 match(Set dst (CmpL3 src1 src2)); 9739 effect(KILL flags); 9740 9741 ins_cost(INSN_COST * 3); 9742 format %{ 9743 "cmp $src1, $src2\n\t" 9744 "csetw $dst, ne\n\t" 9745 "cnegw $dst, lt\t# CmpL3(reg)" 9746 %} 9747 ins_encode %{ 9748 __ cmp($src1$$Register, $src2$$Register); 9749 __ csetw($dst$$Register, Assembler::NE); 9750 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9751 %} 9752 9753 ins_pipe(pipe_class_default); 9754 %} 9755 9756 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9757 %{ 9758 match(Set dst (CmpL3 src1 src2)); 9759 effect(KILL flags); 9760 9761 ins_cost(INSN_COST * 3); 9762 format %{ 9763 "subs zr, $src1, $src2\n\t" 9764 "csetw $dst, ne\n\t" 9765 "cnegw $dst, lt\t# CmpL3(imm)" 9766 %} 9767 ins_encode %{ 9768 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant); 9769 __ csetw($dst$$Register, Assembler::NE); 9770 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9771 %} 9772 9773 ins_pipe(pipe_class_default); 9774 %} 9775 9776 // ============================================================================ 9777 // Conditional Move Instructions 9778 9779 // n.b. we have identical rules for both a signed compare op (cmpOp) 9780 // and an unsigned compare op (cmpOpU). it would be nice if we could 9781 // define an op class which merged both inputs and use it to type the 9782 // argument to a single rule. unfortunatelyt his fails because the 9783 // opclass does not live up to the COND_INTER interface of its 9784 // component operands. When the generic code tries to negate the 9785 // operand it ends up running the generci Machoper::negate method 9786 // which throws a ShouldNotHappen. So, we have to provide two flavours 9787 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9788 9789 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9790 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9791 9792 ins_cost(INSN_COST * 2); 9793 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9794 9795 ins_encode %{ 9796 __ cselw(as_Register($dst$$reg), 9797 as_Register($src2$$reg), 9798 as_Register($src1$$reg), 9799 (Assembler::Condition)$cmp$$cmpcode); 9800 %} 9801 9802 ins_pipe(icond_reg_reg); 9803 %} 9804 9805 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9806 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9807 9808 ins_cost(INSN_COST * 2); 9809 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9810 9811 ins_encode %{ 9812 __ cselw(as_Register($dst$$reg), 9813 as_Register($src2$$reg), 9814 as_Register($src1$$reg), 9815 (Assembler::Condition)$cmp$$cmpcode); 9816 %} 9817 9818 ins_pipe(icond_reg_reg); 9819 %} 9820 9821 // special cases where one arg is zero 9822 9823 // n.b. this is selected in preference to the rule above because it 9824 // avoids loading constant 0 into a source register 9825 9826 // TODO 9827 // we ought only to be able to cull one of these variants as the ideal 9828 // transforms ought always to order the zero consistently (to left/right?) 9829 9830 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9831 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9832 9833 ins_cost(INSN_COST * 2); 9834 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9835 9836 ins_encode %{ 9837 __ cselw(as_Register($dst$$reg), 9838 as_Register($src$$reg), 9839 zr, 9840 (Assembler::Condition)$cmp$$cmpcode); 9841 %} 9842 9843 ins_pipe(icond_reg); 9844 %} 9845 9846 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9847 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9848 9849 ins_cost(INSN_COST * 2); 9850 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9851 9852 ins_encode %{ 9853 __ cselw(as_Register($dst$$reg), 9854 as_Register($src$$reg), 9855 zr, 9856 (Assembler::Condition)$cmp$$cmpcode); 9857 %} 9858 9859 ins_pipe(icond_reg); 9860 %} 9861 9862 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9863 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9864 9865 ins_cost(INSN_COST * 2); 9866 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9867 9868 ins_encode %{ 9869 __ cselw(as_Register($dst$$reg), 9870 zr, 9871 as_Register($src$$reg), 9872 (Assembler::Condition)$cmp$$cmpcode); 9873 %} 9874 9875 ins_pipe(icond_reg); 9876 %} 9877 9878 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9879 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9880 9881 ins_cost(INSN_COST * 2); 9882 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9883 9884 ins_encode %{ 9885 __ cselw(as_Register($dst$$reg), 9886 zr, 9887 as_Register($src$$reg), 9888 (Assembler::Condition)$cmp$$cmpcode); 9889 %} 9890 9891 ins_pipe(icond_reg); 9892 %} 9893 9894 // special case for creating a boolean 0 or 1 9895 9896 // n.b. this is selected in preference to the rule above because it 9897 // avoids loading constants 0 and 1 into a source register 9898 9899 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9900 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9901 9902 ins_cost(INSN_COST * 2); 9903 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9904 9905 ins_encode %{ 9906 // equivalently 9907 // cset(as_Register($dst$$reg), 9908 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9909 __ csincw(as_Register($dst$$reg), 9910 zr, 9911 zr, 9912 (Assembler::Condition)$cmp$$cmpcode); 9913 %} 9914 9915 ins_pipe(icond_none); 9916 %} 9917 9918 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9919 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9920 9921 ins_cost(INSN_COST * 2); 9922 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9923 9924 ins_encode %{ 9925 // equivalently 9926 // cset(as_Register($dst$$reg), 9927 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9928 __ csincw(as_Register($dst$$reg), 9929 zr, 9930 zr, 9931 (Assembler::Condition)$cmp$$cmpcode); 9932 %} 9933 9934 ins_pipe(icond_none); 9935 %} 9936 9937 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9938 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9939 9940 ins_cost(INSN_COST * 2); 9941 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9942 9943 ins_encode %{ 9944 __ csel(as_Register($dst$$reg), 9945 as_Register($src2$$reg), 9946 as_Register($src1$$reg), 9947 (Assembler::Condition)$cmp$$cmpcode); 9948 %} 9949 9950 ins_pipe(icond_reg_reg); 9951 %} 9952 9953 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9954 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9955 9956 ins_cost(INSN_COST * 2); 9957 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9958 9959 ins_encode %{ 9960 __ csel(as_Register($dst$$reg), 9961 as_Register($src2$$reg), 9962 as_Register($src1$$reg), 9963 (Assembler::Condition)$cmp$$cmpcode); 9964 %} 9965 9966 ins_pipe(icond_reg_reg); 9967 %} 9968 9969 // special cases where one arg is zero 9970 9971 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9972 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9973 9974 ins_cost(INSN_COST * 2); 9975 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9976 9977 ins_encode %{ 9978 __ csel(as_Register($dst$$reg), 9979 zr, 9980 as_Register($src$$reg), 9981 (Assembler::Condition)$cmp$$cmpcode); 9982 %} 9983 9984 ins_pipe(icond_reg); 9985 %} 9986 9987 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9988 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9989 9990 ins_cost(INSN_COST * 2); 9991 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9992 9993 ins_encode %{ 9994 __ csel(as_Register($dst$$reg), 9995 zr, 9996 as_Register($src$$reg), 9997 (Assembler::Condition)$cmp$$cmpcode); 9998 %} 9999 10000 ins_pipe(icond_reg); 10001 %} 10002 10003 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 10004 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 10005 10006 ins_cost(INSN_COST * 2); 10007 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 10008 10009 ins_encode %{ 10010 __ csel(as_Register($dst$$reg), 10011 as_Register($src$$reg), 10012 zr, 10013 (Assembler::Condition)$cmp$$cmpcode); 10014 %} 10015 10016 ins_pipe(icond_reg); 10017 %} 10018 10019 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 10020 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 10021 10022 ins_cost(INSN_COST * 2); 10023 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 10024 10025 ins_encode %{ 10026 __ csel(as_Register($dst$$reg), 10027 as_Register($src$$reg), 10028 zr, 10029 (Assembler::Condition)$cmp$$cmpcode); 10030 %} 10031 10032 ins_pipe(icond_reg); 10033 %} 10034 10035 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 10036 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 10037 10038 ins_cost(INSN_COST * 2); 10039 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 10040 10041 ins_encode %{ 10042 __ csel(as_Register($dst$$reg), 10043 as_Register($src2$$reg), 10044 as_Register($src1$$reg), 10045 (Assembler::Condition)$cmp$$cmpcode); 10046 %} 10047 10048 ins_pipe(icond_reg_reg); 10049 %} 10050 10051 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 10052 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 10053 10054 ins_cost(INSN_COST * 2); 10055 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 10056 10057 ins_encode %{ 10058 __ csel(as_Register($dst$$reg), 10059 as_Register($src2$$reg), 10060 as_Register($src1$$reg), 10061 (Assembler::Condition)$cmp$$cmpcode); 10062 %} 10063 10064 ins_pipe(icond_reg_reg); 10065 %} 10066 10067 // special cases where one arg is zero 10068 10069 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 10070 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 10071 10072 ins_cost(INSN_COST * 2); 10073 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 10074 10075 ins_encode %{ 10076 __ csel(as_Register($dst$$reg), 10077 zr, 10078 as_Register($src$$reg), 10079 (Assembler::Condition)$cmp$$cmpcode); 10080 %} 10081 10082 ins_pipe(icond_reg); 10083 %} 10084 10085 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 10086 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 10087 10088 ins_cost(INSN_COST * 2); 10089 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 10090 10091 ins_encode %{ 10092 __ csel(as_Register($dst$$reg), 10093 zr, 10094 as_Register($src$$reg), 10095 (Assembler::Condition)$cmp$$cmpcode); 10096 %} 10097 10098 ins_pipe(icond_reg); 10099 %} 10100 10101 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 10102 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 10103 10104 ins_cost(INSN_COST * 2); 10105 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 10106 10107 ins_encode %{ 10108 __ csel(as_Register($dst$$reg), 10109 as_Register($src$$reg), 10110 zr, 10111 (Assembler::Condition)$cmp$$cmpcode); 10112 %} 10113 10114 ins_pipe(icond_reg); 10115 %} 10116 10117 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 10118 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 10119 10120 ins_cost(INSN_COST * 2); 10121 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 10122 10123 ins_encode %{ 10124 __ csel(as_Register($dst$$reg), 10125 as_Register($src$$reg), 10126 zr, 10127 (Assembler::Condition)$cmp$$cmpcode); 10128 %} 10129 10130 ins_pipe(icond_reg); 10131 %} 10132 10133 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 10134 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 10135 10136 ins_cost(INSN_COST * 2); 10137 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 10138 10139 ins_encode %{ 10140 __ cselw(as_Register($dst$$reg), 10141 as_Register($src2$$reg), 10142 as_Register($src1$$reg), 10143 (Assembler::Condition)$cmp$$cmpcode); 10144 %} 10145 10146 ins_pipe(icond_reg_reg); 10147 %} 10148 10149 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 10150 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 10151 10152 ins_cost(INSN_COST * 2); 10153 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 10154 10155 ins_encode %{ 10156 __ cselw(as_Register($dst$$reg), 10157 as_Register($src2$$reg), 10158 as_Register($src1$$reg), 10159 (Assembler::Condition)$cmp$$cmpcode); 10160 %} 10161 10162 ins_pipe(icond_reg_reg); 10163 %} 10164 10165 // special cases where one arg is zero 10166 10167 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 10168 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 10169 10170 ins_cost(INSN_COST * 2); 10171 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 10172 10173 ins_encode %{ 10174 __ cselw(as_Register($dst$$reg), 10175 zr, 10176 as_Register($src$$reg), 10177 (Assembler::Condition)$cmp$$cmpcode); 10178 %} 10179 10180 ins_pipe(icond_reg); 10181 %} 10182 10183 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 10184 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 10185 10186 ins_cost(INSN_COST * 2); 10187 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 10188 10189 ins_encode %{ 10190 __ cselw(as_Register($dst$$reg), 10191 zr, 10192 as_Register($src$$reg), 10193 (Assembler::Condition)$cmp$$cmpcode); 10194 %} 10195 10196 ins_pipe(icond_reg); 10197 %} 10198 10199 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 10200 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 10201 10202 ins_cost(INSN_COST * 2); 10203 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 10204 10205 ins_encode %{ 10206 __ cselw(as_Register($dst$$reg), 10207 as_Register($src$$reg), 10208 zr, 10209 (Assembler::Condition)$cmp$$cmpcode); 10210 %} 10211 10212 ins_pipe(icond_reg); 10213 %} 10214 10215 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 10216 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 10217 10218 ins_cost(INSN_COST * 2); 10219 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 10220 10221 ins_encode %{ 10222 __ cselw(as_Register($dst$$reg), 10223 as_Register($src$$reg), 10224 zr, 10225 (Assembler::Condition)$cmp$$cmpcode); 10226 %} 10227 10228 ins_pipe(icond_reg); 10229 %} 10230 10231 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 10232 %{ 10233 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10234 10235 ins_cost(INSN_COST * 3); 10236 10237 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10238 ins_encode %{ 10239 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10240 __ fcsels(as_FloatRegister($dst$$reg), 10241 as_FloatRegister($src2$$reg), 10242 as_FloatRegister($src1$$reg), 10243 cond); 10244 %} 10245 10246 ins_pipe(fp_cond_reg_reg_s); 10247 %} 10248 10249 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 10250 %{ 10251 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10252 10253 ins_cost(INSN_COST * 3); 10254 10255 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10256 ins_encode %{ 10257 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10258 __ fcsels(as_FloatRegister($dst$$reg), 10259 as_FloatRegister($src2$$reg), 10260 as_FloatRegister($src1$$reg), 10261 cond); 10262 %} 10263 10264 ins_pipe(fp_cond_reg_reg_s); 10265 %} 10266 10267 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 10268 %{ 10269 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10270 10271 ins_cost(INSN_COST * 3); 10272 10273 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10274 ins_encode %{ 10275 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10276 __ fcseld(as_FloatRegister($dst$$reg), 10277 as_FloatRegister($src2$$reg), 10278 as_FloatRegister($src1$$reg), 10279 cond); 10280 %} 10281 10282 ins_pipe(fp_cond_reg_reg_d); 10283 %} 10284 10285 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 10286 %{ 10287 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10288 10289 ins_cost(INSN_COST * 3); 10290 10291 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10292 ins_encode %{ 10293 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10294 __ fcseld(as_FloatRegister($dst$$reg), 10295 as_FloatRegister($src2$$reg), 10296 as_FloatRegister($src1$$reg), 10297 cond); 10298 %} 10299 10300 ins_pipe(fp_cond_reg_reg_d); 10301 %} 10302 10303 // ============================================================================ 10304 // Arithmetic Instructions 10305 // 10306 10307 // Integer Addition 10308 10309 // TODO 10310 // these currently employ operations which do not set CR and hence are 10311 // not flagged as killing CR but we would like to isolate the cases 10312 // where we want to set flags from those where we don't. need to work 10313 // out how to do that. 10314 10315 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10316 match(Set dst (AddI src1 src2)); 10317 10318 ins_cost(INSN_COST); 10319 format %{ "addw $dst, $src1, $src2" %} 10320 10321 ins_encode %{ 10322 __ addw(as_Register($dst$$reg), 10323 as_Register($src1$$reg), 10324 as_Register($src2$$reg)); 10325 %} 10326 10327 ins_pipe(ialu_reg_reg); 10328 %} 10329 10330 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10331 match(Set dst (AddI src1 src2)); 10332 10333 ins_cost(INSN_COST); 10334 format %{ "addw $dst, $src1, $src2" %} 10335 10336 // use opcode to indicate that this is an add not a sub 10337 opcode(0x0); 10338 10339 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10340 10341 ins_pipe(ialu_reg_imm); 10342 %} 10343 10344 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 10345 match(Set dst (AddI (ConvL2I src1) src2)); 10346 10347 ins_cost(INSN_COST); 10348 format %{ "addw $dst, $src1, $src2" %} 10349 10350 // use opcode to indicate that this is an add not a sub 10351 opcode(0x0); 10352 10353 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10354 10355 ins_pipe(ialu_reg_imm); 10356 %} 10357 10358 // Pointer Addition 10359 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 10360 match(Set dst (AddP src1 src2)); 10361 10362 ins_cost(INSN_COST); 10363 format %{ "add $dst, $src1, $src2\t# ptr" %} 10364 10365 ins_encode %{ 10366 __ add(as_Register($dst$$reg), 10367 as_Register($src1$$reg), 10368 as_Register($src2$$reg)); 10369 %} 10370 10371 ins_pipe(ialu_reg_reg); 10372 %} 10373 10374 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 10375 match(Set dst (AddP src1 (ConvI2L src2))); 10376 10377 ins_cost(1.9 * INSN_COST); 10378 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 10379 10380 ins_encode %{ 10381 __ add(as_Register($dst$$reg), 10382 as_Register($src1$$reg), 10383 as_Register($src2$$reg), ext::sxtw); 10384 %} 10385 10386 ins_pipe(ialu_reg_reg); 10387 %} 10388 10389 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 10390 match(Set dst (AddP src1 (LShiftL src2 scale))); 10391 10392 ins_cost(1.9 * INSN_COST); 10393 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 10394 10395 ins_encode %{ 10396 __ lea(as_Register($dst$$reg), 10397 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10398 Address::lsl($scale$$constant))); 10399 %} 10400 10401 ins_pipe(ialu_reg_reg_shift); 10402 %} 10403 10404 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 10405 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 10406 10407 ins_cost(1.9 * INSN_COST); 10408 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 10409 10410 ins_encode %{ 10411 __ lea(as_Register($dst$$reg), 10412 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10413 Address::sxtw($scale$$constant))); 10414 %} 10415 10416 ins_pipe(ialu_reg_reg_shift); 10417 %} 10418 10419 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 10420 match(Set dst (LShiftL (ConvI2L src) scale)); 10421 10422 ins_cost(INSN_COST); 10423 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 10424 10425 ins_encode %{ 10426 __ sbfiz(as_Register($dst$$reg), 10427 as_Register($src$$reg), 10428 $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63))); 10429 %} 10430 10431 ins_pipe(ialu_reg_shift); 10432 %} 10433 10434 // Pointer Immediate Addition 10435 // n.b. this needs to be more expensive than using an indirect memory 10436 // operand 10437 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 10438 match(Set dst (AddP src1 src2)); 10439 10440 ins_cost(INSN_COST); 10441 format %{ "add $dst, $src1, $src2\t# ptr" %} 10442 10443 // use opcode to indicate that this is an add not a sub 10444 opcode(0x0); 10445 10446 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10447 10448 ins_pipe(ialu_reg_imm); 10449 %} 10450 10451 // Long Addition 10452 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10453 10454 match(Set dst (AddL src1 src2)); 10455 10456 ins_cost(INSN_COST); 10457 format %{ "add $dst, $src1, $src2" %} 10458 10459 ins_encode %{ 10460 __ add(as_Register($dst$$reg), 10461 as_Register($src1$$reg), 10462 as_Register($src2$$reg)); 10463 %} 10464 10465 ins_pipe(ialu_reg_reg); 10466 %} 10467 10468 // No constant pool entries requiredLong Immediate Addition. 10469 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10470 match(Set dst (AddL src1 src2)); 10471 10472 ins_cost(INSN_COST); 10473 format %{ "add $dst, $src1, $src2" %} 10474 10475 // use opcode to indicate that this is an add not a sub 10476 opcode(0x0); 10477 10478 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10479 10480 ins_pipe(ialu_reg_imm); 10481 %} 10482 10483 // Integer Subtraction 10484 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10485 match(Set dst (SubI src1 src2)); 10486 10487 ins_cost(INSN_COST); 10488 format %{ "subw $dst, $src1, $src2" %} 10489 10490 ins_encode %{ 10491 __ subw(as_Register($dst$$reg), 10492 as_Register($src1$$reg), 10493 as_Register($src2$$reg)); 10494 %} 10495 10496 ins_pipe(ialu_reg_reg); 10497 %} 10498 10499 // Immediate Subtraction 10500 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10501 match(Set dst (SubI src1 src2)); 10502 10503 ins_cost(INSN_COST); 10504 format %{ "subw $dst, $src1, $src2" %} 10505 10506 // use opcode to indicate that this is a sub not an add 10507 opcode(0x1); 10508 10509 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10510 10511 ins_pipe(ialu_reg_imm); 10512 %} 10513 10514 // Long Subtraction 10515 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10516 10517 match(Set dst (SubL src1 src2)); 10518 10519 ins_cost(INSN_COST); 10520 format %{ "sub $dst, $src1, $src2" %} 10521 10522 ins_encode %{ 10523 __ sub(as_Register($dst$$reg), 10524 as_Register($src1$$reg), 10525 as_Register($src2$$reg)); 10526 %} 10527 10528 ins_pipe(ialu_reg_reg); 10529 %} 10530 10531 // No constant pool entries requiredLong Immediate Subtraction. 10532 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10533 match(Set dst (SubL src1 src2)); 10534 10535 ins_cost(INSN_COST); 10536 format %{ "sub$dst, $src1, $src2" %} 10537 10538 // use opcode to indicate that this is a sub not an add 10539 opcode(0x1); 10540 10541 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10542 10543 ins_pipe(ialu_reg_imm); 10544 %} 10545 10546 // Integer Negation (special case for sub) 10547 10548 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10549 match(Set dst (SubI zero src)); 10550 10551 ins_cost(INSN_COST); 10552 format %{ "negw $dst, $src\t# int" %} 10553 10554 ins_encode %{ 10555 __ negw(as_Register($dst$$reg), 10556 as_Register($src$$reg)); 10557 %} 10558 10559 ins_pipe(ialu_reg); 10560 %} 10561 10562 // Long Negation 10563 10564 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10565 match(Set dst (SubL zero src)); 10566 10567 ins_cost(INSN_COST); 10568 format %{ "neg $dst, $src\t# long" %} 10569 10570 ins_encode %{ 10571 __ neg(as_Register($dst$$reg), 10572 as_Register($src$$reg)); 10573 %} 10574 10575 ins_pipe(ialu_reg); 10576 %} 10577 10578 // Integer Multiply 10579 10580 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10581 match(Set dst (MulI src1 src2)); 10582 10583 ins_cost(INSN_COST * 3); 10584 format %{ "mulw $dst, $src1, $src2" %} 10585 10586 ins_encode %{ 10587 __ mulw(as_Register($dst$$reg), 10588 as_Register($src1$$reg), 10589 as_Register($src2$$reg)); 10590 %} 10591 10592 ins_pipe(imul_reg_reg); 10593 %} 10594 10595 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10596 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10597 10598 ins_cost(INSN_COST * 3); 10599 format %{ "smull $dst, $src1, $src2" %} 10600 10601 ins_encode %{ 10602 __ smull(as_Register($dst$$reg), 10603 as_Register($src1$$reg), 10604 as_Register($src2$$reg)); 10605 %} 10606 10607 ins_pipe(imul_reg_reg); 10608 %} 10609 10610 // Long Multiply 10611 10612 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10613 match(Set dst (MulL src1 src2)); 10614 10615 ins_cost(INSN_COST * 5); 10616 format %{ "mul $dst, $src1, $src2" %} 10617 10618 ins_encode %{ 10619 __ mul(as_Register($dst$$reg), 10620 as_Register($src1$$reg), 10621 as_Register($src2$$reg)); 10622 %} 10623 10624 ins_pipe(lmul_reg_reg); 10625 %} 10626 10627 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10628 %{ 10629 match(Set dst (MulHiL src1 src2)); 10630 10631 ins_cost(INSN_COST * 7); 10632 format %{ "smulh $dst, $src1, $src2\t# mulhi" %} 10633 10634 ins_encode %{ 10635 __ smulh(as_Register($dst$$reg), 10636 as_Register($src1$$reg), 10637 as_Register($src2$$reg)); 10638 %} 10639 10640 ins_pipe(lmul_reg_reg); 10641 %} 10642 10643 instruct umulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10644 %{ 10645 match(Set dst (UMulHiL src1 src2)); 10646 10647 ins_cost(INSN_COST * 7); 10648 format %{ "umulh $dst, $src1, $src2\t# umulhi" %} 10649 10650 ins_encode %{ 10651 __ umulh(as_Register($dst$$reg), 10652 as_Register($src1$$reg), 10653 as_Register($src2$$reg)); 10654 %} 10655 10656 ins_pipe(lmul_reg_reg); 10657 %} 10658 10659 // Combined Integer Multiply & Add/Sub 10660 10661 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10662 match(Set dst (AddI src3 (MulI src1 src2))); 10663 10664 ins_cost(INSN_COST * 3); 10665 format %{ "madd $dst, $src1, $src2, $src3" %} 10666 10667 ins_encode %{ 10668 __ maddw(as_Register($dst$$reg), 10669 as_Register($src1$$reg), 10670 as_Register($src2$$reg), 10671 as_Register($src3$$reg)); 10672 %} 10673 10674 ins_pipe(imac_reg_reg); 10675 %} 10676 10677 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10678 match(Set dst (SubI src3 (MulI src1 src2))); 10679 10680 ins_cost(INSN_COST * 3); 10681 format %{ "msub $dst, $src1, $src2, $src3" %} 10682 10683 ins_encode %{ 10684 __ msubw(as_Register($dst$$reg), 10685 as_Register($src1$$reg), 10686 as_Register($src2$$reg), 10687 as_Register($src3$$reg)); 10688 %} 10689 10690 ins_pipe(imac_reg_reg); 10691 %} 10692 10693 // Combined Integer Multiply & Neg 10694 10695 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10696 match(Set dst (MulI (SubI zero src1) src2)); 10697 10698 ins_cost(INSN_COST * 3); 10699 format %{ "mneg $dst, $src1, $src2" %} 10700 10701 ins_encode %{ 10702 __ mnegw(as_Register($dst$$reg), 10703 as_Register($src1$$reg), 10704 as_Register($src2$$reg)); 10705 %} 10706 10707 ins_pipe(imac_reg_reg); 10708 %} 10709 10710 // Combined Long Multiply & Add/Sub 10711 10712 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10713 match(Set dst (AddL src3 (MulL src1 src2))); 10714 10715 ins_cost(INSN_COST * 5); 10716 format %{ "madd $dst, $src1, $src2, $src3" %} 10717 10718 ins_encode %{ 10719 __ madd(as_Register($dst$$reg), 10720 as_Register($src1$$reg), 10721 as_Register($src2$$reg), 10722 as_Register($src3$$reg)); 10723 %} 10724 10725 ins_pipe(lmac_reg_reg); 10726 %} 10727 10728 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10729 match(Set dst (SubL src3 (MulL src1 src2))); 10730 10731 ins_cost(INSN_COST * 5); 10732 format %{ "msub $dst, $src1, $src2, $src3" %} 10733 10734 ins_encode %{ 10735 __ msub(as_Register($dst$$reg), 10736 as_Register($src1$$reg), 10737 as_Register($src2$$reg), 10738 as_Register($src3$$reg)); 10739 %} 10740 10741 ins_pipe(lmac_reg_reg); 10742 %} 10743 10744 // Combined Long Multiply & Neg 10745 10746 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10747 match(Set dst (MulL (SubL zero src1) src2)); 10748 10749 ins_cost(INSN_COST * 5); 10750 format %{ "mneg $dst, $src1, $src2" %} 10751 10752 ins_encode %{ 10753 __ mneg(as_Register($dst$$reg), 10754 as_Register($src1$$reg), 10755 as_Register($src2$$reg)); 10756 %} 10757 10758 ins_pipe(lmac_reg_reg); 10759 %} 10760 10761 // Combine Integer Signed Multiply & Add/Sub/Neg Long 10762 10763 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10764 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10765 10766 ins_cost(INSN_COST * 3); 10767 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10768 10769 ins_encode %{ 10770 __ smaddl(as_Register($dst$$reg), 10771 as_Register($src1$$reg), 10772 as_Register($src2$$reg), 10773 as_Register($src3$$reg)); 10774 %} 10775 10776 ins_pipe(imac_reg_reg); 10777 %} 10778 10779 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10780 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10781 10782 ins_cost(INSN_COST * 3); 10783 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10784 10785 ins_encode %{ 10786 __ smsubl(as_Register($dst$$reg), 10787 as_Register($src1$$reg), 10788 as_Register($src2$$reg), 10789 as_Register($src3$$reg)); 10790 %} 10791 10792 ins_pipe(imac_reg_reg); 10793 %} 10794 10795 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10796 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10797 10798 ins_cost(INSN_COST * 3); 10799 format %{ "smnegl $dst, $src1, $src2" %} 10800 10801 ins_encode %{ 10802 __ smnegl(as_Register($dst$$reg), 10803 as_Register($src1$$reg), 10804 as_Register($src2$$reg)); 10805 %} 10806 10807 ins_pipe(imac_reg_reg); 10808 %} 10809 10810 // Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4) 10811 10812 instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{ 10813 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4))); 10814 10815 ins_cost(INSN_COST * 5); 10816 format %{ "mulw rscratch1, $src1, $src2\n\t" 10817 "maddw $dst, $src3, $src4, rscratch1" %} 10818 10819 ins_encode %{ 10820 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg)); 10821 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %} 10822 10823 ins_pipe(imac_reg_reg); 10824 %} 10825 10826 // Integer Divide 10827 10828 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10829 match(Set dst (DivI src1 src2)); 10830 10831 ins_cost(INSN_COST * 19); 10832 format %{ "sdivw $dst, $src1, $src2" %} 10833 10834 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10835 ins_pipe(idiv_reg_reg); 10836 %} 10837 10838 // Long Divide 10839 10840 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10841 match(Set dst (DivL src1 src2)); 10842 10843 ins_cost(INSN_COST * 35); 10844 format %{ "sdiv $dst, $src1, $src2" %} 10845 10846 ins_encode(aarch64_enc_div(dst, src1, src2)); 10847 ins_pipe(ldiv_reg_reg); 10848 %} 10849 10850 // Integer Remainder 10851 10852 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10853 match(Set dst (ModI src1 src2)); 10854 10855 ins_cost(INSN_COST * 22); 10856 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10857 "msubw $dst, rscratch1, $src2, $src1" %} 10858 10859 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10860 ins_pipe(idiv_reg_reg); 10861 %} 10862 10863 // Long Remainder 10864 10865 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10866 match(Set dst (ModL src1 src2)); 10867 10868 ins_cost(INSN_COST * 38); 10869 format %{ "sdiv rscratch1, $src1, $src2\n" 10870 "msub $dst, rscratch1, $src2, $src1" %} 10871 10872 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10873 ins_pipe(ldiv_reg_reg); 10874 %} 10875 10876 // Unsigned Integer Divide 10877 10878 instruct UdivI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10879 match(Set dst (UDivI src1 src2)); 10880 10881 ins_cost(INSN_COST * 19); 10882 format %{ "udivw $dst, $src1, $src2" %} 10883 10884 ins_encode %{ 10885 __ udivw($dst$$Register, $src1$$Register, $src2$$Register); 10886 %} 10887 10888 ins_pipe(idiv_reg_reg); 10889 %} 10890 10891 // Unsigned Long Divide 10892 10893 instruct UdivL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10894 match(Set dst (UDivL src1 src2)); 10895 10896 ins_cost(INSN_COST * 35); 10897 format %{ "udiv $dst, $src1, $src2" %} 10898 10899 ins_encode %{ 10900 __ udiv($dst$$Register, $src1$$Register, $src2$$Register); 10901 %} 10902 10903 ins_pipe(ldiv_reg_reg); 10904 %} 10905 10906 // Unsigned Integer Remainder 10907 10908 instruct UmodI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10909 match(Set dst (UModI src1 src2)); 10910 10911 ins_cost(INSN_COST * 22); 10912 format %{ "udivw rscratch1, $src1, $src2\n\t" 10913 "msubw $dst, rscratch1, $src2, $src1" %} 10914 10915 ins_encode %{ 10916 __ udivw(rscratch1, $src1$$Register, $src2$$Register); 10917 __ msubw($dst$$Register, rscratch1, $src2$$Register, $src1$$Register); 10918 %} 10919 10920 ins_pipe(idiv_reg_reg); 10921 %} 10922 10923 // Unsigned Long Remainder 10924 10925 instruct UModL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10926 match(Set dst (UModL src1 src2)); 10927 10928 ins_cost(INSN_COST * 38); 10929 format %{ "udiv rscratch1, $src1, $src2\n" 10930 "msub $dst, rscratch1, $src2, $src1" %} 10931 10932 ins_encode %{ 10933 __ udiv(rscratch1, $src1$$Register, $src2$$Register); 10934 __ msub($dst$$Register, rscratch1, $src2$$Register, $src1$$Register); 10935 %} 10936 10937 ins_pipe(ldiv_reg_reg); 10938 %} 10939 10940 // Integer Shifts 10941 10942 // Shift Left Register 10943 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10944 match(Set dst (LShiftI src1 src2)); 10945 10946 ins_cost(INSN_COST * 2); 10947 format %{ "lslvw $dst, $src1, $src2" %} 10948 10949 ins_encode %{ 10950 __ lslvw(as_Register($dst$$reg), 10951 as_Register($src1$$reg), 10952 as_Register($src2$$reg)); 10953 %} 10954 10955 ins_pipe(ialu_reg_reg_vshift); 10956 %} 10957 10958 // Shift Left Immediate 10959 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10960 match(Set dst (LShiftI src1 src2)); 10961 10962 ins_cost(INSN_COST); 10963 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10964 10965 ins_encode %{ 10966 __ lslw(as_Register($dst$$reg), 10967 as_Register($src1$$reg), 10968 $src2$$constant & 0x1f); 10969 %} 10970 10971 ins_pipe(ialu_reg_shift); 10972 %} 10973 10974 // Shift Right Logical Register 10975 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10976 match(Set dst (URShiftI src1 src2)); 10977 10978 ins_cost(INSN_COST * 2); 10979 format %{ "lsrvw $dst, $src1, $src2" %} 10980 10981 ins_encode %{ 10982 __ lsrvw(as_Register($dst$$reg), 10983 as_Register($src1$$reg), 10984 as_Register($src2$$reg)); 10985 %} 10986 10987 ins_pipe(ialu_reg_reg_vshift); 10988 %} 10989 10990 // Shift Right Logical Immediate 10991 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10992 match(Set dst (URShiftI src1 src2)); 10993 10994 ins_cost(INSN_COST); 10995 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10996 10997 ins_encode %{ 10998 __ lsrw(as_Register($dst$$reg), 10999 as_Register($src1$$reg), 11000 $src2$$constant & 0x1f); 11001 %} 11002 11003 ins_pipe(ialu_reg_shift); 11004 %} 11005 11006 // Shift Right Arithmetic Register 11007 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 11008 match(Set dst (RShiftI src1 src2)); 11009 11010 ins_cost(INSN_COST * 2); 11011 format %{ "asrvw $dst, $src1, $src2" %} 11012 11013 ins_encode %{ 11014 __ asrvw(as_Register($dst$$reg), 11015 as_Register($src1$$reg), 11016 as_Register($src2$$reg)); 11017 %} 11018 11019 ins_pipe(ialu_reg_reg_vshift); 11020 %} 11021 11022 // Shift Right Arithmetic Immediate 11023 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 11024 match(Set dst (RShiftI src1 src2)); 11025 11026 ins_cost(INSN_COST); 11027 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 11028 11029 ins_encode %{ 11030 __ asrw(as_Register($dst$$reg), 11031 as_Register($src1$$reg), 11032 $src2$$constant & 0x1f); 11033 %} 11034 11035 ins_pipe(ialu_reg_shift); 11036 %} 11037 11038 // Combined Int Mask and Right Shift (using UBFM) 11039 // TODO 11040 11041 // Long Shifts 11042 11043 // Shift Left Register 11044 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 11045 match(Set dst (LShiftL src1 src2)); 11046 11047 ins_cost(INSN_COST * 2); 11048 format %{ "lslv $dst, $src1, $src2" %} 11049 11050 ins_encode %{ 11051 __ lslv(as_Register($dst$$reg), 11052 as_Register($src1$$reg), 11053 as_Register($src2$$reg)); 11054 %} 11055 11056 ins_pipe(ialu_reg_reg_vshift); 11057 %} 11058 11059 // Shift Left Immediate 11060 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11061 match(Set dst (LShiftL src1 src2)); 11062 11063 ins_cost(INSN_COST); 11064 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 11065 11066 ins_encode %{ 11067 __ lsl(as_Register($dst$$reg), 11068 as_Register($src1$$reg), 11069 $src2$$constant & 0x3f); 11070 %} 11071 11072 ins_pipe(ialu_reg_shift); 11073 %} 11074 11075 // Shift Right Logical Register 11076 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 11077 match(Set dst (URShiftL src1 src2)); 11078 11079 ins_cost(INSN_COST * 2); 11080 format %{ "lsrv $dst, $src1, $src2" %} 11081 11082 ins_encode %{ 11083 __ lsrv(as_Register($dst$$reg), 11084 as_Register($src1$$reg), 11085 as_Register($src2$$reg)); 11086 %} 11087 11088 ins_pipe(ialu_reg_reg_vshift); 11089 %} 11090 11091 // Shift Right Logical Immediate 11092 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11093 match(Set dst (URShiftL src1 src2)); 11094 11095 ins_cost(INSN_COST); 11096 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 11097 11098 ins_encode %{ 11099 __ lsr(as_Register($dst$$reg), 11100 as_Register($src1$$reg), 11101 $src2$$constant & 0x3f); 11102 %} 11103 11104 ins_pipe(ialu_reg_shift); 11105 %} 11106 11107 // A special-case pattern for card table stores. 11108 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 11109 match(Set dst (URShiftL (CastP2X src1) src2)); 11110 11111 ins_cost(INSN_COST); 11112 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 11113 11114 ins_encode %{ 11115 __ lsr(as_Register($dst$$reg), 11116 as_Register($src1$$reg), 11117 $src2$$constant & 0x3f); 11118 %} 11119 11120 ins_pipe(ialu_reg_shift); 11121 %} 11122 11123 // Shift Right Arithmetic Register 11124 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 11125 match(Set dst (RShiftL src1 src2)); 11126 11127 ins_cost(INSN_COST * 2); 11128 format %{ "asrv $dst, $src1, $src2" %} 11129 11130 ins_encode %{ 11131 __ asrv(as_Register($dst$$reg), 11132 as_Register($src1$$reg), 11133 as_Register($src2$$reg)); 11134 %} 11135 11136 ins_pipe(ialu_reg_reg_vshift); 11137 %} 11138 11139 // Shift Right Arithmetic Immediate 11140 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11141 match(Set dst (RShiftL src1 src2)); 11142 11143 ins_cost(INSN_COST); 11144 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 11145 11146 ins_encode %{ 11147 __ asr(as_Register($dst$$reg), 11148 as_Register($src1$$reg), 11149 $src2$$constant & 0x3f); 11150 %} 11151 11152 ins_pipe(ialu_reg_shift); 11153 %} 11154 11155 // BEGIN This section of the file is automatically generated. Do not edit -------------- 11156 // This section is generated from aarch64_ad.m4 11157 11158 // This pattern is automatically generated from aarch64_ad.m4 11159 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11160 instruct regL_not_reg(iRegLNoSp dst, 11161 iRegL src1, immL_M1 m1, 11162 rFlagsReg cr) %{ 11163 match(Set dst (XorL src1 m1)); 11164 ins_cost(INSN_COST); 11165 format %{ "eon $dst, $src1, zr" %} 11166 11167 ins_encode %{ 11168 __ eon(as_Register($dst$$reg), 11169 as_Register($src1$$reg), 11170 zr, 11171 Assembler::LSL, 0); 11172 %} 11173 11174 ins_pipe(ialu_reg); 11175 %} 11176 11177 // This pattern is automatically generated from aarch64_ad.m4 11178 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11179 instruct regI_not_reg(iRegINoSp dst, 11180 iRegIorL2I src1, immI_M1 m1, 11181 rFlagsReg cr) %{ 11182 match(Set dst (XorI src1 m1)); 11183 ins_cost(INSN_COST); 11184 format %{ "eonw $dst, $src1, zr" %} 11185 11186 ins_encode %{ 11187 __ eonw(as_Register($dst$$reg), 11188 as_Register($src1$$reg), 11189 zr, 11190 Assembler::LSL, 0); 11191 %} 11192 11193 ins_pipe(ialu_reg); 11194 %} 11195 11196 // This pattern is automatically generated from aarch64_ad.m4 11197 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11198 instruct NegI_reg_URShift_reg(iRegINoSp dst, 11199 immI0 zero, iRegIorL2I src1, immI src2) %{ 11200 match(Set dst (SubI zero (URShiftI src1 src2))); 11201 11202 ins_cost(1.9 * INSN_COST); 11203 format %{ "negw $dst, $src1, LSR $src2" %} 11204 11205 ins_encode %{ 11206 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 11207 Assembler::LSR, $src2$$constant & 0x1f); 11208 %} 11209 11210 ins_pipe(ialu_reg_shift); 11211 %} 11212 11213 // This pattern is automatically generated from aarch64_ad.m4 11214 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11215 instruct NegI_reg_RShift_reg(iRegINoSp dst, 11216 immI0 zero, iRegIorL2I src1, immI src2) %{ 11217 match(Set dst (SubI zero (RShiftI src1 src2))); 11218 11219 ins_cost(1.9 * INSN_COST); 11220 format %{ "negw $dst, $src1, ASR $src2" %} 11221 11222 ins_encode %{ 11223 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 11224 Assembler::ASR, $src2$$constant & 0x1f); 11225 %} 11226 11227 ins_pipe(ialu_reg_shift); 11228 %} 11229 11230 // This pattern is automatically generated from aarch64_ad.m4 11231 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11232 instruct NegI_reg_LShift_reg(iRegINoSp dst, 11233 immI0 zero, iRegIorL2I src1, immI src2) %{ 11234 match(Set dst (SubI zero (LShiftI src1 src2))); 11235 11236 ins_cost(1.9 * INSN_COST); 11237 format %{ "negw $dst, $src1, LSL $src2" %} 11238 11239 ins_encode %{ 11240 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 11241 Assembler::LSL, $src2$$constant & 0x1f); 11242 %} 11243 11244 ins_pipe(ialu_reg_shift); 11245 %} 11246 11247 // This pattern is automatically generated from aarch64_ad.m4 11248 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11249 instruct NegL_reg_URShift_reg(iRegLNoSp dst, 11250 immL0 zero, iRegL src1, immI src2) %{ 11251 match(Set dst (SubL zero (URShiftL src1 src2))); 11252 11253 ins_cost(1.9 * INSN_COST); 11254 format %{ "neg $dst, $src1, LSR $src2" %} 11255 11256 ins_encode %{ 11257 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 11258 Assembler::LSR, $src2$$constant & 0x3f); 11259 %} 11260 11261 ins_pipe(ialu_reg_shift); 11262 %} 11263 11264 // This pattern is automatically generated from aarch64_ad.m4 11265 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11266 instruct NegL_reg_RShift_reg(iRegLNoSp dst, 11267 immL0 zero, iRegL src1, immI src2) %{ 11268 match(Set dst (SubL zero (RShiftL src1 src2))); 11269 11270 ins_cost(1.9 * INSN_COST); 11271 format %{ "neg $dst, $src1, ASR $src2" %} 11272 11273 ins_encode %{ 11274 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 11275 Assembler::ASR, $src2$$constant & 0x3f); 11276 %} 11277 11278 ins_pipe(ialu_reg_shift); 11279 %} 11280 11281 // This pattern is automatically generated from aarch64_ad.m4 11282 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11283 instruct NegL_reg_LShift_reg(iRegLNoSp dst, 11284 immL0 zero, iRegL src1, immI src2) %{ 11285 match(Set dst (SubL zero (LShiftL src1 src2))); 11286 11287 ins_cost(1.9 * INSN_COST); 11288 format %{ "neg $dst, $src1, LSL $src2" %} 11289 11290 ins_encode %{ 11291 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 11292 Assembler::LSL, $src2$$constant & 0x3f); 11293 %} 11294 11295 ins_pipe(ialu_reg_shift); 11296 %} 11297 11298 // This pattern is automatically generated from aarch64_ad.m4 11299 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11300 instruct AndI_reg_not_reg(iRegINoSp dst, 11301 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11302 match(Set dst (AndI src1 (XorI src2 m1))); 11303 ins_cost(INSN_COST); 11304 format %{ "bicw $dst, $src1, $src2" %} 11305 11306 ins_encode %{ 11307 __ bicw(as_Register($dst$$reg), 11308 as_Register($src1$$reg), 11309 as_Register($src2$$reg), 11310 Assembler::LSL, 0); 11311 %} 11312 11313 ins_pipe(ialu_reg_reg); 11314 %} 11315 11316 // This pattern is automatically generated from aarch64_ad.m4 11317 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11318 instruct AndL_reg_not_reg(iRegLNoSp dst, 11319 iRegL src1, iRegL src2, immL_M1 m1) %{ 11320 match(Set dst (AndL src1 (XorL src2 m1))); 11321 ins_cost(INSN_COST); 11322 format %{ "bic $dst, $src1, $src2" %} 11323 11324 ins_encode %{ 11325 __ bic(as_Register($dst$$reg), 11326 as_Register($src1$$reg), 11327 as_Register($src2$$reg), 11328 Assembler::LSL, 0); 11329 %} 11330 11331 ins_pipe(ialu_reg_reg); 11332 %} 11333 11334 // This pattern is automatically generated from aarch64_ad.m4 11335 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11336 instruct OrI_reg_not_reg(iRegINoSp dst, 11337 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11338 match(Set dst (OrI src1 (XorI src2 m1))); 11339 ins_cost(INSN_COST); 11340 format %{ "ornw $dst, $src1, $src2" %} 11341 11342 ins_encode %{ 11343 __ ornw(as_Register($dst$$reg), 11344 as_Register($src1$$reg), 11345 as_Register($src2$$reg), 11346 Assembler::LSL, 0); 11347 %} 11348 11349 ins_pipe(ialu_reg_reg); 11350 %} 11351 11352 // This pattern is automatically generated from aarch64_ad.m4 11353 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11354 instruct OrL_reg_not_reg(iRegLNoSp dst, 11355 iRegL src1, iRegL src2, immL_M1 m1) %{ 11356 match(Set dst (OrL src1 (XorL src2 m1))); 11357 ins_cost(INSN_COST); 11358 format %{ "orn $dst, $src1, $src2" %} 11359 11360 ins_encode %{ 11361 __ orn(as_Register($dst$$reg), 11362 as_Register($src1$$reg), 11363 as_Register($src2$$reg), 11364 Assembler::LSL, 0); 11365 %} 11366 11367 ins_pipe(ialu_reg_reg); 11368 %} 11369 11370 // This pattern is automatically generated from aarch64_ad.m4 11371 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11372 instruct XorI_reg_not_reg(iRegINoSp dst, 11373 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11374 match(Set dst (XorI m1 (XorI src2 src1))); 11375 ins_cost(INSN_COST); 11376 format %{ "eonw $dst, $src1, $src2" %} 11377 11378 ins_encode %{ 11379 __ eonw(as_Register($dst$$reg), 11380 as_Register($src1$$reg), 11381 as_Register($src2$$reg), 11382 Assembler::LSL, 0); 11383 %} 11384 11385 ins_pipe(ialu_reg_reg); 11386 %} 11387 11388 // This pattern is automatically generated from aarch64_ad.m4 11389 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11390 instruct XorL_reg_not_reg(iRegLNoSp dst, 11391 iRegL src1, iRegL src2, immL_M1 m1) %{ 11392 match(Set dst (XorL m1 (XorL src2 src1))); 11393 ins_cost(INSN_COST); 11394 format %{ "eon $dst, $src1, $src2" %} 11395 11396 ins_encode %{ 11397 __ eon(as_Register($dst$$reg), 11398 as_Register($src1$$reg), 11399 as_Register($src2$$reg), 11400 Assembler::LSL, 0); 11401 %} 11402 11403 ins_pipe(ialu_reg_reg); 11404 %} 11405 11406 // This pattern is automatically generated from aarch64_ad.m4 11407 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11408 // val & (-1 ^ (val >>> shift)) ==> bicw 11409 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 11410 iRegIorL2I src1, iRegIorL2I src2, 11411 immI src3, immI_M1 src4) %{ 11412 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 11413 ins_cost(1.9 * INSN_COST); 11414 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 11415 11416 ins_encode %{ 11417 __ bicw(as_Register($dst$$reg), 11418 as_Register($src1$$reg), 11419 as_Register($src2$$reg), 11420 Assembler::LSR, 11421 $src3$$constant & 0x1f); 11422 %} 11423 11424 ins_pipe(ialu_reg_reg_shift); 11425 %} 11426 11427 // This pattern is automatically generated from aarch64_ad.m4 11428 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11429 // val & (-1 ^ (val >>> shift)) ==> bic 11430 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 11431 iRegL src1, iRegL src2, 11432 immI src3, immL_M1 src4) %{ 11433 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 11434 ins_cost(1.9 * INSN_COST); 11435 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 11436 11437 ins_encode %{ 11438 __ bic(as_Register($dst$$reg), 11439 as_Register($src1$$reg), 11440 as_Register($src2$$reg), 11441 Assembler::LSR, 11442 $src3$$constant & 0x3f); 11443 %} 11444 11445 ins_pipe(ialu_reg_reg_shift); 11446 %} 11447 11448 // This pattern is automatically generated from aarch64_ad.m4 11449 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11450 // val & (-1 ^ (val >> shift)) ==> bicw 11451 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 11452 iRegIorL2I src1, iRegIorL2I src2, 11453 immI src3, immI_M1 src4) %{ 11454 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 11455 ins_cost(1.9 * INSN_COST); 11456 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 11457 11458 ins_encode %{ 11459 __ bicw(as_Register($dst$$reg), 11460 as_Register($src1$$reg), 11461 as_Register($src2$$reg), 11462 Assembler::ASR, 11463 $src3$$constant & 0x1f); 11464 %} 11465 11466 ins_pipe(ialu_reg_reg_shift); 11467 %} 11468 11469 // This pattern is automatically generated from aarch64_ad.m4 11470 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11471 // val & (-1 ^ (val >> shift)) ==> bic 11472 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 11473 iRegL src1, iRegL src2, 11474 immI src3, immL_M1 src4) %{ 11475 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 11476 ins_cost(1.9 * INSN_COST); 11477 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 11478 11479 ins_encode %{ 11480 __ bic(as_Register($dst$$reg), 11481 as_Register($src1$$reg), 11482 as_Register($src2$$reg), 11483 Assembler::ASR, 11484 $src3$$constant & 0x3f); 11485 %} 11486 11487 ins_pipe(ialu_reg_reg_shift); 11488 %} 11489 11490 // This pattern is automatically generated from aarch64_ad.m4 11491 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11492 // val & (-1 ^ (val ror shift)) ==> bicw 11493 instruct AndI_reg_RotateRight_not_reg(iRegINoSp dst, 11494 iRegIorL2I src1, iRegIorL2I src2, 11495 immI src3, immI_M1 src4) %{ 11496 match(Set dst (AndI src1 (XorI(RotateRight src2 src3) src4))); 11497 ins_cost(1.9 * INSN_COST); 11498 format %{ "bicw $dst, $src1, $src2, ROR $src3" %} 11499 11500 ins_encode %{ 11501 __ bicw(as_Register($dst$$reg), 11502 as_Register($src1$$reg), 11503 as_Register($src2$$reg), 11504 Assembler::ROR, 11505 $src3$$constant & 0x1f); 11506 %} 11507 11508 ins_pipe(ialu_reg_reg_shift); 11509 %} 11510 11511 // This pattern is automatically generated from aarch64_ad.m4 11512 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11513 // val & (-1 ^ (val ror shift)) ==> bic 11514 instruct AndL_reg_RotateRight_not_reg(iRegLNoSp dst, 11515 iRegL src1, iRegL src2, 11516 immI src3, immL_M1 src4) %{ 11517 match(Set dst (AndL src1 (XorL(RotateRight src2 src3) src4))); 11518 ins_cost(1.9 * INSN_COST); 11519 format %{ "bic $dst, $src1, $src2, ROR $src3" %} 11520 11521 ins_encode %{ 11522 __ bic(as_Register($dst$$reg), 11523 as_Register($src1$$reg), 11524 as_Register($src2$$reg), 11525 Assembler::ROR, 11526 $src3$$constant & 0x3f); 11527 %} 11528 11529 ins_pipe(ialu_reg_reg_shift); 11530 %} 11531 11532 // This pattern is automatically generated from aarch64_ad.m4 11533 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11534 // val & (-1 ^ (val << shift)) ==> bicw 11535 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 11536 iRegIorL2I src1, iRegIorL2I src2, 11537 immI src3, immI_M1 src4) %{ 11538 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 11539 ins_cost(1.9 * INSN_COST); 11540 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 11541 11542 ins_encode %{ 11543 __ bicw(as_Register($dst$$reg), 11544 as_Register($src1$$reg), 11545 as_Register($src2$$reg), 11546 Assembler::LSL, 11547 $src3$$constant & 0x1f); 11548 %} 11549 11550 ins_pipe(ialu_reg_reg_shift); 11551 %} 11552 11553 // This pattern is automatically generated from aarch64_ad.m4 11554 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11555 // val & (-1 ^ (val << shift)) ==> bic 11556 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 11557 iRegL src1, iRegL src2, 11558 immI src3, immL_M1 src4) %{ 11559 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 11560 ins_cost(1.9 * INSN_COST); 11561 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 11562 11563 ins_encode %{ 11564 __ bic(as_Register($dst$$reg), 11565 as_Register($src1$$reg), 11566 as_Register($src2$$reg), 11567 Assembler::LSL, 11568 $src3$$constant & 0x3f); 11569 %} 11570 11571 ins_pipe(ialu_reg_reg_shift); 11572 %} 11573 11574 // This pattern is automatically generated from aarch64_ad.m4 11575 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11576 // val ^ (-1 ^ (val >>> shift)) ==> eonw 11577 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11578 iRegIorL2I src1, iRegIorL2I src2, 11579 immI src3, immI_M1 src4) %{ 11580 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11581 ins_cost(1.9 * INSN_COST); 11582 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11583 11584 ins_encode %{ 11585 __ eonw(as_Register($dst$$reg), 11586 as_Register($src1$$reg), 11587 as_Register($src2$$reg), 11588 Assembler::LSR, 11589 $src3$$constant & 0x1f); 11590 %} 11591 11592 ins_pipe(ialu_reg_reg_shift); 11593 %} 11594 11595 // This pattern is automatically generated from aarch64_ad.m4 11596 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11597 // val ^ (-1 ^ (val >>> shift)) ==> eon 11598 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11599 iRegL src1, iRegL src2, 11600 immI src3, immL_M1 src4) %{ 11601 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11602 ins_cost(1.9 * INSN_COST); 11603 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11604 11605 ins_encode %{ 11606 __ eon(as_Register($dst$$reg), 11607 as_Register($src1$$reg), 11608 as_Register($src2$$reg), 11609 Assembler::LSR, 11610 $src3$$constant & 0x3f); 11611 %} 11612 11613 ins_pipe(ialu_reg_reg_shift); 11614 %} 11615 11616 // This pattern is automatically generated from aarch64_ad.m4 11617 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11618 // val ^ (-1 ^ (val >> shift)) ==> eonw 11619 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11620 iRegIorL2I src1, iRegIorL2I src2, 11621 immI src3, immI_M1 src4) %{ 11622 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11623 ins_cost(1.9 * INSN_COST); 11624 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11625 11626 ins_encode %{ 11627 __ eonw(as_Register($dst$$reg), 11628 as_Register($src1$$reg), 11629 as_Register($src2$$reg), 11630 Assembler::ASR, 11631 $src3$$constant & 0x1f); 11632 %} 11633 11634 ins_pipe(ialu_reg_reg_shift); 11635 %} 11636 11637 // This pattern is automatically generated from aarch64_ad.m4 11638 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11639 // val ^ (-1 ^ (val >> shift)) ==> eon 11640 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11641 iRegL src1, iRegL src2, 11642 immI src3, immL_M1 src4) %{ 11643 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11644 ins_cost(1.9 * INSN_COST); 11645 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11646 11647 ins_encode %{ 11648 __ eon(as_Register($dst$$reg), 11649 as_Register($src1$$reg), 11650 as_Register($src2$$reg), 11651 Assembler::ASR, 11652 $src3$$constant & 0x3f); 11653 %} 11654 11655 ins_pipe(ialu_reg_reg_shift); 11656 %} 11657 11658 // This pattern is automatically generated from aarch64_ad.m4 11659 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11660 // val ^ (-1 ^ (val ror shift)) ==> eonw 11661 instruct XorI_reg_RotateRight_not_reg(iRegINoSp dst, 11662 iRegIorL2I src1, iRegIorL2I src2, 11663 immI src3, immI_M1 src4) %{ 11664 match(Set dst (XorI src4 (XorI(RotateRight src2 src3) src1))); 11665 ins_cost(1.9 * INSN_COST); 11666 format %{ "eonw $dst, $src1, $src2, ROR $src3" %} 11667 11668 ins_encode %{ 11669 __ eonw(as_Register($dst$$reg), 11670 as_Register($src1$$reg), 11671 as_Register($src2$$reg), 11672 Assembler::ROR, 11673 $src3$$constant & 0x1f); 11674 %} 11675 11676 ins_pipe(ialu_reg_reg_shift); 11677 %} 11678 11679 // This pattern is automatically generated from aarch64_ad.m4 11680 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11681 // val ^ (-1 ^ (val ror shift)) ==> eon 11682 instruct XorL_reg_RotateRight_not_reg(iRegLNoSp dst, 11683 iRegL src1, iRegL src2, 11684 immI src3, immL_M1 src4) %{ 11685 match(Set dst (XorL src4 (XorL(RotateRight src2 src3) src1))); 11686 ins_cost(1.9 * INSN_COST); 11687 format %{ "eon $dst, $src1, $src2, ROR $src3" %} 11688 11689 ins_encode %{ 11690 __ eon(as_Register($dst$$reg), 11691 as_Register($src1$$reg), 11692 as_Register($src2$$reg), 11693 Assembler::ROR, 11694 $src3$$constant & 0x3f); 11695 %} 11696 11697 ins_pipe(ialu_reg_reg_shift); 11698 %} 11699 11700 // This pattern is automatically generated from aarch64_ad.m4 11701 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11702 // val ^ (-1 ^ (val << shift)) ==> eonw 11703 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11704 iRegIorL2I src1, iRegIorL2I src2, 11705 immI src3, immI_M1 src4) %{ 11706 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11707 ins_cost(1.9 * INSN_COST); 11708 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11709 11710 ins_encode %{ 11711 __ eonw(as_Register($dst$$reg), 11712 as_Register($src1$$reg), 11713 as_Register($src2$$reg), 11714 Assembler::LSL, 11715 $src3$$constant & 0x1f); 11716 %} 11717 11718 ins_pipe(ialu_reg_reg_shift); 11719 %} 11720 11721 // This pattern is automatically generated from aarch64_ad.m4 11722 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11723 // val ^ (-1 ^ (val << shift)) ==> eon 11724 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11725 iRegL src1, iRegL src2, 11726 immI src3, immL_M1 src4) %{ 11727 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11728 ins_cost(1.9 * INSN_COST); 11729 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11730 11731 ins_encode %{ 11732 __ eon(as_Register($dst$$reg), 11733 as_Register($src1$$reg), 11734 as_Register($src2$$reg), 11735 Assembler::LSL, 11736 $src3$$constant & 0x3f); 11737 %} 11738 11739 ins_pipe(ialu_reg_reg_shift); 11740 %} 11741 11742 // This pattern is automatically generated from aarch64_ad.m4 11743 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11744 // val | (-1 ^ (val >>> shift)) ==> ornw 11745 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11746 iRegIorL2I src1, iRegIorL2I src2, 11747 immI src3, immI_M1 src4) %{ 11748 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11749 ins_cost(1.9 * INSN_COST); 11750 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11751 11752 ins_encode %{ 11753 __ ornw(as_Register($dst$$reg), 11754 as_Register($src1$$reg), 11755 as_Register($src2$$reg), 11756 Assembler::LSR, 11757 $src3$$constant & 0x1f); 11758 %} 11759 11760 ins_pipe(ialu_reg_reg_shift); 11761 %} 11762 11763 // This pattern is automatically generated from aarch64_ad.m4 11764 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11765 // val | (-1 ^ (val >>> shift)) ==> orn 11766 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11767 iRegL src1, iRegL src2, 11768 immI src3, immL_M1 src4) %{ 11769 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11770 ins_cost(1.9 * INSN_COST); 11771 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11772 11773 ins_encode %{ 11774 __ orn(as_Register($dst$$reg), 11775 as_Register($src1$$reg), 11776 as_Register($src2$$reg), 11777 Assembler::LSR, 11778 $src3$$constant & 0x3f); 11779 %} 11780 11781 ins_pipe(ialu_reg_reg_shift); 11782 %} 11783 11784 // This pattern is automatically generated from aarch64_ad.m4 11785 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11786 // val | (-1 ^ (val >> shift)) ==> ornw 11787 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11788 iRegIorL2I src1, iRegIorL2I src2, 11789 immI src3, immI_M1 src4) %{ 11790 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11791 ins_cost(1.9 * INSN_COST); 11792 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11793 11794 ins_encode %{ 11795 __ ornw(as_Register($dst$$reg), 11796 as_Register($src1$$reg), 11797 as_Register($src2$$reg), 11798 Assembler::ASR, 11799 $src3$$constant & 0x1f); 11800 %} 11801 11802 ins_pipe(ialu_reg_reg_shift); 11803 %} 11804 11805 // This pattern is automatically generated from aarch64_ad.m4 11806 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11807 // val | (-1 ^ (val >> shift)) ==> orn 11808 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11809 iRegL src1, iRegL src2, 11810 immI src3, immL_M1 src4) %{ 11811 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11812 ins_cost(1.9 * INSN_COST); 11813 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11814 11815 ins_encode %{ 11816 __ orn(as_Register($dst$$reg), 11817 as_Register($src1$$reg), 11818 as_Register($src2$$reg), 11819 Assembler::ASR, 11820 $src3$$constant & 0x3f); 11821 %} 11822 11823 ins_pipe(ialu_reg_reg_shift); 11824 %} 11825 11826 // This pattern is automatically generated from aarch64_ad.m4 11827 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11828 // val | (-1 ^ (val ror shift)) ==> ornw 11829 instruct OrI_reg_RotateRight_not_reg(iRegINoSp dst, 11830 iRegIorL2I src1, iRegIorL2I src2, 11831 immI src3, immI_M1 src4) %{ 11832 match(Set dst (OrI src1 (XorI(RotateRight src2 src3) src4))); 11833 ins_cost(1.9 * INSN_COST); 11834 format %{ "ornw $dst, $src1, $src2, ROR $src3" %} 11835 11836 ins_encode %{ 11837 __ ornw(as_Register($dst$$reg), 11838 as_Register($src1$$reg), 11839 as_Register($src2$$reg), 11840 Assembler::ROR, 11841 $src3$$constant & 0x1f); 11842 %} 11843 11844 ins_pipe(ialu_reg_reg_shift); 11845 %} 11846 11847 // This pattern is automatically generated from aarch64_ad.m4 11848 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11849 // val | (-1 ^ (val ror shift)) ==> orn 11850 instruct OrL_reg_RotateRight_not_reg(iRegLNoSp dst, 11851 iRegL src1, iRegL src2, 11852 immI src3, immL_M1 src4) %{ 11853 match(Set dst (OrL src1 (XorL(RotateRight src2 src3) src4))); 11854 ins_cost(1.9 * INSN_COST); 11855 format %{ "orn $dst, $src1, $src2, ROR $src3" %} 11856 11857 ins_encode %{ 11858 __ orn(as_Register($dst$$reg), 11859 as_Register($src1$$reg), 11860 as_Register($src2$$reg), 11861 Assembler::ROR, 11862 $src3$$constant & 0x3f); 11863 %} 11864 11865 ins_pipe(ialu_reg_reg_shift); 11866 %} 11867 11868 // This pattern is automatically generated from aarch64_ad.m4 11869 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11870 // val | (-1 ^ (val << shift)) ==> ornw 11871 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11872 iRegIorL2I src1, iRegIorL2I src2, 11873 immI src3, immI_M1 src4) %{ 11874 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11875 ins_cost(1.9 * INSN_COST); 11876 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11877 11878 ins_encode %{ 11879 __ ornw(as_Register($dst$$reg), 11880 as_Register($src1$$reg), 11881 as_Register($src2$$reg), 11882 Assembler::LSL, 11883 $src3$$constant & 0x1f); 11884 %} 11885 11886 ins_pipe(ialu_reg_reg_shift); 11887 %} 11888 11889 // This pattern is automatically generated from aarch64_ad.m4 11890 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11891 // val | (-1 ^ (val << shift)) ==> orn 11892 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11893 iRegL src1, iRegL src2, 11894 immI src3, immL_M1 src4) %{ 11895 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11896 ins_cost(1.9 * INSN_COST); 11897 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11898 11899 ins_encode %{ 11900 __ orn(as_Register($dst$$reg), 11901 as_Register($src1$$reg), 11902 as_Register($src2$$reg), 11903 Assembler::LSL, 11904 $src3$$constant & 0x3f); 11905 %} 11906 11907 ins_pipe(ialu_reg_reg_shift); 11908 %} 11909 11910 // This pattern is automatically generated from aarch64_ad.m4 11911 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11912 instruct AndI_reg_URShift_reg(iRegINoSp dst, 11913 iRegIorL2I src1, iRegIorL2I src2, 11914 immI src3) %{ 11915 match(Set dst (AndI src1 (URShiftI src2 src3))); 11916 11917 ins_cost(1.9 * INSN_COST); 11918 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11919 11920 ins_encode %{ 11921 __ andw(as_Register($dst$$reg), 11922 as_Register($src1$$reg), 11923 as_Register($src2$$reg), 11924 Assembler::LSR, 11925 $src3$$constant & 0x1f); 11926 %} 11927 11928 ins_pipe(ialu_reg_reg_shift); 11929 %} 11930 11931 // This pattern is automatically generated from aarch64_ad.m4 11932 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11933 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11934 iRegL src1, iRegL src2, 11935 immI src3) %{ 11936 match(Set dst (AndL src1 (URShiftL src2 src3))); 11937 11938 ins_cost(1.9 * INSN_COST); 11939 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11940 11941 ins_encode %{ 11942 __ andr(as_Register($dst$$reg), 11943 as_Register($src1$$reg), 11944 as_Register($src2$$reg), 11945 Assembler::LSR, 11946 $src3$$constant & 0x3f); 11947 %} 11948 11949 ins_pipe(ialu_reg_reg_shift); 11950 %} 11951 11952 // This pattern is automatically generated from aarch64_ad.m4 11953 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11954 instruct AndI_reg_RShift_reg(iRegINoSp dst, 11955 iRegIorL2I src1, iRegIorL2I src2, 11956 immI src3) %{ 11957 match(Set dst (AndI src1 (RShiftI src2 src3))); 11958 11959 ins_cost(1.9 * INSN_COST); 11960 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11961 11962 ins_encode %{ 11963 __ andw(as_Register($dst$$reg), 11964 as_Register($src1$$reg), 11965 as_Register($src2$$reg), 11966 Assembler::ASR, 11967 $src3$$constant & 0x1f); 11968 %} 11969 11970 ins_pipe(ialu_reg_reg_shift); 11971 %} 11972 11973 // This pattern is automatically generated from aarch64_ad.m4 11974 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11975 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11976 iRegL src1, iRegL src2, 11977 immI src3) %{ 11978 match(Set dst (AndL src1 (RShiftL src2 src3))); 11979 11980 ins_cost(1.9 * INSN_COST); 11981 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11982 11983 ins_encode %{ 11984 __ andr(as_Register($dst$$reg), 11985 as_Register($src1$$reg), 11986 as_Register($src2$$reg), 11987 Assembler::ASR, 11988 $src3$$constant & 0x3f); 11989 %} 11990 11991 ins_pipe(ialu_reg_reg_shift); 11992 %} 11993 11994 // This pattern is automatically generated from aarch64_ad.m4 11995 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11996 instruct AndI_reg_LShift_reg(iRegINoSp dst, 11997 iRegIorL2I src1, iRegIorL2I src2, 11998 immI src3) %{ 11999 match(Set dst (AndI src1 (LShiftI src2 src3))); 12000 12001 ins_cost(1.9 * INSN_COST); 12002 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 12003 12004 ins_encode %{ 12005 __ andw(as_Register($dst$$reg), 12006 as_Register($src1$$reg), 12007 as_Register($src2$$reg), 12008 Assembler::LSL, 12009 $src3$$constant & 0x1f); 12010 %} 12011 12012 ins_pipe(ialu_reg_reg_shift); 12013 %} 12014 12015 // This pattern is automatically generated from aarch64_ad.m4 12016 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12017 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 12018 iRegL src1, iRegL src2, 12019 immI src3) %{ 12020 match(Set dst (AndL src1 (LShiftL src2 src3))); 12021 12022 ins_cost(1.9 * INSN_COST); 12023 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 12024 12025 ins_encode %{ 12026 __ andr(as_Register($dst$$reg), 12027 as_Register($src1$$reg), 12028 as_Register($src2$$reg), 12029 Assembler::LSL, 12030 $src3$$constant & 0x3f); 12031 %} 12032 12033 ins_pipe(ialu_reg_reg_shift); 12034 %} 12035 12036 // This pattern is automatically generated from aarch64_ad.m4 12037 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12038 instruct AndI_reg_RotateRight_reg(iRegINoSp dst, 12039 iRegIorL2I src1, iRegIorL2I src2, 12040 immI src3) %{ 12041 match(Set dst (AndI src1 (RotateRight src2 src3))); 12042 12043 ins_cost(1.9 * INSN_COST); 12044 format %{ "andw $dst, $src1, $src2, ROR $src3" %} 12045 12046 ins_encode %{ 12047 __ andw(as_Register($dst$$reg), 12048 as_Register($src1$$reg), 12049 as_Register($src2$$reg), 12050 Assembler::ROR, 12051 $src3$$constant & 0x1f); 12052 %} 12053 12054 ins_pipe(ialu_reg_reg_shift); 12055 %} 12056 12057 // This pattern is automatically generated from aarch64_ad.m4 12058 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12059 instruct AndL_reg_RotateRight_reg(iRegLNoSp dst, 12060 iRegL src1, iRegL src2, 12061 immI src3) %{ 12062 match(Set dst (AndL src1 (RotateRight src2 src3))); 12063 12064 ins_cost(1.9 * INSN_COST); 12065 format %{ "andr $dst, $src1, $src2, ROR $src3" %} 12066 12067 ins_encode %{ 12068 __ andr(as_Register($dst$$reg), 12069 as_Register($src1$$reg), 12070 as_Register($src2$$reg), 12071 Assembler::ROR, 12072 $src3$$constant & 0x3f); 12073 %} 12074 12075 ins_pipe(ialu_reg_reg_shift); 12076 %} 12077 12078 // This pattern is automatically generated from aarch64_ad.m4 12079 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12080 instruct XorI_reg_URShift_reg(iRegINoSp dst, 12081 iRegIorL2I src1, iRegIorL2I src2, 12082 immI src3) %{ 12083 match(Set dst (XorI src1 (URShiftI src2 src3))); 12084 12085 ins_cost(1.9 * INSN_COST); 12086 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 12087 12088 ins_encode %{ 12089 __ eorw(as_Register($dst$$reg), 12090 as_Register($src1$$reg), 12091 as_Register($src2$$reg), 12092 Assembler::LSR, 12093 $src3$$constant & 0x1f); 12094 %} 12095 12096 ins_pipe(ialu_reg_reg_shift); 12097 %} 12098 12099 // This pattern is automatically generated from aarch64_ad.m4 12100 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12101 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 12102 iRegL src1, iRegL src2, 12103 immI src3) %{ 12104 match(Set dst (XorL src1 (URShiftL src2 src3))); 12105 12106 ins_cost(1.9 * INSN_COST); 12107 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 12108 12109 ins_encode %{ 12110 __ eor(as_Register($dst$$reg), 12111 as_Register($src1$$reg), 12112 as_Register($src2$$reg), 12113 Assembler::LSR, 12114 $src3$$constant & 0x3f); 12115 %} 12116 12117 ins_pipe(ialu_reg_reg_shift); 12118 %} 12119 12120 // This pattern is automatically generated from aarch64_ad.m4 12121 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12122 instruct XorI_reg_RShift_reg(iRegINoSp dst, 12123 iRegIorL2I src1, iRegIorL2I src2, 12124 immI src3) %{ 12125 match(Set dst (XorI src1 (RShiftI src2 src3))); 12126 12127 ins_cost(1.9 * INSN_COST); 12128 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 12129 12130 ins_encode %{ 12131 __ eorw(as_Register($dst$$reg), 12132 as_Register($src1$$reg), 12133 as_Register($src2$$reg), 12134 Assembler::ASR, 12135 $src3$$constant & 0x1f); 12136 %} 12137 12138 ins_pipe(ialu_reg_reg_shift); 12139 %} 12140 12141 // This pattern is automatically generated from aarch64_ad.m4 12142 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12143 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 12144 iRegL src1, iRegL src2, 12145 immI src3) %{ 12146 match(Set dst (XorL src1 (RShiftL src2 src3))); 12147 12148 ins_cost(1.9 * INSN_COST); 12149 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 12150 12151 ins_encode %{ 12152 __ eor(as_Register($dst$$reg), 12153 as_Register($src1$$reg), 12154 as_Register($src2$$reg), 12155 Assembler::ASR, 12156 $src3$$constant & 0x3f); 12157 %} 12158 12159 ins_pipe(ialu_reg_reg_shift); 12160 %} 12161 12162 // This pattern is automatically generated from aarch64_ad.m4 12163 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12164 instruct XorI_reg_LShift_reg(iRegINoSp dst, 12165 iRegIorL2I src1, iRegIorL2I src2, 12166 immI src3) %{ 12167 match(Set dst (XorI src1 (LShiftI src2 src3))); 12168 12169 ins_cost(1.9 * INSN_COST); 12170 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 12171 12172 ins_encode %{ 12173 __ eorw(as_Register($dst$$reg), 12174 as_Register($src1$$reg), 12175 as_Register($src2$$reg), 12176 Assembler::LSL, 12177 $src3$$constant & 0x1f); 12178 %} 12179 12180 ins_pipe(ialu_reg_reg_shift); 12181 %} 12182 12183 // This pattern is automatically generated from aarch64_ad.m4 12184 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12185 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 12186 iRegL src1, iRegL src2, 12187 immI src3) %{ 12188 match(Set dst (XorL src1 (LShiftL src2 src3))); 12189 12190 ins_cost(1.9 * INSN_COST); 12191 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 12192 12193 ins_encode %{ 12194 __ eor(as_Register($dst$$reg), 12195 as_Register($src1$$reg), 12196 as_Register($src2$$reg), 12197 Assembler::LSL, 12198 $src3$$constant & 0x3f); 12199 %} 12200 12201 ins_pipe(ialu_reg_reg_shift); 12202 %} 12203 12204 // This pattern is automatically generated from aarch64_ad.m4 12205 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12206 instruct XorI_reg_RotateRight_reg(iRegINoSp dst, 12207 iRegIorL2I src1, iRegIorL2I src2, 12208 immI src3) %{ 12209 match(Set dst (XorI src1 (RotateRight src2 src3))); 12210 12211 ins_cost(1.9 * INSN_COST); 12212 format %{ "eorw $dst, $src1, $src2, ROR $src3" %} 12213 12214 ins_encode %{ 12215 __ eorw(as_Register($dst$$reg), 12216 as_Register($src1$$reg), 12217 as_Register($src2$$reg), 12218 Assembler::ROR, 12219 $src3$$constant & 0x1f); 12220 %} 12221 12222 ins_pipe(ialu_reg_reg_shift); 12223 %} 12224 12225 // This pattern is automatically generated from aarch64_ad.m4 12226 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12227 instruct XorL_reg_RotateRight_reg(iRegLNoSp dst, 12228 iRegL src1, iRegL src2, 12229 immI src3) %{ 12230 match(Set dst (XorL src1 (RotateRight src2 src3))); 12231 12232 ins_cost(1.9 * INSN_COST); 12233 format %{ "eor $dst, $src1, $src2, ROR $src3" %} 12234 12235 ins_encode %{ 12236 __ eor(as_Register($dst$$reg), 12237 as_Register($src1$$reg), 12238 as_Register($src2$$reg), 12239 Assembler::ROR, 12240 $src3$$constant & 0x3f); 12241 %} 12242 12243 ins_pipe(ialu_reg_reg_shift); 12244 %} 12245 12246 // This pattern is automatically generated from aarch64_ad.m4 12247 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12248 instruct OrI_reg_URShift_reg(iRegINoSp dst, 12249 iRegIorL2I src1, iRegIorL2I src2, 12250 immI src3) %{ 12251 match(Set dst (OrI src1 (URShiftI src2 src3))); 12252 12253 ins_cost(1.9 * INSN_COST); 12254 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 12255 12256 ins_encode %{ 12257 __ orrw(as_Register($dst$$reg), 12258 as_Register($src1$$reg), 12259 as_Register($src2$$reg), 12260 Assembler::LSR, 12261 $src3$$constant & 0x1f); 12262 %} 12263 12264 ins_pipe(ialu_reg_reg_shift); 12265 %} 12266 12267 // This pattern is automatically generated from aarch64_ad.m4 12268 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12269 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 12270 iRegL src1, iRegL src2, 12271 immI src3) %{ 12272 match(Set dst (OrL src1 (URShiftL src2 src3))); 12273 12274 ins_cost(1.9 * INSN_COST); 12275 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 12276 12277 ins_encode %{ 12278 __ orr(as_Register($dst$$reg), 12279 as_Register($src1$$reg), 12280 as_Register($src2$$reg), 12281 Assembler::LSR, 12282 $src3$$constant & 0x3f); 12283 %} 12284 12285 ins_pipe(ialu_reg_reg_shift); 12286 %} 12287 12288 // This pattern is automatically generated from aarch64_ad.m4 12289 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12290 instruct OrI_reg_RShift_reg(iRegINoSp dst, 12291 iRegIorL2I src1, iRegIorL2I src2, 12292 immI src3) %{ 12293 match(Set dst (OrI src1 (RShiftI src2 src3))); 12294 12295 ins_cost(1.9 * INSN_COST); 12296 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 12297 12298 ins_encode %{ 12299 __ orrw(as_Register($dst$$reg), 12300 as_Register($src1$$reg), 12301 as_Register($src2$$reg), 12302 Assembler::ASR, 12303 $src3$$constant & 0x1f); 12304 %} 12305 12306 ins_pipe(ialu_reg_reg_shift); 12307 %} 12308 12309 // This pattern is automatically generated from aarch64_ad.m4 12310 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12311 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 12312 iRegL src1, iRegL src2, 12313 immI src3) %{ 12314 match(Set dst (OrL src1 (RShiftL src2 src3))); 12315 12316 ins_cost(1.9 * INSN_COST); 12317 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 12318 12319 ins_encode %{ 12320 __ orr(as_Register($dst$$reg), 12321 as_Register($src1$$reg), 12322 as_Register($src2$$reg), 12323 Assembler::ASR, 12324 $src3$$constant & 0x3f); 12325 %} 12326 12327 ins_pipe(ialu_reg_reg_shift); 12328 %} 12329 12330 // This pattern is automatically generated from aarch64_ad.m4 12331 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12332 instruct OrI_reg_LShift_reg(iRegINoSp dst, 12333 iRegIorL2I src1, iRegIorL2I src2, 12334 immI src3) %{ 12335 match(Set dst (OrI src1 (LShiftI src2 src3))); 12336 12337 ins_cost(1.9 * INSN_COST); 12338 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 12339 12340 ins_encode %{ 12341 __ orrw(as_Register($dst$$reg), 12342 as_Register($src1$$reg), 12343 as_Register($src2$$reg), 12344 Assembler::LSL, 12345 $src3$$constant & 0x1f); 12346 %} 12347 12348 ins_pipe(ialu_reg_reg_shift); 12349 %} 12350 12351 // This pattern is automatically generated from aarch64_ad.m4 12352 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12353 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 12354 iRegL src1, iRegL src2, 12355 immI src3) %{ 12356 match(Set dst (OrL src1 (LShiftL src2 src3))); 12357 12358 ins_cost(1.9 * INSN_COST); 12359 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 12360 12361 ins_encode %{ 12362 __ orr(as_Register($dst$$reg), 12363 as_Register($src1$$reg), 12364 as_Register($src2$$reg), 12365 Assembler::LSL, 12366 $src3$$constant & 0x3f); 12367 %} 12368 12369 ins_pipe(ialu_reg_reg_shift); 12370 %} 12371 12372 // This pattern is automatically generated from aarch64_ad.m4 12373 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12374 instruct OrI_reg_RotateRight_reg(iRegINoSp dst, 12375 iRegIorL2I src1, iRegIorL2I src2, 12376 immI src3) %{ 12377 match(Set dst (OrI src1 (RotateRight src2 src3))); 12378 12379 ins_cost(1.9 * INSN_COST); 12380 format %{ "orrw $dst, $src1, $src2, ROR $src3" %} 12381 12382 ins_encode %{ 12383 __ orrw(as_Register($dst$$reg), 12384 as_Register($src1$$reg), 12385 as_Register($src2$$reg), 12386 Assembler::ROR, 12387 $src3$$constant & 0x1f); 12388 %} 12389 12390 ins_pipe(ialu_reg_reg_shift); 12391 %} 12392 12393 // This pattern is automatically generated from aarch64_ad.m4 12394 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12395 instruct OrL_reg_RotateRight_reg(iRegLNoSp dst, 12396 iRegL src1, iRegL src2, 12397 immI src3) %{ 12398 match(Set dst (OrL src1 (RotateRight src2 src3))); 12399 12400 ins_cost(1.9 * INSN_COST); 12401 format %{ "orr $dst, $src1, $src2, ROR $src3" %} 12402 12403 ins_encode %{ 12404 __ orr(as_Register($dst$$reg), 12405 as_Register($src1$$reg), 12406 as_Register($src2$$reg), 12407 Assembler::ROR, 12408 $src3$$constant & 0x3f); 12409 %} 12410 12411 ins_pipe(ialu_reg_reg_shift); 12412 %} 12413 12414 // This pattern is automatically generated from aarch64_ad.m4 12415 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12416 instruct AddI_reg_URShift_reg(iRegINoSp dst, 12417 iRegIorL2I src1, iRegIorL2I src2, 12418 immI src3) %{ 12419 match(Set dst (AddI src1 (URShiftI src2 src3))); 12420 12421 ins_cost(1.9 * INSN_COST); 12422 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 12423 12424 ins_encode %{ 12425 __ addw(as_Register($dst$$reg), 12426 as_Register($src1$$reg), 12427 as_Register($src2$$reg), 12428 Assembler::LSR, 12429 $src3$$constant & 0x1f); 12430 %} 12431 12432 ins_pipe(ialu_reg_reg_shift); 12433 %} 12434 12435 // This pattern is automatically generated from aarch64_ad.m4 12436 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12437 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 12438 iRegL src1, iRegL src2, 12439 immI src3) %{ 12440 match(Set dst (AddL src1 (URShiftL src2 src3))); 12441 12442 ins_cost(1.9 * INSN_COST); 12443 format %{ "add $dst, $src1, $src2, LSR $src3" %} 12444 12445 ins_encode %{ 12446 __ add(as_Register($dst$$reg), 12447 as_Register($src1$$reg), 12448 as_Register($src2$$reg), 12449 Assembler::LSR, 12450 $src3$$constant & 0x3f); 12451 %} 12452 12453 ins_pipe(ialu_reg_reg_shift); 12454 %} 12455 12456 // This pattern is automatically generated from aarch64_ad.m4 12457 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12458 instruct AddI_reg_RShift_reg(iRegINoSp dst, 12459 iRegIorL2I src1, iRegIorL2I src2, 12460 immI src3) %{ 12461 match(Set dst (AddI src1 (RShiftI src2 src3))); 12462 12463 ins_cost(1.9 * INSN_COST); 12464 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 12465 12466 ins_encode %{ 12467 __ addw(as_Register($dst$$reg), 12468 as_Register($src1$$reg), 12469 as_Register($src2$$reg), 12470 Assembler::ASR, 12471 $src3$$constant & 0x1f); 12472 %} 12473 12474 ins_pipe(ialu_reg_reg_shift); 12475 %} 12476 12477 // This pattern is automatically generated from aarch64_ad.m4 12478 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12479 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 12480 iRegL src1, iRegL src2, 12481 immI src3) %{ 12482 match(Set dst (AddL src1 (RShiftL src2 src3))); 12483 12484 ins_cost(1.9 * INSN_COST); 12485 format %{ "add $dst, $src1, $src2, ASR $src3" %} 12486 12487 ins_encode %{ 12488 __ add(as_Register($dst$$reg), 12489 as_Register($src1$$reg), 12490 as_Register($src2$$reg), 12491 Assembler::ASR, 12492 $src3$$constant & 0x3f); 12493 %} 12494 12495 ins_pipe(ialu_reg_reg_shift); 12496 %} 12497 12498 // This pattern is automatically generated from aarch64_ad.m4 12499 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12500 instruct AddI_reg_LShift_reg(iRegINoSp dst, 12501 iRegIorL2I src1, iRegIorL2I src2, 12502 immI src3) %{ 12503 match(Set dst (AddI src1 (LShiftI src2 src3))); 12504 12505 ins_cost(1.9 * INSN_COST); 12506 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 12507 12508 ins_encode %{ 12509 __ addw(as_Register($dst$$reg), 12510 as_Register($src1$$reg), 12511 as_Register($src2$$reg), 12512 Assembler::LSL, 12513 $src3$$constant & 0x1f); 12514 %} 12515 12516 ins_pipe(ialu_reg_reg_shift); 12517 %} 12518 12519 // This pattern is automatically generated from aarch64_ad.m4 12520 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12521 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 12522 iRegL src1, iRegL src2, 12523 immI src3) %{ 12524 match(Set dst (AddL src1 (LShiftL src2 src3))); 12525 12526 ins_cost(1.9 * INSN_COST); 12527 format %{ "add $dst, $src1, $src2, LSL $src3" %} 12528 12529 ins_encode %{ 12530 __ add(as_Register($dst$$reg), 12531 as_Register($src1$$reg), 12532 as_Register($src2$$reg), 12533 Assembler::LSL, 12534 $src3$$constant & 0x3f); 12535 %} 12536 12537 ins_pipe(ialu_reg_reg_shift); 12538 %} 12539 12540 // This pattern is automatically generated from aarch64_ad.m4 12541 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12542 instruct SubI_reg_URShift_reg(iRegINoSp dst, 12543 iRegIorL2I src1, iRegIorL2I src2, 12544 immI src3) %{ 12545 match(Set dst (SubI src1 (URShiftI src2 src3))); 12546 12547 ins_cost(1.9 * INSN_COST); 12548 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 12549 12550 ins_encode %{ 12551 __ subw(as_Register($dst$$reg), 12552 as_Register($src1$$reg), 12553 as_Register($src2$$reg), 12554 Assembler::LSR, 12555 $src3$$constant & 0x1f); 12556 %} 12557 12558 ins_pipe(ialu_reg_reg_shift); 12559 %} 12560 12561 // This pattern is automatically generated from aarch64_ad.m4 12562 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12563 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 12564 iRegL src1, iRegL src2, 12565 immI src3) %{ 12566 match(Set dst (SubL src1 (URShiftL src2 src3))); 12567 12568 ins_cost(1.9 * INSN_COST); 12569 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 12570 12571 ins_encode %{ 12572 __ sub(as_Register($dst$$reg), 12573 as_Register($src1$$reg), 12574 as_Register($src2$$reg), 12575 Assembler::LSR, 12576 $src3$$constant & 0x3f); 12577 %} 12578 12579 ins_pipe(ialu_reg_reg_shift); 12580 %} 12581 12582 // This pattern is automatically generated from aarch64_ad.m4 12583 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12584 instruct SubI_reg_RShift_reg(iRegINoSp dst, 12585 iRegIorL2I src1, iRegIorL2I src2, 12586 immI src3) %{ 12587 match(Set dst (SubI src1 (RShiftI src2 src3))); 12588 12589 ins_cost(1.9 * INSN_COST); 12590 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 12591 12592 ins_encode %{ 12593 __ subw(as_Register($dst$$reg), 12594 as_Register($src1$$reg), 12595 as_Register($src2$$reg), 12596 Assembler::ASR, 12597 $src3$$constant & 0x1f); 12598 %} 12599 12600 ins_pipe(ialu_reg_reg_shift); 12601 %} 12602 12603 // This pattern is automatically generated from aarch64_ad.m4 12604 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12605 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 12606 iRegL src1, iRegL src2, 12607 immI src3) %{ 12608 match(Set dst (SubL src1 (RShiftL src2 src3))); 12609 12610 ins_cost(1.9 * INSN_COST); 12611 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 12612 12613 ins_encode %{ 12614 __ sub(as_Register($dst$$reg), 12615 as_Register($src1$$reg), 12616 as_Register($src2$$reg), 12617 Assembler::ASR, 12618 $src3$$constant & 0x3f); 12619 %} 12620 12621 ins_pipe(ialu_reg_reg_shift); 12622 %} 12623 12624 // This pattern is automatically generated from aarch64_ad.m4 12625 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12626 instruct SubI_reg_LShift_reg(iRegINoSp dst, 12627 iRegIorL2I src1, iRegIorL2I src2, 12628 immI src3) %{ 12629 match(Set dst (SubI src1 (LShiftI src2 src3))); 12630 12631 ins_cost(1.9 * INSN_COST); 12632 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 12633 12634 ins_encode %{ 12635 __ subw(as_Register($dst$$reg), 12636 as_Register($src1$$reg), 12637 as_Register($src2$$reg), 12638 Assembler::LSL, 12639 $src3$$constant & 0x1f); 12640 %} 12641 12642 ins_pipe(ialu_reg_reg_shift); 12643 %} 12644 12645 // This pattern is automatically generated from aarch64_ad.m4 12646 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12647 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 12648 iRegL src1, iRegL src2, 12649 immI src3) %{ 12650 match(Set dst (SubL src1 (LShiftL src2 src3))); 12651 12652 ins_cost(1.9 * INSN_COST); 12653 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 12654 12655 ins_encode %{ 12656 __ sub(as_Register($dst$$reg), 12657 as_Register($src1$$reg), 12658 as_Register($src2$$reg), 12659 Assembler::LSL, 12660 $src3$$constant & 0x3f); 12661 %} 12662 12663 ins_pipe(ialu_reg_reg_shift); 12664 %} 12665 12666 // This pattern is automatically generated from aarch64_ad.m4 12667 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12668 12669 // Shift Left followed by Shift Right. 12670 // This idiom is used by the compiler for the i2b bytecode etc. 12671 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12672 %{ 12673 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 12674 ins_cost(INSN_COST * 2); 12675 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12676 ins_encode %{ 12677 int lshift = $lshift_count$$constant & 63; 12678 int rshift = $rshift_count$$constant & 63; 12679 int s = 63 - lshift; 12680 int r = (rshift - lshift) & 63; 12681 __ sbfm(as_Register($dst$$reg), 12682 as_Register($src$$reg), 12683 r, s); 12684 %} 12685 12686 ins_pipe(ialu_reg_shift); 12687 %} 12688 12689 // This pattern is automatically generated from aarch64_ad.m4 12690 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12691 12692 // Shift Left followed by Shift Right. 12693 // This idiom is used by the compiler for the i2b bytecode etc. 12694 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12695 %{ 12696 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 12697 ins_cost(INSN_COST * 2); 12698 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12699 ins_encode %{ 12700 int lshift = $lshift_count$$constant & 31; 12701 int rshift = $rshift_count$$constant & 31; 12702 int s = 31 - lshift; 12703 int r = (rshift - lshift) & 31; 12704 __ sbfmw(as_Register($dst$$reg), 12705 as_Register($src$$reg), 12706 r, s); 12707 %} 12708 12709 ins_pipe(ialu_reg_shift); 12710 %} 12711 12712 // This pattern is automatically generated from aarch64_ad.m4 12713 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12714 12715 // Shift Left followed by Shift Right. 12716 // This idiom is used by the compiler for the i2b bytecode etc. 12717 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12718 %{ 12719 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 12720 ins_cost(INSN_COST * 2); 12721 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12722 ins_encode %{ 12723 int lshift = $lshift_count$$constant & 63; 12724 int rshift = $rshift_count$$constant & 63; 12725 int s = 63 - lshift; 12726 int r = (rshift - lshift) & 63; 12727 __ ubfm(as_Register($dst$$reg), 12728 as_Register($src$$reg), 12729 r, s); 12730 %} 12731 12732 ins_pipe(ialu_reg_shift); 12733 %} 12734 12735 // This pattern is automatically generated from aarch64_ad.m4 12736 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12737 12738 // Shift Left followed by Shift Right. 12739 // This idiom is used by the compiler for the i2b bytecode etc. 12740 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12741 %{ 12742 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 12743 ins_cost(INSN_COST * 2); 12744 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12745 ins_encode %{ 12746 int lshift = $lshift_count$$constant & 31; 12747 int rshift = $rshift_count$$constant & 31; 12748 int s = 31 - lshift; 12749 int r = (rshift - lshift) & 31; 12750 __ ubfmw(as_Register($dst$$reg), 12751 as_Register($src$$reg), 12752 r, s); 12753 %} 12754 12755 ins_pipe(ialu_reg_shift); 12756 %} 12757 12758 // Bitfield extract with shift & mask 12759 12760 // This pattern is automatically generated from aarch64_ad.m4 12761 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12762 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12763 %{ 12764 match(Set dst (AndI (URShiftI src rshift) mask)); 12765 // Make sure we are not going to exceed what ubfxw can do. 12766 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12767 12768 ins_cost(INSN_COST); 12769 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 12770 ins_encode %{ 12771 int rshift = $rshift$$constant & 31; 12772 intptr_t mask = $mask$$constant; 12773 int width = exact_log2(mask+1); 12774 __ ubfxw(as_Register($dst$$reg), 12775 as_Register($src$$reg), rshift, width); 12776 %} 12777 ins_pipe(ialu_reg_shift); 12778 %} 12779 12780 // This pattern is automatically generated from aarch64_ad.m4 12781 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12782 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 12783 %{ 12784 match(Set dst (AndL (URShiftL src rshift) mask)); 12785 // Make sure we are not going to exceed what ubfx can do. 12786 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 12787 12788 ins_cost(INSN_COST); 12789 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12790 ins_encode %{ 12791 int rshift = $rshift$$constant & 63; 12792 intptr_t mask = $mask$$constant; 12793 int width = exact_log2_long(mask+1); 12794 __ ubfx(as_Register($dst$$reg), 12795 as_Register($src$$reg), rshift, width); 12796 %} 12797 ins_pipe(ialu_reg_shift); 12798 %} 12799 12800 12801 // This pattern is automatically generated from aarch64_ad.m4 12802 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12803 12804 // We can use ubfx when extending an And with a mask when we know mask 12805 // is positive. We know that because immI_bitmask guarantees it. 12806 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12807 %{ 12808 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 12809 // Make sure we are not going to exceed what ubfxw can do. 12810 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12811 12812 ins_cost(INSN_COST * 2); 12813 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12814 ins_encode %{ 12815 int rshift = $rshift$$constant & 31; 12816 intptr_t mask = $mask$$constant; 12817 int width = exact_log2(mask+1); 12818 __ ubfx(as_Register($dst$$reg), 12819 as_Register($src$$reg), rshift, width); 12820 %} 12821 ins_pipe(ialu_reg_shift); 12822 %} 12823 12824 12825 // This pattern is automatically generated from aarch64_ad.m4 12826 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12827 12828 // We can use ubfiz when masking by a positive number and then left shifting the result. 12829 // We know that the mask is positive because immI_bitmask guarantees it. 12830 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12831 %{ 12832 match(Set dst (LShiftI (AndI src mask) lshift)); 12833 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 12834 12835 ins_cost(INSN_COST); 12836 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12837 ins_encode %{ 12838 int lshift = $lshift$$constant & 31; 12839 intptr_t mask = $mask$$constant; 12840 int width = exact_log2(mask+1); 12841 __ ubfizw(as_Register($dst$$reg), 12842 as_Register($src$$reg), lshift, width); 12843 %} 12844 ins_pipe(ialu_reg_shift); 12845 %} 12846 12847 // This pattern is automatically generated from aarch64_ad.m4 12848 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12849 12850 // We can use ubfiz when masking by a positive number and then left shifting the result. 12851 // We know that the mask is positive because immL_bitmask guarantees it. 12852 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 12853 %{ 12854 match(Set dst (LShiftL (AndL src mask) lshift)); 12855 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12856 12857 ins_cost(INSN_COST); 12858 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12859 ins_encode %{ 12860 int lshift = $lshift$$constant & 63; 12861 intptr_t mask = $mask$$constant; 12862 int width = exact_log2_long(mask+1); 12863 __ ubfiz(as_Register($dst$$reg), 12864 as_Register($src$$reg), lshift, width); 12865 %} 12866 ins_pipe(ialu_reg_shift); 12867 %} 12868 12869 // This pattern is automatically generated from aarch64_ad.m4 12870 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12871 12872 // We can use ubfiz when masking by a positive number and then left shifting the result. 12873 // We know that the mask is positive because immI_bitmask guarantees it. 12874 instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12875 %{ 12876 match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift))); 12877 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31); 12878 12879 ins_cost(INSN_COST); 12880 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12881 ins_encode %{ 12882 int lshift = $lshift$$constant & 31; 12883 intptr_t mask = $mask$$constant; 12884 int width = exact_log2(mask+1); 12885 __ ubfizw(as_Register($dst$$reg), 12886 as_Register($src$$reg), lshift, width); 12887 %} 12888 ins_pipe(ialu_reg_shift); 12889 %} 12890 12891 // This pattern is automatically generated from aarch64_ad.m4 12892 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12893 12894 // We can use ubfiz when masking by a positive number and then left shifting the result. 12895 // We know that the mask is positive because immL_bitmask guarantees it. 12896 instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12897 %{ 12898 match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift))); 12899 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31); 12900 12901 ins_cost(INSN_COST); 12902 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12903 ins_encode %{ 12904 int lshift = $lshift$$constant & 63; 12905 intptr_t mask = $mask$$constant; 12906 int width = exact_log2_long(mask+1); 12907 __ ubfiz(as_Register($dst$$reg), 12908 as_Register($src$$reg), lshift, width); 12909 %} 12910 ins_pipe(ialu_reg_shift); 12911 %} 12912 12913 12914 // This pattern is automatically generated from aarch64_ad.m4 12915 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12916 12917 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 12918 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12919 %{ 12920 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 12921 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12922 12923 ins_cost(INSN_COST); 12924 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12925 ins_encode %{ 12926 int lshift = $lshift$$constant & 63; 12927 intptr_t mask = $mask$$constant; 12928 int width = exact_log2(mask+1); 12929 __ ubfiz(as_Register($dst$$reg), 12930 as_Register($src$$reg), lshift, width); 12931 %} 12932 ins_pipe(ialu_reg_shift); 12933 %} 12934 12935 // This pattern is automatically generated from aarch64_ad.m4 12936 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12937 12938 // If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz 12939 instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12940 %{ 12941 match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift)); 12942 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31); 12943 12944 ins_cost(INSN_COST); 12945 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12946 ins_encode %{ 12947 int lshift = $lshift$$constant & 31; 12948 intptr_t mask = $mask$$constant; 12949 int width = exact_log2(mask+1); 12950 __ ubfiz(as_Register($dst$$reg), 12951 as_Register($src$$reg), lshift, width); 12952 %} 12953 ins_pipe(ialu_reg_shift); 12954 %} 12955 12956 // This pattern is automatically generated from aarch64_ad.m4 12957 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12958 12959 // Can skip int2long conversions after AND with small bitmask 12960 instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk) 12961 %{ 12962 match(Set dst (ConvI2L (AndI src msk))); 12963 ins_cost(INSN_COST); 12964 format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %} 12965 ins_encode %{ 12966 __ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1)); 12967 %} 12968 ins_pipe(ialu_reg_shift); 12969 %} 12970 12971 12972 // Rotations 12973 12974 // This pattern is automatically generated from aarch64_ad.m4 12975 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12976 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12977 %{ 12978 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12979 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12980 12981 ins_cost(INSN_COST); 12982 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12983 12984 ins_encode %{ 12985 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12986 $rshift$$constant & 63); 12987 %} 12988 ins_pipe(ialu_reg_reg_extr); 12989 %} 12990 12991 12992 // This pattern is automatically generated from aarch64_ad.m4 12993 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12994 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12995 %{ 12996 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12997 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12998 12999 ins_cost(INSN_COST); 13000 format %{ "extr $dst, $src1, $src2, #$rshift" %} 13001 13002 ins_encode %{ 13003 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 13004 $rshift$$constant & 31); 13005 %} 13006 ins_pipe(ialu_reg_reg_extr); 13007 %} 13008 13009 13010 // This pattern is automatically generated from aarch64_ad.m4 13011 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13012 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 13013 %{ 13014 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 13015 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 13016 13017 ins_cost(INSN_COST); 13018 format %{ "extr $dst, $src1, $src2, #$rshift" %} 13019 13020 ins_encode %{ 13021 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 13022 $rshift$$constant & 63); 13023 %} 13024 ins_pipe(ialu_reg_reg_extr); 13025 %} 13026 13027 13028 // This pattern is automatically generated from aarch64_ad.m4 13029 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13030 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 13031 %{ 13032 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 13033 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 13034 13035 ins_cost(INSN_COST); 13036 format %{ "extr $dst, $src1, $src2, #$rshift" %} 13037 13038 ins_encode %{ 13039 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 13040 $rshift$$constant & 31); 13041 %} 13042 ins_pipe(ialu_reg_reg_extr); 13043 %} 13044 13045 // This pattern is automatically generated from aarch64_ad.m4 13046 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13047 instruct rorI_imm(iRegINoSp dst, iRegI src, immI shift) 13048 %{ 13049 match(Set dst (RotateRight src shift)); 13050 13051 ins_cost(INSN_COST); 13052 format %{ "ror $dst, $src, $shift" %} 13053 13054 ins_encode %{ 13055 __ extrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg), 13056 $shift$$constant & 0x1f); 13057 %} 13058 ins_pipe(ialu_reg_reg_vshift); 13059 %} 13060 13061 // This pattern is automatically generated from aarch64_ad.m4 13062 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13063 instruct rorL_imm(iRegLNoSp dst, iRegL src, immI shift) 13064 %{ 13065 match(Set dst (RotateRight src shift)); 13066 13067 ins_cost(INSN_COST); 13068 format %{ "ror $dst, $src, $shift" %} 13069 13070 ins_encode %{ 13071 __ extr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg), 13072 $shift$$constant & 0x3f); 13073 %} 13074 ins_pipe(ialu_reg_reg_vshift); 13075 %} 13076 13077 // This pattern is automatically generated from aarch64_ad.m4 13078 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13079 instruct rorI_reg(iRegINoSp dst, iRegI src, iRegI shift) 13080 %{ 13081 match(Set dst (RotateRight src shift)); 13082 13083 ins_cost(INSN_COST); 13084 format %{ "ror $dst, $src, $shift" %} 13085 13086 ins_encode %{ 13087 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); 13088 %} 13089 ins_pipe(ialu_reg_reg_vshift); 13090 %} 13091 13092 // This pattern is automatically generated from aarch64_ad.m4 13093 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13094 instruct rorL_reg(iRegLNoSp dst, iRegL src, iRegI shift) 13095 %{ 13096 match(Set dst (RotateRight src shift)); 13097 13098 ins_cost(INSN_COST); 13099 format %{ "ror $dst, $src, $shift" %} 13100 13101 ins_encode %{ 13102 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); 13103 %} 13104 ins_pipe(ialu_reg_reg_vshift); 13105 %} 13106 13107 // This pattern is automatically generated from aarch64_ad.m4 13108 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13109 instruct rolI_reg(iRegINoSp dst, iRegI src, iRegI shift) 13110 %{ 13111 match(Set dst (RotateLeft src shift)); 13112 13113 ins_cost(INSN_COST); 13114 format %{ "rol $dst, $src, $shift" %} 13115 13116 ins_encode %{ 13117 __ subw(rscratch1, zr, as_Register($shift$$reg)); 13118 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), rscratch1); 13119 %} 13120 ins_pipe(ialu_reg_reg_vshift); 13121 %} 13122 13123 // This pattern is automatically generated from aarch64_ad.m4 13124 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13125 instruct rolL_reg(iRegLNoSp dst, iRegL src, iRegI shift) 13126 %{ 13127 match(Set dst (RotateLeft src shift)); 13128 13129 ins_cost(INSN_COST); 13130 format %{ "rol $dst, $src, $shift" %} 13131 13132 ins_encode %{ 13133 __ subw(rscratch1, zr, as_Register($shift$$reg)); 13134 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), rscratch1); 13135 %} 13136 ins_pipe(ialu_reg_reg_vshift); 13137 %} 13138 13139 13140 // Add/subtract (extended) 13141 13142 // This pattern is automatically generated from aarch64_ad.m4 13143 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13144 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 13145 %{ 13146 match(Set dst (AddL src1 (ConvI2L src2))); 13147 ins_cost(INSN_COST); 13148 format %{ "add $dst, $src1, $src2, sxtw" %} 13149 13150 ins_encode %{ 13151 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13152 as_Register($src2$$reg), ext::sxtw); 13153 %} 13154 ins_pipe(ialu_reg_reg); 13155 %} 13156 13157 // This pattern is automatically generated from aarch64_ad.m4 13158 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13159 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 13160 %{ 13161 match(Set dst (SubL src1 (ConvI2L src2))); 13162 ins_cost(INSN_COST); 13163 format %{ "sub $dst, $src1, $src2, sxtw" %} 13164 13165 ins_encode %{ 13166 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13167 as_Register($src2$$reg), ext::sxtw); 13168 %} 13169 ins_pipe(ialu_reg_reg); 13170 %} 13171 13172 // This pattern is automatically generated from aarch64_ad.m4 13173 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13174 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 13175 %{ 13176 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 13177 ins_cost(INSN_COST); 13178 format %{ "add $dst, $src1, $src2, sxth" %} 13179 13180 ins_encode %{ 13181 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13182 as_Register($src2$$reg), ext::sxth); 13183 %} 13184 ins_pipe(ialu_reg_reg); 13185 %} 13186 13187 // This pattern is automatically generated from aarch64_ad.m4 13188 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13189 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 13190 %{ 13191 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 13192 ins_cost(INSN_COST); 13193 format %{ "add $dst, $src1, $src2, sxtb" %} 13194 13195 ins_encode %{ 13196 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13197 as_Register($src2$$reg), ext::sxtb); 13198 %} 13199 ins_pipe(ialu_reg_reg); 13200 %} 13201 13202 // This pattern is automatically generated from aarch64_ad.m4 13203 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13204 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 13205 %{ 13206 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 13207 ins_cost(INSN_COST); 13208 format %{ "add $dst, $src1, $src2, uxtb" %} 13209 13210 ins_encode %{ 13211 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13212 as_Register($src2$$reg), ext::uxtb); 13213 %} 13214 ins_pipe(ialu_reg_reg); 13215 %} 13216 13217 // This pattern is automatically generated from aarch64_ad.m4 13218 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13219 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 13220 %{ 13221 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13222 ins_cost(INSN_COST); 13223 format %{ "add $dst, $src1, $src2, sxth" %} 13224 13225 ins_encode %{ 13226 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13227 as_Register($src2$$reg), ext::sxth); 13228 %} 13229 ins_pipe(ialu_reg_reg); 13230 %} 13231 13232 // This pattern is automatically generated from aarch64_ad.m4 13233 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13234 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 13235 %{ 13236 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13237 ins_cost(INSN_COST); 13238 format %{ "add $dst, $src1, $src2, sxtw" %} 13239 13240 ins_encode %{ 13241 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13242 as_Register($src2$$reg), ext::sxtw); 13243 %} 13244 ins_pipe(ialu_reg_reg); 13245 %} 13246 13247 // This pattern is automatically generated from aarch64_ad.m4 13248 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13249 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 13250 %{ 13251 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13252 ins_cost(INSN_COST); 13253 format %{ "add $dst, $src1, $src2, sxtb" %} 13254 13255 ins_encode %{ 13256 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13257 as_Register($src2$$reg), ext::sxtb); 13258 %} 13259 ins_pipe(ialu_reg_reg); 13260 %} 13261 13262 // This pattern is automatically generated from aarch64_ad.m4 13263 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13264 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 13265 %{ 13266 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 13267 ins_cost(INSN_COST); 13268 format %{ "add $dst, $src1, $src2, uxtb" %} 13269 13270 ins_encode %{ 13271 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13272 as_Register($src2$$reg), ext::uxtb); 13273 %} 13274 ins_pipe(ialu_reg_reg); 13275 %} 13276 13277 // This pattern is automatically generated from aarch64_ad.m4 13278 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13279 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 13280 %{ 13281 match(Set dst (AddI src1 (AndI src2 mask))); 13282 ins_cost(INSN_COST); 13283 format %{ "addw $dst, $src1, $src2, uxtb" %} 13284 13285 ins_encode %{ 13286 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13287 as_Register($src2$$reg), ext::uxtb); 13288 %} 13289 ins_pipe(ialu_reg_reg); 13290 %} 13291 13292 // This pattern is automatically generated from aarch64_ad.m4 13293 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13294 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 13295 %{ 13296 match(Set dst (AddI src1 (AndI src2 mask))); 13297 ins_cost(INSN_COST); 13298 format %{ "addw $dst, $src1, $src2, uxth" %} 13299 13300 ins_encode %{ 13301 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13302 as_Register($src2$$reg), ext::uxth); 13303 %} 13304 ins_pipe(ialu_reg_reg); 13305 %} 13306 13307 // This pattern is automatically generated from aarch64_ad.m4 13308 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13309 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 13310 %{ 13311 match(Set dst (AddL src1 (AndL src2 mask))); 13312 ins_cost(INSN_COST); 13313 format %{ "add $dst, $src1, $src2, uxtb" %} 13314 13315 ins_encode %{ 13316 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13317 as_Register($src2$$reg), ext::uxtb); 13318 %} 13319 ins_pipe(ialu_reg_reg); 13320 %} 13321 13322 // This pattern is automatically generated from aarch64_ad.m4 13323 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13324 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 13325 %{ 13326 match(Set dst (AddL src1 (AndL src2 mask))); 13327 ins_cost(INSN_COST); 13328 format %{ "add $dst, $src1, $src2, uxth" %} 13329 13330 ins_encode %{ 13331 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13332 as_Register($src2$$reg), ext::uxth); 13333 %} 13334 ins_pipe(ialu_reg_reg); 13335 %} 13336 13337 // This pattern is automatically generated from aarch64_ad.m4 13338 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13339 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 13340 %{ 13341 match(Set dst (AddL src1 (AndL src2 mask))); 13342 ins_cost(INSN_COST); 13343 format %{ "add $dst, $src1, $src2, uxtw" %} 13344 13345 ins_encode %{ 13346 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13347 as_Register($src2$$reg), ext::uxtw); 13348 %} 13349 ins_pipe(ialu_reg_reg); 13350 %} 13351 13352 // This pattern is automatically generated from aarch64_ad.m4 13353 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13354 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 13355 %{ 13356 match(Set dst (SubI src1 (AndI src2 mask))); 13357 ins_cost(INSN_COST); 13358 format %{ "subw $dst, $src1, $src2, uxtb" %} 13359 13360 ins_encode %{ 13361 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13362 as_Register($src2$$reg), ext::uxtb); 13363 %} 13364 ins_pipe(ialu_reg_reg); 13365 %} 13366 13367 // This pattern is automatically generated from aarch64_ad.m4 13368 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13369 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 13370 %{ 13371 match(Set dst (SubI src1 (AndI src2 mask))); 13372 ins_cost(INSN_COST); 13373 format %{ "subw $dst, $src1, $src2, uxth" %} 13374 13375 ins_encode %{ 13376 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13377 as_Register($src2$$reg), ext::uxth); 13378 %} 13379 ins_pipe(ialu_reg_reg); 13380 %} 13381 13382 // This pattern is automatically generated from aarch64_ad.m4 13383 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13384 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 13385 %{ 13386 match(Set dst (SubL src1 (AndL src2 mask))); 13387 ins_cost(INSN_COST); 13388 format %{ "sub $dst, $src1, $src2, uxtb" %} 13389 13390 ins_encode %{ 13391 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13392 as_Register($src2$$reg), ext::uxtb); 13393 %} 13394 ins_pipe(ialu_reg_reg); 13395 %} 13396 13397 // This pattern is automatically generated from aarch64_ad.m4 13398 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13399 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 13400 %{ 13401 match(Set dst (SubL src1 (AndL src2 mask))); 13402 ins_cost(INSN_COST); 13403 format %{ "sub $dst, $src1, $src2, uxth" %} 13404 13405 ins_encode %{ 13406 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13407 as_Register($src2$$reg), ext::uxth); 13408 %} 13409 ins_pipe(ialu_reg_reg); 13410 %} 13411 13412 // This pattern is automatically generated from aarch64_ad.m4 13413 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13414 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 13415 %{ 13416 match(Set dst (SubL src1 (AndL src2 mask))); 13417 ins_cost(INSN_COST); 13418 format %{ "sub $dst, $src1, $src2, uxtw" %} 13419 13420 ins_encode %{ 13421 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13422 as_Register($src2$$reg), ext::uxtw); 13423 %} 13424 ins_pipe(ialu_reg_reg); 13425 %} 13426 13427 13428 // This pattern is automatically generated from aarch64_ad.m4 13429 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13430 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 13431 %{ 13432 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13433 ins_cost(1.9 * INSN_COST); 13434 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 13435 13436 ins_encode %{ 13437 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13438 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13439 %} 13440 ins_pipe(ialu_reg_reg_shift); 13441 %} 13442 13443 // This pattern is automatically generated from aarch64_ad.m4 13444 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13445 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 13446 %{ 13447 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13448 ins_cost(1.9 * INSN_COST); 13449 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 13450 13451 ins_encode %{ 13452 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13453 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13454 %} 13455 ins_pipe(ialu_reg_reg_shift); 13456 %} 13457 13458 // This pattern is automatically generated from aarch64_ad.m4 13459 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13460 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 13461 %{ 13462 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13463 ins_cost(1.9 * INSN_COST); 13464 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 13465 13466 ins_encode %{ 13467 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13468 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 13469 %} 13470 ins_pipe(ialu_reg_reg_shift); 13471 %} 13472 13473 // This pattern is automatically generated from aarch64_ad.m4 13474 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13475 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 13476 %{ 13477 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13478 ins_cost(1.9 * INSN_COST); 13479 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 13480 13481 ins_encode %{ 13482 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13483 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13484 %} 13485 ins_pipe(ialu_reg_reg_shift); 13486 %} 13487 13488 // This pattern is automatically generated from aarch64_ad.m4 13489 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13490 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 13491 %{ 13492 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13493 ins_cost(1.9 * INSN_COST); 13494 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 13495 13496 ins_encode %{ 13497 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13498 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13499 %} 13500 ins_pipe(ialu_reg_reg_shift); 13501 %} 13502 13503 // This pattern is automatically generated from aarch64_ad.m4 13504 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13505 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 13506 %{ 13507 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13508 ins_cost(1.9 * INSN_COST); 13509 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 13510 13511 ins_encode %{ 13512 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13513 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 13514 %} 13515 ins_pipe(ialu_reg_reg_shift); 13516 %} 13517 13518 // This pattern is automatically generated from aarch64_ad.m4 13519 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13520 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 13521 %{ 13522 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13523 ins_cost(1.9 * INSN_COST); 13524 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 13525 13526 ins_encode %{ 13527 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13528 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13529 %} 13530 ins_pipe(ialu_reg_reg_shift); 13531 %} 13532 13533 // This pattern is automatically generated from aarch64_ad.m4 13534 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13535 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 13536 %{ 13537 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13538 ins_cost(1.9 * INSN_COST); 13539 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 13540 13541 ins_encode %{ 13542 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13543 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13544 %} 13545 ins_pipe(ialu_reg_reg_shift); 13546 %} 13547 13548 // This pattern is automatically generated from aarch64_ad.m4 13549 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13550 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 13551 %{ 13552 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13553 ins_cost(1.9 * INSN_COST); 13554 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 13555 13556 ins_encode %{ 13557 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13558 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13559 %} 13560 ins_pipe(ialu_reg_reg_shift); 13561 %} 13562 13563 // This pattern is automatically generated from aarch64_ad.m4 13564 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13565 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 13566 %{ 13567 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13568 ins_cost(1.9 * INSN_COST); 13569 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 13570 13571 ins_encode %{ 13572 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13573 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13574 %} 13575 ins_pipe(ialu_reg_reg_shift); 13576 %} 13577 13578 // This pattern is automatically generated from aarch64_ad.m4 13579 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13580 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 13581 %{ 13582 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 13583 ins_cost(1.9 * INSN_COST); 13584 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 13585 13586 ins_encode %{ 13587 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13588 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 13589 %} 13590 ins_pipe(ialu_reg_reg_shift); 13591 %} 13592 13593 // This pattern is automatically generated from aarch64_ad.m4 13594 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13595 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 13596 %{ 13597 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 13598 ins_cost(1.9 * INSN_COST); 13599 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 13600 13601 ins_encode %{ 13602 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13603 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 13604 %} 13605 ins_pipe(ialu_reg_reg_shift); 13606 %} 13607 13608 // This pattern is automatically generated from aarch64_ad.m4 13609 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13610 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 13611 %{ 13612 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13613 ins_cost(1.9 * INSN_COST); 13614 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 13615 13616 ins_encode %{ 13617 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13618 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13619 %} 13620 ins_pipe(ialu_reg_reg_shift); 13621 %} 13622 13623 // This pattern is automatically generated from aarch64_ad.m4 13624 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13625 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 13626 %{ 13627 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13628 ins_cost(1.9 * INSN_COST); 13629 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 13630 13631 ins_encode %{ 13632 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13633 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13634 %} 13635 ins_pipe(ialu_reg_reg_shift); 13636 %} 13637 13638 // This pattern is automatically generated from aarch64_ad.m4 13639 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13640 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13641 %{ 13642 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13643 ins_cost(1.9 * INSN_COST); 13644 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 13645 13646 ins_encode %{ 13647 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13648 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13649 %} 13650 ins_pipe(ialu_reg_reg_shift); 13651 %} 13652 13653 // This pattern is automatically generated from aarch64_ad.m4 13654 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13655 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 13656 %{ 13657 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13658 ins_cost(1.9 * INSN_COST); 13659 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 13660 13661 ins_encode %{ 13662 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13663 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13664 %} 13665 ins_pipe(ialu_reg_reg_shift); 13666 %} 13667 13668 // This pattern is automatically generated from aarch64_ad.m4 13669 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13670 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 13671 %{ 13672 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13673 ins_cost(1.9 * INSN_COST); 13674 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 13675 13676 ins_encode %{ 13677 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13678 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13679 %} 13680 ins_pipe(ialu_reg_reg_shift); 13681 %} 13682 13683 // This pattern is automatically generated from aarch64_ad.m4 13684 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13685 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13686 %{ 13687 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13688 ins_cost(1.9 * INSN_COST); 13689 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 13690 13691 ins_encode %{ 13692 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13693 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13694 %} 13695 ins_pipe(ialu_reg_reg_shift); 13696 %} 13697 13698 // This pattern is automatically generated from aarch64_ad.m4 13699 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13700 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13701 %{ 13702 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13703 ins_cost(1.9 * INSN_COST); 13704 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 13705 13706 ins_encode %{ 13707 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13708 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13709 %} 13710 ins_pipe(ialu_reg_reg_shift); 13711 %} 13712 13713 // This pattern is automatically generated from aarch64_ad.m4 13714 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13715 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13716 %{ 13717 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13718 ins_cost(1.9 * INSN_COST); 13719 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 13720 13721 ins_encode %{ 13722 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13723 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13724 %} 13725 ins_pipe(ialu_reg_reg_shift); 13726 %} 13727 13728 // This pattern is automatically generated from aarch64_ad.m4 13729 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13730 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13731 %{ 13732 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13733 ins_cost(1.9 * INSN_COST); 13734 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 13735 13736 ins_encode %{ 13737 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13738 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13739 %} 13740 ins_pipe(ialu_reg_reg_shift); 13741 %} 13742 13743 // This pattern is automatically generated from aarch64_ad.m4 13744 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13745 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13746 %{ 13747 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13748 ins_cost(1.9 * INSN_COST); 13749 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 13750 13751 ins_encode %{ 13752 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13753 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13754 %} 13755 ins_pipe(ialu_reg_reg_shift); 13756 %} 13757 13758 // This pattern is automatically generated from aarch64_ad.m4 13759 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13760 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13761 %{ 13762 effect(DEF dst, USE src1, USE src2, USE cr); 13763 ins_cost(INSN_COST * 2); 13764 format %{ "cselw $dst, $src1, $src2 lt\t" %} 13765 13766 ins_encode %{ 13767 __ cselw($dst$$Register, 13768 $src1$$Register, 13769 $src2$$Register, 13770 Assembler::LT); 13771 %} 13772 ins_pipe(icond_reg_reg); 13773 %} 13774 13775 // This pattern is automatically generated from aarch64_ad.m4 13776 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13777 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13778 %{ 13779 effect(DEF dst, USE src1, USE src2, USE cr); 13780 ins_cost(INSN_COST * 2); 13781 format %{ "cselw $dst, $src1, $src2 gt\t" %} 13782 13783 ins_encode %{ 13784 __ cselw($dst$$Register, 13785 $src1$$Register, 13786 $src2$$Register, 13787 Assembler::GT); 13788 %} 13789 ins_pipe(icond_reg_reg); 13790 %} 13791 13792 // This pattern is automatically generated from aarch64_ad.m4 13793 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13794 instruct cmovI_reg_imm0_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13795 %{ 13796 effect(DEF dst, USE src1, USE cr); 13797 ins_cost(INSN_COST * 2); 13798 format %{ "cselw $dst, $src1, zr lt\t" %} 13799 13800 ins_encode %{ 13801 __ cselw($dst$$Register, 13802 $src1$$Register, 13803 zr, 13804 Assembler::LT); 13805 %} 13806 ins_pipe(icond_reg); 13807 %} 13808 13809 // This pattern is automatically generated from aarch64_ad.m4 13810 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13811 instruct cmovI_reg_imm0_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13812 %{ 13813 effect(DEF dst, USE src1, USE cr); 13814 ins_cost(INSN_COST * 2); 13815 format %{ "cselw $dst, $src1, zr gt\t" %} 13816 13817 ins_encode %{ 13818 __ cselw($dst$$Register, 13819 $src1$$Register, 13820 zr, 13821 Assembler::GT); 13822 %} 13823 ins_pipe(icond_reg); 13824 %} 13825 13826 // This pattern is automatically generated from aarch64_ad.m4 13827 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13828 instruct cmovI_reg_imm1_le(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13829 %{ 13830 effect(DEF dst, USE src1, USE cr); 13831 ins_cost(INSN_COST * 2); 13832 format %{ "csincw $dst, $src1, zr le\t" %} 13833 13834 ins_encode %{ 13835 __ csincw($dst$$Register, 13836 $src1$$Register, 13837 zr, 13838 Assembler::LE); 13839 %} 13840 ins_pipe(icond_reg); 13841 %} 13842 13843 // This pattern is automatically generated from aarch64_ad.m4 13844 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13845 instruct cmovI_reg_imm1_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13846 %{ 13847 effect(DEF dst, USE src1, USE cr); 13848 ins_cost(INSN_COST * 2); 13849 format %{ "csincw $dst, $src1, zr gt\t" %} 13850 13851 ins_encode %{ 13852 __ csincw($dst$$Register, 13853 $src1$$Register, 13854 zr, 13855 Assembler::GT); 13856 %} 13857 ins_pipe(icond_reg); 13858 %} 13859 13860 // This pattern is automatically generated from aarch64_ad.m4 13861 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13862 instruct cmovI_reg_immM1_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13863 %{ 13864 effect(DEF dst, USE src1, USE cr); 13865 ins_cost(INSN_COST * 2); 13866 format %{ "csinvw $dst, $src1, zr lt\t" %} 13867 13868 ins_encode %{ 13869 __ csinvw($dst$$Register, 13870 $src1$$Register, 13871 zr, 13872 Assembler::LT); 13873 %} 13874 ins_pipe(icond_reg); 13875 %} 13876 13877 // This pattern is automatically generated from aarch64_ad.m4 13878 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13879 instruct cmovI_reg_immM1_ge(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13880 %{ 13881 effect(DEF dst, USE src1, USE cr); 13882 ins_cost(INSN_COST * 2); 13883 format %{ "csinvw $dst, $src1, zr ge\t" %} 13884 13885 ins_encode %{ 13886 __ csinvw($dst$$Register, 13887 $src1$$Register, 13888 zr, 13889 Assembler::GE); 13890 %} 13891 ins_pipe(icond_reg); 13892 %} 13893 13894 // This pattern is automatically generated from aarch64_ad.m4 13895 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13896 instruct minI_reg_imm0(iRegINoSp dst, iRegIorL2I src, immI0 imm) 13897 %{ 13898 match(Set dst (MinI src imm)); 13899 ins_cost(INSN_COST * 3); 13900 expand %{ 13901 rFlagsReg cr; 13902 compI_reg_imm0(cr, src); 13903 cmovI_reg_imm0_lt(dst, src, cr); 13904 %} 13905 %} 13906 13907 // This pattern is automatically generated from aarch64_ad.m4 13908 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13909 instruct minI_imm0_reg(iRegINoSp dst, immI0 imm, iRegIorL2I src) 13910 %{ 13911 match(Set dst (MinI imm src)); 13912 ins_cost(INSN_COST * 3); 13913 expand %{ 13914 rFlagsReg cr; 13915 compI_reg_imm0(cr, src); 13916 cmovI_reg_imm0_lt(dst, src, cr); 13917 %} 13918 %} 13919 13920 // This pattern is automatically generated from aarch64_ad.m4 13921 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13922 instruct minI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm) 13923 %{ 13924 match(Set dst (MinI src imm)); 13925 ins_cost(INSN_COST * 3); 13926 expand %{ 13927 rFlagsReg cr; 13928 compI_reg_imm0(cr, src); 13929 cmovI_reg_imm1_le(dst, src, cr); 13930 %} 13931 %} 13932 13933 // This pattern is automatically generated from aarch64_ad.m4 13934 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13935 instruct minI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src) 13936 %{ 13937 match(Set dst (MinI imm src)); 13938 ins_cost(INSN_COST * 3); 13939 expand %{ 13940 rFlagsReg cr; 13941 compI_reg_imm0(cr, src); 13942 cmovI_reg_imm1_le(dst, src, cr); 13943 %} 13944 %} 13945 13946 // This pattern is automatically generated from aarch64_ad.m4 13947 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13948 instruct minI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm) 13949 %{ 13950 match(Set dst (MinI src imm)); 13951 ins_cost(INSN_COST * 3); 13952 expand %{ 13953 rFlagsReg cr; 13954 compI_reg_imm0(cr, src); 13955 cmovI_reg_immM1_lt(dst, src, cr); 13956 %} 13957 %} 13958 13959 // This pattern is automatically generated from aarch64_ad.m4 13960 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13961 instruct minI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src) 13962 %{ 13963 match(Set dst (MinI imm src)); 13964 ins_cost(INSN_COST * 3); 13965 expand %{ 13966 rFlagsReg cr; 13967 compI_reg_imm0(cr, src); 13968 cmovI_reg_immM1_lt(dst, src, cr); 13969 %} 13970 %} 13971 13972 // This pattern is automatically generated from aarch64_ad.m4 13973 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13974 instruct maxI_reg_imm0(iRegINoSp dst, iRegIorL2I src, immI0 imm) 13975 %{ 13976 match(Set dst (MaxI src imm)); 13977 ins_cost(INSN_COST * 3); 13978 expand %{ 13979 rFlagsReg cr; 13980 compI_reg_imm0(cr, src); 13981 cmovI_reg_imm0_gt(dst, src, cr); 13982 %} 13983 %} 13984 13985 // This pattern is automatically generated from aarch64_ad.m4 13986 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13987 instruct maxI_imm0_reg(iRegINoSp dst, immI0 imm, iRegIorL2I src) 13988 %{ 13989 match(Set dst (MaxI imm src)); 13990 ins_cost(INSN_COST * 3); 13991 expand %{ 13992 rFlagsReg cr; 13993 compI_reg_imm0(cr, src); 13994 cmovI_reg_imm0_gt(dst, src, cr); 13995 %} 13996 %} 13997 13998 // This pattern is automatically generated from aarch64_ad.m4 13999 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14000 instruct maxI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm) 14001 %{ 14002 match(Set dst (MaxI src imm)); 14003 ins_cost(INSN_COST * 3); 14004 expand %{ 14005 rFlagsReg cr; 14006 compI_reg_imm0(cr, src); 14007 cmovI_reg_imm1_gt(dst, src, cr); 14008 %} 14009 %} 14010 14011 // This pattern is automatically generated from aarch64_ad.m4 14012 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14013 instruct maxI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src) 14014 %{ 14015 match(Set dst (MaxI imm src)); 14016 ins_cost(INSN_COST * 3); 14017 expand %{ 14018 rFlagsReg cr; 14019 compI_reg_imm0(cr, src); 14020 cmovI_reg_imm1_gt(dst, src, cr); 14021 %} 14022 %} 14023 14024 // This pattern is automatically generated from aarch64_ad.m4 14025 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14026 instruct maxI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm) 14027 %{ 14028 match(Set dst (MaxI src imm)); 14029 ins_cost(INSN_COST * 3); 14030 expand %{ 14031 rFlagsReg cr; 14032 compI_reg_imm0(cr, src); 14033 cmovI_reg_immM1_ge(dst, src, cr); 14034 %} 14035 %} 14036 14037 // This pattern is automatically generated from aarch64_ad.m4 14038 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14039 instruct maxI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src) 14040 %{ 14041 match(Set dst (MaxI imm src)); 14042 ins_cost(INSN_COST * 3); 14043 expand %{ 14044 rFlagsReg cr; 14045 compI_reg_imm0(cr, src); 14046 cmovI_reg_immM1_ge(dst, src, cr); 14047 %} 14048 %} 14049 14050 // This pattern is automatically generated from aarch64_ad.m4 14051 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14052 instruct bits_reverse_I(iRegINoSp dst, iRegIorL2I src) 14053 %{ 14054 match(Set dst (ReverseI src)); 14055 ins_cost(INSN_COST); 14056 format %{ "rbitw $dst, $src" %} 14057 ins_encode %{ 14058 __ rbitw($dst$$Register, $src$$Register); 14059 %} 14060 ins_pipe(ialu_reg); 14061 %} 14062 14063 // This pattern is automatically generated from aarch64_ad.m4 14064 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14065 instruct bits_reverse_L(iRegLNoSp dst, iRegL src) 14066 %{ 14067 match(Set dst (ReverseL src)); 14068 ins_cost(INSN_COST); 14069 format %{ "rbit $dst, $src" %} 14070 ins_encode %{ 14071 __ rbit($dst$$Register, $src$$Register); 14072 %} 14073 ins_pipe(ialu_reg); 14074 %} 14075 14076 14077 // END This section of the file is automatically generated. Do not edit -------------- 14078 14079 14080 // ============================================================================ 14081 // Floating Point Arithmetic Instructions 14082 14083 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14084 match(Set dst (AddF src1 src2)); 14085 14086 ins_cost(INSN_COST * 5); 14087 format %{ "fadds $dst, $src1, $src2" %} 14088 14089 ins_encode %{ 14090 __ fadds(as_FloatRegister($dst$$reg), 14091 as_FloatRegister($src1$$reg), 14092 as_FloatRegister($src2$$reg)); 14093 %} 14094 14095 ins_pipe(fp_dop_reg_reg_s); 14096 %} 14097 14098 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14099 match(Set dst (AddD src1 src2)); 14100 14101 ins_cost(INSN_COST * 5); 14102 format %{ "faddd $dst, $src1, $src2" %} 14103 14104 ins_encode %{ 14105 __ faddd(as_FloatRegister($dst$$reg), 14106 as_FloatRegister($src1$$reg), 14107 as_FloatRegister($src2$$reg)); 14108 %} 14109 14110 ins_pipe(fp_dop_reg_reg_d); 14111 %} 14112 14113 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14114 match(Set dst (SubF src1 src2)); 14115 14116 ins_cost(INSN_COST * 5); 14117 format %{ "fsubs $dst, $src1, $src2" %} 14118 14119 ins_encode %{ 14120 __ fsubs(as_FloatRegister($dst$$reg), 14121 as_FloatRegister($src1$$reg), 14122 as_FloatRegister($src2$$reg)); 14123 %} 14124 14125 ins_pipe(fp_dop_reg_reg_s); 14126 %} 14127 14128 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14129 match(Set dst (SubD src1 src2)); 14130 14131 ins_cost(INSN_COST * 5); 14132 format %{ "fsubd $dst, $src1, $src2" %} 14133 14134 ins_encode %{ 14135 __ fsubd(as_FloatRegister($dst$$reg), 14136 as_FloatRegister($src1$$reg), 14137 as_FloatRegister($src2$$reg)); 14138 %} 14139 14140 ins_pipe(fp_dop_reg_reg_d); 14141 %} 14142 14143 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14144 match(Set dst (MulF src1 src2)); 14145 14146 ins_cost(INSN_COST * 6); 14147 format %{ "fmuls $dst, $src1, $src2" %} 14148 14149 ins_encode %{ 14150 __ fmuls(as_FloatRegister($dst$$reg), 14151 as_FloatRegister($src1$$reg), 14152 as_FloatRegister($src2$$reg)); 14153 %} 14154 14155 ins_pipe(fp_dop_reg_reg_s); 14156 %} 14157 14158 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14159 match(Set dst (MulD src1 src2)); 14160 14161 ins_cost(INSN_COST * 6); 14162 format %{ "fmuld $dst, $src1, $src2" %} 14163 14164 ins_encode %{ 14165 __ fmuld(as_FloatRegister($dst$$reg), 14166 as_FloatRegister($src1$$reg), 14167 as_FloatRegister($src2$$reg)); 14168 %} 14169 14170 ins_pipe(fp_dop_reg_reg_d); 14171 %} 14172 14173 // src1 * src2 + src3 14174 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 14175 match(Set dst (FmaF src3 (Binary src1 src2))); 14176 14177 format %{ "fmadds $dst, $src1, $src2, $src3" %} 14178 14179 ins_encode %{ 14180 assert(UseFMA, "Needs FMA instructions support."); 14181 __ fmadds(as_FloatRegister($dst$$reg), 14182 as_FloatRegister($src1$$reg), 14183 as_FloatRegister($src2$$reg), 14184 as_FloatRegister($src3$$reg)); 14185 %} 14186 14187 ins_pipe(pipe_class_default); 14188 %} 14189 14190 // src1 * src2 + src3 14191 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 14192 match(Set dst (FmaD src3 (Binary src1 src2))); 14193 14194 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 14195 14196 ins_encode %{ 14197 assert(UseFMA, "Needs FMA instructions support."); 14198 __ fmaddd(as_FloatRegister($dst$$reg), 14199 as_FloatRegister($src1$$reg), 14200 as_FloatRegister($src2$$reg), 14201 as_FloatRegister($src3$$reg)); 14202 %} 14203 14204 ins_pipe(pipe_class_default); 14205 %} 14206 14207 // src1 * (-src2) + src3 14208 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3" 14209 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 14210 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 14211 14212 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 14213 14214 ins_encode %{ 14215 assert(UseFMA, "Needs FMA instructions support."); 14216 __ fmsubs(as_FloatRegister($dst$$reg), 14217 as_FloatRegister($src1$$reg), 14218 as_FloatRegister($src2$$reg), 14219 as_FloatRegister($src3$$reg)); 14220 %} 14221 14222 ins_pipe(pipe_class_default); 14223 %} 14224 14225 // src1 * (-src2) + src3 14226 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3" 14227 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 14228 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 14229 14230 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 14231 14232 ins_encode %{ 14233 assert(UseFMA, "Needs FMA instructions support."); 14234 __ fmsubd(as_FloatRegister($dst$$reg), 14235 as_FloatRegister($src1$$reg), 14236 as_FloatRegister($src2$$reg), 14237 as_FloatRegister($src3$$reg)); 14238 %} 14239 14240 ins_pipe(pipe_class_default); 14241 %} 14242 14243 // src1 * (-src2) - src3 14244 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3" 14245 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 14246 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 14247 14248 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 14249 14250 ins_encode %{ 14251 assert(UseFMA, "Needs FMA instructions support."); 14252 __ fnmadds(as_FloatRegister($dst$$reg), 14253 as_FloatRegister($src1$$reg), 14254 as_FloatRegister($src2$$reg), 14255 as_FloatRegister($src3$$reg)); 14256 %} 14257 14258 ins_pipe(pipe_class_default); 14259 %} 14260 14261 // src1 * (-src2) - src3 14262 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3" 14263 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 14264 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 14265 14266 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 14267 14268 ins_encode %{ 14269 assert(UseFMA, "Needs FMA instructions support."); 14270 __ fnmaddd(as_FloatRegister($dst$$reg), 14271 as_FloatRegister($src1$$reg), 14272 as_FloatRegister($src2$$reg), 14273 as_FloatRegister($src3$$reg)); 14274 %} 14275 14276 ins_pipe(pipe_class_default); 14277 %} 14278 14279 // src1 * src2 - src3 14280 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 14281 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 14282 14283 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 14284 14285 ins_encode %{ 14286 assert(UseFMA, "Needs FMA instructions support."); 14287 __ fnmsubs(as_FloatRegister($dst$$reg), 14288 as_FloatRegister($src1$$reg), 14289 as_FloatRegister($src2$$reg), 14290 as_FloatRegister($src3$$reg)); 14291 %} 14292 14293 ins_pipe(pipe_class_default); 14294 %} 14295 14296 // src1 * src2 - src3 14297 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 14298 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 14299 14300 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 14301 14302 ins_encode %{ 14303 assert(UseFMA, "Needs FMA instructions support."); 14304 // n.b. insn name should be fnmsubd 14305 __ fnmsub(as_FloatRegister($dst$$reg), 14306 as_FloatRegister($src1$$reg), 14307 as_FloatRegister($src2$$reg), 14308 as_FloatRegister($src3$$reg)); 14309 %} 14310 14311 ins_pipe(pipe_class_default); 14312 %} 14313 14314 14315 // Math.max(FF)F 14316 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14317 match(Set dst (MaxF src1 src2)); 14318 14319 format %{ "fmaxs $dst, $src1, $src2" %} 14320 ins_encode %{ 14321 __ fmaxs(as_FloatRegister($dst$$reg), 14322 as_FloatRegister($src1$$reg), 14323 as_FloatRegister($src2$$reg)); 14324 %} 14325 14326 ins_pipe(fp_dop_reg_reg_s); 14327 %} 14328 14329 // Math.min(FF)F 14330 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14331 match(Set dst (MinF src1 src2)); 14332 14333 format %{ "fmins $dst, $src1, $src2" %} 14334 ins_encode %{ 14335 __ fmins(as_FloatRegister($dst$$reg), 14336 as_FloatRegister($src1$$reg), 14337 as_FloatRegister($src2$$reg)); 14338 %} 14339 14340 ins_pipe(fp_dop_reg_reg_s); 14341 %} 14342 14343 // Math.max(DD)D 14344 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14345 match(Set dst (MaxD src1 src2)); 14346 14347 format %{ "fmaxd $dst, $src1, $src2" %} 14348 ins_encode %{ 14349 __ fmaxd(as_FloatRegister($dst$$reg), 14350 as_FloatRegister($src1$$reg), 14351 as_FloatRegister($src2$$reg)); 14352 %} 14353 14354 ins_pipe(fp_dop_reg_reg_d); 14355 %} 14356 14357 // Math.min(DD)D 14358 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14359 match(Set dst (MinD src1 src2)); 14360 14361 format %{ "fmind $dst, $src1, $src2" %} 14362 ins_encode %{ 14363 __ fmind(as_FloatRegister($dst$$reg), 14364 as_FloatRegister($src1$$reg), 14365 as_FloatRegister($src2$$reg)); 14366 %} 14367 14368 ins_pipe(fp_dop_reg_reg_d); 14369 %} 14370 14371 14372 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14373 match(Set dst (DivF src1 src2)); 14374 14375 ins_cost(INSN_COST * 18); 14376 format %{ "fdivs $dst, $src1, $src2" %} 14377 14378 ins_encode %{ 14379 __ fdivs(as_FloatRegister($dst$$reg), 14380 as_FloatRegister($src1$$reg), 14381 as_FloatRegister($src2$$reg)); 14382 %} 14383 14384 ins_pipe(fp_div_s); 14385 %} 14386 14387 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14388 match(Set dst (DivD src1 src2)); 14389 14390 ins_cost(INSN_COST * 32); 14391 format %{ "fdivd $dst, $src1, $src2" %} 14392 14393 ins_encode %{ 14394 __ fdivd(as_FloatRegister($dst$$reg), 14395 as_FloatRegister($src1$$reg), 14396 as_FloatRegister($src2$$reg)); 14397 %} 14398 14399 ins_pipe(fp_div_d); 14400 %} 14401 14402 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 14403 match(Set dst (NegF src)); 14404 14405 ins_cost(INSN_COST * 3); 14406 format %{ "fneg $dst, $src" %} 14407 14408 ins_encode %{ 14409 __ fnegs(as_FloatRegister($dst$$reg), 14410 as_FloatRegister($src$$reg)); 14411 %} 14412 14413 ins_pipe(fp_uop_s); 14414 %} 14415 14416 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 14417 match(Set dst (NegD src)); 14418 14419 ins_cost(INSN_COST * 3); 14420 format %{ "fnegd $dst, $src" %} 14421 14422 ins_encode %{ 14423 __ fnegd(as_FloatRegister($dst$$reg), 14424 as_FloatRegister($src$$reg)); 14425 %} 14426 14427 ins_pipe(fp_uop_d); 14428 %} 14429 14430 instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 14431 %{ 14432 match(Set dst (AbsI src)); 14433 14434 effect(KILL cr); 14435 ins_cost(INSN_COST * 2); 14436 format %{ "cmpw $src, zr\n\t" 14437 "cnegw $dst, $src, Assembler::LT\t# int abs" 14438 %} 14439 14440 ins_encode %{ 14441 __ cmpw(as_Register($src$$reg), zr); 14442 __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 14443 %} 14444 ins_pipe(pipe_class_default); 14445 %} 14446 14447 instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr) 14448 %{ 14449 match(Set dst (AbsL src)); 14450 14451 effect(KILL cr); 14452 ins_cost(INSN_COST * 2); 14453 format %{ "cmp $src, zr\n\t" 14454 "cneg $dst, $src, Assembler::LT\t# long abs" 14455 %} 14456 14457 ins_encode %{ 14458 __ cmp(as_Register($src$$reg), zr); 14459 __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 14460 %} 14461 ins_pipe(pipe_class_default); 14462 %} 14463 14464 instruct absF_reg(vRegF dst, vRegF src) %{ 14465 match(Set dst (AbsF src)); 14466 14467 ins_cost(INSN_COST * 3); 14468 format %{ "fabss $dst, $src" %} 14469 ins_encode %{ 14470 __ fabss(as_FloatRegister($dst$$reg), 14471 as_FloatRegister($src$$reg)); 14472 %} 14473 14474 ins_pipe(fp_uop_s); 14475 %} 14476 14477 instruct absD_reg(vRegD dst, vRegD src) %{ 14478 match(Set dst (AbsD src)); 14479 14480 ins_cost(INSN_COST * 3); 14481 format %{ "fabsd $dst, $src" %} 14482 ins_encode %{ 14483 __ fabsd(as_FloatRegister($dst$$reg), 14484 as_FloatRegister($src$$reg)); 14485 %} 14486 14487 ins_pipe(fp_uop_d); 14488 %} 14489 14490 instruct absdF_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14491 match(Set dst (AbsF (SubF src1 src2))); 14492 14493 ins_cost(INSN_COST * 3); 14494 format %{ "fabds $dst, $src1, $src2" %} 14495 ins_encode %{ 14496 __ fabds(as_FloatRegister($dst$$reg), 14497 as_FloatRegister($src1$$reg), 14498 as_FloatRegister($src2$$reg)); 14499 %} 14500 14501 ins_pipe(fp_uop_s); 14502 %} 14503 14504 instruct absdD_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14505 match(Set dst (AbsD (SubD src1 src2))); 14506 14507 ins_cost(INSN_COST * 3); 14508 format %{ "fabdd $dst, $src1, $src2" %} 14509 ins_encode %{ 14510 __ fabdd(as_FloatRegister($dst$$reg), 14511 as_FloatRegister($src1$$reg), 14512 as_FloatRegister($src2$$reg)); 14513 %} 14514 14515 ins_pipe(fp_uop_d); 14516 %} 14517 14518 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 14519 match(Set dst (SqrtD src)); 14520 14521 ins_cost(INSN_COST * 50); 14522 format %{ "fsqrtd $dst, $src" %} 14523 ins_encode %{ 14524 __ fsqrtd(as_FloatRegister($dst$$reg), 14525 as_FloatRegister($src$$reg)); 14526 %} 14527 14528 ins_pipe(fp_div_s); 14529 %} 14530 14531 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 14532 match(Set dst (SqrtF src)); 14533 14534 ins_cost(INSN_COST * 50); 14535 format %{ "fsqrts $dst, $src" %} 14536 ins_encode %{ 14537 __ fsqrts(as_FloatRegister($dst$$reg), 14538 as_FloatRegister($src$$reg)); 14539 %} 14540 14541 ins_pipe(fp_div_d); 14542 %} 14543 14544 // Math.rint, floor, ceil 14545 instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{ 14546 match(Set dst (RoundDoubleMode src rmode)); 14547 format %{ "frint $dst, $src, $rmode" %} 14548 ins_encode %{ 14549 switch ($rmode$$constant) { 14550 case RoundDoubleModeNode::rmode_rint: 14551 __ frintnd(as_FloatRegister($dst$$reg), 14552 as_FloatRegister($src$$reg)); 14553 break; 14554 case RoundDoubleModeNode::rmode_floor: 14555 __ frintmd(as_FloatRegister($dst$$reg), 14556 as_FloatRegister($src$$reg)); 14557 break; 14558 case RoundDoubleModeNode::rmode_ceil: 14559 __ frintpd(as_FloatRegister($dst$$reg), 14560 as_FloatRegister($src$$reg)); 14561 break; 14562 } 14563 %} 14564 ins_pipe(fp_uop_d); 14565 %} 14566 14567 instruct copySignD_reg(vRegD dst, vRegD src1, vRegD src2, vRegD zero) %{ 14568 match(Set dst (CopySignD src1 (Binary src2 zero))); 14569 effect(TEMP_DEF dst, USE src1, USE src2, USE zero); 14570 format %{ "CopySignD $dst $src1 $src2" %} 14571 ins_encode %{ 14572 FloatRegister dst = as_FloatRegister($dst$$reg), 14573 src1 = as_FloatRegister($src1$$reg), 14574 src2 = as_FloatRegister($src2$$reg), 14575 zero = as_FloatRegister($zero$$reg); 14576 __ fnegd(dst, zero); 14577 __ bsl(dst, __ T8B, src2, src1); 14578 %} 14579 ins_pipe(fp_uop_d); 14580 %} 14581 14582 instruct copySignF_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14583 match(Set dst (CopySignF src1 src2)); 14584 effect(TEMP_DEF dst, USE src1, USE src2); 14585 format %{ "CopySignF $dst $src1 $src2" %} 14586 ins_encode %{ 14587 FloatRegister dst = as_FloatRegister($dst$$reg), 14588 src1 = as_FloatRegister($src1$$reg), 14589 src2 = as_FloatRegister($src2$$reg); 14590 __ movi(dst, __ T2S, 0x80, 24); 14591 __ bsl(dst, __ T8B, src2, src1); 14592 %} 14593 ins_pipe(fp_uop_d); 14594 %} 14595 14596 instruct signumD_reg(vRegD dst, vRegD src, vRegD zero, vRegD one) %{ 14597 match(Set dst (SignumD src (Binary zero one))); 14598 effect(TEMP_DEF dst, USE src, USE zero, USE one); 14599 format %{ "signumD $dst, $src" %} 14600 ins_encode %{ 14601 FloatRegister src = as_FloatRegister($src$$reg), 14602 dst = as_FloatRegister($dst$$reg), 14603 zero = as_FloatRegister($zero$$reg), 14604 one = as_FloatRegister($one$$reg); 14605 __ facgtd(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 14606 __ ushrd(dst, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 14607 // Bit selection instruction gets bit from "one" for each enabled bit in 14608 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 14609 // NaN the whole "src" will be copied because "dst" is zero. For all other 14610 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 14611 // from "src", and all other bits are copied from 1.0. 14612 __ bsl(dst, __ T8B, one, src); 14613 %} 14614 ins_pipe(fp_uop_d); 14615 %} 14616 14617 instruct signumF_reg(vRegF dst, vRegF src, vRegF zero, vRegF one) %{ 14618 match(Set dst (SignumF src (Binary zero one))); 14619 effect(TEMP_DEF dst, USE src, USE zero, USE one); 14620 format %{ "signumF $dst, $src" %} 14621 ins_encode %{ 14622 FloatRegister src = as_FloatRegister($src$$reg), 14623 dst = as_FloatRegister($dst$$reg), 14624 zero = as_FloatRegister($zero$$reg), 14625 one = as_FloatRegister($one$$reg); 14626 __ facgts(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 14627 __ ushr(dst, __ T2S, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 14628 // Bit selection instruction gets bit from "one" for each enabled bit in 14629 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 14630 // NaN the whole "src" will be copied because "dst" is zero. For all other 14631 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 14632 // from "src", and all other bits are copied from 1.0. 14633 __ bsl(dst, __ T8B, one, src); 14634 %} 14635 ins_pipe(fp_uop_d); 14636 %} 14637 14638 instruct onspinwait() %{ 14639 match(OnSpinWait); 14640 ins_cost(INSN_COST); 14641 14642 format %{ "onspinwait" %} 14643 14644 ins_encode %{ 14645 __ spin_wait(); 14646 %} 14647 ins_pipe(pipe_class_empty); 14648 %} 14649 14650 // ============================================================================ 14651 // Logical Instructions 14652 14653 // Integer Logical Instructions 14654 14655 // And Instructions 14656 14657 14658 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 14659 match(Set dst (AndI src1 src2)); 14660 14661 format %{ "andw $dst, $src1, $src2\t# int" %} 14662 14663 ins_cost(INSN_COST); 14664 ins_encode %{ 14665 __ andw(as_Register($dst$$reg), 14666 as_Register($src1$$reg), 14667 as_Register($src2$$reg)); 14668 %} 14669 14670 ins_pipe(ialu_reg_reg); 14671 %} 14672 14673 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 14674 match(Set dst (AndI src1 src2)); 14675 14676 format %{ "andsw $dst, $src1, $src2\t# int" %} 14677 14678 ins_cost(INSN_COST); 14679 ins_encode %{ 14680 __ andw(as_Register($dst$$reg), 14681 as_Register($src1$$reg), 14682 (uint64_t)($src2$$constant)); 14683 %} 14684 14685 ins_pipe(ialu_reg_imm); 14686 %} 14687 14688 // Or Instructions 14689 14690 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 14691 match(Set dst (OrI src1 src2)); 14692 14693 format %{ "orrw $dst, $src1, $src2\t# int" %} 14694 14695 ins_cost(INSN_COST); 14696 ins_encode %{ 14697 __ orrw(as_Register($dst$$reg), 14698 as_Register($src1$$reg), 14699 as_Register($src2$$reg)); 14700 %} 14701 14702 ins_pipe(ialu_reg_reg); 14703 %} 14704 14705 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 14706 match(Set dst (OrI src1 src2)); 14707 14708 format %{ "orrw $dst, $src1, $src2\t# int" %} 14709 14710 ins_cost(INSN_COST); 14711 ins_encode %{ 14712 __ orrw(as_Register($dst$$reg), 14713 as_Register($src1$$reg), 14714 (uint64_t)($src2$$constant)); 14715 %} 14716 14717 ins_pipe(ialu_reg_imm); 14718 %} 14719 14720 // Xor Instructions 14721 14722 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 14723 match(Set dst (XorI src1 src2)); 14724 14725 format %{ "eorw $dst, $src1, $src2\t# int" %} 14726 14727 ins_cost(INSN_COST); 14728 ins_encode %{ 14729 __ eorw(as_Register($dst$$reg), 14730 as_Register($src1$$reg), 14731 as_Register($src2$$reg)); 14732 %} 14733 14734 ins_pipe(ialu_reg_reg); 14735 %} 14736 14737 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 14738 match(Set dst (XorI src1 src2)); 14739 14740 format %{ "eorw $dst, $src1, $src2\t# int" %} 14741 14742 ins_cost(INSN_COST); 14743 ins_encode %{ 14744 __ eorw(as_Register($dst$$reg), 14745 as_Register($src1$$reg), 14746 (uint64_t)($src2$$constant)); 14747 %} 14748 14749 ins_pipe(ialu_reg_imm); 14750 %} 14751 14752 // Long Logical Instructions 14753 // TODO 14754 14755 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 14756 match(Set dst (AndL src1 src2)); 14757 14758 format %{ "and $dst, $src1, $src2\t# int" %} 14759 14760 ins_cost(INSN_COST); 14761 ins_encode %{ 14762 __ andr(as_Register($dst$$reg), 14763 as_Register($src1$$reg), 14764 as_Register($src2$$reg)); 14765 %} 14766 14767 ins_pipe(ialu_reg_reg); 14768 %} 14769 14770 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 14771 match(Set dst (AndL src1 src2)); 14772 14773 format %{ "and $dst, $src1, $src2\t# int" %} 14774 14775 ins_cost(INSN_COST); 14776 ins_encode %{ 14777 __ andr(as_Register($dst$$reg), 14778 as_Register($src1$$reg), 14779 (uint64_t)($src2$$constant)); 14780 %} 14781 14782 ins_pipe(ialu_reg_imm); 14783 %} 14784 14785 // Or Instructions 14786 14787 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 14788 match(Set dst (OrL src1 src2)); 14789 14790 format %{ "orr $dst, $src1, $src2\t# int" %} 14791 14792 ins_cost(INSN_COST); 14793 ins_encode %{ 14794 __ orr(as_Register($dst$$reg), 14795 as_Register($src1$$reg), 14796 as_Register($src2$$reg)); 14797 %} 14798 14799 ins_pipe(ialu_reg_reg); 14800 %} 14801 14802 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 14803 match(Set dst (OrL src1 src2)); 14804 14805 format %{ "orr $dst, $src1, $src2\t# int" %} 14806 14807 ins_cost(INSN_COST); 14808 ins_encode %{ 14809 __ orr(as_Register($dst$$reg), 14810 as_Register($src1$$reg), 14811 (uint64_t)($src2$$constant)); 14812 %} 14813 14814 ins_pipe(ialu_reg_imm); 14815 %} 14816 14817 // Xor Instructions 14818 14819 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 14820 match(Set dst (XorL src1 src2)); 14821 14822 format %{ "eor $dst, $src1, $src2\t# int" %} 14823 14824 ins_cost(INSN_COST); 14825 ins_encode %{ 14826 __ eor(as_Register($dst$$reg), 14827 as_Register($src1$$reg), 14828 as_Register($src2$$reg)); 14829 %} 14830 14831 ins_pipe(ialu_reg_reg); 14832 %} 14833 14834 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 14835 match(Set dst (XorL src1 src2)); 14836 14837 ins_cost(INSN_COST); 14838 format %{ "eor $dst, $src1, $src2\t# int" %} 14839 14840 ins_encode %{ 14841 __ eor(as_Register($dst$$reg), 14842 as_Register($src1$$reg), 14843 (uint64_t)($src2$$constant)); 14844 %} 14845 14846 ins_pipe(ialu_reg_imm); 14847 %} 14848 14849 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 14850 %{ 14851 match(Set dst (ConvI2L src)); 14852 14853 ins_cost(INSN_COST); 14854 format %{ "sxtw $dst, $src\t# i2l" %} 14855 ins_encode %{ 14856 __ sbfm($dst$$Register, $src$$Register, 0, 31); 14857 %} 14858 ins_pipe(ialu_reg_shift); 14859 %} 14860 14861 // this pattern occurs in bigmath arithmetic 14862 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 14863 %{ 14864 match(Set dst (AndL (ConvI2L src) mask)); 14865 14866 ins_cost(INSN_COST); 14867 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 14868 ins_encode %{ 14869 __ ubfm($dst$$Register, $src$$Register, 0, 31); 14870 %} 14871 14872 ins_pipe(ialu_reg_shift); 14873 %} 14874 14875 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 14876 match(Set dst (ConvL2I src)); 14877 14878 ins_cost(INSN_COST); 14879 format %{ "movw $dst, $src \t// l2i" %} 14880 14881 ins_encode %{ 14882 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 14883 %} 14884 14885 ins_pipe(ialu_reg); 14886 %} 14887 14888 instruct convD2F_reg(vRegF dst, vRegD src) %{ 14889 match(Set dst (ConvD2F src)); 14890 14891 ins_cost(INSN_COST * 5); 14892 format %{ "fcvtd $dst, $src \t// d2f" %} 14893 14894 ins_encode %{ 14895 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 14896 %} 14897 14898 ins_pipe(fp_d2f); 14899 %} 14900 14901 instruct convF2D_reg(vRegD dst, vRegF src) %{ 14902 match(Set dst (ConvF2D src)); 14903 14904 ins_cost(INSN_COST * 5); 14905 format %{ "fcvts $dst, $src \t// f2d" %} 14906 14907 ins_encode %{ 14908 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 14909 %} 14910 14911 ins_pipe(fp_f2d); 14912 %} 14913 14914 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 14915 match(Set dst (ConvF2I src)); 14916 14917 ins_cost(INSN_COST * 5); 14918 format %{ "fcvtzsw $dst, $src \t// f2i" %} 14919 14920 ins_encode %{ 14921 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14922 %} 14923 14924 ins_pipe(fp_f2i); 14925 %} 14926 14927 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 14928 match(Set dst (ConvF2L src)); 14929 14930 ins_cost(INSN_COST * 5); 14931 format %{ "fcvtzs $dst, $src \t// f2l" %} 14932 14933 ins_encode %{ 14934 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14935 %} 14936 14937 ins_pipe(fp_f2l); 14938 %} 14939 14940 instruct convF2HF_reg_reg(iRegINoSp dst, vRegF src, vRegF tmp) %{ 14941 match(Set dst (ConvF2HF src)); 14942 format %{ "fcvt $tmp, $src\t# convert single to half precision\n\t" 14943 "smov $dst, $tmp\t# move result from $tmp to $dst" 14944 %} 14945 effect(TEMP tmp); 14946 ins_encode %{ 14947 __ flt_to_flt16($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister); 14948 %} 14949 ins_pipe(pipe_slow); 14950 %} 14951 14952 instruct convHF2F_reg_reg(vRegF dst, iRegINoSp src, vRegF tmp) %{ 14953 match(Set dst (ConvHF2F src)); 14954 format %{ "mov $tmp, $src\t# move source from $src to $tmp\n\t" 14955 "fcvt $dst, $tmp\t# convert half to single precision" 14956 %} 14957 effect(TEMP tmp); 14958 ins_encode %{ 14959 __ flt16_to_flt($dst$$FloatRegister, $src$$Register, $tmp$$FloatRegister); 14960 %} 14961 ins_pipe(pipe_slow); 14962 %} 14963 14964 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 14965 match(Set dst (ConvI2F src)); 14966 14967 ins_cost(INSN_COST * 5); 14968 format %{ "scvtfws $dst, $src \t// i2f" %} 14969 14970 ins_encode %{ 14971 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14972 %} 14973 14974 ins_pipe(fp_i2f); 14975 %} 14976 14977 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 14978 match(Set dst (ConvL2F src)); 14979 14980 ins_cost(INSN_COST * 5); 14981 format %{ "scvtfs $dst, $src \t// l2f" %} 14982 14983 ins_encode %{ 14984 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14985 %} 14986 14987 ins_pipe(fp_l2f); 14988 %} 14989 14990 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 14991 match(Set dst (ConvD2I src)); 14992 14993 ins_cost(INSN_COST * 5); 14994 format %{ "fcvtzdw $dst, $src \t// d2i" %} 14995 14996 ins_encode %{ 14997 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14998 %} 14999 15000 ins_pipe(fp_d2i); 15001 %} 15002 15003 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 15004 match(Set dst (ConvD2L src)); 15005 15006 ins_cost(INSN_COST * 5); 15007 format %{ "fcvtzd $dst, $src \t// d2l" %} 15008 15009 ins_encode %{ 15010 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 15011 %} 15012 15013 ins_pipe(fp_d2l); 15014 %} 15015 15016 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 15017 match(Set dst (ConvI2D src)); 15018 15019 ins_cost(INSN_COST * 5); 15020 format %{ "scvtfwd $dst, $src \t// i2d" %} 15021 15022 ins_encode %{ 15023 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 15024 %} 15025 15026 ins_pipe(fp_i2d); 15027 %} 15028 15029 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 15030 match(Set dst (ConvL2D src)); 15031 15032 ins_cost(INSN_COST * 5); 15033 format %{ "scvtfd $dst, $src \t// l2d" %} 15034 15035 ins_encode %{ 15036 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 15037 %} 15038 15039 ins_pipe(fp_l2d); 15040 %} 15041 15042 instruct round_double_reg(iRegLNoSp dst, vRegD src, vRegD ftmp, rFlagsReg cr) 15043 %{ 15044 match(Set dst (RoundD src)); 15045 effect(TEMP_DEF dst, TEMP ftmp, KILL cr); 15046 format %{ "java_round_double $dst,$src"%} 15047 ins_encode %{ 15048 __ java_round_double($dst$$Register, as_FloatRegister($src$$reg), 15049 as_FloatRegister($ftmp$$reg)); 15050 %} 15051 ins_pipe(pipe_slow); 15052 %} 15053 15054 instruct round_float_reg(iRegINoSp dst, vRegF src, vRegF ftmp, rFlagsReg cr) 15055 %{ 15056 match(Set dst (RoundF src)); 15057 effect(TEMP_DEF dst, TEMP ftmp, KILL cr); 15058 format %{ "java_round_float $dst,$src"%} 15059 ins_encode %{ 15060 __ java_round_float($dst$$Register, as_FloatRegister($src$$reg), 15061 as_FloatRegister($ftmp$$reg)); 15062 %} 15063 ins_pipe(pipe_slow); 15064 %} 15065 15066 // stack <-> reg and reg <-> reg shuffles with no conversion 15067 15068 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 15069 15070 match(Set dst (MoveF2I src)); 15071 15072 effect(DEF dst, USE src); 15073 15074 ins_cost(4 * INSN_COST); 15075 15076 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 15077 15078 ins_encode %{ 15079 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 15080 %} 15081 15082 ins_pipe(iload_reg_reg); 15083 15084 %} 15085 15086 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 15087 15088 match(Set dst (MoveI2F src)); 15089 15090 effect(DEF dst, USE src); 15091 15092 ins_cost(4 * INSN_COST); 15093 15094 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 15095 15096 ins_encode %{ 15097 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 15098 %} 15099 15100 ins_pipe(pipe_class_memory); 15101 15102 %} 15103 15104 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 15105 15106 match(Set dst (MoveD2L src)); 15107 15108 effect(DEF dst, USE src); 15109 15110 ins_cost(4 * INSN_COST); 15111 15112 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 15113 15114 ins_encode %{ 15115 __ ldr($dst$$Register, Address(sp, $src$$disp)); 15116 %} 15117 15118 ins_pipe(iload_reg_reg); 15119 15120 %} 15121 15122 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 15123 15124 match(Set dst (MoveL2D src)); 15125 15126 effect(DEF dst, USE src); 15127 15128 ins_cost(4 * INSN_COST); 15129 15130 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 15131 15132 ins_encode %{ 15133 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 15134 %} 15135 15136 ins_pipe(pipe_class_memory); 15137 15138 %} 15139 15140 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 15141 15142 match(Set dst (MoveF2I src)); 15143 15144 effect(DEF dst, USE src); 15145 15146 ins_cost(INSN_COST); 15147 15148 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 15149 15150 ins_encode %{ 15151 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 15152 %} 15153 15154 ins_pipe(pipe_class_memory); 15155 15156 %} 15157 15158 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 15159 15160 match(Set dst (MoveI2F src)); 15161 15162 effect(DEF dst, USE src); 15163 15164 ins_cost(INSN_COST); 15165 15166 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 15167 15168 ins_encode %{ 15169 __ strw($src$$Register, Address(sp, $dst$$disp)); 15170 %} 15171 15172 ins_pipe(istore_reg_reg); 15173 15174 %} 15175 15176 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 15177 15178 match(Set dst (MoveD2L src)); 15179 15180 effect(DEF dst, USE src); 15181 15182 ins_cost(INSN_COST); 15183 15184 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 15185 15186 ins_encode %{ 15187 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 15188 %} 15189 15190 ins_pipe(pipe_class_memory); 15191 15192 %} 15193 15194 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 15195 15196 match(Set dst (MoveL2D src)); 15197 15198 effect(DEF dst, USE src); 15199 15200 ins_cost(INSN_COST); 15201 15202 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 15203 15204 ins_encode %{ 15205 __ str($src$$Register, Address(sp, $dst$$disp)); 15206 %} 15207 15208 ins_pipe(istore_reg_reg); 15209 15210 %} 15211 15212 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 15213 15214 match(Set dst (MoveF2I src)); 15215 15216 effect(DEF dst, USE src); 15217 15218 ins_cost(INSN_COST); 15219 15220 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 15221 15222 ins_encode %{ 15223 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 15224 %} 15225 15226 ins_pipe(fp_f2i); 15227 15228 %} 15229 15230 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 15231 15232 match(Set dst (MoveI2F src)); 15233 15234 effect(DEF dst, USE src); 15235 15236 ins_cost(INSN_COST); 15237 15238 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 15239 15240 ins_encode %{ 15241 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 15242 %} 15243 15244 ins_pipe(fp_i2f); 15245 15246 %} 15247 15248 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 15249 15250 match(Set dst (MoveD2L src)); 15251 15252 effect(DEF dst, USE src); 15253 15254 ins_cost(INSN_COST); 15255 15256 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 15257 15258 ins_encode %{ 15259 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 15260 %} 15261 15262 ins_pipe(fp_d2l); 15263 15264 %} 15265 15266 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 15267 15268 match(Set dst (MoveL2D src)); 15269 15270 effect(DEF dst, USE src); 15271 15272 ins_cost(INSN_COST); 15273 15274 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 15275 15276 ins_encode %{ 15277 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 15278 %} 15279 15280 ins_pipe(fp_l2d); 15281 15282 %} 15283 15284 // ============================================================================ 15285 // clearing of an array 15286 15287 instruct clearArray_reg_reg_immL0(iRegL_R11 cnt, iRegP_R10 base, immL0 zero, Universe dummy, rFlagsReg cr) 15288 %{ 15289 match(Set dummy (ClearArray (Binary cnt base) zero)); 15290 effect(USE_KILL cnt, USE_KILL base, KILL cr); 15291 15292 ins_cost(4 * INSN_COST); 15293 format %{ "ClearArray $cnt, $base" %} 15294 15295 ins_encode %{ 15296 address tpc = __ zero_words($base$$Register, $cnt$$Register); 15297 if (tpc == nullptr) { 15298 ciEnv::current()->record_failure("CodeCache is full"); 15299 return; 15300 } 15301 %} 15302 15303 ins_pipe(pipe_class_memory); 15304 %} 15305 15306 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, iRegL val, Universe dummy, rFlagsReg cr) 15307 %{ 15308 predicate(((ClearArrayNode*)n)->word_copy_only()); 15309 match(Set dummy (ClearArray (Binary cnt base) val)); 15310 effect(USE_KILL cnt, USE_KILL base, KILL cr); 15311 15312 ins_cost(4 * INSN_COST); 15313 format %{ "ClearArray $cnt, $base, $val" %} 15314 15315 ins_encode %{ 15316 __ fill_words($base$$Register, $cnt$$Register, $val$$Register); 15317 %} 15318 15319 ins_pipe(pipe_class_memory); 15320 %} 15321 15322 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, iRegL_R11 temp, Universe dummy, rFlagsReg cr) 15323 %{ 15324 predicate((uint64_t)n->in(2)->get_long() 15325 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord) 15326 && !((ClearArrayNode*)n)->word_copy_only()); 15327 match(Set dummy (ClearArray cnt base)); 15328 effect(TEMP temp, USE_KILL base, KILL cr); 15329 15330 ins_cost(4 * INSN_COST); 15331 format %{ "ClearArray $cnt, $base" %} 15332 15333 ins_encode %{ 15334 address tpc = __ zero_words($base$$Register, (uint64_t)$cnt$$constant); 15335 if (tpc == nullptr) { 15336 ciEnv::current()->record_failure("CodeCache is full"); 15337 return; 15338 } 15339 %} 15340 15341 ins_pipe(pipe_class_memory); 15342 %} 15343 15344 // ============================================================================ 15345 // Overflow Math Instructions 15346 15347 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 15348 %{ 15349 match(Set cr (OverflowAddI op1 op2)); 15350 15351 format %{ "cmnw $op1, $op2\t# overflow check int" %} 15352 ins_cost(INSN_COST); 15353 ins_encode %{ 15354 __ cmnw($op1$$Register, $op2$$Register); 15355 %} 15356 15357 ins_pipe(icmp_reg_reg); 15358 %} 15359 15360 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 15361 %{ 15362 match(Set cr (OverflowAddI op1 op2)); 15363 15364 format %{ "cmnw $op1, $op2\t# overflow check int" %} 15365 ins_cost(INSN_COST); 15366 ins_encode %{ 15367 __ cmnw($op1$$Register, $op2$$constant); 15368 %} 15369 15370 ins_pipe(icmp_reg_imm); 15371 %} 15372 15373 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15374 %{ 15375 match(Set cr (OverflowAddL op1 op2)); 15376 15377 format %{ "cmn $op1, $op2\t# overflow check long" %} 15378 ins_cost(INSN_COST); 15379 ins_encode %{ 15380 __ cmn($op1$$Register, $op2$$Register); 15381 %} 15382 15383 ins_pipe(icmp_reg_reg); 15384 %} 15385 15386 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 15387 %{ 15388 match(Set cr (OverflowAddL op1 op2)); 15389 15390 format %{ "adds zr, $op1, $op2\t# overflow check long" %} 15391 ins_cost(INSN_COST); 15392 ins_encode %{ 15393 __ adds(zr, $op1$$Register, $op2$$constant); 15394 %} 15395 15396 ins_pipe(icmp_reg_imm); 15397 %} 15398 15399 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 15400 %{ 15401 match(Set cr (OverflowSubI op1 op2)); 15402 15403 format %{ "cmpw $op1, $op2\t# overflow check int" %} 15404 ins_cost(INSN_COST); 15405 ins_encode %{ 15406 __ cmpw($op1$$Register, $op2$$Register); 15407 %} 15408 15409 ins_pipe(icmp_reg_reg); 15410 %} 15411 15412 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 15413 %{ 15414 match(Set cr (OverflowSubI op1 op2)); 15415 15416 format %{ "cmpw $op1, $op2\t# overflow check int" %} 15417 ins_cost(INSN_COST); 15418 ins_encode %{ 15419 __ cmpw($op1$$Register, $op2$$constant); 15420 %} 15421 15422 ins_pipe(icmp_reg_imm); 15423 %} 15424 15425 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15426 %{ 15427 match(Set cr (OverflowSubL op1 op2)); 15428 15429 format %{ "cmp $op1, $op2\t# overflow check long" %} 15430 ins_cost(INSN_COST); 15431 ins_encode %{ 15432 __ cmp($op1$$Register, $op2$$Register); 15433 %} 15434 15435 ins_pipe(icmp_reg_reg); 15436 %} 15437 15438 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 15439 %{ 15440 match(Set cr (OverflowSubL op1 op2)); 15441 15442 format %{ "cmp $op1, $op2\t# overflow check long" %} 15443 ins_cost(INSN_COST); 15444 ins_encode %{ 15445 __ subs(zr, $op1$$Register, $op2$$constant); 15446 %} 15447 15448 ins_pipe(icmp_reg_imm); 15449 %} 15450 15451 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 15452 %{ 15453 match(Set cr (OverflowSubI zero op1)); 15454 15455 format %{ "cmpw zr, $op1\t# overflow check int" %} 15456 ins_cost(INSN_COST); 15457 ins_encode %{ 15458 __ cmpw(zr, $op1$$Register); 15459 %} 15460 15461 ins_pipe(icmp_reg_imm); 15462 %} 15463 15464 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 15465 %{ 15466 match(Set cr (OverflowSubL zero op1)); 15467 15468 format %{ "cmp zr, $op1\t# overflow check long" %} 15469 ins_cost(INSN_COST); 15470 ins_encode %{ 15471 __ cmp(zr, $op1$$Register); 15472 %} 15473 15474 ins_pipe(icmp_reg_imm); 15475 %} 15476 15477 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 15478 %{ 15479 match(Set cr (OverflowMulI op1 op2)); 15480 15481 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 15482 "cmp rscratch1, rscratch1, sxtw\n\t" 15483 "movw rscratch1, #0x80000000\n\t" 15484 "cselw rscratch1, rscratch1, zr, NE\n\t" 15485 "cmpw rscratch1, #1" %} 15486 ins_cost(5 * INSN_COST); 15487 ins_encode %{ 15488 __ smull(rscratch1, $op1$$Register, $op2$$Register); 15489 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 15490 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 15491 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 15492 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 15493 %} 15494 15495 ins_pipe(pipe_slow); 15496 %} 15497 15498 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 15499 %{ 15500 match(If cmp (OverflowMulI op1 op2)); 15501 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 15502 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 15503 effect(USE labl, KILL cr); 15504 15505 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 15506 "cmp rscratch1, rscratch1, sxtw\n\t" 15507 "b$cmp $labl" %} 15508 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 15509 ins_encode %{ 15510 Label* L = $labl$$label; 15511 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15512 __ smull(rscratch1, $op1$$Register, $op2$$Register); 15513 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 15514 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 15515 %} 15516 15517 ins_pipe(pipe_serial); 15518 %} 15519 15520 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15521 %{ 15522 match(Set cr (OverflowMulL op1 op2)); 15523 15524 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 15525 "smulh rscratch2, $op1, $op2\n\t" 15526 "cmp rscratch2, rscratch1, ASR #63\n\t" 15527 "movw rscratch1, #0x80000000\n\t" 15528 "cselw rscratch1, rscratch1, zr, NE\n\t" 15529 "cmpw rscratch1, #1" %} 15530 ins_cost(6 * INSN_COST); 15531 ins_encode %{ 15532 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 15533 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 15534 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 15535 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 15536 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 15537 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 15538 %} 15539 15540 ins_pipe(pipe_slow); 15541 %} 15542 15543 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 15544 %{ 15545 match(If cmp (OverflowMulL op1 op2)); 15546 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 15547 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 15548 effect(USE labl, KILL cr); 15549 15550 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 15551 "smulh rscratch2, $op1, $op2\n\t" 15552 "cmp rscratch2, rscratch1, ASR #63\n\t" 15553 "b$cmp $labl" %} 15554 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 15555 ins_encode %{ 15556 Label* L = $labl$$label; 15557 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15558 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 15559 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 15560 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 15561 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 15562 %} 15563 15564 ins_pipe(pipe_serial); 15565 %} 15566 15567 // ============================================================================ 15568 // Compare Instructions 15569 15570 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 15571 %{ 15572 match(Set cr (CmpI op1 op2)); 15573 15574 effect(DEF cr, USE op1, USE op2); 15575 15576 ins_cost(INSN_COST); 15577 format %{ "cmpw $op1, $op2" %} 15578 15579 ins_encode(aarch64_enc_cmpw(op1, op2)); 15580 15581 ins_pipe(icmp_reg_reg); 15582 %} 15583 15584 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 15585 %{ 15586 match(Set cr (CmpI op1 zero)); 15587 15588 effect(DEF cr, USE op1); 15589 15590 ins_cost(INSN_COST); 15591 format %{ "cmpw $op1, 0" %} 15592 15593 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 15594 15595 ins_pipe(icmp_reg_imm); 15596 %} 15597 15598 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 15599 %{ 15600 match(Set cr (CmpI op1 op2)); 15601 15602 effect(DEF cr, USE op1); 15603 15604 ins_cost(INSN_COST); 15605 format %{ "cmpw $op1, $op2" %} 15606 15607 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 15608 15609 ins_pipe(icmp_reg_imm); 15610 %} 15611 15612 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 15613 %{ 15614 match(Set cr (CmpI op1 op2)); 15615 15616 effect(DEF cr, USE op1); 15617 15618 ins_cost(INSN_COST * 2); 15619 format %{ "cmpw $op1, $op2" %} 15620 15621 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 15622 15623 ins_pipe(icmp_reg_imm); 15624 %} 15625 15626 // Unsigned compare Instructions; really, same as signed compare 15627 // except it should only be used to feed an If or a CMovI which takes a 15628 // cmpOpU. 15629 15630 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 15631 %{ 15632 match(Set cr (CmpU op1 op2)); 15633 15634 effect(DEF cr, USE op1, USE op2); 15635 15636 ins_cost(INSN_COST); 15637 format %{ "cmpw $op1, $op2\t# unsigned" %} 15638 15639 ins_encode(aarch64_enc_cmpw(op1, op2)); 15640 15641 ins_pipe(icmp_reg_reg); 15642 %} 15643 15644 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 15645 %{ 15646 match(Set cr (CmpU op1 zero)); 15647 15648 effect(DEF cr, USE op1); 15649 15650 ins_cost(INSN_COST); 15651 format %{ "cmpw $op1, #0\t# unsigned" %} 15652 15653 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 15654 15655 ins_pipe(icmp_reg_imm); 15656 %} 15657 15658 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 15659 %{ 15660 match(Set cr (CmpU op1 op2)); 15661 15662 effect(DEF cr, USE op1); 15663 15664 ins_cost(INSN_COST); 15665 format %{ "cmpw $op1, $op2\t# unsigned" %} 15666 15667 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 15668 15669 ins_pipe(icmp_reg_imm); 15670 %} 15671 15672 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 15673 %{ 15674 match(Set cr (CmpU op1 op2)); 15675 15676 effect(DEF cr, USE op1); 15677 15678 ins_cost(INSN_COST * 2); 15679 format %{ "cmpw $op1, $op2\t# unsigned" %} 15680 15681 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 15682 15683 ins_pipe(icmp_reg_imm); 15684 %} 15685 15686 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15687 %{ 15688 match(Set cr (CmpL op1 op2)); 15689 15690 effect(DEF cr, USE op1, USE op2); 15691 15692 ins_cost(INSN_COST); 15693 format %{ "cmp $op1, $op2" %} 15694 15695 ins_encode(aarch64_enc_cmp(op1, op2)); 15696 15697 ins_pipe(icmp_reg_reg); 15698 %} 15699 15700 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 15701 %{ 15702 match(Set cr (CmpL op1 zero)); 15703 15704 effect(DEF cr, USE op1); 15705 15706 ins_cost(INSN_COST); 15707 format %{ "tst $op1" %} 15708 15709 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 15710 15711 ins_pipe(icmp_reg_imm); 15712 %} 15713 15714 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 15715 %{ 15716 match(Set cr (CmpL op1 op2)); 15717 15718 effect(DEF cr, USE op1); 15719 15720 ins_cost(INSN_COST); 15721 format %{ "cmp $op1, $op2" %} 15722 15723 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 15724 15725 ins_pipe(icmp_reg_imm); 15726 %} 15727 15728 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 15729 %{ 15730 match(Set cr (CmpL op1 op2)); 15731 15732 effect(DEF cr, USE op1); 15733 15734 ins_cost(INSN_COST * 2); 15735 format %{ "cmp $op1, $op2" %} 15736 15737 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 15738 15739 ins_pipe(icmp_reg_imm); 15740 %} 15741 15742 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 15743 %{ 15744 match(Set cr (CmpUL op1 op2)); 15745 15746 effect(DEF cr, USE op1, USE op2); 15747 15748 ins_cost(INSN_COST); 15749 format %{ "cmp $op1, $op2" %} 15750 15751 ins_encode(aarch64_enc_cmp(op1, op2)); 15752 15753 ins_pipe(icmp_reg_reg); 15754 %} 15755 15756 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 15757 %{ 15758 match(Set cr (CmpUL op1 zero)); 15759 15760 effect(DEF cr, USE op1); 15761 15762 ins_cost(INSN_COST); 15763 format %{ "tst $op1" %} 15764 15765 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 15766 15767 ins_pipe(icmp_reg_imm); 15768 %} 15769 15770 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 15771 %{ 15772 match(Set cr (CmpUL op1 op2)); 15773 15774 effect(DEF cr, USE op1); 15775 15776 ins_cost(INSN_COST); 15777 format %{ "cmp $op1, $op2" %} 15778 15779 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 15780 15781 ins_pipe(icmp_reg_imm); 15782 %} 15783 15784 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 15785 %{ 15786 match(Set cr (CmpUL op1 op2)); 15787 15788 effect(DEF cr, USE op1); 15789 15790 ins_cost(INSN_COST * 2); 15791 format %{ "cmp $op1, $op2" %} 15792 15793 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 15794 15795 ins_pipe(icmp_reg_imm); 15796 %} 15797 15798 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 15799 %{ 15800 match(Set cr (CmpP op1 op2)); 15801 15802 effect(DEF cr, USE op1, USE op2); 15803 15804 ins_cost(INSN_COST); 15805 format %{ "cmp $op1, $op2\t // ptr" %} 15806 15807 ins_encode(aarch64_enc_cmpp(op1, op2)); 15808 15809 ins_pipe(icmp_reg_reg); 15810 %} 15811 15812 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 15813 %{ 15814 match(Set cr (CmpN op1 op2)); 15815 15816 effect(DEF cr, USE op1, USE op2); 15817 15818 ins_cost(INSN_COST); 15819 format %{ "cmp $op1, $op2\t // compressed ptr" %} 15820 15821 ins_encode(aarch64_enc_cmpn(op1, op2)); 15822 15823 ins_pipe(icmp_reg_reg); 15824 %} 15825 15826 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 15827 %{ 15828 match(Set cr (CmpP op1 zero)); 15829 15830 effect(DEF cr, USE op1, USE zero); 15831 15832 ins_cost(INSN_COST); 15833 format %{ "cmp $op1, 0\t // ptr" %} 15834 15835 ins_encode(aarch64_enc_testp(op1)); 15836 15837 ins_pipe(icmp_reg_imm); 15838 %} 15839 15840 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 15841 %{ 15842 match(Set cr (CmpN op1 zero)); 15843 15844 effect(DEF cr, USE op1, USE zero); 15845 15846 ins_cost(INSN_COST); 15847 format %{ "cmp $op1, 0\t // compressed ptr" %} 15848 15849 ins_encode(aarch64_enc_testn(op1)); 15850 15851 ins_pipe(icmp_reg_imm); 15852 %} 15853 15854 // FP comparisons 15855 // 15856 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 15857 // using normal cmpOp. See declaration of rFlagsReg for details. 15858 15859 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 15860 %{ 15861 match(Set cr (CmpF src1 src2)); 15862 15863 ins_cost(3 * INSN_COST); 15864 format %{ "fcmps $src1, $src2" %} 15865 15866 ins_encode %{ 15867 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15868 %} 15869 15870 ins_pipe(pipe_class_compare); 15871 %} 15872 15873 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 15874 %{ 15875 match(Set cr (CmpF src1 src2)); 15876 15877 ins_cost(3 * INSN_COST); 15878 format %{ "fcmps $src1, 0.0" %} 15879 15880 ins_encode %{ 15881 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 15882 %} 15883 15884 ins_pipe(pipe_class_compare); 15885 %} 15886 // FROM HERE 15887 15888 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 15889 %{ 15890 match(Set cr (CmpD src1 src2)); 15891 15892 ins_cost(3 * INSN_COST); 15893 format %{ "fcmpd $src1, $src2" %} 15894 15895 ins_encode %{ 15896 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15897 %} 15898 15899 ins_pipe(pipe_class_compare); 15900 %} 15901 15902 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 15903 %{ 15904 match(Set cr (CmpD src1 src2)); 15905 15906 ins_cost(3 * INSN_COST); 15907 format %{ "fcmpd $src1, 0.0" %} 15908 15909 ins_encode %{ 15910 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 15911 %} 15912 15913 ins_pipe(pipe_class_compare); 15914 %} 15915 15916 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 15917 %{ 15918 match(Set dst (CmpF3 src1 src2)); 15919 effect(KILL cr); 15920 15921 ins_cost(5 * INSN_COST); 15922 format %{ "fcmps $src1, $src2\n\t" 15923 "csinvw($dst, zr, zr, eq\n\t" 15924 "csnegw($dst, $dst, $dst, lt)" 15925 %} 15926 15927 ins_encode %{ 15928 Label done; 15929 FloatRegister s1 = as_FloatRegister($src1$$reg); 15930 FloatRegister s2 = as_FloatRegister($src2$$reg); 15931 Register d = as_Register($dst$$reg); 15932 __ fcmps(s1, s2); 15933 // installs 0 if EQ else -1 15934 __ csinvw(d, zr, zr, Assembler::EQ); 15935 // keeps -1 if less or unordered else installs 1 15936 __ csnegw(d, d, d, Assembler::LT); 15937 __ bind(done); 15938 %} 15939 15940 ins_pipe(pipe_class_default); 15941 15942 %} 15943 15944 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 15945 %{ 15946 match(Set dst (CmpD3 src1 src2)); 15947 effect(KILL cr); 15948 15949 ins_cost(5 * INSN_COST); 15950 format %{ "fcmpd $src1, $src2\n\t" 15951 "csinvw($dst, zr, zr, eq\n\t" 15952 "csnegw($dst, $dst, $dst, lt)" 15953 %} 15954 15955 ins_encode %{ 15956 Label done; 15957 FloatRegister s1 = as_FloatRegister($src1$$reg); 15958 FloatRegister s2 = as_FloatRegister($src2$$reg); 15959 Register d = as_Register($dst$$reg); 15960 __ fcmpd(s1, s2); 15961 // installs 0 if EQ else -1 15962 __ csinvw(d, zr, zr, Assembler::EQ); 15963 // keeps -1 if less or unordered else installs 1 15964 __ csnegw(d, d, d, Assembler::LT); 15965 __ bind(done); 15966 %} 15967 ins_pipe(pipe_class_default); 15968 15969 %} 15970 15971 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 15972 %{ 15973 match(Set dst (CmpF3 src1 zero)); 15974 effect(KILL cr); 15975 15976 ins_cost(5 * INSN_COST); 15977 format %{ "fcmps $src1, 0.0\n\t" 15978 "csinvw($dst, zr, zr, eq\n\t" 15979 "csnegw($dst, $dst, $dst, lt)" 15980 %} 15981 15982 ins_encode %{ 15983 Label done; 15984 FloatRegister s1 = as_FloatRegister($src1$$reg); 15985 Register d = as_Register($dst$$reg); 15986 __ fcmps(s1, 0.0); 15987 // installs 0 if EQ else -1 15988 __ csinvw(d, zr, zr, Assembler::EQ); 15989 // keeps -1 if less or unordered else installs 1 15990 __ csnegw(d, d, d, Assembler::LT); 15991 __ bind(done); 15992 %} 15993 15994 ins_pipe(pipe_class_default); 15995 15996 %} 15997 15998 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 15999 %{ 16000 match(Set dst (CmpD3 src1 zero)); 16001 effect(KILL cr); 16002 16003 ins_cost(5 * INSN_COST); 16004 format %{ "fcmpd $src1, 0.0\n\t" 16005 "csinvw($dst, zr, zr, eq\n\t" 16006 "csnegw($dst, $dst, $dst, lt)" 16007 %} 16008 16009 ins_encode %{ 16010 Label done; 16011 FloatRegister s1 = as_FloatRegister($src1$$reg); 16012 Register d = as_Register($dst$$reg); 16013 __ fcmpd(s1, 0.0); 16014 // installs 0 if EQ else -1 16015 __ csinvw(d, zr, zr, Assembler::EQ); 16016 // keeps -1 if less or unordered else installs 1 16017 __ csnegw(d, d, d, Assembler::LT); 16018 __ bind(done); 16019 %} 16020 ins_pipe(pipe_class_default); 16021 16022 %} 16023 16024 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 16025 %{ 16026 match(Set dst (CmpLTMask p q)); 16027 effect(KILL cr); 16028 16029 ins_cost(3 * INSN_COST); 16030 16031 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 16032 "csetw $dst, lt\n\t" 16033 "subw $dst, zr, $dst" 16034 %} 16035 16036 ins_encode %{ 16037 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 16038 __ csetw(as_Register($dst$$reg), Assembler::LT); 16039 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 16040 %} 16041 16042 ins_pipe(ialu_reg_reg); 16043 %} 16044 16045 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 16046 %{ 16047 match(Set dst (CmpLTMask src zero)); 16048 effect(KILL cr); 16049 16050 ins_cost(INSN_COST); 16051 16052 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 16053 16054 ins_encode %{ 16055 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 16056 %} 16057 16058 ins_pipe(ialu_reg_shift); 16059 %} 16060 16061 // ============================================================================ 16062 // Max and Min 16063 16064 // Like compI_reg_reg or compI_reg_immI0 but without match rule and second zero parameter. 16065 16066 instruct compI_reg_imm0(rFlagsReg cr, iRegI src) 16067 %{ 16068 effect(DEF cr, USE src); 16069 ins_cost(INSN_COST); 16070 format %{ "cmpw $src, 0" %} 16071 16072 ins_encode %{ 16073 __ cmpw($src$$Register, 0); 16074 %} 16075 ins_pipe(icmp_reg_imm); 16076 %} 16077 16078 instruct minI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) 16079 %{ 16080 match(Set dst (MinI src1 src2)); 16081 ins_cost(INSN_COST * 3); 16082 16083 expand %{ 16084 rFlagsReg cr; 16085 compI_reg_reg(cr, src1, src2); 16086 cmovI_reg_reg_lt(dst, src1, src2, cr); 16087 %} 16088 %} 16089 16090 instruct maxI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) 16091 %{ 16092 match(Set dst (MaxI src1 src2)); 16093 ins_cost(INSN_COST * 3); 16094 16095 expand %{ 16096 rFlagsReg cr; 16097 compI_reg_reg(cr, src1, src2); 16098 cmovI_reg_reg_gt(dst, src1, src2, cr); 16099 %} 16100 %} 16101 16102 16103 // ============================================================================ 16104 // Branch Instructions 16105 16106 // Direct Branch. 16107 instruct branch(label lbl) 16108 %{ 16109 match(Goto); 16110 16111 effect(USE lbl); 16112 16113 ins_cost(BRANCH_COST); 16114 format %{ "b $lbl" %} 16115 16116 ins_encode(aarch64_enc_b(lbl)); 16117 16118 ins_pipe(pipe_branch); 16119 %} 16120 16121 // Conditional Near Branch 16122 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 16123 %{ 16124 // Same match rule as `branchConFar'. 16125 match(If cmp cr); 16126 16127 effect(USE lbl); 16128 16129 ins_cost(BRANCH_COST); 16130 // If set to 1 this indicates that the current instruction is a 16131 // short variant of a long branch. This avoids using this 16132 // instruction in first-pass matching. It will then only be used in 16133 // the `Shorten_branches' pass. 16134 // ins_short_branch(1); 16135 format %{ "b$cmp $lbl" %} 16136 16137 ins_encode(aarch64_enc_br_con(cmp, lbl)); 16138 16139 ins_pipe(pipe_branch_cond); 16140 %} 16141 16142 // Conditional Near Branch Unsigned 16143 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 16144 %{ 16145 // Same match rule as `branchConFar'. 16146 match(If cmp cr); 16147 16148 effect(USE lbl); 16149 16150 ins_cost(BRANCH_COST); 16151 // If set to 1 this indicates that the current instruction is a 16152 // short variant of a long branch. This avoids using this 16153 // instruction in first-pass matching. It will then only be used in 16154 // the `Shorten_branches' pass. 16155 // ins_short_branch(1); 16156 format %{ "b$cmp $lbl\t# unsigned" %} 16157 16158 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 16159 16160 ins_pipe(pipe_branch_cond); 16161 %} 16162 16163 // Make use of CBZ and CBNZ. These instructions, as well as being 16164 // shorter than (cmp; branch), have the additional benefit of not 16165 // killing the flags. 16166 16167 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 16168 match(If cmp (CmpI op1 op2)); 16169 effect(USE labl); 16170 16171 ins_cost(BRANCH_COST); 16172 format %{ "cbw$cmp $op1, $labl" %} 16173 ins_encode %{ 16174 Label* L = $labl$$label; 16175 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16176 if (cond == Assembler::EQ) 16177 __ cbzw($op1$$Register, *L); 16178 else 16179 __ cbnzw($op1$$Register, *L); 16180 %} 16181 ins_pipe(pipe_cmp_branch); 16182 %} 16183 16184 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 16185 match(If cmp (CmpL op1 op2)); 16186 effect(USE labl); 16187 16188 ins_cost(BRANCH_COST); 16189 format %{ "cb$cmp $op1, $labl" %} 16190 ins_encode %{ 16191 Label* L = $labl$$label; 16192 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16193 if (cond == Assembler::EQ) 16194 __ cbz($op1$$Register, *L); 16195 else 16196 __ cbnz($op1$$Register, *L); 16197 %} 16198 ins_pipe(pipe_cmp_branch); 16199 %} 16200 16201 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 16202 match(If cmp (CmpP op1 op2)); 16203 effect(USE labl); 16204 16205 ins_cost(BRANCH_COST); 16206 format %{ "cb$cmp $op1, $labl" %} 16207 ins_encode %{ 16208 Label* L = $labl$$label; 16209 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16210 if (cond == Assembler::EQ) 16211 __ cbz($op1$$Register, *L); 16212 else 16213 __ cbnz($op1$$Register, *L); 16214 %} 16215 ins_pipe(pipe_cmp_branch); 16216 %} 16217 16218 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 16219 match(If cmp (CmpN op1 op2)); 16220 effect(USE labl); 16221 16222 ins_cost(BRANCH_COST); 16223 format %{ "cbw$cmp $op1, $labl" %} 16224 ins_encode %{ 16225 Label* L = $labl$$label; 16226 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16227 if (cond == Assembler::EQ) 16228 __ cbzw($op1$$Register, *L); 16229 else 16230 __ cbnzw($op1$$Register, *L); 16231 %} 16232 ins_pipe(pipe_cmp_branch); 16233 %} 16234 16235 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 16236 match(If cmp (CmpP (DecodeN oop) zero)); 16237 effect(USE labl); 16238 16239 ins_cost(BRANCH_COST); 16240 format %{ "cb$cmp $oop, $labl" %} 16241 ins_encode %{ 16242 Label* L = $labl$$label; 16243 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16244 if (cond == Assembler::EQ) 16245 __ cbzw($oop$$Register, *L); 16246 else 16247 __ cbnzw($oop$$Register, *L); 16248 %} 16249 ins_pipe(pipe_cmp_branch); 16250 %} 16251 16252 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 16253 match(If cmp (CmpU op1 op2)); 16254 effect(USE labl); 16255 16256 ins_cost(BRANCH_COST); 16257 format %{ "cbw$cmp $op1, $labl" %} 16258 ins_encode %{ 16259 Label* L = $labl$$label; 16260 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16261 if (cond == Assembler::EQ || cond == Assembler::LS) 16262 __ cbzw($op1$$Register, *L); 16263 else 16264 __ cbnzw($op1$$Register, *L); 16265 %} 16266 ins_pipe(pipe_cmp_branch); 16267 %} 16268 16269 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 16270 match(If cmp (CmpUL op1 op2)); 16271 effect(USE labl); 16272 16273 ins_cost(BRANCH_COST); 16274 format %{ "cb$cmp $op1, $labl" %} 16275 ins_encode %{ 16276 Label* L = $labl$$label; 16277 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16278 if (cond == Assembler::EQ || cond == Assembler::LS) 16279 __ cbz($op1$$Register, *L); 16280 else 16281 __ cbnz($op1$$Register, *L); 16282 %} 16283 ins_pipe(pipe_cmp_branch); 16284 %} 16285 16286 // Test bit and Branch 16287 16288 // Patterns for short (< 32KiB) variants 16289 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 16290 match(If cmp (CmpL op1 op2)); 16291 effect(USE labl); 16292 16293 ins_cost(BRANCH_COST); 16294 format %{ "cb$cmp $op1, $labl # long" %} 16295 ins_encode %{ 16296 Label* L = $labl$$label; 16297 Assembler::Condition cond = 16298 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16299 __ tbr(cond, $op1$$Register, 63, *L); 16300 %} 16301 ins_pipe(pipe_cmp_branch); 16302 ins_short_branch(1); 16303 %} 16304 16305 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 16306 match(If cmp (CmpI op1 op2)); 16307 effect(USE labl); 16308 16309 ins_cost(BRANCH_COST); 16310 format %{ "cb$cmp $op1, $labl # int" %} 16311 ins_encode %{ 16312 Label* L = $labl$$label; 16313 Assembler::Condition cond = 16314 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16315 __ tbr(cond, $op1$$Register, 31, *L); 16316 %} 16317 ins_pipe(pipe_cmp_branch); 16318 ins_short_branch(1); 16319 %} 16320 16321 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 16322 match(If cmp (CmpL (AndL op1 op2) op3)); 16323 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 16324 effect(USE labl); 16325 16326 ins_cost(BRANCH_COST); 16327 format %{ "tb$cmp $op1, $op2, $labl" %} 16328 ins_encode %{ 16329 Label* L = $labl$$label; 16330 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16331 int bit = exact_log2_long($op2$$constant); 16332 __ tbr(cond, $op1$$Register, bit, *L); 16333 %} 16334 ins_pipe(pipe_cmp_branch); 16335 ins_short_branch(1); 16336 %} 16337 16338 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 16339 match(If cmp (CmpI (AndI op1 op2) op3)); 16340 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 16341 effect(USE labl); 16342 16343 ins_cost(BRANCH_COST); 16344 format %{ "tb$cmp $op1, $op2, $labl" %} 16345 ins_encode %{ 16346 Label* L = $labl$$label; 16347 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16348 int bit = exact_log2((juint)$op2$$constant); 16349 __ tbr(cond, $op1$$Register, bit, *L); 16350 %} 16351 ins_pipe(pipe_cmp_branch); 16352 ins_short_branch(1); 16353 %} 16354 16355 // And far variants 16356 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 16357 match(If cmp (CmpL op1 op2)); 16358 effect(USE labl); 16359 16360 ins_cost(BRANCH_COST); 16361 format %{ "cb$cmp $op1, $labl # long" %} 16362 ins_encode %{ 16363 Label* L = $labl$$label; 16364 Assembler::Condition cond = 16365 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16366 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 16367 %} 16368 ins_pipe(pipe_cmp_branch); 16369 %} 16370 16371 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 16372 match(If cmp (CmpI op1 op2)); 16373 effect(USE labl); 16374 16375 ins_cost(BRANCH_COST); 16376 format %{ "cb$cmp $op1, $labl # int" %} 16377 ins_encode %{ 16378 Label* L = $labl$$label; 16379 Assembler::Condition cond = 16380 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16381 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 16382 %} 16383 ins_pipe(pipe_cmp_branch); 16384 %} 16385 16386 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 16387 match(If cmp (CmpL (AndL op1 op2) op3)); 16388 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 16389 effect(USE labl); 16390 16391 ins_cost(BRANCH_COST); 16392 format %{ "tb$cmp $op1, $op2, $labl" %} 16393 ins_encode %{ 16394 Label* L = $labl$$label; 16395 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16396 int bit = exact_log2_long($op2$$constant); 16397 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 16398 %} 16399 ins_pipe(pipe_cmp_branch); 16400 %} 16401 16402 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 16403 match(If cmp (CmpI (AndI op1 op2) op3)); 16404 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 16405 effect(USE labl); 16406 16407 ins_cost(BRANCH_COST); 16408 format %{ "tb$cmp $op1, $op2, $labl" %} 16409 ins_encode %{ 16410 Label* L = $labl$$label; 16411 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16412 int bit = exact_log2((juint)$op2$$constant); 16413 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 16414 %} 16415 ins_pipe(pipe_cmp_branch); 16416 %} 16417 16418 // Test bits 16419 16420 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 16421 match(Set cr (CmpL (AndL op1 op2) op3)); 16422 predicate(Assembler::operand_valid_for_logical_immediate 16423 (/*is_32*/false, n->in(1)->in(2)->get_long())); 16424 16425 ins_cost(INSN_COST); 16426 format %{ "tst $op1, $op2 # long" %} 16427 ins_encode %{ 16428 __ tst($op1$$Register, $op2$$constant); 16429 %} 16430 ins_pipe(ialu_reg_reg); 16431 %} 16432 16433 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 16434 match(Set cr (CmpI (AndI op1 op2) op3)); 16435 predicate(Assembler::operand_valid_for_logical_immediate 16436 (/*is_32*/true, n->in(1)->in(2)->get_int())); 16437 16438 ins_cost(INSN_COST); 16439 format %{ "tst $op1, $op2 # int" %} 16440 ins_encode %{ 16441 __ tstw($op1$$Register, $op2$$constant); 16442 %} 16443 ins_pipe(ialu_reg_reg); 16444 %} 16445 16446 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 16447 match(Set cr (CmpL (AndL op1 op2) op3)); 16448 16449 ins_cost(INSN_COST); 16450 format %{ "tst $op1, $op2 # long" %} 16451 ins_encode %{ 16452 __ tst($op1$$Register, $op2$$Register); 16453 %} 16454 ins_pipe(ialu_reg_reg); 16455 %} 16456 16457 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 16458 match(Set cr (CmpI (AndI op1 op2) op3)); 16459 16460 ins_cost(INSN_COST); 16461 format %{ "tstw $op1, $op2 # int" %} 16462 ins_encode %{ 16463 __ tstw($op1$$Register, $op2$$Register); 16464 %} 16465 ins_pipe(ialu_reg_reg); 16466 %} 16467 16468 16469 // Conditional Far Branch 16470 // Conditional Far Branch Unsigned 16471 // TODO: fixme 16472 16473 // counted loop end branch near 16474 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 16475 %{ 16476 match(CountedLoopEnd cmp cr); 16477 16478 effect(USE lbl); 16479 16480 ins_cost(BRANCH_COST); 16481 // short variant. 16482 // ins_short_branch(1); 16483 format %{ "b$cmp $lbl \t// counted loop end" %} 16484 16485 ins_encode(aarch64_enc_br_con(cmp, lbl)); 16486 16487 ins_pipe(pipe_branch); 16488 %} 16489 16490 // counted loop end branch far 16491 // TODO: fixme 16492 16493 // ============================================================================ 16494 // inlined locking and unlocking 16495 16496 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3) 16497 %{ 16498 match(Set cr (FastLock object box)); 16499 effect(TEMP tmp, TEMP tmp2, TEMP tmp3); 16500 16501 // TODO 16502 // identify correct cost 16503 ins_cost(5 * INSN_COST); 16504 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 16505 16506 ins_encode %{ 16507 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register); 16508 %} 16509 16510 ins_pipe(pipe_serial); 16511 %} 16512 16513 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 16514 %{ 16515 match(Set cr (FastUnlock object box)); 16516 effect(TEMP tmp, TEMP tmp2); 16517 16518 ins_cost(5 * INSN_COST); 16519 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 16520 16521 ins_encode %{ 16522 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register); 16523 %} 16524 16525 ins_pipe(pipe_serial); 16526 %} 16527 16528 16529 // ============================================================================ 16530 // Safepoint Instructions 16531 16532 // TODO 16533 // provide a near and far version of this code 16534 16535 instruct safePoint(rFlagsReg cr, iRegP poll) 16536 %{ 16537 match(SafePoint poll); 16538 effect(KILL cr); 16539 16540 format %{ 16541 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 16542 %} 16543 ins_encode %{ 16544 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 16545 %} 16546 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 16547 %} 16548 16549 16550 // ============================================================================ 16551 // Procedure Call/Return Instructions 16552 16553 // Call Java Static Instruction 16554 16555 instruct CallStaticJavaDirect(method meth) 16556 %{ 16557 match(CallStaticJava); 16558 16559 effect(USE meth); 16560 16561 ins_cost(CALL_COST); 16562 16563 format %{ "call,static $meth \t// ==> " %} 16564 16565 ins_encode(aarch64_enc_java_static_call(meth), 16566 aarch64_enc_call_epilog); 16567 16568 ins_pipe(pipe_class_call); 16569 %} 16570 16571 // TO HERE 16572 16573 // Call Java Dynamic Instruction 16574 instruct CallDynamicJavaDirect(method meth) 16575 %{ 16576 match(CallDynamicJava); 16577 16578 effect(USE meth); 16579 16580 ins_cost(CALL_COST); 16581 16582 format %{ "CALL,dynamic $meth \t// ==> " %} 16583 16584 ins_encode(aarch64_enc_java_dynamic_call(meth), 16585 aarch64_enc_call_epilog); 16586 16587 ins_pipe(pipe_class_call); 16588 %} 16589 16590 // Call Runtime Instruction 16591 16592 instruct CallRuntimeDirect(method meth) 16593 %{ 16594 match(CallRuntime); 16595 16596 effect(USE meth); 16597 16598 ins_cost(CALL_COST); 16599 16600 format %{ "CALL, runtime $meth" %} 16601 16602 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16603 16604 ins_pipe(pipe_class_call); 16605 %} 16606 16607 // Call Runtime Instruction 16608 16609 instruct CallLeafDirect(method meth) 16610 %{ 16611 match(CallLeaf); 16612 16613 effect(USE meth); 16614 16615 ins_cost(CALL_COST); 16616 16617 format %{ "CALL, runtime leaf $meth" %} 16618 16619 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16620 16621 ins_pipe(pipe_class_call); 16622 %} 16623 16624 // Call Runtime Instruction 16625 16626 // entry point is null, target holds the address to call 16627 instruct CallLeafNoFPIndirect(iRegP target) 16628 %{ 16629 predicate(n->as_Call()->entry_point() == nullptr); 16630 16631 match(CallLeafNoFP target); 16632 16633 ins_cost(CALL_COST); 16634 16635 format %{ "CALL, runtime leaf nofp indirect $target" %} 16636 16637 ins_encode %{ 16638 __ blr($target$$Register); 16639 %} 16640 16641 ins_pipe(pipe_class_call); 16642 %} 16643 16644 instruct CallLeafNoFPDirect(method meth) 16645 %{ 16646 predicate(n->as_Call()->entry_point() != nullptr); 16647 16648 match(CallLeafNoFP); 16649 16650 effect(USE meth); 16651 16652 ins_cost(CALL_COST); 16653 16654 format %{ "CALL, runtime leaf nofp $meth" %} 16655 16656 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16657 16658 ins_pipe(pipe_class_call); 16659 %} 16660 16661 // Tail Call; Jump from runtime stub to Java code. 16662 // Also known as an 'interprocedural jump'. 16663 // Target of jump will eventually return to caller. 16664 // TailJump below removes the return address. 16665 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_ptr) 16666 %{ 16667 match(TailCall jump_target method_ptr); 16668 16669 ins_cost(CALL_COST); 16670 16671 format %{ "br $jump_target\t# $method_ptr holds method" %} 16672 16673 ins_encode(aarch64_enc_tail_call(jump_target)); 16674 16675 ins_pipe(pipe_class_call); 16676 %} 16677 16678 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 16679 %{ 16680 match(TailJump jump_target ex_oop); 16681 16682 ins_cost(CALL_COST); 16683 16684 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 16685 16686 ins_encode(aarch64_enc_tail_jmp(jump_target)); 16687 16688 ins_pipe(pipe_class_call); 16689 %} 16690 16691 // Create exception oop: created by stack-crawling runtime code. 16692 // Created exception is now available to this handler, and is setup 16693 // just prior to jumping to this handler. No code emitted. 16694 // TODO check 16695 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 16696 instruct CreateException(iRegP_R0 ex_oop) 16697 %{ 16698 match(Set ex_oop (CreateEx)); 16699 16700 format %{ " -- \t// exception oop; no code emitted" %} 16701 16702 size(0); 16703 16704 ins_encode( /*empty*/ ); 16705 16706 ins_pipe(pipe_class_empty); 16707 %} 16708 16709 // Rethrow exception: The exception oop will come in the first 16710 // argument position. Then JUMP (not call) to the rethrow stub code. 16711 instruct RethrowException() %{ 16712 match(Rethrow); 16713 ins_cost(CALL_COST); 16714 16715 format %{ "b rethrow_stub" %} 16716 16717 ins_encode( aarch64_enc_rethrow() ); 16718 16719 ins_pipe(pipe_class_call); 16720 %} 16721 16722 16723 // Return Instruction 16724 // epilog node loads ret address into lr as part of frame pop 16725 instruct Ret() 16726 %{ 16727 match(Return); 16728 16729 format %{ "ret\t// return register" %} 16730 16731 ins_encode( aarch64_enc_ret() ); 16732 16733 ins_pipe(pipe_branch); 16734 %} 16735 16736 // Die now. 16737 instruct ShouldNotReachHere() %{ 16738 match(Halt); 16739 16740 ins_cost(CALL_COST); 16741 format %{ "ShouldNotReachHere" %} 16742 16743 ins_encode %{ 16744 if (is_reachable()) { 16745 __ stop(_halt_reason); 16746 } 16747 %} 16748 16749 ins_pipe(pipe_class_default); 16750 %} 16751 16752 // ============================================================================ 16753 // Partial Subtype Check 16754 // 16755 // superklass array for an instance of the superklass. Set a hidden 16756 // internal cache on a hit (cache is checked with exposed code in 16757 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 16758 // encoding ALSO sets flags. 16759 16760 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 16761 %{ 16762 match(Set result (PartialSubtypeCheck sub super)); 16763 effect(KILL cr, KILL temp); 16764 16765 ins_cost(1100); // slightly larger than the next version 16766 format %{ "partialSubtypeCheck $result, $sub, $super" %} 16767 16768 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 16769 16770 opcode(0x1); // Force zero of result reg on hit 16771 16772 ins_pipe(pipe_class_memory); 16773 %} 16774 16775 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 16776 %{ 16777 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 16778 effect(KILL temp, KILL result); 16779 16780 ins_cost(1100); // slightly larger than the next version 16781 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 16782 16783 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 16784 16785 opcode(0x0); // Don't zero result reg on hit 16786 16787 ins_pipe(pipe_class_memory); 16788 %} 16789 16790 // Intrisics for String.compareTo() 16791 16792 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16793 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 16794 %{ 16795 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU)); 16796 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16797 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16798 16799 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 16800 ins_encode %{ 16801 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16802 __ string_compare($str1$$Register, $str2$$Register, 16803 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16804 $tmp1$$Register, $tmp2$$Register, 16805 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::UU); 16806 %} 16807 ins_pipe(pipe_class_memory); 16808 %} 16809 16810 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16811 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 16812 %{ 16813 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL)); 16814 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16815 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16816 16817 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 16818 ins_encode %{ 16819 __ string_compare($str1$$Register, $str2$$Register, 16820 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16821 $tmp1$$Register, $tmp2$$Register, 16822 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::LL); 16823 %} 16824 ins_pipe(pipe_class_memory); 16825 %} 16826 16827 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16828 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16829 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 16830 %{ 16831 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL)); 16832 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16833 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 16834 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16835 16836 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 16837 ins_encode %{ 16838 __ string_compare($str1$$Register, $str2$$Register, 16839 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16840 $tmp1$$Register, $tmp2$$Register, 16841 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 16842 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::UL); 16843 %} 16844 ins_pipe(pipe_class_memory); 16845 %} 16846 16847 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16848 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16849 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 16850 %{ 16851 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU)); 16852 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16853 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 16854 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16855 16856 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 16857 ins_encode %{ 16858 __ string_compare($str1$$Register, $str2$$Register, 16859 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16860 $tmp1$$Register, $tmp2$$Register, 16861 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 16862 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::LU); 16863 %} 16864 ins_pipe(pipe_class_memory); 16865 %} 16866 16867 // Note that Z registers alias the corresponding NEON registers, we declare the vector operands of 16868 // these string_compare variants as NEON register type for convenience so that the prototype of 16869 // string_compare can be shared with all variants. 16870 16871 instruct string_compareLL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16872 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16873 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16874 pRegGov_P1 pgtmp2, rFlagsReg cr) 16875 %{ 16876 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL)); 16877 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16878 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16879 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16880 16881 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16882 ins_encode %{ 16883 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16884 __ string_compare($str1$$Register, $str2$$Register, 16885 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16886 $tmp1$$Register, $tmp2$$Register, 16887 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16888 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16889 StrIntrinsicNode::LL); 16890 %} 16891 ins_pipe(pipe_class_memory); 16892 %} 16893 16894 instruct string_compareLU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16895 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16896 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16897 pRegGov_P1 pgtmp2, rFlagsReg cr) 16898 %{ 16899 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU)); 16900 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16901 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16902 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16903 16904 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16905 ins_encode %{ 16906 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16907 __ string_compare($str1$$Register, $str2$$Register, 16908 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16909 $tmp1$$Register, $tmp2$$Register, 16910 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16911 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16912 StrIntrinsicNode::LU); 16913 %} 16914 ins_pipe(pipe_class_memory); 16915 %} 16916 16917 instruct string_compareUL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16918 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16919 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16920 pRegGov_P1 pgtmp2, rFlagsReg cr) 16921 %{ 16922 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL)); 16923 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16924 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16925 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16926 16927 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16928 ins_encode %{ 16929 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16930 __ string_compare($str1$$Register, $str2$$Register, 16931 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16932 $tmp1$$Register, $tmp2$$Register, 16933 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16934 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16935 StrIntrinsicNode::UL); 16936 %} 16937 ins_pipe(pipe_class_memory); 16938 %} 16939 16940 instruct string_compareUU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16941 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16942 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16943 pRegGov_P1 pgtmp2, rFlagsReg cr) 16944 %{ 16945 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU)); 16946 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16947 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16948 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16949 16950 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16951 ins_encode %{ 16952 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16953 __ string_compare($str1$$Register, $str2$$Register, 16954 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16955 $tmp1$$Register, $tmp2$$Register, 16956 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16957 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16958 StrIntrinsicNode::UU); 16959 %} 16960 ins_pipe(pipe_class_memory); 16961 %} 16962 16963 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16964 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 16965 iRegINoSp tmp3, iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 16966 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 16967 %{ 16968 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 16969 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16970 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16971 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, 16972 TEMP vtmp0, TEMP vtmp1, KILL cr); 16973 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU) " 16974 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 16975 16976 ins_encode %{ 16977 __ string_indexof($str1$$Register, $str2$$Register, 16978 $cnt1$$Register, $cnt2$$Register, 16979 $tmp1$$Register, $tmp2$$Register, 16980 $tmp3$$Register, $tmp4$$Register, 16981 $tmp5$$Register, $tmp6$$Register, 16982 -1, $result$$Register, StrIntrinsicNode::UU); 16983 %} 16984 ins_pipe(pipe_class_memory); 16985 %} 16986 16987 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16988 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 16989 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 16990 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 16991 %{ 16992 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 16993 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16994 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16995 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, 16996 TEMP vtmp0, TEMP vtmp1, KILL cr); 16997 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL) " 16998 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 16999 17000 ins_encode %{ 17001 __ string_indexof($str1$$Register, $str2$$Register, 17002 $cnt1$$Register, $cnt2$$Register, 17003 $tmp1$$Register, $tmp2$$Register, 17004 $tmp3$$Register, $tmp4$$Register, 17005 $tmp5$$Register, $tmp6$$Register, 17006 -1, $result$$Register, StrIntrinsicNode::LL); 17007 %} 17008 ins_pipe(pipe_class_memory); 17009 %} 17010 17011 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 17012 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,iRegINoSp tmp3, 17013 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 17014 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 17015 %{ 17016 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 17017 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 17018 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 17019 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 17020 TEMP tmp6, TEMP vtmp0, TEMP vtmp1, KILL cr); 17021 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL) " 17022 "# KILL $str1 cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 17023 17024 ins_encode %{ 17025 __ string_indexof($str1$$Register, $str2$$Register, 17026 $cnt1$$Register, $cnt2$$Register, 17027 $tmp1$$Register, $tmp2$$Register, 17028 $tmp3$$Register, $tmp4$$Register, 17029 $tmp5$$Register, $tmp6$$Register, 17030 -1, $result$$Register, StrIntrinsicNode::UL); 17031 %} 17032 ins_pipe(pipe_class_memory); 17033 %} 17034 17035 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 17036 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 17037 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 17038 %{ 17039 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 17040 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 17041 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 17042 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 17043 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU) " 17044 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 17045 17046 ins_encode %{ 17047 int icnt2 = (int)$int_cnt2$$constant; 17048 __ string_indexof($str1$$Register, $str2$$Register, 17049 $cnt1$$Register, zr, 17050 $tmp1$$Register, $tmp2$$Register, 17051 $tmp3$$Register, $tmp4$$Register, zr, zr, 17052 icnt2, $result$$Register, StrIntrinsicNode::UU); 17053 %} 17054 ins_pipe(pipe_class_memory); 17055 %} 17056 17057 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 17058 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 17059 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 17060 %{ 17061 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 17062 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 17063 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 17064 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 17065 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL) " 17066 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 17067 17068 ins_encode %{ 17069 int icnt2 = (int)$int_cnt2$$constant; 17070 __ string_indexof($str1$$Register, $str2$$Register, 17071 $cnt1$$Register, zr, 17072 $tmp1$$Register, $tmp2$$Register, 17073 $tmp3$$Register, $tmp4$$Register, zr, zr, 17074 icnt2, $result$$Register, StrIntrinsicNode::LL); 17075 %} 17076 ins_pipe(pipe_class_memory); 17077 %} 17078 17079 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 17080 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 17081 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 17082 %{ 17083 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 17084 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 17085 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 17086 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 17087 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL) " 17088 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 17089 17090 ins_encode %{ 17091 int icnt2 = (int)$int_cnt2$$constant; 17092 __ string_indexof($str1$$Register, $str2$$Register, 17093 $cnt1$$Register, zr, 17094 $tmp1$$Register, $tmp2$$Register, 17095 $tmp3$$Register, $tmp4$$Register, zr, zr, 17096 icnt2, $result$$Register, StrIntrinsicNode::UL); 17097 %} 17098 ins_pipe(pipe_class_memory); 17099 %} 17100 17101 instruct string_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17102 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 17103 iRegINoSp tmp3, rFlagsReg cr) 17104 %{ 17105 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17106 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 17107 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 17108 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 17109 17110 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result" %} 17111 17112 ins_encode %{ 17113 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 17114 $result$$Register, $tmp1$$Register, $tmp2$$Register, 17115 $tmp3$$Register); 17116 %} 17117 ins_pipe(pipe_class_memory); 17118 %} 17119 17120 instruct stringL_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17121 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 17122 iRegINoSp tmp3, rFlagsReg cr) 17123 %{ 17124 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17125 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 17126 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 17127 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 17128 17129 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result" %} 17130 17131 ins_encode %{ 17132 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 17133 $result$$Register, $tmp1$$Register, $tmp2$$Register, 17134 $tmp3$$Register); 17135 %} 17136 ins_pipe(pipe_class_memory); 17137 %} 17138 17139 instruct stringL_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17140 iRegI_R0 result, vecA ztmp1, vecA ztmp2, 17141 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{ 17142 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L); 17143 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17144 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr); 17145 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %} 17146 ins_encode %{ 17147 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register, 17148 $result$$Register, $ztmp1$$FloatRegister, 17149 $ztmp2$$FloatRegister, $pgtmp$$PRegister, 17150 $ptmp$$PRegister, true /* isL */); 17151 %} 17152 ins_pipe(pipe_class_memory); 17153 %} 17154 17155 instruct stringU_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17156 iRegI_R0 result, vecA ztmp1, vecA ztmp2, 17157 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{ 17158 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U); 17159 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17160 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr); 17161 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %} 17162 ins_encode %{ 17163 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register, 17164 $result$$Register, $ztmp1$$FloatRegister, 17165 $ztmp2$$FloatRegister, $pgtmp$$PRegister, 17166 $ptmp$$PRegister, false /* isL */); 17167 %} 17168 ins_pipe(pipe_class_memory); 17169 %} 17170 17171 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 17172 iRegI_R0 result, rFlagsReg cr) 17173 %{ 17174 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 17175 match(Set result (StrEquals (Binary str1 str2) cnt)); 17176 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 17177 17178 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 17179 ins_encode %{ 17180 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 17181 __ string_equals($str1$$Register, $str2$$Register, 17182 $result$$Register, $cnt$$Register); 17183 %} 17184 ins_pipe(pipe_class_memory); 17185 %} 17186 17187 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 17188 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 17189 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 17190 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7, 17191 iRegP_R10 tmp, rFlagsReg cr) 17192 %{ 17193 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 17194 match(Set result (AryEq ary1 ary2)); 17195 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, 17196 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 17197 TEMP vtmp6, TEMP vtmp7, KILL cr); 17198 17199 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %} 17200 ins_encode %{ 17201 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 17202 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 17203 $result$$Register, $tmp$$Register, 1); 17204 if (tpc == nullptr) { 17205 ciEnv::current()->record_failure("CodeCache is full"); 17206 return; 17207 } 17208 %} 17209 ins_pipe(pipe_class_memory); 17210 %} 17211 17212 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 17213 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 17214 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 17215 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7, 17216 iRegP_R10 tmp, rFlagsReg cr) 17217 %{ 17218 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 17219 match(Set result (AryEq ary1 ary2)); 17220 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, 17221 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 17222 TEMP vtmp6, TEMP vtmp7, KILL cr); 17223 17224 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %} 17225 ins_encode %{ 17226 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 17227 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 17228 $result$$Register, $tmp$$Register, 2); 17229 if (tpc == nullptr) { 17230 ciEnv::current()->record_failure("CodeCache is full"); 17231 return; 17232 } 17233 %} 17234 ins_pipe(pipe_class_memory); 17235 %} 17236 17237 instruct count_positives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 17238 %{ 17239 match(Set result (CountPositives ary1 len)); 17240 effect(USE_KILL ary1, USE_KILL len, KILL cr); 17241 format %{ "count positives byte[] $ary1,$len -> $result" %} 17242 ins_encode %{ 17243 address tpc = __ count_positives($ary1$$Register, $len$$Register, $result$$Register); 17244 if (tpc == nullptr) { 17245 ciEnv::current()->record_failure("CodeCache is full"); 17246 return; 17247 } 17248 %} 17249 ins_pipe( pipe_slow ); 17250 %} 17251 17252 // fast char[] to byte[] compression 17253 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 17254 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 17255 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 17256 iRegI_R0 result, rFlagsReg cr) 17257 %{ 17258 match(Set result (StrCompressedCopy src (Binary dst len))); 17259 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 17260 USE_KILL src, USE_KILL dst, USE len, KILL cr); 17261 17262 format %{ "String Compress $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 17263 ins_encode %{ 17264 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 17265 $result$$Register, $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17266 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 17267 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 17268 %} 17269 ins_pipe(pipe_slow); 17270 %} 17271 17272 // fast byte[] to char[] inflation 17273 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, iRegP_R3 tmp, 17274 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 17275 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, rFlagsReg cr) 17276 %{ 17277 match(Set dummy (StrInflatedCopy src (Binary dst len))); 17278 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, 17279 TEMP vtmp4, TEMP vtmp5, TEMP vtmp6, TEMP tmp, 17280 USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 17281 17282 format %{ "String Inflate $src,$dst # KILL $tmp $src $dst $len V0-V6 cr" %} 17283 ins_encode %{ 17284 address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 17285 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17286 $vtmp2$$FloatRegister, $tmp$$Register); 17287 if (tpc == nullptr) { 17288 ciEnv::current()->record_failure("CodeCache is full"); 17289 return; 17290 } 17291 %} 17292 ins_pipe(pipe_class_memory); 17293 %} 17294 17295 // encode char[] to byte[] in ISO_8859_1 17296 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 17297 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 17298 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 17299 iRegI_R0 result, rFlagsReg cr) 17300 %{ 17301 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 17302 match(Set result (EncodeISOArray src (Binary dst len))); 17303 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1, 17304 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr); 17305 17306 format %{ "Encode ISO array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 17307 ins_encode %{ 17308 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 17309 $result$$Register, false, 17310 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17311 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 17312 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 17313 %} 17314 ins_pipe(pipe_class_memory); 17315 %} 17316 17317 instruct encode_ascii_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 17318 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 17319 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 17320 iRegI_R0 result, rFlagsReg cr) 17321 %{ 17322 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 17323 match(Set result (EncodeISOArray src (Binary dst len))); 17324 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1, 17325 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr); 17326 17327 format %{ "Encode ASCII array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 17328 ins_encode %{ 17329 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 17330 $result$$Register, true, 17331 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17332 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 17333 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 17334 %} 17335 ins_pipe(pipe_class_memory); 17336 %} 17337 17338 //----------------------------- CompressBits/ExpandBits ------------------------ 17339 17340 instruct compressBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask, 17341 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17342 match(Set dst (CompressBits src mask)); 17343 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17344 format %{ "mov $tsrc, $src\n\t" 17345 "mov $tmask, $mask\n\t" 17346 "bext $tdst, $tsrc, $tmask\n\t" 17347 "mov $dst, $tdst" 17348 %} 17349 ins_encode %{ 17350 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register); 17351 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register); 17352 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17353 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17354 %} 17355 ins_pipe(pipe_slow); 17356 %} 17357 17358 instruct compressBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask, 17359 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17360 match(Set dst (CompressBits (LoadI mem) mask)); 17361 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17362 format %{ "ldrs $tsrc, $mem\n\t" 17363 "ldrs $tmask, $mask\n\t" 17364 "bext $tdst, $tsrc, $tmask\n\t" 17365 "mov $dst, $tdst" 17366 %} 17367 ins_encode %{ 17368 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(), 17369 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 17370 __ ldrs($tmask$$FloatRegister, $constantaddress($mask)); 17371 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17372 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17373 %} 17374 ins_pipe(pipe_slow); 17375 %} 17376 17377 instruct compressBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask, 17378 vRegD tdst, vRegD tsrc, vRegD tmask) %{ 17379 match(Set dst (CompressBits src mask)); 17380 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17381 format %{ "mov $tsrc, $src\n\t" 17382 "mov $tmask, $mask\n\t" 17383 "bext $tdst, $tsrc, $tmask\n\t" 17384 "mov $dst, $tdst" 17385 %} 17386 ins_encode %{ 17387 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register); 17388 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register); 17389 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17390 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17391 %} 17392 ins_pipe(pipe_slow); 17393 %} 17394 17395 instruct compressBitsL_memcon(iRegLNoSp dst, memory8 mem, immL mask, 17396 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17397 match(Set dst (CompressBits (LoadL mem) mask)); 17398 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17399 format %{ "ldrd $tsrc, $mem\n\t" 17400 "ldrd $tmask, $mask\n\t" 17401 "bext $tdst, $tsrc, $tmask\n\t" 17402 "mov $dst, $tdst" 17403 %} 17404 ins_encode %{ 17405 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(), 17406 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 17407 __ ldrd($tmask$$FloatRegister, $constantaddress($mask)); 17408 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17409 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17410 %} 17411 ins_pipe(pipe_slow); 17412 %} 17413 17414 instruct expandBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask, 17415 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17416 match(Set dst (ExpandBits src mask)); 17417 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17418 format %{ "mov $tsrc, $src\n\t" 17419 "mov $tmask, $mask\n\t" 17420 "bdep $tdst, $tsrc, $tmask\n\t" 17421 "mov $dst, $tdst" 17422 %} 17423 ins_encode %{ 17424 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register); 17425 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register); 17426 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17427 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17428 %} 17429 ins_pipe(pipe_slow); 17430 %} 17431 17432 instruct expandBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask, 17433 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17434 match(Set dst (ExpandBits (LoadI mem) mask)); 17435 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17436 format %{ "ldrs $tsrc, $mem\n\t" 17437 "ldrs $tmask, $mask\n\t" 17438 "bdep $tdst, $tsrc, $tmask\n\t" 17439 "mov $dst, $tdst" 17440 %} 17441 ins_encode %{ 17442 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(), 17443 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 17444 __ ldrs($tmask$$FloatRegister, $constantaddress($mask)); 17445 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17446 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17447 %} 17448 ins_pipe(pipe_slow); 17449 %} 17450 17451 instruct expandBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask, 17452 vRegD tdst, vRegD tsrc, vRegD tmask) %{ 17453 match(Set dst (ExpandBits src mask)); 17454 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17455 format %{ "mov $tsrc, $src\n\t" 17456 "mov $tmask, $mask\n\t" 17457 "bdep $tdst, $tsrc, $tmask\n\t" 17458 "mov $dst, $tdst" 17459 %} 17460 ins_encode %{ 17461 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register); 17462 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register); 17463 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17464 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17465 %} 17466 ins_pipe(pipe_slow); 17467 %} 17468 17469 17470 instruct expandBitsL_memcon(iRegINoSp dst, memory8 mem, immL mask, 17471 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17472 match(Set dst (ExpandBits (LoadL mem) mask)); 17473 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17474 format %{ "ldrd $tsrc, $mem\n\t" 17475 "ldrd $tmask, $mask\n\t" 17476 "bdep $tdst, $tsrc, $tmask\n\t" 17477 "mov $dst, $tdst" 17478 %} 17479 ins_encode %{ 17480 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(), 17481 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 17482 __ ldrd($tmask$$FloatRegister, $constantaddress($mask)); 17483 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17484 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17485 %} 17486 ins_pipe(pipe_slow); 17487 %} 17488 17489 // ============================================================================ 17490 // This name is KNOWN by the ADLC and cannot be changed. 17491 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 17492 // for this guy. 17493 instruct tlsLoadP(thread_RegP dst) 17494 %{ 17495 match(Set dst (ThreadLocal)); 17496 17497 ins_cost(0); 17498 17499 format %{ " -- \t// $dst=Thread::current(), empty" %} 17500 17501 size(0); 17502 17503 ins_encode( /*empty*/ ); 17504 17505 ins_pipe(pipe_class_empty); 17506 %} 17507 17508 //----------PEEPHOLE RULES----------------------------------------------------- 17509 // These must follow all instruction definitions as they use the names 17510 // defined in the instructions definitions. 17511 // 17512 // peepmatch ( root_instr_name [preceding_instruction]* ); 17513 // 17514 // peepconstraint %{ 17515 // (instruction_number.operand_name relational_op instruction_number.operand_name 17516 // [, ...] ); 17517 // // instruction numbers are zero-based using left to right order in peepmatch 17518 // 17519 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 17520 // // provide an instruction_number.operand_name for each operand that appears 17521 // // in the replacement instruction's match rule 17522 // 17523 // ---------VM FLAGS--------------------------------------------------------- 17524 // 17525 // All peephole optimizations can be turned off using -XX:-OptoPeephole 17526 // 17527 // Each peephole rule is given an identifying number starting with zero and 17528 // increasing by one in the order seen by the parser. An individual peephole 17529 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 17530 // on the command-line. 17531 // 17532 // ---------CURRENT LIMITATIONS---------------------------------------------- 17533 // 17534 // Only match adjacent instructions in same basic block 17535 // Only equality constraints 17536 // Only constraints between operands, not (0.dest_reg == RAX_enc) 17537 // Only one replacement instruction 17538 // 17539 // ---------EXAMPLE---------------------------------------------------------- 17540 // 17541 // // pertinent parts of existing instructions in architecture description 17542 // instruct movI(iRegINoSp dst, iRegI src) 17543 // %{ 17544 // match(Set dst (CopyI src)); 17545 // %} 17546 // 17547 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 17548 // %{ 17549 // match(Set dst (AddI dst src)); 17550 // effect(KILL cr); 17551 // %} 17552 // 17553 // // Change (inc mov) to lea 17554 // peephole %{ 17555 // // increment preceded by register-register move 17556 // peepmatch ( incI_iReg movI ); 17557 // // require that the destination register of the increment 17558 // // match the destination register of the move 17559 // peepconstraint ( 0.dst == 1.dst ); 17560 // // construct a replacement instruction that sets 17561 // // the destination to ( move's source register + one ) 17562 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 17563 // %} 17564 // 17565 17566 // Implementation no longer uses movX instructions since 17567 // machine-independent system no longer uses CopyX nodes. 17568 // 17569 // peephole 17570 // %{ 17571 // peepmatch (incI_iReg movI); 17572 // peepconstraint (0.dst == 1.dst); 17573 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17574 // %} 17575 17576 // peephole 17577 // %{ 17578 // peepmatch (decI_iReg movI); 17579 // peepconstraint (0.dst == 1.dst); 17580 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17581 // %} 17582 17583 // peephole 17584 // %{ 17585 // peepmatch (addI_iReg_imm movI); 17586 // peepconstraint (0.dst == 1.dst); 17587 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17588 // %} 17589 17590 // peephole 17591 // %{ 17592 // peepmatch (incL_iReg movL); 17593 // peepconstraint (0.dst == 1.dst); 17594 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17595 // %} 17596 17597 // peephole 17598 // %{ 17599 // peepmatch (decL_iReg movL); 17600 // peepconstraint (0.dst == 1.dst); 17601 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17602 // %} 17603 17604 // peephole 17605 // %{ 17606 // peepmatch (addL_iReg_imm movL); 17607 // peepconstraint (0.dst == 1.dst); 17608 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17609 // %} 17610 17611 // peephole 17612 // %{ 17613 // peepmatch (addP_iReg_imm movP); 17614 // peepconstraint (0.dst == 1.dst); 17615 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 17616 // %} 17617 17618 // // Change load of spilled value to only a spill 17619 // instruct storeI(memory mem, iRegI src) 17620 // %{ 17621 // match(Set mem (StoreI mem src)); 17622 // %} 17623 // 17624 // instruct loadI(iRegINoSp dst, memory mem) 17625 // %{ 17626 // match(Set dst (LoadI mem)); 17627 // %} 17628 // 17629 17630 //----------SMARTSPILL RULES--------------------------------------------------- 17631 // These must follow all instruction definitions as they use the names 17632 // defined in the instructions definitions. 17633 17634 // Local Variables: 17635 // mode: c++ 17636 // End: