1 // 2 // Copyright (c) 2003, 2023, 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 if (CompressedKlassPointers::shift() != 0) { 2214 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 2215 } 2216 } else { 2217 st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 2218 } 2219 st->print_cr("\tcmp r0, rscratch1\t # Inline cache check"); 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 Label skip; 2229 2230 // UseCompressedClassPointers logic are inside cmp_klass 2231 __ cmp_klass(j_rarg0, rscratch2, rscratch1); 2232 2233 // TODO 2234 // can we avoid this skip and still use a reloc? 2235 __ br(Assembler::EQ, skip); 2236 __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 2237 __ bind(skip); 2238 } 2239 2240 // REQUIRED EMIT CODE 2241 2242 //============================================================================= 2243 2244 // Emit exception handler code. 2245 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) 2246 { 2247 // mov rscratch1 #exception_blob_entry_point 2248 // br rscratch1 2249 // Note that the code buffer's insts_mark is always relative to insts. 2250 // That's why we must use the macroassembler to generate a handler. 2251 C2_MacroAssembler _masm(&cbuf); 2252 address base = __ start_a_stub(size_exception_handler()); 2253 if (base == nullptr) { 2254 ciEnv::current()->record_failure("CodeCache is full"); 2255 return 0; // CodeBuffer::expand failed 2256 } 2257 int offset = __ offset(); 2258 __ far_jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 2259 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 2260 __ end_a_stub(); 2261 return offset; 2262 } 2263 2264 // Emit deopt handler code. 2265 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) 2266 { 2267 // Note that the code buffer's insts_mark is always relative to insts. 2268 // That's why we must use the macroassembler to generate a handler. 2269 C2_MacroAssembler _masm(&cbuf); 2270 address base = __ start_a_stub(size_deopt_handler()); 2271 if (base == nullptr) { 2272 ciEnv::current()->record_failure("CodeCache is full"); 2273 return 0; // CodeBuffer::expand failed 2274 } 2275 int offset = __ offset(); 2276 2277 __ adr(lr, __ pc()); 2278 __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 2279 2280 assert(__ offset() - offset == (int) size_deopt_handler(), "overflow"); 2281 __ end_a_stub(); 2282 return offset; 2283 } 2284 2285 // REQUIRED MATCHER CODE 2286 2287 //============================================================================= 2288 2289 bool Matcher::match_rule_supported(int opcode) { 2290 if (!has_match_rule(opcode)) 2291 return false; 2292 2293 switch (opcode) { 2294 case Op_OnSpinWait: 2295 return VM_Version::supports_on_spin_wait(); 2296 case Op_CacheWB: 2297 case Op_CacheWBPreSync: 2298 case Op_CacheWBPostSync: 2299 if (!VM_Version::supports_data_cache_line_flush()) { 2300 return false; 2301 } 2302 break; 2303 case Op_ExpandBits: 2304 case Op_CompressBits: 2305 if (!VM_Version::supports_svebitperm()) { 2306 return false; 2307 } 2308 break; 2309 case Op_FmaF: 2310 case Op_FmaD: 2311 case Op_FmaVF: 2312 case Op_FmaVD: 2313 if (!UseFMA) { 2314 return false; 2315 } 2316 break; 2317 } 2318 2319 return true; // Per default match rules are supported. 2320 } 2321 2322 const RegMask* Matcher::predicate_reg_mask(void) { 2323 return &_PR_REG_mask; 2324 } 2325 2326 const TypeVectMask* Matcher::predicate_reg_type(const Type* elemTy, int length) { 2327 return new TypeVectMask(elemTy, length); 2328 } 2329 2330 // Vector calling convention not yet implemented. 2331 bool Matcher::supports_vector_calling_convention(void) { 2332 return false; 2333 } 2334 2335 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 2336 Unimplemented(); 2337 return OptoRegPair(0, 0); 2338 } 2339 2340 // Is this branch offset short enough that a short branch can be used? 2341 // 2342 // NOTE: If the platform does not provide any short branch variants, then 2343 // this method should return false for offset 0. 2344 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2345 // The passed offset is relative to address of the branch. 2346 2347 return (-32768 <= offset && offset < 32768); 2348 } 2349 2350 // Vector width in bytes. 2351 int Matcher::vector_width_in_bytes(BasicType bt) { 2352 // The MaxVectorSize should have been set by detecting SVE max vector register size. 2353 int size = MIN2((UseSVE > 0) ? 256 : 16, (int)MaxVectorSize); 2354 // Minimum 2 values in vector 2355 if (size < 2*type2aelembytes(bt)) size = 0; 2356 // But never < 4 2357 if (size < 4) size = 0; 2358 return size; 2359 } 2360 2361 // Limits on vector size (number of elements) loaded into vector. 2362 int Matcher::max_vector_size(const BasicType bt) { 2363 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2364 } 2365 2366 int Matcher::min_vector_size(const BasicType bt) { 2367 int max_size = max_vector_size(bt); 2368 // Limit the min vector size to 8 bytes. 2369 int size = 8 / type2aelembytes(bt); 2370 if (bt == T_BYTE) { 2371 // To support vector api shuffle/rearrange. 2372 size = 4; 2373 } else if (bt == T_BOOLEAN) { 2374 // To support vector api load/store mask. 2375 size = 2; 2376 } 2377 if (size < 2) size = 2; 2378 return MIN2(size, max_size); 2379 } 2380 2381 int Matcher::superword_max_vector_size(const BasicType bt) { 2382 return Matcher::max_vector_size(bt); 2383 } 2384 2385 // Actual max scalable vector register length. 2386 int Matcher::scalable_vector_reg_size(const BasicType bt) { 2387 return Matcher::max_vector_size(bt); 2388 } 2389 2390 // Vector ideal reg. 2391 uint Matcher::vector_ideal_reg(int len) { 2392 if (UseSVE > 0 && 16 < len && len <= 256) { 2393 return Op_VecA; 2394 } 2395 switch(len) { 2396 // For 16-bit/32-bit mask vector, reuse VecD. 2397 case 2: 2398 case 4: 2399 case 8: return Op_VecD; 2400 case 16: return Op_VecX; 2401 } 2402 ShouldNotReachHere(); 2403 return 0; 2404 } 2405 2406 MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg, bool is_temp) { 2407 assert(Matcher::is_generic_vector(generic_opnd), "not generic"); 2408 switch (ideal_reg) { 2409 case Op_VecA: return new vecAOper(); 2410 case Op_VecD: return new vecDOper(); 2411 case Op_VecX: return new vecXOper(); 2412 } 2413 ShouldNotReachHere(); 2414 return nullptr; 2415 } 2416 2417 bool Matcher::is_reg2reg_move(MachNode* m) { 2418 return false; 2419 } 2420 2421 bool Matcher::is_generic_vector(MachOper* opnd) { 2422 return opnd->opcode() == VREG; 2423 } 2424 2425 // Return whether or not this register is ever used as an argument. 2426 // This function is used on startup to build the trampoline stubs in 2427 // generateOptoStub. Registers not mentioned will be killed by the VM 2428 // call in the trampoline, and arguments in those registers not be 2429 // available to the callee. 2430 bool Matcher::can_be_java_arg(int reg) 2431 { 2432 return 2433 reg == R0_num || reg == R0_H_num || 2434 reg == R1_num || reg == R1_H_num || 2435 reg == R2_num || reg == R2_H_num || 2436 reg == R3_num || reg == R3_H_num || 2437 reg == R4_num || reg == R4_H_num || 2438 reg == R5_num || reg == R5_H_num || 2439 reg == R6_num || reg == R6_H_num || 2440 reg == R7_num || reg == R7_H_num || 2441 reg == V0_num || reg == V0_H_num || 2442 reg == V1_num || reg == V1_H_num || 2443 reg == V2_num || reg == V2_H_num || 2444 reg == V3_num || reg == V3_H_num || 2445 reg == V4_num || reg == V4_H_num || 2446 reg == V5_num || reg == V5_H_num || 2447 reg == V6_num || reg == V6_H_num || 2448 reg == V7_num || reg == V7_H_num; 2449 } 2450 2451 bool Matcher::is_spillable_arg(int reg) 2452 { 2453 return can_be_java_arg(reg); 2454 } 2455 2456 uint Matcher::int_pressure_limit() 2457 { 2458 // JDK-8183543: When taking the number of available registers as int 2459 // register pressure threshold, the jtreg test: 2460 // test/hotspot/jtreg/compiler/regalloc/TestC2IntPressure.java 2461 // failed due to C2 compilation failure with 2462 // "COMPILE SKIPPED: failed spill-split-recycle sanity check". 2463 // 2464 // A derived pointer is live at CallNode and then is flagged by RA 2465 // as a spilled LRG. Spilling heuristics(Spill-USE) explicitly skip 2466 // derived pointers and lastly fail to spill after reaching maximum 2467 // number of iterations. Lowering the default pressure threshold to 2468 // (_NO_SPECIAL_REG32_mask.Size() minus 1) forces CallNode to become 2469 // a high register pressure area of the code so that split_DEF can 2470 // generate DefinitionSpillCopy for the derived pointer. 2471 uint default_int_pressure_threshold = _NO_SPECIAL_REG32_mask.Size() - 1; 2472 if (!PreserveFramePointer) { 2473 // When PreserveFramePointer is off, frame pointer is allocatable, 2474 // but different from other SOC registers, it is excluded from 2475 // fatproj's mask because its save type is No-Save. Decrease 1 to 2476 // ensure high pressure at fatproj when PreserveFramePointer is off. 2477 // See check_pressure_at_fatproj(). 2478 default_int_pressure_threshold--; 2479 } 2480 return (INTPRESSURE == -1) ? default_int_pressure_threshold : INTPRESSURE; 2481 } 2482 2483 uint Matcher::float_pressure_limit() 2484 { 2485 // _FLOAT_REG_mask is generated by adlc from the float_reg register class. 2486 return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.Size() : FLOATPRESSURE; 2487 } 2488 2489 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2490 return false; 2491 } 2492 2493 RegMask Matcher::divI_proj_mask() { 2494 ShouldNotReachHere(); 2495 return RegMask(); 2496 } 2497 2498 // Register for MODI projection of divmodI. 2499 RegMask Matcher::modI_proj_mask() { 2500 ShouldNotReachHere(); 2501 return RegMask(); 2502 } 2503 2504 // Register for DIVL projection of divmodL. 2505 RegMask Matcher::divL_proj_mask() { 2506 ShouldNotReachHere(); 2507 return RegMask(); 2508 } 2509 2510 // Register for MODL projection of divmodL. 2511 RegMask Matcher::modL_proj_mask() { 2512 ShouldNotReachHere(); 2513 return RegMask(); 2514 } 2515 2516 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2517 return FP_REG_mask(); 2518 } 2519 2520 bool size_fits_all_mem_uses(AddPNode* addp, int shift) { 2521 for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) { 2522 Node* u = addp->fast_out(i); 2523 if (u->is_LoadStore()) { 2524 // On AArch64, LoadStoreNodes (i.e. compare and swap 2525 // instructions) only take register indirect as an operand, so 2526 // any attempt to use an AddPNode as an input to a LoadStoreNode 2527 // must fail. 2528 return false; 2529 } 2530 if (u->is_Mem()) { 2531 int opsize = u->as_Mem()->memory_size(); 2532 assert(opsize > 0, "unexpected memory operand size"); 2533 if (u->as_Mem()->memory_size() != (1<<shift)) { 2534 return false; 2535 } 2536 } 2537 } 2538 return true; 2539 } 2540 2541 // Convert BootTest condition to Assembler condition. 2542 // Replicate the logic of cmpOpOper::ccode() and cmpOpUOper::ccode(). 2543 Assembler::Condition to_assembler_cond(BoolTest::mask cond) { 2544 Assembler::Condition result; 2545 switch(cond) { 2546 case BoolTest::eq: 2547 result = Assembler::EQ; break; 2548 case BoolTest::ne: 2549 result = Assembler::NE; break; 2550 case BoolTest::le: 2551 result = Assembler::LE; break; 2552 case BoolTest::ge: 2553 result = Assembler::GE; break; 2554 case BoolTest::lt: 2555 result = Assembler::LT; break; 2556 case BoolTest::gt: 2557 result = Assembler::GT; break; 2558 case BoolTest::ule: 2559 result = Assembler::LS; break; 2560 case BoolTest::uge: 2561 result = Assembler::HS; break; 2562 case BoolTest::ult: 2563 result = Assembler::LO; break; 2564 case BoolTest::ugt: 2565 result = Assembler::HI; break; 2566 case BoolTest::overflow: 2567 result = Assembler::VS; break; 2568 case BoolTest::no_overflow: 2569 result = Assembler::VC; break; 2570 default: 2571 ShouldNotReachHere(); 2572 return Assembler::Condition(-1); 2573 } 2574 2575 // Check conversion 2576 if (cond & BoolTest::unsigned_compare) { 2577 assert(cmpOpUOper((BoolTest::mask)((int)cond & ~(BoolTest::unsigned_compare))).ccode() == result, "Invalid conversion"); 2578 } else { 2579 assert(cmpOpOper(cond).ccode() == result, "Invalid conversion"); 2580 } 2581 2582 return result; 2583 } 2584 2585 // Binary src (Replicate con) 2586 bool is_valid_sve_arith_imm_pattern(Node* n, Node* m) { 2587 if (n == nullptr || m == nullptr) { 2588 return false; 2589 } 2590 2591 if (UseSVE == 0 || m->Opcode() != Op_Replicate) { 2592 return false; 2593 } 2594 2595 Node* imm_node = m->in(1); 2596 if (!imm_node->is_Con()) { 2597 return false; 2598 } 2599 2600 const Type* t = imm_node->bottom_type(); 2601 if (!(t->isa_int() || t->isa_long())) { 2602 return false; 2603 } 2604 2605 switch (n->Opcode()) { 2606 case Op_AndV: 2607 case Op_OrV: 2608 case Op_XorV: { 2609 Assembler::SIMD_RegVariant T = Assembler::elemType_to_regVariant(Matcher::vector_element_basic_type(n)); 2610 uint64_t value = t->isa_long() ? (uint64_t)imm_node->get_long() : (uint64_t)imm_node->get_int(); 2611 return Assembler::operand_valid_for_sve_logical_immediate(Assembler::regVariant_to_elemBits(T), value); 2612 } 2613 case Op_AddVB: 2614 return (imm_node->get_int() <= 255 && imm_node->get_int() >= -255); 2615 case Op_AddVS: 2616 case Op_AddVI: 2617 return Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)imm_node->get_int()); 2618 case Op_AddVL: 2619 return Assembler::operand_valid_for_sve_add_sub_immediate(imm_node->get_long()); 2620 default: 2621 return false; 2622 } 2623 } 2624 2625 // (XorV src (Replicate m1)) 2626 // (XorVMask src (MaskAll m1)) 2627 bool is_vector_bitwise_not_pattern(Node* n, Node* m) { 2628 if (n != nullptr && m != nullptr) { 2629 return (n->Opcode() == Op_XorV || n->Opcode() == Op_XorVMask) && 2630 VectorNode::is_all_ones_vector(m); 2631 } 2632 return false; 2633 } 2634 2635 // Should the matcher clone input 'm' of node 'n'? 2636 bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { 2637 if (is_vshift_con_pattern(n, m) || 2638 is_vector_bitwise_not_pattern(n, m) || 2639 is_valid_sve_arith_imm_pattern(n, m)) { 2640 mstack.push(m, Visit); 2641 return true; 2642 } 2643 return false; 2644 } 2645 2646 // Should the Matcher clone shifts on addressing modes, expecting them 2647 // to be subsumed into complex addressing expressions or compute them 2648 // into registers? 2649 bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 2650 if (clone_base_plus_offset_address(m, mstack, address_visited)) { 2651 return true; 2652 } 2653 2654 Node *off = m->in(AddPNode::Offset); 2655 if (off->Opcode() == Op_LShiftL && off->in(2)->is_Con() && 2656 size_fits_all_mem_uses(m, off->in(2)->get_int()) && 2657 // Are there other uses besides address expressions? 2658 !is_visited(off)) { 2659 address_visited.set(off->_idx); // Flag as address_visited 2660 mstack.push(off->in(2), Visit); 2661 Node *conv = off->in(1); 2662 if (conv->Opcode() == Op_ConvI2L && 2663 // Are there other uses besides address expressions? 2664 !is_visited(conv)) { 2665 address_visited.set(conv->_idx); // Flag as address_visited 2666 mstack.push(conv->in(1), Pre_Visit); 2667 } else { 2668 mstack.push(conv, Pre_Visit); 2669 } 2670 address_visited.test_set(m->_idx); // Flag as address_visited 2671 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2672 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2673 return true; 2674 } else if (off->Opcode() == Op_ConvI2L && 2675 // Are there other uses besides address expressions? 2676 !is_visited(off)) { 2677 address_visited.test_set(m->_idx); // Flag as address_visited 2678 address_visited.set(off->_idx); // Flag as address_visited 2679 mstack.push(off->in(1), Pre_Visit); 2680 mstack.push(m->in(AddPNode::Address), Pre_Visit); 2681 mstack.push(m->in(AddPNode::Base), Pre_Visit); 2682 return true; 2683 } 2684 return false; 2685 } 2686 2687 #define MOV_VOLATILE(REG, BASE, INDEX, SCALE, DISP, SCRATCH, INSN) \ 2688 C2_MacroAssembler _masm(&cbuf); \ 2689 { \ 2690 guarantee(INDEX == -1, "mode not permitted for volatile"); \ 2691 guarantee(DISP == 0, "mode not permitted for volatile"); \ 2692 guarantee(SCALE == 0, "mode not permitted for volatile"); \ 2693 __ INSN(REG, as_Register(BASE)); \ 2694 } 2695 2696 2697 static Address mem2address(int opcode, Register base, int index, int size, int disp) 2698 { 2699 Address::extend scale; 2700 2701 // Hooboy, this is fugly. We need a way to communicate to the 2702 // encoder that the index needs to be sign extended, so we have to 2703 // enumerate all the cases. 2704 switch (opcode) { 2705 case INDINDEXSCALEDI2L: 2706 case INDINDEXSCALEDI2LN: 2707 case INDINDEXI2L: 2708 case INDINDEXI2LN: 2709 scale = Address::sxtw(size); 2710 break; 2711 default: 2712 scale = Address::lsl(size); 2713 } 2714 2715 if (index == -1) { 2716 return Address(base, disp); 2717 } else { 2718 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2719 return Address(base, as_Register(index), scale); 2720 } 2721 } 2722 2723 2724 typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr); 2725 typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr); 2726 typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr); 2727 typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt, 2728 MacroAssembler::SIMD_RegVariant T, const Address &adr); 2729 2730 // Used for all non-volatile memory accesses. The use of 2731 // $mem->opcode() to discover whether this pattern uses sign-extended 2732 // offsets is something of a kludge. 2733 static void loadStore(C2_MacroAssembler masm, mem_insn insn, 2734 Register reg, int opcode, 2735 Register base, int index, int scale, int disp, 2736 int size_in_memory) 2737 { 2738 Address addr = mem2address(opcode, base, index, scale, disp); 2739 if (addr.getMode() == Address::base_plus_offset) { 2740 /* If we get an out-of-range offset it is a bug in the compiler, 2741 so we assert here. */ 2742 assert(Address::offset_ok_for_immed(addr.offset(), exact_log2(size_in_memory)), 2743 "c2 compiler bug"); 2744 /* Fix up any out-of-range offsets. */ 2745 assert_different_registers(rscratch1, base); 2746 assert_different_registers(rscratch1, reg); 2747 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2748 } 2749 (masm.*insn)(reg, addr); 2750 } 2751 2752 static void loadStore(C2_MacroAssembler masm, mem_float_insn insn, 2753 FloatRegister reg, int opcode, 2754 Register base, int index, int size, int disp, 2755 int size_in_memory) 2756 { 2757 Address::extend scale; 2758 2759 switch (opcode) { 2760 case INDINDEXSCALEDI2L: 2761 case INDINDEXSCALEDI2LN: 2762 scale = Address::sxtw(size); 2763 break; 2764 default: 2765 scale = Address::lsl(size); 2766 } 2767 2768 if (index == -1) { 2769 /* If we get an out-of-range offset it is a bug in the compiler, 2770 so we assert here. */ 2771 assert(Address::offset_ok_for_immed(disp, exact_log2(size_in_memory)), "c2 compiler bug"); 2772 /* Fix up any out-of-range offsets. */ 2773 assert_different_registers(rscratch1, base); 2774 Address addr = Address(base, disp); 2775 addr = masm.legitimize_address(addr, size_in_memory, rscratch1); 2776 (masm.*insn)(reg, addr); 2777 } else { 2778 assert(disp == 0, "unsupported address mode: disp = %d", disp); 2779 (masm.*insn)(reg, Address(base, as_Register(index), scale)); 2780 } 2781 } 2782 2783 static void loadStore(C2_MacroAssembler masm, mem_vector_insn insn, 2784 FloatRegister reg, MacroAssembler::SIMD_RegVariant T, 2785 int opcode, Register base, int index, int size, int disp) 2786 { 2787 if (index == -1) { 2788 (masm.*insn)(reg, T, Address(base, disp)); 2789 } else { 2790 assert(disp == 0, "unsupported address mode"); 2791 (masm.*insn)(reg, T, Address(base, as_Register(index), Address::lsl(size))); 2792 } 2793 } 2794 2795 %} 2796 2797 2798 2799 //----------ENCODING BLOCK----------------------------------------------------- 2800 // This block specifies the encoding classes used by the compiler to 2801 // output byte streams. Encoding classes are parameterized macros 2802 // used by Machine Instruction Nodes in order to generate the bit 2803 // encoding of the instruction. Operands specify their base encoding 2804 // interface with the interface keyword. There are currently 2805 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2806 // COND_INTER. REG_INTER causes an operand to generate a function 2807 // which returns its register number when queried. CONST_INTER causes 2808 // an operand to generate a function which returns the value of the 2809 // constant when queried. MEMORY_INTER causes an operand to generate 2810 // four functions which return the Base Register, the Index Register, 2811 // the Scale Value, and the Offset Value of the operand when queried. 2812 // COND_INTER causes an operand to generate six functions which return 2813 // the encoding code (ie - encoding bits for the instruction) 2814 // associated with each basic boolean condition for a conditional 2815 // instruction. 2816 // 2817 // Instructions specify two basic values for encoding. Again, a 2818 // function is available to check if the constant displacement is an 2819 // oop. They use the ins_encode keyword to specify their encoding 2820 // classes (which must be a sequence of enc_class names, and their 2821 // parameters, specified in the encoding block), and they use the 2822 // opcode keyword to specify, in order, their primary, secondary, and 2823 // tertiary opcode. Only the opcode sections which a particular 2824 // instruction needs for encoding need to be specified. 2825 encode %{ 2826 // Build emit functions for each basic byte or larger field in the 2827 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2828 // from C++ code in the enc_class source block. Emit functions will 2829 // live in the main source block for now. In future, we can 2830 // generalize this by adding a syntax that specifies the sizes of 2831 // fields in an order, so that the adlc can build the emit functions 2832 // automagically 2833 2834 // catch all for unimplemented encodings 2835 enc_class enc_unimplemented %{ 2836 C2_MacroAssembler _masm(&cbuf); 2837 __ unimplemented("C2 catch all"); 2838 %} 2839 2840 // BEGIN Non-volatile memory access 2841 2842 // This encoding class is generated automatically from ad_encode.m4. 2843 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2844 enc_class aarch64_enc_ldrsbw(iRegI dst, memory1 mem) %{ 2845 Register dst_reg = as_Register($dst$$reg); 2846 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsbw, dst_reg, $mem->opcode(), 2847 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2848 %} 2849 2850 // This encoding class is generated automatically from ad_encode.m4. 2851 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2852 enc_class aarch64_enc_ldrsb(iRegI dst, memory1 mem) %{ 2853 Register dst_reg = as_Register($dst$$reg); 2854 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsb, dst_reg, $mem->opcode(), 2855 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2856 %} 2857 2858 // This encoding class is generated automatically from ad_encode.m4. 2859 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2860 enc_class aarch64_enc_ldrb(iRegI dst, memory1 mem) %{ 2861 Register dst_reg = as_Register($dst$$reg); 2862 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2863 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2864 %} 2865 2866 // This encoding class is generated automatically from ad_encode.m4. 2867 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2868 enc_class aarch64_enc_ldrb(iRegL dst, memory1 mem) %{ 2869 Register dst_reg = as_Register($dst$$reg); 2870 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrb, dst_reg, $mem->opcode(), 2871 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2872 %} 2873 2874 // This encoding class is generated automatically from ad_encode.m4. 2875 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2876 enc_class aarch64_enc_ldrshw(iRegI dst, memory2 mem) %{ 2877 Register dst_reg = as_Register($dst$$reg); 2878 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrshw, dst_reg, $mem->opcode(), 2879 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2880 %} 2881 2882 // This encoding class is generated automatically from ad_encode.m4. 2883 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2884 enc_class aarch64_enc_ldrsh(iRegI dst, memory2 mem) %{ 2885 Register dst_reg = as_Register($dst$$reg); 2886 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsh, dst_reg, $mem->opcode(), 2887 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2888 %} 2889 2890 // This encoding class is generated automatically from ad_encode.m4. 2891 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2892 enc_class aarch64_enc_ldrh(iRegI dst, memory2 mem) %{ 2893 Register dst_reg = as_Register($dst$$reg); 2894 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2895 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2896 %} 2897 2898 // This encoding class is generated automatically from ad_encode.m4. 2899 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2900 enc_class aarch64_enc_ldrh(iRegL dst, memory2 mem) %{ 2901 Register dst_reg = as_Register($dst$$reg); 2902 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrh, dst_reg, $mem->opcode(), 2903 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2904 %} 2905 2906 // This encoding class is generated automatically from ad_encode.m4. 2907 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2908 enc_class aarch64_enc_ldrw(iRegI dst, memory4 mem) %{ 2909 Register dst_reg = as_Register($dst$$reg); 2910 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2911 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2912 %} 2913 2914 // This encoding class is generated automatically from ad_encode.m4. 2915 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2916 enc_class aarch64_enc_ldrw(iRegL dst, memory4 mem) %{ 2917 Register dst_reg = as_Register($dst$$reg); 2918 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrw, dst_reg, $mem->opcode(), 2919 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2920 %} 2921 2922 // This encoding class is generated automatically from ad_encode.m4. 2923 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2924 enc_class aarch64_enc_ldrsw(iRegL dst, memory4 mem) %{ 2925 Register dst_reg = as_Register($dst$$reg); 2926 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrsw, dst_reg, $mem->opcode(), 2927 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2928 %} 2929 2930 // This encoding class is generated automatically from ad_encode.m4. 2931 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2932 enc_class aarch64_enc_ldr(iRegL dst, memory8 mem) %{ 2933 Register dst_reg = as_Register($dst$$reg); 2934 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, $mem->opcode(), 2935 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2936 %} 2937 2938 // This encoding class is generated automatically from ad_encode.m4. 2939 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2940 enc_class aarch64_enc_ldrs(vRegF dst, memory4 mem) %{ 2941 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2942 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, dst_reg, $mem->opcode(), 2943 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2944 %} 2945 2946 // This encoding class is generated automatically from ad_encode.m4. 2947 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2948 enc_class aarch64_enc_ldrd(vRegD dst, memory8 mem) %{ 2949 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 2950 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, dst_reg, $mem->opcode(), 2951 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 2952 %} 2953 2954 // This encoding class is generated automatically from ad_encode.m4. 2955 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2956 enc_class aarch64_enc_strb(iRegI src, memory1 mem) %{ 2957 Register src_reg = as_Register($src$$reg); 2958 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strb, src_reg, $mem->opcode(), 2959 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2960 %} 2961 2962 // This encoding class is generated automatically from ad_encode.m4. 2963 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2964 enc_class aarch64_enc_strb0(memory1 mem) %{ 2965 C2_MacroAssembler _masm(&cbuf); 2966 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 2967 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 2968 %} 2969 2970 // This encoding class is generated automatically from ad_encode.m4. 2971 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2972 enc_class aarch64_enc_strh(iRegI src, memory2 mem) %{ 2973 Register src_reg = as_Register($src$$reg); 2974 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strh, src_reg, $mem->opcode(), 2975 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2976 %} 2977 2978 // This encoding class is generated automatically from ad_encode.m4. 2979 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2980 enc_class aarch64_enc_strh0(memory2 mem) %{ 2981 C2_MacroAssembler _masm(&cbuf); 2982 loadStore(_masm, &MacroAssembler::strh, zr, $mem->opcode(), 2983 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 2); 2984 %} 2985 2986 // This encoding class is generated automatically from ad_encode.m4. 2987 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2988 enc_class aarch64_enc_strw(iRegI src, memory4 mem) %{ 2989 Register src_reg = as_Register($src$$reg); 2990 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strw, src_reg, $mem->opcode(), 2991 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 2992 %} 2993 2994 // This encoding class is generated automatically from ad_encode.m4. 2995 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 2996 enc_class aarch64_enc_strw0(memory4 mem) %{ 2997 C2_MacroAssembler _masm(&cbuf); 2998 loadStore(_masm, &MacroAssembler::strw, zr, $mem->opcode(), 2999 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 3000 %} 3001 3002 // This encoding class is generated automatically from ad_encode.m4. 3003 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3004 enc_class aarch64_enc_str(iRegL src, memory8 mem) %{ 3005 Register src_reg = as_Register($src$$reg); 3006 // we sometimes get asked to store the stack pointer into the 3007 // current thread -- we cannot do that directly on AArch64 3008 if (src_reg == r31_sp) { 3009 C2_MacroAssembler _masm(&cbuf); 3010 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3011 __ mov(rscratch2, sp); 3012 src_reg = rscratch2; 3013 } 3014 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, $mem->opcode(), 3015 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3016 %} 3017 3018 // This encoding class is generated automatically from ad_encode.m4. 3019 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3020 enc_class aarch64_enc_str0(memory8 mem) %{ 3021 C2_MacroAssembler _masm(&cbuf); 3022 loadStore(_masm, &MacroAssembler::str, zr, $mem->opcode(), 3023 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3024 %} 3025 3026 // This encoding class is generated automatically from ad_encode.m4. 3027 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3028 enc_class aarch64_enc_strs(vRegF src, memory4 mem) %{ 3029 FloatRegister src_reg = as_FloatRegister($src$$reg); 3030 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strs, src_reg, $mem->opcode(), 3031 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 3032 %} 3033 3034 // This encoding class is generated automatically from ad_encode.m4. 3035 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3036 enc_class aarch64_enc_strd(vRegD src, memory8 mem) %{ 3037 FloatRegister src_reg = as_FloatRegister($src$$reg); 3038 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::strd, src_reg, $mem->opcode(), 3039 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 3040 %} 3041 3042 // This encoding class is generated automatically from ad_encode.m4. 3043 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 3044 enc_class aarch64_enc_strb0_ordered(memory4 mem) %{ 3045 C2_MacroAssembler _masm(&cbuf); 3046 __ membar(Assembler::StoreStore); 3047 loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(), 3048 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1); 3049 %} 3050 3051 // END Non-volatile memory access 3052 3053 // Vector loads and stores 3054 enc_class aarch64_enc_ldrvH(vReg dst, memory mem) %{ 3055 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3056 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::H, 3057 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3058 %} 3059 3060 enc_class aarch64_enc_ldrvS(vReg dst, memory mem) %{ 3061 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3062 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::S, 3063 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3064 %} 3065 3066 enc_class aarch64_enc_ldrvD(vReg dst, memory mem) %{ 3067 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3068 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::D, 3069 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3070 %} 3071 3072 enc_class aarch64_enc_ldrvQ(vReg dst, memory mem) %{ 3073 FloatRegister dst_reg = as_FloatRegister($dst$$reg); 3074 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldr, dst_reg, MacroAssembler::Q, 3075 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3076 %} 3077 3078 enc_class aarch64_enc_strvH(vReg src, memory mem) %{ 3079 FloatRegister src_reg = as_FloatRegister($src$$reg); 3080 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::H, 3081 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3082 %} 3083 3084 enc_class aarch64_enc_strvS(vReg src, memory mem) %{ 3085 FloatRegister src_reg = as_FloatRegister($src$$reg); 3086 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::S, 3087 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3088 %} 3089 3090 enc_class aarch64_enc_strvD(vReg src, memory mem) %{ 3091 FloatRegister src_reg = as_FloatRegister($src$$reg); 3092 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::D, 3093 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3094 %} 3095 3096 enc_class aarch64_enc_strvQ(vReg src, memory mem) %{ 3097 FloatRegister src_reg = as_FloatRegister($src$$reg); 3098 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::str, src_reg, MacroAssembler::Q, 3099 $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); 3100 %} 3101 3102 // volatile loads and stores 3103 3104 enc_class aarch64_enc_stlrb(iRegI src, memory mem) %{ 3105 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3106 rscratch1, stlrb); 3107 %} 3108 3109 enc_class aarch64_enc_stlrb0(memory mem) %{ 3110 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3111 rscratch1, stlrb); 3112 %} 3113 3114 enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ 3115 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3116 rscratch1, stlrh); 3117 %} 3118 3119 enc_class aarch64_enc_stlrh0(memory mem) %{ 3120 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3121 rscratch1, stlrh); 3122 %} 3123 3124 enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ 3125 MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3126 rscratch1, stlrw); 3127 %} 3128 3129 enc_class aarch64_enc_stlrw0(memory mem) %{ 3130 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3131 rscratch1, stlrw); 3132 %} 3133 3134 enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ 3135 Register dst_reg = as_Register($dst$$reg); 3136 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3137 rscratch1, ldarb); 3138 __ sxtbw(dst_reg, dst_reg); 3139 %} 3140 3141 enc_class aarch64_enc_ldarsb(iRegL dst, memory mem) %{ 3142 Register dst_reg = as_Register($dst$$reg); 3143 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3144 rscratch1, ldarb); 3145 __ sxtb(dst_reg, dst_reg); 3146 %} 3147 3148 enc_class aarch64_enc_ldarbw(iRegI dst, memory mem) %{ 3149 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3150 rscratch1, ldarb); 3151 %} 3152 3153 enc_class aarch64_enc_ldarb(iRegL dst, memory mem) %{ 3154 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3155 rscratch1, ldarb); 3156 %} 3157 3158 enc_class aarch64_enc_ldarshw(iRegI dst, memory mem) %{ 3159 Register dst_reg = as_Register($dst$$reg); 3160 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3161 rscratch1, ldarh); 3162 __ sxthw(dst_reg, dst_reg); 3163 %} 3164 3165 enc_class aarch64_enc_ldarsh(iRegL dst, memory mem) %{ 3166 Register dst_reg = as_Register($dst$$reg); 3167 MOV_VOLATILE(dst_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3168 rscratch1, ldarh); 3169 __ sxth(dst_reg, dst_reg); 3170 %} 3171 3172 enc_class aarch64_enc_ldarhw(iRegI dst, memory mem) %{ 3173 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3174 rscratch1, ldarh); 3175 %} 3176 3177 enc_class aarch64_enc_ldarh(iRegL dst, memory mem) %{ 3178 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3179 rscratch1, ldarh); 3180 %} 3181 3182 enc_class aarch64_enc_ldarw(iRegI dst, memory mem) %{ 3183 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3184 rscratch1, ldarw); 3185 %} 3186 3187 enc_class aarch64_enc_ldarw(iRegL dst, memory mem) %{ 3188 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3189 rscratch1, ldarw); 3190 %} 3191 3192 enc_class aarch64_enc_ldar(iRegL dst, memory mem) %{ 3193 MOV_VOLATILE(as_Register($dst$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3194 rscratch1, ldar); 3195 %} 3196 3197 enc_class aarch64_enc_fldars(vRegF dst, memory mem) %{ 3198 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3199 rscratch1, ldarw); 3200 __ fmovs(as_FloatRegister($dst$$reg), rscratch1); 3201 %} 3202 3203 enc_class aarch64_enc_fldard(vRegD dst, memory mem) %{ 3204 MOV_VOLATILE(rscratch1, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3205 rscratch1, ldar); 3206 __ fmovd(as_FloatRegister($dst$$reg), rscratch1); 3207 %} 3208 3209 enc_class aarch64_enc_stlr(iRegL src, memory mem) %{ 3210 Register src_reg = as_Register($src$$reg); 3211 // we sometimes get asked to store the stack pointer into the 3212 // current thread -- we cannot do that directly on AArch64 3213 if (src_reg == r31_sp) { 3214 C2_MacroAssembler _masm(&cbuf); 3215 assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); 3216 __ mov(rscratch2, sp); 3217 src_reg = rscratch2; 3218 } 3219 MOV_VOLATILE(src_reg, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3220 rscratch1, stlr); 3221 %} 3222 3223 enc_class aarch64_enc_stlr0(memory mem) %{ 3224 MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3225 rscratch1, stlr); 3226 %} 3227 3228 enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ 3229 { 3230 C2_MacroAssembler _masm(&cbuf); 3231 FloatRegister src_reg = as_FloatRegister($src$$reg); 3232 __ fmovs(rscratch2, src_reg); 3233 } 3234 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3235 rscratch1, stlrw); 3236 %} 3237 3238 enc_class aarch64_enc_fstlrd(vRegD src, memory mem) %{ 3239 { 3240 C2_MacroAssembler _masm(&cbuf); 3241 FloatRegister src_reg = as_FloatRegister($src$$reg); 3242 __ fmovd(rscratch2, src_reg); 3243 } 3244 MOV_VOLATILE(rscratch2, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, 3245 rscratch1, stlr); 3246 %} 3247 3248 // synchronized read/update encodings 3249 3250 enc_class aarch64_enc_ldaxr(iRegL dst, memory8 mem) %{ 3251 C2_MacroAssembler _masm(&cbuf); 3252 Register dst_reg = as_Register($dst$$reg); 3253 Register base = as_Register($mem$$base); 3254 int index = $mem$$index; 3255 int scale = $mem$$scale; 3256 int disp = $mem$$disp; 3257 if (index == -1) { 3258 if (disp != 0) { 3259 __ lea(rscratch1, Address(base, disp)); 3260 __ ldaxr(dst_reg, rscratch1); 3261 } else { 3262 // TODO 3263 // should we ever get anything other than this case? 3264 __ ldaxr(dst_reg, base); 3265 } 3266 } else { 3267 Register index_reg = as_Register(index); 3268 if (disp == 0) { 3269 __ lea(rscratch1, Address(base, index_reg, Address::lsl(scale))); 3270 __ ldaxr(dst_reg, rscratch1); 3271 } else { 3272 __ lea(rscratch1, Address(base, disp)); 3273 __ lea(rscratch1, Address(rscratch1, index_reg, Address::lsl(scale))); 3274 __ ldaxr(dst_reg, rscratch1); 3275 } 3276 } 3277 %} 3278 3279 enc_class aarch64_enc_stlxr(iRegLNoSp src, memory8 mem) %{ 3280 C2_MacroAssembler _masm(&cbuf); 3281 Register src_reg = as_Register($src$$reg); 3282 Register base = as_Register($mem$$base); 3283 int index = $mem$$index; 3284 int scale = $mem$$scale; 3285 int disp = $mem$$disp; 3286 if (index == -1) { 3287 if (disp != 0) { 3288 __ lea(rscratch2, Address(base, disp)); 3289 __ stlxr(rscratch1, src_reg, rscratch2); 3290 } else { 3291 // TODO 3292 // should we ever get anything other than this case? 3293 __ stlxr(rscratch1, src_reg, base); 3294 } 3295 } else { 3296 Register index_reg = as_Register(index); 3297 if (disp == 0) { 3298 __ lea(rscratch2, Address(base, index_reg, Address::lsl(scale))); 3299 __ stlxr(rscratch1, src_reg, rscratch2); 3300 } else { 3301 __ lea(rscratch2, Address(base, disp)); 3302 __ lea(rscratch2, Address(rscratch2, index_reg, Address::lsl(scale))); 3303 __ stlxr(rscratch1, src_reg, rscratch2); 3304 } 3305 } 3306 __ cmpw(rscratch1, zr); 3307 %} 3308 3309 enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3310 C2_MacroAssembler _masm(&cbuf); 3311 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3312 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3313 Assembler::xword, /*acquire*/ false, /*release*/ true, 3314 /*weak*/ false, noreg); 3315 %} 3316 3317 enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3318 C2_MacroAssembler _masm(&cbuf); 3319 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3320 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3321 Assembler::word, /*acquire*/ false, /*release*/ true, 3322 /*weak*/ false, noreg); 3323 %} 3324 3325 enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3326 C2_MacroAssembler _masm(&cbuf); 3327 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3328 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3329 Assembler::halfword, /*acquire*/ false, /*release*/ true, 3330 /*weak*/ false, noreg); 3331 %} 3332 3333 enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3334 C2_MacroAssembler _masm(&cbuf); 3335 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3336 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3337 Assembler::byte, /*acquire*/ false, /*release*/ true, 3338 /*weak*/ false, noreg); 3339 %} 3340 3341 3342 // The only difference between aarch64_enc_cmpxchg and 3343 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the 3344 // CompareAndSwap sequence to serve as a barrier on acquiring a 3345 // lock. 3346 enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{ 3347 C2_MacroAssembler _masm(&cbuf); 3348 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3349 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3350 Assembler::xword, /*acquire*/ true, /*release*/ true, 3351 /*weak*/ false, noreg); 3352 %} 3353 3354 enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3355 C2_MacroAssembler _masm(&cbuf); 3356 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3357 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3358 Assembler::word, /*acquire*/ true, /*release*/ true, 3359 /*weak*/ false, noreg); 3360 %} 3361 3362 enc_class aarch64_enc_cmpxchgs_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3363 C2_MacroAssembler _masm(&cbuf); 3364 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3365 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3366 Assembler::halfword, /*acquire*/ true, /*release*/ true, 3367 /*weak*/ false, noreg); 3368 %} 3369 3370 enc_class aarch64_enc_cmpxchgb_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{ 3371 C2_MacroAssembler _masm(&cbuf); 3372 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 3373 __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, 3374 Assembler::byte, /*acquire*/ true, /*release*/ true, 3375 /*weak*/ false, noreg); 3376 %} 3377 3378 // auxiliary used for CompareAndSwapX to set result register 3379 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ 3380 C2_MacroAssembler _masm(&cbuf); 3381 Register res_reg = as_Register($res$$reg); 3382 __ cset(res_reg, Assembler::EQ); 3383 %} 3384 3385 // prefetch encodings 3386 3387 enc_class aarch64_enc_prefetchw(memory mem) %{ 3388 C2_MacroAssembler _masm(&cbuf); 3389 Register base = as_Register($mem$$base); 3390 int index = $mem$$index; 3391 int scale = $mem$$scale; 3392 int disp = $mem$$disp; 3393 if (index == -1) { 3394 __ prfm(Address(base, disp), PSTL1KEEP); 3395 } else { 3396 Register index_reg = as_Register(index); 3397 if (disp == 0) { 3398 __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP); 3399 } else { 3400 __ lea(rscratch1, Address(base, disp)); 3401 __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP); 3402 } 3403 } 3404 %} 3405 3406 /// mov envcodings 3407 3408 enc_class aarch64_enc_movw_imm(iRegI dst, immI src) %{ 3409 C2_MacroAssembler _masm(&cbuf); 3410 uint32_t con = (uint32_t)$src$$constant; 3411 Register dst_reg = as_Register($dst$$reg); 3412 if (con == 0) { 3413 __ movw(dst_reg, zr); 3414 } else { 3415 __ movw(dst_reg, con); 3416 } 3417 %} 3418 3419 enc_class aarch64_enc_mov_imm(iRegL dst, immL src) %{ 3420 C2_MacroAssembler _masm(&cbuf); 3421 Register dst_reg = as_Register($dst$$reg); 3422 uint64_t con = (uint64_t)$src$$constant; 3423 if (con == 0) { 3424 __ mov(dst_reg, zr); 3425 } else { 3426 __ mov(dst_reg, con); 3427 } 3428 %} 3429 3430 enc_class aarch64_enc_mov_p(iRegP dst, immP src) %{ 3431 C2_MacroAssembler _masm(&cbuf); 3432 Register dst_reg = as_Register($dst$$reg); 3433 address con = (address)$src$$constant; 3434 if (con == nullptr || con == (address)1) { 3435 ShouldNotReachHere(); 3436 } else { 3437 relocInfo::relocType rtype = $src->constant_reloc(); 3438 if (rtype == relocInfo::oop_type) { 3439 __ movoop(dst_reg, (jobject)con); 3440 } else if (rtype == relocInfo::metadata_type) { 3441 __ mov_metadata(dst_reg, (Metadata*)con); 3442 } else { 3443 assert(rtype == relocInfo::none, "unexpected reloc type"); 3444 if (! __ is_valid_AArch64_address(con) || 3445 con < (address)(uintptr_t)os::vm_page_size()) { 3446 __ mov(dst_reg, con); 3447 } else { 3448 uint64_t offset; 3449 __ adrp(dst_reg, con, offset); 3450 __ add(dst_reg, dst_reg, offset); 3451 } 3452 } 3453 } 3454 %} 3455 3456 enc_class aarch64_enc_mov_p0(iRegP dst, immP0 src) %{ 3457 C2_MacroAssembler _masm(&cbuf); 3458 Register dst_reg = as_Register($dst$$reg); 3459 __ mov(dst_reg, zr); 3460 %} 3461 3462 enc_class aarch64_enc_mov_p1(iRegP dst, immP_1 src) %{ 3463 C2_MacroAssembler _masm(&cbuf); 3464 Register dst_reg = as_Register($dst$$reg); 3465 __ mov(dst_reg, (uint64_t)1); 3466 %} 3467 3468 enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ 3469 C2_MacroAssembler _masm(&cbuf); 3470 __ load_byte_map_base($dst$$Register); 3471 %} 3472 3473 enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ 3474 C2_MacroAssembler _masm(&cbuf); 3475 Register dst_reg = as_Register($dst$$reg); 3476 address con = (address)$src$$constant; 3477 if (con == nullptr) { 3478 ShouldNotReachHere(); 3479 } else { 3480 relocInfo::relocType rtype = $src->constant_reloc(); 3481 assert(rtype == relocInfo::oop_type, "unexpected reloc type"); 3482 __ set_narrow_oop(dst_reg, (jobject)con); 3483 } 3484 %} 3485 3486 enc_class aarch64_enc_mov_n0(iRegN dst, immN0 src) %{ 3487 C2_MacroAssembler _masm(&cbuf); 3488 Register dst_reg = as_Register($dst$$reg); 3489 __ mov(dst_reg, zr); 3490 %} 3491 3492 enc_class aarch64_enc_mov_nk(iRegN dst, immNKlass src) %{ 3493 C2_MacroAssembler _masm(&cbuf); 3494 Register dst_reg = as_Register($dst$$reg); 3495 address con = (address)$src$$constant; 3496 if (con == nullptr) { 3497 ShouldNotReachHere(); 3498 } else { 3499 relocInfo::relocType rtype = $src->constant_reloc(); 3500 assert(rtype == relocInfo::metadata_type, "unexpected reloc type"); 3501 __ set_narrow_klass(dst_reg, (Klass *)con); 3502 } 3503 %} 3504 3505 // arithmetic encodings 3506 3507 enc_class aarch64_enc_addsubw_imm(iRegI dst, iRegI src1, immIAddSub src2) %{ 3508 C2_MacroAssembler _masm(&cbuf); 3509 Register dst_reg = as_Register($dst$$reg); 3510 Register src_reg = as_Register($src1$$reg); 3511 int32_t con = (int32_t)$src2$$constant; 3512 // add has primary == 0, subtract has primary == 1 3513 if ($primary) { con = -con; } 3514 if (con < 0) { 3515 __ subw(dst_reg, src_reg, -con); 3516 } else { 3517 __ addw(dst_reg, src_reg, con); 3518 } 3519 %} 3520 3521 enc_class aarch64_enc_addsub_imm(iRegL dst, iRegL src1, immLAddSub src2) %{ 3522 C2_MacroAssembler _masm(&cbuf); 3523 Register dst_reg = as_Register($dst$$reg); 3524 Register src_reg = as_Register($src1$$reg); 3525 int32_t con = (int32_t)$src2$$constant; 3526 // add has primary == 0, subtract has primary == 1 3527 if ($primary) { con = -con; } 3528 if (con < 0) { 3529 __ sub(dst_reg, src_reg, -con); 3530 } else { 3531 __ add(dst_reg, src_reg, con); 3532 } 3533 %} 3534 3535 enc_class aarch64_enc_divw(iRegI dst, iRegI src1, iRegI src2) %{ 3536 C2_MacroAssembler _masm(&cbuf); 3537 Register dst_reg = as_Register($dst$$reg); 3538 Register src1_reg = as_Register($src1$$reg); 3539 Register src2_reg = as_Register($src2$$reg); 3540 __ corrected_idivl(dst_reg, src1_reg, src2_reg, false, rscratch1); 3541 %} 3542 3543 enc_class aarch64_enc_div(iRegI dst, iRegI src1, iRegI src2) %{ 3544 C2_MacroAssembler _masm(&cbuf); 3545 Register dst_reg = as_Register($dst$$reg); 3546 Register src1_reg = as_Register($src1$$reg); 3547 Register src2_reg = as_Register($src2$$reg); 3548 __ corrected_idivq(dst_reg, src1_reg, src2_reg, false, rscratch1); 3549 %} 3550 3551 enc_class aarch64_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{ 3552 C2_MacroAssembler _masm(&cbuf); 3553 Register dst_reg = as_Register($dst$$reg); 3554 Register src1_reg = as_Register($src1$$reg); 3555 Register src2_reg = as_Register($src2$$reg); 3556 __ corrected_idivl(dst_reg, src1_reg, src2_reg, true, rscratch1); 3557 %} 3558 3559 enc_class aarch64_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{ 3560 C2_MacroAssembler _masm(&cbuf); 3561 Register dst_reg = as_Register($dst$$reg); 3562 Register src1_reg = as_Register($src1$$reg); 3563 Register src2_reg = as_Register($src2$$reg); 3564 __ corrected_idivq(dst_reg, src1_reg, src2_reg, true, rscratch1); 3565 %} 3566 3567 // compare instruction encodings 3568 3569 enc_class aarch64_enc_cmpw(iRegI src1, iRegI src2) %{ 3570 C2_MacroAssembler _masm(&cbuf); 3571 Register reg1 = as_Register($src1$$reg); 3572 Register reg2 = as_Register($src2$$reg); 3573 __ cmpw(reg1, reg2); 3574 %} 3575 3576 enc_class aarch64_enc_cmpw_imm_addsub(iRegI src1, immIAddSub src2) %{ 3577 C2_MacroAssembler _masm(&cbuf); 3578 Register reg = as_Register($src1$$reg); 3579 int32_t val = $src2$$constant; 3580 if (val >= 0) { 3581 __ subsw(zr, reg, val); 3582 } else { 3583 __ addsw(zr, reg, -val); 3584 } 3585 %} 3586 3587 enc_class aarch64_enc_cmpw_imm(iRegI src1, immI src2) %{ 3588 C2_MacroAssembler _masm(&cbuf); 3589 Register reg1 = as_Register($src1$$reg); 3590 uint32_t val = (uint32_t)$src2$$constant; 3591 __ movw(rscratch1, val); 3592 __ cmpw(reg1, rscratch1); 3593 %} 3594 3595 enc_class aarch64_enc_cmp(iRegL src1, iRegL src2) %{ 3596 C2_MacroAssembler _masm(&cbuf); 3597 Register reg1 = as_Register($src1$$reg); 3598 Register reg2 = as_Register($src2$$reg); 3599 __ cmp(reg1, reg2); 3600 %} 3601 3602 enc_class aarch64_enc_cmp_imm_addsub(iRegL src1, immL12 src2) %{ 3603 C2_MacroAssembler _masm(&cbuf); 3604 Register reg = as_Register($src1$$reg); 3605 int64_t val = $src2$$constant; 3606 if (val >= 0) { 3607 __ subs(zr, reg, val); 3608 } else if (val != -val) { 3609 __ adds(zr, reg, -val); 3610 } else { 3611 // aargh, Long.MIN_VALUE is a special case 3612 __ orr(rscratch1, zr, (uint64_t)val); 3613 __ subs(zr, reg, rscratch1); 3614 } 3615 %} 3616 3617 enc_class aarch64_enc_cmp_imm(iRegL src1, immL src2) %{ 3618 C2_MacroAssembler _masm(&cbuf); 3619 Register reg1 = as_Register($src1$$reg); 3620 uint64_t val = (uint64_t)$src2$$constant; 3621 __ mov(rscratch1, val); 3622 __ cmp(reg1, rscratch1); 3623 %} 3624 3625 enc_class aarch64_enc_cmpp(iRegP src1, iRegP src2) %{ 3626 C2_MacroAssembler _masm(&cbuf); 3627 Register reg1 = as_Register($src1$$reg); 3628 Register reg2 = as_Register($src2$$reg); 3629 __ cmp(reg1, reg2); 3630 %} 3631 3632 enc_class aarch64_enc_cmpn(iRegN src1, iRegN src2) %{ 3633 C2_MacroAssembler _masm(&cbuf); 3634 Register reg1 = as_Register($src1$$reg); 3635 Register reg2 = as_Register($src2$$reg); 3636 __ cmpw(reg1, reg2); 3637 %} 3638 3639 enc_class aarch64_enc_testp(iRegP src) %{ 3640 C2_MacroAssembler _masm(&cbuf); 3641 Register reg = as_Register($src$$reg); 3642 __ cmp(reg, zr); 3643 %} 3644 3645 enc_class aarch64_enc_testn(iRegN src) %{ 3646 C2_MacroAssembler _masm(&cbuf); 3647 Register reg = as_Register($src$$reg); 3648 __ cmpw(reg, zr); 3649 %} 3650 3651 enc_class aarch64_enc_b(label lbl) %{ 3652 C2_MacroAssembler _masm(&cbuf); 3653 Label *L = $lbl$$label; 3654 __ b(*L); 3655 %} 3656 3657 enc_class aarch64_enc_br_con(cmpOp cmp, label lbl) %{ 3658 C2_MacroAssembler _masm(&cbuf); 3659 Label *L = $lbl$$label; 3660 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3661 %} 3662 3663 enc_class aarch64_enc_br_conU(cmpOpU cmp, label lbl) %{ 3664 C2_MacroAssembler _masm(&cbuf); 3665 Label *L = $lbl$$label; 3666 __ br ((Assembler::Condition)$cmp$$cmpcode, *L); 3667 %} 3668 3669 enc_class aarch64_enc_partial_subtype_check(iRegP sub, iRegP super, iRegP temp, iRegP result) 3670 %{ 3671 Register sub_reg = as_Register($sub$$reg); 3672 Register super_reg = as_Register($super$$reg); 3673 Register temp_reg = as_Register($temp$$reg); 3674 Register result_reg = as_Register($result$$reg); 3675 3676 Label miss; 3677 C2_MacroAssembler _masm(&cbuf); 3678 __ check_klass_subtype_slow_path(sub_reg, super_reg, temp_reg, result_reg, 3679 nullptr, &miss, 3680 /*set_cond_codes:*/ true); 3681 if ($primary) { 3682 __ mov(result_reg, zr); 3683 } 3684 __ bind(miss); 3685 %} 3686 3687 enc_class aarch64_enc_java_static_call(method meth) %{ 3688 C2_MacroAssembler _masm(&cbuf); 3689 3690 address addr = (address)$meth$$method; 3691 address call; 3692 if (!_method) { 3693 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3694 call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type)); 3695 if (call == nullptr) { 3696 ciEnv::current()->record_failure("CodeCache is full"); 3697 return; 3698 } 3699 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 3700 // The NOP here is purely to ensure that eliding a call to 3701 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 3702 __ nop(); 3703 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 3704 } else { 3705 int method_index = resolved_method_index(cbuf); 3706 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3707 : static_call_Relocation::spec(method_index); 3708 call = __ trampoline_call(Address(addr, rspec)); 3709 if (call == nullptr) { 3710 ciEnv::current()->record_failure("CodeCache is full"); 3711 return; 3712 } 3713 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 3714 // Calls of the same statically bound method can share 3715 // a stub to the interpreter. 3716 cbuf.shared_stub_to_interp_for(_method, call - cbuf.insts_begin()); 3717 } else { 3718 // Emit stub for static call 3719 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, call); 3720 if (stub == nullptr) { 3721 ciEnv::current()->record_failure("CodeCache is full"); 3722 return; 3723 } 3724 } 3725 } 3726 3727 __ post_call_nop(); 3728 3729 // Only non uncommon_trap calls need to reinitialize ptrue. 3730 if (Compile::current()->max_vector_size() > 0 && uncommon_trap_request() == 0) { 3731 __ reinitialize_ptrue(); 3732 } 3733 %} 3734 3735 enc_class aarch64_enc_java_dynamic_call(method meth) %{ 3736 C2_MacroAssembler _masm(&cbuf); 3737 int method_index = resolved_method_index(cbuf); 3738 address call = __ ic_call((address)$meth$$method, method_index); 3739 if (call == nullptr) { 3740 ciEnv::current()->record_failure("CodeCache is full"); 3741 return; 3742 } 3743 __ post_call_nop(); 3744 if (Compile::current()->max_vector_size() > 0) { 3745 __ reinitialize_ptrue(); 3746 } 3747 %} 3748 3749 enc_class aarch64_enc_call_epilog() %{ 3750 C2_MacroAssembler _masm(&cbuf); 3751 if (VerifyStackAtCalls) { 3752 // Check that stack depth is unchanged: find majik cookie on stack 3753 __ call_Unimplemented(); 3754 } 3755 if (tf()->returns_inline_type_as_fields() && !_method->is_method_handle_intrinsic()) { 3756 // The last return value is not set by the callee but used to pass IsInit information to compiled code. 3757 // Search for the corresponding projection, get the register and emit code that initialized it. 3758 uint con = (tf()->range_cc()->cnt() - 1); 3759 for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { 3760 ProjNode* proj = fast_out(i)->as_Proj(); 3761 if (proj->_con == con) { 3762 // Set IsInit if r0 is non-null (a non-null value is returned buffered or scalarized) 3763 OptoReg::Name optoReg = ra_->get_reg_first(proj); 3764 VMReg reg = OptoReg::as_VMReg(optoReg, ra_->_framesize, OptoReg::reg2stack(ra_->_matcher._new_SP)); 3765 Register toReg = reg->is_reg() ? reg->as_Register() : rscratch1; 3766 __ cmp(r0, zr); 3767 __ cset(toReg, Assembler::NE); 3768 if (reg->is_stack()) { 3769 int st_off = reg->reg2stack() * VMRegImpl::stack_slot_size; 3770 __ str(toReg, Address(sp, st_off)); 3771 } 3772 break; 3773 } 3774 } 3775 if (return_value_is_used()) { 3776 // An inline type is returned as fields in multiple registers. 3777 // R0 either contains an oop if the inline type is buffered or a pointer 3778 // to the corresponding InlineKlass with the lowest bit set to 1. Zero r0 3779 // if the lowest bit is set to allow C2 to use the oop after null checking. 3780 // r0 &= (r0 & 1) - 1 3781 __ andr(rscratch1, r0, 0x1); 3782 __ sub(rscratch1, rscratch1, 0x1); 3783 __ andr(r0, r0, rscratch1); 3784 } 3785 } 3786 %} 3787 3788 enc_class aarch64_enc_java_to_runtime(method meth) %{ 3789 C2_MacroAssembler _masm(&cbuf); 3790 3791 // some calls to generated routines (arraycopy code) are scheduled 3792 // by C2 as runtime calls. if so we can call them using a br (they 3793 // will be in a reachable segment) otherwise we have to use a blr 3794 // which loads the absolute address into a register. 3795 address entry = (address)$meth$$method; 3796 CodeBlob *cb = CodeCache::find_blob(entry); 3797 if (cb) { 3798 address call = __ trampoline_call(Address(entry, relocInfo::runtime_call_type)); 3799 if (call == nullptr) { 3800 ciEnv::current()->record_failure("CodeCache is full"); 3801 return; 3802 } 3803 __ post_call_nop(); 3804 } else { 3805 Label retaddr; 3806 __ adr(rscratch2, retaddr); 3807 __ lea(rscratch1, RuntimeAddress(entry)); 3808 // Leave a breadcrumb for JavaFrameAnchor::capture_last_Java_pc() 3809 __ stp(zr, rscratch2, Address(__ pre(sp, -2 * wordSize))); 3810 __ blr(rscratch1); 3811 __ bind(retaddr); 3812 __ post_call_nop(); 3813 __ add(sp, sp, 2 * wordSize); 3814 } 3815 if (Compile::current()->max_vector_size() > 0) { 3816 __ reinitialize_ptrue(); 3817 } 3818 %} 3819 3820 enc_class aarch64_enc_rethrow() %{ 3821 C2_MacroAssembler _masm(&cbuf); 3822 __ far_jump(RuntimeAddress(OptoRuntime::rethrow_stub())); 3823 %} 3824 3825 enc_class aarch64_enc_ret() %{ 3826 C2_MacroAssembler _masm(&cbuf); 3827 #ifdef ASSERT 3828 if (Compile::current()->max_vector_size() > 0) { 3829 __ verify_ptrue(); 3830 } 3831 #endif 3832 __ ret(lr); 3833 %} 3834 3835 enc_class aarch64_enc_tail_call(iRegP jump_target) %{ 3836 C2_MacroAssembler _masm(&cbuf); 3837 Register target_reg = as_Register($jump_target$$reg); 3838 __ br(target_reg); 3839 %} 3840 3841 enc_class aarch64_enc_tail_jmp(iRegP jump_target) %{ 3842 C2_MacroAssembler _masm(&cbuf); 3843 Register target_reg = as_Register($jump_target$$reg); 3844 // exception oop should be in r0 3845 // ret addr has been popped into lr 3846 // callee expects it in r3 3847 __ mov(r3, lr); 3848 __ br(target_reg); 3849 %} 3850 3851 %} 3852 3853 //----------FRAME-------------------------------------------------------------- 3854 // Definition of frame structure and management information. 3855 // 3856 // S T A C K L A Y O U T Allocators stack-slot number 3857 // | (to get allocators register number 3858 // G Owned by | | v add OptoReg::stack0()) 3859 // r CALLER | | 3860 // o | +--------+ pad to even-align allocators stack-slot 3861 // w V | pad0 | numbers; owned by CALLER 3862 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3863 // h ^ | in | 5 3864 // | | args | 4 Holes in incoming args owned by SELF 3865 // | | | | 3 3866 // | | +--------+ 3867 // V | | old out| Empty on Intel, window on Sparc 3868 // | old |preserve| Must be even aligned. 3869 // | SP-+--------+----> Matcher::_old_SP, even aligned 3870 // | | in | 3 area for Intel ret address 3871 // Owned by |preserve| Empty on Sparc. 3872 // SELF +--------+ 3873 // | | pad2 | 2 pad to align old SP 3874 // | +--------+ 1 3875 // | | locks | 0 3876 // | +--------+----> OptoReg::stack0(), even aligned 3877 // | | pad1 | 11 pad to align new SP 3878 // | +--------+ 3879 // | | | 10 3880 // | | spills | 9 spills 3881 // V | | 8 (pad0 slot for callee) 3882 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 3883 // ^ | out | 7 3884 // | | args | 6 Holes in outgoing args owned by CALLEE 3885 // Owned by +--------+ 3886 // CALLEE | new out| 6 Empty on Intel, window on Sparc 3887 // | new |preserve| Must be even-aligned. 3888 // | SP-+--------+----> Matcher::_new_SP, even aligned 3889 // | | | 3890 // 3891 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3892 // known from SELF's arguments and the Java calling convention. 3893 // Region 6-7 is determined per call site. 3894 // Note 2: If the calling convention leaves holes in the incoming argument 3895 // area, those holes are owned by SELF. Holes in the outgoing area 3896 // are owned by the CALLEE. Holes should not be necessary in the 3897 // incoming area, as the Java calling convention is completely under 3898 // the control of the AD file. Doubles can be sorted and packed to 3899 // avoid holes. Holes in the outgoing arguments may be necessary for 3900 // varargs C calling conventions. 3901 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3902 // even aligned with pad0 as needed. 3903 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 3904 // (the latter is true on Intel but is it false on AArch64?) 3905 // region 6-11 is even aligned; it may be padded out more so that 3906 // the region from SP to FP meets the minimum stack alignment. 3907 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3908 // alignment. Region 11, pad1, may be dynamically extended so that 3909 // SP meets the minimum alignment. 3910 3911 frame %{ 3912 // These three registers define part of the calling convention 3913 // between compiled code and the interpreter. 3914 3915 // Inline Cache Register or Method for I2C. 3916 inline_cache_reg(R12); 3917 3918 // Number of stack slots consumed by locking an object 3919 sync_stack_slots(2); 3920 3921 // Compiled code's Frame Pointer 3922 frame_pointer(R31); 3923 3924 // Interpreter stores its frame pointer in a register which is 3925 // stored to the stack by I2CAdaptors. 3926 // I2CAdaptors convert from interpreted java to compiled java. 3927 interpreter_frame_pointer(R29); 3928 3929 // Stack alignment requirement 3930 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3931 3932 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3933 // for calls to C. Supports the var-args backing area for register parms. 3934 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3935 3936 // The after-PROLOG location of the return address. Location of 3937 // return address specifies a type (REG or STACK) and a number 3938 // representing the register number (i.e. - use a register name) or 3939 // stack slot. 3940 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3941 // Otherwise, it is above the locks and verification slot and alignment word 3942 // TODO this may well be correct but need to check why that - 2 is there 3943 // ppc port uses 0 but we definitely need to allow for fixed_slots 3944 // which folds in the space used for monitors 3945 return_addr(STACK - 2 + 3946 align_up((Compile::current()->in_preserve_stack_slots() + 3947 Compile::current()->fixed_slots()), 3948 stack_alignment_in_slots())); 3949 3950 // Location of compiled Java return values. Same as C for now. 3951 return_value 3952 %{ 3953 // TODO do we allow ideal_reg == Op_RegN??? 3954 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3955 "only return normal values"); 3956 3957 static const int lo[Op_RegL + 1] = { // enum name 3958 0, // Op_Node 3959 0, // Op_Set 3960 R0_num, // Op_RegN 3961 R0_num, // Op_RegI 3962 R0_num, // Op_RegP 3963 V0_num, // Op_RegF 3964 V0_num, // Op_RegD 3965 R0_num // Op_RegL 3966 }; 3967 3968 static const int hi[Op_RegL + 1] = { // enum name 3969 0, // Op_Node 3970 0, // Op_Set 3971 OptoReg::Bad, // Op_RegN 3972 OptoReg::Bad, // Op_RegI 3973 R0_H_num, // Op_RegP 3974 OptoReg::Bad, // Op_RegF 3975 V0_H_num, // Op_RegD 3976 R0_H_num // Op_RegL 3977 }; 3978 3979 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3980 %} 3981 %} 3982 3983 //----------ATTRIBUTES--------------------------------------------------------- 3984 //----------Operand Attributes------------------------------------------------- 3985 op_attrib op_cost(1); // Required cost attribute 3986 3987 //----------Instruction Attributes--------------------------------------------- 3988 ins_attrib ins_cost(INSN_COST); // Required cost attribute 3989 ins_attrib ins_size(32); // Required size attribute (in bits) 3990 ins_attrib ins_short_branch(0); // Required flag: is this instruction 3991 // a non-matching short branch variant 3992 // of some long branch? 3993 ins_attrib ins_alignment(4); // Required alignment attribute (must 3994 // be a power of 2) specifies the 3995 // alignment that some part of the 3996 // instruction (not necessarily the 3997 // start) requires. If > 1, a 3998 // compute_padding() function must be 3999 // provided for the instruction 4000 4001 //----------OPERANDS----------------------------------------------------------- 4002 // Operand definitions must precede instruction definitions for correct parsing 4003 // in the ADLC because operands constitute user defined types which are used in 4004 // instruction definitions. 4005 4006 //----------Simple Operands---------------------------------------------------- 4007 4008 // Integer operands 32 bit 4009 // 32 bit immediate 4010 operand immI() 4011 %{ 4012 match(ConI); 4013 4014 op_cost(0); 4015 format %{ %} 4016 interface(CONST_INTER); 4017 %} 4018 4019 // 32 bit zero 4020 operand immI0() 4021 %{ 4022 predicate(n->get_int() == 0); 4023 match(ConI); 4024 4025 op_cost(0); 4026 format %{ %} 4027 interface(CONST_INTER); 4028 %} 4029 4030 // 32 bit unit increment 4031 operand immI_1() 4032 %{ 4033 predicate(n->get_int() == 1); 4034 match(ConI); 4035 4036 op_cost(0); 4037 format %{ %} 4038 interface(CONST_INTER); 4039 %} 4040 4041 // 32 bit unit decrement 4042 operand immI_M1() 4043 %{ 4044 predicate(n->get_int() == -1); 4045 match(ConI); 4046 4047 op_cost(0); 4048 format %{ %} 4049 interface(CONST_INTER); 4050 %} 4051 4052 // Shift values for add/sub extension shift 4053 operand immIExt() 4054 %{ 4055 predicate(0 <= n->get_int() && (n->get_int() <= 4)); 4056 match(ConI); 4057 4058 op_cost(0); 4059 format %{ %} 4060 interface(CONST_INTER); 4061 %} 4062 4063 operand immI_gt_1() 4064 %{ 4065 predicate(n->get_int() > 1); 4066 match(ConI); 4067 4068 op_cost(0); 4069 format %{ %} 4070 interface(CONST_INTER); 4071 %} 4072 4073 operand immI_le_4() 4074 %{ 4075 predicate(n->get_int() <= 4); 4076 match(ConI); 4077 4078 op_cost(0); 4079 format %{ %} 4080 interface(CONST_INTER); 4081 %} 4082 4083 operand immI_16() 4084 %{ 4085 predicate(n->get_int() == 16); 4086 match(ConI); 4087 4088 op_cost(0); 4089 format %{ %} 4090 interface(CONST_INTER); 4091 %} 4092 4093 operand immI_24() 4094 %{ 4095 predicate(n->get_int() == 24); 4096 match(ConI); 4097 4098 op_cost(0); 4099 format %{ %} 4100 interface(CONST_INTER); 4101 %} 4102 4103 operand immI_32() 4104 %{ 4105 predicate(n->get_int() == 32); 4106 match(ConI); 4107 4108 op_cost(0); 4109 format %{ %} 4110 interface(CONST_INTER); 4111 %} 4112 4113 operand immI_48() 4114 %{ 4115 predicate(n->get_int() == 48); 4116 match(ConI); 4117 4118 op_cost(0); 4119 format %{ %} 4120 interface(CONST_INTER); 4121 %} 4122 4123 operand immI_56() 4124 %{ 4125 predicate(n->get_int() == 56); 4126 match(ConI); 4127 4128 op_cost(0); 4129 format %{ %} 4130 interface(CONST_INTER); 4131 %} 4132 4133 operand immI_63() 4134 %{ 4135 predicate(n->get_int() == 63); 4136 match(ConI); 4137 4138 op_cost(0); 4139 format %{ %} 4140 interface(CONST_INTER); 4141 %} 4142 4143 operand immI_64() 4144 %{ 4145 predicate(n->get_int() == 64); 4146 match(ConI); 4147 4148 op_cost(0); 4149 format %{ %} 4150 interface(CONST_INTER); 4151 %} 4152 4153 operand immI_255() 4154 %{ 4155 predicate(n->get_int() == 255); 4156 match(ConI); 4157 4158 op_cost(0); 4159 format %{ %} 4160 interface(CONST_INTER); 4161 %} 4162 4163 operand immI_65535() 4164 %{ 4165 predicate(n->get_int() == 65535); 4166 match(ConI); 4167 4168 op_cost(0); 4169 format %{ %} 4170 interface(CONST_INTER); 4171 %} 4172 4173 operand immI_positive() 4174 %{ 4175 predicate(n->get_int() > 0); 4176 match(ConI); 4177 4178 op_cost(0); 4179 format %{ %} 4180 interface(CONST_INTER); 4181 %} 4182 4183 // BoolTest condition for signed compare 4184 operand immI_cmp_cond() 4185 %{ 4186 predicate(!Matcher::is_unsigned_booltest_pred(n->get_int())); 4187 match(ConI); 4188 4189 op_cost(0); 4190 format %{ %} 4191 interface(CONST_INTER); 4192 %} 4193 4194 // BoolTest condition for unsigned compare 4195 operand immI_cmpU_cond() 4196 %{ 4197 predicate(Matcher::is_unsigned_booltest_pred(n->get_int())); 4198 match(ConI); 4199 4200 op_cost(0); 4201 format %{ %} 4202 interface(CONST_INTER); 4203 %} 4204 4205 operand immL_255() 4206 %{ 4207 predicate(n->get_long() == 255L); 4208 match(ConL); 4209 4210 op_cost(0); 4211 format %{ %} 4212 interface(CONST_INTER); 4213 %} 4214 4215 operand immL_65535() 4216 %{ 4217 predicate(n->get_long() == 65535L); 4218 match(ConL); 4219 4220 op_cost(0); 4221 format %{ %} 4222 interface(CONST_INTER); 4223 %} 4224 4225 operand immL_4294967295() 4226 %{ 4227 predicate(n->get_long() == 4294967295L); 4228 match(ConL); 4229 4230 op_cost(0); 4231 format %{ %} 4232 interface(CONST_INTER); 4233 %} 4234 4235 operand immL_bitmask() 4236 %{ 4237 predicate((n->get_long() != 0) 4238 && ((n->get_long() & 0xc000000000000000l) == 0) 4239 && is_power_of_2(n->get_long() + 1)); 4240 match(ConL); 4241 4242 op_cost(0); 4243 format %{ %} 4244 interface(CONST_INTER); 4245 %} 4246 4247 operand immI_bitmask() 4248 %{ 4249 predicate((n->get_int() != 0) 4250 && ((n->get_int() & 0xc0000000) == 0) 4251 && is_power_of_2(n->get_int() + 1)); 4252 match(ConI); 4253 4254 op_cost(0); 4255 format %{ %} 4256 interface(CONST_INTER); 4257 %} 4258 4259 operand immL_positive_bitmaskI() 4260 %{ 4261 predicate((n->get_long() != 0) 4262 && ((julong)n->get_long() < 0x80000000ULL) 4263 && is_power_of_2(n->get_long() + 1)); 4264 match(ConL); 4265 4266 op_cost(0); 4267 format %{ %} 4268 interface(CONST_INTER); 4269 %} 4270 4271 // Scale values for scaled offset addressing modes (up to long but not quad) 4272 operand immIScale() 4273 %{ 4274 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4275 match(ConI); 4276 4277 op_cost(0); 4278 format %{ %} 4279 interface(CONST_INTER); 4280 %} 4281 4282 // 26 bit signed offset -- for pc-relative branches 4283 operand immI26() 4284 %{ 4285 predicate(((-(1 << 25)) <= n->get_int()) && (n->get_int() < (1 << 25))); 4286 match(ConI); 4287 4288 op_cost(0); 4289 format %{ %} 4290 interface(CONST_INTER); 4291 %} 4292 4293 // 19 bit signed offset -- for pc-relative loads 4294 operand immI19() 4295 %{ 4296 predicate(((-(1 << 18)) <= n->get_int()) && (n->get_int() < (1 << 18))); 4297 match(ConI); 4298 4299 op_cost(0); 4300 format %{ %} 4301 interface(CONST_INTER); 4302 %} 4303 4304 // 5 bit signed integer 4305 operand immI5() 4306 %{ 4307 predicate(Assembler::is_simm(n->get_int(), 5)); 4308 match(ConI); 4309 4310 op_cost(0); 4311 format %{ %} 4312 interface(CONST_INTER); 4313 %} 4314 4315 // 7 bit unsigned integer 4316 operand immIU7() 4317 %{ 4318 predicate(Assembler::is_uimm(n->get_int(), 7)); 4319 match(ConI); 4320 4321 op_cost(0); 4322 format %{ %} 4323 interface(CONST_INTER); 4324 %} 4325 4326 // 12 bit unsigned offset -- for base plus immediate loads 4327 operand immIU12() 4328 %{ 4329 predicate((0 <= n->get_int()) && (n->get_int() < (1 << 12))); 4330 match(ConI); 4331 4332 op_cost(0); 4333 format %{ %} 4334 interface(CONST_INTER); 4335 %} 4336 4337 operand immLU12() 4338 %{ 4339 predicate((0 <= n->get_long()) && (n->get_long() < (1 << 12))); 4340 match(ConL); 4341 4342 op_cost(0); 4343 format %{ %} 4344 interface(CONST_INTER); 4345 %} 4346 4347 // Offset for scaled or unscaled immediate loads and stores 4348 operand immIOffset() 4349 %{ 4350 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4351 match(ConI); 4352 4353 op_cost(0); 4354 format %{ %} 4355 interface(CONST_INTER); 4356 %} 4357 4358 operand immIOffset1() 4359 %{ 4360 predicate(Address::offset_ok_for_immed(n->get_int(), 0)); 4361 match(ConI); 4362 4363 op_cost(0); 4364 format %{ %} 4365 interface(CONST_INTER); 4366 %} 4367 4368 operand immIOffset2() 4369 %{ 4370 predicate(Address::offset_ok_for_immed(n->get_int(), 1)); 4371 match(ConI); 4372 4373 op_cost(0); 4374 format %{ %} 4375 interface(CONST_INTER); 4376 %} 4377 4378 operand immIOffset4() 4379 %{ 4380 predicate(Address::offset_ok_for_immed(n->get_int(), 2)); 4381 match(ConI); 4382 4383 op_cost(0); 4384 format %{ %} 4385 interface(CONST_INTER); 4386 %} 4387 4388 operand immIOffset8() 4389 %{ 4390 predicate(Address::offset_ok_for_immed(n->get_int(), 3)); 4391 match(ConI); 4392 4393 op_cost(0); 4394 format %{ %} 4395 interface(CONST_INTER); 4396 %} 4397 4398 operand immIOffset16() 4399 %{ 4400 predicate(Address::offset_ok_for_immed(n->get_int(), 4)); 4401 match(ConI); 4402 4403 op_cost(0); 4404 format %{ %} 4405 interface(CONST_INTER); 4406 %} 4407 4408 operand immLoffset() 4409 %{ 4410 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4411 match(ConL); 4412 4413 op_cost(0); 4414 format %{ %} 4415 interface(CONST_INTER); 4416 %} 4417 4418 operand immLoffset1() 4419 %{ 4420 predicate(Address::offset_ok_for_immed(n->get_long(), 0)); 4421 match(ConL); 4422 4423 op_cost(0); 4424 format %{ %} 4425 interface(CONST_INTER); 4426 %} 4427 4428 operand immLoffset2() 4429 %{ 4430 predicate(Address::offset_ok_for_immed(n->get_long(), 1)); 4431 match(ConL); 4432 4433 op_cost(0); 4434 format %{ %} 4435 interface(CONST_INTER); 4436 %} 4437 4438 operand immLoffset4() 4439 %{ 4440 predicate(Address::offset_ok_for_immed(n->get_long(), 2)); 4441 match(ConL); 4442 4443 op_cost(0); 4444 format %{ %} 4445 interface(CONST_INTER); 4446 %} 4447 4448 operand immLoffset8() 4449 %{ 4450 predicate(Address::offset_ok_for_immed(n->get_long(), 3)); 4451 match(ConL); 4452 4453 op_cost(0); 4454 format %{ %} 4455 interface(CONST_INTER); 4456 %} 4457 4458 operand immLoffset16() 4459 %{ 4460 predicate(Address::offset_ok_for_immed(n->get_long(), 4)); 4461 match(ConL); 4462 4463 op_cost(0); 4464 format %{ %} 4465 interface(CONST_INTER); 4466 %} 4467 4468 // 5 bit signed long integer 4469 operand immL5() 4470 %{ 4471 predicate(Assembler::is_simm(n->get_long(), 5)); 4472 match(ConL); 4473 4474 op_cost(0); 4475 format %{ %} 4476 interface(CONST_INTER); 4477 %} 4478 4479 // 7 bit unsigned long integer 4480 operand immLU7() 4481 %{ 4482 predicate(Assembler::is_uimm(n->get_long(), 7)); 4483 match(ConL); 4484 4485 op_cost(0); 4486 format %{ %} 4487 interface(CONST_INTER); 4488 %} 4489 4490 // 8 bit signed value. 4491 operand immI8() 4492 %{ 4493 predicate(n->get_int() <= 127 && n->get_int() >= -128); 4494 match(ConI); 4495 4496 op_cost(0); 4497 format %{ %} 4498 interface(CONST_INTER); 4499 %} 4500 4501 // 8 bit signed value (simm8), or #simm8 LSL 8. 4502 operand immI8_shift8() 4503 %{ 4504 predicate((n->get_int() <= 127 && n->get_int() >= -128) || 4505 (n->get_int() <= 32512 && n->get_int() >= -32768 && (n->get_int() & 0xff) == 0)); 4506 match(ConI); 4507 4508 op_cost(0); 4509 format %{ %} 4510 interface(CONST_INTER); 4511 %} 4512 4513 // 8 bit signed value (simm8), or #simm8 LSL 8. 4514 operand immL8_shift8() 4515 %{ 4516 predicate((n->get_long() <= 127 && n->get_long() >= -128) || 4517 (n->get_long() <= 32512 && n->get_long() >= -32768 && (n->get_long() & 0xff) == 0)); 4518 match(ConL); 4519 4520 op_cost(0); 4521 format %{ %} 4522 interface(CONST_INTER); 4523 %} 4524 4525 // 8 bit integer valid for vector add sub immediate 4526 operand immBAddSubV() 4527 %{ 4528 predicate(n->get_int() <= 255 && n->get_int() >= -255); 4529 match(ConI); 4530 4531 op_cost(0); 4532 format %{ %} 4533 interface(CONST_INTER); 4534 %} 4535 4536 // 32 bit integer valid for add sub immediate 4537 operand immIAddSub() 4538 %{ 4539 predicate(Assembler::operand_valid_for_add_sub_immediate((int64_t)n->get_int())); 4540 match(ConI); 4541 op_cost(0); 4542 format %{ %} 4543 interface(CONST_INTER); 4544 %} 4545 4546 // 32 bit integer valid for vector add sub immediate 4547 operand immIAddSubV() 4548 %{ 4549 predicate(Assembler::operand_valid_for_sve_add_sub_immediate((int64_t)n->get_int())); 4550 match(ConI); 4551 4552 op_cost(0); 4553 format %{ %} 4554 interface(CONST_INTER); 4555 %} 4556 4557 // 32 bit unsigned integer valid for logical immediate 4558 4559 operand immBLog() 4560 %{ 4561 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerByte, (uint64_t)n->get_int())); 4562 match(ConI); 4563 4564 op_cost(0); 4565 format %{ %} 4566 interface(CONST_INTER); 4567 %} 4568 4569 operand immSLog() 4570 %{ 4571 predicate(Assembler::operand_valid_for_sve_logical_immediate(BitsPerShort, (uint64_t)n->get_int())); 4572 match(ConI); 4573 4574 op_cost(0); 4575 format %{ %} 4576 interface(CONST_INTER); 4577 %} 4578 4579 operand immILog() 4580 %{ 4581 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/true, (uint64_t)n->get_int())); 4582 match(ConI); 4583 4584 op_cost(0); 4585 format %{ %} 4586 interface(CONST_INTER); 4587 %} 4588 4589 // Integer operands 64 bit 4590 // 64 bit immediate 4591 operand immL() 4592 %{ 4593 match(ConL); 4594 4595 op_cost(0); 4596 format %{ %} 4597 interface(CONST_INTER); 4598 %} 4599 4600 // 64 bit zero 4601 operand immL0() 4602 %{ 4603 predicate(n->get_long() == 0); 4604 match(ConL); 4605 4606 op_cost(0); 4607 format %{ %} 4608 interface(CONST_INTER); 4609 %} 4610 4611 // 64 bit unit increment 4612 operand immL_1() 4613 %{ 4614 predicate(n->get_long() == 1); 4615 match(ConL); 4616 4617 op_cost(0); 4618 format %{ %} 4619 interface(CONST_INTER); 4620 %} 4621 4622 // 64 bit unit decrement 4623 operand immL_M1() 4624 %{ 4625 predicate(n->get_long() == -1); 4626 match(ConL); 4627 4628 op_cost(0); 4629 format %{ %} 4630 interface(CONST_INTER); 4631 %} 4632 4633 // 32 bit offset of pc in thread anchor 4634 4635 operand immL_pc_off() 4636 %{ 4637 predicate(n->get_long() == in_bytes(JavaThread::frame_anchor_offset()) + 4638 in_bytes(JavaFrameAnchor::last_Java_pc_offset())); 4639 match(ConL); 4640 4641 op_cost(0); 4642 format %{ %} 4643 interface(CONST_INTER); 4644 %} 4645 4646 // 64 bit integer valid for add sub immediate 4647 operand immLAddSub() 4648 %{ 4649 predicate(Assembler::operand_valid_for_add_sub_immediate(n->get_long())); 4650 match(ConL); 4651 op_cost(0); 4652 format %{ %} 4653 interface(CONST_INTER); 4654 %} 4655 4656 // 64 bit integer valid for addv subv immediate 4657 operand immLAddSubV() 4658 %{ 4659 predicate(Assembler::operand_valid_for_sve_add_sub_immediate(n->get_long())); 4660 match(ConL); 4661 4662 op_cost(0); 4663 format %{ %} 4664 interface(CONST_INTER); 4665 %} 4666 4667 // 64 bit integer valid for logical immediate 4668 operand immLLog() 4669 %{ 4670 predicate(Assembler::operand_valid_for_logical_immediate(/*is32*/false, (uint64_t)n->get_long())); 4671 match(ConL); 4672 op_cost(0); 4673 format %{ %} 4674 interface(CONST_INTER); 4675 %} 4676 4677 // Long Immediate: low 32-bit mask 4678 operand immL_32bits() 4679 %{ 4680 predicate(n->get_long() == 0xFFFFFFFFL); 4681 match(ConL); 4682 op_cost(0); 4683 format %{ %} 4684 interface(CONST_INTER); 4685 %} 4686 4687 // Pointer operands 4688 // Pointer Immediate 4689 operand immP() 4690 %{ 4691 match(ConP); 4692 4693 op_cost(0); 4694 format %{ %} 4695 interface(CONST_INTER); 4696 %} 4697 4698 // nullptr Pointer Immediate 4699 operand immP0() 4700 %{ 4701 predicate(n->get_ptr() == 0); 4702 match(ConP); 4703 4704 op_cost(0); 4705 format %{ %} 4706 interface(CONST_INTER); 4707 %} 4708 4709 // Pointer Immediate One 4710 // this is used in object initialization (initial object header) 4711 operand immP_1() 4712 %{ 4713 predicate(n->get_ptr() == 1); 4714 match(ConP); 4715 4716 op_cost(0); 4717 format %{ %} 4718 interface(CONST_INTER); 4719 %} 4720 4721 // Card Table Byte Map Base 4722 operand immByteMapBase() 4723 %{ 4724 // Get base of card map 4725 predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) && 4726 (CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base()); 4727 match(ConP); 4728 4729 op_cost(0); 4730 format %{ %} 4731 interface(CONST_INTER); 4732 %} 4733 4734 // Pointer Immediate Minus One 4735 // this is used when we want to write the current PC to the thread anchor 4736 operand immP_M1() 4737 %{ 4738 predicate(n->get_ptr() == -1); 4739 match(ConP); 4740 4741 op_cost(0); 4742 format %{ %} 4743 interface(CONST_INTER); 4744 %} 4745 4746 // Pointer Immediate Minus Two 4747 // this is used when we want to write the current PC to the thread anchor 4748 operand immP_M2() 4749 %{ 4750 predicate(n->get_ptr() == -2); 4751 match(ConP); 4752 4753 op_cost(0); 4754 format %{ %} 4755 interface(CONST_INTER); 4756 %} 4757 4758 // Float and Double operands 4759 // Double Immediate 4760 operand immD() 4761 %{ 4762 match(ConD); 4763 op_cost(0); 4764 format %{ %} 4765 interface(CONST_INTER); 4766 %} 4767 4768 // Double Immediate: +0.0d 4769 operand immD0() 4770 %{ 4771 predicate(jlong_cast(n->getd()) == 0); 4772 match(ConD); 4773 4774 op_cost(0); 4775 format %{ %} 4776 interface(CONST_INTER); 4777 %} 4778 4779 // constant 'double +0.0'. 4780 operand immDPacked() 4781 %{ 4782 predicate(Assembler::operand_valid_for_float_immediate(n->getd())); 4783 match(ConD); 4784 op_cost(0); 4785 format %{ %} 4786 interface(CONST_INTER); 4787 %} 4788 4789 // Float Immediate 4790 operand immF() 4791 %{ 4792 match(ConF); 4793 op_cost(0); 4794 format %{ %} 4795 interface(CONST_INTER); 4796 %} 4797 4798 // Float Immediate: +0.0f. 4799 operand immF0() 4800 %{ 4801 predicate(jint_cast(n->getf()) == 0); 4802 match(ConF); 4803 4804 op_cost(0); 4805 format %{ %} 4806 interface(CONST_INTER); 4807 %} 4808 4809 // 4810 operand immFPacked() 4811 %{ 4812 predicate(Assembler::operand_valid_for_float_immediate((double)n->getf())); 4813 match(ConF); 4814 op_cost(0); 4815 format %{ %} 4816 interface(CONST_INTER); 4817 %} 4818 4819 // Narrow pointer operands 4820 // Narrow Pointer Immediate 4821 operand immN() 4822 %{ 4823 match(ConN); 4824 4825 op_cost(0); 4826 format %{ %} 4827 interface(CONST_INTER); 4828 %} 4829 4830 // Narrow nullptr Pointer Immediate 4831 operand immN0() 4832 %{ 4833 predicate(n->get_narrowcon() == 0); 4834 match(ConN); 4835 4836 op_cost(0); 4837 format %{ %} 4838 interface(CONST_INTER); 4839 %} 4840 4841 operand immNKlass() 4842 %{ 4843 match(ConNKlass); 4844 4845 op_cost(0); 4846 format %{ %} 4847 interface(CONST_INTER); 4848 %} 4849 4850 // Integer 32 bit Register Operands 4851 // Integer 32 bitRegister (excludes SP) 4852 operand iRegI() 4853 %{ 4854 constraint(ALLOC_IN_RC(any_reg32)); 4855 match(RegI); 4856 match(iRegINoSp); 4857 op_cost(0); 4858 format %{ %} 4859 interface(REG_INTER); 4860 %} 4861 4862 // Integer 32 bit Register not Special 4863 operand iRegINoSp() 4864 %{ 4865 constraint(ALLOC_IN_RC(no_special_reg32)); 4866 match(RegI); 4867 op_cost(0); 4868 format %{ %} 4869 interface(REG_INTER); 4870 %} 4871 4872 // Integer 64 bit Register Operands 4873 // Integer 64 bit Register (includes SP) 4874 operand iRegL() 4875 %{ 4876 constraint(ALLOC_IN_RC(any_reg)); 4877 match(RegL); 4878 match(iRegLNoSp); 4879 op_cost(0); 4880 format %{ %} 4881 interface(REG_INTER); 4882 %} 4883 4884 // Integer 64 bit Register not Special 4885 operand iRegLNoSp() 4886 %{ 4887 constraint(ALLOC_IN_RC(no_special_reg)); 4888 match(RegL); 4889 match(iRegL_R0); 4890 format %{ %} 4891 interface(REG_INTER); 4892 %} 4893 4894 // Pointer Register Operands 4895 // Pointer Register 4896 operand iRegP() 4897 %{ 4898 constraint(ALLOC_IN_RC(ptr_reg)); 4899 match(RegP); 4900 match(iRegPNoSp); 4901 match(iRegP_R0); 4902 //match(iRegP_R2); 4903 //match(iRegP_R4); 4904 match(iRegP_R5); 4905 match(thread_RegP); 4906 op_cost(0); 4907 format %{ %} 4908 interface(REG_INTER); 4909 %} 4910 4911 // Pointer 64 bit Register not Special 4912 operand iRegPNoSp() 4913 %{ 4914 constraint(ALLOC_IN_RC(no_special_ptr_reg)); 4915 match(RegP); 4916 // match(iRegP); 4917 // match(iRegP_R0); 4918 // match(iRegP_R2); 4919 // match(iRegP_R4); 4920 // match(iRegP_R5); 4921 // match(thread_RegP); 4922 op_cost(0); 4923 format %{ %} 4924 interface(REG_INTER); 4925 %} 4926 4927 // Pointer 64 bit Register R0 only 4928 operand iRegP_R0() 4929 %{ 4930 constraint(ALLOC_IN_RC(r0_reg)); 4931 match(RegP); 4932 // match(iRegP); 4933 match(iRegPNoSp); 4934 op_cost(0); 4935 format %{ %} 4936 interface(REG_INTER); 4937 %} 4938 4939 // Pointer 64 bit Register R1 only 4940 operand iRegP_R1() 4941 %{ 4942 constraint(ALLOC_IN_RC(r1_reg)); 4943 match(RegP); 4944 // match(iRegP); 4945 match(iRegPNoSp); 4946 op_cost(0); 4947 format %{ %} 4948 interface(REG_INTER); 4949 %} 4950 4951 // Pointer 64 bit Register R2 only 4952 operand iRegP_R2() 4953 %{ 4954 constraint(ALLOC_IN_RC(r2_reg)); 4955 match(RegP); 4956 // match(iRegP); 4957 match(iRegPNoSp); 4958 op_cost(0); 4959 format %{ %} 4960 interface(REG_INTER); 4961 %} 4962 4963 // Pointer 64 bit Register R3 only 4964 operand iRegP_R3() 4965 %{ 4966 constraint(ALLOC_IN_RC(r3_reg)); 4967 match(RegP); 4968 // match(iRegP); 4969 match(iRegPNoSp); 4970 op_cost(0); 4971 format %{ %} 4972 interface(REG_INTER); 4973 %} 4974 4975 // Pointer 64 bit Register R4 only 4976 operand iRegP_R4() 4977 %{ 4978 constraint(ALLOC_IN_RC(r4_reg)); 4979 match(RegP); 4980 // match(iRegP); 4981 match(iRegPNoSp); 4982 op_cost(0); 4983 format %{ %} 4984 interface(REG_INTER); 4985 %} 4986 4987 // Pointer 64 bit Register R5 only 4988 operand iRegP_R5() 4989 %{ 4990 constraint(ALLOC_IN_RC(r5_reg)); 4991 match(RegP); 4992 // match(iRegP); 4993 match(iRegPNoSp); 4994 op_cost(0); 4995 format %{ %} 4996 interface(REG_INTER); 4997 %} 4998 4999 // Pointer 64 bit Register R10 only 5000 operand iRegP_R10() 5001 %{ 5002 constraint(ALLOC_IN_RC(r10_reg)); 5003 match(RegP); 5004 // match(iRegP); 5005 match(iRegPNoSp); 5006 op_cost(0); 5007 format %{ %} 5008 interface(REG_INTER); 5009 %} 5010 5011 // Long 64 bit Register R0 only 5012 operand iRegL_R0() 5013 %{ 5014 constraint(ALLOC_IN_RC(r0_reg)); 5015 match(RegL); 5016 match(iRegLNoSp); 5017 op_cost(0); 5018 format %{ %} 5019 interface(REG_INTER); 5020 %} 5021 5022 // Long 64 bit Register R2 only 5023 operand iRegL_R2() 5024 %{ 5025 constraint(ALLOC_IN_RC(r2_reg)); 5026 match(RegL); 5027 match(iRegLNoSp); 5028 op_cost(0); 5029 format %{ %} 5030 interface(REG_INTER); 5031 %} 5032 5033 // Long 64 bit Register R3 only 5034 operand iRegL_R3() 5035 %{ 5036 constraint(ALLOC_IN_RC(r3_reg)); 5037 match(RegL); 5038 match(iRegLNoSp); 5039 op_cost(0); 5040 format %{ %} 5041 interface(REG_INTER); 5042 %} 5043 5044 // Long 64 bit Register R11 only 5045 operand iRegL_R11() 5046 %{ 5047 constraint(ALLOC_IN_RC(r11_reg)); 5048 match(RegL); 5049 match(iRegLNoSp); 5050 op_cost(0); 5051 format %{ %} 5052 interface(REG_INTER); 5053 %} 5054 5055 // Pointer 64 bit Register FP only 5056 operand iRegP_FP() 5057 %{ 5058 constraint(ALLOC_IN_RC(fp_reg)); 5059 match(RegP); 5060 // match(iRegP); 5061 op_cost(0); 5062 format %{ %} 5063 interface(REG_INTER); 5064 %} 5065 5066 // Register R0 only 5067 operand iRegI_R0() 5068 %{ 5069 constraint(ALLOC_IN_RC(int_r0_reg)); 5070 match(RegI); 5071 match(iRegINoSp); 5072 op_cost(0); 5073 format %{ %} 5074 interface(REG_INTER); 5075 %} 5076 5077 // Register R2 only 5078 operand iRegI_R2() 5079 %{ 5080 constraint(ALLOC_IN_RC(int_r2_reg)); 5081 match(RegI); 5082 match(iRegINoSp); 5083 op_cost(0); 5084 format %{ %} 5085 interface(REG_INTER); 5086 %} 5087 5088 // Register R3 only 5089 operand iRegI_R3() 5090 %{ 5091 constraint(ALLOC_IN_RC(int_r3_reg)); 5092 match(RegI); 5093 match(iRegINoSp); 5094 op_cost(0); 5095 format %{ %} 5096 interface(REG_INTER); 5097 %} 5098 5099 5100 // Register R4 only 5101 operand iRegI_R4() 5102 %{ 5103 constraint(ALLOC_IN_RC(int_r4_reg)); 5104 match(RegI); 5105 match(iRegINoSp); 5106 op_cost(0); 5107 format %{ %} 5108 interface(REG_INTER); 5109 %} 5110 5111 5112 // Pointer Register Operands 5113 // Narrow Pointer Register 5114 operand iRegN() 5115 %{ 5116 constraint(ALLOC_IN_RC(any_reg32)); 5117 match(RegN); 5118 match(iRegNNoSp); 5119 op_cost(0); 5120 format %{ %} 5121 interface(REG_INTER); 5122 %} 5123 5124 operand iRegN_R0() 5125 %{ 5126 constraint(ALLOC_IN_RC(r0_reg)); 5127 match(iRegN); 5128 op_cost(0); 5129 format %{ %} 5130 interface(REG_INTER); 5131 %} 5132 5133 operand iRegN_R2() 5134 %{ 5135 constraint(ALLOC_IN_RC(r2_reg)); 5136 match(iRegN); 5137 op_cost(0); 5138 format %{ %} 5139 interface(REG_INTER); 5140 %} 5141 5142 operand iRegN_R3() 5143 %{ 5144 constraint(ALLOC_IN_RC(r3_reg)); 5145 match(iRegN); 5146 op_cost(0); 5147 format %{ %} 5148 interface(REG_INTER); 5149 %} 5150 5151 // Integer 64 bit Register not Special 5152 operand iRegNNoSp() 5153 %{ 5154 constraint(ALLOC_IN_RC(no_special_reg32)); 5155 match(RegN); 5156 op_cost(0); 5157 format %{ %} 5158 interface(REG_INTER); 5159 %} 5160 5161 // Float Register 5162 // Float register operands 5163 operand vRegF() 5164 %{ 5165 constraint(ALLOC_IN_RC(float_reg)); 5166 match(RegF); 5167 5168 op_cost(0); 5169 format %{ %} 5170 interface(REG_INTER); 5171 %} 5172 5173 // Double Register 5174 // Double register operands 5175 operand vRegD() 5176 %{ 5177 constraint(ALLOC_IN_RC(double_reg)); 5178 match(RegD); 5179 5180 op_cost(0); 5181 format %{ %} 5182 interface(REG_INTER); 5183 %} 5184 5185 // Generic vector class. This will be used for 5186 // all vector operands, including NEON and SVE. 5187 operand vReg() 5188 %{ 5189 constraint(ALLOC_IN_RC(dynamic)); 5190 match(VecA); 5191 match(VecD); 5192 match(VecX); 5193 5194 op_cost(0); 5195 format %{ %} 5196 interface(REG_INTER); 5197 %} 5198 5199 operand vecA() 5200 %{ 5201 constraint(ALLOC_IN_RC(vectora_reg)); 5202 match(VecA); 5203 5204 op_cost(0); 5205 format %{ %} 5206 interface(REG_INTER); 5207 %} 5208 5209 operand vecD() 5210 %{ 5211 constraint(ALLOC_IN_RC(vectord_reg)); 5212 match(VecD); 5213 5214 op_cost(0); 5215 format %{ %} 5216 interface(REG_INTER); 5217 %} 5218 5219 operand vecX() 5220 %{ 5221 constraint(ALLOC_IN_RC(vectorx_reg)); 5222 match(VecX); 5223 5224 op_cost(0); 5225 format %{ %} 5226 interface(REG_INTER); 5227 %} 5228 5229 operand vRegD_V0() 5230 %{ 5231 constraint(ALLOC_IN_RC(v0_reg)); 5232 match(RegD); 5233 op_cost(0); 5234 format %{ %} 5235 interface(REG_INTER); 5236 %} 5237 5238 operand vRegD_V1() 5239 %{ 5240 constraint(ALLOC_IN_RC(v1_reg)); 5241 match(RegD); 5242 op_cost(0); 5243 format %{ %} 5244 interface(REG_INTER); 5245 %} 5246 5247 operand vRegD_V2() 5248 %{ 5249 constraint(ALLOC_IN_RC(v2_reg)); 5250 match(RegD); 5251 op_cost(0); 5252 format %{ %} 5253 interface(REG_INTER); 5254 %} 5255 5256 operand vRegD_V3() 5257 %{ 5258 constraint(ALLOC_IN_RC(v3_reg)); 5259 match(RegD); 5260 op_cost(0); 5261 format %{ %} 5262 interface(REG_INTER); 5263 %} 5264 5265 operand vRegD_V4() 5266 %{ 5267 constraint(ALLOC_IN_RC(v4_reg)); 5268 match(RegD); 5269 op_cost(0); 5270 format %{ %} 5271 interface(REG_INTER); 5272 %} 5273 5274 operand vRegD_V5() 5275 %{ 5276 constraint(ALLOC_IN_RC(v5_reg)); 5277 match(RegD); 5278 op_cost(0); 5279 format %{ %} 5280 interface(REG_INTER); 5281 %} 5282 5283 operand vRegD_V6() 5284 %{ 5285 constraint(ALLOC_IN_RC(v6_reg)); 5286 match(RegD); 5287 op_cost(0); 5288 format %{ %} 5289 interface(REG_INTER); 5290 %} 5291 5292 operand vRegD_V7() 5293 %{ 5294 constraint(ALLOC_IN_RC(v7_reg)); 5295 match(RegD); 5296 op_cost(0); 5297 format %{ %} 5298 interface(REG_INTER); 5299 %} 5300 5301 operand vRegD_V8() 5302 %{ 5303 constraint(ALLOC_IN_RC(v8_reg)); 5304 match(RegD); 5305 op_cost(0); 5306 format %{ %} 5307 interface(REG_INTER); 5308 %} 5309 5310 operand vRegD_V9() 5311 %{ 5312 constraint(ALLOC_IN_RC(v9_reg)); 5313 match(RegD); 5314 op_cost(0); 5315 format %{ %} 5316 interface(REG_INTER); 5317 %} 5318 5319 operand vRegD_V10() 5320 %{ 5321 constraint(ALLOC_IN_RC(v10_reg)); 5322 match(RegD); 5323 op_cost(0); 5324 format %{ %} 5325 interface(REG_INTER); 5326 %} 5327 5328 operand vRegD_V11() 5329 %{ 5330 constraint(ALLOC_IN_RC(v11_reg)); 5331 match(RegD); 5332 op_cost(0); 5333 format %{ %} 5334 interface(REG_INTER); 5335 %} 5336 5337 operand vRegD_V12() 5338 %{ 5339 constraint(ALLOC_IN_RC(v12_reg)); 5340 match(RegD); 5341 op_cost(0); 5342 format %{ %} 5343 interface(REG_INTER); 5344 %} 5345 5346 operand vRegD_V13() 5347 %{ 5348 constraint(ALLOC_IN_RC(v13_reg)); 5349 match(RegD); 5350 op_cost(0); 5351 format %{ %} 5352 interface(REG_INTER); 5353 %} 5354 5355 operand vRegD_V14() 5356 %{ 5357 constraint(ALLOC_IN_RC(v14_reg)); 5358 match(RegD); 5359 op_cost(0); 5360 format %{ %} 5361 interface(REG_INTER); 5362 %} 5363 5364 operand vRegD_V15() 5365 %{ 5366 constraint(ALLOC_IN_RC(v15_reg)); 5367 match(RegD); 5368 op_cost(0); 5369 format %{ %} 5370 interface(REG_INTER); 5371 %} 5372 5373 operand vRegD_V16() 5374 %{ 5375 constraint(ALLOC_IN_RC(v16_reg)); 5376 match(RegD); 5377 op_cost(0); 5378 format %{ %} 5379 interface(REG_INTER); 5380 %} 5381 5382 operand vRegD_V17() 5383 %{ 5384 constraint(ALLOC_IN_RC(v17_reg)); 5385 match(RegD); 5386 op_cost(0); 5387 format %{ %} 5388 interface(REG_INTER); 5389 %} 5390 5391 operand vRegD_V18() 5392 %{ 5393 constraint(ALLOC_IN_RC(v18_reg)); 5394 match(RegD); 5395 op_cost(0); 5396 format %{ %} 5397 interface(REG_INTER); 5398 %} 5399 5400 operand vRegD_V19() 5401 %{ 5402 constraint(ALLOC_IN_RC(v19_reg)); 5403 match(RegD); 5404 op_cost(0); 5405 format %{ %} 5406 interface(REG_INTER); 5407 %} 5408 5409 operand vRegD_V20() 5410 %{ 5411 constraint(ALLOC_IN_RC(v20_reg)); 5412 match(RegD); 5413 op_cost(0); 5414 format %{ %} 5415 interface(REG_INTER); 5416 %} 5417 5418 operand vRegD_V21() 5419 %{ 5420 constraint(ALLOC_IN_RC(v21_reg)); 5421 match(RegD); 5422 op_cost(0); 5423 format %{ %} 5424 interface(REG_INTER); 5425 %} 5426 5427 operand vRegD_V22() 5428 %{ 5429 constraint(ALLOC_IN_RC(v22_reg)); 5430 match(RegD); 5431 op_cost(0); 5432 format %{ %} 5433 interface(REG_INTER); 5434 %} 5435 5436 operand vRegD_V23() 5437 %{ 5438 constraint(ALLOC_IN_RC(v23_reg)); 5439 match(RegD); 5440 op_cost(0); 5441 format %{ %} 5442 interface(REG_INTER); 5443 %} 5444 5445 operand vRegD_V24() 5446 %{ 5447 constraint(ALLOC_IN_RC(v24_reg)); 5448 match(RegD); 5449 op_cost(0); 5450 format %{ %} 5451 interface(REG_INTER); 5452 %} 5453 5454 operand vRegD_V25() 5455 %{ 5456 constraint(ALLOC_IN_RC(v25_reg)); 5457 match(RegD); 5458 op_cost(0); 5459 format %{ %} 5460 interface(REG_INTER); 5461 %} 5462 5463 operand vRegD_V26() 5464 %{ 5465 constraint(ALLOC_IN_RC(v26_reg)); 5466 match(RegD); 5467 op_cost(0); 5468 format %{ %} 5469 interface(REG_INTER); 5470 %} 5471 5472 operand vRegD_V27() 5473 %{ 5474 constraint(ALLOC_IN_RC(v27_reg)); 5475 match(RegD); 5476 op_cost(0); 5477 format %{ %} 5478 interface(REG_INTER); 5479 %} 5480 5481 operand vRegD_V28() 5482 %{ 5483 constraint(ALLOC_IN_RC(v28_reg)); 5484 match(RegD); 5485 op_cost(0); 5486 format %{ %} 5487 interface(REG_INTER); 5488 %} 5489 5490 operand vRegD_V29() 5491 %{ 5492 constraint(ALLOC_IN_RC(v29_reg)); 5493 match(RegD); 5494 op_cost(0); 5495 format %{ %} 5496 interface(REG_INTER); 5497 %} 5498 5499 operand vRegD_V30() 5500 %{ 5501 constraint(ALLOC_IN_RC(v30_reg)); 5502 match(RegD); 5503 op_cost(0); 5504 format %{ %} 5505 interface(REG_INTER); 5506 %} 5507 5508 operand vRegD_V31() 5509 %{ 5510 constraint(ALLOC_IN_RC(v31_reg)); 5511 match(RegD); 5512 op_cost(0); 5513 format %{ %} 5514 interface(REG_INTER); 5515 %} 5516 5517 operand pReg() 5518 %{ 5519 constraint(ALLOC_IN_RC(pr_reg)); 5520 match(RegVectMask); 5521 match(pRegGov); 5522 op_cost(0); 5523 format %{ %} 5524 interface(REG_INTER); 5525 %} 5526 5527 operand pRegGov() 5528 %{ 5529 constraint(ALLOC_IN_RC(gov_pr)); 5530 match(RegVectMask); 5531 match(pReg); 5532 op_cost(0); 5533 format %{ %} 5534 interface(REG_INTER); 5535 %} 5536 5537 operand pRegGov_P0() 5538 %{ 5539 constraint(ALLOC_IN_RC(p0_reg)); 5540 match(RegVectMask); 5541 op_cost(0); 5542 format %{ %} 5543 interface(REG_INTER); 5544 %} 5545 5546 operand pRegGov_P1() 5547 %{ 5548 constraint(ALLOC_IN_RC(p1_reg)); 5549 match(RegVectMask); 5550 op_cost(0); 5551 format %{ %} 5552 interface(REG_INTER); 5553 %} 5554 5555 // Flags register, used as output of signed compare instructions 5556 5557 // note that on AArch64 we also use this register as the output for 5558 // for floating point compare instructions (CmpF CmpD). this ensures 5559 // that ordered inequality tests use GT, GE, LT or LE none of which 5560 // pass through cases where the result is unordered i.e. one or both 5561 // inputs to the compare is a NaN. this means that the ideal code can 5562 // replace e.g. a GT with an LE and not end up capturing the NaN case 5563 // (where the comparison should always fail). EQ and NE tests are 5564 // always generated in ideal code so that unordered folds into the NE 5565 // case, matching the behaviour of AArch64 NE. 5566 // 5567 // This differs from x86 where the outputs of FP compares use a 5568 // special FP flags registers and where compares based on this 5569 // register are distinguished into ordered inequalities (cmpOpUCF) and 5570 // EQ/NEQ tests (cmpOpUCF2). x86 has to special case the latter tests 5571 // to explicitly handle the unordered case in branches. x86 also has 5572 // to include extra CMoveX rules to accept a cmpOpUCF input. 5573 5574 operand rFlagsReg() 5575 %{ 5576 constraint(ALLOC_IN_RC(int_flags)); 5577 match(RegFlags); 5578 5579 op_cost(0); 5580 format %{ "RFLAGS" %} 5581 interface(REG_INTER); 5582 %} 5583 5584 // Flags register, used as output of unsigned compare instructions 5585 operand rFlagsRegU() 5586 %{ 5587 constraint(ALLOC_IN_RC(int_flags)); 5588 match(RegFlags); 5589 5590 op_cost(0); 5591 format %{ "RFLAGSU" %} 5592 interface(REG_INTER); 5593 %} 5594 5595 // Special Registers 5596 5597 // Method Register 5598 operand inline_cache_RegP(iRegP reg) 5599 %{ 5600 constraint(ALLOC_IN_RC(method_reg)); // inline_cache_reg 5601 match(reg); 5602 match(iRegPNoSp); 5603 op_cost(0); 5604 format %{ %} 5605 interface(REG_INTER); 5606 %} 5607 5608 // Thread Register 5609 operand thread_RegP(iRegP reg) 5610 %{ 5611 constraint(ALLOC_IN_RC(thread_reg)); // link_reg 5612 match(reg); 5613 op_cost(0); 5614 format %{ %} 5615 interface(REG_INTER); 5616 %} 5617 5618 operand lr_RegP(iRegP reg) 5619 %{ 5620 constraint(ALLOC_IN_RC(lr_reg)); // link_reg 5621 match(reg); 5622 op_cost(0); 5623 format %{ %} 5624 interface(REG_INTER); 5625 %} 5626 5627 //----------Memory Operands---------------------------------------------------- 5628 5629 operand indirect(iRegP reg) 5630 %{ 5631 constraint(ALLOC_IN_RC(ptr_reg)); 5632 match(reg); 5633 op_cost(0); 5634 format %{ "[$reg]" %} 5635 interface(MEMORY_INTER) %{ 5636 base($reg); 5637 index(0xffffffff); 5638 scale(0x0); 5639 disp(0x0); 5640 %} 5641 %} 5642 5643 operand indIndexScaledI2L(iRegP reg, iRegI ireg, immIScale scale) 5644 %{ 5645 constraint(ALLOC_IN_RC(ptr_reg)); 5646 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5647 match(AddP reg (LShiftL (ConvI2L ireg) scale)); 5648 op_cost(0); 5649 format %{ "$reg, $ireg sxtw($scale), 0, I2L" %} 5650 interface(MEMORY_INTER) %{ 5651 base($reg); 5652 index($ireg); 5653 scale($scale); 5654 disp(0x0); 5655 %} 5656 %} 5657 5658 operand indIndexScaled(iRegP reg, iRegL lreg, immIScale scale) 5659 %{ 5660 constraint(ALLOC_IN_RC(ptr_reg)); 5661 predicate(size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5662 match(AddP reg (LShiftL lreg scale)); 5663 op_cost(0); 5664 format %{ "$reg, $lreg lsl($scale)" %} 5665 interface(MEMORY_INTER) %{ 5666 base($reg); 5667 index($lreg); 5668 scale($scale); 5669 disp(0x0); 5670 %} 5671 %} 5672 5673 operand indIndexI2L(iRegP reg, iRegI ireg) 5674 %{ 5675 constraint(ALLOC_IN_RC(ptr_reg)); 5676 match(AddP reg (ConvI2L ireg)); 5677 op_cost(0); 5678 format %{ "$reg, $ireg, 0, I2L" %} 5679 interface(MEMORY_INTER) %{ 5680 base($reg); 5681 index($ireg); 5682 scale(0x0); 5683 disp(0x0); 5684 %} 5685 %} 5686 5687 operand indIndex(iRegP reg, iRegL lreg) 5688 %{ 5689 constraint(ALLOC_IN_RC(ptr_reg)); 5690 match(AddP reg lreg); 5691 op_cost(0); 5692 format %{ "$reg, $lreg" %} 5693 interface(MEMORY_INTER) %{ 5694 base($reg); 5695 index($lreg); 5696 scale(0x0); 5697 disp(0x0); 5698 %} 5699 %} 5700 5701 operand indOffI(iRegP reg, immIOffset off) 5702 %{ 5703 constraint(ALLOC_IN_RC(ptr_reg)); 5704 match(AddP reg off); 5705 op_cost(0); 5706 format %{ "[$reg, $off]" %} 5707 interface(MEMORY_INTER) %{ 5708 base($reg); 5709 index(0xffffffff); 5710 scale(0x0); 5711 disp($off); 5712 %} 5713 %} 5714 5715 operand indOffI1(iRegP reg, immIOffset1 off) 5716 %{ 5717 constraint(ALLOC_IN_RC(ptr_reg)); 5718 match(AddP reg off); 5719 op_cost(0); 5720 format %{ "[$reg, $off]" %} 5721 interface(MEMORY_INTER) %{ 5722 base($reg); 5723 index(0xffffffff); 5724 scale(0x0); 5725 disp($off); 5726 %} 5727 %} 5728 5729 operand indOffI2(iRegP reg, immIOffset2 off) 5730 %{ 5731 constraint(ALLOC_IN_RC(ptr_reg)); 5732 match(AddP reg off); 5733 op_cost(0); 5734 format %{ "[$reg, $off]" %} 5735 interface(MEMORY_INTER) %{ 5736 base($reg); 5737 index(0xffffffff); 5738 scale(0x0); 5739 disp($off); 5740 %} 5741 %} 5742 5743 operand indOffI4(iRegP reg, immIOffset4 off) 5744 %{ 5745 constraint(ALLOC_IN_RC(ptr_reg)); 5746 match(AddP reg off); 5747 op_cost(0); 5748 format %{ "[$reg, $off]" %} 5749 interface(MEMORY_INTER) %{ 5750 base($reg); 5751 index(0xffffffff); 5752 scale(0x0); 5753 disp($off); 5754 %} 5755 %} 5756 5757 operand indOffI8(iRegP reg, immIOffset8 off) 5758 %{ 5759 constraint(ALLOC_IN_RC(ptr_reg)); 5760 match(AddP reg off); 5761 op_cost(0); 5762 format %{ "[$reg, $off]" %} 5763 interface(MEMORY_INTER) %{ 5764 base($reg); 5765 index(0xffffffff); 5766 scale(0x0); 5767 disp($off); 5768 %} 5769 %} 5770 5771 operand indOffI16(iRegP reg, immIOffset16 off) 5772 %{ 5773 constraint(ALLOC_IN_RC(ptr_reg)); 5774 match(AddP reg off); 5775 op_cost(0); 5776 format %{ "[$reg, $off]" %} 5777 interface(MEMORY_INTER) %{ 5778 base($reg); 5779 index(0xffffffff); 5780 scale(0x0); 5781 disp($off); 5782 %} 5783 %} 5784 5785 operand indOffL(iRegP reg, immLoffset off) 5786 %{ 5787 constraint(ALLOC_IN_RC(ptr_reg)); 5788 match(AddP reg off); 5789 op_cost(0); 5790 format %{ "[$reg, $off]" %} 5791 interface(MEMORY_INTER) %{ 5792 base($reg); 5793 index(0xffffffff); 5794 scale(0x0); 5795 disp($off); 5796 %} 5797 %} 5798 5799 operand indOffL1(iRegP reg, immLoffset1 off) 5800 %{ 5801 constraint(ALLOC_IN_RC(ptr_reg)); 5802 match(AddP reg off); 5803 op_cost(0); 5804 format %{ "[$reg, $off]" %} 5805 interface(MEMORY_INTER) %{ 5806 base($reg); 5807 index(0xffffffff); 5808 scale(0x0); 5809 disp($off); 5810 %} 5811 %} 5812 5813 operand indOffL2(iRegP reg, immLoffset2 off) 5814 %{ 5815 constraint(ALLOC_IN_RC(ptr_reg)); 5816 match(AddP reg off); 5817 op_cost(0); 5818 format %{ "[$reg, $off]" %} 5819 interface(MEMORY_INTER) %{ 5820 base($reg); 5821 index(0xffffffff); 5822 scale(0x0); 5823 disp($off); 5824 %} 5825 %} 5826 5827 operand indOffL4(iRegP reg, immLoffset4 off) 5828 %{ 5829 constraint(ALLOC_IN_RC(ptr_reg)); 5830 match(AddP reg off); 5831 op_cost(0); 5832 format %{ "[$reg, $off]" %} 5833 interface(MEMORY_INTER) %{ 5834 base($reg); 5835 index(0xffffffff); 5836 scale(0x0); 5837 disp($off); 5838 %} 5839 %} 5840 5841 operand indOffL8(iRegP reg, immLoffset8 off) 5842 %{ 5843 constraint(ALLOC_IN_RC(ptr_reg)); 5844 match(AddP reg off); 5845 op_cost(0); 5846 format %{ "[$reg, $off]" %} 5847 interface(MEMORY_INTER) %{ 5848 base($reg); 5849 index(0xffffffff); 5850 scale(0x0); 5851 disp($off); 5852 %} 5853 %} 5854 5855 operand indOffL16(iRegP reg, immLoffset16 off) 5856 %{ 5857 constraint(ALLOC_IN_RC(ptr_reg)); 5858 match(AddP reg off); 5859 op_cost(0); 5860 format %{ "[$reg, $off]" %} 5861 interface(MEMORY_INTER) %{ 5862 base($reg); 5863 index(0xffffffff); 5864 scale(0x0); 5865 disp($off); 5866 %} 5867 %} 5868 5869 operand indirectN(iRegN reg) 5870 %{ 5871 predicate(CompressedOops::shift() == 0); 5872 constraint(ALLOC_IN_RC(ptr_reg)); 5873 match(DecodeN reg); 5874 op_cost(0); 5875 format %{ "[$reg]\t# narrow" %} 5876 interface(MEMORY_INTER) %{ 5877 base($reg); 5878 index(0xffffffff); 5879 scale(0x0); 5880 disp(0x0); 5881 %} 5882 %} 5883 5884 operand indIndexScaledI2LN(iRegN reg, iRegI ireg, immIScale scale) 5885 %{ 5886 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5887 constraint(ALLOC_IN_RC(ptr_reg)); 5888 match(AddP (DecodeN reg) (LShiftL (ConvI2L ireg) scale)); 5889 op_cost(0); 5890 format %{ "$reg, $ireg sxtw($scale), 0, I2L\t# narrow" %} 5891 interface(MEMORY_INTER) %{ 5892 base($reg); 5893 index($ireg); 5894 scale($scale); 5895 disp(0x0); 5896 %} 5897 %} 5898 5899 operand indIndexScaledN(iRegN reg, iRegL lreg, immIScale scale) 5900 %{ 5901 predicate(CompressedOops::shift() == 0 && size_fits_all_mem_uses(n->as_AddP(), n->in(AddPNode::Offset)->in(2)->get_int())); 5902 constraint(ALLOC_IN_RC(ptr_reg)); 5903 match(AddP (DecodeN reg) (LShiftL lreg scale)); 5904 op_cost(0); 5905 format %{ "$reg, $lreg lsl($scale)\t# narrow" %} 5906 interface(MEMORY_INTER) %{ 5907 base($reg); 5908 index($lreg); 5909 scale($scale); 5910 disp(0x0); 5911 %} 5912 %} 5913 5914 operand indIndexI2LN(iRegN reg, iRegI ireg) 5915 %{ 5916 predicate(CompressedOops::shift() == 0); 5917 constraint(ALLOC_IN_RC(ptr_reg)); 5918 match(AddP (DecodeN reg) (ConvI2L ireg)); 5919 op_cost(0); 5920 format %{ "$reg, $ireg, 0, I2L\t# narrow" %} 5921 interface(MEMORY_INTER) %{ 5922 base($reg); 5923 index($ireg); 5924 scale(0x0); 5925 disp(0x0); 5926 %} 5927 %} 5928 5929 operand indIndexN(iRegN reg, iRegL lreg) 5930 %{ 5931 predicate(CompressedOops::shift() == 0); 5932 constraint(ALLOC_IN_RC(ptr_reg)); 5933 match(AddP (DecodeN reg) lreg); 5934 op_cost(0); 5935 format %{ "$reg, $lreg\t# narrow" %} 5936 interface(MEMORY_INTER) %{ 5937 base($reg); 5938 index($lreg); 5939 scale(0x0); 5940 disp(0x0); 5941 %} 5942 %} 5943 5944 operand indOffIN(iRegN reg, immIOffset off) 5945 %{ 5946 predicate(CompressedOops::shift() == 0); 5947 constraint(ALLOC_IN_RC(ptr_reg)); 5948 match(AddP (DecodeN reg) off); 5949 op_cost(0); 5950 format %{ "[$reg, $off]\t# narrow" %} 5951 interface(MEMORY_INTER) %{ 5952 base($reg); 5953 index(0xffffffff); 5954 scale(0x0); 5955 disp($off); 5956 %} 5957 %} 5958 5959 operand indOffLN(iRegN reg, immLoffset off) 5960 %{ 5961 predicate(CompressedOops::shift() == 0); 5962 constraint(ALLOC_IN_RC(ptr_reg)); 5963 match(AddP (DecodeN reg) off); 5964 op_cost(0); 5965 format %{ "[$reg, $off]\t# narrow" %} 5966 interface(MEMORY_INTER) %{ 5967 base($reg); 5968 index(0xffffffff); 5969 scale(0x0); 5970 disp($off); 5971 %} 5972 %} 5973 5974 5975 5976 // AArch64 opto stubs need to write to the pc slot in the thread anchor 5977 operand thread_anchor_pc(thread_RegP reg, immL_pc_off off) 5978 %{ 5979 constraint(ALLOC_IN_RC(ptr_reg)); 5980 match(AddP reg off); 5981 op_cost(0); 5982 format %{ "[$reg, $off]" %} 5983 interface(MEMORY_INTER) %{ 5984 base($reg); 5985 index(0xffffffff); 5986 scale(0x0); 5987 disp($off); 5988 %} 5989 %} 5990 5991 //----------Special Memory Operands-------------------------------------------- 5992 // Stack Slot Operand - This operand is used for loading and storing temporary 5993 // values on the stack where a match requires a value to 5994 // flow through memory. 5995 operand stackSlotP(sRegP reg) 5996 %{ 5997 constraint(ALLOC_IN_RC(stack_slots)); 5998 op_cost(100); 5999 // No match rule because this operand is only generated in matching 6000 // match(RegP); 6001 format %{ "[$reg]" %} 6002 interface(MEMORY_INTER) %{ 6003 base(0x1e); // RSP 6004 index(0x0); // No Index 6005 scale(0x0); // No Scale 6006 disp($reg); // Stack Offset 6007 %} 6008 %} 6009 6010 operand stackSlotI(sRegI reg) 6011 %{ 6012 constraint(ALLOC_IN_RC(stack_slots)); 6013 // No match rule because this operand is only generated in matching 6014 // match(RegI); 6015 format %{ "[$reg]" %} 6016 interface(MEMORY_INTER) %{ 6017 base(0x1e); // RSP 6018 index(0x0); // No Index 6019 scale(0x0); // No Scale 6020 disp($reg); // Stack Offset 6021 %} 6022 %} 6023 6024 operand stackSlotF(sRegF reg) 6025 %{ 6026 constraint(ALLOC_IN_RC(stack_slots)); 6027 // No match rule because this operand is only generated in matching 6028 // match(RegF); 6029 format %{ "[$reg]" %} 6030 interface(MEMORY_INTER) %{ 6031 base(0x1e); // RSP 6032 index(0x0); // No Index 6033 scale(0x0); // No Scale 6034 disp($reg); // Stack Offset 6035 %} 6036 %} 6037 6038 operand stackSlotD(sRegD reg) 6039 %{ 6040 constraint(ALLOC_IN_RC(stack_slots)); 6041 // No match rule because this operand is only generated in matching 6042 // match(RegD); 6043 format %{ "[$reg]" %} 6044 interface(MEMORY_INTER) %{ 6045 base(0x1e); // RSP 6046 index(0x0); // No Index 6047 scale(0x0); // No Scale 6048 disp($reg); // Stack Offset 6049 %} 6050 %} 6051 6052 operand stackSlotL(sRegL reg) 6053 %{ 6054 constraint(ALLOC_IN_RC(stack_slots)); 6055 // No match rule because this operand is only generated in matching 6056 // match(RegL); 6057 format %{ "[$reg]" %} 6058 interface(MEMORY_INTER) %{ 6059 base(0x1e); // RSP 6060 index(0x0); // No Index 6061 scale(0x0); // No Scale 6062 disp($reg); // Stack Offset 6063 %} 6064 %} 6065 6066 // Operands for expressing Control Flow 6067 // NOTE: Label is a predefined operand which should not be redefined in 6068 // the AD file. It is generically handled within the ADLC. 6069 6070 //----------Conditional Branch Operands---------------------------------------- 6071 // Comparison Op - This is the operation of the comparison, and is limited to 6072 // the following set of codes: 6073 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 6074 // 6075 // Other attributes of the comparison, such as unsignedness, are specified 6076 // by the comparison instruction that sets a condition code flags register. 6077 // That result is represented by a flags operand whose subtype is appropriate 6078 // to the unsignedness (etc.) of the comparison. 6079 // 6080 // Later, the instruction which matches both the Comparison Op (a Bool) and 6081 // the flags (produced by the Cmp) specifies the coding of the comparison op 6082 // by matching a specific subtype of Bool operand below, such as cmpOpU. 6083 6084 // used for signed integral comparisons and fp comparisons 6085 6086 operand cmpOp() 6087 %{ 6088 match(Bool); 6089 6090 format %{ "" %} 6091 interface(COND_INTER) %{ 6092 equal(0x0, "eq"); 6093 not_equal(0x1, "ne"); 6094 less(0xb, "lt"); 6095 greater_equal(0xa, "ge"); 6096 less_equal(0xd, "le"); 6097 greater(0xc, "gt"); 6098 overflow(0x6, "vs"); 6099 no_overflow(0x7, "vc"); 6100 %} 6101 %} 6102 6103 // used for unsigned integral comparisons 6104 6105 operand cmpOpU() 6106 %{ 6107 match(Bool); 6108 6109 format %{ "" %} 6110 interface(COND_INTER) %{ 6111 equal(0x0, "eq"); 6112 not_equal(0x1, "ne"); 6113 less(0x3, "lo"); 6114 greater_equal(0x2, "hs"); 6115 less_equal(0x9, "ls"); 6116 greater(0x8, "hi"); 6117 overflow(0x6, "vs"); 6118 no_overflow(0x7, "vc"); 6119 %} 6120 %} 6121 6122 // used for certain integral comparisons which can be 6123 // converted to cbxx or tbxx instructions 6124 6125 operand cmpOpEqNe() 6126 %{ 6127 match(Bool); 6128 op_cost(0); 6129 predicate(n->as_Bool()->_test._test == BoolTest::ne 6130 || n->as_Bool()->_test._test == BoolTest::eq); 6131 6132 format %{ "" %} 6133 interface(COND_INTER) %{ 6134 equal(0x0, "eq"); 6135 not_equal(0x1, "ne"); 6136 less(0xb, "lt"); 6137 greater_equal(0xa, "ge"); 6138 less_equal(0xd, "le"); 6139 greater(0xc, "gt"); 6140 overflow(0x6, "vs"); 6141 no_overflow(0x7, "vc"); 6142 %} 6143 %} 6144 6145 // used for certain integral comparisons which can be 6146 // converted to cbxx or tbxx instructions 6147 6148 operand cmpOpLtGe() 6149 %{ 6150 match(Bool); 6151 op_cost(0); 6152 6153 predicate(n->as_Bool()->_test._test == BoolTest::lt 6154 || n->as_Bool()->_test._test == BoolTest::ge); 6155 6156 format %{ "" %} 6157 interface(COND_INTER) %{ 6158 equal(0x0, "eq"); 6159 not_equal(0x1, "ne"); 6160 less(0xb, "lt"); 6161 greater_equal(0xa, "ge"); 6162 less_equal(0xd, "le"); 6163 greater(0xc, "gt"); 6164 overflow(0x6, "vs"); 6165 no_overflow(0x7, "vc"); 6166 %} 6167 %} 6168 6169 // used for certain unsigned integral comparisons which can be 6170 // converted to cbxx or tbxx instructions 6171 6172 operand cmpOpUEqNeLtGe() 6173 %{ 6174 match(Bool); 6175 op_cost(0); 6176 6177 predicate(n->as_Bool()->_test._test == BoolTest::eq 6178 || n->as_Bool()->_test._test == BoolTest::ne 6179 || n->as_Bool()->_test._test == BoolTest::lt 6180 || n->as_Bool()->_test._test == BoolTest::ge); 6181 6182 format %{ "" %} 6183 interface(COND_INTER) %{ 6184 equal(0x0, "eq"); 6185 not_equal(0x1, "ne"); 6186 less(0xb, "lt"); 6187 greater_equal(0xa, "ge"); 6188 less_equal(0xd, "le"); 6189 greater(0xc, "gt"); 6190 overflow(0x6, "vs"); 6191 no_overflow(0x7, "vc"); 6192 %} 6193 %} 6194 6195 // Special operand allowing long args to int ops to be truncated for free 6196 6197 operand iRegL2I(iRegL reg) %{ 6198 6199 op_cost(0); 6200 6201 match(ConvL2I reg); 6202 6203 format %{ "l2i($reg)" %} 6204 6205 interface(REG_INTER) 6206 %} 6207 6208 opclass vmem2(indirect, indIndex, indOffI2, indOffL2); 6209 opclass vmem4(indirect, indIndex, indOffI4, indOffL4); 6210 opclass vmem8(indirect, indIndex, indOffI8, indOffL8); 6211 opclass vmem16(indirect, indIndex, indOffI16, indOffL16); 6212 6213 //----------OPERAND CLASSES---------------------------------------------------- 6214 // Operand Classes are groups of operands that are used as to simplify 6215 // instruction definitions by not requiring the AD writer to specify 6216 // separate instructions for every form of operand when the 6217 // instruction accepts multiple operand types with the same basic 6218 // encoding and format. The classic case of this is memory operands. 6219 6220 // memory is used to define read/write location for load/store 6221 // instruction defs. we can turn a memory op into an Address 6222 6223 opclass memory1(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI1, indOffL1, 6224 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 6225 6226 opclass memory2(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI2, indOffL2, 6227 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN); 6228 6229 opclass memory4(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI4, indOffL4, 6230 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6231 6232 opclass memory8(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, indOffI8, indOffL8, 6233 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6234 6235 // All of the memory operands. For the pipeline description. 6236 opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indIndex, 6237 indOffI1, indOffL1, indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, 6238 indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN); 6239 6240 6241 // iRegIorL2I is used for src inputs in rules for 32 bit int (I) 6242 // operations. it allows the src to be either an iRegI or a (ConvL2I 6243 // iRegL). in the latter case the l2i normally planted for a ConvL2I 6244 // can be elided because the 32-bit instruction will just employ the 6245 // lower 32 bits anyway. 6246 // 6247 // n.b. this does not elide all L2I conversions. if the truncated 6248 // value is consumed by more than one operation then the ConvL2I 6249 // cannot be bundled into the consuming nodes so an l2i gets planted 6250 // (actually a movw $dst $src) and the downstream instructions consume 6251 // the result of the l2i as an iRegI input. That's a shame since the 6252 // movw is actually redundant but its not too costly. 6253 6254 opclass iRegIorL2I(iRegI, iRegL2I); 6255 6256 //----------PIPELINE----------------------------------------------------------- 6257 // Rules which define the behavior of the target architectures pipeline. 6258 6259 // For specific pipelines, eg A53, define the stages of that pipeline 6260 //pipe_desc(ISS, EX1, EX2, WR); 6261 #define ISS S0 6262 #define EX1 S1 6263 #define EX2 S2 6264 #define WR S3 6265 6266 // Integer ALU reg operation 6267 pipeline %{ 6268 6269 attributes %{ 6270 // ARM instructions are of fixed length 6271 fixed_size_instructions; // Fixed size instructions TODO does 6272 max_instructions_per_bundle = 4; // A53 = 2, A57 = 4 6273 // ARM instructions come in 32-bit word units 6274 instruction_unit_size = 4; // An instruction is 4 bytes long 6275 instruction_fetch_unit_size = 64; // The processor fetches one line 6276 instruction_fetch_units = 1; // of 64 bytes 6277 6278 // List of nop instructions 6279 nops( MachNop ); 6280 %} 6281 6282 // We don't use an actual pipeline model so don't care about resources 6283 // or description. we do use pipeline classes to introduce fixed 6284 // latencies 6285 6286 //----------RESOURCES---------------------------------------------------------- 6287 // Resources are the functional units available to the machine 6288 6289 resources( INS0, INS1, INS01 = INS0 | INS1, 6290 ALU0, ALU1, ALU = ALU0 | ALU1, 6291 MAC, 6292 DIV, 6293 BRANCH, 6294 LDST, 6295 NEON_FP); 6296 6297 //----------PIPELINE DESCRIPTION----------------------------------------------- 6298 // Pipeline Description specifies the stages in the machine's pipeline 6299 6300 // Define the pipeline as a generic 6 stage pipeline 6301 pipe_desc(S0, S1, S2, S3, S4, S5); 6302 6303 //----------PIPELINE CLASSES--------------------------------------------------- 6304 // Pipeline Classes describe the stages in which input and output are 6305 // referenced by the hardware pipeline. 6306 6307 pipe_class fp_dop_reg_reg_s(vRegF dst, vRegF src1, vRegF src2) 6308 %{ 6309 single_instruction; 6310 src1 : S1(read); 6311 src2 : S2(read); 6312 dst : S5(write); 6313 INS01 : ISS; 6314 NEON_FP : S5; 6315 %} 6316 6317 pipe_class fp_dop_reg_reg_d(vRegD dst, vRegD src1, vRegD src2) 6318 %{ 6319 single_instruction; 6320 src1 : S1(read); 6321 src2 : S2(read); 6322 dst : S5(write); 6323 INS01 : ISS; 6324 NEON_FP : S5; 6325 %} 6326 6327 pipe_class fp_uop_s(vRegF dst, vRegF 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_uop_d(vRegD 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_d2f(vRegF dst, vRegD 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_f2d(vRegD 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_f2i(iRegINoSp 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_f2l(iRegLNoSp dst, vRegF 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_i2f(vRegF dst, iRegIorL2I 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_l2f(vRegF dst, iRegL 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_d2i(iRegINoSp 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_d2l(iRegLNoSp dst, vRegD 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_i2d(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_l2d(vRegD dst, iRegIorL2I src) 6427 %{ 6428 single_instruction; 6429 src : S1(read); 6430 dst : S5(write); 6431 INS01 : ISS; 6432 NEON_FP : S5; 6433 %} 6434 6435 pipe_class fp_div_s(vRegF dst, vRegF src1, vRegF src2) 6436 %{ 6437 single_instruction; 6438 src1 : S1(read); 6439 src2 : S2(read); 6440 dst : S5(write); 6441 INS0 : ISS; 6442 NEON_FP : S5; 6443 %} 6444 6445 pipe_class fp_div_d(vRegD dst, vRegD src1, vRegD src2) 6446 %{ 6447 single_instruction; 6448 src1 : S1(read); 6449 src2 : S2(read); 6450 dst : S5(write); 6451 INS0 : ISS; 6452 NEON_FP : S5; 6453 %} 6454 6455 pipe_class fp_cond_reg_reg_s(vRegF dst, vRegF src1, vRegF src2, rFlagsReg cr) 6456 %{ 6457 single_instruction; 6458 cr : S1(read); 6459 src1 : S1(read); 6460 src2 : S1(read); 6461 dst : S3(write); 6462 INS01 : ISS; 6463 NEON_FP : S3; 6464 %} 6465 6466 pipe_class fp_cond_reg_reg_d(vRegD dst, vRegD src1, vRegD src2, rFlagsReg cr) 6467 %{ 6468 single_instruction; 6469 cr : S1(read); 6470 src1 : S1(read); 6471 src2 : S1(read); 6472 dst : S3(write); 6473 INS01 : ISS; 6474 NEON_FP : S3; 6475 %} 6476 6477 pipe_class fp_imm_s(vRegF dst) 6478 %{ 6479 single_instruction; 6480 dst : S3(write); 6481 INS01 : ISS; 6482 NEON_FP : S3; 6483 %} 6484 6485 pipe_class fp_imm_d(vRegD dst) 6486 %{ 6487 single_instruction; 6488 dst : S3(write); 6489 INS01 : ISS; 6490 NEON_FP : S3; 6491 %} 6492 6493 pipe_class fp_load_constant_s(vRegF dst) 6494 %{ 6495 single_instruction; 6496 dst : S4(write); 6497 INS01 : ISS; 6498 NEON_FP : S4; 6499 %} 6500 6501 pipe_class fp_load_constant_d(vRegD dst) 6502 %{ 6503 single_instruction; 6504 dst : S4(write); 6505 INS01 : ISS; 6506 NEON_FP : S4; 6507 %} 6508 6509 //------- Integer ALU operations -------------------------- 6510 6511 // Integer ALU reg-reg operation 6512 // Operands needed in EX1, result generated in EX2 6513 // Eg. ADD x0, x1, x2 6514 pipe_class ialu_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6515 %{ 6516 single_instruction; 6517 dst : EX2(write); 6518 src1 : EX1(read); 6519 src2 : EX1(read); 6520 INS01 : ISS; // Dual issue as instruction 0 or 1 6521 ALU : EX2; 6522 %} 6523 6524 // Integer ALU reg-reg operation with constant shift 6525 // Shifted register must be available in LATE_ISS instead of EX1 6526 // Eg. ADD x0, x1, x2, LSL #2 6527 pipe_class ialu_reg_reg_shift(iRegI dst, iRegI src1, iRegI src2, immI shift) 6528 %{ 6529 single_instruction; 6530 dst : EX2(write); 6531 src1 : EX1(read); 6532 src2 : ISS(read); 6533 INS01 : ISS; 6534 ALU : EX2; 6535 %} 6536 6537 // Integer ALU reg operation with constant shift 6538 // Eg. LSL x0, x1, #shift 6539 pipe_class ialu_reg_shift(iRegI dst, iRegI src1) 6540 %{ 6541 single_instruction; 6542 dst : EX2(write); 6543 src1 : ISS(read); 6544 INS01 : ISS; 6545 ALU : EX2; 6546 %} 6547 6548 // Integer ALU reg-reg operation with variable shift 6549 // Both operands must be available in LATE_ISS instead of EX1 6550 // Result is available in EX1 instead of EX2 6551 // Eg. LSLV x0, x1, x2 6552 pipe_class ialu_reg_reg_vshift(iRegI dst, iRegI src1, iRegI src2) 6553 %{ 6554 single_instruction; 6555 dst : EX1(write); 6556 src1 : ISS(read); 6557 src2 : ISS(read); 6558 INS01 : ISS; 6559 ALU : EX1; 6560 %} 6561 6562 // Integer ALU reg-reg operation with extract 6563 // As for _vshift above, but result generated in EX2 6564 // Eg. EXTR x0, x1, x2, #N 6565 pipe_class ialu_reg_reg_extr(iRegI dst, iRegI src1, iRegI src2) 6566 %{ 6567 single_instruction; 6568 dst : EX2(write); 6569 src1 : ISS(read); 6570 src2 : ISS(read); 6571 INS1 : ISS; // Can only dual issue as Instruction 1 6572 ALU : EX1; 6573 %} 6574 6575 // Integer ALU reg operation 6576 // Eg. NEG x0, x1 6577 pipe_class ialu_reg(iRegI dst, iRegI src) 6578 %{ 6579 single_instruction; 6580 dst : EX2(write); 6581 src : EX1(read); 6582 INS01 : ISS; 6583 ALU : EX2; 6584 %} 6585 6586 // Integer ALU reg mmediate operation 6587 // Eg. ADD x0, x1, #N 6588 pipe_class ialu_reg_imm(iRegI dst, iRegI src1) 6589 %{ 6590 single_instruction; 6591 dst : EX2(write); 6592 src1 : EX1(read); 6593 INS01 : ISS; 6594 ALU : EX2; 6595 %} 6596 6597 // Integer ALU immediate operation (no source operands) 6598 // Eg. MOV x0, #N 6599 pipe_class ialu_imm(iRegI dst) 6600 %{ 6601 single_instruction; 6602 dst : EX1(write); 6603 INS01 : ISS; 6604 ALU : EX1; 6605 %} 6606 6607 //------- Compare operation ------------------------------- 6608 6609 // Compare reg-reg 6610 // Eg. CMP x0, x1 6611 pipe_class icmp_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 6612 %{ 6613 single_instruction; 6614 // fixed_latency(16); 6615 cr : EX2(write); 6616 op1 : EX1(read); 6617 op2 : EX1(read); 6618 INS01 : ISS; 6619 ALU : EX2; 6620 %} 6621 6622 // Compare reg-reg 6623 // Eg. CMP x0, #N 6624 pipe_class icmp_reg_imm(rFlagsReg cr, iRegI op1) 6625 %{ 6626 single_instruction; 6627 // fixed_latency(16); 6628 cr : EX2(write); 6629 op1 : EX1(read); 6630 INS01 : ISS; 6631 ALU : EX2; 6632 %} 6633 6634 //------- Conditional instructions ------------------------ 6635 6636 // Conditional no operands 6637 // Eg. CSINC x0, zr, zr, <cond> 6638 pipe_class icond_none(iRegI dst, rFlagsReg cr) 6639 %{ 6640 single_instruction; 6641 cr : EX1(read); 6642 dst : EX2(write); 6643 INS01 : ISS; 6644 ALU : EX2; 6645 %} 6646 6647 // Conditional 2 operand 6648 // EG. CSEL X0, X1, X2, <cond> 6649 pipe_class icond_reg_reg(iRegI dst, iRegI src1, iRegI src2, rFlagsReg cr) 6650 %{ 6651 single_instruction; 6652 cr : EX1(read); 6653 src1 : EX1(read); 6654 src2 : EX1(read); 6655 dst : EX2(write); 6656 INS01 : ISS; 6657 ALU : EX2; 6658 %} 6659 6660 // Conditional 2 operand 6661 // EG. CSEL X0, X1, X2, <cond> 6662 pipe_class icond_reg(iRegI dst, iRegI src, rFlagsReg cr) 6663 %{ 6664 single_instruction; 6665 cr : EX1(read); 6666 src : EX1(read); 6667 dst : EX2(write); 6668 INS01 : ISS; 6669 ALU : EX2; 6670 %} 6671 6672 //------- Multiply pipeline operations -------------------- 6673 6674 // Multiply reg-reg 6675 // Eg. MUL w0, w1, w2 6676 pipe_class imul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6677 %{ 6678 single_instruction; 6679 dst : WR(write); 6680 src1 : ISS(read); 6681 src2 : ISS(read); 6682 INS01 : ISS; 6683 MAC : WR; 6684 %} 6685 6686 // Multiply accumulate 6687 // Eg. MADD w0, w1, w2, w3 6688 pipe_class imac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6689 %{ 6690 single_instruction; 6691 dst : WR(write); 6692 src1 : ISS(read); 6693 src2 : ISS(read); 6694 src3 : ISS(read); 6695 INS01 : ISS; 6696 MAC : WR; 6697 %} 6698 6699 // Eg. MUL w0, w1, w2 6700 pipe_class lmul_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6701 %{ 6702 single_instruction; 6703 fixed_latency(3); // Maximum latency for 64 bit mul 6704 dst : WR(write); 6705 src1 : ISS(read); 6706 src2 : ISS(read); 6707 INS01 : ISS; 6708 MAC : WR; 6709 %} 6710 6711 // Multiply accumulate 6712 // Eg. MADD w0, w1, w2, w3 6713 pipe_class lmac_reg_reg(iRegI dst, iRegI src1, iRegI src2, iRegI src3) 6714 %{ 6715 single_instruction; 6716 fixed_latency(3); // Maximum latency for 64 bit mul 6717 dst : WR(write); 6718 src1 : ISS(read); 6719 src2 : ISS(read); 6720 src3 : ISS(read); 6721 INS01 : ISS; 6722 MAC : WR; 6723 %} 6724 6725 //------- Divide pipeline operations -------------------- 6726 6727 // Eg. SDIV w0, w1, w2 6728 pipe_class idiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6729 %{ 6730 single_instruction; 6731 fixed_latency(8); // Maximum latency for 32 bit divide 6732 dst : WR(write); 6733 src1 : ISS(read); 6734 src2 : ISS(read); 6735 INS0 : ISS; // Can only dual issue as instruction 0 6736 DIV : WR; 6737 %} 6738 6739 // Eg. SDIV x0, x1, x2 6740 pipe_class ldiv_reg_reg(iRegI dst, iRegI src1, iRegI src2) 6741 %{ 6742 single_instruction; 6743 fixed_latency(16); // Maximum latency for 64 bit divide 6744 dst : WR(write); 6745 src1 : ISS(read); 6746 src2 : ISS(read); 6747 INS0 : ISS; // Can only dual issue as instruction 0 6748 DIV : WR; 6749 %} 6750 6751 //------- Load pipeline operations ------------------------ 6752 6753 // Load - prefetch 6754 // Eg. PFRM <mem> 6755 pipe_class iload_prefetch(memory mem) 6756 %{ 6757 single_instruction; 6758 mem : ISS(read); 6759 INS01 : ISS; 6760 LDST : WR; 6761 %} 6762 6763 // Load - reg, mem 6764 // Eg. LDR x0, <mem> 6765 pipe_class iload_reg_mem(iRegI dst, memory mem) 6766 %{ 6767 single_instruction; 6768 dst : WR(write); 6769 mem : ISS(read); 6770 INS01 : ISS; 6771 LDST : WR; 6772 %} 6773 6774 // Load - reg, reg 6775 // Eg. LDR x0, [sp, x1] 6776 pipe_class iload_reg_reg(iRegI dst, iRegI src) 6777 %{ 6778 single_instruction; 6779 dst : WR(write); 6780 src : ISS(read); 6781 INS01 : ISS; 6782 LDST : WR; 6783 %} 6784 6785 //------- Store pipeline operations ----------------------- 6786 6787 // Store - zr, mem 6788 // Eg. STR zr, <mem> 6789 pipe_class istore_mem(memory mem) 6790 %{ 6791 single_instruction; 6792 mem : ISS(read); 6793 INS01 : ISS; 6794 LDST : WR; 6795 %} 6796 6797 // Store - reg, mem 6798 // Eg. STR x0, <mem> 6799 pipe_class istore_reg_mem(iRegI src, memory mem) 6800 %{ 6801 single_instruction; 6802 mem : ISS(read); 6803 src : EX2(read); 6804 INS01 : ISS; 6805 LDST : WR; 6806 %} 6807 6808 // Store - reg, reg 6809 // Eg. STR x0, [sp, x1] 6810 pipe_class istore_reg_reg(iRegI dst, iRegI src) 6811 %{ 6812 single_instruction; 6813 dst : ISS(read); 6814 src : EX2(read); 6815 INS01 : ISS; 6816 LDST : WR; 6817 %} 6818 6819 //------- Store pipeline operations ----------------------- 6820 6821 // Branch 6822 pipe_class pipe_branch() 6823 %{ 6824 single_instruction; 6825 INS01 : ISS; 6826 BRANCH : EX1; 6827 %} 6828 6829 // Conditional branch 6830 pipe_class pipe_branch_cond(rFlagsReg cr) 6831 %{ 6832 single_instruction; 6833 cr : EX1(read); 6834 INS01 : ISS; 6835 BRANCH : EX1; 6836 %} 6837 6838 // Compare & Branch 6839 // EG. CBZ/CBNZ 6840 pipe_class pipe_cmp_branch(iRegI op1) 6841 %{ 6842 single_instruction; 6843 op1 : EX1(read); 6844 INS01 : ISS; 6845 BRANCH : EX1; 6846 %} 6847 6848 //------- Synchronisation operations ---------------------- 6849 6850 // Any operation requiring serialization. 6851 // EG. DMB/Atomic Ops/Load Acquire/Str Release 6852 pipe_class pipe_serial() 6853 %{ 6854 single_instruction; 6855 force_serialization; 6856 fixed_latency(16); 6857 INS01 : ISS(2); // Cannot dual issue with any other instruction 6858 LDST : WR; 6859 %} 6860 6861 // Generic big/slow expanded idiom - also serialized 6862 pipe_class pipe_slow() 6863 %{ 6864 instruction_count(10); 6865 multiple_bundles; 6866 force_serialization; 6867 fixed_latency(16); 6868 INS01 : ISS(2); // Cannot dual issue with any other instruction 6869 LDST : WR; 6870 %} 6871 6872 // Empty pipeline class 6873 pipe_class pipe_class_empty() 6874 %{ 6875 single_instruction; 6876 fixed_latency(0); 6877 %} 6878 6879 // Default pipeline class. 6880 pipe_class pipe_class_default() 6881 %{ 6882 single_instruction; 6883 fixed_latency(2); 6884 %} 6885 6886 // Pipeline class for compares. 6887 pipe_class pipe_class_compare() 6888 %{ 6889 single_instruction; 6890 fixed_latency(16); 6891 %} 6892 6893 // Pipeline class for memory operations. 6894 pipe_class pipe_class_memory() 6895 %{ 6896 single_instruction; 6897 fixed_latency(16); 6898 %} 6899 6900 // Pipeline class for call. 6901 pipe_class pipe_class_call() 6902 %{ 6903 single_instruction; 6904 fixed_latency(100); 6905 %} 6906 6907 // Define the class for the Nop node. 6908 define %{ 6909 MachNop = pipe_class_empty; 6910 %} 6911 6912 %} 6913 //----------INSTRUCTIONS------------------------------------------------------- 6914 // 6915 // match -- States which machine-independent subtree may be replaced 6916 // by this instruction. 6917 // ins_cost -- The estimated cost of this instruction is used by instruction 6918 // selection to identify a minimum cost tree of machine 6919 // instructions that matches a tree of machine-independent 6920 // instructions. 6921 // format -- A string providing the disassembly for this instruction. 6922 // The value of an instruction's operand may be inserted 6923 // by referring to it with a '$' prefix. 6924 // opcode -- Three instruction opcodes may be provided. These are referred 6925 // to within an encode class as $primary, $secondary, and $tertiary 6926 // rrspectively. The primary opcode is commonly used to 6927 // indicate the type of machine instruction, while secondary 6928 // and tertiary are often used for prefix options or addressing 6929 // modes. 6930 // ins_encode -- A list of encode classes with parameters. The encode class 6931 // name must have been defined in an 'enc_class' specification 6932 // in the encode section of the architecture description. 6933 6934 // ============================================================================ 6935 // Memory (Load/Store) Instructions 6936 6937 // Load Instructions 6938 6939 // Load Byte (8 bit signed) 6940 instruct loadB(iRegINoSp dst, memory1 mem) 6941 %{ 6942 match(Set dst (LoadB mem)); 6943 predicate(!needs_acquiring_load(n)); 6944 6945 ins_cost(4 * INSN_COST); 6946 format %{ "ldrsbw $dst, $mem\t# byte" %} 6947 6948 ins_encode(aarch64_enc_ldrsbw(dst, mem)); 6949 6950 ins_pipe(iload_reg_mem); 6951 %} 6952 6953 // Load Byte (8 bit signed) into long 6954 instruct loadB2L(iRegLNoSp dst, memory1 mem) 6955 %{ 6956 match(Set dst (ConvI2L (LoadB mem))); 6957 predicate(!needs_acquiring_load(n->in(1))); 6958 6959 ins_cost(4 * INSN_COST); 6960 format %{ "ldrsb $dst, $mem\t# byte" %} 6961 6962 ins_encode(aarch64_enc_ldrsb(dst, mem)); 6963 6964 ins_pipe(iload_reg_mem); 6965 %} 6966 6967 // Load Byte (8 bit unsigned) 6968 instruct loadUB(iRegINoSp dst, memory1 mem) 6969 %{ 6970 match(Set dst (LoadUB mem)); 6971 predicate(!needs_acquiring_load(n)); 6972 6973 ins_cost(4 * INSN_COST); 6974 format %{ "ldrbw $dst, $mem\t# byte" %} 6975 6976 ins_encode(aarch64_enc_ldrb(dst, mem)); 6977 6978 ins_pipe(iload_reg_mem); 6979 %} 6980 6981 // Load Byte (8 bit unsigned) into long 6982 instruct loadUB2L(iRegLNoSp dst, memory1 mem) 6983 %{ 6984 match(Set dst (ConvI2L (LoadUB mem))); 6985 predicate(!needs_acquiring_load(n->in(1))); 6986 6987 ins_cost(4 * INSN_COST); 6988 format %{ "ldrb $dst, $mem\t# byte" %} 6989 6990 ins_encode(aarch64_enc_ldrb(dst, mem)); 6991 6992 ins_pipe(iload_reg_mem); 6993 %} 6994 6995 // Load Short (16 bit signed) 6996 instruct loadS(iRegINoSp dst, memory2 mem) 6997 %{ 6998 match(Set dst (LoadS mem)); 6999 predicate(!needs_acquiring_load(n)); 7000 7001 ins_cost(4 * INSN_COST); 7002 format %{ "ldrshw $dst, $mem\t# short" %} 7003 7004 ins_encode(aarch64_enc_ldrshw(dst, mem)); 7005 7006 ins_pipe(iload_reg_mem); 7007 %} 7008 7009 // Load Short (16 bit signed) into long 7010 instruct loadS2L(iRegLNoSp dst, memory2 mem) 7011 %{ 7012 match(Set dst (ConvI2L (LoadS mem))); 7013 predicate(!needs_acquiring_load(n->in(1))); 7014 7015 ins_cost(4 * INSN_COST); 7016 format %{ "ldrsh $dst, $mem\t# short" %} 7017 7018 ins_encode(aarch64_enc_ldrsh(dst, mem)); 7019 7020 ins_pipe(iload_reg_mem); 7021 %} 7022 7023 // Load Char (16 bit unsigned) 7024 instruct loadUS(iRegINoSp dst, memory2 mem) 7025 %{ 7026 match(Set dst (LoadUS mem)); 7027 predicate(!needs_acquiring_load(n)); 7028 7029 ins_cost(4 * INSN_COST); 7030 format %{ "ldrh $dst, $mem\t# short" %} 7031 7032 ins_encode(aarch64_enc_ldrh(dst, mem)); 7033 7034 ins_pipe(iload_reg_mem); 7035 %} 7036 7037 // Load Short/Char (16 bit unsigned) into long 7038 instruct loadUS2L(iRegLNoSp dst, memory2 mem) 7039 %{ 7040 match(Set dst (ConvI2L (LoadUS mem))); 7041 predicate(!needs_acquiring_load(n->in(1))); 7042 7043 ins_cost(4 * INSN_COST); 7044 format %{ "ldrh $dst, $mem\t# short" %} 7045 7046 ins_encode(aarch64_enc_ldrh(dst, mem)); 7047 7048 ins_pipe(iload_reg_mem); 7049 %} 7050 7051 // Load Integer (32 bit signed) 7052 instruct loadI(iRegINoSp dst, memory4 mem) 7053 %{ 7054 match(Set dst (LoadI mem)); 7055 predicate(!needs_acquiring_load(n)); 7056 7057 ins_cost(4 * INSN_COST); 7058 format %{ "ldrw $dst, $mem\t# int" %} 7059 7060 ins_encode(aarch64_enc_ldrw(dst, mem)); 7061 7062 ins_pipe(iload_reg_mem); 7063 %} 7064 7065 // Load Integer (32 bit signed) into long 7066 instruct loadI2L(iRegLNoSp dst, memory4 mem) 7067 %{ 7068 match(Set dst (ConvI2L (LoadI mem))); 7069 predicate(!needs_acquiring_load(n->in(1))); 7070 7071 ins_cost(4 * INSN_COST); 7072 format %{ "ldrsw $dst, $mem\t# int" %} 7073 7074 ins_encode(aarch64_enc_ldrsw(dst, mem)); 7075 7076 ins_pipe(iload_reg_mem); 7077 %} 7078 7079 // Load Integer (32 bit unsigned) into long 7080 instruct loadUI2L(iRegLNoSp dst, memory4 mem, immL_32bits mask) 7081 %{ 7082 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7083 predicate(!needs_acquiring_load(n->in(1)->in(1)->as_Load())); 7084 7085 ins_cost(4 * INSN_COST); 7086 format %{ "ldrw $dst, $mem\t# int" %} 7087 7088 ins_encode(aarch64_enc_ldrw(dst, mem)); 7089 7090 ins_pipe(iload_reg_mem); 7091 %} 7092 7093 // Load Long (64 bit signed) 7094 instruct loadL(iRegLNoSp dst, memory8 mem) 7095 %{ 7096 match(Set dst (LoadL mem)); 7097 predicate(!needs_acquiring_load(n)); 7098 7099 ins_cost(4 * INSN_COST); 7100 format %{ "ldr $dst, $mem\t# int" %} 7101 7102 ins_encode(aarch64_enc_ldr(dst, mem)); 7103 7104 ins_pipe(iload_reg_mem); 7105 %} 7106 7107 // Load Range 7108 instruct loadRange(iRegINoSp dst, memory4 mem) 7109 %{ 7110 match(Set dst (LoadRange mem)); 7111 7112 ins_cost(4 * INSN_COST); 7113 format %{ "ldrw $dst, $mem\t# range" %} 7114 7115 ins_encode(aarch64_enc_ldrw(dst, mem)); 7116 7117 ins_pipe(iload_reg_mem); 7118 %} 7119 7120 // Load Pointer 7121 instruct loadP(iRegPNoSp dst, memory8 mem) 7122 %{ 7123 match(Set dst (LoadP mem)); 7124 predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0)); 7125 7126 ins_cost(4 * INSN_COST); 7127 format %{ "ldr $dst, $mem\t# ptr" %} 7128 7129 ins_encode(aarch64_enc_ldr(dst, mem)); 7130 7131 ins_pipe(iload_reg_mem); 7132 %} 7133 7134 // Load Compressed Pointer 7135 instruct loadN(iRegNNoSp dst, memory4 mem) 7136 %{ 7137 match(Set dst (LoadN mem)); 7138 predicate(!needs_acquiring_load(n)); 7139 7140 ins_cost(4 * INSN_COST); 7141 format %{ "ldrw $dst, $mem\t# compressed ptr" %} 7142 7143 ins_encode(aarch64_enc_ldrw(dst, mem)); 7144 7145 ins_pipe(iload_reg_mem); 7146 %} 7147 7148 // Load Klass Pointer 7149 instruct loadKlass(iRegPNoSp dst, memory8 mem) 7150 %{ 7151 match(Set dst (LoadKlass mem)); 7152 predicate(!needs_acquiring_load(n)); 7153 7154 ins_cost(4 * INSN_COST); 7155 format %{ "ldr $dst, $mem\t# class" %} 7156 7157 ins_encode(aarch64_enc_ldr(dst, mem)); 7158 7159 ins_pipe(iload_reg_mem); 7160 %} 7161 7162 // Load Narrow Klass Pointer 7163 instruct loadNKlass(iRegNNoSp dst, memory4 mem) 7164 %{ 7165 match(Set dst (LoadNKlass mem)); 7166 predicate(!needs_acquiring_load(n)); 7167 7168 ins_cost(4 * INSN_COST); 7169 format %{ "ldrw $dst, $mem\t# compressed class ptr" %} 7170 7171 ins_encode(aarch64_enc_ldrw(dst, mem)); 7172 7173 ins_pipe(iload_reg_mem); 7174 %} 7175 7176 // Load Float 7177 instruct loadF(vRegF dst, memory4 mem) 7178 %{ 7179 match(Set dst (LoadF mem)); 7180 predicate(!needs_acquiring_load(n)); 7181 7182 ins_cost(4 * INSN_COST); 7183 format %{ "ldrs $dst, $mem\t# float" %} 7184 7185 ins_encode( aarch64_enc_ldrs(dst, mem) ); 7186 7187 ins_pipe(pipe_class_memory); 7188 %} 7189 7190 // Load Double 7191 instruct loadD(vRegD dst, memory8 mem) 7192 %{ 7193 match(Set dst (LoadD mem)); 7194 predicate(!needs_acquiring_load(n)); 7195 7196 ins_cost(4 * INSN_COST); 7197 format %{ "ldrd $dst, $mem\t# double" %} 7198 7199 ins_encode( aarch64_enc_ldrd(dst, mem) ); 7200 7201 ins_pipe(pipe_class_memory); 7202 %} 7203 7204 7205 // Load Int Constant 7206 instruct loadConI(iRegINoSp dst, immI src) 7207 %{ 7208 match(Set dst src); 7209 7210 ins_cost(INSN_COST); 7211 format %{ "mov $dst, $src\t# int" %} 7212 7213 ins_encode( aarch64_enc_movw_imm(dst, src) ); 7214 7215 ins_pipe(ialu_imm); 7216 %} 7217 7218 // Load Long Constant 7219 instruct loadConL(iRegLNoSp dst, immL src) 7220 %{ 7221 match(Set dst src); 7222 7223 ins_cost(INSN_COST); 7224 format %{ "mov $dst, $src\t# long" %} 7225 7226 ins_encode( aarch64_enc_mov_imm(dst, src) ); 7227 7228 ins_pipe(ialu_imm); 7229 %} 7230 7231 // Load Pointer Constant 7232 7233 instruct loadConP(iRegPNoSp dst, immP con) 7234 %{ 7235 match(Set dst con); 7236 7237 ins_cost(INSN_COST * 4); 7238 format %{ 7239 "mov $dst, $con\t# ptr" 7240 %} 7241 7242 ins_encode(aarch64_enc_mov_p(dst, con)); 7243 7244 ins_pipe(ialu_imm); 7245 %} 7246 7247 // Load Null Pointer Constant 7248 7249 instruct loadConP0(iRegPNoSp dst, immP0 con) 7250 %{ 7251 match(Set dst con); 7252 7253 ins_cost(INSN_COST); 7254 format %{ "mov $dst, $con\t# nullptr ptr" %} 7255 7256 ins_encode(aarch64_enc_mov_p0(dst, con)); 7257 7258 ins_pipe(ialu_imm); 7259 %} 7260 7261 // Load Pointer Constant One 7262 7263 instruct loadConP1(iRegPNoSp dst, immP_1 con) 7264 %{ 7265 match(Set dst con); 7266 7267 ins_cost(INSN_COST); 7268 format %{ "mov $dst, $con\t# nullptr ptr" %} 7269 7270 ins_encode(aarch64_enc_mov_p1(dst, con)); 7271 7272 ins_pipe(ialu_imm); 7273 %} 7274 7275 // Load Byte Map Base Constant 7276 7277 instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) 7278 %{ 7279 match(Set dst con); 7280 7281 ins_cost(INSN_COST); 7282 format %{ "adr $dst, $con\t# Byte Map Base" %} 7283 7284 ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); 7285 7286 ins_pipe(ialu_imm); 7287 %} 7288 7289 // Load Narrow Pointer Constant 7290 7291 instruct loadConN(iRegNNoSp dst, immN con) 7292 %{ 7293 match(Set dst con); 7294 7295 ins_cost(INSN_COST * 4); 7296 format %{ "mov $dst, $con\t# compressed ptr" %} 7297 7298 ins_encode(aarch64_enc_mov_n(dst, con)); 7299 7300 ins_pipe(ialu_imm); 7301 %} 7302 7303 // Load Narrow Null Pointer Constant 7304 7305 instruct loadConN0(iRegNNoSp dst, immN0 con) 7306 %{ 7307 match(Set dst con); 7308 7309 ins_cost(INSN_COST); 7310 format %{ "mov $dst, $con\t# compressed nullptr ptr" %} 7311 7312 ins_encode(aarch64_enc_mov_n0(dst, con)); 7313 7314 ins_pipe(ialu_imm); 7315 %} 7316 7317 // Load Narrow Klass Constant 7318 7319 instruct loadConNKlass(iRegNNoSp dst, immNKlass con) 7320 %{ 7321 match(Set dst con); 7322 7323 ins_cost(INSN_COST); 7324 format %{ "mov $dst, $con\t# compressed klass ptr" %} 7325 7326 ins_encode(aarch64_enc_mov_nk(dst, con)); 7327 7328 ins_pipe(ialu_imm); 7329 %} 7330 7331 // Load Packed Float Constant 7332 7333 instruct loadConF_packed(vRegF dst, immFPacked con) %{ 7334 match(Set dst con); 7335 ins_cost(INSN_COST * 4); 7336 format %{ "fmovs $dst, $con"%} 7337 ins_encode %{ 7338 __ fmovs(as_FloatRegister($dst$$reg), (double)$con$$constant); 7339 %} 7340 7341 ins_pipe(fp_imm_s); 7342 %} 7343 7344 // Load Float Constant 7345 7346 instruct loadConF(vRegF dst, immF con) %{ 7347 match(Set dst con); 7348 7349 ins_cost(INSN_COST * 4); 7350 7351 format %{ 7352 "ldrs $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7353 %} 7354 7355 ins_encode %{ 7356 __ ldrs(as_FloatRegister($dst$$reg), $constantaddress($con)); 7357 %} 7358 7359 ins_pipe(fp_load_constant_s); 7360 %} 7361 7362 // Load Packed Double Constant 7363 7364 instruct loadConD_packed(vRegD dst, immDPacked con) %{ 7365 match(Set dst con); 7366 ins_cost(INSN_COST); 7367 format %{ "fmovd $dst, $con"%} 7368 ins_encode %{ 7369 __ fmovd(as_FloatRegister($dst$$reg), $con$$constant); 7370 %} 7371 7372 ins_pipe(fp_imm_d); 7373 %} 7374 7375 // Load Double Constant 7376 7377 instruct loadConD(vRegD dst, immD con) %{ 7378 match(Set dst con); 7379 7380 ins_cost(INSN_COST * 5); 7381 format %{ 7382 "ldrd $dst, [$constantaddress]\t# load from constant table: float=$con\n\t" 7383 %} 7384 7385 ins_encode %{ 7386 __ ldrd(as_FloatRegister($dst$$reg), $constantaddress($con)); 7387 %} 7388 7389 ins_pipe(fp_load_constant_d); 7390 %} 7391 7392 // Store Instructions 7393 7394 // Store CMS card-mark Immediate 7395 instruct storeimmCM0(immI0 zero, memory1 mem) 7396 %{ 7397 match(Set mem (StoreCM mem zero)); 7398 7399 ins_cost(INSN_COST); 7400 format %{ "storestore (elided)\n\t" 7401 "strb zr, $mem\t# byte" %} 7402 7403 ins_encode(aarch64_enc_strb0(mem)); 7404 7405 ins_pipe(istore_mem); 7406 %} 7407 7408 // Store CMS card-mark Immediate with intervening StoreStore 7409 // needed when using CMS with no conditional card marking 7410 instruct storeimmCM0_ordered(immI0 zero, memory1 mem) 7411 %{ 7412 match(Set mem (StoreCM mem zero)); 7413 7414 ins_cost(INSN_COST * 2); 7415 format %{ "storestore\n\t" 7416 "dmb ishst" 7417 "\n\tstrb zr, $mem\t# byte" %} 7418 7419 ins_encode(aarch64_enc_strb0_ordered(mem)); 7420 7421 ins_pipe(istore_mem); 7422 %} 7423 7424 // Store Byte 7425 instruct storeB(iRegIorL2I src, memory1 mem) 7426 %{ 7427 match(Set mem (StoreB mem src)); 7428 predicate(!needs_releasing_store(n)); 7429 7430 ins_cost(INSN_COST); 7431 format %{ "strb $src, $mem\t# byte" %} 7432 7433 ins_encode(aarch64_enc_strb(src, mem)); 7434 7435 ins_pipe(istore_reg_mem); 7436 %} 7437 7438 7439 instruct storeimmB0(immI0 zero, memory1 mem) 7440 %{ 7441 match(Set mem (StoreB mem zero)); 7442 predicate(!needs_releasing_store(n)); 7443 7444 ins_cost(INSN_COST); 7445 format %{ "strb rscractch2, $mem\t# byte" %} 7446 7447 ins_encode(aarch64_enc_strb0(mem)); 7448 7449 ins_pipe(istore_mem); 7450 %} 7451 7452 // Store Char/Short 7453 instruct storeC(iRegIorL2I src, memory2 mem) 7454 %{ 7455 match(Set mem (StoreC mem src)); 7456 predicate(!needs_releasing_store(n)); 7457 7458 ins_cost(INSN_COST); 7459 format %{ "strh $src, $mem\t# short" %} 7460 7461 ins_encode(aarch64_enc_strh(src, mem)); 7462 7463 ins_pipe(istore_reg_mem); 7464 %} 7465 7466 instruct storeimmC0(immI0 zero, memory2 mem) 7467 %{ 7468 match(Set mem (StoreC mem zero)); 7469 predicate(!needs_releasing_store(n)); 7470 7471 ins_cost(INSN_COST); 7472 format %{ "strh zr, $mem\t# short" %} 7473 7474 ins_encode(aarch64_enc_strh0(mem)); 7475 7476 ins_pipe(istore_mem); 7477 %} 7478 7479 // Store Integer 7480 7481 instruct storeI(iRegIorL2I src, memory4 mem) 7482 %{ 7483 match(Set mem(StoreI mem src)); 7484 predicate(!needs_releasing_store(n)); 7485 7486 ins_cost(INSN_COST); 7487 format %{ "strw $src, $mem\t# int" %} 7488 7489 ins_encode(aarch64_enc_strw(src, mem)); 7490 7491 ins_pipe(istore_reg_mem); 7492 %} 7493 7494 instruct storeimmI0(immI0 zero, memory4 mem) 7495 %{ 7496 match(Set mem(StoreI mem zero)); 7497 predicate(!needs_releasing_store(n)); 7498 7499 ins_cost(INSN_COST); 7500 format %{ "strw zr, $mem\t# int" %} 7501 7502 ins_encode(aarch64_enc_strw0(mem)); 7503 7504 ins_pipe(istore_mem); 7505 %} 7506 7507 // Store Long (64 bit signed) 7508 instruct storeL(iRegL src, memory8 mem) 7509 %{ 7510 match(Set mem (StoreL mem src)); 7511 predicate(!needs_releasing_store(n)); 7512 7513 ins_cost(INSN_COST); 7514 format %{ "str $src, $mem\t# int" %} 7515 7516 ins_encode(aarch64_enc_str(src, mem)); 7517 7518 ins_pipe(istore_reg_mem); 7519 %} 7520 7521 // Store Long (64 bit signed) 7522 instruct storeimmL0(immL0 zero, memory8 mem) 7523 %{ 7524 match(Set mem (StoreL mem zero)); 7525 predicate(!needs_releasing_store(n)); 7526 7527 ins_cost(INSN_COST); 7528 format %{ "str zr, $mem\t# int" %} 7529 7530 ins_encode(aarch64_enc_str0(mem)); 7531 7532 ins_pipe(istore_mem); 7533 %} 7534 7535 // Store Pointer 7536 instruct storeP(iRegP src, memory8 mem) 7537 %{ 7538 match(Set mem (StoreP mem src)); 7539 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0); 7540 7541 ins_cost(INSN_COST); 7542 format %{ "str $src, $mem\t# ptr" %} 7543 7544 ins_encode(aarch64_enc_str(src, mem)); 7545 7546 ins_pipe(istore_reg_mem); 7547 %} 7548 7549 // Store Pointer 7550 instruct storeimmP0(immP0 zero, memory8 mem) 7551 %{ 7552 match(Set mem (StoreP mem zero)); 7553 predicate(!needs_releasing_store(n) && n->as_Store()->barrier_data() == 0); 7554 7555 ins_cost(INSN_COST); 7556 format %{ "str zr, $mem\t# ptr" %} 7557 7558 ins_encode(aarch64_enc_str0(mem)); 7559 7560 ins_pipe(istore_mem); 7561 %} 7562 7563 // Store Compressed Pointer 7564 instruct storeN(iRegN src, memory4 mem) 7565 %{ 7566 match(Set mem (StoreN mem src)); 7567 predicate(!needs_releasing_store(n)); 7568 7569 ins_cost(INSN_COST); 7570 format %{ "strw $src, $mem\t# compressed ptr" %} 7571 7572 ins_encode(aarch64_enc_strw(src, mem)); 7573 7574 ins_pipe(istore_reg_mem); 7575 %} 7576 7577 instruct storeImmN0(immN0 zero, memory4 mem) 7578 %{ 7579 match(Set mem (StoreN mem zero)); 7580 predicate(!needs_releasing_store(n)); 7581 7582 ins_cost(INSN_COST); 7583 format %{ "strw zr, $mem\t# compressed ptr" %} 7584 7585 ins_encode(aarch64_enc_strw0(mem)); 7586 7587 ins_pipe(istore_mem); 7588 %} 7589 7590 // Store Float 7591 instruct storeF(vRegF src, memory4 mem) 7592 %{ 7593 match(Set mem (StoreF mem src)); 7594 predicate(!needs_releasing_store(n)); 7595 7596 ins_cost(INSN_COST); 7597 format %{ "strs $src, $mem\t# float" %} 7598 7599 ins_encode( aarch64_enc_strs(src, mem) ); 7600 7601 ins_pipe(pipe_class_memory); 7602 %} 7603 7604 // TODO 7605 // implement storeImmF0 and storeFImmPacked 7606 7607 // Store Double 7608 instruct storeD(vRegD src, memory8 mem) 7609 %{ 7610 match(Set mem (StoreD mem src)); 7611 predicate(!needs_releasing_store(n)); 7612 7613 ins_cost(INSN_COST); 7614 format %{ "strd $src, $mem\t# double" %} 7615 7616 ins_encode( aarch64_enc_strd(src, mem) ); 7617 7618 ins_pipe(pipe_class_memory); 7619 %} 7620 7621 // Store Compressed Klass Pointer 7622 instruct storeNKlass(iRegN src, memory4 mem) 7623 %{ 7624 predicate(!needs_releasing_store(n)); 7625 match(Set mem (StoreNKlass mem src)); 7626 7627 ins_cost(INSN_COST); 7628 format %{ "strw $src, $mem\t# compressed klass ptr" %} 7629 7630 ins_encode(aarch64_enc_strw(src, mem)); 7631 7632 ins_pipe(istore_reg_mem); 7633 %} 7634 7635 // TODO 7636 // implement storeImmD0 and storeDImmPacked 7637 7638 // prefetch instructions 7639 // Must be safe to execute with invalid address (cannot fault). 7640 7641 instruct prefetchalloc( memory8 mem ) %{ 7642 match(PrefetchAllocation mem); 7643 7644 ins_cost(INSN_COST); 7645 format %{ "prfm $mem, PSTL1KEEP\t# Prefetch into level 1 cache write keep" %} 7646 7647 ins_encode( aarch64_enc_prefetchw(mem) ); 7648 7649 ins_pipe(iload_prefetch); 7650 %} 7651 7652 // ---------------- volatile loads and stores ---------------- 7653 7654 // Load Byte (8 bit signed) 7655 instruct loadB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7656 %{ 7657 match(Set dst (LoadB mem)); 7658 7659 ins_cost(VOLATILE_REF_COST); 7660 format %{ "ldarsb $dst, $mem\t# byte" %} 7661 7662 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7663 7664 ins_pipe(pipe_serial); 7665 %} 7666 7667 // Load Byte (8 bit signed) into long 7668 instruct loadB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7669 %{ 7670 match(Set dst (ConvI2L (LoadB mem))); 7671 7672 ins_cost(VOLATILE_REF_COST); 7673 format %{ "ldarsb $dst, $mem\t# byte" %} 7674 7675 ins_encode(aarch64_enc_ldarsb(dst, mem)); 7676 7677 ins_pipe(pipe_serial); 7678 %} 7679 7680 // Load Byte (8 bit unsigned) 7681 instruct loadUB_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7682 %{ 7683 match(Set dst (LoadUB mem)); 7684 7685 ins_cost(VOLATILE_REF_COST); 7686 format %{ "ldarb $dst, $mem\t# byte" %} 7687 7688 ins_encode(aarch64_enc_ldarb(dst, mem)); 7689 7690 ins_pipe(pipe_serial); 7691 %} 7692 7693 // Load Byte (8 bit unsigned) into long 7694 instruct loadUB2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7695 %{ 7696 match(Set dst (ConvI2L (LoadUB mem))); 7697 7698 ins_cost(VOLATILE_REF_COST); 7699 format %{ "ldarb $dst, $mem\t# byte" %} 7700 7701 ins_encode(aarch64_enc_ldarb(dst, mem)); 7702 7703 ins_pipe(pipe_serial); 7704 %} 7705 7706 // Load Short (16 bit signed) 7707 instruct loadS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7708 %{ 7709 match(Set dst (LoadS mem)); 7710 7711 ins_cost(VOLATILE_REF_COST); 7712 format %{ "ldarshw $dst, $mem\t# short" %} 7713 7714 ins_encode(aarch64_enc_ldarshw(dst, mem)); 7715 7716 ins_pipe(pipe_serial); 7717 %} 7718 7719 instruct loadUS_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7720 %{ 7721 match(Set dst (LoadUS mem)); 7722 7723 ins_cost(VOLATILE_REF_COST); 7724 format %{ "ldarhw $dst, $mem\t# short" %} 7725 7726 ins_encode(aarch64_enc_ldarhw(dst, mem)); 7727 7728 ins_pipe(pipe_serial); 7729 %} 7730 7731 // Load Short/Char (16 bit unsigned) into long 7732 instruct loadUS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7733 %{ 7734 match(Set dst (ConvI2L (LoadUS mem))); 7735 7736 ins_cost(VOLATILE_REF_COST); 7737 format %{ "ldarh $dst, $mem\t# short" %} 7738 7739 ins_encode(aarch64_enc_ldarh(dst, mem)); 7740 7741 ins_pipe(pipe_serial); 7742 %} 7743 7744 // Load Short/Char (16 bit signed) into long 7745 instruct loadS2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7746 %{ 7747 match(Set dst (ConvI2L (LoadS mem))); 7748 7749 ins_cost(VOLATILE_REF_COST); 7750 format %{ "ldarh $dst, $mem\t# short" %} 7751 7752 ins_encode(aarch64_enc_ldarsh(dst, mem)); 7753 7754 ins_pipe(pipe_serial); 7755 %} 7756 7757 // Load Integer (32 bit signed) 7758 instruct loadI_volatile(iRegINoSp dst, /* sync_memory*/indirect mem) 7759 %{ 7760 match(Set dst (LoadI mem)); 7761 7762 ins_cost(VOLATILE_REF_COST); 7763 format %{ "ldarw $dst, $mem\t# int" %} 7764 7765 ins_encode(aarch64_enc_ldarw(dst, mem)); 7766 7767 ins_pipe(pipe_serial); 7768 %} 7769 7770 // Load Integer (32 bit unsigned) into long 7771 instruct loadUI2L_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem, immL_32bits mask) 7772 %{ 7773 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 7774 7775 ins_cost(VOLATILE_REF_COST); 7776 format %{ "ldarw $dst, $mem\t# int" %} 7777 7778 ins_encode(aarch64_enc_ldarw(dst, mem)); 7779 7780 ins_pipe(pipe_serial); 7781 %} 7782 7783 // Load Long (64 bit signed) 7784 instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem) 7785 %{ 7786 match(Set dst (LoadL mem)); 7787 7788 ins_cost(VOLATILE_REF_COST); 7789 format %{ "ldar $dst, $mem\t# int" %} 7790 7791 ins_encode(aarch64_enc_ldar(dst, mem)); 7792 7793 ins_pipe(pipe_serial); 7794 %} 7795 7796 // Load Pointer 7797 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem) 7798 %{ 7799 match(Set dst (LoadP mem)); 7800 predicate(n->as_Load()->barrier_data() == 0); 7801 7802 ins_cost(VOLATILE_REF_COST); 7803 format %{ "ldar $dst, $mem\t# ptr" %} 7804 7805 ins_encode(aarch64_enc_ldar(dst, mem)); 7806 7807 ins_pipe(pipe_serial); 7808 %} 7809 7810 // Load Compressed Pointer 7811 instruct loadN_volatile(iRegNNoSp dst, /* sync_memory*/indirect mem) 7812 %{ 7813 match(Set dst (LoadN mem)); 7814 7815 ins_cost(VOLATILE_REF_COST); 7816 format %{ "ldarw $dst, $mem\t# compressed ptr" %} 7817 7818 ins_encode(aarch64_enc_ldarw(dst, mem)); 7819 7820 ins_pipe(pipe_serial); 7821 %} 7822 7823 // Load Float 7824 instruct loadF_volatile(vRegF dst, /* sync_memory*/indirect mem) 7825 %{ 7826 match(Set dst (LoadF mem)); 7827 7828 ins_cost(VOLATILE_REF_COST); 7829 format %{ "ldars $dst, $mem\t# float" %} 7830 7831 ins_encode( aarch64_enc_fldars(dst, mem) ); 7832 7833 ins_pipe(pipe_serial); 7834 %} 7835 7836 // Load Double 7837 instruct loadD_volatile(vRegD dst, /* sync_memory*/indirect mem) 7838 %{ 7839 match(Set dst (LoadD mem)); 7840 7841 ins_cost(VOLATILE_REF_COST); 7842 format %{ "ldard $dst, $mem\t# double" %} 7843 7844 ins_encode( aarch64_enc_fldard(dst, mem) ); 7845 7846 ins_pipe(pipe_serial); 7847 %} 7848 7849 // Store Byte 7850 instruct storeB_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7851 %{ 7852 match(Set mem (StoreB mem src)); 7853 7854 ins_cost(VOLATILE_REF_COST); 7855 format %{ "stlrb $src, $mem\t# byte" %} 7856 7857 ins_encode(aarch64_enc_stlrb(src, mem)); 7858 7859 ins_pipe(pipe_class_memory); 7860 %} 7861 7862 instruct storeimmB0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7863 %{ 7864 match(Set mem (StoreB mem zero)); 7865 7866 ins_cost(VOLATILE_REF_COST); 7867 format %{ "stlrb zr, $mem\t# byte" %} 7868 7869 ins_encode(aarch64_enc_stlrb0(mem)); 7870 7871 ins_pipe(pipe_class_memory); 7872 %} 7873 7874 // Store Char/Short 7875 instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7876 %{ 7877 match(Set mem (StoreC mem src)); 7878 7879 ins_cost(VOLATILE_REF_COST); 7880 format %{ "stlrh $src, $mem\t# short" %} 7881 7882 ins_encode(aarch64_enc_stlrh(src, mem)); 7883 7884 ins_pipe(pipe_class_memory); 7885 %} 7886 7887 instruct storeimmC0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7888 %{ 7889 match(Set mem (StoreC mem zero)); 7890 7891 ins_cost(VOLATILE_REF_COST); 7892 format %{ "stlrh zr, $mem\t# short" %} 7893 7894 ins_encode(aarch64_enc_stlrh0(mem)); 7895 7896 ins_pipe(pipe_class_memory); 7897 %} 7898 7899 // Store Integer 7900 7901 instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) 7902 %{ 7903 match(Set mem(StoreI mem src)); 7904 7905 ins_cost(VOLATILE_REF_COST); 7906 format %{ "stlrw $src, $mem\t# int" %} 7907 7908 ins_encode(aarch64_enc_stlrw(src, mem)); 7909 7910 ins_pipe(pipe_class_memory); 7911 %} 7912 7913 instruct storeimmI0_volatile(immI0 zero, /* sync_memory*/indirect mem) 7914 %{ 7915 match(Set mem(StoreI mem zero)); 7916 7917 ins_cost(VOLATILE_REF_COST); 7918 format %{ "stlrw zr, $mem\t# int" %} 7919 7920 ins_encode(aarch64_enc_stlrw0(mem)); 7921 7922 ins_pipe(pipe_class_memory); 7923 %} 7924 7925 // Store Long (64 bit signed) 7926 instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) 7927 %{ 7928 match(Set mem (StoreL mem src)); 7929 7930 ins_cost(VOLATILE_REF_COST); 7931 format %{ "stlr $src, $mem\t# int" %} 7932 7933 ins_encode(aarch64_enc_stlr(src, mem)); 7934 7935 ins_pipe(pipe_class_memory); 7936 %} 7937 7938 instruct storeimmL0_volatile(immL0 zero, /* sync_memory*/indirect mem) 7939 %{ 7940 match(Set mem (StoreL mem zero)); 7941 7942 ins_cost(VOLATILE_REF_COST); 7943 format %{ "stlr zr, $mem\t# int" %} 7944 7945 ins_encode(aarch64_enc_stlr0(mem)); 7946 7947 ins_pipe(pipe_class_memory); 7948 %} 7949 7950 // Store Pointer 7951 instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) 7952 %{ 7953 match(Set mem (StoreP mem src)); 7954 predicate(n->as_Store()->barrier_data() == 0); 7955 7956 ins_cost(VOLATILE_REF_COST); 7957 format %{ "stlr $src, $mem\t# ptr" %} 7958 7959 ins_encode(aarch64_enc_stlr(src, mem)); 7960 7961 ins_pipe(pipe_class_memory); 7962 %} 7963 7964 instruct storeimmP0_volatile(immP0 zero, /* sync_memory*/indirect mem) 7965 %{ 7966 match(Set mem (StoreP mem zero)); 7967 predicate(n->as_Store()->barrier_data() == 0); 7968 7969 ins_cost(VOLATILE_REF_COST); 7970 format %{ "stlr zr, $mem\t# ptr" %} 7971 7972 ins_encode(aarch64_enc_stlr0(mem)); 7973 7974 ins_pipe(pipe_class_memory); 7975 %} 7976 7977 // Store Compressed Pointer 7978 instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) 7979 %{ 7980 match(Set mem (StoreN mem src)); 7981 7982 ins_cost(VOLATILE_REF_COST); 7983 format %{ "stlrw $src, $mem\t# compressed ptr" %} 7984 7985 ins_encode(aarch64_enc_stlrw(src, mem)); 7986 7987 ins_pipe(pipe_class_memory); 7988 %} 7989 7990 instruct storeimmN0_volatile(immN0 zero, /* sync_memory*/indirect mem) 7991 %{ 7992 match(Set mem (StoreN mem zero)); 7993 7994 ins_cost(VOLATILE_REF_COST); 7995 format %{ "stlrw zr, $mem\t# compressed ptr" %} 7996 7997 ins_encode(aarch64_enc_stlrw0(mem)); 7998 7999 ins_pipe(pipe_class_memory); 8000 %} 8001 8002 // Store Float 8003 instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) 8004 %{ 8005 match(Set mem (StoreF mem src)); 8006 8007 ins_cost(VOLATILE_REF_COST); 8008 format %{ "stlrs $src, $mem\t# float" %} 8009 8010 ins_encode( aarch64_enc_fstlrs(src, mem) ); 8011 8012 ins_pipe(pipe_class_memory); 8013 %} 8014 8015 // TODO 8016 // implement storeImmF0 and storeFImmPacked 8017 8018 // Store Double 8019 instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem) 8020 %{ 8021 match(Set mem (StoreD mem src)); 8022 8023 ins_cost(VOLATILE_REF_COST); 8024 format %{ "stlrd $src, $mem\t# double" %} 8025 8026 ins_encode( aarch64_enc_fstlrd(src, mem) ); 8027 8028 ins_pipe(pipe_class_memory); 8029 %} 8030 8031 // ---------------- end of volatile loads and stores ---------------- 8032 8033 instruct cacheWB(indirect addr) 8034 %{ 8035 predicate(VM_Version::supports_data_cache_line_flush()); 8036 match(CacheWB addr); 8037 8038 ins_cost(100); 8039 format %{"cache wb $addr" %} 8040 ins_encode %{ 8041 assert($addr->index_position() < 0, "should be"); 8042 assert($addr$$disp == 0, "should be"); 8043 __ cache_wb(Address($addr$$base$$Register, 0)); 8044 %} 8045 ins_pipe(pipe_slow); // XXX 8046 %} 8047 8048 instruct cacheWBPreSync() 8049 %{ 8050 predicate(VM_Version::supports_data_cache_line_flush()); 8051 match(CacheWBPreSync); 8052 8053 ins_cost(100); 8054 format %{"cache wb presync" %} 8055 ins_encode %{ 8056 __ cache_wbsync(true); 8057 %} 8058 ins_pipe(pipe_slow); // XXX 8059 %} 8060 8061 instruct cacheWBPostSync() 8062 %{ 8063 predicate(VM_Version::supports_data_cache_line_flush()); 8064 match(CacheWBPostSync); 8065 8066 ins_cost(100); 8067 format %{"cache wb postsync" %} 8068 ins_encode %{ 8069 __ cache_wbsync(false); 8070 %} 8071 ins_pipe(pipe_slow); // XXX 8072 %} 8073 8074 // ============================================================================ 8075 // BSWAP Instructions 8076 8077 instruct bytes_reverse_int(iRegINoSp dst, iRegIorL2I src) %{ 8078 match(Set dst (ReverseBytesI src)); 8079 8080 ins_cost(INSN_COST); 8081 format %{ "revw $dst, $src" %} 8082 8083 ins_encode %{ 8084 __ revw(as_Register($dst$$reg), as_Register($src$$reg)); 8085 %} 8086 8087 ins_pipe(ialu_reg); 8088 %} 8089 8090 instruct bytes_reverse_long(iRegLNoSp dst, iRegL src) %{ 8091 match(Set dst (ReverseBytesL src)); 8092 8093 ins_cost(INSN_COST); 8094 format %{ "rev $dst, $src" %} 8095 8096 ins_encode %{ 8097 __ rev(as_Register($dst$$reg), as_Register($src$$reg)); 8098 %} 8099 8100 ins_pipe(ialu_reg); 8101 %} 8102 8103 instruct bytes_reverse_unsigned_short(iRegINoSp dst, iRegIorL2I src) %{ 8104 match(Set dst (ReverseBytesUS src)); 8105 8106 ins_cost(INSN_COST); 8107 format %{ "rev16w $dst, $src" %} 8108 8109 ins_encode %{ 8110 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 8111 %} 8112 8113 ins_pipe(ialu_reg); 8114 %} 8115 8116 instruct bytes_reverse_short(iRegINoSp dst, iRegIorL2I src) %{ 8117 match(Set dst (ReverseBytesS src)); 8118 8119 ins_cost(INSN_COST); 8120 format %{ "rev16w $dst, $src\n\t" 8121 "sbfmw $dst, $dst, #0, #15" %} 8122 8123 ins_encode %{ 8124 __ rev16w(as_Register($dst$$reg), as_Register($src$$reg)); 8125 __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); 8126 %} 8127 8128 ins_pipe(ialu_reg); 8129 %} 8130 8131 // ============================================================================ 8132 // Zero Count Instructions 8133 8134 instruct countLeadingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8135 match(Set dst (CountLeadingZerosI src)); 8136 8137 ins_cost(INSN_COST); 8138 format %{ "clzw $dst, $src" %} 8139 ins_encode %{ 8140 __ clzw(as_Register($dst$$reg), as_Register($src$$reg)); 8141 %} 8142 8143 ins_pipe(ialu_reg); 8144 %} 8145 8146 instruct countLeadingZerosL(iRegINoSp dst, iRegL src) %{ 8147 match(Set dst (CountLeadingZerosL src)); 8148 8149 ins_cost(INSN_COST); 8150 format %{ "clz $dst, $src" %} 8151 ins_encode %{ 8152 __ clz(as_Register($dst$$reg), as_Register($src$$reg)); 8153 %} 8154 8155 ins_pipe(ialu_reg); 8156 %} 8157 8158 instruct countTrailingZerosI(iRegINoSp dst, iRegIorL2I src) %{ 8159 match(Set dst (CountTrailingZerosI src)); 8160 8161 ins_cost(INSN_COST * 2); 8162 format %{ "rbitw $dst, $src\n\t" 8163 "clzw $dst, $dst" %} 8164 ins_encode %{ 8165 __ rbitw(as_Register($dst$$reg), as_Register($src$$reg)); 8166 __ clzw(as_Register($dst$$reg), as_Register($dst$$reg)); 8167 %} 8168 8169 ins_pipe(ialu_reg); 8170 %} 8171 8172 instruct countTrailingZerosL(iRegINoSp dst, iRegL src) %{ 8173 match(Set dst (CountTrailingZerosL src)); 8174 8175 ins_cost(INSN_COST * 2); 8176 format %{ "rbit $dst, $src\n\t" 8177 "clz $dst, $dst" %} 8178 ins_encode %{ 8179 __ rbit(as_Register($dst$$reg), as_Register($src$$reg)); 8180 __ clz(as_Register($dst$$reg), as_Register($dst$$reg)); 8181 %} 8182 8183 ins_pipe(ialu_reg); 8184 %} 8185 8186 //---------- Population Count Instructions ------------------------------------- 8187 // 8188 8189 instruct popCountI(iRegINoSp dst, iRegIorL2I src, vRegF tmp) %{ 8190 match(Set dst (PopCountI src)); 8191 effect(TEMP tmp); 8192 ins_cost(INSN_COST * 13); 8193 8194 format %{ "movw $src, $src\n\t" 8195 "mov $tmp, $src\t# vector (1D)\n\t" 8196 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8197 "addv $tmp, $tmp\t# vector (8B)\n\t" 8198 "mov $dst, $tmp\t# vector (1D)" %} 8199 ins_encode %{ 8200 __ movw($src$$Register, $src$$Register); // ensure top 32 bits 0 8201 __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); 8202 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8203 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8204 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8205 %} 8206 8207 ins_pipe(pipe_class_default); 8208 %} 8209 8210 instruct popCountI_mem(iRegINoSp dst, memory4 mem, vRegF tmp) %{ 8211 match(Set dst (PopCountI (LoadI mem))); 8212 effect(TEMP tmp); 8213 ins_cost(INSN_COST * 13); 8214 8215 format %{ "ldrs $tmp, $mem\n\t" 8216 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8217 "addv $tmp, $tmp\t# vector (8B)\n\t" 8218 "mov $dst, $tmp\t# vector (1D)" %} 8219 ins_encode %{ 8220 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8221 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, tmp_reg, $mem->opcode(), 8222 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 8223 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8224 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8225 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8226 %} 8227 8228 ins_pipe(pipe_class_default); 8229 %} 8230 8231 // Note: Long.bitCount(long) returns an int. 8232 instruct popCountL(iRegINoSp dst, iRegL src, vRegD tmp) %{ 8233 match(Set dst (PopCountL src)); 8234 effect(TEMP tmp); 8235 ins_cost(INSN_COST * 13); 8236 8237 format %{ "mov $tmp, $src\t# vector (1D)\n\t" 8238 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8239 "addv $tmp, $tmp\t# vector (8B)\n\t" 8240 "mov $dst, $tmp\t# vector (1D)" %} 8241 ins_encode %{ 8242 __ mov($tmp$$FloatRegister, __ D, 0, $src$$Register); 8243 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8244 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8245 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8246 %} 8247 8248 ins_pipe(pipe_class_default); 8249 %} 8250 8251 instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{ 8252 match(Set dst (PopCountL (LoadL mem))); 8253 effect(TEMP tmp); 8254 ins_cost(INSN_COST * 13); 8255 8256 format %{ "ldrd $tmp, $mem\n\t" 8257 "cnt $tmp, $tmp\t# vector (8B)\n\t" 8258 "addv $tmp, $tmp\t# vector (8B)\n\t" 8259 "mov $dst, $tmp\t# vector (1D)" %} 8260 ins_encode %{ 8261 FloatRegister tmp_reg = as_FloatRegister($tmp$$reg); 8262 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, tmp_reg, $mem->opcode(), 8263 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 8264 __ cnt($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8265 __ addv($tmp$$FloatRegister, __ T8B, $tmp$$FloatRegister); 8266 __ mov($dst$$Register, $tmp$$FloatRegister, __ D, 0); 8267 %} 8268 8269 ins_pipe(pipe_class_default); 8270 %} 8271 8272 // ============================================================================ 8273 // MemBar Instruction 8274 8275 instruct load_fence() %{ 8276 match(LoadFence); 8277 ins_cost(VOLATILE_REF_COST); 8278 8279 format %{ "load_fence" %} 8280 8281 ins_encode %{ 8282 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8283 %} 8284 ins_pipe(pipe_serial); 8285 %} 8286 8287 instruct unnecessary_membar_acquire() %{ 8288 predicate(unnecessary_acquire(n)); 8289 match(MemBarAcquire); 8290 ins_cost(0); 8291 8292 format %{ "membar_acquire (elided)" %} 8293 8294 ins_encode %{ 8295 __ block_comment("membar_acquire (elided)"); 8296 %} 8297 8298 ins_pipe(pipe_class_empty); 8299 %} 8300 8301 instruct membar_acquire() %{ 8302 match(MemBarAcquire); 8303 ins_cost(VOLATILE_REF_COST); 8304 8305 format %{ "membar_acquire\n\t" 8306 "dmb ish" %} 8307 8308 ins_encode %{ 8309 __ block_comment("membar_acquire"); 8310 __ membar(Assembler::LoadLoad|Assembler::LoadStore); 8311 %} 8312 8313 ins_pipe(pipe_serial); 8314 %} 8315 8316 8317 instruct membar_acquire_lock() %{ 8318 match(MemBarAcquireLock); 8319 ins_cost(VOLATILE_REF_COST); 8320 8321 format %{ "membar_acquire_lock (elided)" %} 8322 8323 ins_encode %{ 8324 __ block_comment("membar_acquire_lock (elided)"); 8325 %} 8326 8327 ins_pipe(pipe_serial); 8328 %} 8329 8330 instruct store_fence() %{ 8331 match(StoreFence); 8332 ins_cost(VOLATILE_REF_COST); 8333 8334 format %{ "store_fence" %} 8335 8336 ins_encode %{ 8337 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8338 %} 8339 ins_pipe(pipe_serial); 8340 %} 8341 8342 instruct unnecessary_membar_release() %{ 8343 predicate(unnecessary_release(n)); 8344 match(MemBarRelease); 8345 ins_cost(0); 8346 8347 format %{ "membar_release (elided)" %} 8348 8349 ins_encode %{ 8350 __ block_comment("membar_release (elided)"); 8351 %} 8352 ins_pipe(pipe_serial); 8353 %} 8354 8355 instruct membar_release() %{ 8356 match(MemBarRelease); 8357 ins_cost(VOLATILE_REF_COST); 8358 8359 format %{ "membar_release\n\t" 8360 "dmb ish" %} 8361 8362 ins_encode %{ 8363 __ block_comment("membar_release"); 8364 __ membar(Assembler::LoadStore|Assembler::StoreStore); 8365 %} 8366 ins_pipe(pipe_serial); 8367 %} 8368 8369 instruct membar_storestore() %{ 8370 match(MemBarStoreStore); 8371 match(StoreStoreFence); 8372 ins_cost(VOLATILE_REF_COST); 8373 8374 format %{ "MEMBAR-store-store" %} 8375 8376 ins_encode %{ 8377 __ membar(Assembler::StoreStore); 8378 %} 8379 ins_pipe(pipe_serial); 8380 %} 8381 8382 instruct membar_release_lock() %{ 8383 match(MemBarReleaseLock); 8384 ins_cost(VOLATILE_REF_COST); 8385 8386 format %{ "membar_release_lock (elided)" %} 8387 8388 ins_encode %{ 8389 __ block_comment("membar_release_lock (elided)"); 8390 %} 8391 8392 ins_pipe(pipe_serial); 8393 %} 8394 8395 instruct unnecessary_membar_volatile() %{ 8396 predicate(unnecessary_volatile(n)); 8397 match(MemBarVolatile); 8398 ins_cost(0); 8399 8400 format %{ "membar_volatile (elided)" %} 8401 8402 ins_encode %{ 8403 __ block_comment("membar_volatile (elided)"); 8404 %} 8405 8406 ins_pipe(pipe_serial); 8407 %} 8408 8409 instruct membar_volatile() %{ 8410 match(MemBarVolatile); 8411 ins_cost(VOLATILE_REF_COST*100); 8412 8413 format %{ "membar_volatile\n\t" 8414 "dmb ish"%} 8415 8416 ins_encode %{ 8417 __ block_comment("membar_volatile"); 8418 __ membar(Assembler::StoreLoad); 8419 %} 8420 8421 ins_pipe(pipe_serial); 8422 %} 8423 8424 // ============================================================================ 8425 // Cast/Convert Instructions 8426 8427 instruct castX2P(iRegPNoSp dst, iRegL src) %{ 8428 match(Set dst (CastX2P src)); 8429 8430 ins_cost(INSN_COST); 8431 format %{ "mov $dst, $src\t# long -> ptr" %} 8432 8433 ins_encode %{ 8434 if ($dst$$reg != $src$$reg) { 8435 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8436 } 8437 %} 8438 8439 ins_pipe(ialu_reg); 8440 %} 8441 8442 instruct castN2X(iRegLNoSp dst, iRegN src) %{ 8443 match(Set dst (CastP2X src)); 8444 8445 ins_cost(INSN_COST); 8446 format %{ "mov $dst, $src\t# ptr -> long" %} 8447 8448 ins_encode %{ 8449 if ($dst$$reg != $src$$reg) { 8450 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8451 } 8452 %} 8453 8454 ins_pipe(ialu_reg); 8455 %} 8456 8457 instruct castP2X(iRegLNoSp dst, iRegP src) %{ 8458 match(Set dst (CastP2X src)); 8459 8460 ins_cost(INSN_COST); 8461 format %{ "mov $dst, $src\t# ptr -> long" %} 8462 8463 ins_encode %{ 8464 if ($dst$$reg != $src$$reg) { 8465 __ mov(as_Register($dst$$reg), as_Register($src$$reg)); 8466 } 8467 %} 8468 8469 ins_pipe(ialu_reg); 8470 %} 8471 8472 // Convert oop into int for vectors alignment masking 8473 instruct convP2I(iRegINoSp dst, iRegP src) %{ 8474 match(Set dst (ConvL2I (CastP2X src))); 8475 8476 ins_cost(INSN_COST); 8477 format %{ "movw $dst, $src\t# ptr -> int" %} 8478 ins_encode %{ 8479 __ movw($dst$$Register, $src$$Register); 8480 %} 8481 8482 ins_pipe(ialu_reg); 8483 %} 8484 8485 // Convert compressed oop into int for vectors alignment masking 8486 // in case of 32bit oops (heap < 4Gb). 8487 instruct convN2I(iRegINoSp dst, iRegN src) 8488 %{ 8489 predicate(CompressedOops::shift() == 0); 8490 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 8491 8492 ins_cost(INSN_COST); 8493 format %{ "mov dst, $src\t# compressed ptr -> int" %} 8494 ins_encode %{ 8495 __ movw($dst$$Register, $src$$Register); 8496 %} 8497 8498 ins_pipe(ialu_reg); 8499 %} 8500 8501 8502 // Convert oop pointer into compressed form 8503 instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8504 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 8505 match(Set dst (EncodeP src)); 8506 effect(KILL cr); 8507 ins_cost(INSN_COST * 3); 8508 format %{ "encode_heap_oop $dst, $src" %} 8509 ins_encode %{ 8510 Register s = $src$$Register; 8511 Register d = $dst$$Register; 8512 __ encode_heap_oop(d, s); 8513 %} 8514 ins_pipe(ialu_reg); 8515 %} 8516 8517 instruct encodeHeapOop_not_null(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ 8518 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 8519 match(Set dst (EncodeP src)); 8520 ins_cost(INSN_COST * 3); 8521 format %{ "encode_heap_oop_not_null $dst, $src" %} 8522 ins_encode %{ 8523 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 8524 %} 8525 ins_pipe(ialu_reg); 8526 %} 8527 8528 instruct decodeHeapOop(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8529 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 8530 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 8531 match(Set dst (DecodeN src)); 8532 ins_cost(INSN_COST * 3); 8533 format %{ "decode_heap_oop $dst, $src" %} 8534 ins_encode %{ 8535 Register s = $src$$Register; 8536 Register d = $dst$$Register; 8537 __ decode_heap_oop(d, s); 8538 %} 8539 ins_pipe(ialu_reg); 8540 %} 8541 8542 instruct decodeHeapOop_not_null(iRegPNoSp dst, iRegN src, rFlagsReg cr) %{ 8543 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 8544 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 8545 match(Set dst (DecodeN src)); 8546 ins_cost(INSN_COST * 3); 8547 format %{ "decode_heap_oop_not_null $dst, $src" %} 8548 ins_encode %{ 8549 Register s = $src$$Register; 8550 Register d = $dst$$Register; 8551 __ decode_heap_oop_not_null(d, s); 8552 %} 8553 ins_pipe(ialu_reg); 8554 %} 8555 8556 // n.b. AArch64 implementations of encode_klass_not_null and 8557 // decode_klass_not_null do not modify the flags register so, unlike 8558 // Intel, we don't kill CR as a side effect here 8559 8560 instruct encodeKlass_not_null(iRegNNoSp dst, iRegP src) %{ 8561 match(Set dst (EncodePKlass src)); 8562 8563 ins_cost(INSN_COST * 3); 8564 format %{ "encode_klass_not_null $dst,$src" %} 8565 8566 ins_encode %{ 8567 Register src_reg = as_Register($src$$reg); 8568 Register dst_reg = as_Register($dst$$reg); 8569 __ encode_klass_not_null(dst_reg, src_reg); 8570 %} 8571 8572 ins_pipe(ialu_reg); 8573 %} 8574 8575 instruct decodeKlass_not_null(iRegPNoSp dst, iRegN src) %{ 8576 match(Set dst (DecodeNKlass src)); 8577 8578 ins_cost(INSN_COST * 3); 8579 format %{ "decode_klass_not_null $dst,$src" %} 8580 8581 ins_encode %{ 8582 Register src_reg = as_Register($src$$reg); 8583 Register dst_reg = as_Register($dst$$reg); 8584 if (dst_reg != src_reg) { 8585 __ decode_klass_not_null(dst_reg, src_reg); 8586 } else { 8587 __ decode_klass_not_null(dst_reg); 8588 } 8589 %} 8590 8591 ins_pipe(ialu_reg); 8592 %} 8593 8594 instruct checkCastPP(iRegPNoSp dst) 8595 %{ 8596 match(Set dst (CheckCastPP dst)); 8597 8598 size(0); 8599 format %{ "# checkcastPP of $dst" %} 8600 ins_encode(/* empty encoding */); 8601 ins_pipe(pipe_class_empty); 8602 %} 8603 8604 instruct castPP(iRegPNoSp dst) 8605 %{ 8606 match(Set dst (CastPP dst)); 8607 8608 size(0); 8609 format %{ "# castPP of $dst" %} 8610 ins_encode(/* empty encoding */); 8611 ins_pipe(pipe_class_empty); 8612 %} 8613 8614 instruct castII(iRegI dst) 8615 %{ 8616 match(Set dst (CastII dst)); 8617 8618 size(0); 8619 format %{ "# castII of $dst" %} 8620 ins_encode(/* empty encoding */); 8621 ins_cost(0); 8622 ins_pipe(pipe_class_empty); 8623 %} 8624 8625 instruct castLL(iRegL dst) 8626 %{ 8627 match(Set dst (CastLL dst)); 8628 8629 size(0); 8630 format %{ "# castLL of $dst" %} 8631 ins_encode(/* empty encoding */); 8632 ins_cost(0); 8633 ins_pipe(pipe_class_empty); 8634 %} 8635 8636 instruct castFF(vRegF dst) 8637 %{ 8638 match(Set dst (CastFF dst)); 8639 8640 size(0); 8641 format %{ "# castFF of $dst" %} 8642 ins_encode(/* empty encoding */); 8643 ins_cost(0); 8644 ins_pipe(pipe_class_empty); 8645 %} 8646 8647 instruct castDD(vRegD dst) 8648 %{ 8649 match(Set dst (CastDD dst)); 8650 8651 size(0); 8652 format %{ "# castDD of $dst" %} 8653 ins_encode(/* empty encoding */); 8654 ins_cost(0); 8655 ins_pipe(pipe_class_empty); 8656 %} 8657 8658 instruct castVV(vReg dst) 8659 %{ 8660 match(Set dst (CastVV dst)); 8661 8662 size(0); 8663 format %{ "# castVV of $dst" %} 8664 ins_encode(/* empty encoding */); 8665 ins_cost(0); 8666 ins_pipe(pipe_class_empty); 8667 %} 8668 8669 instruct castVVMask(pRegGov dst) 8670 %{ 8671 match(Set dst (CastVV dst)); 8672 8673 size(0); 8674 format %{ "# castVV of $dst" %} 8675 ins_encode(/* empty encoding */); 8676 ins_cost(0); 8677 ins_pipe(pipe_class_empty); 8678 %} 8679 8680 // ============================================================================ 8681 // Atomic operation instructions 8682 // 8683 8684 // standard CompareAndSwapX when we are using barriers 8685 // these have higher priority than the rules selected by a predicate 8686 8687 // XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher 8688 // can't match them 8689 8690 instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8691 8692 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8693 ins_cost(2 * VOLATILE_REF_COST); 8694 8695 effect(KILL cr); 8696 8697 format %{ 8698 "cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8699 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8700 %} 8701 8702 ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval), 8703 aarch64_enc_cset_eq(res)); 8704 8705 ins_pipe(pipe_slow); 8706 %} 8707 8708 instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8709 8710 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8711 ins_cost(2 * VOLATILE_REF_COST); 8712 8713 effect(KILL cr); 8714 8715 format %{ 8716 "cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8717 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8718 %} 8719 8720 ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval), 8721 aarch64_enc_cset_eq(res)); 8722 8723 ins_pipe(pipe_slow); 8724 %} 8725 8726 instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8727 8728 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8729 ins_cost(2 * VOLATILE_REF_COST); 8730 8731 effect(KILL cr); 8732 8733 format %{ 8734 "cmpxchgw $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8735 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8736 %} 8737 8738 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8739 aarch64_enc_cset_eq(res)); 8740 8741 ins_pipe(pipe_slow); 8742 %} 8743 8744 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8745 8746 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8747 ins_cost(2 * VOLATILE_REF_COST); 8748 8749 effect(KILL cr); 8750 8751 format %{ 8752 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8753 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8754 %} 8755 8756 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8757 aarch64_enc_cset_eq(res)); 8758 8759 ins_pipe(pipe_slow); 8760 %} 8761 8762 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8763 8764 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8765 predicate(n->as_LoadStore()->barrier_data() == 0); 8766 ins_cost(2 * VOLATILE_REF_COST); 8767 8768 effect(KILL cr); 8769 8770 format %{ 8771 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8772 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8773 %} 8774 8775 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval), 8776 aarch64_enc_cset_eq(res)); 8777 8778 ins_pipe(pipe_slow); 8779 %} 8780 8781 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8782 8783 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8784 ins_cost(2 * VOLATILE_REF_COST); 8785 8786 effect(KILL cr); 8787 8788 format %{ 8789 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8790 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8791 %} 8792 8793 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval), 8794 aarch64_enc_cset_eq(res)); 8795 8796 ins_pipe(pipe_slow); 8797 %} 8798 8799 // alternative CompareAndSwapX when we are eliding barriers 8800 8801 instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8802 8803 predicate(needs_acquiring_load_exclusive(n)); 8804 match(Set res (CompareAndSwapB mem (Binary oldval newval))); 8805 ins_cost(VOLATILE_REF_COST); 8806 8807 effect(KILL cr); 8808 8809 format %{ 8810 "cmpxchgb_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8811 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8812 %} 8813 8814 ins_encode(aarch64_enc_cmpxchgb_acq(mem, oldval, newval), 8815 aarch64_enc_cset_eq(res)); 8816 8817 ins_pipe(pipe_slow); 8818 %} 8819 8820 instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8821 8822 predicate(needs_acquiring_load_exclusive(n)); 8823 match(Set res (CompareAndSwapS mem (Binary oldval newval))); 8824 ins_cost(VOLATILE_REF_COST); 8825 8826 effect(KILL cr); 8827 8828 format %{ 8829 "cmpxchgs_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8830 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8831 %} 8832 8833 ins_encode(aarch64_enc_cmpxchgs_acq(mem, oldval, newval), 8834 aarch64_enc_cset_eq(res)); 8835 8836 ins_pipe(pipe_slow); 8837 %} 8838 8839 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ 8840 8841 predicate(needs_acquiring_load_exclusive(n)); 8842 match(Set res (CompareAndSwapI mem (Binary oldval newval))); 8843 ins_cost(VOLATILE_REF_COST); 8844 8845 effect(KILL cr); 8846 8847 format %{ 8848 "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval" 8849 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8850 %} 8851 8852 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8853 aarch64_enc_cset_eq(res)); 8854 8855 ins_pipe(pipe_slow); 8856 %} 8857 8858 instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ 8859 8860 predicate(needs_acquiring_load_exclusive(n)); 8861 match(Set res (CompareAndSwapL mem (Binary oldval newval))); 8862 ins_cost(VOLATILE_REF_COST); 8863 8864 effect(KILL cr); 8865 8866 format %{ 8867 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval" 8868 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8869 %} 8870 8871 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8872 aarch64_enc_cset_eq(res)); 8873 8874 ins_pipe(pipe_slow); 8875 %} 8876 8877 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 8878 8879 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 8880 match(Set res (CompareAndSwapP mem (Binary oldval newval))); 8881 ins_cost(VOLATILE_REF_COST); 8882 8883 effect(KILL cr); 8884 8885 format %{ 8886 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval" 8887 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8888 %} 8889 8890 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval), 8891 aarch64_enc_cset_eq(res)); 8892 8893 ins_pipe(pipe_slow); 8894 %} 8895 8896 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ 8897 8898 predicate(needs_acquiring_load_exclusive(n)); 8899 match(Set res (CompareAndSwapN mem (Binary oldval newval))); 8900 ins_cost(VOLATILE_REF_COST); 8901 8902 effect(KILL cr); 8903 8904 format %{ 8905 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval" 8906 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" 8907 %} 8908 8909 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval), 8910 aarch64_enc_cset_eq(res)); 8911 8912 ins_pipe(pipe_slow); 8913 %} 8914 8915 8916 // --------------------------------------------------------------------- 8917 8918 // BEGIN This section of the file is automatically generated. Do not edit -------------- 8919 8920 // Sundry CAS operations. Note that release is always true, 8921 // regardless of the memory ordering of the CAS. This is because we 8922 // need the volatile case to be sequentially consistent but there is 8923 // no trailing StoreLoad barrier emitted by C2. Unfortunately we 8924 // can't check the type of memory ordering here, so we always emit a 8925 // STLXR. 8926 8927 // This section is generated from cas.m4 8928 8929 8930 // This pattern is generated automatically from cas.m4. 8931 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8932 instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8933 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 8934 ins_cost(2 * VOLATILE_REF_COST); 8935 effect(TEMP_DEF res, KILL cr); 8936 format %{ 8937 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 8938 %} 8939 ins_encode %{ 8940 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8941 Assembler::byte, /*acquire*/ false, /*release*/ true, 8942 /*weak*/ false, $res$$Register); 8943 __ sxtbw($res$$Register, $res$$Register); 8944 %} 8945 ins_pipe(pipe_slow); 8946 %} 8947 8948 // This pattern is generated automatically from cas.m4. 8949 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8950 instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8951 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 8952 ins_cost(2 * VOLATILE_REF_COST); 8953 effect(TEMP_DEF res, KILL cr); 8954 format %{ 8955 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 8956 %} 8957 ins_encode %{ 8958 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8959 Assembler::halfword, /*acquire*/ false, /*release*/ true, 8960 /*weak*/ false, $res$$Register); 8961 __ sxthw($res$$Register, $res$$Register); 8962 %} 8963 ins_pipe(pipe_slow); 8964 %} 8965 8966 // This pattern is generated automatically from cas.m4. 8967 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8968 instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 8969 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 8970 ins_cost(2 * VOLATILE_REF_COST); 8971 effect(TEMP_DEF res, KILL cr); 8972 format %{ 8973 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 8974 %} 8975 ins_encode %{ 8976 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8977 Assembler::word, /*acquire*/ false, /*release*/ true, 8978 /*weak*/ false, $res$$Register); 8979 %} 8980 ins_pipe(pipe_slow); 8981 %} 8982 8983 // This pattern is generated automatically from cas.m4. 8984 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 8985 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 8986 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 8987 ins_cost(2 * VOLATILE_REF_COST); 8988 effect(TEMP_DEF res, KILL cr); 8989 format %{ 8990 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 8991 %} 8992 ins_encode %{ 8993 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 8994 Assembler::xword, /*acquire*/ false, /*release*/ true, 8995 /*weak*/ false, $res$$Register); 8996 %} 8997 ins_pipe(pipe_slow); 8998 %} 8999 9000 // This pattern is generated automatically from cas.m4. 9001 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9002 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9003 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 9004 ins_cost(2 * VOLATILE_REF_COST); 9005 effect(TEMP_DEF res, KILL cr); 9006 format %{ 9007 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9008 %} 9009 ins_encode %{ 9010 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9011 Assembler::word, /*acquire*/ false, /*release*/ true, 9012 /*weak*/ false, $res$$Register); 9013 %} 9014 ins_pipe(pipe_slow); 9015 %} 9016 9017 // This pattern is generated automatically from cas.m4. 9018 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9019 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9020 predicate(n->as_LoadStore()->barrier_data() == 0); 9021 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 9022 ins_cost(2 * VOLATILE_REF_COST); 9023 effect(TEMP_DEF res, KILL cr); 9024 format %{ 9025 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9026 %} 9027 ins_encode %{ 9028 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9029 Assembler::xword, /*acquire*/ false, /*release*/ true, 9030 /*weak*/ false, $res$$Register); 9031 %} 9032 ins_pipe(pipe_slow); 9033 %} 9034 9035 // This pattern is generated automatically from cas.m4. 9036 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9037 instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9038 predicate(needs_acquiring_load_exclusive(n)); 9039 match(Set res (CompareAndExchangeB mem (Binary oldval newval))); 9040 ins_cost(VOLATILE_REF_COST); 9041 effect(TEMP_DEF res, KILL cr); 9042 format %{ 9043 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9044 %} 9045 ins_encode %{ 9046 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9047 Assembler::byte, /*acquire*/ true, /*release*/ true, 9048 /*weak*/ false, $res$$Register); 9049 __ sxtbw($res$$Register, $res$$Register); 9050 %} 9051 ins_pipe(pipe_slow); 9052 %} 9053 9054 // This pattern is generated automatically from cas.m4. 9055 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9056 instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9057 predicate(needs_acquiring_load_exclusive(n)); 9058 match(Set res (CompareAndExchangeS mem (Binary oldval newval))); 9059 ins_cost(VOLATILE_REF_COST); 9060 effect(TEMP_DEF res, KILL cr); 9061 format %{ 9062 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9063 %} 9064 ins_encode %{ 9065 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9066 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9067 /*weak*/ false, $res$$Register); 9068 __ sxthw($res$$Register, $res$$Register); 9069 %} 9070 ins_pipe(pipe_slow); 9071 %} 9072 9073 // This pattern is generated automatically from cas.m4. 9074 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9075 instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9076 predicate(needs_acquiring_load_exclusive(n)); 9077 match(Set res (CompareAndExchangeI mem (Binary oldval newval))); 9078 ins_cost(VOLATILE_REF_COST); 9079 effect(TEMP_DEF res, KILL cr); 9080 format %{ 9081 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9082 %} 9083 ins_encode %{ 9084 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9085 Assembler::word, /*acquire*/ true, /*release*/ true, 9086 /*weak*/ false, $res$$Register); 9087 %} 9088 ins_pipe(pipe_slow); 9089 %} 9090 9091 // This pattern is generated automatically from cas.m4. 9092 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9093 instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9094 predicate(needs_acquiring_load_exclusive(n)); 9095 match(Set res (CompareAndExchangeL mem (Binary oldval newval))); 9096 ins_cost(VOLATILE_REF_COST); 9097 effect(TEMP_DEF res, KILL cr); 9098 format %{ 9099 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9100 %} 9101 ins_encode %{ 9102 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9103 Assembler::xword, /*acquire*/ true, /*release*/ true, 9104 /*weak*/ false, $res$$Register); 9105 %} 9106 ins_pipe(pipe_slow); 9107 %} 9108 9109 // This pattern is generated automatically from cas.m4. 9110 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9111 instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9112 predicate(needs_acquiring_load_exclusive(n)); 9113 match(Set res (CompareAndExchangeN mem (Binary oldval newval))); 9114 ins_cost(VOLATILE_REF_COST); 9115 effect(TEMP_DEF res, KILL cr); 9116 format %{ 9117 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9118 %} 9119 ins_encode %{ 9120 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9121 Assembler::word, /*acquire*/ true, /*release*/ true, 9122 /*weak*/ false, $res$$Register); 9123 %} 9124 ins_pipe(pipe_slow); 9125 %} 9126 9127 // This pattern is generated automatically from cas.m4. 9128 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9129 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9130 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9131 match(Set res (CompareAndExchangeP mem (Binary oldval newval))); 9132 ins_cost(VOLATILE_REF_COST); 9133 effect(TEMP_DEF res, KILL cr); 9134 format %{ 9135 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9136 %} 9137 ins_encode %{ 9138 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9139 Assembler::xword, /*acquire*/ true, /*release*/ true, 9140 /*weak*/ false, $res$$Register); 9141 %} 9142 ins_pipe(pipe_slow); 9143 %} 9144 9145 // This pattern is generated automatically from cas.m4. 9146 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9147 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9148 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9149 ins_cost(2 * VOLATILE_REF_COST); 9150 effect(KILL cr); 9151 format %{ 9152 "cmpxchgb $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9153 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9154 %} 9155 ins_encode %{ 9156 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9157 Assembler::byte, /*acquire*/ false, /*release*/ true, 9158 /*weak*/ true, noreg); 9159 __ csetw($res$$Register, Assembler::EQ); 9160 %} 9161 ins_pipe(pipe_slow); 9162 %} 9163 9164 // This pattern is generated automatically from cas.m4. 9165 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9166 instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9167 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9168 ins_cost(2 * VOLATILE_REF_COST); 9169 effect(KILL cr); 9170 format %{ 9171 "cmpxchgs $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9172 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9173 %} 9174 ins_encode %{ 9175 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9176 Assembler::halfword, /*acquire*/ false, /*release*/ true, 9177 /*weak*/ true, noreg); 9178 __ csetw($res$$Register, Assembler::EQ); 9179 %} 9180 ins_pipe(pipe_slow); 9181 %} 9182 9183 // This pattern is generated automatically from cas.m4. 9184 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9185 instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9186 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9187 ins_cost(2 * VOLATILE_REF_COST); 9188 effect(KILL cr); 9189 format %{ 9190 "cmpxchgw $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9191 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9192 %} 9193 ins_encode %{ 9194 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9195 Assembler::word, /*acquire*/ false, /*release*/ true, 9196 /*weak*/ true, noreg); 9197 __ csetw($res$$Register, Assembler::EQ); 9198 %} 9199 ins_pipe(pipe_slow); 9200 %} 9201 9202 // This pattern is generated automatically from cas.m4. 9203 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9204 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9205 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9206 ins_cost(2 * VOLATILE_REF_COST); 9207 effect(KILL cr); 9208 format %{ 9209 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9210 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9211 %} 9212 ins_encode %{ 9213 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9214 Assembler::xword, /*acquire*/ false, /*release*/ true, 9215 /*weak*/ true, noreg); 9216 __ csetw($res$$Register, Assembler::EQ); 9217 %} 9218 ins_pipe(pipe_slow); 9219 %} 9220 9221 // This pattern is generated automatically from cas.m4. 9222 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9223 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9224 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9225 ins_cost(2 * VOLATILE_REF_COST); 9226 effect(KILL cr); 9227 format %{ 9228 "cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9229 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9230 %} 9231 ins_encode %{ 9232 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9233 Assembler::word, /*acquire*/ false, /*release*/ true, 9234 /*weak*/ true, noreg); 9235 __ csetw($res$$Register, Assembler::EQ); 9236 %} 9237 ins_pipe(pipe_slow); 9238 %} 9239 9240 // This pattern is generated automatically from cas.m4. 9241 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9242 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9243 predicate(n->as_LoadStore()->barrier_data() == 0); 9244 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9245 ins_cost(2 * VOLATILE_REF_COST); 9246 effect(KILL cr); 9247 format %{ 9248 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9249 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9250 %} 9251 ins_encode %{ 9252 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9253 Assembler::xword, /*acquire*/ false, /*release*/ true, 9254 /*weak*/ true, noreg); 9255 __ csetw($res$$Register, Assembler::EQ); 9256 %} 9257 ins_pipe(pipe_slow); 9258 %} 9259 9260 // This pattern is generated automatically from cas.m4. 9261 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9262 instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9263 predicate(needs_acquiring_load_exclusive(n)); 9264 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval))); 9265 ins_cost(VOLATILE_REF_COST); 9266 effect(KILL cr); 9267 format %{ 9268 "cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval" 9269 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9270 %} 9271 ins_encode %{ 9272 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9273 Assembler::byte, /*acquire*/ true, /*release*/ true, 9274 /*weak*/ true, noreg); 9275 __ csetw($res$$Register, Assembler::EQ); 9276 %} 9277 ins_pipe(pipe_slow); 9278 %} 9279 9280 // This pattern is generated automatically from cas.m4. 9281 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9282 instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9283 predicate(needs_acquiring_load_exclusive(n)); 9284 match(Set res (WeakCompareAndSwapS mem (Binary oldval newval))); 9285 ins_cost(VOLATILE_REF_COST); 9286 effect(KILL cr); 9287 format %{ 9288 "cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short, weak) if $mem == $oldval then $mem <-- $newval" 9289 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9290 %} 9291 ins_encode %{ 9292 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9293 Assembler::halfword, /*acquire*/ true, /*release*/ true, 9294 /*weak*/ true, noreg); 9295 __ csetw($res$$Register, Assembler::EQ); 9296 %} 9297 ins_pipe(pipe_slow); 9298 %} 9299 9300 // This pattern is generated automatically from cas.m4. 9301 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9302 instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{ 9303 predicate(needs_acquiring_load_exclusive(n)); 9304 match(Set res (WeakCompareAndSwapI mem (Binary oldval newval))); 9305 ins_cost(VOLATILE_REF_COST); 9306 effect(KILL cr); 9307 format %{ 9308 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int, weak) if $mem == $oldval then $mem <-- $newval" 9309 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9310 %} 9311 ins_encode %{ 9312 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9313 Assembler::word, /*acquire*/ true, /*release*/ true, 9314 /*weak*/ true, noreg); 9315 __ csetw($res$$Register, Assembler::EQ); 9316 %} 9317 ins_pipe(pipe_slow); 9318 %} 9319 9320 // This pattern is generated automatically from cas.m4. 9321 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9322 instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{ 9323 predicate(needs_acquiring_load_exclusive(n)); 9324 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval))); 9325 ins_cost(VOLATILE_REF_COST); 9326 effect(KILL cr); 9327 format %{ 9328 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval" 9329 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9330 %} 9331 ins_encode %{ 9332 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9333 Assembler::xword, /*acquire*/ true, /*release*/ true, 9334 /*weak*/ true, noreg); 9335 __ csetw($res$$Register, Assembler::EQ); 9336 %} 9337 ins_pipe(pipe_slow); 9338 %} 9339 9340 // This pattern is generated automatically from cas.m4. 9341 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9342 instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{ 9343 predicate(needs_acquiring_load_exclusive(n)); 9344 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval))); 9345 ins_cost(VOLATILE_REF_COST); 9346 effect(KILL cr); 9347 format %{ 9348 "cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 9349 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9350 %} 9351 ins_encode %{ 9352 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9353 Assembler::word, /*acquire*/ true, /*release*/ true, 9354 /*weak*/ true, noreg); 9355 __ csetw($res$$Register, Assembler::EQ); 9356 %} 9357 ins_pipe(pipe_slow); 9358 %} 9359 9360 // This pattern is generated automatically from cas.m4. 9361 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 9362 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ 9363 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9364 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval))); 9365 ins_cost(VOLATILE_REF_COST); 9366 effect(KILL cr); 9367 format %{ 9368 "cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 9369 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 9370 %} 9371 ins_encode %{ 9372 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, 9373 Assembler::xword, /*acquire*/ true, /*release*/ true, 9374 /*weak*/ true, noreg); 9375 __ csetw($res$$Register, Assembler::EQ); 9376 %} 9377 ins_pipe(pipe_slow); 9378 %} 9379 9380 // END This section of the file is automatically generated. Do not edit -------------- 9381 // --------------------------------------------------------------------- 9382 9383 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ 9384 match(Set prev (GetAndSetI mem newv)); 9385 ins_cost(2 * VOLATILE_REF_COST); 9386 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9387 ins_encode %{ 9388 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9389 %} 9390 ins_pipe(pipe_serial); 9391 %} 9392 9393 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9394 match(Set prev (GetAndSetL mem newv)); 9395 ins_cost(2 * VOLATILE_REF_COST); 9396 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9397 ins_encode %{ 9398 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9399 %} 9400 ins_pipe(pipe_serial); 9401 %} 9402 9403 instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{ 9404 match(Set prev (GetAndSetN mem newv)); 9405 ins_cost(2 * VOLATILE_REF_COST); 9406 format %{ "atomic_xchgw $prev, $newv, [$mem]" %} 9407 ins_encode %{ 9408 __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9409 %} 9410 ins_pipe(pipe_serial); 9411 %} 9412 9413 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9414 predicate(n->as_LoadStore()->barrier_data() == 0); 9415 match(Set prev (GetAndSetP mem newv)); 9416 ins_cost(2 * VOLATILE_REF_COST); 9417 format %{ "atomic_xchg $prev, $newv, [$mem]" %} 9418 ins_encode %{ 9419 __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9420 %} 9421 ins_pipe(pipe_serial); 9422 %} 9423 9424 instruct get_and_setIAcq(indirect mem, iRegI newv, iRegINoSp prev) %{ 9425 predicate(needs_acquiring_load_exclusive(n)); 9426 match(Set prev (GetAndSetI mem newv)); 9427 ins_cost(VOLATILE_REF_COST); 9428 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9429 ins_encode %{ 9430 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9431 %} 9432 ins_pipe(pipe_serial); 9433 %} 9434 9435 instruct get_and_setLAcq(indirect mem, iRegL newv, iRegLNoSp prev) %{ 9436 predicate(needs_acquiring_load_exclusive(n)); 9437 match(Set prev (GetAndSetL mem newv)); 9438 ins_cost(VOLATILE_REF_COST); 9439 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9440 ins_encode %{ 9441 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9442 %} 9443 ins_pipe(pipe_serial); 9444 %} 9445 9446 instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{ 9447 predicate(needs_acquiring_load_exclusive(n)); 9448 match(Set prev (GetAndSetN mem newv)); 9449 ins_cost(VOLATILE_REF_COST); 9450 format %{ "atomic_xchgw_acq $prev, $newv, [$mem]" %} 9451 ins_encode %{ 9452 __ atomic_xchgalw($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9453 %} 9454 ins_pipe(pipe_serial); 9455 %} 9456 9457 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{ 9458 predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0)); 9459 match(Set prev (GetAndSetP mem newv)); 9460 ins_cost(VOLATILE_REF_COST); 9461 format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %} 9462 ins_encode %{ 9463 __ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base)); 9464 %} 9465 ins_pipe(pipe_serial); 9466 %} 9467 9468 9469 instruct get_and_addL(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9470 match(Set newval (GetAndAddL mem incr)); 9471 ins_cost(2 * VOLATILE_REF_COST + 1); 9472 format %{ "get_and_addL $newval, [$mem], $incr" %} 9473 ins_encode %{ 9474 __ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9475 %} 9476 ins_pipe(pipe_serial); 9477 %} 9478 9479 instruct get_and_addL_no_res(indirect mem, Universe dummy, iRegL incr) %{ 9480 predicate(n->as_LoadStore()->result_not_used()); 9481 match(Set dummy (GetAndAddL mem incr)); 9482 ins_cost(2 * VOLATILE_REF_COST); 9483 format %{ "get_and_addL [$mem], $incr" %} 9484 ins_encode %{ 9485 __ atomic_add(noreg, $incr$$Register, as_Register($mem$$base)); 9486 %} 9487 ins_pipe(pipe_serial); 9488 %} 9489 9490 instruct get_and_addLi(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9491 match(Set newval (GetAndAddL mem incr)); 9492 ins_cost(2 * VOLATILE_REF_COST + 1); 9493 format %{ "get_and_addL $newval, [$mem], $incr" %} 9494 ins_encode %{ 9495 __ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9496 %} 9497 ins_pipe(pipe_serial); 9498 %} 9499 9500 instruct get_and_addLi_no_res(indirect mem, Universe dummy, immLAddSub incr) %{ 9501 predicate(n->as_LoadStore()->result_not_used()); 9502 match(Set dummy (GetAndAddL mem incr)); 9503 ins_cost(2 * VOLATILE_REF_COST); 9504 format %{ "get_and_addL [$mem], $incr" %} 9505 ins_encode %{ 9506 __ atomic_add(noreg, $incr$$constant, as_Register($mem$$base)); 9507 %} 9508 ins_pipe(pipe_serial); 9509 %} 9510 9511 instruct get_and_addI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9512 match(Set newval (GetAndAddI mem incr)); 9513 ins_cost(2 * VOLATILE_REF_COST + 1); 9514 format %{ "get_and_addI $newval, [$mem], $incr" %} 9515 ins_encode %{ 9516 __ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9517 %} 9518 ins_pipe(pipe_serial); 9519 %} 9520 9521 instruct get_and_addI_no_res(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9522 predicate(n->as_LoadStore()->result_not_used()); 9523 match(Set dummy (GetAndAddI mem incr)); 9524 ins_cost(2 * VOLATILE_REF_COST); 9525 format %{ "get_and_addI [$mem], $incr" %} 9526 ins_encode %{ 9527 __ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base)); 9528 %} 9529 ins_pipe(pipe_serial); 9530 %} 9531 9532 instruct get_and_addIi(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9533 match(Set newval (GetAndAddI mem incr)); 9534 ins_cost(2 * VOLATILE_REF_COST + 1); 9535 format %{ "get_and_addI $newval, [$mem], $incr" %} 9536 ins_encode %{ 9537 __ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9538 %} 9539 ins_pipe(pipe_serial); 9540 %} 9541 9542 instruct get_and_addIi_no_res(indirect mem, Universe dummy, immIAddSub incr) %{ 9543 predicate(n->as_LoadStore()->result_not_used()); 9544 match(Set dummy (GetAndAddI mem incr)); 9545 ins_cost(2 * VOLATILE_REF_COST); 9546 format %{ "get_and_addI [$mem], $incr" %} 9547 ins_encode %{ 9548 __ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base)); 9549 %} 9550 ins_pipe(pipe_serial); 9551 %} 9552 9553 instruct get_and_addLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{ 9554 predicate(needs_acquiring_load_exclusive(n)); 9555 match(Set newval (GetAndAddL mem incr)); 9556 ins_cost(VOLATILE_REF_COST + 1); 9557 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9558 ins_encode %{ 9559 __ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9560 %} 9561 ins_pipe(pipe_serial); 9562 %} 9563 9564 instruct get_and_addL_no_resAcq(indirect mem, Universe dummy, iRegL incr) %{ 9565 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9566 match(Set dummy (GetAndAddL mem incr)); 9567 ins_cost(VOLATILE_REF_COST); 9568 format %{ "get_and_addL_acq [$mem], $incr" %} 9569 ins_encode %{ 9570 __ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base)); 9571 %} 9572 ins_pipe(pipe_serial); 9573 %} 9574 9575 instruct get_and_addLiAcq(indirect mem, iRegLNoSp newval, immLAddSub incr) %{ 9576 predicate(needs_acquiring_load_exclusive(n)); 9577 match(Set newval (GetAndAddL mem incr)); 9578 ins_cost(VOLATILE_REF_COST + 1); 9579 format %{ "get_and_addL_acq $newval, [$mem], $incr" %} 9580 ins_encode %{ 9581 __ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9582 %} 9583 ins_pipe(pipe_serial); 9584 %} 9585 9586 instruct get_and_addLi_no_resAcq(indirect mem, Universe dummy, immLAddSub incr) %{ 9587 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9588 match(Set dummy (GetAndAddL mem incr)); 9589 ins_cost(VOLATILE_REF_COST); 9590 format %{ "get_and_addL_acq [$mem], $incr" %} 9591 ins_encode %{ 9592 __ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base)); 9593 %} 9594 ins_pipe(pipe_serial); 9595 %} 9596 9597 instruct get_and_addIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{ 9598 predicate(needs_acquiring_load_exclusive(n)); 9599 match(Set newval (GetAndAddI mem incr)); 9600 ins_cost(VOLATILE_REF_COST + 1); 9601 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9602 ins_encode %{ 9603 __ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base)); 9604 %} 9605 ins_pipe(pipe_serial); 9606 %} 9607 9608 instruct get_and_addI_no_resAcq(indirect mem, Universe dummy, iRegIorL2I incr) %{ 9609 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9610 match(Set dummy (GetAndAddI mem incr)); 9611 ins_cost(VOLATILE_REF_COST); 9612 format %{ "get_and_addI_acq [$mem], $incr" %} 9613 ins_encode %{ 9614 __ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base)); 9615 %} 9616 ins_pipe(pipe_serial); 9617 %} 9618 9619 instruct get_and_addIiAcq(indirect mem, iRegINoSp newval, immIAddSub incr) %{ 9620 predicate(needs_acquiring_load_exclusive(n)); 9621 match(Set newval (GetAndAddI mem incr)); 9622 ins_cost(VOLATILE_REF_COST + 1); 9623 format %{ "get_and_addI_acq $newval, [$mem], $incr" %} 9624 ins_encode %{ 9625 __ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base)); 9626 %} 9627 ins_pipe(pipe_serial); 9628 %} 9629 9630 instruct get_and_addIi_no_resAcq(indirect mem, Universe dummy, immIAddSub incr) %{ 9631 predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n)); 9632 match(Set dummy (GetAndAddI mem incr)); 9633 ins_cost(VOLATILE_REF_COST); 9634 format %{ "get_and_addI_acq [$mem], $incr" %} 9635 ins_encode %{ 9636 __ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base)); 9637 %} 9638 ins_pipe(pipe_serial); 9639 %} 9640 9641 // Manifest a CmpU result in an integer register. 9642 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9643 instruct cmpU3_reg_reg(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg flags) 9644 %{ 9645 match(Set dst (CmpU3 src1 src2)); 9646 effect(KILL flags); 9647 9648 ins_cost(INSN_COST * 3); 9649 format %{ 9650 "cmpw $src1, $src2\n\t" 9651 "csetw $dst, ne\n\t" 9652 "cnegw $dst, lo\t# CmpU3(reg)" 9653 %} 9654 ins_encode %{ 9655 __ cmpw($src1$$Register, $src2$$Register); 9656 __ csetw($dst$$Register, Assembler::NE); 9657 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9658 %} 9659 9660 ins_pipe(pipe_class_default); 9661 %} 9662 9663 instruct cmpU3_reg_imm(iRegINoSp dst, iRegI src1, immIAddSub src2, rFlagsReg flags) 9664 %{ 9665 match(Set dst (CmpU3 src1 src2)); 9666 effect(KILL flags); 9667 9668 ins_cost(INSN_COST * 3); 9669 format %{ 9670 "subsw zr, $src1, $src2\n\t" 9671 "csetw $dst, ne\n\t" 9672 "cnegw $dst, lo\t# CmpU3(imm)" 9673 %} 9674 ins_encode %{ 9675 __ subsw(zr, $src1$$Register, (int32_t)$src2$$constant); 9676 __ csetw($dst$$Register, Assembler::NE); 9677 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9678 %} 9679 9680 ins_pipe(pipe_class_default); 9681 %} 9682 9683 // Manifest a CmpUL result in an integer register. 9684 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9685 instruct cmpUL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9686 %{ 9687 match(Set dst (CmpUL3 src1 src2)); 9688 effect(KILL flags); 9689 9690 ins_cost(INSN_COST * 3); 9691 format %{ 9692 "cmp $src1, $src2\n\t" 9693 "csetw $dst, ne\n\t" 9694 "cnegw $dst, lo\t# CmpUL3(reg)" 9695 %} 9696 ins_encode %{ 9697 __ cmp($src1$$Register, $src2$$Register); 9698 __ csetw($dst$$Register, Assembler::NE); 9699 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9700 %} 9701 9702 ins_pipe(pipe_class_default); 9703 %} 9704 9705 instruct cmpUL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9706 %{ 9707 match(Set dst (CmpUL3 src1 src2)); 9708 effect(KILL flags); 9709 9710 ins_cost(INSN_COST * 3); 9711 format %{ 9712 "subs zr, $src1, $src2\n\t" 9713 "csetw $dst, ne\n\t" 9714 "cnegw $dst, lo\t# CmpUL3(imm)" 9715 %} 9716 ins_encode %{ 9717 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant); 9718 __ csetw($dst$$Register, Assembler::NE); 9719 __ cnegw($dst$$Register, $dst$$Register, Assembler::LO); 9720 %} 9721 9722 ins_pipe(pipe_class_default); 9723 %} 9724 9725 // Manifest a CmpL result in an integer register. 9726 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 9727 instruct cmpL3_reg_reg(iRegINoSp dst, iRegL src1, iRegL src2, rFlagsReg flags) 9728 %{ 9729 match(Set dst (CmpL3 src1 src2)); 9730 effect(KILL flags); 9731 9732 ins_cost(INSN_COST * 3); 9733 format %{ 9734 "cmp $src1, $src2\n\t" 9735 "csetw $dst, ne\n\t" 9736 "cnegw $dst, lt\t# CmpL3(reg)" 9737 %} 9738 ins_encode %{ 9739 __ cmp($src1$$Register, $src2$$Register); 9740 __ csetw($dst$$Register, Assembler::NE); 9741 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9742 %} 9743 9744 ins_pipe(pipe_class_default); 9745 %} 9746 9747 instruct cmpL3_reg_imm(iRegINoSp dst, iRegL src1, immLAddSub src2, rFlagsReg flags) 9748 %{ 9749 match(Set dst (CmpL3 src1 src2)); 9750 effect(KILL flags); 9751 9752 ins_cost(INSN_COST * 3); 9753 format %{ 9754 "subs zr, $src1, $src2\n\t" 9755 "csetw $dst, ne\n\t" 9756 "cnegw $dst, lt\t# CmpL3(imm)" 9757 %} 9758 ins_encode %{ 9759 __ subs(zr, $src1$$Register, (int32_t)$src2$$constant); 9760 __ csetw($dst$$Register, Assembler::NE); 9761 __ cnegw($dst$$Register, $dst$$Register, Assembler::LT); 9762 %} 9763 9764 ins_pipe(pipe_class_default); 9765 %} 9766 9767 // ============================================================================ 9768 // Conditional Move Instructions 9769 9770 // n.b. we have identical rules for both a signed compare op (cmpOp) 9771 // and an unsigned compare op (cmpOpU). it would be nice if we could 9772 // define an op class which merged both inputs and use it to type the 9773 // argument to a single rule. unfortunatelyt his fails because the 9774 // opclass does not live up to the COND_INTER interface of its 9775 // component operands. When the generic code tries to negate the 9776 // operand it ends up running the generci Machoper::negate method 9777 // which throws a ShouldNotHappen. So, we have to provide two flavours 9778 // of each rule, one for a cmpOp and a second for a cmpOpU (sigh). 9779 9780 instruct cmovI_reg_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9781 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9782 9783 ins_cost(INSN_COST * 2); 9784 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, int" %} 9785 9786 ins_encode %{ 9787 __ cselw(as_Register($dst$$reg), 9788 as_Register($src2$$reg), 9789 as_Register($src1$$reg), 9790 (Assembler::Condition)$cmp$$cmpcode); 9791 %} 9792 9793 ins_pipe(icond_reg_reg); 9794 %} 9795 9796 instruct cmovUI_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 9797 match(Set dst (CMoveI (Binary cmp cr) (Binary src1 src2))); 9798 9799 ins_cost(INSN_COST * 2); 9800 format %{ "cselw $dst, $src2, $src1 $cmp\t# unsigned, int" %} 9801 9802 ins_encode %{ 9803 __ cselw(as_Register($dst$$reg), 9804 as_Register($src2$$reg), 9805 as_Register($src1$$reg), 9806 (Assembler::Condition)$cmp$$cmpcode); 9807 %} 9808 9809 ins_pipe(icond_reg_reg); 9810 %} 9811 9812 // special cases where one arg is zero 9813 9814 // n.b. this is selected in preference to the rule above because it 9815 // avoids loading constant 0 into a source register 9816 9817 // TODO 9818 // we ought only to be able to cull one of these variants as the ideal 9819 // transforms ought always to order the zero consistently (to left/right?) 9820 9821 instruct cmovI_zero_reg(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9822 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9823 9824 ins_cost(INSN_COST * 2); 9825 format %{ "cselw $dst, $src, zr $cmp\t# signed, int" %} 9826 9827 ins_encode %{ 9828 __ cselw(as_Register($dst$$reg), 9829 as_Register($src$$reg), 9830 zr, 9831 (Assembler::Condition)$cmp$$cmpcode); 9832 %} 9833 9834 ins_pipe(icond_reg); 9835 %} 9836 9837 instruct cmovUI_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, iRegIorL2I src) %{ 9838 match(Set dst (CMoveI (Binary cmp cr) (Binary zero src))); 9839 9840 ins_cost(INSN_COST * 2); 9841 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, int" %} 9842 9843 ins_encode %{ 9844 __ cselw(as_Register($dst$$reg), 9845 as_Register($src$$reg), 9846 zr, 9847 (Assembler::Condition)$cmp$$cmpcode); 9848 %} 9849 9850 ins_pipe(icond_reg); 9851 %} 9852 9853 instruct cmovI_reg_zero(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9854 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9855 9856 ins_cost(INSN_COST * 2); 9857 format %{ "cselw $dst, zr, $src $cmp\t# signed, int" %} 9858 9859 ins_encode %{ 9860 __ cselw(as_Register($dst$$reg), 9861 zr, 9862 as_Register($src$$reg), 9863 (Assembler::Condition)$cmp$$cmpcode); 9864 %} 9865 9866 ins_pipe(icond_reg); 9867 %} 9868 9869 instruct cmovUI_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, iRegIorL2I src, immI0 zero) %{ 9870 match(Set dst (CMoveI (Binary cmp cr) (Binary src zero))); 9871 9872 ins_cost(INSN_COST * 2); 9873 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, int" %} 9874 9875 ins_encode %{ 9876 __ cselw(as_Register($dst$$reg), 9877 zr, 9878 as_Register($src$$reg), 9879 (Assembler::Condition)$cmp$$cmpcode); 9880 %} 9881 9882 ins_pipe(icond_reg); 9883 %} 9884 9885 // special case for creating a boolean 0 or 1 9886 9887 // n.b. this is selected in preference to the rule above because it 9888 // avoids loading constants 0 and 1 into a source register 9889 9890 instruct cmovI_reg_zero_one(cmpOp cmp, rFlagsReg cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9891 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9892 9893 ins_cost(INSN_COST * 2); 9894 format %{ "csincw $dst, zr, zr $cmp\t# signed, int" %} 9895 9896 ins_encode %{ 9897 // equivalently 9898 // cset(as_Register($dst$$reg), 9899 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9900 __ csincw(as_Register($dst$$reg), 9901 zr, 9902 zr, 9903 (Assembler::Condition)$cmp$$cmpcode); 9904 %} 9905 9906 ins_pipe(icond_none); 9907 %} 9908 9909 instruct cmovUI_reg_zero_one(cmpOpU cmp, rFlagsRegU cr, iRegINoSp dst, immI0 zero, immI_1 one) %{ 9910 match(Set dst (CMoveI (Binary cmp cr) (Binary one zero))); 9911 9912 ins_cost(INSN_COST * 2); 9913 format %{ "csincw $dst, zr, zr $cmp\t# unsigned, int" %} 9914 9915 ins_encode %{ 9916 // equivalently 9917 // cset(as_Register($dst$$reg), 9918 // negate_condition((Assembler::Condition)$cmp$$cmpcode)); 9919 __ csincw(as_Register($dst$$reg), 9920 zr, 9921 zr, 9922 (Assembler::Condition)$cmp$$cmpcode); 9923 %} 9924 9925 ins_pipe(icond_none); 9926 %} 9927 9928 instruct cmovL_reg_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9929 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9930 9931 ins_cost(INSN_COST * 2); 9932 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, long" %} 9933 9934 ins_encode %{ 9935 __ csel(as_Register($dst$$reg), 9936 as_Register($src2$$reg), 9937 as_Register($src1$$reg), 9938 (Assembler::Condition)$cmp$$cmpcode); 9939 %} 9940 9941 ins_pipe(icond_reg_reg); 9942 %} 9943 9944 instruct cmovUL_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src1, iRegL src2) %{ 9945 match(Set dst (CMoveL (Binary cmp cr) (Binary src1 src2))); 9946 9947 ins_cost(INSN_COST * 2); 9948 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, long" %} 9949 9950 ins_encode %{ 9951 __ csel(as_Register($dst$$reg), 9952 as_Register($src2$$reg), 9953 as_Register($src1$$reg), 9954 (Assembler::Condition)$cmp$$cmpcode); 9955 %} 9956 9957 ins_pipe(icond_reg_reg); 9958 %} 9959 9960 // special cases where one arg is zero 9961 9962 instruct cmovL_reg_zero(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9963 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9964 9965 ins_cost(INSN_COST * 2); 9966 format %{ "csel $dst, zr, $src $cmp\t# signed, long" %} 9967 9968 ins_encode %{ 9969 __ csel(as_Register($dst$$reg), 9970 zr, 9971 as_Register($src$$reg), 9972 (Assembler::Condition)$cmp$$cmpcode); 9973 %} 9974 9975 ins_pipe(icond_reg); 9976 %} 9977 9978 instruct cmovUL_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, iRegL src, immL0 zero) %{ 9979 match(Set dst (CMoveL (Binary cmp cr) (Binary src zero))); 9980 9981 ins_cost(INSN_COST * 2); 9982 format %{ "csel $dst, zr, $src $cmp\t# unsigned, long" %} 9983 9984 ins_encode %{ 9985 __ csel(as_Register($dst$$reg), 9986 zr, 9987 as_Register($src$$reg), 9988 (Assembler::Condition)$cmp$$cmpcode); 9989 %} 9990 9991 ins_pipe(icond_reg); 9992 %} 9993 9994 instruct cmovL_zero_reg(cmpOp cmp, rFlagsReg cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 9995 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 9996 9997 ins_cost(INSN_COST * 2); 9998 format %{ "csel $dst, $src, zr $cmp\t# signed, long" %} 9999 10000 ins_encode %{ 10001 __ csel(as_Register($dst$$reg), 10002 as_Register($src$$reg), 10003 zr, 10004 (Assembler::Condition)$cmp$$cmpcode); 10005 %} 10006 10007 ins_pipe(icond_reg); 10008 %} 10009 10010 instruct cmovUL_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegLNoSp dst, immL0 zero, iRegL src) %{ 10011 match(Set dst (CMoveL (Binary cmp cr) (Binary zero src))); 10012 10013 ins_cost(INSN_COST * 2); 10014 format %{ "csel $dst, $src, zr $cmp\t# unsigned, long" %} 10015 10016 ins_encode %{ 10017 __ csel(as_Register($dst$$reg), 10018 as_Register($src$$reg), 10019 zr, 10020 (Assembler::Condition)$cmp$$cmpcode); 10021 %} 10022 10023 ins_pipe(icond_reg); 10024 %} 10025 10026 instruct cmovP_reg_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 10027 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 10028 10029 ins_cost(INSN_COST * 2); 10030 format %{ "csel $dst, $src2, $src1 $cmp\t# signed, ptr" %} 10031 10032 ins_encode %{ 10033 __ csel(as_Register($dst$$reg), 10034 as_Register($src2$$reg), 10035 as_Register($src1$$reg), 10036 (Assembler::Condition)$cmp$$cmpcode); 10037 %} 10038 10039 ins_pipe(icond_reg_reg); 10040 %} 10041 10042 instruct cmovUP_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src1, iRegP src2) %{ 10043 match(Set dst (CMoveP (Binary cmp cr) (Binary src1 src2))); 10044 10045 ins_cost(INSN_COST * 2); 10046 format %{ "csel $dst, $src2, $src1 $cmp\t# unsigned, ptr" %} 10047 10048 ins_encode %{ 10049 __ csel(as_Register($dst$$reg), 10050 as_Register($src2$$reg), 10051 as_Register($src1$$reg), 10052 (Assembler::Condition)$cmp$$cmpcode); 10053 %} 10054 10055 ins_pipe(icond_reg_reg); 10056 %} 10057 10058 // special cases where one arg is zero 10059 10060 instruct cmovP_reg_zero(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 10061 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 10062 10063 ins_cost(INSN_COST * 2); 10064 format %{ "csel $dst, zr, $src $cmp\t# signed, ptr" %} 10065 10066 ins_encode %{ 10067 __ csel(as_Register($dst$$reg), 10068 zr, 10069 as_Register($src$$reg), 10070 (Assembler::Condition)$cmp$$cmpcode); 10071 %} 10072 10073 ins_pipe(icond_reg); 10074 %} 10075 10076 instruct cmovUP_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, iRegP src, immP0 zero) %{ 10077 match(Set dst (CMoveP (Binary cmp cr) (Binary src zero))); 10078 10079 ins_cost(INSN_COST * 2); 10080 format %{ "csel $dst, zr, $src $cmp\t# unsigned, ptr" %} 10081 10082 ins_encode %{ 10083 __ csel(as_Register($dst$$reg), 10084 zr, 10085 as_Register($src$$reg), 10086 (Assembler::Condition)$cmp$$cmpcode); 10087 %} 10088 10089 ins_pipe(icond_reg); 10090 %} 10091 10092 instruct cmovP_zero_reg(cmpOp cmp, rFlagsReg cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 10093 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 10094 10095 ins_cost(INSN_COST * 2); 10096 format %{ "csel $dst, $src, zr $cmp\t# signed, ptr" %} 10097 10098 ins_encode %{ 10099 __ csel(as_Register($dst$$reg), 10100 as_Register($src$$reg), 10101 zr, 10102 (Assembler::Condition)$cmp$$cmpcode); 10103 %} 10104 10105 ins_pipe(icond_reg); 10106 %} 10107 10108 instruct cmovUP_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegPNoSp dst, immP0 zero, iRegP src) %{ 10109 match(Set dst (CMoveP (Binary cmp cr) (Binary zero src))); 10110 10111 ins_cost(INSN_COST * 2); 10112 format %{ "csel $dst, $src, zr $cmp\t# unsigned, ptr" %} 10113 10114 ins_encode %{ 10115 __ csel(as_Register($dst$$reg), 10116 as_Register($src$$reg), 10117 zr, 10118 (Assembler::Condition)$cmp$$cmpcode); 10119 %} 10120 10121 ins_pipe(icond_reg); 10122 %} 10123 10124 instruct cmovN_reg_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 10125 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 10126 10127 ins_cost(INSN_COST * 2); 10128 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 10129 10130 ins_encode %{ 10131 __ cselw(as_Register($dst$$reg), 10132 as_Register($src2$$reg), 10133 as_Register($src1$$reg), 10134 (Assembler::Condition)$cmp$$cmpcode); 10135 %} 10136 10137 ins_pipe(icond_reg_reg); 10138 %} 10139 10140 instruct cmovUN_reg_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src1, iRegN src2) %{ 10141 match(Set dst (CMoveN (Binary cmp cr) (Binary src1 src2))); 10142 10143 ins_cost(INSN_COST * 2); 10144 format %{ "cselw $dst, $src2, $src1 $cmp\t# signed, compressed ptr" %} 10145 10146 ins_encode %{ 10147 __ cselw(as_Register($dst$$reg), 10148 as_Register($src2$$reg), 10149 as_Register($src1$$reg), 10150 (Assembler::Condition)$cmp$$cmpcode); 10151 %} 10152 10153 ins_pipe(icond_reg_reg); 10154 %} 10155 10156 // special cases where one arg is zero 10157 10158 instruct cmovN_reg_zero(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 10159 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 10160 10161 ins_cost(INSN_COST * 2); 10162 format %{ "cselw $dst, zr, $src $cmp\t# signed, compressed ptr" %} 10163 10164 ins_encode %{ 10165 __ cselw(as_Register($dst$$reg), 10166 zr, 10167 as_Register($src$$reg), 10168 (Assembler::Condition)$cmp$$cmpcode); 10169 %} 10170 10171 ins_pipe(icond_reg); 10172 %} 10173 10174 instruct cmovUN_reg_zero(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, iRegN src, immN0 zero) %{ 10175 match(Set dst (CMoveN (Binary cmp cr) (Binary src zero))); 10176 10177 ins_cost(INSN_COST * 2); 10178 format %{ "cselw $dst, zr, $src $cmp\t# unsigned, compressed ptr" %} 10179 10180 ins_encode %{ 10181 __ cselw(as_Register($dst$$reg), 10182 zr, 10183 as_Register($src$$reg), 10184 (Assembler::Condition)$cmp$$cmpcode); 10185 %} 10186 10187 ins_pipe(icond_reg); 10188 %} 10189 10190 instruct cmovN_zero_reg(cmpOp cmp, rFlagsReg cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 10191 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 10192 10193 ins_cost(INSN_COST * 2); 10194 format %{ "cselw $dst, $src, zr $cmp\t# signed, compressed ptr" %} 10195 10196 ins_encode %{ 10197 __ cselw(as_Register($dst$$reg), 10198 as_Register($src$$reg), 10199 zr, 10200 (Assembler::Condition)$cmp$$cmpcode); 10201 %} 10202 10203 ins_pipe(icond_reg); 10204 %} 10205 10206 instruct cmovUN_zero_reg(cmpOpU cmp, rFlagsRegU cr, iRegNNoSp dst, immN0 zero, iRegN src) %{ 10207 match(Set dst (CMoveN (Binary cmp cr) (Binary zero src))); 10208 10209 ins_cost(INSN_COST * 2); 10210 format %{ "cselw $dst, $src, zr $cmp\t# unsigned, compressed ptr" %} 10211 10212 ins_encode %{ 10213 __ cselw(as_Register($dst$$reg), 10214 as_Register($src$$reg), 10215 zr, 10216 (Assembler::Condition)$cmp$$cmpcode); 10217 %} 10218 10219 ins_pipe(icond_reg); 10220 %} 10221 10222 instruct cmovF_reg(cmpOp cmp, rFlagsReg cr, vRegF dst, vRegF src1, vRegF src2) 10223 %{ 10224 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10225 10226 ins_cost(INSN_COST * 3); 10227 10228 format %{ "fcsels $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10229 ins_encode %{ 10230 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10231 __ fcsels(as_FloatRegister($dst$$reg), 10232 as_FloatRegister($src2$$reg), 10233 as_FloatRegister($src1$$reg), 10234 cond); 10235 %} 10236 10237 ins_pipe(fp_cond_reg_reg_s); 10238 %} 10239 10240 instruct cmovUF_reg(cmpOpU cmp, rFlagsRegU cr, vRegF dst, vRegF src1, vRegF src2) 10241 %{ 10242 match(Set dst (CMoveF (Binary cmp cr) (Binary src1 src2))); 10243 10244 ins_cost(INSN_COST * 3); 10245 10246 format %{ "fcsels $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10247 ins_encode %{ 10248 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10249 __ fcsels(as_FloatRegister($dst$$reg), 10250 as_FloatRegister($src2$$reg), 10251 as_FloatRegister($src1$$reg), 10252 cond); 10253 %} 10254 10255 ins_pipe(fp_cond_reg_reg_s); 10256 %} 10257 10258 instruct cmovD_reg(cmpOp cmp, rFlagsReg cr, vRegD dst, vRegD src1, vRegD src2) 10259 %{ 10260 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10261 10262 ins_cost(INSN_COST * 3); 10263 10264 format %{ "fcseld $dst, $src1, $src2, $cmp\t# signed cmove float\n\t" %} 10265 ins_encode %{ 10266 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10267 __ fcseld(as_FloatRegister($dst$$reg), 10268 as_FloatRegister($src2$$reg), 10269 as_FloatRegister($src1$$reg), 10270 cond); 10271 %} 10272 10273 ins_pipe(fp_cond_reg_reg_d); 10274 %} 10275 10276 instruct cmovUD_reg(cmpOpU cmp, rFlagsRegU cr, vRegD dst, vRegD src1, vRegD src2) 10277 %{ 10278 match(Set dst (CMoveD (Binary cmp cr) (Binary src1 src2))); 10279 10280 ins_cost(INSN_COST * 3); 10281 10282 format %{ "fcseld $dst, $src1, $src2, $cmp\t# unsigned cmove float\n\t" %} 10283 ins_encode %{ 10284 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 10285 __ fcseld(as_FloatRegister($dst$$reg), 10286 as_FloatRegister($src2$$reg), 10287 as_FloatRegister($src1$$reg), 10288 cond); 10289 %} 10290 10291 ins_pipe(fp_cond_reg_reg_d); 10292 %} 10293 10294 // ============================================================================ 10295 // Arithmetic Instructions 10296 // 10297 10298 // Integer Addition 10299 10300 // TODO 10301 // these currently employ operations which do not set CR and hence are 10302 // not flagged as killing CR but we would like to isolate the cases 10303 // where we want to set flags from those where we don't. need to work 10304 // out how to do that. 10305 10306 instruct addI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10307 match(Set dst (AddI src1 src2)); 10308 10309 ins_cost(INSN_COST); 10310 format %{ "addw $dst, $src1, $src2" %} 10311 10312 ins_encode %{ 10313 __ addw(as_Register($dst$$reg), 10314 as_Register($src1$$reg), 10315 as_Register($src2$$reg)); 10316 %} 10317 10318 ins_pipe(ialu_reg_reg); 10319 %} 10320 10321 instruct addI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10322 match(Set dst (AddI src1 src2)); 10323 10324 ins_cost(INSN_COST); 10325 format %{ "addw $dst, $src1, $src2" %} 10326 10327 // use opcode to indicate that this is an add not a sub 10328 opcode(0x0); 10329 10330 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10331 10332 ins_pipe(ialu_reg_imm); 10333 %} 10334 10335 instruct addI_reg_imm_i2l(iRegINoSp dst, iRegL src1, immIAddSub src2) %{ 10336 match(Set dst (AddI (ConvL2I src1) src2)); 10337 10338 ins_cost(INSN_COST); 10339 format %{ "addw $dst, $src1, $src2" %} 10340 10341 // use opcode to indicate that this is an add not a sub 10342 opcode(0x0); 10343 10344 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10345 10346 ins_pipe(ialu_reg_imm); 10347 %} 10348 10349 // Pointer Addition 10350 instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{ 10351 match(Set dst (AddP src1 src2)); 10352 10353 ins_cost(INSN_COST); 10354 format %{ "add $dst, $src1, $src2\t# ptr" %} 10355 10356 ins_encode %{ 10357 __ add(as_Register($dst$$reg), 10358 as_Register($src1$$reg), 10359 as_Register($src2$$reg)); 10360 %} 10361 10362 ins_pipe(ialu_reg_reg); 10363 %} 10364 10365 instruct addP_reg_reg_ext(iRegPNoSp dst, iRegP src1, iRegIorL2I src2) %{ 10366 match(Set dst (AddP src1 (ConvI2L src2))); 10367 10368 ins_cost(1.9 * INSN_COST); 10369 format %{ "add $dst, $src1, $src2, sxtw\t# ptr" %} 10370 10371 ins_encode %{ 10372 __ add(as_Register($dst$$reg), 10373 as_Register($src1$$reg), 10374 as_Register($src2$$reg), ext::sxtw); 10375 %} 10376 10377 ins_pipe(ialu_reg_reg); 10378 %} 10379 10380 instruct addP_reg_reg_lsl(iRegPNoSp dst, iRegP src1, iRegL src2, immIScale scale) %{ 10381 match(Set dst (AddP src1 (LShiftL src2 scale))); 10382 10383 ins_cost(1.9 * INSN_COST); 10384 format %{ "add $dst, $src1, $src2, LShiftL $scale\t# ptr" %} 10385 10386 ins_encode %{ 10387 __ lea(as_Register($dst$$reg), 10388 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10389 Address::lsl($scale$$constant))); 10390 %} 10391 10392 ins_pipe(ialu_reg_reg_shift); 10393 %} 10394 10395 instruct addP_reg_reg_ext_shift(iRegPNoSp dst, iRegP src1, iRegIorL2I src2, immIScale scale) %{ 10396 match(Set dst (AddP src1 (LShiftL (ConvI2L src2) scale))); 10397 10398 ins_cost(1.9 * INSN_COST); 10399 format %{ "add $dst, $src1, $src2, I2L $scale\t# ptr" %} 10400 10401 ins_encode %{ 10402 __ lea(as_Register($dst$$reg), 10403 Address(as_Register($src1$$reg), as_Register($src2$$reg), 10404 Address::sxtw($scale$$constant))); 10405 %} 10406 10407 ins_pipe(ialu_reg_reg_shift); 10408 %} 10409 10410 instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{ 10411 match(Set dst (LShiftL (ConvI2L src) scale)); 10412 10413 ins_cost(INSN_COST); 10414 format %{ "sbfiz $dst, $src, $scale & 63, -$scale & 63\t" %} 10415 10416 ins_encode %{ 10417 __ sbfiz(as_Register($dst$$reg), 10418 as_Register($src$$reg), 10419 $scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63))); 10420 %} 10421 10422 ins_pipe(ialu_reg_shift); 10423 %} 10424 10425 // Pointer Immediate Addition 10426 // n.b. this needs to be more expensive than using an indirect memory 10427 // operand 10428 instruct addP_reg_imm(iRegPNoSp dst, iRegP src1, immLAddSub src2) %{ 10429 match(Set dst (AddP src1 src2)); 10430 10431 ins_cost(INSN_COST); 10432 format %{ "add $dst, $src1, $src2\t# ptr" %} 10433 10434 // use opcode to indicate that this is an add not a sub 10435 opcode(0x0); 10436 10437 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10438 10439 ins_pipe(ialu_reg_imm); 10440 %} 10441 10442 // Long Addition 10443 instruct addL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10444 10445 match(Set dst (AddL src1 src2)); 10446 10447 ins_cost(INSN_COST); 10448 format %{ "add $dst, $src1, $src2" %} 10449 10450 ins_encode %{ 10451 __ add(as_Register($dst$$reg), 10452 as_Register($src1$$reg), 10453 as_Register($src2$$reg)); 10454 %} 10455 10456 ins_pipe(ialu_reg_reg); 10457 %} 10458 10459 // No constant pool entries requiredLong Immediate Addition. 10460 instruct addL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10461 match(Set dst (AddL src1 src2)); 10462 10463 ins_cost(INSN_COST); 10464 format %{ "add $dst, $src1, $src2" %} 10465 10466 // use opcode to indicate that this is an add not a sub 10467 opcode(0x0); 10468 10469 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10470 10471 ins_pipe(ialu_reg_imm); 10472 %} 10473 10474 // Integer Subtraction 10475 instruct subI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10476 match(Set dst (SubI src1 src2)); 10477 10478 ins_cost(INSN_COST); 10479 format %{ "subw $dst, $src1, $src2" %} 10480 10481 ins_encode %{ 10482 __ subw(as_Register($dst$$reg), 10483 as_Register($src1$$reg), 10484 as_Register($src2$$reg)); 10485 %} 10486 10487 ins_pipe(ialu_reg_reg); 10488 %} 10489 10490 // Immediate Subtraction 10491 instruct subI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immIAddSub src2) %{ 10492 match(Set dst (SubI src1 src2)); 10493 10494 ins_cost(INSN_COST); 10495 format %{ "subw $dst, $src1, $src2" %} 10496 10497 // use opcode to indicate that this is a sub not an add 10498 opcode(0x1); 10499 10500 ins_encode(aarch64_enc_addsubw_imm(dst, src1, src2)); 10501 10502 ins_pipe(ialu_reg_imm); 10503 %} 10504 10505 // Long Subtraction 10506 instruct subL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10507 10508 match(Set dst (SubL src1 src2)); 10509 10510 ins_cost(INSN_COST); 10511 format %{ "sub $dst, $src1, $src2" %} 10512 10513 ins_encode %{ 10514 __ sub(as_Register($dst$$reg), 10515 as_Register($src1$$reg), 10516 as_Register($src2$$reg)); 10517 %} 10518 10519 ins_pipe(ialu_reg_reg); 10520 %} 10521 10522 // No constant pool entries requiredLong Immediate Subtraction. 10523 instruct subL_reg_imm(iRegLNoSp dst, iRegL src1, immLAddSub src2) %{ 10524 match(Set dst (SubL src1 src2)); 10525 10526 ins_cost(INSN_COST); 10527 format %{ "sub$dst, $src1, $src2" %} 10528 10529 // use opcode to indicate that this is a sub not an add 10530 opcode(0x1); 10531 10532 ins_encode( aarch64_enc_addsub_imm(dst, src1, src2) ); 10533 10534 ins_pipe(ialu_reg_imm); 10535 %} 10536 10537 // Integer Negation (special case for sub) 10538 10539 instruct negI_reg(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) %{ 10540 match(Set dst (SubI zero src)); 10541 10542 ins_cost(INSN_COST); 10543 format %{ "negw $dst, $src\t# int" %} 10544 10545 ins_encode %{ 10546 __ negw(as_Register($dst$$reg), 10547 as_Register($src$$reg)); 10548 %} 10549 10550 ins_pipe(ialu_reg); 10551 %} 10552 10553 // Long Negation 10554 10555 instruct negL_reg(iRegLNoSp dst, iRegL src, immL0 zero, rFlagsReg cr) %{ 10556 match(Set dst (SubL zero src)); 10557 10558 ins_cost(INSN_COST); 10559 format %{ "neg $dst, $src\t# long" %} 10560 10561 ins_encode %{ 10562 __ neg(as_Register($dst$$reg), 10563 as_Register($src$$reg)); 10564 %} 10565 10566 ins_pipe(ialu_reg); 10567 %} 10568 10569 // Integer Multiply 10570 10571 instruct mulI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10572 match(Set dst (MulI src1 src2)); 10573 10574 ins_cost(INSN_COST * 3); 10575 format %{ "mulw $dst, $src1, $src2" %} 10576 10577 ins_encode %{ 10578 __ mulw(as_Register($dst$$reg), 10579 as_Register($src1$$reg), 10580 as_Register($src2$$reg)); 10581 %} 10582 10583 ins_pipe(imul_reg_reg); 10584 %} 10585 10586 instruct smulI(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10587 match(Set dst (MulL (ConvI2L src1) (ConvI2L src2))); 10588 10589 ins_cost(INSN_COST * 3); 10590 format %{ "smull $dst, $src1, $src2" %} 10591 10592 ins_encode %{ 10593 __ smull(as_Register($dst$$reg), 10594 as_Register($src1$$reg), 10595 as_Register($src2$$reg)); 10596 %} 10597 10598 ins_pipe(imul_reg_reg); 10599 %} 10600 10601 // Long Multiply 10602 10603 instruct mulL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10604 match(Set dst (MulL src1 src2)); 10605 10606 ins_cost(INSN_COST * 5); 10607 format %{ "mul $dst, $src1, $src2" %} 10608 10609 ins_encode %{ 10610 __ mul(as_Register($dst$$reg), 10611 as_Register($src1$$reg), 10612 as_Register($src2$$reg)); 10613 %} 10614 10615 ins_pipe(lmul_reg_reg); 10616 %} 10617 10618 instruct mulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10619 %{ 10620 match(Set dst (MulHiL src1 src2)); 10621 10622 ins_cost(INSN_COST * 7); 10623 format %{ "smulh $dst, $src1, $src2\t# mulhi" %} 10624 10625 ins_encode %{ 10626 __ smulh(as_Register($dst$$reg), 10627 as_Register($src1$$reg), 10628 as_Register($src2$$reg)); 10629 %} 10630 10631 ins_pipe(lmul_reg_reg); 10632 %} 10633 10634 instruct umulHiL_rReg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) 10635 %{ 10636 match(Set dst (UMulHiL src1 src2)); 10637 10638 ins_cost(INSN_COST * 7); 10639 format %{ "umulh $dst, $src1, $src2\t# umulhi" %} 10640 10641 ins_encode %{ 10642 __ umulh(as_Register($dst$$reg), 10643 as_Register($src1$$reg), 10644 as_Register($src2$$reg)); 10645 %} 10646 10647 ins_pipe(lmul_reg_reg); 10648 %} 10649 10650 // Combined Integer Multiply & Add/Sub 10651 10652 instruct maddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10653 match(Set dst (AddI src3 (MulI src1 src2))); 10654 10655 ins_cost(INSN_COST * 3); 10656 format %{ "madd $dst, $src1, $src2, $src3" %} 10657 10658 ins_encode %{ 10659 __ maddw(as_Register($dst$$reg), 10660 as_Register($src1$$reg), 10661 as_Register($src2$$reg), 10662 as_Register($src3$$reg)); 10663 %} 10664 10665 ins_pipe(imac_reg_reg); 10666 %} 10667 10668 instruct msubI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3) %{ 10669 match(Set dst (SubI src3 (MulI src1 src2))); 10670 10671 ins_cost(INSN_COST * 3); 10672 format %{ "msub $dst, $src1, $src2, $src3" %} 10673 10674 ins_encode %{ 10675 __ msubw(as_Register($dst$$reg), 10676 as_Register($src1$$reg), 10677 as_Register($src2$$reg), 10678 as_Register($src3$$reg)); 10679 %} 10680 10681 ins_pipe(imac_reg_reg); 10682 %} 10683 10684 // Combined Integer Multiply & Neg 10685 10686 instruct mnegI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI0 zero) %{ 10687 match(Set dst (MulI (SubI zero src1) src2)); 10688 10689 ins_cost(INSN_COST * 3); 10690 format %{ "mneg $dst, $src1, $src2" %} 10691 10692 ins_encode %{ 10693 __ mnegw(as_Register($dst$$reg), 10694 as_Register($src1$$reg), 10695 as_Register($src2$$reg)); 10696 %} 10697 10698 ins_pipe(imac_reg_reg); 10699 %} 10700 10701 // Combined Long Multiply & Add/Sub 10702 10703 instruct maddL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10704 match(Set dst (AddL src3 (MulL src1 src2))); 10705 10706 ins_cost(INSN_COST * 5); 10707 format %{ "madd $dst, $src1, $src2, $src3" %} 10708 10709 ins_encode %{ 10710 __ madd(as_Register($dst$$reg), 10711 as_Register($src1$$reg), 10712 as_Register($src2$$reg), 10713 as_Register($src3$$reg)); 10714 %} 10715 10716 ins_pipe(lmac_reg_reg); 10717 %} 10718 10719 instruct msubL(iRegLNoSp dst, iRegL src1, iRegL src2, iRegL src3) %{ 10720 match(Set dst (SubL src3 (MulL src1 src2))); 10721 10722 ins_cost(INSN_COST * 5); 10723 format %{ "msub $dst, $src1, $src2, $src3" %} 10724 10725 ins_encode %{ 10726 __ msub(as_Register($dst$$reg), 10727 as_Register($src1$$reg), 10728 as_Register($src2$$reg), 10729 as_Register($src3$$reg)); 10730 %} 10731 10732 ins_pipe(lmac_reg_reg); 10733 %} 10734 10735 // Combined Long Multiply & Neg 10736 10737 instruct mnegL(iRegLNoSp dst, iRegL src1, iRegL src2, immL0 zero) %{ 10738 match(Set dst (MulL (SubL zero src1) src2)); 10739 10740 ins_cost(INSN_COST * 5); 10741 format %{ "mneg $dst, $src1, $src2" %} 10742 10743 ins_encode %{ 10744 __ mneg(as_Register($dst$$reg), 10745 as_Register($src1$$reg), 10746 as_Register($src2$$reg)); 10747 %} 10748 10749 ins_pipe(lmac_reg_reg); 10750 %} 10751 10752 // Combine Integer Signed Multiply & Add/Sub/Neg Long 10753 10754 instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10755 match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10756 10757 ins_cost(INSN_COST * 3); 10758 format %{ "smaddl $dst, $src1, $src2, $src3" %} 10759 10760 ins_encode %{ 10761 __ smaddl(as_Register($dst$$reg), 10762 as_Register($src1$$reg), 10763 as_Register($src2$$reg), 10764 as_Register($src3$$reg)); 10765 %} 10766 10767 ins_pipe(imac_reg_reg); 10768 %} 10769 10770 instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ 10771 match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); 10772 10773 ins_cost(INSN_COST * 3); 10774 format %{ "smsubl $dst, $src1, $src2, $src3" %} 10775 10776 ins_encode %{ 10777 __ smsubl(as_Register($dst$$reg), 10778 as_Register($src1$$reg), 10779 as_Register($src2$$reg), 10780 as_Register($src3$$reg)); 10781 %} 10782 10783 ins_pipe(imac_reg_reg); 10784 %} 10785 10786 instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ 10787 match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); 10788 10789 ins_cost(INSN_COST * 3); 10790 format %{ "smnegl $dst, $src1, $src2" %} 10791 10792 ins_encode %{ 10793 __ smnegl(as_Register($dst$$reg), 10794 as_Register($src1$$reg), 10795 as_Register($src2$$reg)); 10796 %} 10797 10798 ins_pipe(imac_reg_reg); 10799 %} 10800 10801 // Combined Multiply-Add Shorts into Integer (dst = src1 * src2 + src3 * src4) 10802 10803 instruct muladdS2I(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegIorL2I src3, iRegIorL2I src4) %{ 10804 match(Set dst (MulAddS2I (Binary src1 src2) (Binary src3 src4))); 10805 10806 ins_cost(INSN_COST * 5); 10807 format %{ "mulw rscratch1, $src1, $src2\n\t" 10808 "maddw $dst, $src3, $src4, rscratch1" %} 10809 10810 ins_encode %{ 10811 __ mulw(rscratch1, as_Register($src1$$reg), as_Register($src2$$reg)); 10812 __ maddw(as_Register($dst$$reg), as_Register($src3$$reg), as_Register($src4$$reg), rscratch1); %} 10813 10814 ins_pipe(imac_reg_reg); 10815 %} 10816 10817 // Integer Divide 10818 10819 instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10820 match(Set dst (DivI src1 src2)); 10821 10822 ins_cost(INSN_COST * 19); 10823 format %{ "sdivw $dst, $src1, $src2" %} 10824 10825 ins_encode(aarch64_enc_divw(dst, src1, src2)); 10826 ins_pipe(idiv_reg_reg); 10827 %} 10828 10829 // Long Divide 10830 10831 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10832 match(Set dst (DivL src1 src2)); 10833 10834 ins_cost(INSN_COST * 35); 10835 format %{ "sdiv $dst, $src1, $src2" %} 10836 10837 ins_encode(aarch64_enc_div(dst, src1, src2)); 10838 ins_pipe(ldiv_reg_reg); 10839 %} 10840 10841 // Integer Remainder 10842 10843 instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10844 match(Set dst (ModI src1 src2)); 10845 10846 ins_cost(INSN_COST * 22); 10847 format %{ "sdivw rscratch1, $src1, $src2\n\t" 10848 "msubw $dst, rscratch1, $src2, $src1" %} 10849 10850 ins_encode(aarch64_enc_modw(dst, src1, src2)); 10851 ins_pipe(idiv_reg_reg); 10852 %} 10853 10854 // Long Remainder 10855 10856 instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10857 match(Set dst (ModL src1 src2)); 10858 10859 ins_cost(INSN_COST * 38); 10860 format %{ "sdiv rscratch1, $src1, $src2\n" 10861 "msub $dst, rscratch1, $src2, $src1" %} 10862 10863 ins_encode(aarch64_enc_mod(dst, src1, src2)); 10864 ins_pipe(ldiv_reg_reg); 10865 %} 10866 10867 // Unsigned Integer Divide 10868 10869 instruct UdivI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10870 match(Set dst (UDivI src1 src2)); 10871 10872 ins_cost(INSN_COST * 19); 10873 format %{ "udivw $dst, $src1, $src2" %} 10874 10875 ins_encode %{ 10876 __ udivw($dst$$Register, $src1$$Register, $src2$$Register); 10877 %} 10878 10879 ins_pipe(idiv_reg_reg); 10880 %} 10881 10882 // Unsigned Long Divide 10883 10884 instruct UdivL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10885 match(Set dst (UDivL src1 src2)); 10886 10887 ins_cost(INSN_COST * 35); 10888 format %{ "udiv $dst, $src1, $src2" %} 10889 10890 ins_encode %{ 10891 __ udiv($dst$$Register, $src1$$Register, $src2$$Register); 10892 %} 10893 10894 ins_pipe(ldiv_reg_reg); 10895 %} 10896 10897 // Unsigned Integer Remainder 10898 10899 instruct UmodI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10900 match(Set dst (UModI src1 src2)); 10901 10902 ins_cost(INSN_COST * 22); 10903 format %{ "udivw rscratch1, $src1, $src2\n\t" 10904 "msubw $dst, rscratch1, $src2, $src1" %} 10905 10906 ins_encode %{ 10907 __ udivw(rscratch1, $src1$$Register, $src2$$Register); 10908 __ msubw($dst$$Register, rscratch1, $src2$$Register, $src1$$Register); 10909 %} 10910 10911 ins_pipe(idiv_reg_reg); 10912 %} 10913 10914 // Unsigned Long Remainder 10915 10916 instruct UModL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 10917 match(Set dst (UModL src1 src2)); 10918 10919 ins_cost(INSN_COST * 38); 10920 format %{ "udiv rscratch1, $src1, $src2\n" 10921 "msub $dst, rscratch1, $src2, $src1" %} 10922 10923 ins_encode %{ 10924 __ udiv(rscratch1, $src1$$Register, $src2$$Register); 10925 __ msub($dst$$Register, rscratch1, $src2$$Register, $src1$$Register); 10926 %} 10927 10928 ins_pipe(ldiv_reg_reg); 10929 %} 10930 10931 // Integer Shifts 10932 10933 // Shift Left Register 10934 instruct lShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10935 match(Set dst (LShiftI src1 src2)); 10936 10937 ins_cost(INSN_COST * 2); 10938 format %{ "lslvw $dst, $src1, $src2" %} 10939 10940 ins_encode %{ 10941 __ lslvw(as_Register($dst$$reg), 10942 as_Register($src1$$reg), 10943 as_Register($src2$$reg)); 10944 %} 10945 10946 ins_pipe(ialu_reg_reg_vshift); 10947 %} 10948 10949 // Shift Left Immediate 10950 instruct lShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10951 match(Set dst (LShiftI src1 src2)); 10952 10953 ins_cost(INSN_COST); 10954 format %{ "lslw $dst, $src1, ($src2 & 0x1f)" %} 10955 10956 ins_encode %{ 10957 __ lslw(as_Register($dst$$reg), 10958 as_Register($src1$$reg), 10959 $src2$$constant & 0x1f); 10960 %} 10961 10962 ins_pipe(ialu_reg_shift); 10963 %} 10964 10965 // Shift Right Logical Register 10966 instruct urShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10967 match(Set dst (URShiftI src1 src2)); 10968 10969 ins_cost(INSN_COST * 2); 10970 format %{ "lsrvw $dst, $src1, $src2" %} 10971 10972 ins_encode %{ 10973 __ lsrvw(as_Register($dst$$reg), 10974 as_Register($src1$$reg), 10975 as_Register($src2$$reg)); 10976 %} 10977 10978 ins_pipe(ialu_reg_reg_vshift); 10979 %} 10980 10981 // Shift Right Logical Immediate 10982 instruct urShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 10983 match(Set dst (URShiftI src1 src2)); 10984 10985 ins_cost(INSN_COST); 10986 format %{ "lsrw $dst, $src1, ($src2 & 0x1f)" %} 10987 10988 ins_encode %{ 10989 __ lsrw(as_Register($dst$$reg), 10990 as_Register($src1$$reg), 10991 $src2$$constant & 0x1f); 10992 %} 10993 10994 ins_pipe(ialu_reg_shift); 10995 %} 10996 10997 // Shift Right Arithmetic Register 10998 instruct rShiftI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 10999 match(Set dst (RShiftI src1 src2)); 11000 11001 ins_cost(INSN_COST * 2); 11002 format %{ "asrvw $dst, $src1, $src2" %} 11003 11004 ins_encode %{ 11005 __ asrvw(as_Register($dst$$reg), 11006 as_Register($src1$$reg), 11007 as_Register($src2$$reg)); 11008 %} 11009 11010 ins_pipe(ialu_reg_reg_vshift); 11011 %} 11012 11013 // Shift Right Arithmetic Immediate 11014 instruct rShiftI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immI src2) %{ 11015 match(Set dst (RShiftI src1 src2)); 11016 11017 ins_cost(INSN_COST); 11018 format %{ "asrw $dst, $src1, ($src2 & 0x1f)" %} 11019 11020 ins_encode %{ 11021 __ asrw(as_Register($dst$$reg), 11022 as_Register($src1$$reg), 11023 $src2$$constant & 0x1f); 11024 %} 11025 11026 ins_pipe(ialu_reg_shift); 11027 %} 11028 11029 // Combined Int Mask and Right Shift (using UBFM) 11030 // TODO 11031 11032 // Long Shifts 11033 11034 // Shift Left Register 11035 instruct lShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 11036 match(Set dst (LShiftL src1 src2)); 11037 11038 ins_cost(INSN_COST * 2); 11039 format %{ "lslv $dst, $src1, $src2" %} 11040 11041 ins_encode %{ 11042 __ lslv(as_Register($dst$$reg), 11043 as_Register($src1$$reg), 11044 as_Register($src2$$reg)); 11045 %} 11046 11047 ins_pipe(ialu_reg_reg_vshift); 11048 %} 11049 11050 // Shift Left Immediate 11051 instruct lShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11052 match(Set dst (LShiftL src1 src2)); 11053 11054 ins_cost(INSN_COST); 11055 format %{ "lsl $dst, $src1, ($src2 & 0x3f)" %} 11056 11057 ins_encode %{ 11058 __ lsl(as_Register($dst$$reg), 11059 as_Register($src1$$reg), 11060 $src2$$constant & 0x3f); 11061 %} 11062 11063 ins_pipe(ialu_reg_shift); 11064 %} 11065 11066 // Shift Right Logical Register 11067 instruct urShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 11068 match(Set dst (URShiftL src1 src2)); 11069 11070 ins_cost(INSN_COST * 2); 11071 format %{ "lsrv $dst, $src1, $src2" %} 11072 11073 ins_encode %{ 11074 __ lsrv(as_Register($dst$$reg), 11075 as_Register($src1$$reg), 11076 as_Register($src2$$reg)); 11077 %} 11078 11079 ins_pipe(ialu_reg_reg_vshift); 11080 %} 11081 11082 // Shift Right Logical Immediate 11083 instruct urShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11084 match(Set dst (URShiftL src1 src2)); 11085 11086 ins_cost(INSN_COST); 11087 format %{ "lsr $dst, $src1, ($src2 & 0x3f)" %} 11088 11089 ins_encode %{ 11090 __ lsr(as_Register($dst$$reg), 11091 as_Register($src1$$reg), 11092 $src2$$constant & 0x3f); 11093 %} 11094 11095 ins_pipe(ialu_reg_shift); 11096 %} 11097 11098 // A special-case pattern for card table stores. 11099 instruct urShiftP_reg_imm(iRegLNoSp dst, iRegP src1, immI src2) %{ 11100 match(Set dst (URShiftL (CastP2X src1) src2)); 11101 11102 ins_cost(INSN_COST); 11103 format %{ "lsr $dst, p2x($src1), ($src2 & 0x3f)" %} 11104 11105 ins_encode %{ 11106 __ lsr(as_Register($dst$$reg), 11107 as_Register($src1$$reg), 11108 $src2$$constant & 0x3f); 11109 %} 11110 11111 ins_pipe(ialu_reg_shift); 11112 %} 11113 11114 // Shift Right Arithmetic Register 11115 instruct rShiftL_reg_reg(iRegLNoSp dst, iRegL src1, iRegIorL2I src2) %{ 11116 match(Set dst (RShiftL src1 src2)); 11117 11118 ins_cost(INSN_COST * 2); 11119 format %{ "asrv $dst, $src1, $src2" %} 11120 11121 ins_encode %{ 11122 __ asrv(as_Register($dst$$reg), 11123 as_Register($src1$$reg), 11124 as_Register($src2$$reg)); 11125 %} 11126 11127 ins_pipe(ialu_reg_reg_vshift); 11128 %} 11129 11130 // Shift Right Arithmetic Immediate 11131 instruct rShiftL_reg_imm(iRegLNoSp dst, iRegL src1, immI src2) %{ 11132 match(Set dst (RShiftL src1 src2)); 11133 11134 ins_cost(INSN_COST); 11135 format %{ "asr $dst, $src1, ($src2 & 0x3f)" %} 11136 11137 ins_encode %{ 11138 __ asr(as_Register($dst$$reg), 11139 as_Register($src1$$reg), 11140 $src2$$constant & 0x3f); 11141 %} 11142 11143 ins_pipe(ialu_reg_shift); 11144 %} 11145 11146 // BEGIN This section of the file is automatically generated. Do not edit -------------- 11147 // This section is generated from aarch64_ad.m4 11148 11149 // This pattern is automatically generated from aarch64_ad.m4 11150 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11151 instruct regL_not_reg(iRegLNoSp dst, 11152 iRegL src1, immL_M1 m1, 11153 rFlagsReg cr) %{ 11154 match(Set dst (XorL src1 m1)); 11155 ins_cost(INSN_COST); 11156 format %{ "eon $dst, $src1, zr" %} 11157 11158 ins_encode %{ 11159 __ eon(as_Register($dst$$reg), 11160 as_Register($src1$$reg), 11161 zr, 11162 Assembler::LSL, 0); 11163 %} 11164 11165 ins_pipe(ialu_reg); 11166 %} 11167 11168 // This pattern is automatically generated from aarch64_ad.m4 11169 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11170 instruct regI_not_reg(iRegINoSp dst, 11171 iRegIorL2I src1, immI_M1 m1, 11172 rFlagsReg cr) %{ 11173 match(Set dst (XorI src1 m1)); 11174 ins_cost(INSN_COST); 11175 format %{ "eonw $dst, $src1, zr" %} 11176 11177 ins_encode %{ 11178 __ eonw(as_Register($dst$$reg), 11179 as_Register($src1$$reg), 11180 zr, 11181 Assembler::LSL, 0); 11182 %} 11183 11184 ins_pipe(ialu_reg); 11185 %} 11186 11187 // This pattern is automatically generated from aarch64_ad.m4 11188 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11189 instruct NegI_reg_URShift_reg(iRegINoSp dst, 11190 immI0 zero, iRegIorL2I src1, immI src2) %{ 11191 match(Set dst (SubI zero (URShiftI src1 src2))); 11192 11193 ins_cost(1.9 * INSN_COST); 11194 format %{ "negw $dst, $src1, LSR $src2" %} 11195 11196 ins_encode %{ 11197 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 11198 Assembler::LSR, $src2$$constant & 0x1f); 11199 %} 11200 11201 ins_pipe(ialu_reg_shift); 11202 %} 11203 11204 // This pattern is automatically generated from aarch64_ad.m4 11205 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11206 instruct NegI_reg_RShift_reg(iRegINoSp dst, 11207 immI0 zero, iRegIorL2I src1, immI src2) %{ 11208 match(Set dst (SubI zero (RShiftI src1 src2))); 11209 11210 ins_cost(1.9 * INSN_COST); 11211 format %{ "negw $dst, $src1, ASR $src2" %} 11212 11213 ins_encode %{ 11214 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 11215 Assembler::ASR, $src2$$constant & 0x1f); 11216 %} 11217 11218 ins_pipe(ialu_reg_shift); 11219 %} 11220 11221 // This pattern is automatically generated from aarch64_ad.m4 11222 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11223 instruct NegI_reg_LShift_reg(iRegINoSp dst, 11224 immI0 zero, iRegIorL2I src1, immI src2) %{ 11225 match(Set dst (SubI zero (LShiftI src1 src2))); 11226 11227 ins_cost(1.9 * INSN_COST); 11228 format %{ "negw $dst, $src1, LSL $src2" %} 11229 11230 ins_encode %{ 11231 __ negw(as_Register($dst$$reg), as_Register($src1$$reg), 11232 Assembler::LSL, $src2$$constant & 0x1f); 11233 %} 11234 11235 ins_pipe(ialu_reg_shift); 11236 %} 11237 11238 // This pattern is automatically generated from aarch64_ad.m4 11239 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11240 instruct NegL_reg_URShift_reg(iRegLNoSp dst, 11241 immL0 zero, iRegL src1, immI src2) %{ 11242 match(Set dst (SubL zero (URShiftL src1 src2))); 11243 11244 ins_cost(1.9 * INSN_COST); 11245 format %{ "neg $dst, $src1, LSR $src2" %} 11246 11247 ins_encode %{ 11248 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 11249 Assembler::LSR, $src2$$constant & 0x3f); 11250 %} 11251 11252 ins_pipe(ialu_reg_shift); 11253 %} 11254 11255 // This pattern is automatically generated from aarch64_ad.m4 11256 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11257 instruct NegL_reg_RShift_reg(iRegLNoSp dst, 11258 immL0 zero, iRegL src1, immI src2) %{ 11259 match(Set dst (SubL zero (RShiftL src1 src2))); 11260 11261 ins_cost(1.9 * INSN_COST); 11262 format %{ "neg $dst, $src1, ASR $src2" %} 11263 11264 ins_encode %{ 11265 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 11266 Assembler::ASR, $src2$$constant & 0x3f); 11267 %} 11268 11269 ins_pipe(ialu_reg_shift); 11270 %} 11271 11272 // This pattern is automatically generated from aarch64_ad.m4 11273 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11274 instruct NegL_reg_LShift_reg(iRegLNoSp dst, 11275 immL0 zero, iRegL src1, immI src2) %{ 11276 match(Set dst (SubL zero (LShiftL src1 src2))); 11277 11278 ins_cost(1.9 * INSN_COST); 11279 format %{ "neg $dst, $src1, LSL $src2" %} 11280 11281 ins_encode %{ 11282 __ neg(as_Register($dst$$reg), as_Register($src1$$reg), 11283 Assembler::LSL, $src2$$constant & 0x3f); 11284 %} 11285 11286 ins_pipe(ialu_reg_shift); 11287 %} 11288 11289 // This pattern is automatically generated from aarch64_ad.m4 11290 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11291 instruct AndI_reg_not_reg(iRegINoSp dst, 11292 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11293 match(Set dst (AndI src1 (XorI src2 m1))); 11294 ins_cost(INSN_COST); 11295 format %{ "bicw $dst, $src1, $src2" %} 11296 11297 ins_encode %{ 11298 __ bicw(as_Register($dst$$reg), 11299 as_Register($src1$$reg), 11300 as_Register($src2$$reg), 11301 Assembler::LSL, 0); 11302 %} 11303 11304 ins_pipe(ialu_reg_reg); 11305 %} 11306 11307 // This pattern is automatically generated from aarch64_ad.m4 11308 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11309 instruct AndL_reg_not_reg(iRegLNoSp dst, 11310 iRegL src1, iRegL src2, immL_M1 m1) %{ 11311 match(Set dst (AndL src1 (XorL src2 m1))); 11312 ins_cost(INSN_COST); 11313 format %{ "bic $dst, $src1, $src2" %} 11314 11315 ins_encode %{ 11316 __ bic(as_Register($dst$$reg), 11317 as_Register($src1$$reg), 11318 as_Register($src2$$reg), 11319 Assembler::LSL, 0); 11320 %} 11321 11322 ins_pipe(ialu_reg_reg); 11323 %} 11324 11325 // This pattern is automatically generated from aarch64_ad.m4 11326 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11327 instruct OrI_reg_not_reg(iRegINoSp dst, 11328 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11329 match(Set dst (OrI src1 (XorI src2 m1))); 11330 ins_cost(INSN_COST); 11331 format %{ "ornw $dst, $src1, $src2" %} 11332 11333 ins_encode %{ 11334 __ ornw(as_Register($dst$$reg), 11335 as_Register($src1$$reg), 11336 as_Register($src2$$reg), 11337 Assembler::LSL, 0); 11338 %} 11339 11340 ins_pipe(ialu_reg_reg); 11341 %} 11342 11343 // This pattern is automatically generated from aarch64_ad.m4 11344 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11345 instruct OrL_reg_not_reg(iRegLNoSp dst, 11346 iRegL src1, iRegL src2, immL_M1 m1) %{ 11347 match(Set dst (OrL src1 (XorL src2 m1))); 11348 ins_cost(INSN_COST); 11349 format %{ "orn $dst, $src1, $src2" %} 11350 11351 ins_encode %{ 11352 __ orn(as_Register($dst$$reg), 11353 as_Register($src1$$reg), 11354 as_Register($src2$$reg), 11355 Assembler::LSL, 0); 11356 %} 11357 11358 ins_pipe(ialu_reg_reg); 11359 %} 11360 11361 // This pattern is automatically generated from aarch64_ad.m4 11362 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11363 instruct XorI_reg_not_reg(iRegINoSp dst, 11364 iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ 11365 match(Set dst (XorI m1 (XorI src2 src1))); 11366 ins_cost(INSN_COST); 11367 format %{ "eonw $dst, $src1, $src2" %} 11368 11369 ins_encode %{ 11370 __ eonw(as_Register($dst$$reg), 11371 as_Register($src1$$reg), 11372 as_Register($src2$$reg), 11373 Assembler::LSL, 0); 11374 %} 11375 11376 ins_pipe(ialu_reg_reg); 11377 %} 11378 11379 // This pattern is automatically generated from aarch64_ad.m4 11380 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11381 instruct XorL_reg_not_reg(iRegLNoSp dst, 11382 iRegL src1, iRegL src2, immL_M1 m1) %{ 11383 match(Set dst (XorL m1 (XorL src2 src1))); 11384 ins_cost(INSN_COST); 11385 format %{ "eon $dst, $src1, $src2" %} 11386 11387 ins_encode %{ 11388 __ eon(as_Register($dst$$reg), 11389 as_Register($src1$$reg), 11390 as_Register($src2$$reg), 11391 Assembler::LSL, 0); 11392 %} 11393 11394 ins_pipe(ialu_reg_reg); 11395 %} 11396 11397 // This pattern is automatically generated from aarch64_ad.m4 11398 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11399 // val & (-1 ^ (val >>> shift)) ==> bicw 11400 instruct AndI_reg_URShift_not_reg(iRegINoSp dst, 11401 iRegIorL2I src1, iRegIorL2I src2, 11402 immI src3, immI_M1 src4) %{ 11403 match(Set dst (AndI src1 (XorI(URShiftI src2 src3) src4))); 11404 ins_cost(1.9 * INSN_COST); 11405 format %{ "bicw $dst, $src1, $src2, LSR $src3" %} 11406 11407 ins_encode %{ 11408 __ bicw(as_Register($dst$$reg), 11409 as_Register($src1$$reg), 11410 as_Register($src2$$reg), 11411 Assembler::LSR, 11412 $src3$$constant & 0x1f); 11413 %} 11414 11415 ins_pipe(ialu_reg_reg_shift); 11416 %} 11417 11418 // This pattern is automatically generated from aarch64_ad.m4 11419 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11420 // val & (-1 ^ (val >>> shift)) ==> bic 11421 instruct AndL_reg_URShift_not_reg(iRegLNoSp dst, 11422 iRegL src1, iRegL src2, 11423 immI src3, immL_M1 src4) %{ 11424 match(Set dst (AndL src1 (XorL(URShiftL src2 src3) src4))); 11425 ins_cost(1.9 * INSN_COST); 11426 format %{ "bic $dst, $src1, $src2, LSR $src3" %} 11427 11428 ins_encode %{ 11429 __ bic(as_Register($dst$$reg), 11430 as_Register($src1$$reg), 11431 as_Register($src2$$reg), 11432 Assembler::LSR, 11433 $src3$$constant & 0x3f); 11434 %} 11435 11436 ins_pipe(ialu_reg_reg_shift); 11437 %} 11438 11439 // This pattern is automatically generated from aarch64_ad.m4 11440 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11441 // val & (-1 ^ (val >> shift)) ==> bicw 11442 instruct AndI_reg_RShift_not_reg(iRegINoSp dst, 11443 iRegIorL2I src1, iRegIorL2I src2, 11444 immI src3, immI_M1 src4) %{ 11445 match(Set dst (AndI src1 (XorI(RShiftI src2 src3) src4))); 11446 ins_cost(1.9 * INSN_COST); 11447 format %{ "bicw $dst, $src1, $src2, ASR $src3" %} 11448 11449 ins_encode %{ 11450 __ bicw(as_Register($dst$$reg), 11451 as_Register($src1$$reg), 11452 as_Register($src2$$reg), 11453 Assembler::ASR, 11454 $src3$$constant & 0x1f); 11455 %} 11456 11457 ins_pipe(ialu_reg_reg_shift); 11458 %} 11459 11460 // This pattern is automatically generated from aarch64_ad.m4 11461 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11462 // val & (-1 ^ (val >> shift)) ==> bic 11463 instruct AndL_reg_RShift_not_reg(iRegLNoSp dst, 11464 iRegL src1, iRegL src2, 11465 immI src3, immL_M1 src4) %{ 11466 match(Set dst (AndL src1 (XorL(RShiftL src2 src3) src4))); 11467 ins_cost(1.9 * INSN_COST); 11468 format %{ "bic $dst, $src1, $src2, ASR $src3" %} 11469 11470 ins_encode %{ 11471 __ bic(as_Register($dst$$reg), 11472 as_Register($src1$$reg), 11473 as_Register($src2$$reg), 11474 Assembler::ASR, 11475 $src3$$constant & 0x3f); 11476 %} 11477 11478 ins_pipe(ialu_reg_reg_shift); 11479 %} 11480 11481 // This pattern is automatically generated from aarch64_ad.m4 11482 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11483 // val & (-1 ^ (val ror shift)) ==> bicw 11484 instruct AndI_reg_RotateRight_not_reg(iRegINoSp dst, 11485 iRegIorL2I src1, iRegIorL2I src2, 11486 immI src3, immI_M1 src4) %{ 11487 match(Set dst (AndI src1 (XorI(RotateRight src2 src3) src4))); 11488 ins_cost(1.9 * INSN_COST); 11489 format %{ "bicw $dst, $src1, $src2, ROR $src3" %} 11490 11491 ins_encode %{ 11492 __ bicw(as_Register($dst$$reg), 11493 as_Register($src1$$reg), 11494 as_Register($src2$$reg), 11495 Assembler::ROR, 11496 $src3$$constant & 0x1f); 11497 %} 11498 11499 ins_pipe(ialu_reg_reg_shift); 11500 %} 11501 11502 // This pattern is automatically generated from aarch64_ad.m4 11503 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11504 // val & (-1 ^ (val ror shift)) ==> bic 11505 instruct AndL_reg_RotateRight_not_reg(iRegLNoSp dst, 11506 iRegL src1, iRegL src2, 11507 immI src3, immL_M1 src4) %{ 11508 match(Set dst (AndL src1 (XorL(RotateRight src2 src3) src4))); 11509 ins_cost(1.9 * INSN_COST); 11510 format %{ "bic $dst, $src1, $src2, ROR $src3" %} 11511 11512 ins_encode %{ 11513 __ bic(as_Register($dst$$reg), 11514 as_Register($src1$$reg), 11515 as_Register($src2$$reg), 11516 Assembler::ROR, 11517 $src3$$constant & 0x3f); 11518 %} 11519 11520 ins_pipe(ialu_reg_reg_shift); 11521 %} 11522 11523 // This pattern is automatically generated from aarch64_ad.m4 11524 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11525 // val & (-1 ^ (val << shift)) ==> bicw 11526 instruct AndI_reg_LShift_not_reg(iRegINoSp dst, 11527 iRegIorL2I src1, iRegIorL2I src2, 11528 immI src3, immI_M1 src4) %{ 11529 match(Set dst (AndI src1 (XorI(LShiftI src2 src3) src4))); 11530 ins_cost(1.9 * INSN_COST); 11531 format %{ "bicw $dst, $src1, $src2, LSL $src3" %} 11532 11533 ins_encode %{ 11534 __ bicw(as_Register($dst$$reg), 11535 as_Register($src1$$reg), 11536 as_Register($src2$$reg), 11537 Assembler::LSL, 11538 $src3$$constant & 0x1f); 11539 %} 11540 11541 ins_pipe(ialu_reg_reg_shift); 11542 %} 11543 11544 // This pattern is automatically generated from aarch64_ad.m4 11545 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11546 // val & (-1 ^ (val << shift)) ==> bic 11547 instruct AndL_reg_LShift_not_reg(iRegLNoSp dst, 11548 iRegL src1, iRegL src2, 11549 immI src3, immL_M1 src4) %{ 11550 match(Set dst (AndL src1 (XorL(LShiftL src2 src3) src4))); 11551 ins_cost(1.9 * INSN_COST); 11552 format %{ "bic $dst, $src1, $src2, LSL $src3" %} 11553 11554 ins_encode %{ 11555 __ bic(as_Register($dst$$reg), 11556 as_Register($src1$$reg), 11557 as_Register($src2$$reg), 11558 Assembler::LSL, 11559 $src3$$constant & 0x3f); 11560 %} 11561 11562 ins_pipe(ialu_reg_reg_shift); 11563 %} 11564 11565 // This pattern is automatically generated from aarch64_ad.m4 11566 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11567 // val ^ (-1 ^ (val >>> shift)) ==> eonw 11568 instruct XorI_reg_URShift_not_reg(iRegINoSp dst, 11569 iRegIorL2I src1, iRegIorL2I src2, 11570 immI src3, immI_M1 src4) %{ 11571 match(Set dst (XorI src4 (XorI(URShiftI src2 src3) src1))); 11572 ins_cost(1.9 * INSN_COST); 11573 format %{ "eonw $dst, $src1, $src2, LSR $src3" %} 11574 11575 ins_encode %{ 11576 __ eonw(as_Register($dst$$reg), 11577 as_Register($src1$$reg), 11578 as_Register($src2$$reg), 11579 Assembler::LSR, 11580 $src3$$constant & 0x1f); 11581 %} 11582 11583 ins_pipe(ialu_reg_reg_shift); 11584 %} 11585 11586 // This pattern is automatically generated from aarch64_ad.m4 11587 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11588 // val ^ (-1 ^ (val >>> shift)) ==> eon 11589 instruct XorL_reg_URShift_not_reg(iRegLNoSp dst, 11590 iRegL src1, iRegL src2, 11591 immI src3, immL_M1 src4) %{ 11592 match(Set dst (XorL src4 (XorL(URShiftL src2 src3) src1))); 11593 ins_cost(1.9 * INSN_COST); 11594 format %{ "eon $dst, $src1, $src2, LSR $src3" %} 11595 11596 ins_encode %{ 11597 __ eon(as_Register($dst$$reg), 11598 as_Register($src1$$reg), 11599 as_Register($src2$$reg), 11600 Assembler::LSR, 11601 $src3$$constant & 0x3f); 11602 %} 11603 11604 ins_pipe(ialu_reg_reg_shift); 11605 %} 11606 11607 // This pattern is automatically generated from aarch64_ad.m4 11608 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11609 // val ^ (-1 ^ (val >> shift)) ==> eonw 11610 instruct XorI_reg_RShift_not_reg(iRegINoSp dst, 11611 iRegIorL2I src1, iRegIorL2I src2, 11612 immI src3, immI_M1 src4) %{ 11613 match(Set dst (XorI src4 (XorI(RShiftI src2 src3) src1))); 11614 ins_cost(1.9 * INSN_COST); 11615 format %{ "eonw $dst, $src1, $src2, ASR $src3" %} 11616 11617 ins_encode %{ 11618 __ eonw(as_Register($dst$$reg), 11619 as_Register($src1$$reg), 11620 as_Register($src2$$reg), 11621 Assembler::ASR, 11622 $src3$$constant & 0x1f); 11623 %} 11624 11625 ins_pipe(ialu_reg_reg_shift); 11626 %} 11627 11628 // This pattern is automatically generated from aarch64_ad.m4 11629 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11630 // val ^ (-1 ^ (val >> shift)) ==> eon 11631 instruct XorL_reg_RShift_not_reg(iRegLNoSp dst, 11632 iRegL src1, iRegL src2, 11633 immI src3, immL_M1 src4) %{ 11634 match(Set dst (XorL src4 (XorL(RShiftL src2 src3) src1))); 11635 ins_cost(1.9 * INSN_COST); 11636 format %{ "eon $dst, $src1, $src2, ASR $src3" %} 11637 11638 ins_encode %{ 11639 __ eon(as_Register($dst$$reg), 11640 as_Register($src1$$reg), 11641 as_Register($src2$$reg), 11642 Assembler::ASR, 11643 $src3$$constant & 0x3f); 11644 %} 11645 11646 ins_pipe(ialu_reg_reg_shift); 11647 %} 11648 11649 // This pattern is automatically generated from aarch64_ad.m4 11650 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11651 // val ^ (-1 ^ (val ror shift)) ==> eonw 11652 instruct XorI_reg_RotateRight_not_reg(iRegINoSp dst, 11653 iRegIorL2I src1, iRegIorL2I src2, 11654 immI src3, immI_M1 src4) %{ 11655 match(Set dst (XorI src4 (XorI(RotateRight src2 src3) src1))); 11656 ins_cost(1.9 * INSN_COST); 11657 format %{ "eonw $dst, $src1, $src2, ROR $src3" %} 11658 11659 ins_encode %{ 11660 __ eonw(as_Register($dst$$reg), 11661 as_Register($src1$$reg), 11662 as_Register($src2$$reg), 11663 Assembler::ROR, 11664 $src3$$constant & 0x1f); 11665 %} 11666 11667 ins_pipe(ialu_reg_reg_shift); 11668 %} 11669 11670 // This pattern is automatically generated from aarch64_ad.m4 11671 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11672 // val ^ (-1 ^ (val ror shift)) ==> eon 11673 instruct XorL_reg_RotateRight_not_reg(iRegLNoSp dst, 11674 iRegL src1, iRegL src2, 11675 immI src3, immL_M1 src4) %{ 11676 match(Set dst (XorL src4 (XorL(RotateRight src2 src3) src1))); 11677 ins_cost(1.9 * INSN_COST); 11678 format %{ "eon $dst, $src1, $src2, ROR $src3" %} 11679 11680 ins_encode %{ 11681 __ eon(as_Register($dst$$reg), 11682 as_Register($src1$$reg), 11683 as_Register($src2$$reg), 11684 Assembler::ROR, 11685 $src3$$constant & 0x3f); 11686 %} 11687 11688 ins_pipe(ialu_reg_reg_shift); 11689 %} 11690 11691 // This pattern is automatically generated from aarch64_ad.m4 11692 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11693 // val ^ (-1 ^ (val << shift)) ==> eonw 11694 instruct XorI_reg_LShift_not_reg(iRegINoSp dst, 11695 iRegIorL2I src1, iRegIorL2I src2, 11696 immI src3, immI_M1 src4) %{ 11697 match(Set dst (XorI src4 (XorI(LShiftI src2 src3) src1))); 11698 ins_cost(1.9 * INSN_COST); 11699 format %{ "eonw $dst, $src1, $src2, LSL $src3" %} 11700 11701 ins_encode %{ 11702 __ eonw(as_Register($dst$$reg), 11703 as_Register($src1$$reg), 11704 as_Register($src2$$reg), 11705 Assembler::LSL, 11706 $src3$$constant & 0x1f); 11707 %} 11708 11709 ins_pipe(ialu_reg_reg_shift); 11710 %} 11711 11712 // This pattern is automatically generated from aarch64_ad.m4 11713 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11714 // val ^ (-1 ^ (val << shift)) ==> eon 11715 instruct XorL_reg_LShift_not_reg(iRegLNoSp dst, 11716 iRegL src1, iRegL src2, 11717 immI src3, immL_M1 src4) %{ 11718 match(Set dst (XorL src4 (XorL(LShiftL src2 src3) src1))); 11719 ins_cost(1.9 * INSN_COST); 11720 format %{ "eon $dst, $src1, $src2, LSL $src3" %} 11721 11722 ins_encode %{ 11723 __ eon(as_Register($dst$$reg), 11724 as_Register($src1$$reg), 11725 as_Register($src2$$reg), 11726 Assembler::LSL, 11727 $src3$$constant & 0x3f); 11728 %} 11729 11730 ins_pipe(ialu_reg_reg_shift); 11731 %} 11732 11733 // This pattern is automatically generated from aarch64_ad.m4 11734 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11735 // val | (-1 ^ (val >>> shift)) ==> ornw 11736 instruct OrI_reg_URShift_not_reg(iRegINoSp dst, 11737 iRegIorL2I src1, iRegIorL2I src2, 11738 immI src3, immI_M1 src4) %{ 11739 match(Set dst (OrI src1 (XorI(URShiftI src2 src3) src4))); 11740 ins_cost(1.9 * INSN_COST); 11741 format %{ "ornw $dst, $src1, $src2, LSR $src3" %} 11742 11743 ins_encode %{ 11744 __ ornw(as_Register($dst$$reg), 11745 as_Register($src1$$reg), 11746 as_Register($src2$$reg), 11747 Assembler::LSR, 11748 $src3$$constant & 0x1f); 11749 %} 11750 11751 ins_pipe(ialu_reg_reg_shift); 11752 %} 11753 11754 // This pattern is automatically generated from aarch64_ad.m4 11755 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11756 // val | (-1 ^ (val >>> shift)) ==> orn 11757 instruct OrL_reg_URShift_not_reg(iRegLNoSp dst, 11758 iRegL src1, iRegL src2, 11759 immI src3, immL_M1 src4) %{ 11760 match(Set dst (OrL src1 (XorL(URShiftL src2 src3) src4))); 11761 ins_cost(1.9 * INSN_COST); 11762 format %{ "orn $dst, $src1, $src2, LSR $src3" %} 11763 11764 ins_encode %{ 11765 __ orn(as_Register($dst$$reg), 11766 as_Register($src1$$reg), 11767 as_Register($src2$$reg), 11768 Assembler::LSR, 11769 $src3$$constant & 0x3f); 11770 %} 11771 11772 ins_pipe(ialu_reg_reg_shift); 11773 %} 11774 11775 // This pattern is automatically generated from aarch64_ad.m4 11776 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11777 // val | (-1 ^ (val >> shift)) ==> ornw 11778 instruct OrI_reg_RShift_not_reg(iRegINoSp dst, 11779 iRegIorL2I src1, iRegIorL2I src2, 11780 immI src3, immI_M1 src4) %{ 11781 match(Set dst (OrI src1 (XorI(RShiftI src2 src3) src4))); 11782 ins_cost(1.9 * INSN_COST); 11783 format %{ "ornw $dst, $src1, $src2, ASR $src3" %} 11784 11785 ins_encode %{ 11786 __ ornw(as_Register($dst$$reg), 11787 as_Register($src1$$reg), 11788 as_Register($src2$$reg), 11789 Assembler::ASR, 11790 $src3$$constant & 0x1f); 11791 %} 11792 11793 ins_pipe(ialu_reg_reg_shift); 11794 %} 11795 11796 // This pattern is automatically generated from aarch64_ad.m4 11797 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11798 // val | (-1 ^ (val >> shift)) ==> orn 11799 instruct OrL_reg_RShift_not_reg(iRegLNoSp dst, 11800 iRegL src1, iRegL src2, 11801 immI src3, immL_M1 src4) %{ 11802 match(Set dst (OrL src1 (XorL(RShiftL src2 src3) src4))); 11803 ins_cost(1.9 * INSN_COST); 11804 format %{ "orn $dst, $src1, $src2, ASR $src3" %} 11805 11806 ins_encode %{ 11807 __ orn(as_Register($dst$$reg), 11808 as_Register($src1$$reg), 11809 as_Register($src2$$reg), 11810 Assembler::ASR, 11811 $src3$$constant & 0x3f); 11812 %} 11813 11814 ins_pipe(ialu_reg_reg_shift); 11815 %} 11816 11817 // This pattern is automatically generated from aarch64_ad.m4 11818 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11819 // val | (-1 ^ (val ror shift)) ==> ornw 11820 instruct OrI_reg_RotateRight_not_reg(iRegINoSp dst, 11821 iRegIorL2I src1, iRegIorL2I src2, 11822 immI src3, immI_M1 src4) %{ 11823 match(Set dst (OrI src1 (XorI(RotateRight src2 src3) src4))); 11824 ins_cost(1.9 * INSN_COST); 11825 format %{ "ornw $dst, $src1, $src2, ROR $src3" %} 11826 11827 ins_encode %{ 11828 __ ornw(as_Register($dst$$reg), 11829 as_Register($src1$$reg), 11830 as_Register($src2$$reg), 11831 Assembler::ROR, 11832 $src3$$constant & 0x1f); 11833 %} 11834 11835 ins_pipe(ialu_reg_reg_shift); 11836 %} 11837 11838 // This pattern is automatically generated from aarch64_ad.m4 11839 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11840 // val | (-1 ^ (val ror shift)) ==> orn 11841 instruct OrL_reg_RotateRight_not_reg(iRegLNoSp dst, 11842 iRegL src1, iRegL src2, 11843 immI src3, immL_M1 src4) %{ 11844 match(Set dst (OrL src1 (XorL(RotateRight src2 src3) src4))); 11845 ins_cost(1.9 * INSN_COST); 11846 format %{ "orn $dst, $src1, $src2, ROR $src3" %} 11847 11848 ins_encode %{ 11849 __ orn(as_Register($dst$$reg), 11850 as_Register($src1$$reg), 11851 as_Register($src2$$reg), 11852 Assembler::ROR, 11853 $src3$$constant & 0x3f); 11854 %} 11855 11856 ins_pipe(ialu_reg_reg_shift); 11857 %} 11858 11859 // This pattern is automatically generated from aarch64_ad.m4 11860 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11861 // val | (-1 ^ (val << shift)) ==> ornw 11862 instruct OrI_reg_LShift_not_reg(iRegINoSp dst, 11863 iRegIorL2I src1, iRegIorL2I src2, 11864 immI src3, immI_M1 src4) %{ 11865 match(Set dst (OrI src1 (XorI(LShiftI src2 src3) src4))); 11866 ins_cost(1.9 * INSN_COST); 11867 format %{ "ornw $dst, $src1, $src2, LSL $src3" %} 11868 11869 ins_encode %{ 11870 __ ornw(as_Register($dst$$reg), 11871 as_Register($src1$$reg), 11872 as_Register($src2$$reg), 11873 Assembler::LSL, 11874 $src3$$constant & 0x1f); 11875 %} 11876 11877 ins_pipe(ialu_reg_reg_shift); 11878 %} 11879 11880 // This pattern is automatically generated from aarch64_ad.m4 11881 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11882 // val | (-1 ^ (val << shift)) ==> orn 11883 instruct OrL_reg_LShift_not_reg(iRegLNoSp dst, 11884 iRegL src1, iRegL src2, 11885 immI src3, immL_M1 src4) %{ 11886 match(Set dst (OrL src1 (XorL(LShiftL src2 src3) src4))); 11887 ins_cost(1.9 * INSN_COST); 11888 format %{ "orn $dst, $src1, $src2, LSL $src3" %} 11889 11890 ins_encode %{ 11891 __ orn(as_Register($dst$$reg), 11892 as_Register($src1$$reg), 11893 as_Register($src2$$reg), 11894 Assembler::LSL, 11895 $src3$$constant & 0x3f); 11896 %} 11897 11898 ins_pipe(ialu_reg_reg_shift); 11899 %} 11900 11901 // This pattern is automatically generated from aarch64_ad.m4 11902 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11903 instruct AndI_reg_URShift_reg(iRegINoSp dst, 11904 iRegIorL2I src1, iRegIorL2I src2, 11905 immI src3) %{ 11906 match(Set dst (AndI src1 (URShiftI src2 src3))); 11907 11908 ins_cost(1.9 * INSN_COST); 11909 format %{ "andw $dst, $src1, $src2, LSR $src3" %} 11910 11911 ins_encode %{ 11912 __ andw(as_Register($dst$$reg), 11913 as_Register($src1$$reg), 11914 as_Register($src2$$reg), 11915 Assembler::LSR, 11916 $src3$$constant & 0x1f); 11917 %} 11918 11919 ins_pipe(ialu_reg_reg_shift); 11920 %} 11921 11922 // This pattern is automatically generated from aarch64_ad.m4 11923 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11924 instruct AndL_reg_URShift_reg(iRegLNoSp dst, 11925 iRegL src1, iRegL src2, 11926 immI src3) %{ 11927 match(Set dst (AndL src1 (URShiftL src2 src3))); 11928 11929 ins_cost(1.9 * INSN_COST); 11930 format %{ "andr $dst, $src1, $src2, LSR $src3" %} 11931 11932 ins_encode %{ 11933 __ andr(as_Register($dst$$reg), 11934 as_Register($src1$$reg), 11935 as_Register($src2$$reg), 11936 Assembler::LSR, 11937 $src3$$constant & 0x3f); 11938 %} 11939 11940 ins_pipe(ialu_reg_reg_shift); 11941 %} 11942 11943 // This pattern is automatically generated from aarch64_ad.m4 11944 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11945 instruct AndI_reg_RShift_reg(iRegINoSp dst, 11946 iRegIorL2I src1, iRegIorL2I src2, 11947 immI src3) %{ 11948 match(Set dst (AndI src1 (RShiftI src2 src3))); 11949 11950 ins_cost(1.9 * INSN_COST); 11951 format %{ "andw $dst, $src1, $src2, ASR $src3" %} 11952 11953 ins_encode %{ 11954 __ andw(as_Register($dst$$reg), 11955 as_Register($src1$$reg), 11956 as_Register($src2$$reg), 11957 Assembler::ASR, 11958 $src3$$constant & 0x1f); 11959 %} 11960 11961 ins_pipe(ialu_reg_reg_shift); 11962 %} 11963 11964 // This pattern is automatically generated from aarch64_ad.m4 11965 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11966 instruct AndL_reg_RShift_reg(iRegLNoSp dst, 11967 iRegL src1, iRegL src2, 11968 immI src3) %{ 11969 match(Set dst (AndL src1 (RShiftL src2 src3))); 11970 11971 ins_cost(1.9 * INSN_COST); 11972 format %{ "andr $dst, $src1, $src2, ASR $src3" %} 11973 11974 ins_encode %{ 11975 __ andr(as_Register($dst$$reg), 11976 as_Register($src1$$reg), 11977 as_Register($src2$$reg), 11978 Assembler::ASR, 11979 $src3$$constant & 0x3f); 11980 %} 11981 11982 ins_pipe(ialu_reg_reg_shift); 11983 %} 11984 11985 // This pattern is automatically generated from aarch64_ad.m4 11986 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 11987 instruct AndI_reg_LShift_reg(iRegINoSp dst, 11988 iRegIorL2I src1, iRegIorL2I src2, 11989 immI src3) %{ 11990 match(Set dst (AndI src1 (LShiftI src2 src3))); 11991 11992 ins_cost(1.9 * INSN_COST); 11993 format %{ "andw $dst, $src1, $src2, LSL $src3" %} 11994 11995 ins_encode %{ 11996 __ andw(as_Register($dst$$reg), 11997 as_Register($src1$$reg), 11998 as_Register($src2$$reg), 11999 Assembler::LSL, 12000 $src3$$constant & 0x1f); 12001 %} 12002 12003 ins_pipe(ialu_reg_reg_shift); 12004 %} 12005 12006 // This pattern is automatically generated from aarch64_ad.m4 12007 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12008 instruct AndL_reg_LShift_reg(iRegLNoSp dst, 12009 iRegL src1, iRegL src2, 12010 immI src3) %{ 12011 match(Set dst (AndL src1 (LShiftL src2 src3))); 12012 12013 ins_cost(1.9 * INSN_COST); 12014 format %{ "andr $dst, $src1, $src2, LSL $src3" %} 12015 12016 ins_encode %{ 12017 __ andr(as_Register($dst$$reg), 12018 as_Register($src1$$reg), 12019 as_Register($src2$$reg), 12020 Assembler::LSL, 12021 $src3$$constant & 0x3f); 12022 %} 12023 12024 ins_pipe(ialu_reg_reg_shift); 12025 %} 12026 12027 // This pattern is automatically generated from aarch64_ad.m4 12028 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12029 instruct AndI_reg_RotateRight_reg(iRegINoSp dst, 12030 iRegIorL2I src1, iRegIorL2I src2, 12031 immI src3) %{ 12032 match(Set dst (AndI src1 (RotateRight src2 src3))); 12033 12034 ins_cost(1.9 * INSN_COST); 12035 format %{ "andw $dst, $src1, $src2, ROR $src3" %} 12036 12037 ins_encode %{ 12038 __ andw(as_Register($dst$$reg), 12039 as_Register($src1$$reg), 12040 as_Register($src2$$reg), 12041 Assembler::ROR, 12042 $src3$$constant & 0x1f); 12043 %} 12044 12045 ins_pipe(ialu_reg_reg_shift); 12046 %} 12047 12048 // This pattern is automatically generated from aarch64_ad.m4 12049 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12050 instruct AndL_reg_RotateRight_reg(iRegLNoSp dst, 12051 iRegL src1, iRegL src2, 12052 immI src3) %{ 12053 match(Set dst (AndL src1 (RotateRight src2 src3))); 12054 12055 ins_cost(1.9 * INSN_COST); 12056 format %{ "andr $dst, $src1, $src2, ROR $src3" %} 12057 12058 ins_encode %{ 12059 __ andr(as_Register($dst$$reg), 12060 as_Register($src1$$reg), 12061 as_Register($src2$$reg), 12062 Assembler::ROR, 12063 $src3$$constant & 0x3f); 12064 %} 12065 12066 ins_pipe(ialu_reg_reg_shift); 12067 %} 12068 12069 // This pattern is automatically generated from aarch64_ad.m4 12070 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12071 instruct XorI_reg_URShift_reg(iRegINoSp dst, 12072 iRegIorL2I src1, iRegIorL2I src2, 12073 immI src3) %{ 12074 match(Set dst (XorI src1 (URShiftI src2 src3))); 12075 12076 ins_cost(1.9 * INSN_COST); 12077 format %{ "eorw $dst, $src1, $src2, LSR $src3" %} 12078 12079 ins_encode %{ 12080 __ eorw(as_Register($dst$$reg), 12081 as_Register($src1$$reg), 12082 as_Register($src2$$reg), 12083 Assembler::LSR, 12084 $src3$$constant & 0x1f); 12085 %} 12086 12087 ins_pipe(ialu_reg_reg_shift); 12088 %} 12089 12090 // This pattern is automatically generated from aarch64_ad.m4 12091 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12092 instruct XorL_reg_URShift_reg(iRegLNoSp dst, 12093 iRegL src1, iRegL src2, 12094 immI src3) %{ 12095 match(Set dst (XorL src1 (URShiftL src2 src3))); 12096 12097 ins_cost(1.9 * INSN_COST); 12098 format %{ "eor $dst, $src1, $src2, LSR $src3" %} 12099 12100 ins_encode %{ 12101 __ eor(as_Register($dst$$reg), 12102 as_Register($src1$$reg), 12103 as_Register($src2$$reg), 12104 Assembler::LSR, 12105 $src3$$constant & 0x3f); 12106 %} 12107 12108 ins_pipe(ialu_reg_reg_shift); 12109 %} 12110 12111 // This pattern is automatically generated from aarch64_ad.m4 12112 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12113 instruct XorI_reg_RShift_reg(iRegINoSp dst, 12114 iRegIorL2I src1, iRegIorL2I src2, 12115 immI src3) %{ 12116 match(Set dst (XorI src1 (RShiftI src2 src3))); 12117 12118 ins_cost(1.9 * INSN_COST); 12119 format %{ "eorw $dst, $src1, $src2, ASR $src3" %} 12120 12121 ins_encode %{ 12122 __ eorw(as_Register($dst$$reg), 12123 as_Register($src1$$reg), 12124 as_Register($src2$$reg), 12125 Assembler::ASR, 12126 $src3$$constant & 0x1f); 12127 %} 12128 12129 ins_pipe(ialu_reg_reg_shift); 12130 %} 12131 12132 // This pattern is automatically generated from aarch64_ad.m4 12133 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12134 instruct XorL_reg_RShift_reg(iRegLNoSp dst, 12135 iRegL src1, iRegL src2, 12136 immI src3) %{ 12137 match(Set dst (XorL src1 (RShiftL src2 src3))); 12138 12139 ins_cost(1.9 * INSN_COST); 12140 format %{ "eor $dst, $src1, $src2, ASR $src3" %} 12141 12142 ins_encode %{ 12143 __ eor(as_Register($dst$$reg), 12144 as_Register($src1$$reg), 12145 as_Register($src2$$reg), 12146 Assembler::ASR, 12147 $src3$$constant & 0x3f); 12148 %} 12149 12150 ins_pipe(ialu_reg_reg_shift); 12151 %} 12152 12153 // This pattern is automatically generated from aarch64_ad.m4 12154 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12155 instruct XorI_reg_LShift_reg(iRegINoSp dst, 12156 iRegIorL2I src1, iRegIorL2I src2, 12157 immI src3) %{ 12158 match(Set dst (XorI src1 (LShiftI src2 src3))); 12159 12160 ins_cost(1.9 * INSN_COST); 12161 format %{ "eorw $dst, $src1, $src2, LSL $src3" %} 12162 12163 ins_encode %{ 12164 __ eorw(as_Register($dst$$reg), 12165 as_Register($src1$$reg), 12166 as_Register($src2$$reg), 12167 Assembler::LSL, 12168 $src3$$constant & 0x1f); 12169 %} 12170 12171 ins_pipe(ialu_reg_reg_shift); 12172 %} 12173 12174 // This pattern is automatically generated from aarch64_ad.m4 12175 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12176 instruct XorL_reg_LShift_reg(iRegLNoSp dst, 12177 iRegL src1, iRegL src2, 12178 immI src3) %{ 12179 match(Set dst (XorL src1 (LShiftL src2 src3))); 12180 12181 ins_cost(1.9 * INSN_COST); 12182 format %{ "eor $dst, $src1, $src2, LSL $src3" %} 12183 12184 ins_encode %{ 12185 __ eor(as_Register($dst$$reg), 12186 as_Register($src1$$reg), 12187 as_Register($src2$$reg), 12188 Assembler::LSL, 12189 $src3$$constant & 0x3f); 12190 %} 12191 12192 ins_pipe(ialu_reg_reg_shift); 12193 %} 12194 12195 // This pattern is automatically generated from aarch64_ad.m4 12196 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12197 instruct XorI_reg_RotateRight_reg(iRegINoSp dst, 12198 iRegIorL2I src1, iRegIorL2I src2, 12199 immI src3) %{ 12200 match(Set dst (XorI src1 (RotateRight src2 src3))); 12201 12202 ins_cost(1.9 * INSN_COST); 12203 format %{ "eorw $dst, $src1, $src2, ROR $src3" %} 12204 12205 ins_encode %{ 12206 __ eorw(as_Register($dst$$reg), 12207 as_Register($src1$$reg), 12208 as_Register($src2$$reg), 12209 Assembler::ROR, 12210 $src3$$constant & 0x1f); 12211 %} 12212 12213 ins_pipe(ialu_reg_reg_shift); 12214 %} 12215 12216 // This pattern is automatically generated from aarch64_ad.m4 12217 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12218 instruct XorL_reg_RotateRight_reg(iRegLNoSp dst, 12219 iRegL src1, iRegL src2, 12220 immI src3) %{ 12221 match(Set dst (XorL src1 (RotateRight src2 src3))); 12222 12223 ins_cost(1.9 * INSN_COST); 12224 format %{ "eor $dst, $src1, $src2, ROR $src3" %} 12225 12226 ins_encode %{ 12227 __ eor(as_Register($dst$$reg), 12228 as_Register($src1$$reg), 12229 as_Register($src2$$reg), 12230 Assembler::ROR, 12231 $src3$$constant & 0x3f); 12232 %} 12233 12234 ins_pipe(ialu_reg_reg_shift); 12235 %} 12236 12237 // This pattern is automatically generated from aarch64_ad.m4 12238 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12239 instruct OrI_reg_URShift_reg(iRegINoSp dst, 12240 iRegIorL2I src1, iRegIorL2I src2, 12241 immI src3) %{ 12242 match(Set dst (OrI src1 (URShiftI src2 src3))); 12243 12244 ins_cost(1.9 * INSN_COST); 12245 format %{ "orrw $dst, $src1, $src2, LSR $src3" %} 12246 12247 ins_encode %{ 12248 __ orrw(as_Register($dst$$reg), 12249 as_Register($src1$$reg), 12250 as_Register($src2$$reg), 12251 Assembler::LSR, 12252 $src3$$constant & 0x1f); 12253 %} 12254 12255 ins_pipe(ialu_reg_reg_shift); 12256 %} 12257 12258 // This pattern is automatically generated from aarch64_ad.m4 12259 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12260 instruct OrL_reg_URShift_reg(iRegLNoSp dst, 12261 iRegL src1, iRegL src2, 12262 immI src3) %{ 12263 match(Set dst (OrL src1 (URShiftL src2 src3))); 12264 12265 ins_cost(1.9 * INSN_COST); 12266 format %{ "orr $dst, $src1, $src2, LSR $src3" %} 12267 12268 ins_encode %{ 12269 __ orr(as_Register($dst$$reg), 12270 as_Register($src1$$reg), 12271 as_Register($src2$$reg), 12272 Assembler::LSR, 12273 $src3$$constant & 0x3f); 12274 %} 12275 12276 ins_pipe(ialu_reg_reg_shift); 12277 %} 12278 12279 // This pattern is automatically generated from aarch64_ad.m4 12280 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12281 instruct OrI_reg_RShift_reg(iRegINoSp dst, 12282 iRegIorL2I src1, iRegIorL2I src2, 12283 immI src3) %{ 12284 match(Set dst (OrI src1 (RShiftI src2 src3))); 12285 12286 ins_cost(1.9 * INSN_COST); 12287 format %{ "orrw $dst, $src1, $src2, ASR $src3" %} 12288 12289 ins_encode %{ 12290 __ orrw(as_Register($dst$$reg), 12291 as_Register($src1$$reg), 12292 as_Register($src2$$reg), 12293 Assembler::ASR, 12294 $src3$$constant & 0x1f); 12295 %} 12296 12297 ins_pipe(ialu_reg_reg_shift); 12298 %} 12299 12300 // This pattern is automatically generated from aarch64_ad.m4 12301 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12302 instruct OrL_reg_RShift_reg(iRegLNoSp dst, 12303 iRegL src1, iRegL src2, 12304 immI src3) %{ 12305 match(Set dst (OrL src1 (RShiftL src2 src3))); 12306 12307 ins_cost(1.9 * INSN_COST); 12308 format %{ "orr $dst, $src1, $src2, ASR $src3" %} 12309 12310 ins_encode %{ 12311 __ orr(as_Register($dst$$reg), 12312 as_Register($src1$$reg), 12313 as_Register($src2$$reg), 12314 Assembler::ASR, 12315 $src3$$constant & 0x3f); 12316 %} 12317 12318 ins_pipe(ialu_reg_reg_shift); 12319 %} 12320 12321 // This pattern is automatically generated from aarch64_ad.m4 12322 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12323 instruct OrI_reg_LShift_reg(iRegINoSp dst, 12324 iRegIorL2I src1, iRegIorL2I src2, 12325 immI src3) %{ 12326 match(Set dst (OrI src1 (LShiftI src2 src3))); 12327 12328 ins_cost(1.9 * INSN_COST); 12329 format %{ "orrw $dst, $src1, $src2, LSL $src3" %} 12330 12331 ins_encode %{ 12332 __ orrw(as_Register($dst$$reg), 12333 as_Register($src1$$reg), 12334 as_Register($src2$$reg), 12335 Assembler::LSL, 12336 $src3$$constant & 0x1f); 12337 %} 12338 12339 ins_pipe(ialu_reg_reg_shift); 12340 %} 12341 12342 // This pattern is automatically generated from aarch64_ad.m4 12343 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12344 instruct OrL_reg_LShift_reg(iRegLNoSp dst, 12345 iRegL src1, iRegL src2, 12346 immI src3) %{ 12347 match(Set dst (OrL src1 (LShiftL src2 src3))); 12348 12349 ins_cost(1.9 * INSN_COST); 12350 format %{ "orr $dst, $src1, $src2, LSL $src3" %} 12351 12352 ins_encode %{ 12353 __ orr(as_Register($dst$$reg), 12354 as_Register($src1$$reg), 12355 as_Register($src2$$reg), 12356 Assembler::LSL, 12357 $src3$$constant & 0x3f); 12358 %} 12359 12360 ins_pipe(ialu_reg_reg_shift); 12361 %} 12362 12363 // This pattern is automatically generated from aarch64_ad.m4 12364 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12365 instruct OrI_reg_RotateRight_reg(iRegINoSp dst, 12366 iRegIorL2I src1, iRegIorL2I src2, 12367 immI src3) %{ 12368 match(Set dst (OrI src1 (RotateRight src2 src3))); 12369 12370 ins_cost(1.9 * INSN_COST); 12371 format %{ "orrw $dst, $src1, $src2, ROR $src3" %} 12372 12373 ins_encode %{ 12374 __ orrw(as_Register($dst$$reg), 12375 as_Register($src1$$reg), 12376 as_Register($src2$$reg), 12377 Assembler::ROR, 12378 $src3$$constant & 0x1f); 12379 %} 12380 12381 ins_pipe(ialu_reg_reg_shift); 12382 %} 12383 12384 // This pattern is automatically generated from aarch64_ad.m4 12385 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12386 instruct OrL_reg_RotateRight_reg(iRegLNoSp dst, 12387 iRegL src1, iRegL src2, 12388 immI src3) %{ 12389 match(Set dst (OrL src1 (RotateRight src2 src3))); 12390 12391 ins_cost(1.9 * INSN_COST); 12392 format %{ "orr $dst, $src1, $src2, ROR $src3" %} 12393 12394 ins_encode %{ 12395 __ orr(as_Register($dst$$reg), 12396 as_Register($src1$$reg), 12397 as_Register($src2$$reg), 12398 Assembler::ROR, 12399 $src3$$constant & 0x3f); 12400 %} 12401 12402 ins_pipe(ialu_reg_reg_shift); 12403 %} 12404 12405 // This pattern is automatically generated from aarch64_ad.m4 12406 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12407 instruct AddI_reg_URShift_reg(iRegINoSp dst, 12408 iRegIorL2I src1, iRegIorL2I src2, 12409 immI src3) %{ 12410 match(Set dst (AddI src1 (URShiftI src2 src3))); 12411 12412 ins_cost(1.9 * INSN_COST); 12413 format %{ "addw $dst, $src1, $src2, LSR $src3" %} 12414 12415 ins_encode %{ 12416 __ addw(as_Register($dst$$reg), 12417 as_Register($src1$$reg), 12418 as_Register($src2$$reg), 12419 Assembler::LSR, 12420 $src3$$constant & 0x1f); 12421 %} 12422 12423 ins_pipe(ialu_reg_reg_shift); 12424 %} 12425 12426 // This pattern is automatically generated from aarch64_ad.m4 12427 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12428 instruct AddL_reg_URShift_reg(iRegLNoSp dst, 12429 iRegL src1, iRegL src2, 12430 immI src3) %{ 12431 match(Set dst (AddL src1 (URShiftL src2 src3))); 12432 12433 ins_cost(1.9 * INSN_COST); 12434 format %{ "add $dst, $src1, $src2, LSR $src3" %} 12435 12436 ins_encode %{ 12437 __ add(as_Register($dst$$reg), 12438 as_Register($src1$$reg), 12439 as_Register($src2$$reg), 12440 Assembler::LSR, 12441 $src3$$constant & 0x3f); 12442 %} 12443 12444 ins_pipe(ialu_reg_reg_shift); 12445 %} 12446 12447 // This pattern is automatically generated from aarch64_ad.m4 12448 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12449 instruct AddI_reg_RShift_reg(iRegINoSp dst, 12450 iRegIorL2I src1, iRegIorL2I src2, 12451 immI src3) %{ 12452 match(Set dst (AddI src1 (RShiftI src2 src3))); 12453 12454 ins_cost(1.9 * INSN_COST); 12455 format %{ "addw $dst, $src1, $src2, ASR $src3" %} 12456 12457 ins_encode %{ 12458 __ addw(as_Register($dst$$reg), 12459 as_Register($src1$$reg), 12460 as_Register($src2$$reg), 12461 Assembler::ASR, 12462 $src3$$constant & 0x1f); 12463 %} 12464 12465 ins_pipe(ialu_reg_reg_shift); 12466 %} 12467 12468 // This pattern is automatically generated from aarch64_ad.m4 12469 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12470 instruct AddL_reg_RShift_reg(iRegLNoSp dst, 12471 iRegL src1, iRegL src2, 12472 immI src3) %{ 12473 match(Set dst (AddL src1 (RShiftL src2 src3))); 12474 12475 ins_cost(1.9 * INSN_COST); 12476 format %{ "add $dst, $src1, $src2, ASR $src3" %} 12477 12478 ins_encode %{ 12479 __ add(as_Register($dst$$reg), 12480 as_Register($src1$$reg), 12481 as_Register($src2$$reg), 12482 Assembler::ASR, 12483 $src3$$constant & 0x3f); 12484 %} 12485 12486 ins_pipe(ialu_reg_reg_shift); 12487 %} 12488 12489 // This pattern is automatically generated from aarch64_ad.m4 12490 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12491 instruct AddI_reg_LShift_reg(iRegINoSp dst, 12492 iRegIorL2I src1, iRegIorL2I src2, 12493 immI src3) %{ 12494 match(Set dst (AddI src1 (LShiftI src2 src3))); 12495 12496 ins_cost(1.9 * INSN_COST); 12497 format %{ "addw $dst, $src1, $src2, LSL $src3" %} 12498 12499 ins_encode %{ 12500 __ addw(as_Register($dst$$reg), 12501 as_Register($src1$$reg), 12502 as_Register($src2$$reg), 12503 Assembler::LSL, 12504 $src3$$constant & 0x1f); 12505 %} 12506 12507 ins_pipe(ialu_reg_reg_shift); 12508 %} 12509 12510 // This pattern is automatically generated from aarch64_ad.m4 12511 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12512 instruct AddL_reg_LShift_reg(iRegLNoSp dst, 12513 iRegL src1, iRegL src2, 12514 immI src3) %{ 12515 match(Set dst (AddL src1 (LShiftL src2 src3))); 12516 12517 ins_cost(1.9 * INSN_COST); 12518 format %{ "add $dst, $src1, $src2, LSL $src3" %} 12519 12520 ins_encode %{ 12521 __ add(as_Register($dst$$reg), 12522 as_Register($src1$$reg), 12523 as_Register($src2$$reg), 12524 Assembler::LSL, 12525 $src3$$constant & 0x3f); 12526 %} 12527 12528 ins_pipe(ialu_reg_reg_shift); 12529 %} 12530 12531 // This pattern is automatically generated from aarch64_ad.m4 12532 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12533 instruct SubI_reg_URShift_reg(iRegINoSp dst, 12534 iRegIorL2I src1, iRegIorL2I src2, 12535 immI src3) %{ 12536 match(Set dst (SubI src1 (URShiftI src2 src3))); 12537 12538 ins_cost(1.9 * INSN_COST); 12539 format %{ "subw $dst, $src1, $src2, LSR $src3" %} 12540 12541 ins_encode %{ 12542 __ subw(as_Register($dst$$reg), 12543 as_Register($src1$$reg), 12544 as_Register($src2$$reg), 12545 Assembler::LSR, 12546 $src3$$constant & 0x1f); 12547 %} 12548 12549 ins_pipe(ialu_reg_reg_shift); 12550 %} 12551 12552 // This pattern is automatically generated from aarch64_ad.m4 12553 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12554 instruct SubL_reg_URShift_reg(iRegLNoSp dst, 12555 iRegL src1, iRegL src2, 12556 immI src3) %{ 12557 match(Set dst (SubL src1 (URShiftL src2 src3))); 12558 12559 ins_cost(1.9 * INSN_COST); 12560 format %{ "sub $dst, $src1, $src2, LSR $src3" %} 12561 12562 ins_encode %{ 12563 __ sub(as_Register($dst$$reg), 12564 as_Register($src1$$reg), 12565 as_Register($src2$$reg), 12566 Assembler::LSR, 12567 $src3$$constant & 0x3f); 12568 %} 12569 12570 ins_pipe(ialu_reg_reg_shift); 12571 %} 12572 12573 // This pattern is automatically generated from aarch64_ad.m4 12574 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12575 instruct SubI_reg_RShift_reg(iRegINoSp dst, 12576 iRegIorL2I src1, iRegIorL2I src2, 12577 immI src3) %{ 12578 match(Set dst (SubI src1 (RShiftI src2 src3))); 12579 12580 ins_cost(1.9 * INSN_COST); 12581 format %{ "subw $dst, $src1, $src2, ASR $src3" %} 12582 12583 ins_encode %{ 12584 __ subw(as_Register($dst$$reg), 12585 as_Register($src1$$reg), 12586 as_Register($src2$$reg), 12587 Assembler::ASR, 12588 $src3$$constant & 0x1f); 12589 %} 12590 12591 ins_pipe(ialu_reg_reg_shift); 12592 %} 12593 12594 // This pattern is automatically generated from aarch64_ad.m4 12595 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12596 instruct SubL_reg_RShift_reg(iRegLNoSp dst, 12597 iRegL src1, iRegL src2, 12598 immI src3) %{ 12599 match(Set dst (SubL src1 (RShiftL src2 src3))); 12600 12601 ins_cost(1.9 * INSN_COST); 12602 format %{ "sub $dst, $src1, $src2, ASR $src3" %} 12603 12604 ins_encode %{ 12605 __ sub(as_Register($dst$$reg), 12606 as_Register($src1$$reg), 12607 as_Register($src2$$reg), 12608 Assembler::ASR, 12609 $src3$$constant & 0x3f); 12610 %} 12611 12612 ins_pipe(ialu_reg_reg_shift); 12613 %} 12614 12615 // This pattern is automatically generated from aarch64_ad.m4 12616 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12617 instruct SubI_reg_LShift_reg(iRegINoSp dst, 12618 iRegIorL2I src1, iRegIorL2I src2, 12619 immI src3) %{ 12620 match(Set dst (SubI src1 (LShiftI src2 src3))); 12621 12622 ins_cost(1.9 * INSN_COST); 12623 format %{ "subw $dst, $src1, $src2, LSL $src3" %} 12624 12625 ins_encode %{ 12626 __ subw(as_Register($dst$$reg), 12627 as_Register($src1$$reg), 12628 as_Register($src2$$reg), 12629 Assembler::LSL, 12630 $src3$$constant & 0x1f); 12631 %} 12632 12633 ins_pipe(ialu_reg_reg_shift); 12634 %} 12635 12636 // This pattern is automatically generated from aarch64_ad.m4 12637 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12638 instruct SubL_reg_LShift_reg(iRegLNoSp dst, 12639 iRegL src1, iRegL src2, 12640 immI src3) %{ 12641 match(Set dst (SubL src1 (LShiftL src2 src3))); 12642 12643 ins_cost(1.9 * INSN_COST); 12644 format %{ "sub $dst, $src1, $src2, LSL $src3" %} 12645 12646 ins_encode %{ 12647 __ sub(as_Register($dst$$reg), 12648 as_Register($src1$$reg), 12649 as_Register($src2$$reg), 12650 Assembler::LSL, 12651 $src3$$constant & 0x3f); 12652 %} 12653 12654 ins_pipe(ialu_reg_reg_shift); 12655 %} 12656 12657 // This pattern is automatically generated from aarch64_ad.m4 12658 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12659 12660 // Shift Left followed by Shift Right. 12661 // This idiom is used by the compiler for the i2b bytecode etc. 12662 instruct sbfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12663 %{ 12664 match(Set dst (RShiftL (LShiftL src lshift_count) rshift_count)); 12665 ins_cost(INSN_COST * 2); 12666 format %{ "sbfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12667 ins_encode %{ 12668 int lshift = $lshift_count$$constant & 63; 12669 int rshift = $rshift_count$$constant & 63; 12670 int s = 63 - lshift; 12671 int r = (rshift - lshift) & 63; 12672 __ sbfm(as_Register($dst$$reg), 12673 as_Register($src$$reg), 12674 r, s); 12675 %} 12676 12677 ins_pipe(ialu_reg_shift); 12678 %} 12679 12680 // This pattern is automatically generated from aarch64_ad.m4 12681 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12682 12683 // Shift Left followed by Shift Right. 12684 // This idiom is used by the compiler for the i2b bytecode etc. 12685 instruct sbfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12686 %{ 12687 match(Set dst (RShiftI (LShiftI src lshift_count) rshift_count)); 12688 ins_cost(INSN_COST * 2); 12689 format %{ "sbfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12690 ins_encode %{ 12691 int lshift = $lshift_count$$constant & 31; 12692 int rshift = $rshift_count$$constant & 31; 12693 int s = 31 - lshift; 12694 int r = (rshift - lshift) & 31; 12695 __ sbfmw(as_Register($dst$$reg), 12696 as_Register($src$$reg), 12697 r, s); 12698 %} 12699 12700 ins_pipe(ialu_reg_shift); 12701 %} 12702 12703 // This pattern is automatically generated from aarch64_ad.m4 12704 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12705 12706 // Shift Left followed by Shift Right. 12707 // This idiom is used by the compiler for the i2b bytecode etc. 12708 instruct ubfmL(iRegLNoSp dst, iRegL src, immI lshift_count, immI rshift_count) 12709 %{ 12710 match(Set dst (URShiftL (LShiftL src lshift_count) rshift_count)); 12711 ins_cost(INSN_COST * 2); 12712 format %{ "ubfm $dst, $src, $rshift_count - $lshift_count, #63 - $lshift_count" %} 12713 ins_encode %{ 12714 int lshift = $lshift_count$$constant & 63; 12715 int rshift = $rshift_count$$constant & 63; 12716 int s = 63 - lshift; 12717 int r = (rshift - lshift) & 63; 12718 __ ubfm(as_Register($dst$$reg), 12719 as_Register($src$$reg), 12720 r, s); 12721 %} 12722 12723 ins_pipe(ialu_reg_shift); 12724 %} 12725 12726 // This pattern is automatically generated from aarch64_ad.m4 12727 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12728 12729 // Shift Left followed by Shift Right. 12730 // This idiom is used by the compiler for the i2b bytecode etc. 12731 instruct ubfmwI(iRegINoSp dst, iRegIorL2I src, immI lshift_count, immI rshift_count) 12732 %{ 12733 match(Set dst (URShiftI (LShiftI src lshift_count) rshift_count)); 12734 ins_cost(INSN_COST * 2); 12735 format %{ "ubfmw $dst, $src, $rshift_count - $lshift_count, #31 - $lshift_count" %} 12736 ins_encode %{ 12737 int lshift = $lshift_count$$constant & 31; 12738 int rshift = $rshift_count$$constant & 31; 12739 int s = 31 - lshift; 12740 int r = (rshift - lshift) & 31; 12741 __ ubfmw(as_Register($dst$$reg), 12742 as_Register($src$$reg), 12743 r, s); 12744 %} 12745 12746 ins_pipe(ialu_reg_shift); 12747 %} 12748 12749 // Bitfield extract with shift & mask 12750 12751 // This pattern is automatically generated from aarch64_ad.m4 12752 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12753 instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12754 %{ 12755 match(Set dst (AndI (URShiftI src rshift) mask)); 12756 // Make sure we are not going to exceed what ubfxw can do. 12757 predicate((exact_log2(n->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12758 12759 ins_cost(INSN_COST); 12760 format %{ "ubfxw $dst, $src, $rshift, $mask" %} 12761 ins_encode %{ 12762 int rshift = $rshift$$constant & 31; 12763 intptr_t mask = $mask$$constant; 12764 int width = exact_log2(mask+1); 12765 __ ubfxw(as_Register($dst$$reg), 12766 as_Register($src$$reg), rshift, width); 12767 %} 12768 ins_pipe(ialu_reg_shift); 12769 %} 12770 12771 // This pattern is automatically generated from aarch64_ad.m4 12772 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12773 instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) 12774 %{ 12775 match(Set dst (AndL (URShiftL src rshift) mask)); 12776 // Make sure we are not going to exceed what ubfx can do. 12777 predicate((exact_log2_long(n->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= (63 + 1)); 12778 12779 ins_cost(INSN_COST); 12780 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12781 ins_encode %{ 12782 int rshift = $rshift$$constant & 63; 12783 intptr_t mask = $mask$$constant; 12784 int width = exact_log2_long(mask+1); 12785 __ ubfx(as_Register($dst$$reg), 12786 as_Register($src$$reg), rshift, width); 12787 %} 12788 ins_pipe(ialu_reg_shift); 12789 %} 12790 12791 12792 // This pattern is automatically generated from aarch64_ad.m4 12793 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12794 12795 // We can use ubfx when extending an And with a mask when we know mask 12796 // is positive. We know that because immI_bitmask guarantees it. 12797 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) 12798 %{ 12799 match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask))); 12800 // Make sure we are not going to exceed what ubfxw can do. 12801 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(1)->in(2)->get_int() & 31)) <= (31 + 1)); 12802 12803 ins_cost(INSN_COST * 2); 12804 format %{ "ubfx $dst, $src, $rshift, $mask" %} 12805 ins_encode %{ 12806 int rshift = $rshift$$constant & 31; 12807 intptr_t mask = $mask$$constant; 12808 int width = exact_log2(mask+1); 12809 __ ubfx(as_Register($dst$$reg), 12810 as_Register($src$$reg), rshift, width); 12811 %} 12812 ins_pipe(ialu_reg_shift); 12813 %} 12814 12815 12816 // This pattern is automatically generated from aarch64_ad.m4 12817 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12818 12819 // We can use ubfiz when masking by a positive number and then left shifting the result. 12820 // We know that the mask is positive because immI_bitmask guarantees it. 12821 instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12822 %{ 12823 match(Set dst (LShiftI (AndI src mask) lshift)); 12824 predicate((exact_log2(n->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 31)) <= (31 + 1)); 12825 12826 ins_cost(INSN_COST); 12827 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12828 ins_encode %{ 12829 int lshift = $lshift$$constant & 31; 12830 intptr_t mask = $mask$$constant; 12831 int width = exact_log2(mask+1); 12832 __ ubfizw(as_Register($dst$$reg), 12833 as_Register($src$$reg), lshift, width); 12834 %} 12835 ins_pipe(ialu_reg_shift); 12836 %} 12837 12838 // This pattern is automatically generated from aarch64_ad.m4 12839 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12840 12841 // We can use ubfiz when masking by a positive number and then left shifting the result. 12842 // We know that the mask is positive because immL_bitmask guarantees it. 12843 instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask) 12844 %{ 12845 match(Set dst (LShiftL (AndL src mask) lshift)); 12846 predicate((exact_log2_long(n->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12847 12848 ins_cost(INSN_COST); 12849 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12850 ins_encode %{ 12851 int lshift = $lshift$$constant & 63; 12852 intptr_t mask = $mask$$constant; 12853 int width = exact_log2_long(mask+1); 12854 __ ubfiz(as_Register($dst$$reg), 12855 as_Register($src$$reg), lshift, width); 12856 %} 12857 ins_pipe(ialu_reg_shift); 12858 %} 12859 12860 // This pattern is automatically generated from aarch64_ad.m4 12861 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12862 12863 // We can use ubfiz when masking by a positive number and then left shifting the result. 12864 // We know that the mask is positive because immI_bitmask guarantees it. 12865 instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12866 %{ 12867 match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift))); 12868 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31); 12869 12870 ins_cost(INSN_COST); 12871 format %{ "ubfizw $dst, $src, $lshift, $mask" %} 12872 ins_encode %{ 12873 int lshift = $lshift$$constant & 31; 12874 intptr_t mask = $mask$$constant; 12875 int width = exact_log2(mask+1); 12876 __ ubfizw(as_Register($dst$$reg), 12877 as_Register($src$$reg), lshift, width); 12878 %} 12879 ins_pipe(ialu_reg_shift); 12880 %} 12881 12882 // This pattern is automatically generated from aarch64_ad.m4 12883 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12884 12885 // We can use ubfiz when masking by a positive number and then left shifting the result. 12886 // We know that the mask is positive because immL_bitmask guarantees it. 12887 instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12888 %{ 12889 match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift))); 12890 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31); 12891 12892 ins_cost(INSN_COST); 12893 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12894 ins_encode %{ 12895 int lshift = $lshift$$constant & 63; 12896 intptr_t mask = $mask$$constant; 12897 int width = exact_log2_long(mask+1); 12898 __ ubfiz(as_Register($dst$$reg), 12899 as_Register($src$$reg), lshift, width); 12900 %} 12901 ins_pipe(ialu_reg_shift); 12902 %} 12903 12904 12905 // This pattern is automatically generated from aarch64_ad.m4 12906 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12907 12908 // If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz 12909 instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask) 12910 %{ 12911 match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift)); 12912 predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1)); 12913 12914 ins_cost(INSN_COST); 12915 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12916 ins_encode %{ 12917 int lshift = $lshift$$constant & 63; 12918 intptr_t mask = $mask$$constant; 12919 int width = exact_log2(mask+1); 12920 __ ubfiz(as_Register($dst$$reg), 12921 as_Register($src$$reg), lshift, width); 12922 %} 12923 ins_pipe(ialu_reg_shift); 12924 %} 12925 12926 // This pattern is automatically generated from aarch64_ad.m4 12927 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12928 12929 // If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz 12930 instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask) 12931 %{ 12932 match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift)); 12933 predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31); 12934 12935 ins_cost(INSN_COST); 12936 format %{ "ubfiz $dst, $src, $lshift, $mask" %} 12937 ins_encode %{ 12938 int lshift = $lshift$$constant & 31; 12939 intptr_t mask = $mask$$constant; 12940 int width = exact_log2(mask+1); 12941 __ ubfiz(as_Register($dst$$reg), 12942 as_Register($src$$reg), lshift, width); 12943 %} 12944 ins_pipe(ialu_reg_shift); 12945 %} 12946 12947 // This pattern is automatically generated from aarch64_ad.m4 12948 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12949 12950 // Can skip int2long conversions after AND with small bitmask 12951 instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk) 12952 %{ 12953 match(Set dst (ConvI2L (AndI src msk))); 12954 ins_cost(INSN_COST); 12955 format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %} 12956 ins_encode %{ 12957 __ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1)); 12958 %} 12959 ins_pipe(ialu_reg_shift); 12960 %} 12961 12962 12963 // Rotations 12964 12965 // This pattern is automatically generated from aarch64_ad.m4 12966 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12967 instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 12968 %{ 12969 match(Set dst (OrL (LShiftL src1 lshift) (URShiftL src2 rshift))); 12970 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 12971 12972 ins_cost(INSN_COST); 12973 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12974 12975 ins_encode %{ 12976 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12977 $rshift$$constant & 63); 12978 %} 12979 ins_pipe(ialu_reg_reg_extr); 12980 %} 12981 12982 12983 // This pattern is automatically generated from aarch64_ad.m4 12984 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 12985 instruct extrOrI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 12986 %{ 12987 match(Set dst (OrI (LShiftI src1 lshift) (URShiftI src2 rshift))); 12988 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 12989 12990 ins_cost(INSN_COST); 12991 format %{ "extr $dst, $src1, $src2, #$rshift" %} 12992 12993 ins_encode %{ 12994 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 12995 $rshift$$constant & 31); 12996 %} 12997 ins_pipe(ialu_reg_reg_extr); 12998 %} 12999 13000 13001 // This pattern is automatically generated from aarch64_ad.m4 13002 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13003 instruct extrAddL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr) 13004 %{ 13005 match(Set dst (AddL (LShiftL src1 lshift) (URShiftL src2 rshift))); 13006 predicate(0 == (((n->in(1)->in(2)->get_int() & 63) + (n->in(2)->in(2)->get_int() & 63)) & 63)); 13007 13008 ins_cost(INSN_COST); 13009 format %{ "extr $dst, $src1, $src2, #$rshift" %} 13010 13011 ins_encode %{ 13012 __ extr(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 13013 $rshift$$constant & 63); 13014 %} 13015 ins_pipe(ialu_reg_reg_extr); 13016 %} 13017 13018 13019 // This pattern is automatically generated from aarch64_ad.m4 13020 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13021 instruct extrAddI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI lshift, immI rshift, rFlagsReg cr) 13022 %{ 13023 match(Set dst (AddI (LShiftI src1 lshift) (URShiftI src2 rshift))); 13024 predicate(0 == (((n->in(1)->in(2)->get_int() & 31) + (n->in(2)->in(2)->get_int() & 31)) & 31)); 13025 13026 ins_cost(INSN_COST); 13027 format %{ "extr $dst, $src1, $src2, #$rshift" %} 13028 13029 ins_encode %{ 13030 __ extrw(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg), 13031 $rshift$$constant & 31); 13032 %} 13033 ins_pipe(ialu_reg_reg_extr); 13034 %} 13035 13036 // This pattern is automatically generated from aarch64_ad.m4 13037 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13038 instruct rorI_imm(iRegINoSp dst, iRegI src, immI shift) 13039 %{ 13040 match(Set dst (RotateRight src shift)); 13041 13042 ins_cost(INSN_COST); 13043 format %{ "ror $dst, $src, $shift" %} 13044 13045 ins_encode %{ 13046 __ extrw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg), 13047 $shift$$constant & 0x1f); 13048 %} 13049 ins_pipe(ialu_reg_reg_vshift); 13050 %} 13051 13052 // This pattern is automatically generated from aarch64_ad.m4 13053 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13054 instruct rorL_imm(iRegLNoSp dst, iRegL src, immI shift) 13055 %{ 13056 match(Set dst (RotateRight src shift)); 13057 13058 ins_cost(INSN_COST); 13059 format %{ "ror $dst, $src, $shift" %} 13060 13061 ins_encode %{ 13062 __ extr(as_Register($dst$$reg), as_Register($src$$reg), as_Register($src$$reg), 13063 $shift$$constant & 0x3f); 13064 %} 13065 ins_pipe(ialu_reg_reg_vshift); 13066 %} 13067 13068 // This pattern is automatically generated from aarch64_ad.m4 13069 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13070 instruct rorI_reg(iRegINoSp dst, iRegI src, iRegI shift) 13071 %{ 13072 match(Set dst (RotateRight src shift)); 13073 13074 ins_cost(INSN_COST); 13075 format %{ "ror $dst, $src, $shift" %} 13076 13077 ins_encode %{ 13078 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); 13079 %} 13080 ins_pipe(ialu_reg_reg_vshift); 13081 %} 13082 13083 // This pattern is automatically generated from aarch64_ad.m4 13084 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13085 instruct rorL_reg(iRegLNoSp dst, iRegL src, iRegI shift) 13086 %{ 13087 match(Set dst (RotateRight src shift)); 13088 13089 ins_cost(INSN_COST); 13090 format %{ "ror $dst, $src, $shift" %} 13091 13092 ins_encode %{ 13093 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), as_Register($shift$$reg)); 13094 %} 13095 ins_pipe(ialu_reg_reg_vshift); 13096 %} 13097 13098 // This pattern is automatically generated from aarch64_ad.m4 13099 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13100 instruct rolI_reg(iRegINoSp dst, iRegI src, iRegI shift) 13101 %{ 13102 match(Set dst (RotateLeft src shift)); 13103 13104 ins_cost(INSN_COST); 13105 format %{ "rol $dst, $src, $shift" %} 13106 13107 ins_encode %{ 13108 __ subw(rscratch1, zr, as_Register($shift$$reg)); 13109 __ rorvw(as_Register($dst$$reg), as_Register($src$$reg), rscratch1); 13110 %} 13111 ins_pipe(ialu_reg_reg_vshift); 13112 %} 13113 13114 // This pattern is automatically generated from aarch64_ad.m4 13115 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13116 instruct rolL_reg(iRegLNoSp dst, iRegL src, iRegI shift) 13117 %{ 13118 match(Set dst (RotateLeft src shift)); 13119 13120 ins_cost(INSN_COST); 13121 format %{ "rol $dst, $src, $shift" %} 13122 13123 ins_encode %{ 13124 __ subw(rscratch1, zr, as_Register($shift$$reg)); 13125 __ rorv(as_Register($dst$$reg), as_Register($src$$reg), rscratch1); 13126 %} 13127 ins_pipe(ialu_reg_reg_vshift); 13128 %} 13129 13130 13131 // Add/subtract (extended) 13132 13133 // This pattern is automatically generated from aarch64_ad.m4 13134 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13135 instruct AddExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 13136 %{ 13137 match(Set dst (AddL src1 (ConvI2L src2))); 13138 ins_cost(INSN_COST); 13139 format %{ "add $dst, $src1, $src2, sxtw" %} 13140 13141 ins_encode %{ 13142 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13143 as_Register($src2$$reg), ext::sxtw); 13144 %} 13145 ins_pipe(ialu_reg_reg); 13146 %} 13147 13148 // This pattern is automatically generated from aarch64_ad.m4 13149 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13150 instruct SubExtI(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, rFlagsReg cr) 13151 %{ 13152 match(Set dst (SubL src1 (ConvI2L src2))); 13153 ins_cost(INSN_COST); 13154 format %{ "sub $dst, $src1, $src2, sxtw" %} 13155 13156 ins_encode %{ 13157 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13158 as_Register($src2$$reg), ext::sxtw); 13159 %} 13160 ins_pipe(ialu_reg_reg); 13161 %} 13162 13163 // This pattern is automatically generated from aarch64_ad.m4 13164 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13165 instruct AddExtI_sxth(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_16 lshift, immI_16 rshift, rFlagsReg cr) 13166 %{ 13167 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 13168 ins_cost(INSN_COST); 13169 format %{ "add $dst, $src1, $src2, sxth" %} 13170 13171 ins_encode %{ 13172 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13173 as_Register($src2$$reg), ext::sxth); 13174 %} 13175 ins_pipe(ialu_reg_reg); 13176 %} 13177 13178 // This pattern is automatically generated from aarch64_ad.m4 13179 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13180 instruct AddExtI_sxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 13181 %{ 13182 match(Set dst (AddI src1 (RShiftI (LShiftI src2 lshift) rshift))); 13183 ins_cost(INSN_COST); 13184 format %{ "add $dst, $src1, $src2, sxtb" %} 13185 13186 ins_encode %{ 13187 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13188 as_Register($src2$$reg), ext::sxtb); 13189 %} 13190 ins_pipe(ialu_reg_reg); 13191 %} 13192 13193 // This pattern is automatically generated from aarch64_ad.m4 13194 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13195 instruct AddExtI_uxtb(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_24 lshift, immI_24 rshift, rFlagsReg cr) 13196 %{ 13197 match(Set dst (AddI src1 (URShiftI (LShiftI src2 lshift) rshift))); 13198 ins_cost(INSN_COST); 13199 format %{ "add $dst, $src1, $src2, uxtb" %} 13200 13201 ins_encode %{ 13202 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13203 as_Register($src2$$reg), ext::uxtb); 13204 %} 13205 ins_pipe(ialu_reg_reg); 13206 %} 13207 13208 // This pattern is automatically generated from aarch64_ad.m4 13209 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13210 instruct AddExtL_sxth(iRegLNoSp dst, iRegL src1, iRegL src2, immI_48 lshift, immI_48 rshift, rFlagsReg cr) 13211 %{ 13212 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13213 ins_cost(INSN_COST); 13214 format %{ "add $dst, $src1, $src2, sxth" %} 13215 13216 ins_encode %{ 13217 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13218 as_Register($src2$$reg), ext::sxth); 13219 %} 13220 ins_pipe(ialu_reg_reg); 13221 %} 13222 13223 // This pattern is automatically generated from aarch64_ad.m4 13224 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13225 instruct AddExtL_sxtw(iRegLNoSp dst, iRegL src1, iRegL src2, immI_32 lshift, immI_32 rshift, rFlagsReg cr) 13226 %{ 13227 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13228 ins_cost(INSN_COST); 13229 format %{ "add $dst, $src1, $src2, sxtw" %} 13230 13231 ins_encode %{ 13232 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13233 as_Register($src2$$reg), ext::sxtw); 13234 %} 13235 ins_pipe(ialu_reg_reg); 13236 %} 13237 13238 // This pattern is automatically generated from aarch64_ad.m4 13239 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13240 instruct AddExtL_sxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 13241 %{ 13242 match(Set dst (AddL src1 (RShiftL (LShiftL src2 lshift) rshift))); 13243 ins_cost(INSN_COST); 13244 format %{ "add $dst, $src1, $src2, sxtb" %} 13245 13246 ins_encode %{ 13247 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13248 as_Register($src2$$reg), ext::sxtb); 13249 %} 13250 ins_pipe(ialu_reg_reg); 13251 %} 13252 13253 // This pattern is automatically generated from aarch64_ad.m4 13254 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13255 instruct AddExtL_uxtb(iRegLNoSp dst, iRegL src1, iRegL src2, immI_56 lshift, immI_56 rshift, rFlagsReg cr) 13256 %{ 13257 match(Set dst (AddL src1 (URShiftL (LShiftL src2 lshift) rshift))); 13258 ins_cost(INSN_COST); 13259 format %{ "add $dst, $src1, $src2, uxtb" %} 13260 13261 ins_encode %{ 13262 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13263 as_Register($src2$$reg), ext::uxtb); 13264 %} 13265 ins_pipe(ialu_reg_reg); 13266 %} 13267 13268 // This pattern is automatically generated from aarch64_ad.m4 13269 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13270 instruct AddExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 13271 %{ 13272 match(Set dst (AddI src1 (AndI src2 mask))); 13273 ins_cost(INSN_COST); 13274 format %{ "addw $dst, $src1, $src2, uxtb" %} 13275 13276 ins_encode %{ 13277 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13278 as_Register($src2$$reg), ext::uxtb); 13279 %} 13280 ins_pipe(ialu_reg_reg); 13281 %} 13282 13283 // This pattern is automatically generated from aarch64_ad.m4 13284 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13285 instruct AddExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 13286 %{ 13287 match(Set dst (AddI src1 (AndI src2 mask))); 13288 ins_cost(INSN_COST); 13289 format %{ "addw $dst, $src1, $src2, uxth" %} 13290 13291 ins_encode %{ 13292 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13293 as_Register($src2$$reg), ext::uxth); 13294 %} 13295 ins_pipe(ialu_reg_reg); 13296 %} 13297 13298 // This pattern is automatically generated from aarch64_ad.m4 13299 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13300 instruct AddExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 13301 %{ 13302 match(Set dst (AddL src1 (AndL src2 mask))); 13303 ins_cost(INSN_COST); 13304 format %{ "add $dst, $src1, $src2, uxtb" %} 13305 13306 ins_encode %{ 13307 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13308 as_Register($src2$$reg), ext::uxtb); 13309 %} 13310 ins_pipe(ialu_reg_reg); 13311 %} 13312 13313 // This pattern is automatically generated from aarch64_ad.m4 13314 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13315 instruct AddExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 13316 %{ 13317 match(Set dst (AddL src1 (AndL src2 mask))); 13318 ins_cost(INSN_COST); 13319 format %{ "add $dst, $src1, $src2, uxth" %} 13320 13321 ins_encode %{ 13322 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13323 as_Register($src2$$reg), ext::uxth); 13324 %} 13325 ins_pipe(ialu_reg_reg); 13326 %} 13327 13328 // This pattern is automatically generated from aarch64_ad.m4 13329 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13330 instruct AddExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 13331 %{ 13332 match(Set dst (AddL src1 (AndL src2 mask))); 13333 ins_cost(INSN_COST); 13334 format %{ "add $dst, $src1, $src2, uxtw" %} 13335 13336 ins_encode %{ 13337 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13338 as_Register($src2$$reg), ext::uxtw); 13339 %} 13340 ins_pipe(ialu_reg_reg); 13341 %} 13342 13343 // This pattern is automatically generated from aarch64_ad.m4 13344 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13345 instruct SubExtI_uxtb_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, rFlagsReg cr) 13346 %{ 13347 match(Set dst (SubI src1 (AndI src2 mask))); 13348 ins_cost(INSN_COST); 13349 format %{ "subw $dst, $src1, $src2, uxtb" %} 13350 13351 ins_encode %{ 13352 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13353 as_Register($src2$$reg), ext::uxtb); 13354 %} 13355 ins_pipe(ialu_reg_reg); 13356 %} 13357 13358 // This pattern is automatically generated from aarch64_ad.m4 13359 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13360 instruct SubExtI_uxth_and(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, rFlagsReg cr) 13361 %{ 13362 match(Set dst (SubI src1 (AndI src2 mask))); 13363 ins_cost(INSN_COST); 13364 format %{ "subw $dst, $src1, $src2, uxth" %} 13365 13366 ins_encode %{ 13367 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13368 as_Register($src2$$reg), ext::uxth); 13369 %} 13370 ins_pipe(ialu_reg_reg); 13371 %} 13372 13373 // This pattern is automatically generated from aarch64_ad.m4 13374 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13375 instruct SubExtL_uxtb_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, rFlagsReg cr) 13376 %{ 13377 match(Set dst (SubL src1 (AndL src2 mask))); 13378 ins_cost(INSN_COST); 13379 format %{ "sub $dst, $src1, $src2, uxtb" %} 13380 13381 ins_encode %{ 13382 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13383 as_Register($src2$$reg), ext::uxtb); 13384 %} 13385 ins_pipe(ialu_reg_reg); 13386 %} 13387 13388 // This pattern is automatically generated from aarch64_ad.m4 13389 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13390 instruct SubExtL_uxth_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, rFlagsReg cr) 13391 %{ 13392 match(Set dst (SubL src1 (AndL src2 mask))); 13393 ins_cost(INSN_COST); 13394 format %{ "sub $dst, $src1, $src2, uxth" %} 13395 13396 ins_encode %{ 13397 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13398 as_Register($src2$$reg), ext::uxth); 13399 %} 13400 ins_pipe(ialu_reg_reg); 13401 %} 13402 13403 // This pattern is automatically generated from aarch64_ad.m4 13404 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13405 instruct SubExtL_uxtw_and(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, rFlagsReg cr) 13406 %{ 13407 match(Set dst (SubL src1 (AndL src2 mask))); 13408 ins_cost(INSN_COST); 13409 format %{ "sub $dst, $src1, $src2, uxtw" %} 13410 13411 ins_encode %{ 13412 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13413 as_Register($src2$$reg), ext::uxtw); 13414 %} 13415 ins_pipe(ialu_reg_reg); 13416 %} 13417 13418 13419 // This pattern is automatically generated from aarch64_ad.m4 13420 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13421 instruct AddExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 13422 %{ 13423 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13424 ins_cost(1.9 * INSN_COST); 13425 format %{ "add $dst, $src1, $src2, sxtb #lshift2" %} 13426 13427 ins_encode %{ 13428 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13429 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13430 %} 13431 ins_pipe(ialu_reg_reg_shift); 13432 %} 13433 13434 // This pattern is automatically generated from aarch64_ad.m4 13435 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13436 instruct AddExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 13437 %{ 13438 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13439 ins_cost(1.9 * INSN_COST); 13440 format %{ "add $dst, $src1, $src2, sxth #lshift2" %} 13441 13442 ins_encode %{ 13443 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13444 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13445 %} 13446 ins_pipe(ialu_reg_reg_shift); 13447 %} 13448 13449 // This pattern is automatically generated from aarch64_ad.m4 13450 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13451 instruct AddExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 13452 %{ 13453 match(Set dst (AddL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13454 ins_cost(1.9 * INSN_COST); 13455 format %{ "add $dst, $src1, $src2, sxtw #lshift2" %} 13456 13457 ins_encode %{ 13458 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13459 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 13460 %} 13461 ins_pipe(ialu_reg_reg_shift); 13462 %} 13463 13464 // This pattern is automatically generated from aarch64_ad.m4 13465 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13466 instruct SubExtL_sxtb_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_56 lshift1, immI_56 rshift1, rFlagsReg cr) 13467 %{ 13468 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13469 ins_cost(1.9 * INSN_COST); 13470 format %{ "sub $dst, $src1, $src2, sxtb #lshift2" %} 13471 13472 ins_encode %{ 13473 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13474 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13475 %} 13476 ins_pipe(ialu_reg_reg_shift); 13477 %} 13478 13479 // This pattern is automatically generated from aarch64_ad.m4 13480 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13481 instruct SubExtL_sxth_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_48 lshift1, immI_48 rshift1, rFlagsReg cr) 13482 %{ 13483 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13484 ins_cost(1.9 * INSN_COST); 13485 format %{ "sub $dst, $src1, $src2, sxth #lshift2" %} 13486 13487 ins_encode %{ 13488 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13489 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13490 %} 13491 ins_pipe(ialu_reg_reg_shift); 13492 %} 13493 13494 // This pattern is automatically generated from aarch64_ad.m4 13495 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13496 instruct SubExtL_sxtw_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immIExt lshift2, immI_32 lshift1, immI_32 rshift1, rFlagsReg cr) 13497 %{ 13498 match(Set dst (SubL src1 (LShiftL (RShiftL (LShiftL src2 lshift1) rshift1) lshift2))); 13499 ins_cost(1.9 * INSN_COST); 13500 format %{ "sub $dst, $src1, $src2, sxtw #lshift2" %} 13501 13502 ins_encode %{ 13503 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13504 as_Register($src2$$reg), ext::sxtw, ($lshift2$$constant)); 13505 %} 13506 ins_pipe(ialu_reg_reg_shift); 13507 %} 13508 13509 // This pattern is automatically generated from aarch64_ad.m4 13510 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13511 instruct AddExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 13512 %{ 13513 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13514 ins_cost(1.9 * INSN_COST); 13515 format %{ "addw $dst, $src1, $src2, sxtb #lshift2" %} 13516 13517 ins_encode %{ 13518 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13519 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13520 %} 13521 ins_pipe(ialu_reg_reg_shift); 13522 %} 13523 13524 // This pattern is automatically generated from aarch64_ad.m4 13525 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13526 instruct AddExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 13527 %{ 13528 match(Set dst (AddI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13529 ins_cost(1.9 * INSN_COST); 13530 format %{ "addw $dst, $src1, $src2, sxth #lshift2" %} 13531 13532 ins_encode %{ 13533 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13534 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13535 %} 13536 ins_pipe(ialu_reg_reg_shift); 13537 %} 13538 13539 // This pattern is automatically generated from aarch64_ad.m4 13540 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13541 instruct SubExtI_sxtb_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_24 lshift1, immI_24 rshift1, rFlagsReg cr) 13542 %{ 13543 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13544 ins_cost(1.9 * INSN_COST); 13545 format %{ "subw $dst, $src1, $src2, sxtb #lshift2" %} 13546 13547 ins_encode %{ 13548 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13549 as_Register($src2$$reg), ext::sxtb, ($lshift2$$constant)); 13550 %} 13551 ins_pipe(ialu_reg_reg_shift); 13552 %} 13553 13554 // This pattern is automatically generated from aarch64_ad.m4 13555 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13556 instruct SubExtI_sxth_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immIExt lshift2, immI_16 lshift1, immI_16 rshift1, rFlagsReg cr) 13557 %{ 13558 match(Set dst (SubI src1 (LShiftI (RShiftI (LShiftI src2 lshift1) rshift1) lshift2))); 13559 ins_cost(1.9 * INSN_COST); 13560 format %{ "subw $dst, $src1, $src2, sxth #lshift2" %} 13561 13562 ins_encode %{ 13563 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13564 as_Register($src2$$reg), ext::sxth, ($lshift2$$constant)); 13565 %} 13566 ins_pipe(ialu_reg_reg_shift); 13567 %} 13568 13569 // This pattern is automatically generated from aarch64_ad.m4 13570 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13571 instruct AddExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 13572 %{ 13573 match(Set dst (AddL src1 (LShiftL (ConvI2L src2) lshift))); 13574 ins_cost(1.9 * INSN_COST); 13575 format %{ "add $dst, $src1, $src2, sxtw #lshift" %} 13576 13577 ins_encode %{ 13578 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13579 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 13580 %} 13581 ins_pipe(ialu_reg_reg_shift); 13582 %} 13583 13584 // This pattern is automatically generated from aarch64_ad.m4 13585 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13586 instruct SubExtI_shift(iRegLNoSp dst, iRegL src1, iRegIorL2I src2, immIExt lshift, rFlagsReg cr) 13587 %{ 13588 match(Set dst (SubL src1 (LShiftL (ConvI2L src2) lshift))); 13589 ins_cost(1.9 * INSN_COST); 13590 format %{ "sub $dst, $src1, $src2, sxtw #lshift" %} 13591 13592 ins_encode %{ 13593 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13594 as_Register($src2$$reg), ext::sxtw, ($lshift$$constant)); 13595 %} 13596 ins_pipe(ialu_reg_reg_shift); 13597 %} 13598 13599 // This pattern is automatically generated from aarch64_ad.m4 13600 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13601 instruct AddExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 13602 %{ 13603 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13604 ins_cost(1.9 * INSN_COST); 13605 format %{ "add $dst, $src1, $src2, uxtb #lshift" %} 13606 13607 ins_encode %{ 13608 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13609 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13610 %} 13611 ins_pipe(ialu_reg_reg_shift); 13612 %} 13613 13614 // This pattern is automatically generated from aarch64_ad.m4 13615 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13616 instruct AddExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 13617 %{ 13618 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13619 ins_cost(1.9 * INSN_COST); 13620 format %{ "add $dst, $src1, $src2, uxth #lshift" %} 13621 13622 ins_encode %{ 13623 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13624 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13625 %} 13626 ins_pipe(ialu_reg_reg_shift); 13627 %} 13628 13629 // This pattern is automatically generated from aarch64_ad.m4 13630 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13631 instruct AddExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13632 %{ 13633 match(Set dst (AddL src1 (LShiftL (AndL src2 mask) lshift))); 13634 ins_cost(1.9 * INSN_COST); 13635 format %{ "add $dst, $src1, $src2, uxtw #lshift" %} 13636 13637 ins_encode %{ 13638 __ add(as_Register($dst$$reg), as_Register($src1$$reg), 13639 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13640 %} 13641 ins_pipe(ialu_reg_reg_shift); 13642 %} 13643 13644 // This pattern is automatically generated from aarch64_ad.m4 13645 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13646 instruct SubExtL_uxtb_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_255 mask, immIExt lshift, rFlagsReg cr) 13647 %{ 13648 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13649 ins_cost(1.9 * INSN_COST); 13650 format %{ "sub $dst, $src1, $src2, uxtb #lshift" %} 13651 13652 ins_encode %{ 13653 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13654 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13655 %} 13656 ins_pipe(ialu_reg_reg_shift); 13657 %} 13658 13659 // This pattern is automatically generated from aarch64_ad.m4 13660 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13661 instruct SubExtL_uxth_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_65535 mask, immIExt lshift, rFlagsReg cr) 13662 %{ 13663 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13664 ins_cost(1.9 * INSN_COST); 13665 format %{ "sub $dst, $src1, $src2, uxth #lshift" %} 13666 13667 ins_encode %{ 13668 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13669 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13670 %} 13671 ins_pipe(ialu_reg_reg_shift); 13672 %} 13673 13674 // This pattern is automatically generated from aarch64_ad.m4 13675 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13676 instruct SubExtL_uxtw_and_shift(iRegLNoSp dst, iRegL src1, iRegL src2, immL_4294967295 mask, immIExt lshift, rFlagsReg cr) 13677 %{ 13678 match(Set dst (SubL src1 (LShiftL (AndL src2 mask) lshift))); 13679 ins_cost(1.9 * INSN_COST); 13680 format %{ "sub $dst, $src1, $src2, uxtw #lshift" %} 13681 13682 ins_encode %{ 13683 __ sub(as_Register($dst$$reg), as_Register($src1$$reg), 13684 as_Register($src2$$reg), ext::uxtw, ($lshift$$constant)); 13685 %} 13686 ins_pipe(ialu_reg_reg_shift); 13687 %} 13688 13689 // This pattern is automatically generated from aarch64_ad.m4 13690 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13691 instruct AddExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13692 %{ 13693 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13694 ins_cost(1.9 * INSN_COST); 13695 format %{ "addw $dst, $src1, $src2, uxtb #lshift" %} 13696 13697 ins_encode %{ 13698 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13699 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13700 %} 13701 ins_pipe(ialu_reg_reg_shift); 13702 %} 13703 13704 // This pattern is automatically generated from aarch64_ad.m4 13705 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13706 instruct AddExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13707 %{ 13708 match(Set dst (AddI src1 (LShiftI (AndI src2 mask) lshift))); 13709 ins_cost(1.9 * INSN_COST); 13710 format %{ "addw $dst, $src1, $src2, uxth #lshift" %} 13711 13712 ins_encode %{ 13713 __ addw(as_Register($dst$$reg), as_Register($src1$$reg), 13714 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13715 %} 13716 ins_pipe(ialu_reg_reg_shift); 13717 %} 13718 13719 // This pattern is automatically generated from aarch64_ad.m4 13720 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13721 instruct SubExtI_uxtb_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_255 mask, immIExt lshift, rFlagsReg cr) 13722 %{ 13723 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13724 ins_cost(1.9 * INSN_COST); 13725 format %{ "subw $dst, $src1, $src2, uxtb #lshift" %} 13726 13727 ins_encode %{ 13728 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13729 as_Register($src2$$reg), ext::uxtb, ($lshift$$constant)); 13730 %} 13731 ins_pipe(ialu_reg_reg_shift); 13732 %} 13733 13734 // This pattern is automatically generated from aarch64_ad.m4 13735 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13736 instruct SubExtI_uxth_and_shift(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_65535 mask, immIExt lshift, rFlagsReg cr) 13737 %{ 13738 match(Set dst (SubI src1 (LShiftI (AndI src2 mask) lshift))); 13739 ins_cost(1.9 * INSN_COST); 13740 format %{ "subw $dst, $src1, $src2, uxth #lshift" %} 13741 13742 ins_encode %{ 13743 __ subw(as_Register($dst$$reg), as_Register($src1$$reg), 13744 as_Register($src2$$reg), ext::uxth, ($lshift$$constant)); 13745 %} 13746 ins_pipe(ialu_reg_reg_shift); 13747 %} 13748 13749 // This pattern is automatically generated from aarch64_ad.m4 13750 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13751 instruct cmovI_reg_reg_lt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13752 %{ 13753 effect(DEF dst, USE src1, USE src2, USE cr); 13754 ins_cost(INSN_COST * 2); 13755 format %{ "cselw $dst, $src1, $src2 lt\t" %} 13756 13757 ins_encode %{ 13758 __ cselw($dst$$Register, 13759 $src1$$Register, 13760 $src2$$Register, 13761 Assembler::LT); 13762 %} 13763 ins_pipe(icond_reg_reg); 13764 %} 13765 13766 // This pattern is automatically generated from aarch64_ad.m4 13767 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13768 instruct cmovI_reg_reg_gt(iRegINoSp dst, iRegI src1, iRegI src2, rFlagsReg cr) 13769 %{ 13770 effect(DEF dst, USE src1, USE src2, USE cr); 13771 ins_cost(INSN_COST * 2); 13772 format %{ "cselw $dst, $src1, $src2 gt\t" %} 13773 13774 ins_encode %{ 13775 __ cselw($dst$$Register, 13776 $src1$$Register, 13777 $src2$$Register, 13778 Assembler::GT); 13779 %} 13780 ins_pipe(icond_reg_reg); 13781 %} 13782 13783 // This pattern is automatically generated from aarch64_ad.m4 13784 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13785 instruct cmovI_reg_imm0_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13786 %{ 13787 effect(DEF dst, USE src1, USE cr); 13788 ins_cost(INSN_COST * 2); 13789 format %{ "cselw $dst, $src1, zr lt\t" %} 13790 13791 ins_encode %{ 13792 __ cselw($dst$$Register, 13793 $src1$$Register, 13794 zr, 13795 Assembler::LT); 13796 %} 13797 ins_pipe(icond_reg); 13798 %} 13799 13800 // This pattern is automatically generated from aarch64_ad.m4 13801 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13802 instruct cmovI_reg_imm0_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13803 %{ 13804 effect(DEF dst, USE src1, USE cr); 13805 ins_cost(INSN_COST * 2); 13806 format %{ "cselw $dst, $src1, zr gt\t" %} 13807 13808 ins_encode %{ 13809 __ cselw($dst$$Register, 13810 $src1$$Register, 13811 zr, 13812 Assembler::GT); 13813 %} 13814 ins_pipe(icond_reg); 13815 %} 13816 13817 // This pattern is automatically generated from aarch64_ad.m4 13818 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13819 instruct cmovI_reg_imm1_le(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13820 %{ 13821 effect(DEF dst, USE src1, USE cr); 13822 ins_cost(INSN_COST * 2); 13823 format %{ "csincw $dst, $src1, zr le\t" %} 13824 13825 ins_encode %{ 13826 __ csincw($dst$$Register, 13827 $src1$$Register, 13828 zr, 13829 Assembler::LE); 13830 %} 13831 ins_pipe(icond_reg); 13832 %} 13833 13834 // This pattern is automatically generated from aarch64_ad.m4 13835 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13836 instruct cmovI_reg_imm1_gt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13837 %{ 13838 effect(DEF dst, USE src1, USE cr); 13839 ins_cost(INSN_COST * 2); 13840 format %{ "csincw $dst, $src1, zr gt\t" %} 13841 13842 ins_encode %{ 13843 __ csincw($dst$$Register, 13844 $src1$$Register, 13845 zr, 13846 Assembler::GT); 13847 %} 13848 ins_pipe(icond_reg); 13849 %} 13850 13851 // This pattern is automatically generated from aarch64_ad.m4 13852 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13853 instruct cmovI_reg_immM1_lt(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13854 %{ 13855 effect(DEF dst, USE src1, USE cr); 13856 ins_cost(INSN_COST * 2); 13857 format %{ "csinvw $dst, $src1, zr lt\t" %} 13858 13859 ins_encode %{ 13860 __ csinvw($dst$$Register, 13861 $src1$$Register, 13862 zr, 13863 Assembler::LT); 13864 %} 13865 ins_pipe(icond_reg); 13866 %} 13867 13868 // This pattern is automatically generated from aarch64_ad.m4 13869 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13870 instruct cmovI_reg_immM1_ge(iRegINoSp dst, iRegI src1, rFlagsReg cr) 13871 %{ 13872 effect(DEF dst, USE src1, USE cr); 13873 ins_cost(INSN_COST * 2); 13874 format %{ "csinvw $dst, $src1, zr ge\t" %} 13875 13876 ins_encode %{ 13877 __ csinvw($dst$$Register, 13878 $src1$$Register, 13879 zr, 13880 Assembler::GE); 13881 %} 13882 ins_pipe(icond_reg); 13883 %} 13884 13885 // This pattern is automatically generated from aarch64_ad.m4 13886 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13887 instruct minI_reg_imm0(iRegINoSp dst, iRegIorL2I src, immI0 imm) 13888 %{ 13889 match(Set dst (MinI src imm)); 13890 ins_cost(INSN_COST * 3); 13891 expand %{ 13892 rFlagsReg cr; 13893 compI_reg_imm0(cr, src); 13894 cmovI_reg_imm0_lt(dst, src, cr); 13895 %} 13896 %} 13897 13898 // This pattern is automatically generated from aarch64_ad.m4 13899 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13900 instruct minI_imm0_reg(iRegINoSp dst, immI0 imm, iRegIorL2I src) 13901 %{ 13902 match(Set dst (MinI imm src)); 13903 ins_cost(INSN_COST * 3); 13904 expand %{ 13905 rFlagsReg cr; 13906 compI_reg_imm0(cr, src); 13907 cmovI_reg_imm0_lt(dst, src, cr); 13908 %} 13909 %} 13910 13911 // This pattern is automatically generated from aarch64_ad.m4 13912 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13913 instruct minI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm) 13914 %{ 13915 match(Set dst (MinI src imm)); 13916 ins_cost(INSN_COST * 3); 13917 expand %{ 13918 rFlagsReg cr; 13919 compI_reg_imm0(cr, src); 13920 cmovI_reg_imm1_le(dst, src, cr); 13921 %} 13922 %} 13923 13924 // This pattern is automatically generated from aarch64_ad.m4 13925 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13926 instruct minI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src) 13927 %{ 13928 match(Set dst (MinI imm src)); 13929 ins_cost(INSN_COST * 3); 13930 expand %{ 13931 rFlagsReg cr; 13932 compI_reg_imm0(cr, src); 13933 cmovI_reg_imm1_le(dst, src, cr); 13934 %} 13935 %} 13936 13937 // This pattern is automatically generated from aarch64_ad.m4 13938 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13939 instruct minI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm) 13940 %{ 13941 match(Set dst (MinI src imm)); 13942 ins_cost(INSN_COST * 3); 13943 expand %{ 13944 rFlagsReg cr; 13945 compI_reg_imm0(cr, src); 13946 cmovI_reg_immM1_lt(dst, src, cr); 13947 %} 13948 %} 13949 13950 // This pattern is automatically generated from aarch64_ad.m4 13951 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13952 instruct minI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src) 13953 %{ 13954 match(Set dst (MinI imm src)); 13955 ins_cost(INSN_COST * 3); 13956 expand %{ 13957 rFlagsReg cr; 13958 compI_reg_imm0(cr, src); 13959 cmovI_reg_immM1_lt(dst, src, cr); 13960 %} 13961 %} 13962 13963 // This pattern is automatically generated from aarch64_ad.m4 13964 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13965 instruct maxI_reg_imm0(iRegINoSp dst, iRegIorL2I src, immI0 imm) 13966 %{ 13967 match(Set dst (MaxI src imm)); 13968 ins_cost(INSN_COST * 3); 13969 expand %{ 13970 rFlagsReg cr; 13971 compI_reg_imm0(cr, src); 13972 cmovI_reg_imm0_gt(dst, src, cr); 13973 %} 13974 %} 13975 13976 // This pattern is automatically generated from aarch64_ad.m4 13977 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13978 instruct maxI_imm0_reg(iRegINoSp dst, immI0 imm, iRegIorL2I src) 13979 %{ 13980 match(Set dst (MaxI imm src)); 13981 ins_cost(INSN_COST * 3); 13982 expand %{ 13983 rFlagsReg cr; 13984 compI_reg_imm0(cr, src); 13985 cmovI_reg_imm0_gt(dst, src, cr); 13986 %} 13987 %} 13988 13989 // This pattern is automatically generated from aarch64_ad.m4 13990 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 13991 instruct maxI_reg_imm1(iRegINoSp dst, iRegIorL2I src, immI_1 imm) 13992 %{ 13993 match(Set dst (MaxI src imm)); 13994 ins_cost(INSN_COST * 3); 13995 expand %{ 13996 rFlagsReg cr; 13997 compI_reg_imm0(cr, src); 13998 cmovI_reg_imm1_gt(dst, src, cr); 13999 %} 14000 %} 14001 14002 // This pattern is automatically generated from aarch64_ad.m4 14003 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14004 instruct maxI_imm1_reg(iRegINoSp dst, immI_1 imm, iRegIorL2I src) 14005 %{ 14006 match(Set dst (MaxI imm src)); 14007 ins_cost(INSN_COST * 3); 14008 expand %{ 14009 rFlagsReg cr; 14010 compI_reg_imm0(cr, src); 14011 cmovI_reg_imm1_gt(dst, src, cr); 14012 %} 14013 %} 14014 14015 // This pattern is automatically generated from aarch64_ad.m4 14016 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14017 instruct maxI_reg_immM1(iRegINoSp dst, iRegIorL2I src, immI_M1 imm) 14018 %{ 14019 match(Set dst (MaxI src imm)); 14020 ins_cost(INSN_COST * 3); 14021 expand %{ 14022 rFlagsReg cr; 14023 compI_reg_imm0(cr, src); 14024 cmovI_reg_immM1_ge(dst, src, cr); 14025 %} 14026 %} 14027 14028 // This pattern is automatically generated from aarch64_ad.m4 14029 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14030 instruct maxI_immM1_reg(iRegINoSp dst, immI_M1 imm, iRegIorL2I src) 14031 %{ 14032 match(Set dst (MaxI imm src)); 14033 ins_cost(INSN_COST * 3); 14034 expand %{ 14035 rFlagsReg cr; 14036 compI_reg_imm0(cr, src); 14037 cmovI_reg_immM1_ge(dst, src, cr); 14038 %} 14039 %} 14040 14041 // This pattern is automatically generated from aarch64_ad.m4 14042 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14043 instruct bits_reverse_I(iRegINoSp dst, iRegIorL2I src) 14044 %{ 14045 match(Set dst (ReverseI src)); 14046 ins_cost(INSN_COST); 14047 format %{ "rbitw $dst, $src" %} 14048 ins_encode %{ 14049 __ rbitw($dst$$Register, $src$$Register); 14050 %} 14051 ins_pipe(ialu_reg); 14052 %} 14053 14054 // This pattern is automatically generated from aarch64_ad.m4 14055 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE 14056 instruct bits_reverse_L(iRegLNoSp dst, iRegL src) 14057 %{ 14058 match(Set dst (ReverseL src)); 14059 ins_cost(INSN_COST); 14060 format %{ "rbit $dst, $src" %} 14061 ins_encode %{ 14062 __ rbit($dst$$Register, $src$$Register); 14063 %} 14064 ins_pipe(ialu_reg); 14065 %} 14066 14067 14068 // END This section of the file is automatically generated. Do not edit -------------- 14069 14070 14071 // ============================================================================ 14072 // Floating Point Arithmetic Instructions 14073 14074 instruct addF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14075 match(Set dst (AddF src1 src2)); 14076 14077 ins_cost(INSN_COST * 5); 14078 format %{ "fadds $dst, $src1, $src2" %} 14079 14080 ins_encode %{ 14081 __ fadds(as_FloatRegister($dst$$reg), 14082 as_FloatRegister($src1$$reg), 14083 as_FloatRegister($src2$$reg)); 14084 %} 14085 14086 ins_pipe(fp_dop_reg_reg_s); 14087 %} 14088 14089 instruct addD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14090 match(Set dst (AddD src1 src2)); 14091 14092 ins_cost(INSN_COST * 5); 14093 format %{ "faddd $dst, $src1, $src2" %} 14094 14095 ins_encode %{ 14096 __ faddd(as_FloatRegister($dst$$reg), 14097 as_FloatRegister($src1$$reg), 14098 as_FloatRegister($src2$$reg)); 14099 %} 14100 14101 ins_pipe(fp_dop_reg_reg_d); 14102 %} 14103 14104 instruct subF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14105 match(Set dst (SubF src1 src2)); 14106 14107 ins_cost(INSN_COST * 5); 14108 format %{ "fsubs $dst, $src1, $src2" %} 14109 14110 ins_encode %{ 14111 __ fsubs(as_FloatRegister($dst$$reg), 14112 as_FloatRegister($src1$$reg), 14113 as_FloatRegister($src2$$reg)); 14114 %} 14115 14116 ins_pipe(fp_dop_reg_reg_s); 14117 %} 14118 14119 instruct subD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14120 match(Set dst (SubD src1 src2)); 14121 14122 ins_cost(INSN_COST * 5); 14123 format %{ "fsubd $dst, $src1, $src2" %} 14124 14125 ins_encode %{ 14126 __ fsubd(as_FloatRegister($dst$$reg), 14127 as_FloatRegister($src1$$reg), 14128 as_FloatRegister($src2$$reg)); 14129 %} 14130 14131 ins_pipe(fp_dop_reg_reg_d); 14132 %} 14133 14134 instruct mulF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14135 match(Set dst (MulF src1 src2)); 14136 14137 ins_cost(INSN_COST * 6); 14138 format %{ "fmuls $dst, $src1, $src2" %} 14139 14140 ins_encode %{ 14141 __ fmuls(as_FloatRegister($dst$$reg), 14142 as_FloatRegister($src1$$reg), 14143 as_FloatRegister($src2$$reg)); 14144 %} 14145 14146 ins_pipe(fp_dop_reg_reg_s); 14147 %} 14148 14149 instruct mulD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14150 match(Set dst (MulD src1 src2)); 14151 14152 ins_cost(INSN_COST * 6); 14153 format %{ "fmuld $dst, $src1, $src2" %} 14154 14155 ins_encode %{ 14156 __ fmuld(as_FloatRegister($dst$$reg), 14157 as_FloatRegister($src1$$reg), 14158 as_FloatRegister($src2$$reg)); 14159 %} 14160 14161 ins_pipe(fp_dop_reg_reg_d); 14162 %} 14163 14164 // src1 * src2 + src3 14165 instruct maddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 14166 match(Set dst (FmaF src3 (Binary src1 src2))); 14167 14168 format %{ "fmadds $dst, $src1, $src2, $src3" %} 14169 14170 ins_encode %{ 14171 assert(UseFMA, "Needs FMA instructions support."); 14172 __ fmadds(as_FloatRegister($dst$$reg), 14173 as_FloatRegister($src1$$reg), 14174 as_FloatRegister($src2$$reg), 14175 as_FloatRegister($src3$$reg)); 14176 %} 14177 14178 ins_pipe(pipe_class_default); 14179 %} 14180 14181 // src1 * src2 + src3 14182 instruct maddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 14183 match(Set dst (FmaD src3 (Binary src1 src2))); 14184 14185 format %{ "fmaddd $dst, $src1, $src2, $src3" %} 14186 14187 ins_encode %{ 14188 assert(UseFMA, "Needs FMA instructions support."); 14189 __ fmaddd(as_FloatRegister($dst$$reg), 14190 as_FloatRegister($src1$$reg), 14191 as_FloatRegister($src2$$reg), 14192 as_FloatRegister($src3$$reg)); 14193 %} 14194 14195 ins_pipe(pipe_class_default); 14196 %} 14197 14198 // src1 * (-src2) + src3 14199 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3" 14200 instruct msubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 14201 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 14202 14203 format %{ "fmsubs $dst, $src1, $src2, $src3" %} 14204 14205 ins_encode %{ 14206 assert(UseFMA, "Needs FMA instructions support."); 14207 __ fmsubs(as_FloatRegister($dst$$reg), 14208 as_FloatRegister($src1$$reg), 14209 as_FloatRegister($src2$$reg), 14210 as_FloatRegister($src3$$reg)); 14211 %} 14212 14213 ins_pipe(pipe_class_default); 14214 %} 14215 14216 // src1 * (-src2) + src3 14217 // "(-src1) * src2 + src3" has been idealized to "src2 * (-src1) + src3" 14218 instruct msubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 14219 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 14220 14221 format %{ "fmsubd $dst, $src1, $src2, $src3" %} 14222 14223 ins_encode %{ 14224 assert(UseFMA, "Needs FMA instructions support."); 14225 __ fmsubd(as_FloatRegister($dst$$reg), 14226 as_FloatRegister($src1$$reg), 14227 as_FloatRegister($src2$$reg), 14228 as_FloatRegister($src3$$reg)); 14229 %} 14230 14231 ins_pipe(pipe_class_default); 14232 %} 14233 14234 // src1 * (-src2) - src3 14235 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3" 14236 instruct mnaddF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3) %{ 14237 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 14238 14239 format %{ "fnmadds $dst, $src1, $src2, $src3" %} 14240 14241 ins_encode %{ 14242 assert(UseFMA, "Needs FMA instructions support."); 14243 __ fnmadds(as_FloatRegister($dst$$reg), 14244 as_FloatRegister($src1$$reg), 14245 as_FloatRegister($src2$$reg), 14246 as_FloatRegister($src3$$reg)); 14247 %} 14248 14249 ins_pipe(pipe_class_default); 14250 %} 14251 14252 // src1 * (-src2) - src3 14253 // "(-src1) * src2 - src3" has been idealized to "src2 * (-src1) - src3" 14254 instruct mnaddD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3) %{ 14255 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 14256 14257 format %{ "fnmaddd $dst, $src1, $src2, $src3" %} 14258 14259 ins_encode %{ 14260 assert(UseFMA, "Needs FMA instructions support."); 14261 __ fnmaddd(as_FloatRegister($dst$$reg), 14262 as_FloatRegister($src1$$reg), 14263 as_FloatRegister($src2$$reg), 14264 as_FloatRegister($src3$$reg)); 14265 %} 14266 14267 ins_pipe(pipe_class_default); 14268 %} 14269 14270 // src1 * src2 - src3 14271 instruct mnsubF_reg_reg(vRegF dst, vRegF src1, vRegF src2, vRegF src3, immF0 zero) %{ 14272 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 14273 14274 format %{ "fnmsubs $dst, $src1, $src2, $src3" %} 14275 14276 ins_encode %{ 14277 assert(UseFMA, "Needs FMA instructions support."); 14278 __ fnmsubs(as_FloatRegister($dst$$reg), 14279 as_FloatRegister($src1$$reg), 14280 as_FloatRegister($src2$$reg), 14281 as_FloatRegister($src3$$reg)); 14282 %} 14283 14284 ins_pipe(pipe_class_default); 14285 %} 14286 14287 // src1 * src2 - src3 14288 instruct mnsubD_reg_reg(vRegD dst, vRegD src1, vRegD src2, vRegD src3, immD0 zero) %{ 14289 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 14290 14291 format %{ "fnmsubd $dst, $src1, $src2, $src3" %} 14292 14293 ins_encode %{ 14294 assert(UseFMA, "Needs FMA instructions support."); 14295 // n.b. insn name should be fnmsubd 14296 __ fnmsub(as_FloatRegister($dst$$reg), 14297 as_FloatRegister($src1$$reg), 14298 as_FloatRegister($src2$$reg), 14299 as_FloatRegister($src3$$reg)); 14300 %} 14301 14302 ins_pipe(pipe_class_default); 14303 %} 14304 14305 14306 // Math.max(FF)F 14307 instruct maxF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14308 match(Set dst (MaxF src1 src2)); 14309 14310 format %{ "fmaxs $dst, $src1, $src2" %} 14311 ins_encode %{ 14312 __ fmaxs(as_FloatRegister($dst$$reg), 14313 as_FloatRegister($src1$$reg), 14314 as_FloatRegister($src2$$reg)); 14315 %} 14316 14317 ins_pipe(fp_dop_reg_reg_s); 14318 %} 14319 14320 // Math.min(FF)F 14321 instruct minF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14322 match(Set dst (MinF src1 src2)); 14323 14324 format %{ "fmins $dst, $src1, $src2" %} 14325 ins_encode %{ 14326 __ fmins(as_FloatRegister($dst$$reg), 14327 as_FloatRegister($src1$$reg), 14328 as_FloatRegister($src2$$reg)); 14329 %} 14330 14331 ins_pipe(fp_dop_reg_reg_s); 14332 %} 14333 14334 // Math.max(DD)D 14335 instruct maxD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14336 match(Set dst (MaxD src1 src2)); 14337 14338 format %{ "fmaxd $dst, $src1, $src2" %} 14339 ins_encode %{ 14340 __ fmaxd(as_FloatRegister($dst$$reg), 14341 as_FloatRegister($src1$$reg), 14342 as_FloatRegister($src2$$reg)); 14343 %} 14344 14345 ins_pipe(fp_dop_reg_reg_d); 14346 %} 14347 14348 // Math.min(DD)D 14349 instruct minD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14350 match(Set dst (MinD src1 src2)); 14351 14352 format %{ "fmind $dst, $src1, $src2" %} 14353 ins_encode %{ 14354 __ fmind(as_FloatRegister($dst$$reg), 14355 as_FloatRegister($src1$$reg), 14356 as_FloatRegister($src2$$reg)); 14357 %} 14358 14359 ins_pipe(fp_dop_reg_reg_d); 14360 %} 14361 14362 14363 instruct divF_reg_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14364 match(Set dst (DivF src1 src2)); 14365 14366 ins_cost(INSN_COST * 18); 14367 format %{ "fdivs $dst, $src1, $src2" %} 14368 14369 ins_encode %{ 14370 __ fdivs(as_FloatRegister($dst$$reg), 14371 as_FloatRegister($src1$$reg), 14372 as_FloatRegister($src2$$reg)); 14373 %} 14374 14375 ins_pipe(fp_div_s); 14376 %} 14377 14378 instruct divD_reg_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14379 match(Set dst (DivD src1 src2)); 14380 14381 ins_cost(INSN_COST * 32); 14382 format %{ "fdivd $dst, $src1, $src2" %} 14383 14384 ins_encode %{ 14385 __ fdivd(as_FloatRegister($dst$$reg), 14386 as_FloatRegister($src1$$reg), 14387 as_FloatRegister($src2$$reg)); 14388 %} 14389 14390 ins_pipe(fp_div_d); 14391 %} 14392 14393 instruct negF_reg_reg(vRegF dst, vRegF src) %{ 14394 match(Set dst (NegF src)); 14395 14396 ins_cost(INSN_COST * 3); 14397 format %{ "fneg $dst, $src" %} 14398 14399 ins_encode %{ 14400 __ fnegs(as_FloatRegister($dst$$reg), 14401 as_FloatRegister($src$$reg)); 14402 %} 14403 14404 ins_pipe(fp_uop_s); 14405 %} 14406 14407 instruct negD_reg_reg(vRegD dst, vRegD src) %{ 14408 match(Set dst (NegD src)); 14409 14410 ins_cost(INSN_COST * 3); 14411 format %{ "fnegd $dst, $src" %} 14412 14413 ins_encode %{ 14414 __ fnegd(as_FloatRegister($dst$$reg), 14415 as_FloatRegister($src$$reg)); 14416 %} 14417 14418 ins_pipe(fp_uop_d); 14419 %} 14420 14421 instruct absI_reg(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr) 14422 %{ 14423 match(Set dst (AbsI src)); 14424 14425 effect(KILL cr); 14426 ins_cost(INSN_COST * 2); 14427 format %{ "cmpw $src, zr\n\t" 14428 "cnegw $dst, $src, Assembler::LT\t# int abs" 14429 %} 14430 14431 ins_encode %{ 14432 __ cmpw(as_Register($src$$reg), zr); 14433 __ cnegw(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 14434 %} 14435 ins_pipe(pipe_class_default); 14436 %} 14437 14438 instruct absL_reg(iRegLNoSp dst, iRegL src, rFlagsReg cr) 14439 %{ 14440 match(Set dst (AbsL src)); 14441 14442 effect(KILL cr); 14443 ins_cost(INSN_COST * 2); 14444 format %{ "cmp $src, zr\n\t" 14445 "cneg $dst, $src, Assembler::LT\t# long abs" 14446 %} 14447 14448 ins_encode %{ 14449 __ cmp(as_Register($src$$reg), zr); 14450 __ cneg(as_Register($dst$$reg), as_Register($src$$reg), Assembler::LT); 14451 %} 14452 ins_pipe(pipe_class_default); 14453 %} 14454 14455 instruct absF_reg(vRegF dst, vRegF src) %{ 14456 match(Set dst (AbsF src)); 14457 14458 ins_cost(INSN_COST * 3); 14459 format %{ "fabss $dst, $src" %} 14460 ins_encode %{ 14461 __ fabss(as_FloatRegister($dst$$reg), 14462 as_FloatRegister($src$$reg)); 14463 %} 14464 14465 ins_pipe(fp_uop_s); 14466 %} 14467 14468 instruct absD_reg(vRegD dst, vRegD src) %{ 14469 match(Set dst (AbsD src)); 14470 14471 ins_cost(INSN_COST * 3); 14472 format %{ "fabsd $dst, $src" %} 14473 ins_encode %{ 14474 __ fabsd(as_FloatRegister($dst$$reg), 14475 as_FloatRegister($src$$reg)); 14476 %} 14477 14478 ins_pipe(fp_uop_d); 14479 %} 14480 14481 instruct absdF_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14482 match(Set dst (AbsF (SubF src1 src2))); 14483 14484 ins_cost(INSN_COST * 3); 14485 format %{ "fabds $dst, $src1, $src2" %} 14486 ins_encode %{ 14487 __ fabds(as_FloatRegister($dst$$reg), 14488 as_FloatRegister($src1$$reg), 14489 as_FloatRegister($src2$$reg)); 14490 %} 14491 14492 ins_pipe(fp_uop_s); 14493 %} 14494 14495 instruct absdD_reg(vRegD dst, vRegD src1, vRegD src2) %{ 14496 match(Set dst (AbsD (SubD src1 src2))); 14497 14498 ins_cost(INSN_COST * 3); 14499 format %{ "fabdd $dst, $src1, $src2" %} 14500 ins_encode %{ 14501 __ fabdd(as_FloatRegister($dst$$reg), 14502 as_FloatRegister($src1$$reg), 14503 as_FloatRegister($src2$$reg)); 14504 %} 14505 14506 ins_pipe(fp_uop_d); 14507 %} 14508 14509 instruct sqrtD_reg(vRegD dst, vRegD src) %{ 14510 match(Set dst (SqrtD src)); 14511 14512 ins_cost(INSN_COST * 50); 14513 format %{ "fsqrtd $dst, $src" %} 14514 ins_encode %{ 14515 __ fsqrtd(as_FloatRegister($dst$$reg), 14516 as_FloatRegister($src$$reg)); 14517 %} 14518 14519 ins_pipe(fp_div_s); 14520 %} 14521 14522 instruct sqrtF_reg(vRegF dst, vRegF src) %{ 14523 match(Set dst (SqrtF src)); 14524 14525 ins_cost(INSN_COST * 50); 14526 format %{ "fsqrts $dst, $src" %} 14527 ins_encode %{ 14528 __ fsqrts(as_FloatRegister($dst$$reg), 14529 as_FloatRegister($src$$reg)); 14530 %} 14531 14532 ins_pipe(fp_div_d); 14533 %} 14534 14535 // Math.rint, floor, ceil 14536 instruct roundD_reg(vRegD dst, vRegD src, immI rmode) %{ 14537 match(Set dst (RoundDoubleMode src rmode)); 14538 format %{ "frint $dst, $src, $rmode" %} 14539 ins_encode %{ 14540 switch ($rmode$$constant) { 14541 case RoundDoubleModeNode::rmode_rint: 14542 __ frintnd(as_FloatRegister($dst$$reg), 14543 as_FloatRegister($src$$reg)); 14544 break; 14545 case RoundDoubleModeNode::rmode_floor: 14546 __ frintmd(as_FloatRegister($dst$$reg), 14547 as_FloatRegister($src$$reg)); 14548 break; 14549 case RoundDoubleModeNode::rmode_ceil: 14550 __ frintpd(as_FloatRegister($dst$$reg), 14551 as_FloatRegister($src$$reg)); 14552 break; 14553 } 14554 %} 14555 ins_pipe(fp_uop_d); 14556 %} 14557 14558 instruct copySignD_reg(vRegD dst, vRegD src1, vRegD src2, vRegD zero) %{ 14559 match(Set dst (CopySignD src1 (Binary src2 zero))); 14560 effect(TEMP_DEF dst, USE src1, USE src2, USE zero); 14561 format %{ "CopySignD $dst $src1 $src2" %} 14562 ins_encode %{ 14563 FloatRegister dst = as_FloatRegister($dst$$reg), 14564 src1 = as_FloatRegister($src1$$reg), 14565 src2 = as_FloatRegister($src2$$reg), 14566 zero = as_FloatRegister($zero$$reg); 14567 __ fnegd(dst, zero); 14568 __ bsl(dst, __ T8B, src2, src1); 14569 %} 14570 ins_pipe(fp_uop_d); 14571 %} 14572 14573 instruct copySignF_reg(vRegF dst, vRegF src1, vRegF src2) %{ 14574 match(Set dst (CopySignF src1 src2)); 14575 effect(TEMP_DEF dst, USE src1, USE src2); 14576 format %{ "CopySignF $dst $src1 $src2" %} 14577 ins_encode %{ 14578 FloatRegister dst = as_FloatRegister($dst$$reg), 14579 src1 = as_FloatRegister($src1$$reg), 14580 src2 = as_FloatRegister($src2$$reg); 14581 __ movi(dst, __ T2S, 0x80, 24); 14582 __ bsl(dst, __ T8B, src2, src1); 14583 %} 14584 ins_pipe(fp_uop_d); 14585 %} 14586 14587 instruct signumD_reg(vRegD dst, vRegD src, vRegD zero, vRegD one) %{ 14588 match(Set dst (SignumD src (Binary zero one))); 14589 effect(TEMP_DEF dst, USE src, USE zero, USE one); 14590 format %{ "signumD $dst, $src" %} 14591 ins_encode %{ 14592 FloatRegister src = as_FloatRegister($src$$reg), 14593 dst = as_FloatRegister($dst$$reg), 14594 zero = as_FloatRegister($zero$$reg), 14595 one = as_FloatRegister($one$$reg); 14596 __ facgtd(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 14597 __ ushrd(dst, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 14598 // Bit selection instruction gets bit from "one" for each enabled bit in 14599 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 14600 // NaN the whole "src" will be copied because "dst" is zero. For all other 14601 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 14602 // from "src", and all other bits are copied from 1.0. 14603 __ bsl(dst, __ T8B, one, src); 14604 %} 14605 ins_pipe(fp_uop_d); 14606 %} 14607 14608 instruct signumF_reg(vRegF dst, vRegF src, vRegF zero, vRegF one) %{ 14609 match(Set dst (SignumF src (Binary zero one))); 14610 effect(TEMP_DEF dst, USE src, USE zero, USE one); 14611 format %{ "signumF $dst, $src" %} 14612 ins_encode %{ 14613 FloatRegister src = as_FloatRegister($src$$reg), 14614 dst = as_FloatRegister($dst$$reg), 14615 zero = as_FloatRegister($zero$$reg), 14616 one = as_FloatRegister($one$$reg); 14617 __ facgts(dst, src, zero); // dst=0 for +-0.0 and NaN. 0xFFF..F otherwise 14618 __ ushr(dst, __ T2S, dst, 1); // dst=0 for +-0.0 and NaN. 0x7FF..F otherwise 14619 // Bit selection instruction gets bit from "one" for each enabled bit in 14620 // "dst", otherwise gets a bit from "src". For "src" that contains +-0.0 or 14621 // NaN the whole "src" will be copied because "dst" is zero. For all other 14622 // "src" values dst is 0x7FF..F, which means only the sign bit is copied 14623 // from "src", and all other bits are copied from 1.0. 14624 __ bsl(dst, __ T8B, one, src); 14625 %} 14626 ins_pipe(fp_uop_d); 14627 %} 14628 14629 instruct onspinwait() %{ 14630 match(OnSpinWait); 14631 ins_cost(INSN_COST); 14632 14633 format %{ "onspinwait" %} 14634 14635 ins_encode %{ 14636 __ spin_wait(); 14637 %} 14638 ins_pipe(pipe_class_empty); 14639 %} 14640 14641 // ============================================================================ 14642 // Logical Instructions 14643 14644 // Integer Logical Instructions 14645 14646 // And Instructions 14647 14648 14649 instruct andI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, rFlagsReg cr) %{ 14650 match(Set dst (AndI src1 src2)); 14651 14652 format %{ "andw $dst, $src1, $src2\t# int" %} 14653 14654 ins_cost(INSN_COST); 14655 ins_encode %{ 14656 __ andw(as_Register($dst$$reg), 14657 as_Register($src1$$reg), 14658 as_Register($src2$$reg)); 14659 %} 14660 14661 ins_pipe(ialu_reg_reg); 14662 %} 14663 14664 instruct andI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2, rFlagsReg cr) %{ 14665 match(Set dst (AndI src1 src2)); 14666 14667 format %{ "andsw $dst, $src1, $src2\t# int" %} 14668 14669 ins_cost(INSN_COST); 14670 ins_encode %{ 14671 __ andw(as_Register($dst$$reg), 14672 as_Register($src1$$reg), 14673 (uint64_t)($src2$$constant)); 14674 %} 14675 14676 ins_pipe(ialu_reg_imm); 14677 %} 14678 14679 // Or Instructions 14680 14681 instruct orI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 14682 match(Set dst (OrI src1 src2)); 14683 14684 format %{ "orrw $dst, $src1, $src2\t# int" %} 14685 14686 ins_cost(INSN_COST); 14687 ins_encode %{ 14688 __ orrw(as_Register($dst$$reg), 14689 as_Register($src1$$reg), 14690 as_Register($src2$$reg)); 14691 %} 14692 14693 ins_pipe(ialu_reg_reg); 14694 %} 14695 14696 instruct orI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 14697 match(Set dst (OrI src1 src2)); 14698 14699 format %{ "orrw $dst, $src1, $src2\t# int" %} 14700 14701 ins_cost(INSN_COST); 14702 ins_encode %{ 14703 __ orrw(as_Register($dst$$reg), 14704 as_Register($src1$$reg), 14705 (uint64_t)($src2$$constant)); 14706 %} 14707 14708 ins_pipe(ialu_reg_imm); 14709 %} 14710 14711 // Xor Instructions 14712 14713 instruct xorI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ 14714 match(Set dst (XorI src1 src2)); 14715 14716 format %{ "eorw $dst, $src1, $src2\t# int" %} 14717 14718 ins_cost(INSN_COST); 14719 ins_encode %{ 14720 __ eorw(as_Register($dst$$reg), 14721 as_Register($src1$$reg), 14722 as_Register($src2$$reg)); 14723 %} 14724 14725 ins_pipe(ialu_reg_reg); 14726 %} 14727 14728 instruct xorI_reg_imm(iRegINoSp dst, iRegIorL2I src1, immILog src2) %{ 14729 match(Set dst (XorI src1 src2)); 14730 14731 format %{ "eorw $dst, $src1, $src2\t# int" %} 14732 14733 ins_cost(INSN_COST); 14734 ins_encode %{ 14735 __ eorw(as_Register($dst$$reg), 14736 as_Register($src1$$reg), 14737 (uint64_t)($src2$$constant)); 14738 %} 14739 14740 ins_pipe(ialu_reg_imm); 14741 %} 14742 14743 // Long Logical Instructions 14744 // TODO 14745 14746 instruct andL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2, rFlagsReg cr) %{ 14747 match(Set dst (AndL src1 src2)); 14748 14749 format %{ "and $dst, $src1, $src2\t# int" %} 14750 14751 ins_cost(INSN_COST); 14752 ins_encode %{ 14753 __ andr(as_Register($dst$$reg), 14754 as_Register($src1$$reg), 14755 as_Register($src2$$reg)); 14756 %} 14757 14758 ins_pipe(ialu_reg_reg); 14759 %} 14760 14761 instruct andL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2, rFlagsReg cr) %{ 14762 match(Set dst (AndL src1 src2)); 14763 14764 format %{ "and $dst, $src1, $src2\t# int" %} 14765 14766 ins_cost(INSN_COST); 14767 ins_encode %{ 14768 __ andr(as_Register($dst$$reg), 14769 as_Register($src1$$reg), 14770 (uint64_t)($src2$$constant)); 14771 %} 14772 14773 ins_pipe(ialu_reg_imm); 14774 %} 14775 14776 // Or Instructions 14777 14778 instruct orL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 14779 match(Set dst (OrL src1 src2)); 14780 14781 format %{ "orr $dst, $src1, $src2\t# int" %} 14782 14783 ins_cost(INSN_COST); 14784 ins_encode %{ 14785 __ orr(as_Register($dst$$reg), 14786 as_Register($src1$$reg), 14787 as_Register($src2$$reg)); 14788 %} 14789 14790 ins_pipe(ialu_reg_reg); 14791 %} 14792 14793 instruct orL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 14794 match(Set dst (OrL src1 src2)); 14795 14796 format %{ "orr $dst, $src1, $src2\t# int" %} 14797 14798 ins_cost(INSN_COST); 14799 ins_encode %{ 14800 __ orr(as_Register($dst$$reg), 14801 as_Register($src1$$reg), 14802 (uint64_t)($src2$$constant)); 14803 %} 14804 14805 ins_pipe(ialu_reg_imm); 14806 %} 14807 14808 // Xor Instructions 14809 14810 instruct xorL_reg_reg(iRegLNoSp dst, iRegL src1, iRegL src2) %{ 14811 match(Set dst (XorL src1 src2)); 14812 14813 format %{ "eor $dst, $src1, $src2\t# int" %} 14814 14815 ins_cost(INSN_COST); 14816 ins_encode %{ 14817 __ eor(as_Register($dst$$reg), 14818 as_Register($src1$$reg), 14819 as_Register($src2$$reg)); 14820 %} 14821 14822 ins_pipe(ialu_reg_reg); 14823 %} 14824 14825 instruct xorL_reg_imm(iRegLNoSp dst, iRegL src1, immLLog src2) %{ 14826 match(Set dst (XorL src1 src2)); 14827 14828 ins_cost(INSN_COST); 14829 format %{ "eor $dst, $src1, $src2\t# int" %} 14830 14831 ins_encode %{ 14832 __ eor(as_Register($dst$$reg), 14833 as_Register($src1$$reg), 14834 (uint64_t)($src2$$constant)); 14835 %} 14836 14837 ins_pipe(ialu_reg_imm); 14838 %} 14839 14840 instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src) 14841 %{ 14842 match(Set dst (ConvI2L src)); 14843 14844 ins_cost(INSN_COST); 14845 format %{ "sxtw $dst, $src\t# i2l" %} 14846 ins_encode %{ 14847 __ sbfm($dst$$Register, $src$$Register, 0, 31); 14848 %} 14849 ins_pipe(ialu_reg_shift); 14850 %} 14851 14852 // this pattern occurs in bigmath arithmetic 14853 instruct convUI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src, immL_32bits mask) 14854 %{ 14855 match(Set dst (AndL (ConvI2L src) mask)); 14856 14857 ins_cost(INSN_COST); 14858 format %{ "ubfm $dst, $src, 0, 31\t# ui2l" %} 14859 ins_encode %{ 14860 __ ubfm($dst$$Register, $src$$Register, 0, 31); 14861 %} 14862 14863 ins_pipe(ialu_reg_shift); 14864 %} 14865 14866 instruct convL2I_reg(iRegINoSp dst, iRegL src) %{ 14867 match(Set dst (ConvL2I src)); 14868 14869 ins_cost(INSN_COST); 14870 format %{ "movw $dst, $src \t// l2i" %} 14871 14872 ins_encode %{ 14873 __ movw(as_Register($dst$$reg), as_Register($src$$reg)); 14874 %} 14875 14876 ins_pipe(ialu_reg); 14877 %} 14878 14879 instruct convD2F_reg(vRegF dst, vRegD src) %{ 14880 match(Set dst (ConvD2F src)); 14881 14882 ins_cost(INSN_COST * 5); 14883 format %{ "fcvtd $dst, $src \t// d2f" %} 14884 14885 ins_encode %{ 14886 __ fcvtd(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 14887 %} 14888 14889 ins_pipe(fp_d2f); 14890 %} 14891 14892 instruct convF2D_reg(vRegD dst, vRegF src) %{ 14893 match(Set dst (ConvF2D src)); 14894 14895 ins_cost(INSN_COST * 5); 14896 format %{ "fcvts $dst, $src \t// f2d" %} 14897 14898 ins_encode %{ 14899 __ fcvts(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg)); 14900 %} 14901 14902 ins_pipe(fp_f2d); 14903 %} 14904 14905 instruct convF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 14906 match(Set dst (ConvF2I src)); 14907 14908 ins_cost(INSN_COST * 5); 14909 format %{ "fcvtzsw $dst, $src \t// f2i" %} 14910 14911 ins_encode %{ 14912 __ fcvtzsw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14913 %} 14914 14915 ins_pipe(fp_f2i); 14916 %} 14917 14918 instruct convF2L_reg_reg(iRegLNoSp dst, vRegF src) %{ 14919 match(Set dst (ConvF2L src)); 14920 14921 ins_cost(INSN_COST * 5); 14922 format %{ "fcvtzs $dst, $src \t// f2l" %} 14923 14924 ins_encode %{ 14925 __ fcvtzs(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14926 %} 14927 14928 ins_pipe(fp_f2l); 14929 %} 14930 14931 instruct convF2HF_reg_reg(iRegINoSp dst, vRegF src, vRegF tmp) %{ 14932 match(Set dst (ConvF2HF src)); 14933 format %{ "fcvt $tmp, $src\t# convert single to half precision\n\t" 14934 "smov $dst, $tmp\t# move result from $tmp to $dst" 14935 %} 14936 effect(TEMP tmp); 14937 ins_encode %{ 14938 __ flt_to_flt16($dst$$Register, $src$$FloatRegister, $tmp$$FloatRegister); 14939 %} 14940 ins_pipe(pipe_slow); 14941 %} 14942 14943 instruct convHF2F_reg_reg(vRegF dst, iRegINoSp src, vRegF tmp) %{ 14944 match(Set dst (ConvHF2F src)); 14945 format %{ "mov $tmp, $src\t# move source from $src to $tmp\n\t" 14946 "fcvt $dst, $tmp\t# convert half to single precision" 14947 %} 14948 effect(TEMP tmp); 14949 ins_encode %{ 14950 __ flt16_to_flt($dst$$FloatRegister, $src$$Register, $tmp$$FloatRegister); 14951 %} 14952 ins_pipe(pipe_slow); 14953 %} 14954 14955 instruct convI2F_reg_reg(vRegF dst, iRegIorL2I src) %{ 14956 match(Set dst (ConvI2F src)); 14957 14958 ins_cost(INSN_COST * 5); 14959 format %{ "scvtfws $dst, $src \t// i2f" %} 14960 14961 ins_encode %{ 14962 __ scvtfws(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14963 %} 14964 14965 ins_pipe(fp_i2f); 14966 %} 14967 14968 instruct convL2F_reg_reg(vRegF dst, iRegL src) %{ 14969 match(Set dst (ConvL2F src)); 14970 14971 ins_cost(INSN_COST * 5); 14972 format %{ "scvtfs $dst, $src \t// l2f" %} 14973 14974 ins_encode %{ 14975 __ scvtfs(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 14976 %} 14977 14978 ins_pipe(fp_l2f); 14979 %} 14980 14981 instruct convD2I_reg_reg(iRegINoSp dst, vRegD src) %{ 14982 match(Set dst (ConvD2I src)); 14983 14984 ins_cost(INSN_COST * 5); 14985 format %{ "fcvtzdw $dst, $src \t// d2i" %} 14986 14987 ins_encode %{ 14988 __ fcvtzdw(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 14989 %} 14990 14991 ins_pipe(fp_d2i); 14992 %} 14993 14994 instruct convD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 14995 match(Set dst (ConvD2L src)); 14996 14997 ins_cost(INSN_COST * 5); 14998 format %{ "fcvtzd $dst, $src \t// d2l" %} 14999 15000 ins_encode %{ 15001 __ fcvtzd(as_Register($dst$$reg), as_FloatRegister($src$$reg)); 15002 %} 15003 15004 ins_pipe(fp_d2l); 15005 %} 15006 15007 instruct convI2D_reg_reg(vRegD dst, iRegIorL2I src) %{ 15008 match(Set dst (ConvI2D src)); 15009 15010 ins_cost(INSN_COST * 5); 15011 format %{ "scvtfwd $dst, $src \t// i2d" %} 15012 15013 ins_encode %{ 15014 __ scvtfwd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 15015 %} 15016 15017 ins_pipe(fp_i2d); 15018 %} 15019 15020 instruct convL2D_reg_reg(vRegD dst, iRegL src) %{ 15021 match(Set dst (ConvL2D src)); 15022 15023 ins_cost(INSN_COST * 5); 15024 format %{ "scvtfd $dst, $src \t// l2d" %} 15025 15026 ins_encode %{ 15027 __ scvtfd(as_FloatRegister($dst$$reg), as_Register($src$$reg)); 15028 %} 15029 15030 ins_pipe(fp_l2d); 15031 %} 15032 15033 instruct round_double_reg(iRegLNoSp dst, vRegD src, vRegD ftmp, rFlagsReg cr) 15034 %{ 15035 match(Set dst (RoundD src)); 15036 effect(TEMP_DEF dst, TEMP ftmp, KILL cr); 15037 format %{ "java_round_double $dst,$src"%} 15038 ins_encode %{ 15039 __ java_round_double($dst$$Register, as_FloatRegister($src$$reg), 15040 as_FloatRegister($ftmp$$reg)); 15041 %} 15042 ins_pipe(pipe_slow); 15043 %} 15044 15045 instruct round_float_reg(iRegINoSp dst, vRegF src, vRegF ftmp, rFlagsReg cr) 15046 %{ 15047 match(Set dst (RoundF src)); 15048 effect(TEMP_DEF dst, TEMP ftmp, KILL cr); 15049 format %{ "java_round_float $dst,$src"%} 15050 ins_encode %{ 15051 __ java_round_float($dst$$Register, as_FloatRegister($src$$reg), 15052 as_FloatRegister($ftmp$$reg)); 15053 %} 15054 ins_pipe(pipe_slow); 15055 %} 15056 15057 // stack <-> reg and reg <-> reg shuffles with no conversion 15058 15059 instruct MoveF2I_stack_reg(iRegINoSp dst, stackSlotF src) %{ 15060 15061 match(Set dst (MoveF2I src)); 15062 15063 effect(DEF dst, USE src); 15064 15065 ins_cost(4 * INSN_COST); 15066 15067 format %{ "ldrw $dst, $src\t# MoveF2I_stack_reg" %} 15068 15069 ins_encode %{ 15070 __ ldrw($dst$$Register, Address(sp, $src$$disp)); 15071 %} 15072 15073 ins_pipe(iload_reg_reg); 15074 15075 %} 15076 15077 instruct MoveI2F_stack_reg(vRegF dst, stackSlotI src) %{ 15078 15079 match(Set dst (MoveI2F src)); 15080 15081 effect(DEF dst, USE src); 15082 15083 ins_cost(4 * INSN_COST); 15084 15085 format %{ "ldrs $dst, $src\t# MoveI2F_stack_reg" %} 15086 15087 ins_encode %{ 15088 __ ldrs(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 15089 %} 15090 15091 ins_pipe(pipe_class_memory); 15092 15093 %} 15094 15095 instruct MoveD2L_stack_reg(iRegLNoSp dst, stackSlotD src) %{ 15096 15097 match(Set dst (MoveD2L src)); 15098 15099 effect(DEF dst, USE src); 15100 15101 ins_cost(4 * INSN_COST); 15102 15103 format %{ "ldr $dst, $src\t# MoveD2L_stack_reg" %} 15104 15105 ins_encode %{ 15106 __ ldr($dst$$Register, Address(sp, $src$$disp)); 15107 %} 15108 15109 ins_pipe(iload_reg_reg); 15110 15111 %} 15112 15113 instruct MoveL2D_stack_reg(vRegD dst, stackSlotL src) %{ 15114 15115 match(Set dst (MoveL2D src)); 15116 15117 effect(DEF dst, USE src); 15118 15119 ins_cost(4 * INSN_COST); 15120 15121 format %{ "ldrd $dst, $src\t# MoveL2D_stack_reg" %} 15122 15123 ins_encode %{ 15124 __ ldrd(as_FloatRegister($dst$$reg), Address(sp, $src$$disp)); 15125 %} 15126 15127 ins_pipe(pipe_class_memory); 15128 15129 %} 15130 15131 instruct MoveF2I_reg_stack(stackSlotI dst, vRegF src) %{ 15132 15133 match(Set dst (MoveF2I src)); 15134 15135 effect(DEF dst, USE src); 15136 15137 ins_cost(INSN_COST); 15138 15139 format %{ "strs $src, $dst\t# MoveF2I_reg_stack" %} 15140 15141 ins_encode %{ 15142 __ strs(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 15143 %} 15144 15145 ins_pipe(pipe_class_memory); 15146 15147 %} 15148 15149 instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{ 15150 15151 match(Set dst (MoveI2F src)); 15152 15153 effect(DEF dst, USE src); 15154 15155 ins_cost(INSN_COST); 15156 15157 format %{ "strw $src, $dst\t# MoveI2F_reg_stack" %} 15158 15159 ins_encode %{ 15160 __ strw($src$$Register, Address(sp, $dst$$disp)); 15161 %} 15162 15163 ins_pipe(istore_reg_reg); 15164 15165 %} 15166 15167 instruct MoveD2L_reg_stack(stackSlotL dst, vRegD src) %{ 15168 15169 match(Set dst (MoveD2L src)); 15170 15171 effect(DEF dst, USE src); 15172 15173 ins_cost(INSN_COST); 15174 15175 format %{ "strd $dst, $src\t# MoveD2L_reg_stack" %} 15176 15177 ins_encode %{ 15178 __ strd(as_FloatRegister($src$$reg), Address(sp, $dst$$disp)); 15179 %} 15180 15181 ins_pipe(pipe_class_memory); 15182 15183 %} 15184 15185 instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{ 15186 15187 match(Set dst (MoveL2D src)); 15188 15189 effect(DEF dst, USE src); 15190 15191 ins_cost(INSN_COST); 15192 15193 format %{ "str $src, $dst\t# MoveL2D_reg_stack" %} 15194 15195 ins_encode %{ 15196 __ str($src$$Register, Address(sp, $dst$$disp)); 15197 %} 15198 15199 ins_pipe(istore_reg_reg); 15200 15201 %} 15202 15203 instruct MoveF2I_reg_reg(iRegINoSp dst, vRegF src) %{ 15204 15205 match(Set dst (MoveF2I src)); 15206 15207 effect(DEF dst, USE src); 15208 15209 ins_cost(INSN_COST); 15210 15211 format %{ "fmovs $dst, $src\t# MoveF2I_reg_reg" %} 15212 15213 ins_encode %{ 15214 __ fmovs($dst$$Register, as_FloatRegister($src$$reg)); 15215 %} 15216 15217 ins_pipe(fp_f2i); 15218 15219 %} 15220 15221 instruct MoveI2F_reg_reg(vRegF dst, iRegI src) %{ 15222 15223 match(Set dst (MoveI2F src)); 15224 15225 effect(DEF dst, USE src); 15226 15227 ins_cost(INSN_COST); 15228 15229 format %{ "fmovs $dst, $src\t# MoveI2F_reg_reg" %} 15230 15231 ins_encode %{ 15232 __ fmovs(as_FloatRegister($dst$$reg), $src$$Register); 15233 %} 15234 15235 ins_pipe(fp_i2f); 15236 15237 %} 15238 15239 instruct MoveD2L_reg_reg(iRegLNoSp dst, vRegD src) %{ 15240 15241 match(Set dst (MoveD2L src)); 15242 15243 effect(DEF dst, USE src); 15244 15245 ins_cost(INSN_COST); 15246 15247 format %{ "fmovd $dst, $src\t# MoveD2L_reg_reg" %} 15248 15249 ins_encode %{ 15250 __ fmovd($dst$$Register, as_FloatRegister($src$$reg)); 15251 %} 15252 15253 ins_pipe(fp_d2l); 15254 15255 %} 15256 15257 instruct MoveL2D_reg_reg(vRegD dst, iRegL src) %{ 15258 15259 match(Set dst (MoveL2D src)); 15260 15261 effect(DEF dst, USE src); 15262 15263 ins_cost(INSN_COST); 15264 15265 format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %} 15266 15267 ins_encode %{ 15268 __ fmovd(as_FloatRegister($dst$$reg), $src$$Register); 15269 %} 15270 15271 ins_pipe(fp_l2d); 15272 15273 %} 15274 15275 // ============================================================================ 15276 // clearing of an array 15277 15278 instruct clearArray_reg_reg_immL0(iRegL_R11 cnt, iRegP_R10 base, immL0 zero, Universe dummy, rFlagsReg cr) 15279 %{ 15280 match(Set dummy (ClearArray (Binary cnt base) zero)); 15281 effect(USE_KILL cnt, USE_KILL base, KILL cr); 15282 15283 ins_cost(4 * INSN_COST); 15284 format %{ "ClearArray $cnt, $base" %} 15285 15286 ins_encode %{ 15287 address tpc = __ zero_words($base$$Register, $cnt$$Register); 15288 if (tpc == nullptr) { 15289 ciEnv::current()->record_failure("CodeCache is full"); 15290 return; 15291 } 15292 %} 15293 15294 ins_pipe(pipe_class_memory); 15295 %} 15296 15297 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, iRegL val, Universe dummy, rFlagsReg cr) 15298 %{ 15299 predicate(((ClearArrayNode*)n)->word_copy_only()); 15300 match(Set dummy (ClearArray (Binary cnt base) val)); 15301 effect(USE_KILL cnt, USE_KILL base, KILL cr); 15302 15303 ins_cost(4 * INSN_COST); 15304 format %{ "ClearArray $cnt, $base, $val" %} 15305 15306 ins_encode %{ 15307 __ fill_words($base$$Register, $cnt$$Register, $val$$Register); 15308 %} 15309 15310 ins_pipe(pipe_class_memory); 15311 %} 15312 15313 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, iRegL_R11 temp, Universe dummy, rFlagsReg cr) 15314 %{ 15315 predicate((uint64_t)n->in(2)->get_long() 15316 < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord) 15317 && !((ClearArrayNode*)n)->word_copy_only()); 15318 match(Set dummy (ClearArray cnt base)); 15319 effect(TEMP temp, USE_KILL base, KILL cr); 15320 15321 ins_cost(4 * INSN_COST); 15322 format %{ "ClearArray $cnt, $base" %} 15323 15324 ins_encode %{ 15325 address tpc = __ zero_words($base$$Register, (uint64_t)$cnt$$constant); 15326 if (tpc == nullptr) { 15327 ciEnv::current()->record_failure("CodeCache is full"); 15328 return; 15329 } 15330 %} 15331 15332 ins_pipe(pipe_class_memory); 15333 %} 15334 15335 // ============================================================================ 15336 // Overflow Math Instructions 15337 15338 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 15339 %{ 15340 match(Set cr (OverflowAddI op1 op2)); 15341 15342 format %{ "cmnw $op1, $op2\t# overflow check int" %} 15343 ins_cost(INSN_COST); 15344 ins_encode %{ 15345 __ cmnw($op1$$Register, $op2$$Register); 15346 %} 15347 15348 ins_pipe(icmp_reg_reg); 15349 %} 15350 15351 instruct overflowAddI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 15352 %{ 15353 match(Set cr (OverflowAddI op1 op2)); 15354 15355 format %{ "cmnw $op1, $op2\t# overflow check int" %} 15356 ins_cost(INSN_COST); 15357 ins_encode %{ 15358 __ cmnw($op1$$Register, $op2$$constant); 15359 %} 15360 15361 ins_pipe(icmp_reg_imm); 15362 %} 15363 15364 instruct overflowAddL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15365 %{ 15366 match(Set cr (OverflowAddL op1 op2)); 15367 15368 format %{ "cmn $op1, $op2\t# overflow check long" %} 15369 ins_cost(INSN_COST); 15370 ins_encode %{ 15371 __ cmn($op1$$Register, $op2$$Register); 15372 %} 15373 15374 ins_pipe(icmp_reg_reg); 15375 %} 15376 15377 instruct overflowAddL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 15378 %{ 15379 match(Set cr (OverflowAddL op1 op2)); 15380 15381 format %{ "adds zr, $op1, $op2\t# overflow check long" %} 15382 ins_cost(INSN_COST); 15383 ins_encode %{ 15384 __ adds(zr, $op1$$Register, $op2$$constant); 15385 %} 15386 15387 ins_pipe(icmp_reg_imm); 15388 %} 15389 15390 instruct overflowSubI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 15391 %{ 15392 match(Set cr (OverflowSubI op1 op2)); 15393 15394 format %{ "cmpw $op1, $op2\t# overflow check int" %} 15395 ins_cost(INSN_COST); 15396 ins_encode %{ 15397 __ cmpw($op1$$Register, $op2$$Register); 15398 %} 15399 15400 ins_pipe(icmp_reg_reg); 15401 %} 15402 15403 instruct overflowSubI_reg_imm(rFlagsReg cr, iRegIorL2I op1, immIAddSub op2) 15404 %{ 15405 match(Set cr (OverflowSubI op1 op2)); 15406 15407 format %{ "cmpw $op1, $op2\t# overflow check int" %} 15408 ins_cost(INSN_COST); 15409 ins_encode %{ 15410 __ cmpw($op1$$Register, $op2$$constant); 15411 %} 15412 15413 ins_pipe(icmp_reg_imm); 15414 %} 15415 15416 instruct overflowSubL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15417 %{ 15418 match(Set cr (OverflowSubL op1 op2)); 15419 15420 format %{ "cmp $op1, $op2\t# overflow check long" %} 15421 ins_cost(INSN_COST); 15422 ins_encode %{ 15423 __ cmp($op1$$Register, $op2$$Register); 15424 %} 15425 15426 ins_pipe(icmp_reg_reg); 15427 %} 15428 15429 instruct overflowSubL_reg_imm(rFlagsReg cr, iRegL op1, immLAddSub op2) 15430 %{ 15431 match(Set cr (OverflowSubL op1 op2)); 15432 15433 format %{ "cmp $op1, $op2\t# overflow check long" %} 15434 ins_cost(INSN_COST); 15435 ins_encode %{ 15436 __ subs(zr, $op1$$Register, $op2$$constant); 15437 %} 15438 15439 ins_pipe(icmp_reg_imm); 15440 %} 15441 15442 instruct overflowNegI_reg(rFlagsReg cr, immI0 zero, iRegIorL2I op1) 15443 %{ 15444 match(Set cr (OverflowSubI zero op1)); 15445 15446 format %{ "cmpw zr, $op1\t# overflow check int" %} 15447 ins_cost(INSN_COST); 15448 ins_encode %{ 15449 __ cmpw(zr, $op1$$Register); 15450 %} 15451 15452 ins_pipe(icmp_reg_imm); 15453 %} 15454 15455 instruct overflowNegL_reg(rFlagsReg cr, immI0 zero, iRegL op1) 15456 %{ 15457 match(Set cr (OverflowSubL zero op1)); 15458 15459 format %{ "cmp zr, $op1\t# overflow check long" %} 15460 ins_cost(INSN_COST); 15461 ins_encode %{ 15462 __ cmp(zr, $op1$$Register); 15463 %} 15464 15465 ins_pipe(icmp_reg_imm); 15466 %} 15467 15468 instruct overflowMulI_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2) 15469 %{ 15470 match(Set cr (OverflowMulI op1 op2)); 15471 15472 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 15473 "cmp rscratch1, rscratch1, sxtw\n\t" 15474 "movw rscratch1, #0x80000000\n\t" 15475 "cselw rscratch1, rscratch1, zr, NE\n\t" 15476 "cmpw rscratch1, #1" %} 15477 ins_cost(5 * INSN_COST); 15478 ins_encode %{ 15479 __ smull(rscratch1, $op1$$Register, $op2$$Register); 15480 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 15481 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 15482 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 15483 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 15484 %} 15485 15486 ins_pipe(pipe_slow); 15487 %} 15488 15489 instruct overflowMulI_reg_branch(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, label labl, rFlagsReg cr) 15490 %{ 15491 match(If cmp (OverflowMulI op1 op2)); 15492 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 15493 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 15494 effect(USE labl, KILL cr); 15495 15496 format %{ "smull rscratch1, $op1, $op2\t# overflow check int\n\t" 15497 "cmp rscratch1, rscratch1, sxtw\n\t" 15498 "b$cmp $labl" %} 15499 ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST 15500 ins_encode %{ 15501 Label* L = $labl$$label; 15502 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15503 __ smull(rscratch1, $op1$$Register, $op2$$Register); 15504 __ subs(zr, rscratch1, rscratch1, ext::sxtw); // NE => overflow 15505 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 15506 %} 15507 15508 ins_pipe(pipe_serial); 15509 %} 15510 15511 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15512 %{ 15513 match(Set cr (OverflowMulL op1 op2)); 15514 15515 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 15516 "smulh rscratch2, $op1, $op2\n\t" 15517 "cmp rscratch2, rscratch1, ASR #63\n\t" 15518 "movw rscratch1, #0x80000000\n\t" 15519 "cselw rscratch1, rscratch1, zr, NE\n\t" 15520 "cmpw rscratch1, #1" %} 15521 ins_cost(6 * INSN_COST); 15522 ins_encode %{ 15523 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 15524 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 15525 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 15526 __ movw(rscratch1, 0x80000000); // Develop 0 (EQ), 15527 __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE) 15528 __ cmpw(rscratch1, 1); // 0x80000000 - 1 => VS 15529 %} 15530 15531 ins_pipe(pipe_slow); 15532 %} 15533 15534 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr) 15535 %{ 15536 match(If cmp (OverflowMulL op1 op2)); 15537 predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow 15538 || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow); 15539 effect(USE labl, KILL cr); 15540 15541 format %{ "mul rscratch1, $op1, $op2\t#overflow check long\n\t" 15542 "smulh rscratch2, $op1, $op2\n\t" 15543 "cmp rscratch2, rscratch1, ASR #63\n\t" 15544 "b$cmp $labl" %} 15545 ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST 15546 ins_encode %{ 15547 Label* L = $labl$$label; 15548 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 15549 __ mul(rscratch1, $op1$$Register, $op2$$Register); // Result bits 0..63 15550 __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127 15551 __ cmp(rscratch2, rscratch1, Assembler::ASR, 63); // Top is pure sign ext 15552 __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L); 15553 %} 15554 15555 ins_pipe(pipe_serial); 15556 %} 15557 15558 // ============================================================================ 15559 // Compare Instructions 15560 15561 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2) 15562 %{ 15563 match(Set cr (CmpI op1 op2)); 15564 15565 effect(DEF cr, USE op1, USE op2); 15566 15567 ins_cost(INSN_COST); 15568 format %{ "cmpw $op1, $op2" %} 15569 15570 ins_encode(aarch64_enc_cmpw(op1, op2)); 15571 15572 ins_pipe(icmp_reg_reg); 15573 %} 15574 15575 instruct compI_reg_immI0(rFlagsReg cr, iRegI op1, immI0 zero) 15576 %{ 15577 match(Set cr (CmpI op1 zero)); 15578 15579 effect(DEF cr, USE op1); 15580 15581 ins_cost(INSN_COST); 15582 format %{ "cmpw $op1, 0" %} 15583 15584 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 15585 15586 ins_pipe(icmp_reg_imm); 15587 %} 15588 15589 instruct compI_reg_immIAddSub(rFlagsReg cr, iRegI op1, immIAddSub op2) 15590 %{ 15591 match(Set cr (CmpI op1 op2)); 15592 15593 effect(DEF cr, USE op1); 15594 15595 ins_cost(INSN_COST); 15596 format %{ "cmpw $op1, $op2" %} 15597 15598 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 15599 15600 ins_pipe(icmp_reg_imm); 15601 %} 15602 15603 instruct compI_reg_immI(rFlagsReg cr, iRegI op1, immI op2) 15604 %{ 15605 match(Set cr (CmpI op1 op2)); 15606 15607 effect(DEF cr, USE op1); 15608 15609 ins_cost(INSN_COST * 2); 15610 format %{ "cmpw $op1, $op2" %} 15611 15612 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 15613 15614 ins_pipe(icmp_reg_imm); 15615 %} 15616 15617 // Unsigned compare Instructions; really, same as signed compare 15618 // except it should only be used to feed an If or a CMovI which takes a 15619 // cmpOpU. 15620 15621 instruct compU_reg_reg(rFlagsRegU cr, iRegI op1, iRegI op2) 15622 %{ 15623 match(Set cr (CmpU op1 op2)); 15624 15625 effect(DEF cr, USE op1, USE op2); 15626 15627 ins_cost(INSN_COST); 15628 format %{ "cmpw $op1, $op2\t# unsigned" %} 15629 15630 ins_encode(aarch64_enc_cmpw(op1, op2)); 15631 15632 ins_pipe(icmp_reg_reg); 15633 %} 15634 15635 instruct compU_reg_immI0(rFlagsRegU cr, iRegI op1, immI0 zero) 15636 %{ 15637 match(Set cr (CmpU op1 zero)); 15638 15639 effect(DEF cr, USE op1); 15640 15641 ins_cost(INSN_COST); 15642 format %{ "cmpw $op1, #0\t# unsigned" %} 15643 15644 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, zero)); 15645 15646 ins_pipe(icmp_reg_imm); 15647 %} 15648 15649 instruct compU_reg_immIAddSub(rFlagsRegU cr, iRegI op1, immIAddSub op2) 15650 %{ 15651 match(Set cr (CmpU op1 op2)); 15652 15653 effect(DEF cr, USE op1); 15654 15655 ins_cost(INSN_COST); 15656 format %{ "cmpw $op1, $op2\t# unsigned" %} 15657 15658 ins_encode(aarch64_enc_cmpw_imm_addsub(op1, op2)); 15659 15660 ins_pipe(icmp_reg_imm); 15661 %} 15662 15663 instruct compU_reg_immI(rFlagsRegU cr, iRegI op1, immI op2) 15664 %{ 15665 match(Set cr (CmpU op1 op2)); 15666 15667 effect(DEF cr, USE op1); 15668 15669 ins_cost(INSN_COST * 2); 15670 format %{ "cmpw $op1, $op2\t# unsigned" %} 15671 15672 ins_encode(aarch64_enc_cmpw_imm(op1, op2)); 15673 15674 ins_pipe(icmp_reg_imm); 15675 %} 15676 15677 instruct compL_reg_reg(rFlagsReg cr, iRegL op1, iRegL op2) 15678 %{ 15679 match(Set cr (CmpL op1 op2)); 15680 15681 effect(DEF cr, USE op1, USE op2); 15682 15683 ins_cost(INSN_COST); 15684 format %{ "cmp $op1, $op2" %} 15685 15686 ins_encode(aarch64_enc_cmp(op1, op2)); 15687 15688 ins_pipe(icmp_reg_reg); 15689 %} 15690 15691 instruct compL_reg_immL0(rFlagsReg cr, iRegL op1, immL0 zero) 15692 %{ 15693 match(Set cr (CmpL op1 zero)); 15694 15695 effect(DEF cr, USE op1); 15696 15697 ins_cost(INSN_COST); 15698 format %{ "tst $op1" %} 15699 15700 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 15701 15702 ins_pipe(icmp_reg_imm); 15703 %} 15704 15705 instruct compL_reg_immLAddSub(rFlagsReg cr, iRegL op1, immLAddSub op2) 15706 %{ 15707 match(Set cr (CmpL op1 op2)); 15708 15709 effect(DEF cr, USE op1); 15710 15711 ins_cost(INSN_COST); 15712 format %{ "cmp $op1, $op2" %} 15713 15714 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 15715 15716 ins_pipe(icmp_reg_imm); 15717 %} 15718 15719 instruct compL_reg_immL(rFlagsReg cr, iRegL op1, immL op2) 15720 %{ 15721 match(Set cr (CmpL op1 op2)); 15722 15723 effect(DEF cr, USE op1); 15724 15725 ins_cost(INSN_COST * 2); 15726 format %{ "cmp $op1, $op2" %} 15727 15728 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 15729 15730 ins_pipe(icmp_reg_imm); 15731 %} 15732 15733 instruct compUL_reg_reg(rFlagsRegU cr, iRegL op1, iRegL op2) 15734 %{ 15735 match(Set cr (CmpUL op1 op2)); 15736 15737 effect(DEF cr, USE op1, USE op2); 15738 15739 ins_cost(INSN_COST); 15740 format %{ "cmp $op1, $op2" %} 15741 15742 ins_encode(aarch64_enc_cmp(op1, op2)); 15743 15744 ins_pipe(icmp_reg_reg); 15745 %} 15746 15747 instruct compUL_reg_immL0(rFlagsRegU cr, iRegL op1, immL0 zero) 15748 %{ 15749 match(Set cr (CmpUL op1 zero)); 15750 15751 effect(DEF cr, USE op1); 15752 15753 ins_cost(INSN_COST); 15754 format %{ "tst $op1" %} 15755 15756 ins_encode(aarch64_enc_cmp_imm_addsub(op1, zero)); 15757 15758 ins_pipe(icmp_reg_imm); 15759 %} 15760 15761 instruct compUL_reg_immLAddSub(rFlagsRegU cr, iRegL op1, immLAddSub op2) 15762 %{ 15763 match(Set cr (CmpUL op1 op2)); 15764 15765 effect(DEF cr, USE op1); 15766 15767 ins_cost(INSN_COST); 15768 format %{ "cmp $op1, $op2" %} 15769 15770 ins_encode(aarch64_enc_cmp_imm_addsub(op1, op2)); 15771 15772 ins_pipe(icmp_reg_imm); 15773 %} 15774 15775 instruct compUL_reg_immL(rFlagsRegU cr, iRegL op1, immL op2) 15776 %{ 15777 match(Set cr (CmpUL op1 op2)); 15778 15779 effect(DEF cr, USE op1); 15780 15781 ins_cost(INSN_COST * 2); 15782 format %{ "cmp $op1, $op2" %} 15783 15784 ins_encode(aarch64_enc_cmp_imm(op1, op2)); 15785 15786 ins_pipe(icmp_reg_imm); 15787 %} 15788 15789 instruct compP_reg_reg(rFlagsRegU cr, iRegP op1, iRegP op2) 15790 %{ 15791 match(Set cr (CmpP op1 op2)); 15792 15793 effect(DEF cr, USE op1, USE op2); 15794 15795 ins_cost(INSN_COST); 15796 format %{ "cmp $op1, $op2\t // ptr" %} 15797 15798 ins_encode(aarch64_enc_cmpp(op1, op2)); 15799 15800 ins_pipe(icmp_reg_reg); 15801 %} 15802 15803 instruct compN_reg_reg(rFlagsRegU cr, iRegN op1, iRegN op2) 15804 %{ 15805 match(Set cr (CmpN op1 op2)); 15806 15807 effect(DEF cr, USE op1, USE op2); 15808 15809 ins_cost(INSN_COST); 15810 format %{ "cmp $op1, $op2\t // compressed ptr" %} 15811 15812 ins_encode(aarch64_enc_cmpn(op1, op2)); 15813 15814 ins_pipe(icmp_reg_reg); 15815 %} 15816 15817 instruct testP_reg(rFlagsRegU cr, iRegP op1, immP0 zero) 15818 %{ 15819 match(Set cr (CmpP op1 zero)); 15820 15821 effect(DEF cr, USE op1, USE zero); 15822 15823 ins_cost(INSN_COST); 15824 format %{ "cmp $op1, 0\t // ptr" %} 15825 15826 ins_encode(aarch64_enc_testp(op1)); 15827 15828 ins_pipe(icmp_reg_imm); 15829 %} 15830 15831 instruct testN_reg(rFlagsRegU cr, iRegN op1, immN0 zero) 15832 %{ 15833 match(Set cr (CmpN op1 zero)); 15834 15835 effect(DEF cr, USE op1, USE zero); 15836 15837 ins_cost(INSN_COST); 15838 format %{ "cmp $op1, 0\t // compressed ptr" %} 15839 15840 ins_encode(aarch64_enc_testn(op1)); 15841 15842 ins_pipe(icmp_reg_imm); 15843 %} 15844 15845 // FP comparisons 15846 // 15847 // n.b. CmpF/CmpD set a normal flags reg which then gets compared 15848 // using normal cmpOp. See declaration of rFlagsReg for details. 15849 15850 instruct compF_reg_reg(rFlagsReg cr, vRegF src1, vRegF src2) 15851 %{ 15852 match(Set cr (CmpF src1 src2)); 15853 15854 ins_cost(3 * INSN_COST); 15855 format %{ "fcmps $src1, $src2" %} 15856 15857 ins_encode %{ 15858 __ fcmps(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15859 %} 15860 15861 ins_pipe(pipe_class_compare); 15862 %} 15863 15864 instruct compF_reg_zero(rFlagsReg cr, vRegF src1, immF0 src2) 15865 %{ 15866 match(Set cr (CmpF src1 src2)); 15867 15868 ins_cost(3 * INSN_COST); 15869 format %{ "fcmps $src1, 0.0" %} 15870 15871 ins_encode %{ 15872 __ fcmps(as_FloatRegister($src1$$reg), 0.0); 15873 %} 15874 15875 ins_pipe(pipe_class_compare); 15876 %} 15877 // FROM HERE 15878 15879 instruct compD_reg_reg(rFlagsReg cr, vRegD src1, vRegD src2) 15880 %{ 15881 match(Set cr (CmpD src1 src2)); 15882 15883 ins_cost(3 * INSN_COST); 15884 format %{ "fcmpd $src1, $src2" %} 15885 15886 ins_encode %{ 15887 __ fcmpd(as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); 15888 %} 15889 15890 ins_pipe(pipe_class_compare); 15891 %} 15892 15893 instruct compD_reg_zero(rFlagsReg cr, vRegD src1, immD0 src2) 15894 %{ 15895 match(Set cr (CmpD src1 src2)); 15896 15897 ins_cost(3 * INSN_COST); 15898 format %{ "fcmpd $src1, 0.0" %} 15899 15900 ins_encode %{ 15901 __ fcmpd(as_FloatRegister($src1$$reg), 0.0); 15902 %} 15903 15904 ins_pipe(pipe_class_compare); 15905 %} 15906 15907 instruct compF3_reg_reg(iRegINoSp dst, vRegF src1, vRegF src2, rFlagsReg cr) 15908 %{ 15909 match(Set dst (CmpF3 src1 src2)); 15910 effect(KILL cr); 15911 15912 ins_cost(5 * INSN_COST); 15913 format %{ "fcmps $src1, $src2\n\t" 15914 "csinvw($dst, zr, zr, eq\n\t" 15915 "csnegw($dst, $dst, $dst, lt)" 15916 %} 15917 15918 ins_encode %{ 15919 Label done; 15920 FloatRegister s1 = as_FloatRegister($src1$$reg); 15921 FloatRegister s2 = as_FloatRegister($src2$$reg); 15922 Register d = as_Register($dst$$reg); 15923 __ fcmps(s1, s2); 15924 // installs 0 if EQ else -1 15925 __ csinvw(d, zr, zr, Assembler::EQ); 15926 // keeps -1 if less or unordered else installs 1 15927 __ csnegw(d, d, d, Assembler::LT); 15928 __ bind(done); 15929 %} 15930 15931 ins_pipe(pipe_class_default); 15932 15933 %} 15934 15935 instruct compD3_reg_reg(iRegINoSp dst, vRegD src1, vRegD src2, rFlagsReg cr) 15936 %{ 15937 match(Set dst (CmpD3 src1 src2)); 15938 effect(KILL cr); 15939 15940 ins_cost(5 * INSN_COST); 15941 format %{ "fcmpd $src1, $src2\n\t" 15942 "csinvw($dst, zr, zr, eq\n\t" 15943 "csnegw($dst, $dst, $dst, lt)" 15944 %} 15945 15946 ins_encode %{ 15947 Label done; 15948 FloatRegister s1 = as_FloatRegister($src1$$reg); 15949 FloatRegister s2 = as_FloatRegister($src2$$reg); 15950 Register d = as_Register($dst$$reg); 15951 __ fcmpd(s1, s2); 15952 // installs 0 if EQ else -1 15953 __ csinvw(d, zr, zr, Assembler::EQ); 15954 // keeps -1 if less or unordered else installs 1 15955 __ csnegw(d, d, d, Assembler::LT); 15956 __ bind(done); 15957 %} 15958 ins_pipe(pipe_class_default); 15959 15960 %} 15961 15962 instruct compF3_reg_immF0(iRegINoSp dst, vRegF src1, immF0 zero, rFlagsReg cr) 15963 %{ 15964 match(Set dst (CmpF3 src1 zero)); 15965 effect(KILL cr); 15966 15967 ins_cost(5 * INSN_COST); 15968 format %{ "fcmps $src1, 0.0\n\t" 15969 "csinvw($dst, zr, zr, eq\n\t" 15970 "csnegw($dst, $dst, $dst, lt)" 15971 %} 15972 15973 ins_encode %{ 15974 Label done; 15975 FloatRegister s1 = as_FloatRegister($src1$$reg); 15976 Register d = as_Register($dst$$reg); 15977 __ fcmps(s1, 0.0); 15978 // installs 0 if EQ else -1 15979 __ csinvw(d, zr, zr, Assembler::EQ); 15980 // keeps -1 if less or unordered else installs 1 15981 __ csnegw(d, d, d, Assembler::LT); 15982 __ bind(done); 15983 %} 15984 15985 ins_pipe(pipe_class_default); 15986 15987 %} 15988 15989 instruct compD3_reg_immD0(iRegINoSp dst, vRegD src1, immD0 zero, rFlagsReg cr) 15990 %{ 15991 match(Set dst (CmpD3 src1 zero)); 15992 effect(KILL cr); 15993 15994 ins_cost(5 * INSN_COST); 15995 format %{ "fcmpd $src1, 0.0\n\t" 15996 "csinvw($dst, zr, zr, eq\n\t" 15997 "csnegw($dst, $dst, $dst, lt)" 15998 %} 15999 16000 ins_encode %{ 16001 Label done; 16002 FloatRegister s1 = as_FloatRegister($src1$$reg); 16003 Register d = as_Register($dst$$reg); 16004 __ fcmpd(s1, 0.0); 16005 // installs 0 if EQ else -1 16006 __ csinvw(d, zr, zr, Assembler::EQ); 16007 // keeps -1 if less or unordered else installs 1 16008 __ csnegw(d, d, d, Assembler::LT); 16009 __ bind(done); 16010 %} 16011 ins_pipe(pipe_class_default); 16012 16013 %} 16014 16015 instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegIorL2I p, iRegIorL2I q, rFlagsReg cr) 16016 %{ 16017 match(Set dst (CmpLTMask p q)); 16018 effect(KILL cr); 16019 16020 ins_cost(3 * INSN_COST); 16021 16022 format %{ "cmpw $p, $q\t# cmpLTMask\n\t" 16023 "csetw $dst, lt\n\t" 16024 "subw $dst, zr, $dst" 16025 %} 16026 16027 ins_encode %{ 16028 __ cmpw(as_Register($p$$reg), as_Register($q$$reg)); 16029 __ csetw(as_Register($dst$$reg), Assembler::LT); 16030 __ subw(as_Register($dst$$reg), zr, as_Register($dst$$reg)); 16031 %} 16032 16033 ins_pipe(ialu_reg_reg); 16034 %} 16035 16036 instruct cmpLTMask_reg_zero(iRegINoSp dst, iRegIorL2I src, immI0 zero, rFlagsReg cr) 16037 %{ 16038 match(Set dst (CmpLTMask src zero)); 16039 effect(KILL cr); 16040 16041 ins_cost(INSN_COST); 16042 16043 format %{ "asrw $dst, $src, #31\t# cmpLTMask0" %} 16044 16045 ins_encode %{ 16046 __ asrw(as_Register($dst$$reg), as_Register($src$$reg), 31); 16047 %} 16048 16049 ins_pipe(ialu_reg_shift); 16050 %} 16051 16052 // ============================================================================ 16053 // Max and Min 16054 16055 // Like compI_reg_reg or compI_reg_immI0 but without match rule and second zero parameter. 16056 16057 instruct compI_reg_imm0(rFlagsReg cr, iRegI src) 16058 %{ 16059 effect(DEF cr, USE src); 16060 ins_cost(INSN_COST); 16061 format %{ "cmpw $src, 0" %} 16062 16063 ins_encode %{ 16064 __ cmpw($src$$Register, 0); 16065 %} 16066 ins_pipe(icmp_reg_imm); 16067 %} 16068 16069 instruct minI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) 16070 %{ 16071 match(Set dst (MinI src1 src2)); 16072 ins_cost(INSN_COST * 3); 16073 16074 expand %{ 16075 rFlagsReg cr; 16076 compI_reg_reg(cr, src1, src2); 16077 cmovI_reg_reg_lt(dst, src1, src2, cr); 16078 %} 16079 %} 16080 16081 instruct maxI_reg_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) 16082 %{ 16083 match(Set dst (MaxI src1 src2)); 16084 ins_cost(INSN_COST * 3); 16085 16086 expand %{ 16087 rFlagsReg cr; 16088 compI_reg_reg(cr, src1, src2); 16089 cmovI_reg_reg_gt(dst, src1, src2, cr); 16090 %} 16091 %} 16092 16093 16094 // ============================================================================ 16095 // Branch Instructions 16096 16097 // Direct Branch. 16098 instruct branch(label lbl) 16099 %{ 16100 match(Goto); 16101 16102 effect(USE lbl); 16103 16104 ins_cost(BRANCH_COST); 16105 format %{ "b $lbl" %} 16106 16107 ins_encode(aarch64_enc_b(lbl)); 16108 16109 ins_pipe(pipe_branch); 16110 %} 16111 16112 // Conditional Near Branch 16113 instruct branchCon(cmpOp cmp, rFlagsReg cr, label lbl) 16114 %{ 16115 // Same match rule as `branchConFar'. 16116 match(If cmp cr); 16117 16118 effect(USE lbl); 16119 16120 ins_cost(BRANCH_COST); 16121 // If set to 1 this indicates that the current instruction is a 16122 // short variant of a long branch. This avoids using this 16123 // instruction in first-pass matching. It will then only be used in 16124 // the `Shorten_branches' pass. 16125 // ins_short_branch(1); 16126 format %{ "b$cmp $lbl" %} 16127 16128 ins_encode(aarch64_enc_br_con(cmp, lbl)); 16129 16130 ins_pipe(pipe_branch_cond); 16131 %} 16132 16133 // Conditional Near Branch Unsigned 16134 instruct branchConU(cmpOpU cmp, rFlagsRegU cr, label lbl) 16135 %{ 16136 // Same match rule as `branchConFar'. 16137 match(If cmp cr); 16138 16139 effect(USE lbl); 16140 16141 ins_cost(BRANCH_COST); 16142 // If set to 1 this indicates that the current instruction is a 16143 // short variant of a long branch. This avoids using this 16144 // instruction in first-pass matching. It will then only be used in 16145 // the `Shorten_branches' pass. 16146 // ins_short_branch(1); 16147 format %{ "b$cmp $lbl\t# unsigned" %} 16148 16149 ins_encode(aarch64_enc_br_conU(cmp, lbl)); 16150 16151 ins_pipe(pipe_branch_cond); 16152 %} 16153 16154 // Make use of CBZ and CBNZ. These instructions, as well as being 16155 // shorter than (cmp; branch), have the additional benefit of not 16156 // killing the flags. 16157 16158 instruct cmpI_imm0_branch(cmpOpEqNe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{ 16159 match(If cmp (CmpI op1 op2)); 16160 effect(USE labl); 16161 16162 ins_cost(BRANCH_COST); 16163 format %{ "cbw$cmp $op1, $labl" %} 16164 ins_encode %{ 16165 Label* L = $labl$$label; 16166 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16167 if (cond == Assembler::EQ) 16168 __ cbzw($op1$$Register, *L); 16169 else 16170 __ cbnzw($op1$$Register, *L); 16171 %} 16172 ins_pipe(pipe_cmp_branch); 16173 %} 16174 16175 instruct cmpL_imm0_branch(cmpOpEqNe cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{ 16176 match(If cmp (CmpL op1 op2)); 16177 effect(USE labl); 16178 16179 ins_cost(BRANCH_COST); 16180 format %{ "cb$cmp $op1, $labl" %} 16181 ins_encode %{ 16182 Label* L = $labl$$label; 16183 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16184 if (cond == Assembler::EQ) 16185 __ cbz($op1$$Register, *L); 16186 else 16187 __ cbnz($op1$$Register, *L); 16188 %} 16189 ins_pipe(pipe_cmp_branch); 16190 %} 16191 16192 instruct cmpP_imm0_branch(cmpOpEqNe cmp, iRegP op1, immP0 op2, label labl, rFlagsReg cr) %{ 16193 match(If cmp (CmpP op1 op2)); 16194 effect(USE labl); 16195 16196 ins_cost(BRANCH_COST); 16197 format %{ "cb$cmp $op1, $labl" %} 16198 ins_encode %{ 16199 Label* L = $labl$$label; 16200 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16201 if (cond == Assembler::EQ) 16202 __ cbz($op1$$Register, *L); 16203 else 16204 __ cbnz($op1$$Register, *L); 16205 %} 16206 ins_pipe(pipe_cmp_branch); 16207 %} 16208 16209 instruct cmpN_imm0_branch(cmpOpEqNe cmp, iRegN op1, immN0 op2, label labl, rFlagsReg cr) %{ 16210 match(If cmp (CmpN op1 op2)); 16211 effect(USE labl); 16212 16213 ins_cost(BRANCH_COST); 16214 format %{ "cbw$cmp $op1, $labl" %} 16215 ins_encode %{ 16216 Label* L = $labl$$label; 16217 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16218 if (cond == Assembler::EQ) 16219 __ cbzw($op1$$Register, *L); 16220 else 16221 __ cbnzw($op1$$Register, *L); 16222 %} 16223 ins_pipe(pipe_cmp_branch); 16224 %} 16225 16226 instruct cmpP_narrowOop_imm0_branch(cmpOpEqNe cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{ 16227 match(If cmp (CmpP (DecodeN oop) zero)); 16228 effect(USE labl); 16229 16230 ins_cost(BRANCH_COST); 16231 format %{ "cb$cmp $oop, $labl" %} 16232 ins_encode %{ 16233 Label* L = $labl$$label; 16234 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16235 if (cond == Assembler::EQ) 16236 __ cbzw($oop$$Register, *L); 16237 else 16238 __ cbnzw($oop$$Register, *L); 16239 %} 16240 ins_pipe(pipe_cmp_branch); 16241 %} 16242 16243 instruct cmpUI_imm0_branch(cmpOpUEqNeLtGe cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsRegU cr) %{ 16244 match(If cmp (CmpU op1 op2)); 16245 effect(USE labl); 16246 16247 ins_cost(BRANCH_COST); 16248 format %{ "cbw$cmp $op1, $labl" %} 16249 ins_encode %{ 16250 Label* L = $labl$$label; 16251 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16252 if (cond == Assembler::EQ || cond == Assembler::LS) 16253 __ cbzw($op1$$Register, *L); 16254 else 16255 __ cbnzw($op1$$Register, *L); 16256 %} 16257 ins_pipe(pipe_cmp_branch); 16258 %} 16259 16260 instruct cmpUL_imm0_branch(cmpOpUEqNeLtGe cmp, iRegL op1, immL0 op2, label labl, rFlagsRegU cr) %{ 16261 match(If cmp (CmpUL op1 op2)); 16262 effect(USE labl); 16263 16264 ins_cost(BRANCH_COST); 16265 format %{ "cb$cmp $op1, $labl" %} 16266 ins_encode %{ 16267 Label* L = $labl$$label; 16268 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16269 if (cond == Assembler::EQ || cond == Assembler::LS) 16270 __ cbz($op1$$Register, *L); 16271 else 16272 __ cbnz($op1$$Register, *L); 16273 %} 16274 ins_pipe(pipe_cmp_branch); 16275 %} 16276 16277 // Test bit and Branch 16278 16279 // Patterns for short (< 32KiB) variants 16280 instruct cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 16281 match(If cmp (CmpL op1 op2)); 16282 effect(USE labl); 16283 16284 ins_cost(BRANCH_COST); 16285 format %{ "cb$cmp $op1, $labl # long" %} 16286 ins_encode %{ 16287 Label* L = $labl$$label; 16288 Assembler::Condition cond = 16289 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16290 __ tbr(cond, $op1$$Register, 63, *L); 16291 %} 16292 ins_pipe(pipe_cmp_branch); 16293 ins_short_branch(1); 16294 %} 16295 16296 instruct cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 16297 match(If cmp (CmpI op1 op2)); 16298 effect(USE labl); 16299 16300 ins_cost(BRANCH_COST); 16301 format %{ "cb$cmp $op1, $labl # int" %} 16302 ins_encode %{ 16303 Label* L = $labl$$label; 16304 Assembler::Condition cond = 16305 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16306 __ tbr(cond, $op1$$Register, 31, *L); 16307 %} 16308 ins_pipe(pipe_cmp_branch); 16309 ins_short_branch(1); 16310 %} 16311 16312 instruct cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 16313 match(If cmp (CmpL (AndL op1 op2) op3)); 16314 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 16315 effect(USE labl); 16316 16317 ins_cost(BRANCH_COST); 16318 format %{ "tb$cmp $op1, $op2, $labl" %} 16319 ins_encode %{ 16320 Label* L = $labl$$label; 16321 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16322 int bit = exact_log2_long($op2$$constant); 16323 __ tbr(cond, $op1$$Register, bit, *L); 16324 %} 16325 ins_pipe(pipe_cmp_branch); 16326 ins_short_branch(1); 16327 %} 16328 16329 instruct cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 16330 match(If cmp (CmpI (AndI op1 op2) op3)); 16331 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 16332 effect(USE labl); 16333 16334 ins_cost(BRANCH_COST); 16335 format %{ "tb$cmp $op1, $op2, $labl" %} 16336 ins_encode %{ 16337 Label* L = $labl$$label; 16338 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16339 int bit = exact_log2((juint)$op2$$constant); 16340 __ tbr(cond, $op1$$Register, bit, *L); 16341 %} 16342 ins_pipe(pipe_cmp_branch); 16343 ins_short_branch(1); 16344 %} 16345 16346 // And far variants 16347 instruct far_cmpL_branch_sign(cmpOpLtGe cmp, iRegL op1, immL0 op2, label labl) %{ 16348 match(If cmp (CmpL op1 op2)); 16349 effect(USE labl); 16350 16351 ins_cost(BRANCH_COST); 16352 format %{ "cb$cmp $op1, $labl # long" %} 16353 ins_encode %{ 16354 Label* L = $labl$$label; 16355 Assembler::Condition cond = 16356 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16357 __ tbr(cond, $op1$$Register, 63, *L, /*far*/true); 16358 %} 16359 ins_pipe(pipe_cmp_branch); 16360 %} 16361 16362 instruct far_cmpI_branch_sign(cmpOpLtGe cmp, iRegIorL2I op1, immI0 op2, label labl) %{ 16363 match(If cmp (CmpI op1 op2)); 16364 effect(USE labl); 16365 16366 ins_cost(BRANCH_COST); 16367 format %{ "cb$cmp $op1, $labl # int" %} 16368 ins_encode %{ 16369 Label* L = $labl$$label; 16370 Assembler::Condition cond = 16371 ((Assembler::Condition)$cmp$$cmpcode == Assembler::LT) ? Assembler::NE : Assembler::EQ; 16372 __ tbr(cond, $op1$$Register, 31, *L, /*far*/true); 16373 %} 16374 ins_pipe(pipe_cmp_branch); 16375 %} 16376 16377 instruct far_cmpL_branch_bit(cmpOpEqNe cmp, iRegL op1, immL op2, immL0 op3, label labl) %{ 16378 match(If cmp (CmpL (AndL op1 op2) op3)); 16379 predicate(is_power_of_2((julong)n->in(2)->in(1)->in(2)->get_long())); 16380 effect(USE labl); 16381 16382 ins_cost(BRANCH_COST); 16383 format %{ "tb$cmp $op1, $op2, $labl" %} 16384 ins_encode %{ 16385 Label* L = $labl$$label; 16386 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16387 int bit = exact_log2_long($op2$$constant); 16388 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 16389 %} 16390 ins_pipe(pipe_cmp_branch); 16391 %} 16392 16393 instruct far_cmpI_branch_bit(cmpOpEqNe cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl) %{ 16394 match(If cmp (CmpI (AndI op1 op2) op3)); 16395 predicate(is_power_of_2((juint)n->in(2)->in(1)->in(2)->get_int())); 16396 effect(USE labl); 16397 16398 ins_cost(BRANCH_COST); 16399 format %{ "tb$cmp $op1, $op2, $labl" %} 16400 ins_encode %{ 16401 Label* L = $labl$$label; 16402 Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode; 16403 int bit = exact_log2((juint)$op2$$constant); 16404 __ tbr(cond, $op1$$Register, bit, *L, /*far*/true); 16405 %} 16406 ins_pipe(pipe_cmp_branch); 16407 %} 16408 16409 // Test bits 16410 16411 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{ 16412 match(Set cr (CmpL (AndL op1 op2) op3)); 16413 predicate(Assembler::operand_valid_for_logical_immediate 16414 (/*is_32*/false, n->in(1)->in(2)->get_long())); 16415 16416 ins_cost(INSN_COST); 16417 format %{ "tst $op1, $op2 # long" %} 16418 ins_encode %{ 16419 __ tst($op1$$Register, $op2$$constant); 16420 %} 16421 ins_pipe(ialu_reg_reg); 16422 %} 16423 16424 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{ 16425 match(Set cr (CmpI (AndI op1 op2) op3)); 16426 predicate(Assembler::operand_valid_for_logical_immediate 16427 (/*is_32*/true, n->in(1)->in(2)->get_int())); 16428 16429 ins_cost(INSN_COST); 16430 format %{ "tst $op1, $op2 # int" %} 16431 ins_encode %{ 16432 __ tstw($op1$$Register, $op2$$constant); 16433 %} 16434 ins_pipe(ialu_reg_reg); 16435 %} 16436 16437 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{ 16438 match(Set cr (CmpL (AndL op1 op2) op3)); 16439 16440 ins_cost(INSN_COST); 16441 format %{ "tst $op1, $op2 # long" %} 16442 ins_encode %{ 16443 __ tst($op1$$Register, $op2$$Register); 16444 %} 16445 ins_pipe(ialu_reg_reg); 16446 %} 16447 16448 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{ 16449 match(Set cr (CmpI (AndI op1 op2) op3)); 16450 16451 ins_cost(INSN_COST); 16452 format %{ "tstw $op1, $op2 # int" %} 16453 ins_encode %{ 16454 __ tstw($op1$$Register, $op2$$Register); 16455 %} 16456 ins_pipe(ialu_reg_reg); 16457 %} 16458 16459 16460 // Conditional Far Branch 16461 // Conditional Far Branch Unsigned 16462 // TODO: fixme 16463 16464 // counted loop end branch near 16465 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl) 16466 %{ 16467 match(CountedLoopEnd cmp cr); 16468 16469 effect(USE lbl); 16470 16471 ins_cost(BRANCH_COST); 16472 // short variant. 16473 // ins_short_branch(1); 16474 format %{ "b$cmp $lbl \t// counted loop end" %} 16475 16476 ins_encode(aarch64_enc_br_con(cmp, lbl)); 16477 16478 ins_pipe(pipe_branch); 16479 %} 16480 16481 // counted loop end branch far 16482 // TODO: fixme 16483 16484 // ============================================================================ 16485 // inlined locking and unlocking 16486 16487 instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3) 16488 %{ 16489 match(Set cr (FastLock object box)); 16490 effect(TEMP tmp, TEMP tmp2, TEMP tmp3); 16491 16492 // TODO 16493 // identify correct cost 16494 ins_cost(5 * INSN_COST); 16495 format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %} 16496 16497 ins_encode %{ 16498 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register); 16499 %} 16500 16501 ins_pipe(pipe_serial); 16502 %} 16503 16504 instruct cmpFastUnlock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2) 16505 %{ 16506 match(Set cr (FastUnlock object box)); 16507 effect(TEMP tmp, TEMP tmp2); 16508 16509 ins_cost(5 * INSN_COST); 16510 format %{ "fastunlock $object,$box\t! kills $tmp, $tmp2" %} 16511 16512 ins_encode %{ 16513 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register); 16514 %} 16515 16516 ins_pipe(pipe_serial); 16517 %} 16518 16519 16520 // ============================================================================ 16521 // Safepoint Instructions 16522 16523 // TODO 16524 // provide a near and far version of this code 16525 16526 instruct safePoint(rFlagsReg cr, iRegP poll) 16527 %{ 16528 match(SafePoint poll); 16529 effect(KILL cr); 16530 16531 format %{ 16532 "ldrw zr, [$poll]\t# Safepoint: poll for GC" 16533 %} 16534 ins_encode %{ 16535 __ read_polling_page(as_Register($poll$$reg), relocInfo::poll_type); 16536 %} 16537 ins_pipe(pipe_serial); // ins_pipe(iload_reg_mem); 16538 %} 16539 16540 16541 // ============================================================================ 16542 // Procedure Call/Return Instructions 16543 16544 // Call Java Static Instruction 16545 16546 instruct CallStaticJavaDirect(method meth) 16547 %{ 16548 match(CallStaticJava); 16549 16550 effect(USE meth); 16551 16552 ins_cost(CALL_COST); 16553 16554 format %{ "call,static $meth \t// ==> " %} 16555 16556 ins_encode(aarch64_enc_java_static_call(meth), 16557 aarch64_enc_call_epilog); 16558 16559 ins_pipe(pipe_class_call); 16560 %} 16561 16562 // TO HERE 16563 16564 // Call Java Dynamic Instruction 16565 instruct CallDynamicJavaDirect(method meth) 16566 %{ 16567 match(CallDynamicJava); 16568 16569 effect(USE meth); 16570 16571 ins_cost(CALL_COST); 16572 16573 format %{ "CALL,dynamic $meth \t// ==> " %} 16574 16575 ins_encode(aarch64_enc_java_dynamic_call(meth), 16576 aarch64_enc_call_epilog); 16577 16578 ins_pipe(pipe_class_call); 16579 %} 16580 16581 // Call Runtime Instruction 16582 16583 instruct CallRuntimeDirect(method meth) 16584 %{ 16585 match(CallRuntime); 16586 16587 effect(USE meth); 16588 16589 ins_cost(CALL_COST); 16590 16591 format %{ "CALL, runtime $meth" %} 16592 16593 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16594 16595 ins_pipe(pipe_class_call); 16596 %} 16597 16598 // Call Runtime Instruction 16599 16600 instruct CallLeafDirect(method meth) 16601 %{ 16602 match(CallLeaf); 16603 16604 effect(USE meth); 16605 16606 ins_cost(CALL_COST); 16607 16608 format %{ "CALL, runtime leaf $meth" %} 16609 16610 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16611 16612 ins_pipe(pipe_class_call); 16613 %} 16614 16615 // Call Runtime Instruction 16616 16617 // entry point is null, target holds the address to call 16618 instruct CallLeafNoFPIndirect(iRegP target) 16619 %{ 16620 predicate(n->as_Call()->entry_point() == nullptr); 16621 16622 match(CallLeafNoFP target); 16623 16624 ins_cost(CALL_COST); 16625 16626 format %{ "CALL, runtime leaf nofp indirect $target" %} 16627 16628 ins_encode %{ 16629 __ blr($target$$Register); 16630 %} 16631 16632 ins_pipe(pipe_class_call); 16633 %} 16634 16635 instruct CallLeafNoFPDirect(method meth) 16636 %{ 16637 predicate(n->as_Call()->entry_point() != nullptr); 16638 16639 match(CallLeafNoFP); 16640 16641 effect(USE meth); 16642 16643 ins_cost(CALL_COST); 16644 16645 format %{ "CALL, runtime leaf nofp $meth" %} 16646 16647 ins_encode( aarch64_enc_java_to_runtime(meth) ); 16648 16649 ins_pipe(pipe_class_call); 16650 %} 16651 16652 // Tail Call; Jump from runtime stub to Java code. 16653 // Also known as an 'interprocedural jump'. 16654 // Target of jump will eventually return to caller. 16655 // TailJump below removes the return address. 16656 instruct TailCalljmpInd(iRegPNoSp jump_target, inline_cache_RegP method_ptr) 16657 %{ 16658 match(TailCall jump_target method_ptr); 16659 16660 ins_cost(CALL_COST); 16661 16662 format %{ "br $jump_target\t# $method_ptr holds method" %} 16663 16664 ins_encode(aarch64_enc_tail_call(jump_target)); 16665 16666 ins_pipe(pipe_class_call); 16667 %} 16668 16669 instruct TailjmpInd(iRegPNoSp jump_target, iRegP_R0 ex_oop) 16670 %{ 16671 match(TailJump jump_target ex_oop); 16672 16673 ins_cost(CALL_COST); 16674 16675 format %{ "br $jump_target\t# $ex_oop holds exception oop" %} 16676 16677 ins_encode(aarch64_enc_tail_jmp(jump_target)); 16678 16679 ins_pipe(pipe_class_call); 16680 %} 16681 16682 // Create exception oop: created by stack-crawling runtime code. 16683 // Created exception is now available to this handler, and is setup 16684 // just prior to jumping to this handler. No code emitted. 16685 // TODO check 16686 // should ex_oop be in r0? intel uses rax, ppc cannot use r0 so uses rarg1 16687 instruct CreateException(iRegP_R0 ex_oop) 16688 %{ 16689 match(Set ex_oop (CreateEx)); 16690 16691 format %{ " -- \t// exception oop; no code emitted" %} 16692 16693 size(0); 16694 16695 ins_encode( /*empty*/ ); 16696 16697 ins_pipe(pipe_class_empty); 16698 %} 16699 16700 // Rethrow exception: The exception oop will come in the first 16701 // argument position. Then JUMP (not call) to the rethrow stub code. 16702 instruct RethrowException() %{ 16703 match(Rethrow); 16704 ins_cost(CALL_COST); 16705 16706 format %{ "b rethrow_stub" %} 16707 16708 ins_encode( aarch64_enc_rethrow() ); 16709 16710 ins_pipe(pipe_class_call); 16711 %} 16712 16713 16714 // Return Instruction 16715 // epilog node loads ret address into lr as part of frame pop 16716 instruct Ret() 16717 %{ 16718 match(Return); 16719 16720 format %{ "ret\t// return register" %} 16721 16722 ins_encode( aarch64_enc_ret() ); 16723 16724 ins_pipe(pipe_branch); 16725 %} 16726 16727 // Die now. 16728 instruct ShouldNotReachHere() %{ 16729 match(Halt); 16730 16731 ins_cost(CALL_COST); 16732 format %{ "ShouldNotReachHere" %} 16733 16734 ins_encode %{ 16735 if (is_reachable()) { 16736 __ stop(_halt_reason); 16737 } 16738 %} 16739 16740 ins_pipe(pipe_class_default); 16741 %} 16742 16743 // ============================================================================ 16744 // Partial Subtype Check 16745 // 16746 // superklass array for an instance of the superklass. Set a hidden 16747 // internal cache on a hit (cache is checked with exposed code in 16748 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 16749 // encoding ALSO sets flags. 16750 16751 instruct partialSubtypeCheck(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, rFlagsReg cr) 16752 %{ 16753 match(Set result (PartialSubtypeCheck sub super)); 16754 effect(KILL cr, KILL temp); 16755 16756 ins_cost(1100); // slightly larger than the next version 16757 format %{ "partialSubtypeCheck $result, $sub, $super" %} 16758 16759 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 16760 16761 opcode(0x1); // Force zero of result reg on hit 16762 16763 ins_pipe(pipe_class_memory); 16764 %} 16765 16766 instruct partialSubtypeCheckVsZero(iRegP_R4 sub, iRegP_R0 super, iRegP_R2 temp, iRegP_R5 result, immP0 zero, rFlagsReg cr) 16767 %{ 16768 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 16769 effect(KILL temp, KILL result); 16770 16771 ins_cost(1100); // slightly larger than the next version 16772 format %{ "partialSubtypeCheck $result, $sub, $super == 0" %} 16773 16774 ins_encode(aarch64_enc_partial_subtype_check(sub, super, temp, result)); 16775 16776 opcode(0x0); // Don't zero result reg on hit 16777 16778 ins_pipe(pipe_class_memory); 16779 %} 16780 16781 // Intrisics for String.compareTo() 16782 16783 instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16784 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 16785 %{ 16786 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU)); 16787 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16788 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16789 16790 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 16791 ins_encode %{ 16792 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16793 __ string_compare($str1$$Register, $str2$$Register, 16794 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16795 $tmp1$$Register, $tmp2$$Register, 16796 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::UU); 16797 %} 16798 ins_pipe(pipe_class_memory); 16799 %} 16800 16801 instruct string_compareL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16802 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, rFlagsReg cr) 16803 %{ 16804 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL)); 16805 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16806 effect(KILL tmp1, KILL tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16807 16808 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1" %} 16809 ins_encode %{ 16810 __ string_compare($str1$$Register, $str2$$Register, 16811 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16812 $tmp1$$Register, $tmp2$$Register, 16813 fnoreg, fnoreg, fnoreg, pnoreg, pnoreg, StrIntrinsicNode::LL); 16814 %} 16815 ins_pipe(pipe_class_memory); 16816 %} 16817 16818 instruct string_compareUL(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16819 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16820 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 16821 %{ 16822 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL)); 16823 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16824 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 16825 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16826 16827 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 16828 ins_encode %{ 16829 __ string_compare($str1$$Register, $str2$$Register, 16830 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16831 $tmp1$$Register, $tmp2$$Register, 16832 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 16833 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::UL); 16834 %} 16835 ins_pipe(pipe_class_memory); 16836 %} 16837 16838 instruct string_compareLU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16839 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16840 vRegD_V0 vtmp1, vRegD_V1 vtmp2, vRegD_V2 vtmp3, rFlagsReg cr) 16841 %{ 16842 predicate((UseSVE == 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU)); 16843 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16844 effect(KILL tmp1, KILL tmp2, KILL vtmp1, KILL vtmp2, KILL vtmp3, 16845 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16846 16847 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # KILL $tmp1, $tmp2, $vtmp1, $vtmp2, $vtmp3" %} 16848 ins_encode %{ 16849 __ string_compare($str1$$Register, $str2$$Register, 16850 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16851 $tmp1$$Register, $tmp2$$Register, 16852 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, 16853 $vtmp3$$FloatRegister, pnoreg, pnoreg, StrIntrinsicNode::LU); 16854 %} 16855 ins_pipe(pipe_class_memory); 16856 %} 16857 16858 // Note that Z registers alias the corresponding NEON registers, we declare the vector operands of 16859 // these string_compare variants as NEON register type for convenience so that the prototype of 16860 // string_compare can be shared with all variants. 16861 16862 instruct string_compareLL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16863 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16864 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16865 pRegGov_P1 pgtmp2, rFlagsReg cr) 16866 %{ 16867 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL)); 16868 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16869 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16870 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16871 16872 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16873 ins_encode %{ 16874 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16875 __ string_compare($str1$$Register, $str2$$Register, 16876 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16877 $tmp1$$Register, $tmp2$$Register, 16878 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16879 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16880 StrIntrinsicNode::LL); 16881 %} 16882 ins_pipe(pipe_class_memory); 16883 %} 16884 16885 instruct string_compareLU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16886 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16887 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16888 pRegGov_P1 pgtmp2, rFlagsReg cr) 16889 %{ 16890 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU)); 16891 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16892 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16893 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16894 16895 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16896 ins_encode %{ 16897 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16898 __ string_compare($str1$$Register, $str2$$Register, 16899 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16900 $tmp1$$Register, $tmp2$$Register, 16901 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16902 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16903 StrIntrinsicNode::LU); 16904 %} 16905 ins_pipe(pipe_class_memory); 16906 %} 16907 16908 instruct string_compareUL_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16909 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16910 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16911 pRegGov_P1 pgtmp2, rFlagsReg cr) 16912 %{ 16913 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL)); 16914 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16915 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16916 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16917 16918 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16919 ins_encode %{ 16920 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16921 __ string_compare($str1$$Register, $str2$$Register, 16922 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16923 $tmp1$$Register, $tmp2$$Register, 16924 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16925 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16926 StrIntrinsicNode::UL); 16927 %} 16928 ins_pipe(pipe_class_memory); 16929 %} 16930 16931 instruct string_compareUU_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2, 16932 iRegI_R0 result, iRegP_R10 tmp1, iRegL_R11 tmp2, 16933 vRegD_V0 vtmp1, vRegD_V1 vtmp2, pRegGov_P0 pgtmp1, 16934 pRegGov_P1 pgtmp2, rFlagsReg cr) 16935 %{ 16936 predicate((UseSVE > 0) && (((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU)); 16937 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 16938 effect(TEMP tmp1, TEMP tmp2, TEMP vtmp1, TEMP vtmp2, TEMP pgtmp1, TEMP pgtmp2, 16939 USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 16940 16941 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result # USE sve" %} 16942 ins_encode %{ 16943 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 16944 __ string_compare($str1$$Register, $str2$$Register, 16945 $cnt1$$Register, $cnt2$$Register, $result$$Register, 16946 $tmp1$$Register, $tmp2$$Register, 16947 $vtmp1$$FloatRegister, $vtmp2$$FloatRegister, fnoreg, 16948 as_PRegister($pgtmp1$$reg), as_PRegister($pgtmp2$$reg), 16949 StrIntrinsicNode::UU); 16950 %} 16951 ins_pipe(pipe_class_memory); 16952 %} 16953 16954 instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16955 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 16956 iRegINoSp tmp3, iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 16957 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 16958 %{ 16959 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 16960 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16961 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16962 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, 16963 TEMP vtmp0, TEMP vtmp1, KILL cr); 16964 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU) " 16965 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 16966 16967 ins_encode %{ 16968 __ string_indexof($str1$$Register, $str2$$Register, 16969 $cnt1$$Register, $cnt2$$Register, 16970 $tmp1$$Register, $tmp2$$Register, 16971 $tmp3$$Register, $tmp4$$Register, 16972 $tmp5$$Register, $tmp6$$Register, 16973 -1, $result$$Register, StrIntrinsicNode::UU); 16974 %} 16975 ins_pipe(pipe_class_memory); 16976 %} 16977 16978 instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 16979 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, 16980 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 16981 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 16982 %{ 16983 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 16984 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 16985 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 16986 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, 16987 TEMP vtmp0, TEMP vtmp1, KILL cr); 16988 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL) " 16989 "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 16990 16991 ins_encode %{ 16992 __ string_indexof($str1$$Register, $str2$$Register, 16993 $cnt1$$Register, $cnt2$$Register, 16994 $tmp1$$Register, $tmp2$$Register, 16995 $tmp3$$Register, $tmp4$$Register, 16996 $tmp5$$Register, $tmp6$$Register, 16997 -1, $result$$Register, StrIntrinsicNode::LL); 16998 %} 16999 ins_pipe(pipe_class_memory); 17000 %} 17001 17002 instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, 17003 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2,iRegINoSp tmp3, 17004 iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, 17005 vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) 17006 %{ 17007 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 17008 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 17009 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, 17010 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 17011 TEMP tmp6, TEMP vtmp0, TEMP vtmp1, KILL cr); 17012 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL) " 17013 "# KILL $str1 cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} 17014 17015 ins_encode %{ 17016 __ string_indexof($str1$$Register, $str2$$Register, 17017 $cnt1$$Register, $cnt2$$Register, 17018 $tmp1$$Register, $tmp2$$Register, 17019 $tmp3$$Register, $tmp4$$Register, 17020 $tmp5$$Register, $tmp6$$Register, 17021 -1, $result$$Register, StrIntrinsicNode::UL); 17022 %} 17023 ins_pipe(pipe_class_memory); 17024 %} 17025 17026 instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 17027 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 17028 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 17029 %{ 17030 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 17031 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 17032 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 17033 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 17034 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU) " 17035 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 17036 17037 ins_encode %{ 17038 int icnt2 = (int)$int_cnt2$$constant; 17039 __ string_indexof($str1$$Register, $str2$$Register, 17040 $cnt1$$Register, zr, 17041 $tmp1$$Register, $tmp2$$Register, 17042 $tmp3$$Register, $tmp4$$Register, zr, zr, 17043 icnt2, $result$$Register, StrIntrinsicNode::UU); 17044 %} 17045 ins_pipe(pipe_class_memory); 17046 %} 17047 17048 instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 17049 immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 17050 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 17051 %{ 17052 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 17053 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 17054 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 17055 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 17056 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL) " 17057 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 17058 17059 ins_encode %{ 17060 int icnt2 = (int)$int_cnt2$$constant; 17061 __ string_indexof($str1$$Register, $str2$$Register, 17062 $cnt1$$Register, zr, 17063 $tmp1$$Register, $tmp2$$Register, 17064 $tmp3$$Register, $tmp4$$Register, zr, zr, 17065 icnt2, $result$$Register, StrIntrinsicNode::LL); 17066 %} 17067 ins_pipe(pipe_class_memory); 17068 %} 17069 17070 instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, 17071 immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, 17072 iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) 17073 %{ 17074 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 17075 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 17076 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, 17077 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); 17078 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL) " 17079 "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} 17080 17081 ins_encode %{ 17082 int icnt2 = (int)$int_cnt2$$constant; 17083 __ string_indexof($str1$$Register, $str2$$Register, 17084 $cnt1$$Register, zr, 17085 $tmp1$$Register, $tmp2$$Register, 17086 $tmp3$$Register, $tmp4$$Register, zr, zr, 17087 icnt2, $result$$Register, StrIntrinsicNode::UL); 17088 %} 17089 ins_pipe(pipe_class_memory); 17090 %} 17091 17092 instruct string_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17093 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 17094 iRegINoSp tmp3, rFlagsReg cr) 17095 %{ 17096 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17097 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 17098 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 17099 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 17100 17101 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result" %} 17102 17103 ins_encode %{ 17104 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 17105 $result$$Register, $tmp1$$Register, $tmp2$$Register, 17106 $tmp3$$Register); 17107 %} 17108 ins_pipe(pipe_class_memory); 17109 %} 17110 17111 instruct stringL_indexof_char(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17112 iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, 17113 iRegINoSp tmp3, rFlagsReg cr) 17114 %{ 17115 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17116 predicate((UseSVE == 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 17117 effect(USE_KILL str1, USE_KILL cnt1, USE_KILL ch, 17118 TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); 17119 17120 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result" %} 17121 17122 ins_encode %{ 17123 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, 17124 $result$$Register, $tmp1$$Register, $tmp2$$Register, 17125 $tmp3$$Register); 17126 %} 17127 ins_pipe(pipe_class_memory); 17128 %} 17129 17130 instruct stringL_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17131 iRegI_R0 result, vecA ztmp1, vecA ztmp2, 17132 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{ 17133 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L); 17134 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17135 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr); 17136 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %} 17137 ins_encode %{ 17138 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register, 17139 $result$$Register, $ztmp1$$FloatRegister, 17140 $ztmp2$$FloatRegister, $pgtmp$$PRegister, 17141 $ptmp$$PRegister, true /* isL */); 17142 %} 17143 ins_pipe(pipe_class_memory); 17144 %} 17145 17146 instruct stringU_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, 17147 iRegI_R0 result, vecA ztmp1, vecA ztmp2, 17148 pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{ 17149 predicate(UseSVE > 0 && ((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U); 17150 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 17151 effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr); 17152 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %} 17153 ins_encode %{ 17154 __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register, 17155 $result$$Register, $ztmp1$$FloatRegister, 17156 $ztmp2$$FloatRegister, $pgtmp$$PRegister, 17157 $ptmp$$PRegister, false /* isL */); 17158 %} 17159 ins_pipe(pipe_class_memory); 17160 %} 17161 17162 instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 17163 iRegI_R0 result, rFlagsReg cr) 17164 %{ 17165 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 17166 match(Set result (StrEquals (Binary str1 str2) cnt)); 17167 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 17168 17169 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 17170 ins_encode %{ 17171 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 17172 __ string_equals($str1$$Register, $str2$$Register, 17173 $result$$Register, $cnt$$Register, 1); 17174 %} 17175 ins_pipe(pipe_class_memory); 17176 %} 17177 17178 instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt, 17179 iRegI_R0 result, rFlagsReg cr) 17180 %{ 17181 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 17182 match(Set result (StrEquals (Binary str1 str2) cnt)); 17183 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr); 17184 17185 format %{ "String Equals $str1,$str2,$cnt -> $result" %} 17186 ins_encode %{ 17187 // Count is in 8-bit bytes; non-Compact chars are 16 bits. 17188 __ string_equals($str1$$Register, $str2$$Register, 17189 $result$$Register, $cnt$$Register, 2); 17190 %} 17191 ins_pipe(pipe_class_memory); 17192 %} 17193 17194 instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 17195 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 17196 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 17197 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7, 17198 iRegP_R10 tmp, rFlagsReg cr) 17199 %{ 17200 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 17201 match(Set result (AryEq ary1 ary2)); 17202 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, 17203 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 17204 TEMP vtmp6, TEMP vtmp7, KILL cr); 17205 17206 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %} 17207 ins_encode %{ 17208 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 17209 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 17210 $result$$Register, $tmp$$Register, 1); 17211 if (tpc == nullptr) { 17212 ciEnv::current()->record_failure("CodeCache is full"); 17213 return; 17214 } 17215 %} 17216 ins_pipe(pipe_class_memory); 17217 %} 17218 17219 instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, 17220 iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, 17221 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 17222 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7, 17223 iRegP_R10 tmp, rFlagsReg cr) 17224 %{ 17225 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 17226 match(Set result (AryEq ary1 ary2)); 17227 effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, 17228 TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 17229 TEMP vtmp6, TEMP vtmp7, KILL cr); 17230 17231 format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %} 17232 ins_encode %{ 17233 address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, 17234 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 17235 $result$$Register, $tmp$$Register, 2); 17236 if (tpc == nullptr) { 17237 ciEnv::current()->record_failure("CodeCache is full"); 17238 return; 17239 } 17240 %} 17241 ins_pipe(pipe_class_memory); 17242 %} 17243 17244 instruct count_positives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg cr) 17245 %{ 17246 match(Set result (CountPositives ary1 len)); 17247 effect(USE_KILL ary1, USE_KILL len, KILL cr); 17248 format %{ "count positives byte[] $ary1,$len -> $result" %} 17249 ins_encode %{ 17250 address tpc = __ count_positives($ary1$$Register, $len$$Register, $result$$Register); 17251 if (tpc == nullptr) { 17252 ciEnv::current()->record_failure("CodeCache is full"); 17253 return; 17254 } 17255 %} 17256 ins_pipe( pipe_slow ); 17257 %} 17258 17259 // fast char[] to byte[] compression 17260 instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 17261 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 17262 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 17263 iRegI_R0 result, rFlagsReg cr) 17264 %{ 17265 match(Set result (StrCompressedCopy src (Binary dst len))); 17266 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, 17267 USE_KILL src, USE_KILL dst, USE len, KILL cr); 17268 17269 format %{ "String Compress $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 17270 ins_encode %{ 17271 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 17272 $result$$Register, $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17273 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 17274 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 17275 %} 17276 ins_pipe(pipe_slow); 17277 %} 17278 17279 // fast byte[] to char[] inflation 17280 instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, iRegP_R3 tmp, 17281 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, 17282 vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, rFlagsReg cr) 17283 %{ 17284 match(Set dummy (StrInflatedCopy src (Binary dst len))); 17285 effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, 17286 TEMP vtmp4, TEMP vtmp5, TEMP vtmp6, TEMP tmp, 17287 USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 17288 17289 format %{ "String Inflate $src,$dst # KILL $tmp $src $dst $len V0-V6 cr" %} 17290 ins_encode %{ 17291 address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 17292 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17293 $vtmp2$$FloatRegister, $tmp$$Register); 17294 if (tpc == nullptr) { 17295 ciEnv::current()->record_failure("CodeCache is full"); 17296 return; 17297 } 17298 %} 17299 ins_pipe(pipe_class_memory); 17300 %} 17301 17302 // encode char[] to byte[] in ISO_8859_1 17303 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 17304 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 17305 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 17306 iRegI_R0 result, rFlagsReg cr) 17307 %{ 17308 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 17309 match(Set result (EncodeISOArray src (Binary dst len))); 17310 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1, 17311 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr); 17312 17313 format %{ "Encode ISO array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 17314 ins_encode %{ 17315 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 17316 $result$$Register, false, 17317 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17318 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 17319 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 17320 %} 17321 ins_pipe(pipe_class_memory); 17322 %} 17323 17324 instruct encode_ascii_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, 17325 vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, 17326 vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, 17327 iRegI_R0 result, rFlagsReg cr) 17328 %{ 17329 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 17330 match(Set result (EncodeISOArray src (Binary dst len))); 17331 effect(USE_KILL src, USE_KILL dst, USE len, KILL vtmp0, KILL vtmp1, 17332 KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr); 17333 17334 format %{ "Encode ASCII array $src,$dst,$len -> $result # KILL $src $dst V0-V5 cr" %} 17335 ins_encode %{ 17336 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 17337 $result$$Register, true, 17338 $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, 17339 $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, 17340 $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); 17341 %} 17342 ins_pipe(pipe_class_memory); 17343 %} 17344 17345 //----------------------------- CompressBits/ExpandBits ------------------------ 17346 17347 instruct compressBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask, 17348 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17349 match(Set dst (CompressBits src mask)); 17350 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17351 format %{ "mov $tsrc, $src\n\t" 17352 "mov $tmask, $mask\n\t" 17353 "bext $tdst, $tsrc, $tmask\n\t" 17354 "mov $dst, $tdst" 17355 %} 17356 ins_encode %{ 17357 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register); 17358 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register); 17359 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17360 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17361 %} 17362 ins_pipe(pipe_slow); 17363 %} 17364 17365 instruct compressBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask, 17366 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17367 match(Set dst (CompressBits (LoadI mem) mask)); 17368 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17369 format %{ "ldrs $tsrc, $mem\n\t" 17370 "ldrs $tmask, $mask\n\t" 17371 "bext $tdst, $tsrc, $tmask\n\t" 17372 "mov $dst, $tdst" 17373 %} 17374 ins_encode %{ 17375 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(), 17376 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 17377 __ ldrs($tmask$$FloatRegister, $constantaddress($mask)); 17378 __ sve_bext($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17379 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17380 %} 17381 ins_pipe(pipe_slow); 17382 %} 17383 17384 instruct compressBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask, 17385 vRegD tdst, vRegD tsrc, vRegD tmask) %{ 17386 match(Set dst (CompressBits src mask)); 17387 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17388 format %{ "mov $tsrc, $src\n\t" 17389 "mov $tmask, $mask\n\t" 17390 "bext $tdst, $tsrc, $tmask\n\t" 17391 "mov $dst, $tdst" 17392 %} 17393 ins_encode %{ 17394 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register); 17395 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register); 17396 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17397 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17398 %} 17399 ins_pipe(pipe_slow); 17400 %} 17401 17402 instruct compressBitsL_memcon(iRegLNoSp dst, memory8 mem, immL mask, 17403 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17404 match(Set dst (CompressBits (LoadL mem) mask)); 17405 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17406 format %{ "ldrd $tsrc, $mem\n\t" 17407 "ldrd $tmask, $mask\n\t" 17408 "bext $tdst, $tsrc, $tmask\n\t" 17409 "mov $dst, $tdst" 17410 %} 17411 ins_encode %{ 17412 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(), 17413 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 17414 __ ldrd($tmask$$FloatRegister, $constantaddress($mask)); 17415 __ sve_bext($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17416 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17417 %} 17418 ins_pipe(pipe_slow); 17419 %} 17420 17421 instruct expandBitsI_reg(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask, 17422 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17423 match(Set dst (ExpandBits src mask)); 17424 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17425 format %{ "mov $tsrc, $src\n\t" 17426 "mov $tmask, $mask\n\t" 17427 "bdep $tdst, $tsrc, $tmask\n\t" 17428 "mov $dst, $tdst" 17429 %} 17430 ins_encode %{ 17431 __ mov($tsrc$$FloatRegister, __ S, 0, $src$$Register); 17432 __ mov($tmask$$FloatRegister, __ S, 0, $mask$$Register); 17433 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17434 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17435 %} 17436 ins_pipe(pipe_slow); 17437 %} 17438 17439 instruct expandBitsI_memcon(iRegINoSp dst, memory4 mem, immI mask, 17440 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17441 match(Set dst (ExpandBits (LoadI mem) mask)); 17442 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17443 format %{ "ldrs $tsrc, $mem\n\t" 17444 "ldrs $tmask, $mask\n\t" 17445 "bdep $tdst, $tsrc, $tmask\n\t" 17446 "mov $dst, $tdst" 17447 %} 17448 ins_encode %{ 17449 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrs, $tsrc$$FloatRegister, $mem->opcode(), 17450 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); 17451 __ ldrs($tmask$$FloatRegister, $constantaddress($mask)); 17452 __ sve_bdep($tdst$$FloatRegister, __ S, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17453 __ mov($dst$$Register, $tdst$$FloatRegister, __ S, 0); 17454 %} 17455 ins_pipe(pipe_slow); 17456 %} 17457 17458 instruct expandBitsL_reg(iRegLNoSp dst, iRegL src, iRegL mask, 17459 vRegD tdst, vRegD tsrc, vRegD tmask) %{ 17460 match(Set dst (ExpandBits src mask)); 17461 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17462 format %{ "mov $tsrc, $src\n\t" 17463 "mov $tmask, $mask\n\t" 17464 "bdep $tdst, $tsrc, $tmask\n\t" 17465 "mov $dst, $tdst" 17466 %} 17467 ins_encode %{ 17468 __ mov($tsrc$$FloatRegister, __ D, 0, $src$$Register); 17469 __ mov($tmask$$FloatRegister, __ D, 0, $mask$$Register); 17470 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17471 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17472 %} 17473 ins_pipe(pipe_slow); 17474 %} 17475 17476 17477 instruct expandBitsL_memcon(iRegINoSp dst, memory8 mem, immL mask, 17478 vRegF tdst, vRegF tsrc, vRegF tmask) %{ 17479 match(Set dst (ExpandBits (LoadL mem) mask)); 17480 effect(TEMP tdst, TEMP tsrc, TEMP tmask); 17481 format %{ "ldrd $tsrc, $mem\n\t" 17482 "ldrd $tmask, $mask\n\t" 17483 "bdep $tdst, $tsrc, $tmask\n\t" 17484 "mov $dst, $tdst" 17485 %} 17486 ins_encode %{ 17487 loadStore(C2_MacroAssembler(&cbuf), &MacroAssembler::ldrd, $tsrc$$FloatRegister, $mem->opcode(), 17488 as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 8); 17489 __ ldrd($tmask$$FloatRegister, $constantaddress($mask)); 17490 __ sve_bdep($tdst$$FloatRegister, __ D, $tsrc$$FloatRegister, $tmask$$FloatRegister); 17491 __ mov($dst$$Register, $tdst$$FloatRegister, __ D, 0); 17492 %} 17493 ins_pipe(pipe_slow); 17494 %} 17495 17496 // ============================================================================ 17497 // This name is KNOWN by the ADLC and cannot be changed. 17498 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 17499 // for this guy. 17500 instruct tlsLoadP(thread_RegP dst) 17501 %{ 17502 match(Set dst (ThreadLocal)); 17503 17504 ins_cost(0); 17505 17506 format %{ " -- \t// $dst=Thread::current(), empty" %} 17507 17508 size(0); 17509 17510 ins_encode( /*empty*/ ); 17511 17512 ins_pipe(pipe_class_empty); 17513 %} 17514 17515 //----------PEEPHOLE RULES----------------------------------------------------- 17516 // These must follow all instruction definitions as they use the names 17517 // defined in the instructions definitions. 17518 // 17519 // peepmatch ( root_instr_name [preceding_instruction]* ); 17520 // 17521 // peepconstraint %{ 17522 // (instruction_number.operand_name relational_op instruction_number.operand_name 17523 // [, ...] ); 17524 // // instruction numbers are zero-based using left to right order in peepmatch 17525 // 17526 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 17527 // // provide an instruction_number.operand_name for each operand that appears 17528 // // in the replacement instruction's match rule 17529 // 17530 // ---------VM FLAGS--------------------------------------------------------- 17531 // 17532 // All peephole optimizations can be turned off using -XX:-OptoPeephole 17533 // 17534 // Each peephole rule is given an identifying number starting with zero and 17535 // increasing by one in the order seen by the parser. An individual peephole 17536 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 17537 // on the command-line. 17538 // 17539 // ---------CURRENT LIMITATIONS---------------------------------------------- 17540 // 17541 // Only match adjacent instructions in same basic block 17542 // Only equality constraints 17543 // Only constraints between operands, not (0.dest_reg == RAX_enc) 17544 // Only one replacement instruction 17545 // 17546 // ---------EXAMPLE---------------------------------------------------------- 17547 // 17548 // // pertinent parts of existing instructions in architecture description 17549 // instruct movI(iRegINoSp dst, iRegI src) 17550 // %{ 17551 // match(Set dst (CopyI src)); 17552 // %} 17553 // 17554 // instruct incI_iReg(iRegINoSp dst, immI1 src, rFlagsReg cr) 17555 // %{ 17556 // match(Set dst (AddI dst src)); 17557 // effect(KILL cr); 17558 // %} 17559 // 17560 // // Change (inc mov) to lea 17561 // peephole %{ 17562 // // increment preceded by register-register move 17563 // peepmatch ( incI_iReg movI ); 17564 // // require that the destination register of the increment 17565 // // match the destination register of the move 17566 // peepconstraint ( 0.dst == 1.dst ); 17567 // // construct a replacement instruction that sets 17568 // // the destination to ( move's source register + one ) 17569 // peepreplace ( leaI_iReg_immI( 0.dst 1.src 0.src ) ); 17570 // %} 17571 // 17572 17573 // Implementation no longer uses movX instructions since 17574 // machine-independent system no longer uses CopyX nodes. 17575 // 17576 // peephole 17577 // %{ 17578 // peepmatch (incI_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 (decI_iReg 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 (addI_iReg_imm movI); 17593 // peepconstraint (0.dst == 1.dst); 17594 // peepreplace (leaI_iReg_immI(0.dst 1.src 0.src)); 17595 // %} 17596 17597 // peephole 17598 // %{ 17599 // peepmatch (incL_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 (decL_iReg 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 (addL_iReg_imm movL); 17614 // peepconstraint (0.dst == 1.dst); 17615 // peepreplace (leaL_iReg_immL(0.dst 1.src 0.src)); 17616 // %} 17617 17618 // peephole 17619 // %{ 17620 // peepmatch (addP_iReg_imm movP); 17621 // peepconstraint (0.dst == 1.dst); 17622 // peepreplace (leaP_iReg_imm(0.dst 1.src 0.src)); 17623 // %} 17624 17625 // // Change load of spilled value to only a spill 17626 // instruct storeI(memory mem, iRegI src) 17627 // %{ 17628 // match(Set mem (StoreI mem src)); 17629 // %} 17630 // 17631 // instruct loadI(iRegINoSp dst, memory mem) 17632 // %{ 17633 // match(Set dst (LoadI mem)); 17634 // %} 17635 // 17636 17637 //----------SMARTSPILL RULES--------------------------------------------------- 17638 // These must follow all instruction definitions as they use the names 17639 // defined in the instructions definitions. 17640 17641 // Local Variables: 17642 // mode: c++ 17643 // End: